================================================= UDP-Lite Howto (kernel and userland applications) ================================================= This file describes how to build a UDP-Lite enabled kernel and how to compile the applications that are included in this package. I) KERNEL COMPILATION UDP-Lite is now in the mainline kernel: obtain the latest version of a 2.6.20 Linux kernel from (a mirror of) www.kernel.org and compile. There is nothing else required to do. II) PROGRAMMING API UDP-Lite provides a connectionless, unreliable datagram service and hence uses the same socket type as UDP. In fact, porting from UDP to UDP-Lite is dead easy: simply add `IPPROTO_UDPLITE' as the last argument of the socket(2) call so that the statement looks like: s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE); or, respectively, s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE); Since both UDP-Litev4 and UDP-Litev6 are supported, the porting process is the same in both occasions. With just this change you are able to run UDP-Lite services or connect to UDP-Lite servers. The kernel will assume that you are not interested in using partial checksum coverage and so emulate UDP mode. To make use of the partial checksum coverage facilities requires setting just one socket option which takes an integer specifying the coverage length: * Sender checksum coverage: UDPLITE_SEND_CSCOV For example, int val = 20; setsockopt(s, SOL_UDPLITE, UDPLITE_SEND_CSCOV, &val, sizeof(int)); sets the checksum coverage length to 20 bytes (12b data + 8b header). Of each packet only the first 20 bytes (plus the pseudo-header) will be checksummed. This is useful for RTP applications which have a 12-byte base header. * Receiver checksum coverage: UDPLITE_RECV_CSCOV This option is the receiver-side analogue. It is truly optional, i.e. not required to enable traffic with partial checksum coverage. Its function is that of a traffic filter: when enabled, it instructs the kernel to drop all packets which have a coverage _less_ than this value. For example, if RTP and UDP headers are to be protected, a receiver can enforce that only packets with a minimum coverage of 20 are admitted: int min = 20; setsockopt(s, SOL_UDPLITE, UDPLITE_RECV_CSCOV, &min, sizeof(int)); The calls to getsockopt(2) are analogous. Being an extension and not a stand- alone protocol, all socket options known from UDP can be used in exactly the same manner as before, e.g. UDP_CORK or UDP_ENCAP. A detailed discussion of UDP-Lite checksum coverage options is in section V. III) HEADER FILES AND PROTOCOL IDENTIFICATION The socket API requires support in two /usr/include header files: * netinet/udplite.h This file is new and provided in the header_files directory. * netinet/in.h requires two new lines, see README in the header_files directory. If your /etc/protocols is up-to-date, it should contain an `udplite' line, run the following to make getprotobyname(3), getprotobynumber(3) work: file=/etc/protocols; grep -q ^udplite $file || \ echo 'udplite 136 UDP-Lite # UDP-Lite [RFC 3828]' >> $file Having done that, you can now refer to the protocol as `udplite', e.g. #include struct protoent *p; p = getprotobyname("udplite"); /* p = getprotobynumber(136); */ if(p) { printf("%s: %d\n", p->p_name, p->p_proto); while(*p->p_aliases) puts(*(p->p_aliases++)); } IV) APPLICATIONS Bundled with this package are three applications: (1) Client-Server application (IPv6 enabled) A README is included in the source directory. Type `make' to build, start the server with ./udpserver& and the client with ./udpclient There is also a Perl variant of this application, for fun. (2) The sock program [originally by W. Richard Stevens, "TCP/IP Illustrated Vol. 1"] This is a useful testing tool, since many options can be influenced via the commandline. See the README in the apps/sock directory. (3) The ttcp network testing program This is a classic (see http://ftp.arl.mil/~mike/ttcp.html), the patched version is UDP-Lite ready. (4) Video LAN Client for streaming multimedia over UDP Lite A patch and instructions are provided to replace UDP with UDP-Lite as streaming transport protocol, see the README file in the apps/vlc directory. Using this, we have been able to successfully stream MPEG-files, audio files, DVD and the like. These sources can be used as inspiration to build own applications. If you have performed the above header file modifications, no further changes are necessary to build UDP-Lite applications. You can test if there is support for UDP-Lite by using the conditional #ifdef IPPROTO_UDPLITE /* UDP-Lite specific code goes here */ #endif This works by including netinet/in.h (which is included by default in most socket applications), where this constant is defined. V) KERNEL BEHAVIOUR WITH REGARD TO THE VARIOUS SOCKET OPTIONS To enable debugging messages, the log level must be set to 8, as most messages use the KERN_DEBUG level (7). 1) Sender Socket Options If the sender specifies a value of 0 as coverage length, the module assumes full coverage, transmits a packet with coverage length of 0 and according checksum. If the sender specifies a coverage < 8 and different from 0, the kernel assumes 8 as default value. Finally, if the specified coverage length exceeds the packet length, the packet length is used instead as coverage length. 2) Receiver Socket Options The receiver specifies the minimum value of the coverage length it is willing to accept. A value of 0 here indicates that the receiver always wants the whole of the packet covered. In this case, all partially covered packets are dropped and an error is logged. It is not possible to specify illegal values (<0 and <8); in these cases the default of 8 is assumed. All packets arriving with a coverage value less than the specified threshold are discarded, these events are also logged. 3) Disabling the Checksum Computation (SO_NO_CHECK) This is not supported in UDP-Lite, since the checksum is mandatory (RFC 3828, 3.1). 4) Fragmentation The checksum computation respects both buffersize and MTU. The size of UDP Lite packets is determined by the size of the send buffer. The minimum size of the send buffer is 2048 (defined as SOCK_MIN_SNDBUF in include/net/sock.h), the default value is configurable as net.core.wmem_default or via setting the SO_SNDBUF socket(7) option. The maximum upper bound for the send buffer is determined by net.core.wmem_max. Given a payload size larger than the send buffer size, UDP Lite will split the payload into several individual packets, filling up the send buffer size in each case. The precise value also depends on the interface MTU. The interface MTU, in turn, may trigger IP fragmentation. In this case, the generated UDP Lite packet is split into several IP packets, of which only the first one contains the header. The send buffer size has implications on the checksum coverage length. Consider the following example: Payload: 1536 bytes Send Buffer: 1024 bytes MTU : 1500 bytes Coverage Length: 856 bytes UDP Lite will ship the 1536 bytes in two separate packets: Packet 1: 1024 payload + 8 byte header + 20 byte IP header = 1052 bytes Packet 2: 520 payload + 8 byte header + 20 byte IP header = 528 bytes The coverage packet covers the UDP Lite header and 848 bytes of the payload in the first packet, the second packet is fully covered. Note that for the second packet, the coverage length exceeds the packet length. The kernel always re-adjusts the coverage length to the packet length in such cases. As an example of what happens when one UDP Lite packet is split into several tiny fragments, consider the following example. Payload: 1024 bytes Send buffer size: 1024 bytes MTU: 300 bytes Coverage length: 575 bytes +-+-----------+--------------+--------------+--------------+ |8| 272 | 280 | 280 | 280 | +-+-----------+--------------+--------------+--------------+ 280 560 840 1032 ^ *****checksum coverage************* The UDP Lite module generates one 1032 byte packet (1024 + 8 byte header). According to the interface MTU, these are split into 4 IP packets (280 byte IP payload + 20 byte IP header). The kernel module sums the contents of the entire first two packets, plus 15 bytes of the last packet before releasing the fragments to the IP module. VI) UDP-LITE STATISTICS AND THEIR MEANING Exceptional and error conditions are logged to syslog at the KERN_DEBUG level. Live statistics about UDP-Lite are available in /proc/net/snmp and can--with newer versions of netstat--be queried using netstat -svu This displays UDP-Lite statistics variables, whose meaning is as follows. InDatagrams: Total number of received datagrams (as in UDP). NoPorts: Number of packets received to an unknown port (as in UDP). These cases are counted separately (not as InErrors). InErrors: Number of erroneous UDP-Lite packets. Errors include: * internal socket queue receive errors * packet too short (less than 8 bytes or stated coverage length exceeds received length) * IPsec check returned error * application has specified larger min. coverage length than that of incoming packet (cf. below) * checksum coverage violated * bad checksum OutDatagrams: Total number of sent datagrams. If a receiving application has specified a minimum coverage length and received a packet with a smaller coverage value than this, or if it has specified full coverage (UDP mode) and received a partially covered packet, this counts as error (under InErrors), and an error message is logged.