2 * Copyright 2000, International Business Machines Corporation and others.
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
13 #if defined(AFS_NT40_ENV)
14 #include "rx_xmit_nt.h"
18 #endif /* !AFS_NT40_ENV */
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.
35 #if defined(AFS_NT40_ENV)
37 # define MIN(a,b) ((a)<(b)?(a):(b))
40 # define MAX(a,b) ((a)>(b)?(a):(b))
42 #else /* AFS_NT40_ENV */
43 # if !defined(AFS_DARWIN_ENV) && !defined(AFS_USR_DARWIN_ENV) \
44 && !defined(AFS_XBSD_ENV) && !defined(AFS_USR_FBSD_ENV) \
45 && !defined(AFS_USR_DFBSD_ENV) && !defined(AFS_LINUX20_ENV)
46 # include <sys/sysmacros.h> /* MIN, MAX on most commercial UNIX */
48 /* Linux 3.7 doesn't have sys/param.h in kernel space, and afs/param.h ensures
49 * that MIN and MAX are available for kernel builds. */
50 # if !(defined(AFS_LINUX26_ENV) && defined(KERNEL))
51 # include <sys/param.h> /* MIN, MAX elsewhere */
53 #endif /* !AFS_NT40_ENV */
55 #define IPv6_HDR_SIZE 40 /* IPv6 Header */
56 #define IPv6_FRAG_HDR_SIZE 8 /* IPv6 Fragment Header */
57 #define UDP_HDR_SIZE 8 /* UDP Header */
58 #define RX_IP_SIZE (IPv6_HDR_SIZE + IPv6_FRAG_HDR_SIZE)
59 #define _RX_IPUDP_SIZE (RX_IP_SIZE + UDP_HDR_SIZE)
61 /* REMOTE_PACKET_SIZE is currently the same as local. This is because REMOTE
62 * is defined much too generally for my tastes, and includes the case of
63 * multiple class C nets connected with a router within one campus or MAN.
64 * I don't want to make local performance suffer just because of some
65 * out-dated protocol that used to be in use on the NSFANET that's
66 * practically unused anymore. Any modern IP implementation will be
67 * using MTU discovery, and even old routers shouldn't frag packets
68 * when sending from one connected network directly to another. Maybe
69 * the next release of RX will do MTU discovery. */
71 /* MTUXXX the various "MAX" params here must be rationalized. From now on,
72 * the MAX packet size will be the maximum receive size, but the maximum send
73 * size will be larger than that. */
76 4352 what FDDI(RFC1188) uses... Larger?
77 4096 VJ's recommendation for FDDI
78 17914 what IBM 16MB TR uses
81 2002 IEEE 802.5 Recommended
82 1500 what Ethernet uses
83 1492 what 802.3 uses ( 8 bytes for 802.2 SAP )
84 9180 Classical IP over ATM (RFC2225)
87 #define RX_HEADER_SIZE sizeof (struct rx_header)
89 /* The minimum MTU for an IP network is 576 bytes including headers */
90 #define RX_MIN_PACKET_SIZE (576 - RX_IPUDP_SIZE)
91 #define RX_PP_PACKET_SIZE RX_MIN_PACKET_SIZE
92 #define _RX_MIN_PACKET_SIZE (576 - _RX_IPUDP_SIZE)
93 #define _RX_PP_PACKET_SIZE _RX_MIN_PACKET_SIZE
95 #define OLD_MAX_PACKET_SIZE (1500 - RX_IPUDP_SIZE)
96 #define _OLD_MAX_PACKET_SIZE (1500 - _RX_IPUDP_SIZE)
98 /* if the other guy is not on the local net, use this size */
99 #define RX_REMOTE_PACKET_SIZE (1500 - RX_IPUDP_SIZE)
100 #define _RX_REMOTE_PACKET_SIZE (1500 - _RX_IPUDP_SIZE)
102 /* for now, never send more data than this */
103 #define RX_MAX_PACKET_SIZE 16384
104 #define RX_MAX_PACKET_DATA_SIZE (16384 - RX_HEADER_SIZE)
106 /* Packet types, for rx_packet.type */
107 #define RX_PACKET_TYPE_DATA 1 /* A vanilla data packet */
108 #define RX_PACKET_TYPE_ACK 2 /* Acknowledge packet */
109 #define RX_PACKET_TYPE_BUSY 3 /* Busy: can't accept call immediately; try later */
110 #define RX_PACKET_TYPE_ABORT 4 /* Abort packet. No response needed. */
111 #define RX_PACKET_TYPE_ACKALL 5 /* Acknowledges receipt of all packets */
112 #define RX_PACKET_TYPE_CHALLENGE 6 /* Challenge client's identity: request credentials */
113 #define RX_PACKET_TYPE_RESPONSE 7 /* Respond to challenge packet */
114 #define RX_PACKET_TYPE_DEBUG 8 /* Get debug information */
116 #define RX_PACKET_TYPE_PARAMS 9 /* exchange size params (showUmine) */
117 #define RX_PACKET_TYPE_VERSION 13 /* get AFS version */
119 /* Flags for rx_header flags field */
120 #define RX_CLIENT_INITIATED 1 /* Packet is sent/received from client side of call */
121 #define RX_REQUEST_ACK 2 /* Peer requests acknowledgement */
122 #define RX_LAST_PACKET 4 /* This is the last packet from this side of the call */
123 #define RX_MORE_PACKETS 8 /* There are more packets following this,
124 * i.e. the next sequence number seen by
125 * the receiver should be greater than
126 * this one, rather than a resend of an
127 * earlier sequence number */
128 #define RX_SLOW_START_OK 32 /* Set this flag in an ack packet to
129 * inform the sender that slow start is
130 * supported by the receiver. */
131 #define RX_JUMBO_PACKET 32 /* Set this flag in a data packet to
132 * indicate that more packets follow
133 * this packet in the datagram */
135 /* The following flags are preset per packet, i.e. they don't change
136 * on retransmission of the packet */
137 #define RX_PRESET_FLAGS (RX_CLIENT_INITIATED | RX_LAST_PACKET)
141 * Flags for the packet structure itself, housekeeping for the
142 * most part. These live in rx_packet->flags.
144 #define RX_PKTFLAG_ACKED 0x01
145 #ifdef RX_TRACK_PACKETS
146 #define RX_PKTFLAG_FREE 0x02
147 #define RX_PKTFLAG_TQ 0x04
148 #define RX_PKTFLAG_RQ 0x08
149 #define RX_PKTFLAG_IOVQ 0x10
150 #define RX_PKTFLAG_CP 0x20
152 #define RX_PKTFLAG_SENT 0x40
154 /* The rx part of the header of a packet, in host form */
156 afs_uint32 epoch; /* Start time of client process */
157 afs_uint32 cid; /* Connection id (defined by client) */
158 afs_uint32 callNumber; /* Current call number */
159 afs_uint32 seq; /* Sequence number of this packet, within this call */
160 afs_uint32 serial; /* Serial number of this packet: a new serial
161 * number is stamped on each packet sent out */
162 u_char type; /* RX packet type */
163 u_char flags; /* Flags, defined below */
164 u_char userStatus; /* User defined status information,
165 * returned/set by macros
166 * rx_Get/SetLocal/RemoteStatus */
167 u_char securityIndex; /* Which service-defined security method to use */
168 u_short serviceId; /* service this packet is directed _to_ */
169 /* This spare is now used for packet header checkksum. see
170 * rxi_ReceiveDataPacket and packet cksum macros above for details. */
174 /* The abbreviated header for jumbo packets. Most fields in the
175 * jumbo packet headers are either the same as or can be quickly
176 * derived from their counterparts in the main packet header.
178 struct rx_jumboHeader {
179 u_char flags; /* Flags, defined below */
181 u_short cksum; /* packet header checksum */
187 * The values for the RX buffer sizes are calculated to ensure efficient
188 * use of network resources when sending AFS 3.5 jumbograms over Ethernet,
189 * 802.3, FDDI, and ATM networks running IPv4 or IPv6. Changing these
190 * values may affect interoperability with AFS 3.5 clients.
194 * We always transmit jumbo grams so that each packet starts at the
195 * beginning of a packet buffer. Because of the requirement that all
196 * segments of a 3.4a jumbogram contain multiples of eight bytes, the
197 * receivers iovec has RX_HEADERSIZE bytes in the first element,
198 * RX_FIRSTBUFFERSIZE bytes in the second element, and RX_CBUFFERSIZE
199 * bytes in each successive entry. All packets in a jumbogram
200 * except for the last must contain RX_JUMBOBUFFERSIZE bytes of data
201 * so the receiver can split the AFS 3.5 jumbograms back into packets
202 * without having to copy any of the data.
204 #define RX_JUMBOBUFFERSIZE 1412
205 #define RX_JUMBOHEADERSIZE 4
207 * RX_FIRSTBUFFERSIZE must be larger than the largest ack packet,
208 * the largest possible challenge or response packet.
209 * Both Firstbuffersize and cbuffersize must be integral multiples of 8,
210 * so the security header and trailer stuff works for rxkad_crypt. yuck.
212 #define RX_FIRSTBUFFERSIZE (RX_JUMBOBUFFERSIZE+RX_JUMBOHEADERSIZE)
214 * The size of a continuation buffer is buffer is the same as the
215 * size of the first buffer, which must also the size of a jumbo packet
216 * buffer plus the size of a jumbo packet header. */
217 #define RX_CBUFFERSIZE (RX_JUMBOBUFFERSIZE+RX_JUMBOHEADERSIZE)
219 * Add an extra four bytes of slop at the end of each buffer.
221 #define RX_EXTRABUFFERSIZE 4
224 #error RX_MAXWVECS not defined
228 struct opr_queue entry; /* Packets are chained using opr_queue */
229 struct clock timeSent; /* When this packet was transmitted last */
230 afs_uint32 firstSerial; /* Original serial number of this packet */
231 struct clock firstSent; /* When this packet was transmitted first */
232 struct rx_header header; /* The internal packet header */
233 unsigned int niovecs; /* # of iovecs that potentially have data */
234 unsigned int aiovecs; /* # of allocated iovecs */
235 struct iovec wirevec[RX_MAXWVECS + 1]; /* the new form of the packet */
237 u_char flags; /* Flags for local state of this packet */
238 u_char unused; /* was backoff, now just here for alignment */
239 u_short length; /* Data length */
240 /* NT port relies on the fact that the next two are physically adjacent.
241 * If that assumption changes change sendmsg and recvmsg in rx_xmit_nt.c .
242 * The jumbo datagram code also relies on the next two being
243 * physically adjacent.
244 * The Linux port uses this knowledge as well in osi_NetSend.
246 * The extradata field is padding in case the recvmsg implementation
247 * writes beyond the end of the final iovec buffer. We do not know
248 * what platforms had this problem so we are reluctant to remove it.
249 * the extradata must be adjacent to localdata.
250 * See rxk_ReadPacket and rxi_ReadPacket.
252 afs_uint32 wirehead[RX_HEADER_SIZE / sizeof(afs_int32)];
253 afs_uint32 localdata[RX_CBUFFERSIZE / sizeof(afs_int32)];
254 afs_uint32 extradata[RX_EXTRABUFFERSIZE / sizeof(afs_int32)];
256 #ifdef RXDEBUG_PACKET
258 struct rx_packet *allNextp; /* A list of all packets */
259 afs_uint32 packetId; /* An unique id number for debugging */
263 /* Macro to convert continuation buffer pointers to packet pointers */
264 #define RX_CBUF_TO_PACKET(CP, PP) \
265 ((struct rx_packet *) \
266 ((char *)(CP) - ((char *)(&(PP)->localdata[0])-(char *)(PP))))
268 /* This is the address of the data portion of the packet. Any encryption
269 * headers will be at this address, the actual data, for a data packet, will
270 * start at this address + the connection's security header size. */
271 #define rx_DataOf(packet) ((char *) (packet)->wirevec[1].iov_base)
272 #define rx_GetDataSize(packet) ((packet)->length)
273 #define rx_SetDataSize(packet, size) ((packet)->length = (size))
275 /* These macros used in conjunction with reuse of packet header spare as a
276 * packet cksum for rxkad security module. */
277 #define rx_GetPacketCksum(packet) ((packet)->header.spare)
278 #define rx_SetPacketCksum(packet, cksum) ((packet)->header.spare = (cksum))
281 #define rxi_OverQuota(packetclass) (rx_nFreePackets - 1 < rx_packetQuota[packetclass])
282 #define rxi_OverQuota2(packetclass,num_alloc) (rx_nFreePackets - (num_alloc) < rx_packetQuota[packetclass])
285 /* this returns an afs_int32 from byte offset o in packet p. offset must
286 * always be aligned properly for an afs_int32, I'm leaving this up to the
288 #define rx_GetInt32(p,off) (( (off) >= (p)->wirevec[1].iov_len) ? \
289 rx_SlowGetInt32((p), (off)) : \
290 *((afs_int32 *)((char *)((p)->wirevec[1].iov_base) + (off))))
292 #define rx_PutInt32(p,off,b) { \
293 if ((off) >= (p)->wirevec[1].iov_len) \
294 rx_SlowPutInt32((p), (off), (b)); \
295 else *((afs_int32 *)((char *)((p)->wirevec[1].iov_base) + (off))) = b; }
297 #define rx_data(p, o, l) ((l=((struct rx_packet*)(p))->wirevec[(o+1)].iov_len),\
298 (((struct rx_packet*)(p))->wirevec[(o+1)].iov_base))
301 /* copy data into an RX packet */
302 #define rx_packetwrite(p, off, len, in) \
303 ( (off) + (len) > (p)->wirevec[1].iov_len ? \
304 rx_SlowWritePacket(p, off, len, (char*)(in)) : \
305 ((memcpy((char*)((p)->wirevec[1].iov_base)+(off), (char *)(in), (len))),0))
307 /* copy data from an RX packet */
308 #define rx_packetread(p, off, len, out) \
309 ( (off) + (len) > (p)->wirevec[1].iov_len ? \
310 rx_SlowReadPacket(p, off, len, (char*)(out)) : \
311 ((memcpy((char *)(out), (char*)((p)->wirevec[1].iov_base)+(off), (len))),0))
313 #define rx_computelen(p,l) { unsigned int i; \
314 for (l=0, i=1; i < p->niovecs; i++ ) l += p->wirevec[i].iov_len; }
316 /* return what the actual contiguous space is: should be min(length,size) */
317 /* The things that call this really want something like ...pullup MTUXXX */
318 #define rx_Contiguous(p) \
319 MIN((unsigned) (p)->length, (unsigned) ((p)->wirevec[1].iov_len))
326 /* === packet-ized down to here, the following macros work temporarily */
327 /* Unfortunately, they know that the cbuf stuff isn't there. */
329 /* try to ensure that rx_DataOf will return a contiguous space at
330 * least size bytes long */
331 /* return what the actual contiguous space is: should be min(length,size) */
332 #define rx_Pullup(p,size) /* this idea here is that this will make a guarantee */
335 /* The offset of the actual user's data in the packet, skipping any
338 #define rx_UserDataOf(conn, packet) (((char *) (packet)->wirevec[1].iov_base) + (conn)->securityHeaderSize)
341 /* Debugging for Windows Cache Manager - fs memdump */
342 int rx_DumpPackets(FILE *outputFile, char *cookie);
343 #endif /* AFS_NT40_ENV */
345 #endif /* _RX_PACKET_ */