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