initial-freebsd-port-work-20010414
[openafs.git] / src / rx / rx_packet.h
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #ifndef _RX_PACKET_
11 #define _RX_PACKET_
12 #ifndef UKERNEL
13 #ifdef AFS_NT40_ENV
14 #include "rx_xmit_nt.h"
15 #else
16 #include <sys/uio.h>
17 #endif
18 #endif /* !UKERNEL */
19 /* this file includes the macros and decls which depend on packet
20  * format, and related packet manipulation macros.  Note that code
21  * which runs at NETPRI should not sleep, or AIX will panic */
22 /* There are some assumptions that various code makes -- I'll try to 
23  * express them all here: 
24  * 1.  rx_ReceiveAckPacket assumes that it can get an entire ack
25  * contiguous in the first iovec.  As a result, the iovec buffers must
26  * be >= sizeof (struct rx_ackpacket)
27  * 2. All callers of rx_Pullup besides rx_ReceiveAckPacket try to pull
28  * up less data than rx_ReceiveAckPacket does.
29  * 3. rx_GetInt32 and rx_PutInt32 (and the slow versions of same) assume
30  * that the iovec buffers are all integral multiples of the word size,
31  * and that the offsets are as well.
32  */
33
34
35 #ifdef AFS_NT40_ENV
36 #ifndef MIN
37 #define MIN(a,b)  ((a)<(b)?(a):(b))
38 #endif
39 #ifndef MAX
40 #define MAX(a,b)  ((a)>(b)?(a):(b))
41 #endif
42 #else /* AFS_NT40_ENV */
43 #if !defined(AFS_DARWIN_ENV) && !defined(AFS_USR_DARWIN_ENV) && !defined(AFS_FBSD_ENV) && !defined(AFS_USR_FBSD_ENV)
44 #include <sys/sysmacros.h>      /* MIN, MAX on Solaris */
45 #endif
46 #include <sys/param.h>          /* MIN, MAX elsewhere */
47 #endif /* AFS_NT40_ENV */
48
49 #define IPv6_HDR_SIZE           40      /* IPv6 Header */
50 #define IPv6_FRAG_HDR_SIZE       8      /* IPv6 Fragment Header */
51 #define UDP_HDR_SIZE             8      /* UDP Header */
52 #define RX_IP_SIZE              (IPv6_HDR_SIZE + IPv6_FRAG_HDR_SIZE)
53 #define RX_IPUDP_SIZE           (RX_IP_SIZE + UDP_HDR_SIZE)
54
55 /* REMOTE_PACKET_SIZE is currently the same as local.  This is because REMOTE
56  * is defined much too generally for my tastes, and includes the case of 
57  * multiple class C nets connected with a router within one campus or MAN. 
58  * I don't want to make local performance suffer just because of some
59  * out-dated protocol that used to be in use on the NSFANET that's
60  * practically unused anymore.  Any modern IP implementation will be
61  * using MTU discovery, and even old routers shouldn't frag packets
62  * when sending from one connected network directly to another.  Maybe
63  * the next release of RX will do MTU discovery. */
64
65 /* MTUXXX the various "MAX" params here must be rationalized.  From now on,
66  * the MAX packet size will be the maximum receive size, but the maximum send
67  * size will be larger than that. */
68
69 #ifdef notdef 
70 /*  some sample MTUs 
71            4352   what FDDI(RFC1188) uses... Larger? 
72            4096   VJ's recommendation for FDDI 
73           17914   what IBM 16MB TR  uses   
74            8166   IEEE 802.4 
75            4464   IEEE 802.5 MAX
76            2002   IEEE 802.5 Recommended 
77            1500   what Ethernet uses 
78            1492   what 802.3 uses ( 8 bytes for 802.2 SAP )
79            9180   Classical IP over ATM (RFC2225)
80 */
81
82 /* * * * these are the old defines
83 */
84  define RX_MAX_PACKET_SIZE      (RX_MAX_DL_MTU -RX_IPUDP_SIZE)
85
86  define RX_MAX_PACKET_DATA_SIZE (RX_MAX_PACKET_SIZE-RX_HEADER_SIZE)
87  ifdef AFS_HPUX_ENV
88 /* HPUX by default uses an 802.3 size, and it's not evident from SIOCGIFCONF */
89  define RX_LOCAL_PACKET_SIZE    (1492 - RX_IPUDP_SIZE)   
90  define RX_REMOTE_PACKET_SIZE   (1492 - RX_IPUDP_SIZE)   
91  else
92  define RX_LOCAL_PACKET_SIZE    RX_MAX_PACKET_SIZE  /* For hosts on same net */
93  define RX_REMOTE_PACKET_SIZE   RX_MAX_PACKET_SIZE  /* see note above */
94  endif
95 #endif /* notdef */
96
97 /* These are the new, streamlined ones.
98  */
99 #define RX_HEADER_SIZE          sizeof (struct rx_header) 
100
101 /* The minimum MTU for an IP network is 576 bytes including headers */
102 #define RX_MIN_PACKET_SIZE      (576 - RX_IPUDP_SIZE)
103 #define RX_PP_PACKET_SIZE       RX_MIN_PACKET_SIZE
104
105 #define OLD_MAX_PACKET_SIZE     (1500 - RX_IPUDP_SIZE)
106
107 /* if the other guy is not on the local net, use this size */
108 #define RX_REMOTE_PACKET_SIZE   (1500 - RX_IPUDP_SIZE)   
109
110 /* for now, never send more data than this */
111 #define RX_MAX_PACKET_SIZE      16384
112 #define RX_MAX_PACKET_DATA_SIZE (16384 - RX_HEADER_SIZE) 
113
114 /* Packet types, for rx_packet.type */
115 #define RX_PACKET_TYPE_DATA         1    /* A vanilla data packet */
116 #define RX_PACKET_TYPE_ACK          2    /* Acknowledge packet */
117 #define RX_PACKET_TYPE_BUSY         3    /* Busy: can't accept call immediately; try later */
118 #define RX_PACKET_TYPE_ABORT        4    /* Abort packet.  No response needed. */
119 #define RX_PACKET_TYPE_ACKALL       5    /* Acknowledges receipt of all packets */
120 #define RX_PACKET_TYPE_CHALLENGE    6    /* Challenge client's identity: request credentials */
121 #define RX_PACKET_TYPE_RESPONSE     7    /* Respond to challenge packet */
122 #define RX_PACKET_TYPE_DEBUG        8    /* Get debug information */
123
124 #define RX_PACKET_TYPE_PARAMS       9    /* exchange size params (showUmine) */
125 #define RX_PACKET_TYPE_VERSION     13   /* get AFS version */
126
127
128 #define RX_PACKET_TYPES     {"data", "ack", "busy", "abort", "ackall", "challenge", "response", "debug", "params", "unused", "unused", "unused", "version"}
129 #define RX_N_PACKET_TYPES           13      /* Must agree with above list;
130                                                counts 0
131                                                WARNING: if this number ever
132                                                grows past 13, rxdebug packets
133                                                will need to be modified */
134
135 /* Packet classes, for rx_AllocPacket */
136 #define RX_PACKET_CLASS_RECEIVE     0
137 #define RX_PACKET_CLASS_SEND        1
138 #define RX_PACKET_CLASS_SPECIAL     2
139 #define RX_PACKET_CLASS_RECV_CBUF   3
140 #define RX_PACKET_CLASS_SEND_CBUF   4
141
142 #define RX_N_PACKET_CLASSES         5       /* Must agree with above list */
143
144 /* Flags for rx_header flags field */
145 #define RX_CLIENT_INITIATED     1   /* Packet is sent/received from client side of call */
146 #define RX_REQUEST_ACK          2   /* Peer requests acknowledgement */
147 #define RX_LAST_PACKET          4   /* This is the last packet from this side of the call */
148 #define RX_MORE_PACKETS         8   /* There are more packets following this,
149                                      * i.e. the next sequence number seen by
150                                      * the receiver should be greater than
151                                      * this one, rather than a resend of an
152                                      * earlier sequence number */
153 #define RX_FREE_PACKET          16      /* Unallocated to a call */
154 #define RX_SLOW_START_OK        32  /* Set this flag in an ack packet to
155                                      * inform the sender that slow start is
156                                      * supported by the receiver. */
157 #define RX_JUMBO_PACKET         32  /* Set this flag in a data packet to
158                                      * indicate that more packets follow
159                                      * this packet in the datagram */
160
161 /* The following flags are preset per packet, i.e. they don't change
162  * on retransmission of the packet */
163 #define RX_PRESET_FLAGS         (RX_CLIENT_INITIATED | RX_LAST_PACKET)
164
165
166 /* The rx part of the header of a packet, in host form */
167 struct rx_header {
168     afs_uint32 epoch;   /* Start time of client process */
169     afs_uint32 cid;             /* Connection id (defined by client) */
170     afs_uint32 callNumber;      /* Current call number */
171     afs_uint32 seq;             /* Sequence number of this packet, within this call */
172     afs_uint32 serial;  /* Serial number of this packet: a new serial
173                          * number is stamped on each packet sent out */
174     u_char type;        /* RX packet type */
175     u_char flags;       /* Flags, defined below */
176     u_char userStatus;  /* User defined status information,
177                          * returned/set by macros
178                          * rx_Get/SetLocal/RemoteStatus */
179     u_char securityIndex; /* Which service-defined security method to use */
180     u_short serviceId;  /* service this packet is directed _to_ */
181     /* This spare is now used for packet header checkksum.  see
182      * rxi_ReceiveDataPacket and packet cksum macros above for details. */
183     u_short spare;
184 };
185
186 /* The abbreviated header for jumbo packets. Most fields in the
187  * jumbo packet headers are either the same as or can be quickly
188  * derived from their counterparts in the main packet header.
189  */
190 struct rx_jumboHeader {
191     u_char flags;      /* Flags, defined below */
192     u_char spare1;
193     u_short cksum;     /* packet header checksum */
194 };
195
196 /* For most Unixes, maximum elements in an iovec is 16 */
197 #define RX_MAXIOVECS 16            /* limit for ReadvProc/WritevProc */
198 #define RX_MAXWVECS RX_MAXIOVECS-1 /* need one iovec for packet header */
199
200 /*
201  * The values for the RX buffer sizes are calculated to ensure efficient
202  * use of network resources when sending AFS 3.5 jumbograms over Ethernet,
203  * 802.3, FDDI, and ATM networks running IPv4 or IPv6. Changing these
204  * values may affect interoperability with AFS 3.5 clients.
205  */
206
207 /*
208  * We always transmit jumbo grams so that each packet starts at the
209  * beginning of a packet buffer. Because of the requirement that all
210  * segments of a 3.4a jumbogram contain multiples of eight bytes, the
211  * receivers iovec has RX_HEADERSIZE bytes in the first element,
212  * RX_FIRSTBUFFERSIZE bytes in the second element, and RX_CBUFFERSIZE
213  * bytes in each successive entry.  All packets in a jumbogram
214  * except for the last must contain RX_JUMBOBUFFERSIZE bytes of data
215  * so the receiver can split the AFS 3.5 jumbograms back into packets
216  * without having to copy any of the data.
217  */
218 #define RX_JUMBOBUFFERSIZE 1412
219 #define RX_JUMBOHEADERSIZE 4
220 /*
221  * RX_FIRSTBUFFERSIZE must be larger than the largest ack packet, 
222  * the largest possible challenge or response packet. 
223  * Both Firstbuffersize and cbuffersize must be integral multiples of 8,
224  * so the security header and trailer stuff works for rxkad_crypt.  yuck.
225  */
226 #define RX_FIRSTBUFFERSIZE (RX_JUMBOBUFFERSIZE+RX_JUMBOHEADERSIZE)
227 /*
228  * The size of a continuation buffer is buffer is the same as the
229  * size of the first buffer, which must also the size of a jumbo packet
230  * buffer plus the size of a jumbo packet header. */
231 #define RX_CBUFFERSIZE (RX_JUMBOBUFFERSIZE+RX_JUMBOHEADERSIZE)
232 /*
233  * Add an extra four bytes of slop at the end of each buffer.
234  */
235 #define RX_EXTRABUFFERSIZE 4
236
237 struct rx_packet {
238     struct rx_queue queueItemHeader;   /* Packets are chained using the queue.h package */
239     struct clock retryTime;         /* When this packet should NEXT be re-transmitted */
240     struct clock timeSent;          /* When this packet was transmitted last */
241     afs_uint32 firstSerial;                 /* Original serial number of this packet */
242     struct clock firstSent;         /* When this packet was transmitted first */
243     struct rx_header header;        /* The internal packet header */
244     unsigned int niovecs;
245     struct iovec wirevec[RX_MAXWVECS+1];       /* the new form of the packet */
246     
247     u_char acked;       /* This packet has been *tentatively* acknowledged */
248     u_char backoff;                 /* for multiple re-sends */
249     u_short length;                 /* Data length */
250     /* NT port relies on the fact that the next two are physically adjacent.
251      * If that assumption changes change sendmsg and recvmsg in rx_xmit_nt.c .
252      * The jumbo datagram code also relies on the next two being
253      * physically adjacent.
254      * The Linux port uses this knowledge as well in osi_NetSend.
255      */
256     afs_uint32 wirehead[RX_HEADER_SIZE/sizeof(afs_int32)];
257     afs_uint32 localdata[RX_CBUFFERSIZE/sizeof(afs_int32)]; 
258     afs_uint32 extradata[RX_EXTRABUFFERSIZE/sizeof(afs_int32)];
259 };
260
261 /* Macro to convert continuation buffer pointers to packet pointers */
262 #define RX_CBUF_TO_PACKET(CP, PP) \
263     ((struct rx_packet *) \
264      ((char *)(CP) - ((char *)(&(PP)->localdata[0])-(char *)(PP))))
265
266 /* Macros callable by security modules, to set header/trailer lengths,
267  * set actual packet size, and find the beginning of the security
268  * header (or data) */
269 #define rx_SetSecurityHeaderSize(conn, length) ((conn)->securityHeaderSize = (length))
270 #define rx_SetSecurityMaxTrailerSize(conn, length) ((conn)->securityMaxTrailerSize = (length))
271 #define rx_GetSecurityHeaderSize(conn) ((conn)->securityHeaderSize)
272 #define rx_GetSecurityMaxTrailerSize(conn) ((conn)->securityMaxTrailerSize)
273
274 /* This is the address of the data portion of the packet.  Any encryption
275  * headers will be at this address, the actual data, for a data packet, will
276  * start at this address + the connection's security header size. */
277 #define rx_DataOf(packet)               ((char *) (packet)->wirevec[1].iov_base)
278 #define rx_GetDataSize(packet)          ((packet)->length)
279 #define rx_SetDataSize(packet, size)    ((packet)->length = (size))
280
281 /* These macros used in conjunction with reuse of packet header spare as a
282  * packet cksum for rxkad security module. */
283 #define rx_GetPacketCksum(packet)        ((packet)->header.spare)
284 #define rx_SetPacketCksum(packet, cksum) ((packet)->header.spare = (cksum))
285
286 #ifdef KERNEL
287 #define rxi_OverQuota(packetclass) (rx_nFreePackets - 1 < rx_packetQuota[packetclass])
288 #endif /* KERNEL */
289
290 /* this returns an afs_int32 from byte offset o in packet p.  offset must
291  * always be aligned properly for an afs_int32, I'm leaving this up to the
292  * caller. */
293 #define rx_GetInt32(p,off) (( (off) >= (p)->wirevec[1].iov_len) ? \
294    rx_SlowGetInt32((p), (off)) :  \
295   *((afs_int32 *)((char *)((p)->wirevec[1].iov_base) + (off))))
296
297 #define rx_PutInt32(p,off,b) { \
298        if ((off) >= (p)->wirevec[1].iov_len) \
299           rx_SlowPutInt32((p), (off), (b));   \
300        else *((afs_int32 *)((char *)((p)->wirevec[1].iov_base) + (off))) = b; }
301
302 #define rx_data(p, o, l) ((l=((struct rx_packet*)(p))->wirevec[(o+1)].iov_len),\
303   (((struct rx_packet*)(p))->wirevec[(o+1)].iov_base))
304
305
306 struct rx_packet *rx_AllocPacket();
307 struct rx_packet *rxi_ReceiveDebugPacket();
308 struct rx_packet *rxi_ReceiveVersionPacket();
309 struct rx_packet *rxi_SplitJumboPacket();
310
311 /* copy data into an RX packet */
312 #define rx_packetwrite(p, off, len, in)               \
313   ( (off) + (len) > (p)->wirevec[1].iov_len ?         \
314     rx_SlowWritePacket(p, off, len, (char*)(in)) :             \
315     ((bcopy((char *)(in), (char*)((p)->wirevec[1].iov_base)+(off), (len))),0))
316
317 /* copy data from an RX packet */
318 #define rx_packetread(p, off, len, out)               \
319   ( (off) + (len) > (p)->wirevec[1].iov_len ?         \
320     rx_SlowReadPacket(p, off, len, (char*)out) :             \
321     ((bcopy((char*)((p)->wirevec[1].iov_base)+(off), (char *)(out), len)),0))
322
323 #define rx_computelen(p,l) { register int i; \
324    for (l=0, i=1; i < p->niovecs; i++ ) l += p->wirevec[i].iov_len; }
325
326 /* return what the actual contiguous space is: should be min(length,size) */
327 /* The things that call this really want something like ...pullup MTUXXX  */
328 #define rx_Contiguous(p) \
329     MIN((unsigned) (p)->length, (unsigned) ((p)->wirevec[1].iov_len))
330
331 #ifndef TRUE
332 #define TRUE 1
333 #define FALSE 0
334 #endif
335
336 /* === packet-ized down to here, the following macros work temporarily */
337 /* Unfortunately, they know that the cbuf stuff isn't there. */
338
339 /* try to ensure that rx_DataOf will return a contiguous space at
340  * least size bytes long */
341 /* return what the actual contiguous space is: should be min(length,size) */
342 #define rx_Pullup(p,size) /* this idea here is that this will make a guarantee */
343
344
345 /* The offset of the actual user's data in the packet, skipping any
346  * security header */
347 /* DEPRECATED */
348 #define rx_UserDataOf(conn, packet)     (((char *) (packet)->wirevec[1].iov_base) + (conn)->securityHeaderSize)
349
350 /* Adjust an MTU for efficient use of RX buffers */
351 extern int rxi_AdjustIfMTU(int mtu);
352 /* Adjust a maximum MTU for efficient use of RX buffers */
353 extern int rxi_AdjustMaxMTU(int mtu, int peerMaxMTU);
354 /* Figure out how many datagram packets will fit in this mtu */
355 extern int rxi_AdjustDgramPackets(int frags, int mtu);
356
357 #endif /* _RX_PACKET_ */