This is part of How Gnutella Works
The Gnutella Handshake
A Gnutella connection begins with the handshake. The handshake tells a program that accepts a connection the remote computer wants to speak Gnutella. It lets two programs advertise which advanced Gnutella features they support, and negotiate what compression format they'll use. It also lets a program disconnect from an incompatible peer, or refuse a connection that isn't needed.
One Gnutella program opens a TCP socket connection to another. It sends the greeting GNUTELLA CONNECT/0.6, followed by a group of handshake headers. There are 3 groups of headers in the handshake. After the handshake, Gnutella programs begin exchanging Gnutella messages.
A Sample Handshake
A Gnutella handshake always consists of 3 groups of headers. The computer that initiated the connection sends the first group. The computer that received the connection responds with the second. The initiating computer sends a third, completing the handshake. Here is a sample handshake from LimeWire version 4.10.9, a modern Gnutella program:
Computer that made the connection Computer that received the connection
--------------------------------- -------------------------------------
GNUTELLA CONNECT/0.6
User-Agent: LimeWire/4.10.9
X-Locale-Pref: en
X-Requeries: false
X-Version: 4.9
Listen-IP: 217.254.98.153:6346
Remote-IP: 68.37.233.44
Accept-Encoding: deflate
X-Ultrapeer: True
X-Degree: 32
X-Query-Routing: 0.1
X-Ultrapeer-Query-Routing: 0.1
X-Dynamic-Querying: 0.1
X-Ext-Probes: 0.1
Vendor-Message: 0.2
GGEP: 0.5
Pong-Caching: 0.1
X-Max-TTL: 3
X-Guess: 0.1
GNUTELLA/0.6 200 OK
X-Try-Ultrapeers: 171.195.105.218:3988,24.166.9.141:6346,67.188.94.23:6346,72.1...
User-Agent: LimeWire/4.10.9
X-Locale-Pref: en
X-Requeries: false
X-Version: 4.9
Listen-IP: 68.37.233.44:9376
Remote-IP: 217.254.98.153
Accept-Encoding: deflate
Content-Encoding: deflate
X-Ultrapeer: True
X-Ultrapeer-Needed: true
X-Degree: 32
X-Query-Routing: 0.1
X-Ultrapeer-Query-Routing: 0.1
X-Dynamic-Querying: 0.1
X-Ext-Probes: 0.1
Vendor-Message: 0.2
GGEP: 0.5
Pong-Caching: 0.1
X-Max-TTL: 3
X-Guess: 0.1
GNUTELLA/0.6 200 OK
Content-Encoding: deflate
(Gnutella messages) (Gnutella messages)
Later, we'll examine the headers individually, and describe what each means. Gnutella programs ignore the headers they don't understand.
Handshake Data Format
Gnutella handshake headers are like the HTTP headers that begin a Web connection. The initiating program makes a new TCP socket connection to the receiving computer's listening socket. The headers are written in ASCII text, with letters taking up single bytes. In the diagram above, each header is shown on a separate line. On the wire, they are terminated by a carriage return byte and a line feed byte. In C and Java, these 2 bytes are escaped \r\n.
A complete header looks like this:
X-Header-Name: header value 1, header value 2\r\n
A colon separates the header name from its value. There is usualy a space after the colon. The value can be a list separated with commas. Case doesn't matter in header names, and the values True and False.
The Gnutella handshake consists of 3 groups of headers. A Gnutella program can wait for an entire group of headers to arrive, read the group, and then compose and send a reply group. A blank line ends a group of headers. To parse for the end of a header group, look for \r\n\r\n.
GREETING LINE\r\n X-Header-Name: header value\r\n X-Another-Name: value 1, value 2\r\n \r\n
The headers in a group can be in any order. The HTTP specification allows for header values spread across multiple lines. LimeWire doesn't use this feature, keeping each header on a single line.
After the last group of handshake headers is the stream of Gnutella messages. The messages come one after another without any space between them. The message data stream is usually compressed.
Greeting
Each group of headers starts with a greeting line. The 3 greeting lines look like this:
Computer that made the connection Computer that received the connection
--------------------------------- -------------------------------------
GNUTELLA CONNECT/0.6
GNUTELLA/0.6 200 OK
GNUTELLA/0.6 200 OK
Version Number
The current version of the Gnutella protocol is 0.6. Original Gnutella programs were version 0.4, and used a different handshake format than the one described here. Gnutella 0.4 programs are very rare, and modern Gnutella programs don't have to be compatible with them.
This number versions the handshake, not the advanced Gnutella features it advertises. Gnutella programmers have extended the protocol in many ways without needing to change to a higher version number. It's unlikely a Gnutella program will ever have to worry about a 0.7 handshake, or any other number than 0.6.
Refusing the Connection
The program that receives the connection may read the initiating program's first group of headers, and decide it doesn't want the new connection. In that case, the handshake only has 2 stages:
Computer that made the connection Computer that received the connection
--------------------------------- -------------------------------------
GNUTELLA CONNECT/0.6
GNUTELLA/0.6 503 Service unavailable
X-Try-Ultrapeers: 171.195.105.218:3988,24.166.9.141:6346,67.188.94.23:6346,72.1...
The receiving computer rejects the connection with any status number other than 200. The rejection shown above, 503 Service unavailable, is the most common. It means the receiving computer already has enough connections, and doesn't want another.
More Addresses to Try
With the X-Try-Ultrapeers header, LimeWire provides 10 IP addresses and port numbers. They're the addresses of remote computers on the Internet running Gnutella software. A program should always send X-Try-Ultrapeers in stage 2, and it's especially important when refusing the connection. The program is saying, I can't accept your connection, but here are 10 more addresses you can try.
Older Gnutella programs may name the header X-Try instead of X-Try-Ultrapeers. Both headers list the IP addresses of ultrapeers. Leaves don't accept connections, so listing their addresses wouldn't make sense.
Each value may include date and time information, like this:
X-Try-Ultrapeers: 24.98.97.155:6348 2004-12-18T23:47Z,
Look for a space after the port number to avoid this extended information.
Program Name and Version
Computer that made the connection Computer that received the connection
--------------------------------- -------------------------------------
User-Agent: LimeWire/4.10.9
X-Locale-Pref: en
X-Requeries: false
X-Version: 4.9
User-Agent: LimeWire/4.10.9
X-Locale-Pref: en
X-Requeries: false
X-Version: 4.9
The User-Agent header lets a Gnutella program tell its vendor and version number.
The value of X-Locale-Pref is a 2-letter code that identifies a language, like en for English. It tells what language the user has configured his or her computer to use. LimeWire exchanges X-Locale-Pref headers to try to identify and keep connections that match a non-English language. Language preferencing is an advanced and optional feature for a modern Gnutella program.
As peers carrying the traffic of decentralized search, it's very important that Gnutella programs don't use more resources than they give back to the network. Specifically, a Gnutella program should never issue the same search twice. The header X-Requeries: false is a promise. LimeWire looks for this header, and is more likely to accept connections from programs that make this pledge.
X-Version is part of LimeWire's automatic software update feature. For the version number, look after the slash in User-Agent.
Addresses
Computer that made the connection Computer that received the connection
Located at 217.254.98.153:6346 Located at 68.37.233.44:9376
--------------------------------- -------------------------------------
Listen-IP: 217.254.98.153:6346
Remote-IP: 68.37.233.44
Listen-IP: 68.37.233.44:9376
Remote-IP: 217.254.98.153
Gnutella programs include the Listen-IP and Remote-IP headers in the first group of handshake headers they send. Speaking from the perspective of a computer sending headers, Listen-IP is my IP address, and Remote-IP is yours. Why am I telling you your own IP address? Actually, you may not know it yet. You're likely behind a broadband router that's assigned your computer a LAN IP address like 192.168.0.101. To find your real IP address, you'll connect to a peer. It will tell you what your address looks like from the far side of the Internet with Remote-IP.
Listen-IP includes the port number, while Remote-IP does not. A Gnutella program knows what port number it has listening for new connections.
In place of Listen-IP, some clients use X-My-Address or Node.
Compression
Computer that made the connection Computer that received the connection
--------------------------------- -------------------------------------
Accept-Encoding: deflate
Accept-Encoding: deflate
Content-Encoding: deflate
Content-Encoding: deflate
After the handshake, Gnutella programs exchange Gnutella messages. The data stream of messages is usually compressed. Accept-Encoding: deflate means, I can understand a compressed data stream, and would like one. Content-Encoding: deflate means, I am going to send you a compressed data stream.
This exchange uses all 3 stages of the handshake. The initiating computer can't send a compressed stream without sending the warning Content-Encoding: deflate first. It can't send the warning without hearing Accept-Encoding: deflate first.
Omit these headers to refuse compression, or not request it in the first place. A Gnutella connection can be compressed in one direction and not the other. Almost all connections, however, are compressed in both directions.
Gnutella uses a standard stream compression format named deflate. A popular C libray for deflate compression is zlib. In Java, use the Deflater class.
These header names don't start X- because they are standard HTTP headers, not headers programmers created for Gnutella.
Ultrapeers
Computer that made the connection Computer that received the connection
--------------------------------- -------------------------------------
X-Ultrapeer: true
X-Degree: 32
X-Ultrapeer: true
X-Ultrapeer-Needed: true
X-Degree: 32
Several headers deal with Gnutella's ultrapeer system. X-Ultrapeer: true means, I am an ultrapeer. X-Ultrapeer: false means, I am a leaf. X-Ultrapeer-Needed: true means, I need more connections to ultrapeers. X-Ultrapeer-Needed: false means, I already have enough ultrapeers, and can only connect to you if you decide to become a leaf. X-Degree tells how many ultrapeers the program, as an ultrapeer, will try to find and keep connected. LimeWire ultrapeers have 32 connection slots for other ultrapeers.
The sample above shows an ultrapeer connecting to another ultrapeer. Ultrapeers documents each situation that involves these headers.
Search
Computer that made the connection Computer that received the connection
--------------------------------- -------------------------------------
X-Query-Routing: 0.1
X-Ultrapeer-Query-Routing: 0.1
X-Dynamic-Querying: 0.1
X-Ext-Probes: 0.1
X-Query-Routing: 0.1
X-Ultrapeer-Query-Routing: 0.1
X-Dynamic-Querying: 0.1
X-Ext-Probes: 0.1
Modern Gnutella programs have a suite of advanced features to make distributed search possible and efficient. The headers outlined above advertise support for these features.
X-Query-Routing and X-Ultrapeer-Query-Routing involve the Query Routing Protocol (QRP), Gnutella's sytem of exchanging query routing tables that mask out searches. X-Query-Routing concerns leaves sending QRP tables to their ultrapeers, while X-Ultrapeer-Query-Routing is about ultrapeers sharing QRP tables with each other. The two headers are separate because ultrapeer query routing is a newer Gnutella feature than query routing.
Specifically, X-Query-Routing: 0.1 means, I understand how leaves send QRP tables to their ultrapeers, and have the code to do what's necessary in either role. X-Ultrapeer-Query-Routing: 0.1 means, I understand how ultrapeers exchange QRP tables with other ultrapeers, and can perform this feature when I'm an ultrapeer.
Dynamic Querying is the efficient and modern method of searching the Gnutella network. X-Dynamic-Querying: 0.1 means, I understand how to perform the steps of dynamic querying. X-Ext-Probes: 0.1 means, I won't block messages sent in the later steps of dynamic querying, as a program unfamiliar with dynamic querying would.
Currently, all of these features are in their initial version, 0.1.
Additional Gnutella Features
The remaining headers advertise support for a variety of additional features that modern Gnutella programs support.
Computer that made the connection Computer that received the connection
--------------------------------- -------------------------------------
Vendor-Message: 0.2
GGEP: 0.5
Pong-Caching: 0.1
X-Max-TTL: 3
X-Guess: 0.1
Vendor-Message: 0.2
GGEP: 0.5
Pong-Caching: 0.1
X-Max-TTL: 3
X-Guess: 0.1
Vendor-Message: 0.1 means the program supports vendor-specific messges. If a remote computer says Vendor-Message: 0.1 or later, LimeWire sends it a Messages Supported vendor message and a Capabilities vendor message at the start of the message stream. Most vendor-specific Gnutella messages have a TTL of 1 and a hops of 0. They travel from source computer to destination computer, and go no further. Vendor-Message: 0.2 means the program can route vendor messages beyond a single hop. LimeWire routes Head Ping vendor messages.
GGEP is a standard method of adding additional information to Gnutella messages. GGEP: 0.5 advertises support for the version that is current and widely in use.
Pong-Caching: 0.1 indicates support for Pong Caching, a modern Gnutella system of spreading addresses across the network. Instead of pinging a remote computer that supports pong caching, LimeWire just starts sending cached pongs.
X-Max-TTL: 3 means, Do not send me a message with a TTL bigger than 3.
X-Guess: 0.1 indicates support for GUESS-style queries. GUESS is a method of searching in Gnutella that sends Query messages in UDP packets directly to ultrapeers. It is no longer commonly in use.
Desired Features
LimeWire looks for particular handshake headers to determine if a Gnutella program will provide a good connection and help the network.
X-Requeries: false X-Dynamic-Querying: 0.1 X-Ultrapeer-Query-Routing: 0.1 X-Degree: 15 (Or higher) X-Max-TTL: 4 (Or lower)
The program must make the no-requeries pledge. It has to be able to use Dynamic Querying and Ultrapeer Query Routing. It should connect to 15 or more ultrapeers when an ultrapeer, and only work with packets with a TTL of 4 or less.
After the Handshake
After the handshake, Gnutella programs send 2 vendor messages that serve a similar purpose. They also start Pong Caching.

