OpenAFS
OpenAFS distributed network file system
|
00001 /* 00002 * Copyright 2000, International Business Machines Corporation and others. 00003 * All Rights Reserved. 00004 * 00005 * This software has been released under the terms of the IBM Public 00006 * License. For details, see the LICENSE file in the top-level source 00007 * directory or online at http://www.openafs.org/dl/license10.html 00008 */ 00009 00010 #ifndef _RX_PACKET_ 00011 #define _RX_PACKET_ 00012 00013 #include "rx_queue.h" 00014 00015 #if defined(AFS_NT40_ENV) 00016 #include "rx_xmit_nt.h" 00017 #endif 00018 #ifndef AFS_NT40_ENV 00019 #include <sys/uio.h> 00020 #endif /* !AFS_NT40_ENV */ 00021 /* this file includes the macros and decls which depend on packet 00022 * format, and related packet manipulation macros. Note that code 00023 * which runs at NETPRI should not sleep, or AIX will panic */ 00024 /* There are some assumptions that various code makes -- I'll try to 00025 * express them all here: 00026 * 1. rx_ReceiveAckPacket assumes that it can get an entire ack 00027 * contiguous in the first iovec. As a result, the iovec buffers must 00028 * be >= sizeof (struct rx_ackpacket) 00029 * 2. All callers of rx_Pullup besides rx_ReceiveAckPacket try to pull 00030 * up less data than rx_ReceiveAckPacket does. 00031 * 3. rx_GetInt32 and rx_PutInt32 (and the slow versions of same) assume 00032 * that the iovec buffers are all integral multiples of the word size, 00033 * and that the offsets are as well. 00034 */ 00035 00036 00037 #if defined(AFS_NT40_ENV) 00038 #ifndef MIN 00039 #define MIN(a,b) ((a)<(b)?(a):(b)) 00040 #endif 00041 #ifndef MAX 00042 #define MAX(a,b) ((a)>(b)?(a):(b)) 00043 #endif 00044 #else /* AFS_NT40_ENV */ 00045 #if !defined(AFS_DARWIN_ENV) && !defined(AFS_USR_DARWIN_ENV) && !defined(AFS_XBSD_ENV) && !defined(AFS_USR_FBSD_ENV) && !defined(AFS_USR_DFBSD_ENV) && !defined(AFS_LINUX20_ENV) 00046 #include <sys/sysmacros.h> /* MIN, MAX on Solaris */ 00047 #endif 00048 #include <sys/param.h> /* MIN, MAX elsewhere */ 00049 #endif /* AFS_NT40_ENV */ 00050 00051 #define IPv6_HDR_SIZE 40 /* IPv6 Header */ 00052 #define IPv6_FRAG_HDR_SIZE 8 /* IPv6 Fragment Header */ 00053 #define UDP_HDR_SIZE 8 /* UDP Header */ 00054 #define RX_IP_SIZE (IPv6_HDR_SIZE + IPv6_FRAG_HDR_SIZE) 00055 #define _RX_IPUDP_SIZE (RX_IP_SIZE + UDP_HDR_SIZE) 00056 00057 /* REMOTE_PACKET_SIZE is currently the same as local. This is because REMOTE 00058 * is defined much too generally for my tastes, and includes the case of 00059 * multiple class C nets connected with a router within one campus or MAN. 00060 * I don't want to make local performance suffer just because of some 00061 * out-dated protocol that used to be in use on the NSFANET that's 00062 * practically unused anymore. Any modern IP implementation will be 00063 * using MTU discovery, and even old routers shouldn't frag packets 00064 * when sending from one connected network directly to another. Maybe 00065 * the next release of RX will do MTU discovery. */ 00066 00067 /* MTUXXX the various "MAX" params here must be rationalized. From now on, 00068 * the MAX packet size will be the maximum receive size, but the maximum send 00069 * size will be larger than that. */ 00070 00071 #ifdef notdef 00072 /* some sample MTUs 00073 4352 what FDDI(RFC1188) uses... Larger? 00074 4096 VJ's recommendation for FDDI 00075 17914 what IBM 16MB TR uses 00076 8166 IEEE 802.4 00077 4464 IEEE 802.5 MAX 00078 2002 IEEE 802.5 Recommended 00079 1500 what Ethernet uses 00080 1492 what 802.3 uses ( 8 bytes for 802.2 SAP ) 00081 9180 Classical IP over ATM (RFC2225) 00082 */ 00083 00084 /* * * * these are the old defines 00085 */ 00086 #define RX_MAX_PACKET_SIZE (RX_MAX_DL_MTU -RX_IPUDP_SIZE) 00087 00088 #define RX_MAX_PACKET_DATA_SIZE (RX_MAX_PACKET_SIZE-RX_HEADER_SIZE) 00089 #ifdef AFS_HPUX_ENV 00090 /* HPUX by default uses an 802.3 size, and it's not evident from SIOCGIFCONF */ 00091 #define RX_LOCAL_PACKET_SIZE (1492 - RX_IPUDP_SIZE) 00092 #define RX_REMOTE_PACKET_SIZE (1492 - RX_IPUDP_SIZE) 00093 #else 00094 #define RX_LOCAL_PACKET_SIZE RX_MAX_PACKET_SIZE /* For hosts on same net */ 00095 #define RX_REMOTE_PACKET_SIZE RX_MAX_PACKET_SIZE /* see note above */ 00096 #endif 00097 #endif /* notdef */ 00098 00099 /* These are the new, streamlined ones. 00100 */ 00101 #define RX_HEADER_SIZE sizeof (struct rx_header) 00102 00103 /* The minimum MTU for an IP network is 576 bytes including headers */ 00104 #define RX_MIN_PACKET_SIZE (576 - RX_IPUDP_SIZE) 00105 #define RX_PP_PACKET_SIZE RX_MIN_PACKET_SIZE 00106 #define _RX_MIN_PACKET_SIZE (576 - _RX_IPUDP_SIZE) 00107 #define _RX_PP_PACKET_SIZE _RX_MIN_PACKET_SIZE 00108 00109 #define OLD_MAX_PACKET_SIZE (1500 - RX_IPUDP_SIZE) 00110 #define _OLD_MAX_PACKET_SIZE (1500 - _RX_IPUDP_SIZE) 00111 00112 /* if the other guy is not on the local net, use this size */ 00113 #define RX_REMOTE_PACKET_SIZE (1500 - RX_IPUDP_SIZE) 00114 #define _RX_REMOTE_PACKET_SIZE (1500 - _RX_IPUDP_SIZE) 00115 00116 /* for now, never send more data than this */ 00117 #define RX_MAX_PACKET_SIZE 16384 00118 #define RX_MAX_PACKET_DATA_SIZE (16384 - RX_HEADER_SIZE) 00119 00120 /* Packet types, for rx_packet.type */ 00121 #define RX_PACKET_TYPE_DATA 1 /* A vanilla data packet */ 00122 #define RX_PACKET_TYPE_ACK 2 /* Acknowledge packet */ 00123 #define RX_PACKET_TYPE_BUSY 3 /* Busy: can't accept call immediately; try later */ 00124 #define RX_PACKET_TYPE_ABORT 4 /* Abort packet. No response needed. */ 00125 #define RX_PACKET_TYPE_ACKALL 5 /* Acknowledges receipt of all packets */ 00126 #define RX_PACKET_TYPE_CHALLENGE 6 /* Challenge client's identity: request credentials */ 00127 #define RX_PACKET_TYPE_RESPONSE 7 /* Respond to challenge packet */ 00128 #define RX_PACKET_TYPE_DEBUG 8 /* Get debug information */ 00129 00130 #define RX_PACKET_TYPE_PARAMS 9 /* exchange size params (showUmine) */ 00131 #define RX_PACKET_TYPE_VERSION 13 /* get AFS version */ 00132 00133 /* Flags for rx_header flags field */ 00134 #define RX_CLIENT_INITIATED 1 /* Packet is sent/received from client side of call */ 00135 #define RX_REQUEST_ACK 2 /* Peer requests acknowledgement */ 00136 #define RX_LAST_PACKET 4 /* This is the last packet from this side of the call */ 00137 #define RX_MORE_PACKETS 8 /* There are more packets following this, 00138 * i.e. the next sequence number seen by 00139 * the receiver should be greater than 00140 * this one, rather than a resend of an 00141 * earlier sequence number */ 00142 #define RX_SLOW_START_OK 32 /* Set this flag in an ack packet to 00143 * inform the sender that slow start is 00144 * supported by the receiver. */ 00145 #define RX_JUMBO_PACKET 32 /* Set this flag in a data packet to 00146 * indicate that more packets follow 00147 * this packet in the datagram */ 00148 00149 /* The following flags are preset per packet, i.e. they don't change 00150 * on retransmission of the packet */ 00151 #define RX_PRESET_FLAGS (RX_CLIENT_INITIATED | RX_LAST_PACKET) 00152 00153 00154 /* 00155 * Flags for the packet structure itself, housekeeping for the 00156 * most part. These live in rx_packet->flags. 00157 */ 00158 #define RX_PKTFLAG_ACKED 0x01 00159 #ifdef RX_TRACK_PACKETS 00160 #define RX_PKTFLAG_FREE 0x02 00161 #define RX_PKTFLAG_TQ 0x04 00162 #define RX_PKTFLAG_RQ 0x08 00163 #define RX_PKTFLAG_IOVQ 0x10 00164 #define RX_PKTFLAG_CP 0x20 00165 #endif 00166 #define RX_PKTFLAG_SENT 0x40 00167 00168 /* The rx part of the header of a packet, in host form */ 00169 struct rx_header { 00170 afs_uint32 epoch; /* Start time of client process */ 00171 afs_uint32 cid; /* Connection id (defined by client) */ 00172 afs_uint32 callNumber; /* Current call number */ 00173 afs_uint32 seq; /* Sequence number of this packet, within this call */ 00174 afs_uint32 serial; /* Serial number of this packet: a new serial 00175 * number is stamped on each packet sent out */ 00176 u_char type; /* RX packet type */ 00177 u_char flags; /* Flags, defined below */ 00178 u_char userStatus; /* User defined status information, 00179 * returned/set by macros 00180 * rx_Get/SetLocal/RemoteStatus */ 00181 u_char securityIndex; /* Which service-defined security method to use */ 00182 u_short serviceId; /* service this packet is directed _to_ */ 00183 /* This spare is now used for packet header checkksum. see 00184 * rxi_ReceiveDataPacket and packet cksum macros above for details. */ 00185 u_short spare; 00186 }; 00187 00188 /* The abbreviated header for jumbo packets. Most fields in the 00189 * jumbo packet headers are either the same as or can be quickly 00190 * derived from their counterparts in the main packet header. 00191 */ 00192 struct rx_jumboHeader { 00193 u_char flags; /* Flags, defined below */ 00194 u_char spare1; 00195 u_short cksum; /* packet header checksum */ 00196 }; 00197 00198 00199 00200 /* 00201 * The values for the RX buffer sizes are calculated to ensure efficient 00202 * use of network resources when sending AFS 3.5 jumbograms over Ethernet, 00203 * 802.3, FDDI, and ATM networks running IPv4 or IPv6. Changing these 00204 * values may affect interoperability with AFS 3.5 clients. 00205 */ 00206 00207 /* 00208 * We always transmit jumbo grams so that each packet starts at the 00209 * beginning of a packet buffer. Because of the requirement that all 00210 * segments of a 3.4a jumbogram contain multiples of eight bytes, the 00211 * receivers iovec has RX_HEADERSIZE bytes in the first element, 00212 * RX_FIRSTBUFFERSIZE bytes in the second element, and RX_CBUFFERSIZE 00213 * bytes in each successive entry. All packets in a jumbogram 00214 * except for the last must contain RX_JUMBOBUFFERSIZE bytes of data 00215 * so the receiver can split the AFS 3.5 jumbograms back into packets 00216 * without having to copy any of the data. 00217 */ 00218 #define RX_JUMBOBUFFERSIZE 1412 00219 #define RX_JUMBOHEADERSIZE 4 00220 /* 00221 * RX_FIRSTBUFFERSIZE must be larger than the largest ack packet, 00222 * the largest possible challenge or response packet. 00223 * Both Firstbuffersize and cbuffersize must be integral multiples of 8, 00224 * so the security header and trailer stuff works for rxkad_crypt. yuck. 00225 */ 00226 #define RX_FIRSTBUFFERSIZE (RX_JUMBOBUFFERSIZE+RX_JUMBOHEADERSIZE) 00227 /* 00228 * The size of a continuation buffer is buffer is the same as the 00229 * size of the first buffer, which must also the size of a jumbo packet 00230 * buffer plus the size of a jumbo packet header. */ 00231 #define RX_CBUFFERSIZE (RX_JUMBOBUFFERSIZE+RX_JUMBOHEADERSIZE) 00232 /* 00233 * Add an extra four bytes of slop at the end of each buffer. 00234 */ 00235 #define RX_EXTRABUFFERSIZE 4 00236 00237 #ifndef RX_MAXWVECS 00238 #error RX_MAXWVECS not defined 00239 #endif 00240 00241 struct rx_packet { 00242 struct rx_queue queueItemHeader; /* Packets are chained using the queue.h package */ 00243 struct clock timeSent; /* When this packet was transmitted last */ 00244 afs_uint32 firstSerial; /* Original serial number of this packet */ 00245 struct clock firstSent; /* When this packet was transmitted first */ 00246 struct rx_header header; /* The internal packet header */ 00247 unsigned int niovecs; /* # of iovecs that potentially have data */ 00248 unsigned int aiovecs; /* # of allocated iovecs */ 00249 struct iovec wirevec[RX_MAXWVECS + 1]; /* the new form of the packet */ 00250 00251 u_char flags; /* Flags for local state of this packet */ 00252 u_char unused; /* was backoff, now just here for alignment */ 00253 u_short length; /* Data length */ 00254 /* NT port relies on the fact that the next two are physically adjacent. 00255 * If that assumption changes change sendmsg and recvmsg in rx_xmit_nt.c . 00256 * The jumbo datagram code also relies on the next two being 00257 * physically adjacent. 00258 * The Linux port uses this knowledge as well in osi_NetSend. 00259 * 00260 * The extradata field is padding in case the recvmsg implementation 00261 * writes beyond the end of the final iovec buffer. We do not know 00262 * what platforms had this problem so we are reluctant to remove it. 00263 * the extradata must be adjacent to localdata. 00264 * See rxk_ReadPacket and rxi_ReadPacket. 00265 */ 00266 afs_uint32 wirehead[RX_HEADER_SIZE / sizeof(afs_int32)]; 00267 afs_uint32 localdata[RX_CBUFFERSIZE / sizeof(afs_int32)]; 00268 afs_uint32 extradata[RX_EXTRABUFFERSIZE / sizeof(afs_int32)]; 00269 00270 #ifdef RXDEBUG_PACKET 00271 /* For debugging */ 00272 struct rx_packet *allNextp; /* A list of all packets */ 00273 afs_uint32 packetId; /* An unique id number for debugging */ 00274 #endif 00275 }; 00276 00277 /* Macro to convert continuation buffer pointers to packet pointers */ 00278 #define RX_CBUF_TO_PACKET(CP, PP) \ 00279 ((struct rx_packet *) \ 00280 ((char *)(CP) - ((char *)(&(PP)->localdata[0])-(char *)(PP)))) 00281 00282 /* This is the address of the data portion of the packet. Any encryption 00283 * headers will be at this address, the actual data, for a data packet, will 00284 * start at this address + the connection's security header size. */ 00285 #define rx_DataOf(packet) ((char *) (packet)->wirevec[1].iov_base) 00286 #define rx_GetDataSize(packet) ((packet)->length) 00287 #define rx_SetDataSize(packet, size) ((packet)->length = (size)) 00288 00289 /* These macros used in conjunction with reuse of packet header spare as a 00290 * packet cksum for rxkad security module. */ 00291 #define rx_GetPacketCksum(packet) ((packet)->header.spare) 00292 #define rx_SetPacketCksum(packet, cksum) ((packet)->header.spare = (cksum)) 00293 00294 #ifdef KERNEL 00295 #define rxi_OverQuota(packetclass) (rx_nFreePackets - 1 < rx_packetQuota[packetclass]) 00296 #define rxi_OverQuota2(packetclass,num_alloc) (rx_nFreePackets - (num_alloc) < rx_packetQuota[packetclass]) 00297 #endif /* KERNEL */ 00298 00299 /* this returns an afs_int32 from byte offset o in packet p. offset must 00300 * always be aligned properly for an afs_int32, I'm leaving this up to the 00301 * caller. */ 00302 #define rx_GetInt32(p,off) (( (off) >= (p)->wirevec[1].iov_len) ? \ 00303 rx_SlowGetInt32((p), (off)) : \ 00304 *((afs_int32 *)((char *)((p)->wirevec[1].iov_base) + (off)))) 00305 00306 #define rx_PutInt32(p,off,b) { \ 00307 if ((off) >= (p)->wirevec[1].iov_len) \ 00308 rx_SlowPutInt32((p), (off), (b)); \ 00309 else *((afs_int32 *)((char *)((p)->wirevec[1].iov_base) + (off))) = b; } 00310 00311 #define rx_data(p, o, l) ((l=((struct rx_packet*)(p))->wirevec[(o+1)].iov_len),\ 00312 (((struct rx_packet*)(p))->wirevec[(o+1)].iov_base)) 00313 00314 00315 /* copy data into an RX packet */ 00316 #define rx_packetwrite(p, off, len, in) \ 00317 ( (off) + (len) > (p)->wirevec[1].iov_len ? \ 00318 rx_SlowWritePacket(p, off, len, (char*)(in)) : \ 00319 ((memcpy((char*)((p)->wirevec[1].iov_base)+(off), (char *)(in), (len))),0)) 00320 00321 /* copy data from an RX packet */ 00322 #define rx_packetread(p, off, len, out) \ 00323 ( (off) + (len) > (p)->wirevec[1].iov_len ? \ 00324 rx_SlowReadPacket(p, off, len, (char*)(out)) : \ 00325 ((memcpy((char *)(out), (char*)((p)->wirevec[1].iov_base)+(off), (len))),0)) 00326 00327 #define rx_computelen(p,l) { unsigned int i; \ 00328 for (l=0, i=1; i < p->niovecs; i++ ) l += p->wirevec[i].iov_len; } 00329 00330 /* return what the actual contiguous space is: should be min(length,size) */ 00331 /* The things that call this really want something like ...pullup MTUXXX */ 00332 #define rx_Contiguous(p) \ 00333 MIN((unsigned) (p)->length, (unsigned) ((p)->wirevec[1].iov_len)) 00334 00335 #ifndef TRUE 00336 #define TRUE 1 00337 #define FALSE 0 00338 #endif 00339 00340 /* === packet-ized down to here, the following macros work temporarily */ 00341 /* Unfortunately, they know that the cbuf stuff isn't there. */ 00342 00343 /* try to ensure that rx_DataOf will return a contiguous space at 00344 * least size bytes long */ 00345 /* return what the actual contiguous space is: should be min(length,size) */ 00346 #define rx_Pullup(p,size) /* this idea here is that this will make a guarantee */ 00347 00348 00349 /* The offset of the actual user's data in the packet, skipping any 00350 * security header */ 00351 /* DEPRECATED */ 00352 #define rx_UserDataOf(conn, packet) (((char *) (packet)->wirevec[1].iov_base) + (conn)->securityHeaderSize) 00353 00354 #ifdef AFS_NT40_ENV 00355 /* Debugging for Windows Cache Manager - fs memdump */ 00356 int rx_DumpPackets(FILE *outputFile, char *cookie); 00357 #endif /* AFS_NT40_ENV */ 00358 00359 #endif /* _RX_PACKET_ */