barmar@think.COM (Barry Margolin) (11/17/88)
A week or so ago I wrote asking for hints on implementing trailer reception efficiently. This posting is a summary of the responses. I didn't actually save most of the responses, so I'll just paraphrase. Thanks to everyone who responded. Several of the responses didn't really address my question. I received several responses telling me that trailers are a lose, and I shouldn't bother. Perhaps I wasn't clear about my reasons in my original posting. The problem is that my machines (Symbolics Lisp Machines) are on a network with a number of Vaxes and Suns running Unix, and we sometimes forget to turn trailers off on these machines. This causes transient problems when communicating with the incorrectly-configured machines. The best, permanent solution I could think of was to teach the Lispms to handle trailers. The more useful responses generally described how trailers are processed in Unix. The interface between the Ethernet driver and the network protocol layers is in terms of a linked list of mbufs. It is relatively easy in such an implementation to splice the trailer header ahead of the data portion. I believe that the comment in RFC-893 about the small amount of code needed to implement trailers assumed such an interface architecture. Unfortunately, Genera's Ethernet driver interface doesn't provide such a structure. I did receive one response from someone knowledgeable about the low levels of Genera's networking software (JTW@XX.LCS.MIT.EDU), but I ended up not using his suggested implementation. Genera uses objects called SUB-PACKETS, which are Lisp arrays that indirect into the Ethernet packet buffers. There are routines for creating a new SUB-PACKET offset from the beginning of a given SUB-PACKET; the Ethernet driver returns a SUB-PACKET pointing past the Ethernet header to the IP driver, who does an analogous thing when passing the packet up to TCP, etc. If the requested offset is negative you can get access to the portions of the packet buffer preceding the current layer's data, and it will automatically copy the current packet into a new buffer if the negative offset would go past the beginning of the packet. JTW suggested I use this to open up space before the beginning of the data and copy the header into it. I ended up using the simplest implementation, copying the trailer header into a temporary array, shifting the data over, and copying the header back in. I chose not to use the above suggestion because I am not sure about all the ramifications. Such an implementation would overwrite the Ethernet header with the TCP/IP headers, and I'm not absolutely sure that nothing would ever try to look at the Ethernet header. I also wasn't very comfortable with the packet allocation/deallocation issues. I may optimize it in the future, but for the moment I'm being conservative. I specifically pulled this operation out into its own routine to make it easy to plug in different implementations. My entire implementation is about 200 lines of code. However, most of it is support code for interfacing with various system diagnostic tools, enabling/disabling network drivers, etc. The actual protocol implementation is under 50 lines of Lisp code. After we've run with it for a while I'm going to send it to Symbolics and request that they include it (or something like it) in future releases. Meanwhile, I'll make it available for anonymous FTP on Think.COM, in the file /public/trailers.lisp. For the benefit of others who might be thinking of implementing trailers, I did find an annoying wording problem in the RFC. In the Trailer Format section (p.5), the following appears: Header length: 16 bits The header length field of the trailer data segment. This specifies the length in bytes of the following header data. I initially interpreted this to mean that the Header length field specifies the length of the original header. However, in the implementation I was testing against, I was getting consistent TCP checksum errors. When I turned off checksum checking on my machine, I noticed that the first four data characters of each TCP segment were garbage. I then decided that the Header length field must be the size of the entire trailer, so I must subtract 4 from it when determining how much space to allocate at the beginning of the packet. Barry Margolin Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar