Introducing New Bye (0x02) Packet in Gnutella 0.4 Raphael Manfredi September, 11th 2001 Updated October, 5th 2001 1. Introduction This proposal is about a new Bye packet that would be sent by servents upon disconnecting from a connected node, giving a final reason that the remote end can display. It is safe to retrofit the Bye packet into the 0.4 protocol. Indeed, the packet is the last thing that will be sent by a disconnecting servent, and it will be otherwise ignored as a bad packet by older servents, which is not dramatic given it is the last thing they will see on that connection. This packet is believed to be useful to the developers of Gnutella servents. Users will be able to report the error, and maybe understand what is going wrong, with them or with the remote node. This packet is also considered by the tenant of that proposal as carrying some "social value". Friends say good-bye to each other when they part, and the Gnutella Network is some kind of modern electronic friendship, where people gather and friendly share and exchange files, to the mutual benefit of all parties. 2. The Bye (0x02) Packet The payload descriptor is 0x02, and the payload content is: +------+-----------------------+ | Code | NUL-terminated String | +------+-----------------------+ where Code is a 2-byte error code, encoded in little endian, as usual on Gnutella. The remaining is a NUL-terminated String, giving a description of the error. The presence of the Code allows for automated processing of the message, and the regular SMTP classification of error code ranges should apply. Of particular interests are the 200..299, 400..499 and 500..599 ranges. Here is the general classification ("User" here refers to the remote node that we are disconnecting from): 2xx The User did nothing wrong, but the servent chose to close the connection: it is either exiting normally (200), or the local manager of the servent requested an explicit close of the connection (201). 4xx The User did something wrong, as far as the servent is concerned. It can send packets deemed too big (400), too many duplicate messages (401), relay improper queries (402), relay messages deemed excessively long-lived [hop+TTL > max] (403), send too many unknown messages (404), the node reached its inactivity timeout (405), it failed to reply to a ping with TTL=1 (406), or it is not sharing enough (407). 5xx The servent noticed an error, but it is an "internal" one. It can be an I/O error or other bad error (500), a protocol desynchronization (501), the send queue became full (502). The format of the String is the following ( refers to "\r" and to "\n"): Error message, as descriptive as possible or optionally, something more qualified, with HTTP-like headers giving out more information: Error message, as descriptive as possible Server: some server/version X-Gnutella-XXX: some specific gnutella header for instance telling the host about alternate nodes it could connect to The presence of a at the end of message indicates that HTTP-like headers are present. The absence of any indicates that the short error message form was used. Unless circumstances making that impossible (urgent disconnection due to a memory fault), the HTTP-like headers version should be used, with at least a Server: header, allowing better tracing and debugging. 3. Sending a Bye (0x02) Packet Servents should send a Bye packet to a node as the last thing on the network, and then close the connection. TCP/IP will make its best to relay the final data to the other end, even though the local connection appears closed. The data may not be able to make it though, but at least the servent tried. A Bye packet must be sent with TTL=1 (to avoid accidental propagation by an unaware servent), and hop=0 (of course!). 4. Reception of a Bye (0x02) Packet A Bye packet should have hop=0, TTL=1 upon reception, or it should be immediately discarded as being incorrect. Upon reading a a Bye packet, a node should immediately close the connection and stop processing of any other received packet from that connection that was still pending processing. A Bye packet should not be sent back on the connection before closing, since the remote party already initiated the farewell. 5. Write Errors When a servent is unable to write to an another node (TCP/IP reports the connection was closed, or the send buffer is full because the node does not read quickly enough), it should perform additional checking: * If the connection is reported closed, the servent should begin reading from the connection, as TCP/IP buffers the pending input and will deliver all the bytes sent by the remote party before closing and received by the local host. The servent should skip all the packets and look for a Bye (0x02) packet. If it finds it, it should display/log the error. Otherwise, it will report a disconnection as usual. * If the sending buffer is full, the servent should remove all pending messages, leaving only the only message that could possibly be partially sent, and which needs to be flush in whole to avoid protocol desynchronization. Then, it should enqueue a Bye packet, with error code 502, and attempt the delivery of that information for some reasonable time. In any case, no further data should be enqueued for this node. The servent still needs to read the incoming data to avoid filling of its own transmit queue at the other end, but discard all read data immediately. This includes any partially received packet that we got before discovery of the "send queue full" condition. 6. Examples Here are examples of Bye packet payloads. I am showing the error code in ASCII, but keep in mind it is encoded in the leading two bytes of the payload, and should not be repeated in ASCII in the message String. This is simply done here for reading convenience. 200 Shutting Down Server: my server/version 502 Send Queue Full (40960 bytes) Server: my server/version 401 Too Many Duplicates (Got 12 packets, 1.4% of your traffic) Server: my server/version 7. Conclusion Because the Bye (0x02) packet is the last one sent, it is fully compatible with the 0.4 protocol. Servents could begin sending it this very minute, nothing would break in the Gnutella Network. Due to this very desirable property, it is hoped that the Bye (0x02) packet will be retrofitted into the protocol document for version 0.4. Finally, due to its simple format and its nice social nature, it is expected to be widespread quite quickly. Expect to get more informative disconnection messages anytime soon. --RAM, 11/09/2001