1 /* BLURB lgpl 2 3 Coda File System 4 Release 5 5 6 Copyright (c) 1987-2008 Carnegie Mellon University 7 Additional copyrights listed below 8 9 This code is distributed "AS IS" without warranty of any kind under 10 the terms of the GNU Library General Public Licence Version 2, as 11 shown in the file LICENSE. The technical and financial contributors to 12 Coda are listed in the file CREDITS. 13 14 Additional copyrights 15 16 #*/ 17 18 /* 19 IBM COPYRIGHT NOTICE 20 21 Copyright (C) 1986 22 International Business Machines Corporation 23 All Rights Reserved 24 25 This file contains some code identical to or derived from the 1986 26 version of the Andrew File System ("AFS"), which is owned by the IBM 27 Corporation. This code is provided "AS IS" and IBM does not warrant 28 that it is free of infringement of any intellectual rights of any 29 third party. IBM disclaims liability of any kind for any damages 30 whatsoever resulting directly or indirectly from use of this software 31 or of any derivative work. Carnegie Mellon University has obtained 32 permission to modify, distribute and sublicense this code, which is 33 based on Version 2 of AFS and does not contain the features and 34 enhancements that are part of Version 3 of AFS. Version 3 of AFS is 35 commercially available and supported by Transarc Corporation, 36 Pittsburgh, PA. 37 38 */ 39 40 #ifndef _RPC2_PRIVATE_H_ 41 #define _RPC2_PRIVATE_H_ 42 43 #ifdef HAVE_CONFIG_H 44 #include <config.h> 45 #endif 46 47 #include <netinet/in.h> 48 #include <signal.h> 49 #include <lwp/lwp.h> 50 #include <lwp/timer.h> 51 #include <rpc2/rpc2.h> 52 #include <string.h> 53 #include <dllist.h> 54 55 #include <rpc2/rpc2_addrinfo.h> 56 #include <rpc2/secure.h> 57 58 #ifndef HAVE_STRUCT_SOCKADDR_STORAGE 59 /* this should be large enough to fit 'any' socket address. */ 60 struct sockaddr_storage { 61 struct sockaddr __ss_sa; 62 char _ss_padding[128 - sizeof(struct sockaddr)]; 63 }; 64 #endif 65 66 #ifndef HAVE_STRUCT_SOCKADDR_IN6 67 struct in6_addr { 68 u_int8_t u6_addr[16]; 69 }; 70 struct sockaddr_in6 { 71 u_int16_t sin6_family; 72 u_int16_t sin6_port; 73 u_int32_t sin6_flowinfo; 74 struct in6_addr sin6_addr; 75 }; 76 #endif 77 78 #ifndef HAVE_SOCKLEN_T 79 #define socklen_t unsigned int 80 #endif 81 82 83 /* 84 Magic Number assignments for runtime system objects. 85 Truly random values to allow easy detection of storage corruption. 86 87 OBJ_PACKETBUFFER = 3247517 88 OBJ_CENTRY = 868 89 OBJ_MENTRY = 69743 90 OBJ_SLENTRY = 107 91 OBJ_SSENTRY = 34079 92 OBJ_HENTRY = 48127 93 94 */ 95 96 /* Role and state determination: 97 Top 2 bytes (0x0088 or 0x0044) determine client or server 98 Bottom 2 bytes determine state within client or server. 99 This allows rapid testing using bit masks. 100 */ 101 102 /* Server or Client? */ 103 #define FREE 0x0 104 #define CLIENT 0x00880000 105 #define SERVER 0x00440000 106 107 /* Client States */ 108 #define C_THINK 0x1 109 #define C_AWAITREPLY 0x2 110 #define C_HARDERROR 0x4 111 #define C_AWAITINIT2 0x8 112 #define C_AWAITINIT4 0x10 113 114 /* Server States */ 115 #define S_AWAITREQUEST 0x1 116 #define S_REQINQUEUE 0x2 117 #define S_PROCESS 0x4 118 #define S_INSE 0x8 119 #define S_HARDERROR 0x10 120 #define S_STARTBIND 0x20 121 #define S_AWAITINIT3 0x40 122 #define S_FINISHBIND 0x80 123 #define S_AWAITENABLE 0x0100 124 125 126 #define SetRole(e, role) (e->State = role) 127 #define SetState(e, new) (e->State = (e->State & 0xffff0000) | (new)) 128 #define TestRole(e, role) ((e->State & 0xffff0000) == role) 129 #define TestState(e, role, smask)\ 130 (TestRole(e, role) && ((e->State & 0x0000ffff) & (smask))) 131 132 #ifndef O_BINARY 133 #define O_BINARY 0 134 #endif 135 136 /* MAXRTO is used to avoid unbounded timeouts */ 137 #define RPC2_MAXRTO 30000000 /* max rto (rtt + variance) is 30 seconds */ 138 #define RPC2_DELACK_DELAY 100000 /* delay for server to send an ack that it 139 received a request. This provides an 140 upper bound on server response time. */ 141 142 /* Definitions for Flags field of connections */ 143 #define CE_OLDV 0x1 /* old version detected during bind */ 144 145 /*---------------- Data Structures ----------------*/ 146 struct LinkEntry /* form of entries in doubly-linked lists */ 147 { 148 struct LinkEntry *NextEntry; /* in accordance with insque(3) */ 149 struct LinkEntry *PrevEntry; 150 long MagicNumber; /* unique for object type; NEVER altered */ 151 struct LinkEntry **Qname; /* head pointer of queue on which this element should be */ 152 /* body comes here, but is irrelevant for list manipulation and object validation */ 153 }; 154 155 struct CEntry /* describes a single RPC connection */ 156 { 157 /* Link Entry Fields */ 158 struct dllist_head connlist; 159 enum {OBJ_CENTRY = 868, OBJ_FREE_CENTRY = 686} MagicNumber; 160 struct CEntry *Qname; 161 162 struct dllist_head Chain; 163 164 /* State, identity and sequencing */ 165 long State; 166 RPC2_Handle UniqueCID; 167 RPC2_Unsigned NextSeqNumber; 168 RPC2_Integer SubsysId; 169 RPC2_Integer Flags; /* CE_OLDV ? */ 170 time_t LastRef; /* when CEntry was last looked up */ 171 172 /* Security */ 173 RPC2_Integer SecurityLevel; 174 RPC2_EncryptionKey SessionKey; 175 RPC2_Integer EncryptionType; 176 177 /* PeerInfo */ 178 RPC2_Handle PeerHandle; /* peer's connection ID */ 179 RPC2_Integer PeerUnique; /* Unique integer used in Init1 bind request 180 from peer */ 181 struct HEntry *HostInfo; /* Link to host table and liveness 182 information */ 183 184 /* Auxiliary stuff */ 185 struct SE_Definition *SEProcs; /* pointer to side effect routines */ 186 long sebroken; /* flag set on hard se errors */ 187 struct MEntry *Mgrp; /* Multicast group of this conn */ 188 char *PrivatePtr; /* rock for pointer to user data */ 189 char *SideEffectPtr; /* rock for per-connection side-effect data */ 190 RPC2_Integer Color; /* Packets sent out get this color. 191 See documentation for libfail(3). 192 Only lowest byte is useful. */ 193 /* Stuff for SocketListener */ 194 struct SL_Entry *MySl; /* SL entry pertaining to this conn, or NULL */ 195 RPC2_PacketBuffer *HeldPacket; /* NULL or pointer to packet held in readiness 196 for retransmission (reply or last packet 197 of Bind handshake */ 198 unsigned long reqsize; /* size of request, for RTT calcs */ 199 200 unsigned int TimeStampEcho; 201 unsigned int RequestTime; 202 struct timeval TimeBomb; /* Time limit for some rpc2 requests on 203 this connection. */ 204 struct timeval SaveResponse; /* 2*KeepAlive, lifetime of saved response packet. */ 205 RPC2_RequestFilter Filter; /* Set on the server during binding, 206 filter incoming requests so that the 207 SubsysID/Connection matches that of 208 the handler we authenticated with */ 209 struct security_association sa; 210 }; 211 212 213 struct MEntry /* describes an RPC multicast connection */ 214 { 215 /* Link Entry Pointers */ 216 struct MEntry *Next; 217 struct MEntry *Prev; 218 enum {OBJ_MENTRY = 69743} 219 MagicNumber; 220 struct MEntry *Qname; 221 222 /* Multicast Group Connection info */ 223 RPC2_Integer State; /* eg {C,S}_AWAITREQUEST */ 224 struct RPC2_addrinfo *ClientAddr; /* | */ 225 RPC2_Handle MgroupID; /* | */ 226 RPC2_Integer NextSeqNumber; /* for mgrp connection */ 227 228 /* Auxiliary stuff */ 229 struct SE_Definition *SEProcs; /* pointer to side effect routines */ 230 char *SideEffectPtr; /* rock for per-mgrp side-effect data */ 231 232 /* Connection entries associated with this Mgrp. Clients have an 233 array of these, servers only one. */ 234 union 235 { 236 struct 237 { 238 struct CEntry **mec_listeners; 239 long mec_howmanylisteners; 240 long mec_maxlisteners; 241 } me_client; 242 struct CEntry *mes_conn; 243 } me_conns; 244 #define listeners me_conns.me_client.mec_listeners 245 #define howmanylisteners me_conns.me_client.mec_howmanylisteners 246 #define maxlisteners me_conns.me_client.mec_maxlisteners 247 #define conn me_conns.mes_conn 248 }; 249 250 251 /* SL entries are the data structures used for comm between user LWPs and 252 the SocketListener. The user LWP creates an entry, sets it up, sets a 253 timeout on it and goes to sleep. SocketListener eventually sets a 254 return code on the entry and wakes up the LWP. 255 256 SL Entries are typed: 257 REPLY associated with a specific connection 258 created by user LWP in SendResponse 259 creating LWP does not wait for timeout to expire 260 destroyed by SocketListener 261 262 REQ not associated with a specific connection 263 created and destroyed by user LWP in GetRequest 264 265 DELACK delayed ack response to receiving a request 266 created by SocketListener in HandleRequest 267 destroyed by SocketListener on timeout 268 destroyed by user LWP when reply is sent. 269 270 DELAYED_SEND Artificially introduced a transmission delay 271 DELAYED_RECV Artificially introduced a reception delay 272 273 OTHER associated with a specific connection 274 created and destroyed by user LWP 275 276 Entries of type REQ are on a separate list to minimize list searching in 277 SocketListener. Other types of entries can be directly accessed via the 278 connection they are associated with. 279 280 */ 281 282 /* NOTE: enum definitions have to be non-anonymous: else a dbx bug is triggered */ 283 enum SL_Type {REPLY=1421, REQ=1422, OTHER=1423, DELACK=20010911, 284 DELAYED_SEND=20061016, DELAYED_RECV=20061017}; 285 enum RetVal {WAITING=38358230, ARRIVED=38358231, TIMEOUT=38358232, 286 KEPTALIVE=38358233, KILLED=38358234, NAKED=38358235}; 287 288 /* data structure for communication with SocketListener */ 289 struct SL_Entry 290 { 291 /* LinkEntry fields */ 292 struct SL_Entry *NextEntry; 293 struct SL_Entry *PrevEntry; 294 enum {OBJ_SLENTRY = 107} MagicNumber; 295 struct SL_Entry *Qname; 296 297 enum SL_Type Type; 298 299 /* Timeout-related fields */ 300 struct TM_Elem TElem; /* element to be inserted into timer chain; 301 The BackPointer field of TElem will 302 point to this SL_Entry */ 303 enum RetVal ReturnCode; /* SocketListener changes this from WAITING */ 304 305 /* Other fields */ 306 RPC2_Handle Conn; /* NULL or conn corr to this SL Entry */ 307 void *data; /* NULL, packet buffer, or delayed xmit data */ 308 RPC2_RequestFilter Filter; /* useful only in GetRequest */ 309 int RetryIndex; /* useful only in MakeRPC */ 310 struct timeval RInterval; /* current retry timeout */ 311 }; 312 313 314 struct SubsysEntry /* Defines a subsystem being actively serviced by a server */ 315 { /* Created by RPC2_InitSubsys(); destroyed by RPC2_EndSubsys() */ 316 struct SubsysEntry *Next; /* LinkEntry field */ 317 struct SubsysEntry *Prev; /* LinkEntry field */ 318 enum {OBJ_SSENTRY = 34079} MagicNumber; 319 struct SubsysEntry *Qname; /* LinkEntry field */ 320 long Id; /* using a struct is a little excessive, but it makes things uniform */ 321 }; 322 323 324 /* extend with other side effect types */ 325 typedef enum {UNSET_HE = 0, RPC2_HE = 1, SMARTFTP_HE = 2} HEType; 326 327 struct HEntry { 328 /* Link Entry Pointers */ 329 struct HEntry *Next; /* LinkEntry field */ 330 struct HEntry *Prev; /* LinkEntry field */ 331 enum {OBJ_HENTRY = 48127} 332 MagicNumber; 333 struct HEntry *Qname; /* LinkEntry field */ 334 struct HEntry *HLink; /* for host hash */ 335 int RefCount; /* # connections that have a reference */ 336 struct RPC2_addrinfo *Addr; /* network address */ 337 struct timeval LastWord; /* Most recent time we've heard from this host*/ 338 unsigned RPC2_NumEntries; /* number of observations recorded */ 339 RPC2_NetLogEntry RPC2_Log[RPC2_MAXLOGLENGTH]; 340 /* circular buffer for recent observations on 341 * round trip times and packet sizes */ 342 unsigned SE_NumEntries; /* number of sideeffect observations recorded */ 343 RPC2_NetLogEntry SE_Log[RPC2_MAXLOGLENGTH]; 344 345 /* the RTT is shifted analogous to Jacobson's article in SIGCOMM'88 */ 346 #define RPC2_RTT_SHIFT 3 /* Bits to right of binary point of RTT */ 347 #define RPC2_RTTVAR_SHIFT 2 /* Bits to right of binary point of RTTvar */ 348 unsigned long RTT; /* RTT (us<<RPC2_RTT_SHIFT) */ 349 unsigned long RTTvar; /* RTT variance (us<<RPC2_RTTVAR_SHIFT) */ 350 351 #define RPC2_INITIAL_BW 100000 352 #define RPC2_BW_SHIFT 4 353 uint32_t BWlo_in, BWhi_in; /* Incoming Bandwidth (B/s) */ 354 uint32_t BWlo_out, BWhi_out; /* Outgoing Bandwidth (B/s) */ 355 }; 356 357 358 /*-------------- Format of special packets ----------------*/ 359 360 /* WARNING: if you port RPC2, make sure the structure sizes work out to be the same on your target machine */ 361 362 struct Init1Body /* Client to Server: format of packets with opcode of RPC2_INIT1xxx */ 363 { 364 /* body of fake packet from RPC2_GetRequest() */ 365 RPC2_Integer FakeBody_SideEffectType; 366 RPC2_Integer FakeBody_SecurityLevel; 367 RPC2_Integer FakeBody_EncryptionType; 368 RPC2_Integer FakeBody_AuthenticationType; 369 RPC2_Unsigned FakeBody_ClientIdent_SeqLen; 370 RPC2_Unsigned FakeBody_ClientIdent_SeqBody; 371 /* end of body of fake packet from RPC2_GetRequest() */ 372 /* When MakeFake is called we'll clobber the remaining data in this packet 373 * because we don't really send a pointer to the ClientIdent.SeqBody, but 374 * we move it there from the tail of the packet so that the stub generator 375 * can unpack it as a valid RPC2_NEWCONNECTION rpc call */ 376 377 RPC2_Integer XRandom; /* encrypted random number */ 378 char usedtobehostport[92]; /* XXX not used anymore but old rpc2 379 servers need the alignment */ 380 RPC2_Integer Uniquefier; /* to allow detection of retransmissions */ 381 RPC2_Unsigned RPC2SEC_version; /* supported handshake version */ 382 RPC2_Unsigned Preferred_Keysize; /* preferred encryption key length */ 383 RPC2_Integer Spare3; 384 RPC2_Byte Version[96]; /* set to RPC2_VERSION */ 385 RPC2_Byte Text[4]; /* Storage for the ClientIdent. Moved 386 to FakeBody_ClientIdent_SeqBody in 387 rpc2a.c:MakeFake(). It can of course 388 be more than 4 bytes, this is just 389 for alignment purposes. */ 390 }; 391 392 struct Init2Body /* Server to Client */ 393 { 394 RPC2_Integer XRandomPlusOne; 395 RPC2_Integer YRandom; 396 RPC2_Integer Spare1; 397 RPC2_Integer Spare2; 398 RPC2_Integer Spare3; 399 }; 400 401 struct Init3Body /* Client to Server */ 402 { 403 RPC2_Integer YRandomPlusOne; 404 RPC2_Integer Spare1; 405 RPC2_Integer Spare2; 406 RPC2_Integer Spare3; 407 }; 408 409 struct Init4Body /* Server to Client */ 410 { 411 RPC2_Integer InitialSeqNumber; /* Seq number of first expected packet from client */ 412 RPC2_EncryptionKey SessionKey; /* for use from now on */ 413 RPC2_Integer XRandomPlusTwo; /* prevent replays of this packet -rnw 2/7/98 */ 414 RPC2_Integer Spare1; 415 RPC2_Integer Spare2; 416 }; 417 418 struct InitMulticastBody /* Client to Server */ 419 { 420 RPC2_Handle MgroupHandle; 421 RPC2_Integer InitialSeqNumber; /* Seq number of next packet from client */ 422 RPC2_EncryptionKey SessionKey; /* for use on the multicast channel */ 423 RPC2_Integer Spare1; 424 RPC2_Integer Spare2; 425 RPC2_Integer Spare3; 426 }; 427 428 /* Macros for manipulating color field of packets */ 429 #define htonPktColor(p) (p->Header.Flags = htonl(p->Header.Flags)) 430 #define ntohPktColor(p) (p->Header.Flags = ntohl(p->Header.Flags)) 431 #define SetPktColor(p,c)\ 432 (p->Header.Flags = (p->Header.Flags & 0xff00ffff) | ((c & 0xff) << 16)) 433 #define GetPktColor(p) ((p->Header.Flags >> 16) & 0x000000ff) 434 435 436 437 438 /*------------- List headers and counts -------------*/ 439 440 /* NOTE: all these lists are doubly-linked and circular */ 441 442 /* The multicast group abstraction */ 443 extern struct MEntry *rpc2_MgrpFreeList; /* free mgrp blocks */ 444 extern long rpc2_MgrpFreeCount, rpc2_MgrpCreationCount; 445 446 /* Items for SocketListener */ 447 448 extern struct SL_Entry *rpc2_SLFreeList, /* free entries */ 449 *rpc2_SLReqList, /* in use, of type REQ */ 450 *rpc2_SLList; /* in use, of types REPLY or OTHER */ 451 extern long rpc2_SLReqCount, rpc2_SLCount; 452 453 /* Packet buffers */ 454 extern RPC2_PacketBuffer *rpc2_PBList, *rpc2_PBHoldList; 455 extern RPC2_PacketBuffer *rpc2_PBSmallFreeList, *rpc2_PBMediumFreeList, *rpc2_PBLargeFreeList; 456 457 /* Subsystem definitions */ 458 extern struct SubsysEntry *rpc2_SSFreeList, /* free entries */ 459 *rpc2_SSList; /* subsystems in active use */ 460 461 /* Host info definitions */ 462 extern struct HEntry *rpc2_HostFreeList, *rpc2_HostList; 463 extern long rpc2_HostFreeCount, rpc2_HostCount, rpc2_HostCreationCount; 464 465 466 /*------------- Miscellaneous global data ------------*/ 467 extern int rpc2_ipv6ready; /* can userspace handle IPv6 addresses */ 468 extern int rpc2_v4RequestSocket; /* fd of RPC socket */ 469 extern int rpc2_v6RequestSocket; /* fd of RPC socket */ 470 /* we may need more when we deal with many domains */ 471 extern struct TM_Elem *rpc2_TimerQueue; 472 extern struct CBUF_Header *rpc2_TraceBuffHeader; 473 extern PROCESS rpc2_SocketListenerPID; /* used in IOMGR_Cancel() calls */ 474 extern unsigned long rpc2_LamportClock; 475 extern long Retry_N; 476 extern struct timeval KeepAlive; 477 extern uint32_t *rpc2_RTTvals; 478 479 /* List manipulation routines */ 480 void rpc2_Replenish(); 481 struct LinkEntry *rpc2_MoveEntry(); 482 struct SL_Entry *rpc2_AllocSle(); 483 void rpc2_FreeSle(struct SL_Entry **sl); 484 void rpc2_ActivateSle(), rpc2_DeactivateSle(); 485 struct SubsysEntry *rpc2_AllocSubsys(); 486 void rpc2_FreeSubsys(); 487 488 void FreeHeld(struct SL_Entry *sle); 489 490 /* Socket creation */ 491 492 long rpc2_CreateIPSocket(int af, int *svar, struct RPC2_addrinfo *addr, short *Port); 493 494 /* Packet routines */ 495 long rpc2_SendReliably(), rpc2_MSendPacketsReliably(); 496 void rpc2_XmitPacket(RPC2_PacketBuffer *pb, struct RPC2_addrinfo *addr, 497 int confirm); 498 void rpc2_InitPacket(); 499 int rpc2_MorePackets(void); 500 long rpc2_RecvPacket(long whichSocket, RPC2_PacketBuffer *whichBuff); 501 void rpc2_htonp(RPC2_PacketBuffer *p); 502 void rpc2_ntohp(RPC2_PacketBuffer *p); 503 long rpc2_CancelRetry(struct CEntry *Conn, struct SL_Entry *Sle); 504 void rpc2_UpdateRTT(RPC2_PacketBuffer *pb, struct CEntry *ceaddr); 505 void rpc2_ExpireEvents(); 506 507 /* Connection manipulation routines */ 508 int rpc2_InitConn(void); 509 void rpc2_FreeConn(), rpc2_SetConnError(); 510 struct CEntry *rpc2_AllocConn(); 511 struct CEntry *rpc2_ConnFromBindInfo(struct RPC2_addrinfo *peeraddr, 512 RPC2_Handle RemoteHandle, 513 RPC2_Integer whichUnique); 514 struct CEntry *__rpc2_GetConn(RPC2_Handle handle); /* doesn't bump lastref */ 515 struct CEntry *rpc2_GetConn(RPC2_Handle handle); 516 void rpc2_ReapDeadConns(void); 517 void rpc2_IncrementSeqNumber(struct CEntry *); 518 519 /* Host manipulation routines */ 520 void rpc2_InitHost(void); 521 struct HEntry *rpc2_GetHost(struct RPC2_addrinfo *addr); 522 void rpc2_FreeHost(struct HEntry **whichHost); 523 void rpc2_GetHostLog(struct HEntry *whichHost, RPC2_NetLog *log, 524 NetLogEntryType type); 525 int rpc2_AppendHostLog(struct HEntry *whichHost, RPC2_NetLogEntry *entry, 526 NetLogEntryType type); 527 void rpc2_ClearHostLog(struct HEntry *whichHost, NetLogEntryType type); 528 529 void RPC2_UpdateEstimates(struct HEntry *whichHost, RPC2_Unsigned ElapsedTime, 530 RPC2_Unsigned InBytes, RPC2_Unsigned OutBytes); 531 int rpc2_RetryInterval(struct CEntry *ce, int retry, struct timeval *tv, 532 RPC2_Unsigned OutBytes, RPC2_Unsigned InBytes, int sftp); 533 534 /* Multicast group manipulation routines */ 535 void rpc2_InitMgrp(), rpc2_FreeMgrp(), rpc2_RemoveFromMgrp(), rpc2_DeleteMgrp(); 536 struct MEntry *rpc2_AllocMgrp(struct RPC2_addrinfo *addr, RPC2_Handle handle); 537 struct MEntry *rpc2_GetMgrp(struct RPC2_addrinfo *addr, RPC2_Handle handle, 538 long role); 539 540 /* Hold queue routines */ 541 void rpc2_HoldPacket(), rpc2_UnholdPacket(); 542 543 /* RPC2_GetRequest() filter matching function */ 544 int rpc2_FilterMatch(); 545 546 /* Autonomous LWPs */ 547 void rpc2_SocketListener(void *); 548 void rpc2_ClockTick(void *); 549 550 /* rpc2_SocketListener packet handlers */ 551 void SL_RegisterHandler(unsigned int proto, void (*func)(RPC2_PacketBuffer *)); 552 void rpc2_HandlePacket(RPC2_PacketBuffer *pb); 553 void RPC2_DispatchProcess(void); 554 555 /* Packet timestamp creation */ 556 unsigned int rpc2_TVTOTS(const struct timeval *tv); 557 void rpc2_TSTOTV(const unsigned int ts, struct timeval *tv); 558 unsigned int rpc2_MakeTimeStamp(); 559 560 /* Debugging routines */ 561 void rpc2_PrintTMElem(), rpc2_PrintFilter(), rpc2_PrintSLEntry(), 562 rpc2_PrintCEntry(), rpc2_PrintTraceElem(), rpc2_PrintPacketHeader(), 563 rpc2_PrintHostIdent(), rpc2_PrintPortIdent(), rpc2_PrintSEDesc(); 564 extern FILE *ErrorLogFile; 565 566 /* encryption */ 567 struct security_association *rpc2_GetSA(uint32_t spi); 568 569 void rpc2_ApplyD(RPC2_PacketBuffer *pb, struct CEntry *ce); 570 void rpc2_ApplyE(RPC2_PacketBuffer *pb, struct CEntry *ce); 571 572 time_t rpc2_time(); 573 long rpc2_InitRetry(long HowManyRetries, struct timeval *Beta0); 574 575 void rpc2_NoteBinding(struct RPC2_addrinfo *peeraddr, 576 RPC2_Handle RemoteHandle, RPC2_Integer whichUnique, 577 RPC2_Handle whichConn); 578 579 int mkcall(RPC2_HandleResult_func *ClientHandler, int ArgCount, int HowMany, 580 RPC2_Handle ConnList[], long offset, long rpcval, int *args); 581 582 583 /*----------- Macros ---------- */ 584 585 /* Test if more than one bit is set; WARNING: make sure at least one bit is set first! */ 586 #define MORETHANONEBITSET(x) (x != (1 << (ffs((long)x)-1))) 587 588 /* Macros to work with preemption package */ 589 /* #define rpc2_Enter() (PRE_BeginCritical()) */ 590 #define rpc2_Enter() do { } while (0) 591 /*#define rpc2_Quit(rc) return(PRE_EndCritical(), (long)rc) */ 592 #define rpc2_Quit(rc) return((long)rc) 593 594 /* Macros to check if host and portal ident structures are equal */ 595 /* The lengths of the names really should be #defined. */ 596 #define rpc2_HostIdentEqual(_hi1p_,_hi2p_) \ 597 (((_hi1p_)->Tag == RPC2_HOSTBYINETADDR && (_hi2p_)->Tag == RPC2_HOSTBYINETADDR)? \ 598 ((_hi1p_)->Value.AddrInfo->ai_family == (_hi2p_)->Value.AddrInfo->ai_family && \ 599 (_hi1p_)->Value.AddrInfo->ai_addrlen == (_hi2p_)->Value.AddrInfo->ai_addrlen && !memcmp((_hi1p_)->Value.AddrInfo->ai_addr,(_hi2p_)->Value.AddrInfo->ai_addr,(_hi2p_)->Value.AddrInfo->ai_addrlen)): \ 600 (((_hi1p_)->Tag == RPC2_HOSTBYNAME && (_hi2p_)->Tag == RPC2_HOSTBYNAME)? \ 601 (strncmp((_hi1p_)->Value.Name, (_hi2p_)->Value.Name, 64) == 0):0)) 602 603 /*------ Other definitions ------*/ 604 605 /* Allocation constants */ 606 607 #define SMALLPACKET 350 608 #define MEDIUMPACKET 1500 609 #define LARGEPACKET RPC2_MAXPACKETSIZE 610 611 612 /* Packets sent */ 613 extern unsigned long rpc2_NoNaks; 614 extern long rpc2_BindLimit, rpc2_BindsInQueue; 615 extern long rpc2_FreeMgrps, rpc2_AllocMgrps; 616 617 /* RPC2_addrinfo helper routines */ 618 struct RPC2_addrinfo *rpc2_resolve(RPC2_HostIdent *Host, RPC2_PortIdent *Port); 619 void rpc2_printaddrinfo(const struct RPC2_addrinfo *ai, FILE *f); 620 void rpc2_splitaddrinfo(RPC2_HostIdent *Host, RPC2_PortIdent *Port, 621 const struct RPC2_addrinfo *ai); 622 void rpc2_simplifyHost(RPC2_HostIdent *Host, RPC2_PortIdent *Port); 623 void rpc2_formataddrinfo(const struct RPC2_addrinfo *ai, char *buf, 624 size_t buflen, int use_canonname); 625 626 627 /*--------------- Useful definitions that used to be in potpourri.h or util.h ---------------*/ 628 /* Now included here to avoid including either of those files */ 629 630 /* Parameter usage */ 631 #define IN /* Input parameter */ 632 #define OUT /* Output parameter */ 633 #define INOUT /* Obvious */ 634 635 636 /* Conditional debugging output macros: no side effect in these! */ 637 char *rpc2_timestring(); 638 #ifdef RPC2DEBUG 639 #define say(when, what, how...)\ 640 do { \ 641 if (when < what){fprintf(rpc2_logfile, "[%s]%s: \"%s\", line %d: ",\ 642 rpc2_timestring(), LWP_Name(), __FILE__, __LINE__);\ 643 fprintf(rpc2_logfile, ## how);(void) fflush(rpc2_logfile);}\ 644 } while(0); 645 #else 646 #define say(when, what, how...) 647 #endif 648 649 #ifndef TRUE 650 #define TRUE 1 651 #define FALSE 0 652 #endif 653 654 655 /*--------- End stuff from util.h ------------*/ 656 657 658 /* macro to subtract one timeval from another */ 659 #define SUBTIME(fromp, subp)\ 660 do {\ 661 if ((subp)->tv_usec > (fromp)->tv_usec) \ 662 { (fromp)->tv_sec--; (fromp)->tv_usec += 1000000; }\ 663 (fromp)->tv_sec -= (subp)->tv_sec;\ 664 (fromp)->tv_usec -= (subp)->tv_usec;\ 665 } while(0); 666 667 /* add one timeval to another */ 668 #define ADDTIME(top, fromp)\ 669 do {\ 670 (top)->tv_sec += (fromp)->tv_sec;\ 671 (top)->tv_usec += (fromp)->tv_usec;\ 672 if ((top)->tv_usec >= 1000000)\ 673 { (top)->tv_sec++; (top)->tv_usec -= 1000000; }\ 674 } while(0); 675 676 #define CMPTIME(a, b, CMP)\ 677 (((a)->tv_sec == (b)->tv_sec) ?\ 678 ((a)->tv_usec CMP (b)->tv_usec) :\ 679 ((a)->tv_sec CMP (b)->tv_sec)) 680 681 #define CLRTIME(tm) ((tm)->tv_sec = 0, (tm)->tv_usec = 0) 682 #define TIMERISSET(tm) ((tm)->tv_sec || (tm)->tv_usec) 683 684 /* macros to convert between timeval and timestamp */ 685 #define TVTOTS(_tvp_, _ts_)\ 686 do {\ 687 _ts_ = ((_tvp_)->tv_sec * 1000000 + (_tvp_)->tv_usec);\ 688 } while(0); 689 690 #define TSTOTV(_tvp_, _ts_)\ 691 do {\ 692 (_tvp_)->tv_sec = (_ts_) / 1000000;\ 693 (_tvp_)->tv_usec = (_ts_) % 1000000;\ 694 } while(0); 695 696 #define TSDELTA(_ts1_, _ts2_) ((int)(_ts1_) - (int)(_ts2_)) 697 698 #ifdef USE_LUA 699 /* lua.c - include Lua interpreter for roundtrip time estimators */ 700 void LUA_init(void); 701 void LUA_clocktick(void); 702 void LUA_drop_hosttable(struct HEntry *he); 703 704 void LUA_rtt_update(struct HEntry *he, uint32_t rtt, uint32_t tx, uint32_t rx); 705 int LUA_rtt_getrto(struct HEntry *he, uint32_t tx, uint32_t rx); 706 int LUA_rtt_getbandwidth(struct HEntry *he, uint32_t *bw_tx, uint32_t *bw_rx); 707 /* not sure if we want to allow the estimator to control number of retries 708 * and/or overall timeout, so I might not actually use this function... */ 709 int LUA_rtt_retryinterval(struct HEntry *he, uint32_t n, uint32_t tx, uint32_t rx); 710 int LUA_fail_delay(struct RPC2_addrinfo *addr, RPC2_PacketBuffer *pb, int out, 711 struct timeval *tv); 712 #else 713 /* do not include Lua interpreter, define empty stubs */ 714 #define LUA_init() 715 #define LUA_clocktick() 716 #define LUA_drop_hosttable(a) 717 #define LUA_rtt_update(a,b,c,d) 718 #define LUA_rtt_getrto(a,b,c) 0 719 #define LUA_rtt_getbandwidth(a,b,c) 0 720 #define LUA_rtt_retryinterval(a,b,c,d) 0 721 #define LUA_fail_delay(a,b,c,d) 0 722 #endif 723 724 int rpc2_DelayedSend(int s, struct RPC2_addrinfo *addr, RPC2_PacketBuffer *pb, 725 struct timeval *delay); 726 int rpc2_DelayedRecv(RPC2_PacketBuffer *pb, struct timeval *delay); 727 728 void rpc2_SendDelayedPacket(struct SL_Entry *sl); 729 RPC2_PacketBuffer *rpc2_RecvDelayedPacket(struct SL_Entry *sl); 730 731 #endif /* _RPC2_PRIVATE_H_ */ 732 733