Handshaking

From Gnutella Developers

<< Bootstrapping | Leaf Mode and Ultrapeer Mode >> | Main Page

Handshaking Source : [Original Handshake Proposal. (http://rfc-gnutella.sourceforge.net/src/gnutellaHandshakeProposal-0_6.html)]

A Gnutella servent connects itself to the network by establishing a connection with another servent currently on the network. Techniques for finding the first host are described in Chapter 2.1. Once the first connection is established, the addresses of more hosts will be supplied over the network. The default Gnutella port is 6346, but servents MAY use any unused port. If the desired port is used (probably by another Gnutella servent) the servent SHOULD attempt to listen on another port. This listening port is advertised by the servent through the Pong messages.

Techniques and rules for how to select what other Gnutella hosts to connect to and when to accept connection requests can be found in Appendix 4.

Once the address of another servent on the network is obtained, a TCP/IP connection to the servent is created, and a handshaking sequence is initiated. The client is the host initiating the connection and the server is the host receiving it. "<cr>" refers to ASCII character 13 (carriage return), and "<lf>" to 10 (new line).

  1. The client establishes a TCP connection with the server.
  2. The client sends "GNUTELLA CONNECT/0.6<cr><lf>".
  3. The client sends all capability headers--except for
     vendor-specific headers--each terminated by "<cr><lf>",
     with an extra "<cr><lf>" at the end.
  4. The server responds with "GNUTELLA/0.6 200 <string><cr><lf>".
     <string> SHOULD be "OK", but servents SHOULD just look for the
     "200" code.
  5. The server sends all its headers, in the same format as in (3).
  6. The client sends "GNUTELLA/0.6 200 OK<cr><lf>", as in (4) if
     after parsing the server's headers, it still wishes to connect.
     Otherwise, it needs to reply with an error code and close the
     connection.
  7. The client sends any vendor-specific headers as needed, in the
     same format as (3).
  8. Both client and server send binary messages at will, using the
     information gained in (3) and (5).

All headers SHOULD be registered with the GDF database at http://groups.yahoo.com/group/the_gdf/database?method=reportRows&tbl=9 (Requires GDF membership)

Headers follow the standards described in RFC822 and RFC2616. Each header is made of a field name, followed by a colon, and then the value. Each line ends with the <cr><lf> sequence, and the end of the headers is marked by a single <cr><lf> line. Each line normally starts a new header, unless it begins with a space or an horizontal tab (ASCII codes 32 and 9 in decimal, respectively), in which case it continues the preceding header line. The extra spaces and tabs may be collapsed into a single space as far as the header value goes. For instance:

   First-Field: this is the value of the first field<cr><lf>
   Second-Field: this is the value<cr><lf>
       of the<cr><lf>
       second field<cr><lf>
   <cr><lf>

The header above is made of two fields, "First-Field" and "Second- Field" whose values are respectively "this is the value of the first field" and "this is the value of the second field" (leading spaces of the continuation were collapsed). Note that the leading space between the ":" ending the field name and the start of the value string does not count.

Multiple header lines with the same field name are identical to one header line where all the values of the fields would be separated by ". This means:

   Field: first<cr><lf>
   Field: second<cr><lf>

is strictly equivalent to saying:

   Field: first,second<cr><lf>

In other words, order matters in that case.

Here is a sample interaction between a client and a server. Data sent from client to server is shown on the left; data sent from server to client is shown on the right.

      Client                          Server
      -----------------------------------------------------------
      GNUTELLA CONNECT/0.6<cr><lf>
      User-Agent: BearShare/1.0<cr><lf>
      Pong-Caching: 0.1<cr><lf>
      GGEP: 0.5<cr><lf>
      <cr><lf>
                                      GNUTELLA/0.6 200 OK<cr><lf>
                                      User-Agent: BearShare/1.0<cr><lf>
                                      Pong-Caching: 0.1<cr><lf>
                                      GGEP: 0.5<cr><lf>
                                      Private-Data: 5ef89a<cr><lf>
                                      <cr><lf>
      GNUTELLA/0.6 200 OK<cr><lf>
      Private-Data: a04fce<cr><lf>
      <cr><lf>
     [binary messages]                [binary messages]

A few notes about the responses: first, the client (server) SHOULD disconnect if receiving any response other than "200" at step 4 (6). There is no need to define these error codes now. Second, servents SHOULD ignore higher version numbers in steps (2), (4), and (6). For example, it is perfectly legal for a future client to connect to a server and send "GNUTELLA CONNECT/0.7". The server SHOULD respond with "GNUTELLA/0.7 200 OK" if it supports the 0.7 protocol, or "GNUTELLA/0.6 200 OK" otherwise.

A few notes about the headers: servents SHOULD use standard HTTP headers whenever appropriate. For example, servents SHOULD use the standard "User-Agent" header rather than make up a "Servent-Vendor" header. However, it is perfectly legal to add new headers (e.g., "Query-Routing") when no appropriate HTTP header exists, as long as they follow HTTP syntax. Headers unknown to the servent MUST be ignored.

Some older servents will initiate the handshake by sending "GNUTELLA CONNECT/0.4<lf><lf>". The server SHOULD then reply with "GNUTELLA OK<lf><lf>" followed by binary messages, if it can accept the connection. Servents MAY retry using the 0.4 connect string if the 0.6 connection attempt were rejected. No handshaking headers can be used in 0.4 handshaking.

When rejecting a connection, a servent MUST, if possible, provide the remote host with a list of other Gnutella hosts, so it can try connecting to them. This SHOULD be done using the X-Try header.

An X-Try header can look like:

       X-Try:1.2.3.4:1234,3.4.5.6:3456

There MAY be a space after the colon and after each comma. There MAY be multiple X-Try headers in one header set. The header MAY end with an extra comma. The header MAY be formatted on several lines using continuations.

Each item in the X-Try header gives the IP address of a servent and its listening port number. This is sometimes referred to as being a "connection pong". If the server sending the X-Try implements Pong-Caching, then the connection pongs being sent must be fresh ones.

The normal status code for rejecting a connection because the servent is busy is "503 " followed by "Busy" or another description string.

<< Bootstrapping | Leaf Mode and Ultrapeer Mode >> | Main Page