Gnutella Protocol Development

Our blue logo

Gnutella Protocol Development

Home :: Developer :: Press :: Research :: Servents

               Framework for Vendor-specific Messages
                            Version 0.1

                          Raphael Manfredi
                    
                          January 2nd, 2003
                     Revised on January 5th, 2003
                

[These specifications are a summary of messages exchanged on the GDF.
 The initial introduction of vendor-specific messages was done by
 BearShare.  However, some refinements to the initial proposal have been
 introduced and never documented formally.  This document tries to remedy
 to that].

1. OVERVIEW

Vendor-specific messages allow vendors to experiment with new messages
without disrupting the regular Gnutella network.

This document defines the framework which is used to define the new
vendor-specific messages.  Whilst those message are inherently highy
specific and free form, they are minimally structured so as to be
manageable.

2. MESSAGE FORMAT

All vendor-specific message use the new message code 0x31 (49 decimal).

The message code 0x32 (50 decimal) is hereby also reserved for
standardized vendor messages, i.e. messages that were initially specified
privately as a 0x31 message and which were deemed so generally useful
that they were "promoted".  There is otherwise no difference between
the 0x32 and the 0x31 version of a message, as far as the format goes.

Since all vendor-specific messages are defined within one 0x31 message
type, the leading bytes of the payload further define the message
as follows:

Bytes 0-3: Vendor ID, case sensitive sequence of 4 ASCII characters,
           as with query hits.  For instance, "BEAR" would be coded as
           the 0x42454152 digit, in hexadecimal.  Note that this
           representation is inherently big-endian.

           [Note from RAM: yes, it is case SENSITIVE.  All vendors
            traditionally used upper-cased chars in query hits, and
            being case-insensitive would not buy us anything but
            problems.]

           You can also view this field as a big-endian unsigned
           32-bit integer.

Bytes 4-5: Sub-selector, yielding the message type for this vendor ID.
           This field is a little-endian unsigned 16-bit integer.

Bytes 6-7: Version number, a little-endian unsigned 16-bit integer.
           Versions traditionally start with 1, but a vendor may choose
           to start at 0 if he so wishes.

The type of the vendor-specific message is therefore determined by the
tuple (Vendor ID, Sub-selector).  For ease of notation, the message from
vendor ID "BEAR" bearing sub-selector 34 (for instance) at version 1 will
be noted "BEAR/34v1".

Hereinafter, when we talk about a "message type", we mean a
vendor-specific message type, i.e. a tuple (Vendor ID, Sub-selector).
Thus, "BEAR/34" is a message type, and you must understand that it is
sent encapsulated within a regular Gnutella message bearing the message
code 0x31.

The remainder of the payload is defined by the message type.

The rules for routing 0x31 messages, value for GUID, ttl, and hops are
defined on a message type basis.  This specification (version 0.1) only
defines messages sent with TTL=1 and hops=0.  Unknown messages types,
or messages sent with something other than TTL=1 and hops=0 MUST be
dropped without prejudice.

3. HANDSHAKING

During Gnutella handshaking, servents supporting reception of
vendor-specific messages compliant with this specification MUST
advertise so by emitting the following header:

    Vendor-Message: 0.1

Note that understanding 0x31 messages simply means that you will
read the message and not terminate the connection.  It gives no
assurance that you will be able to understand and process the
received message.

4. ADVERTISING SUPPORTED MESSAGES

Because the set of vendor-messages supported is not really bounded and
can be fairly large, it is not advertised directly in the handshake.

At times, all you want to know is whether a servent supports
vendor-messages.  This is indicated by the presence of the Vendor-Message
field in the handshake.  So you blindly send the message, and do not
really care whether the other end will act on it or simply ignore it.

On the other hand, some vendor-specific messages may require a reply from
the other party.  Before sending the message, you need to know whether
the other end will support it, so that you do not wait the reply forever,
or close the connection if the reply does not come after a timeout,
for instance.

Whenever a servent supporting vendor messages meets another servent that
has advertised "Vendor-Message" in its handshaking header, it MUST send
it a "Messages Supported" message, guaranteed to be understood by all
implementations, right after the initial "handshaking ping".

The message is known as "null/0v0".  "null" is because the vendor ID
field is set with zeros, as in 0x00000000.  "0" because the sub-selector
ID is 0 in decimal.  And "v0" because the only version specified for
this message is 0.

The payload of the "null/0v0" message is defined as follows (offset
relative to the start of the payload, byte 0 being actually byte 8 in
the payload of the encapsulating 0x31 message).

    Bytes 0-1: vector size (little-endian unsigned 16-bit integer)

The vector that follows has `vector size' items, of 8 bytes each, all
formatted the same way.  Each item describes a particular vendor-specific
message supported by the servent.  The first item of that vector would be:

    Bytes 2-5: vendor ID (big-endian, e.g. "GTKG")
    Bytes 6-7: sub-selector ID (little-endian)
    Bytes 8-9: version number (little-endian)

If several version numbers are supported for a given sub-selector ID,
whether or not all are mentionned depends how backward compatible those
messages were.  If they are guaranteed to be backward compatible, only
the highest version supported (i.e. understood when read) needs to be
sent back.

5. EXAMPLE - HOPS FLOW

Here is a sample definition for a REAL vendor-specific message, known
as BEAR/4v1, but also as "Hops Flow".

    Name: Hops Flow
    Vendor: BEAR
    ID: 4
    Version: 1
    TTL: 1
    Payload:
        unsigned byte: hop value

This message carries a single 8-bit unsigned integer representing the
upper bound value for hops that a servent wishes to see in queries
from its neighbors.  Only queries whose hops are STRICLY lesser than
the threshold are expected to be received.  A threshold of 0 therefore
requests that NO queries be sent at all, since the minimal valid hop count
is 0, for a query originated by an immediate neighbour.  A threshold of
1 would limit queries to those originated by immediate neighbours, etc...

This message MUST NOT be routed, and MUST always be sent with TTL=1
and hops=0.  The GUID is ignored.

BearShare will use the Hops Flow feature to allow leaves to inform its
Ultrapeers that they should turn the forwarding of queries on and off
(by setting hops to max_TTL and 0 respectively) based on whether or not
the leaf has sharing of files turned on. Setting hops to 0 results in a
substantial bandwidth reduction with modem users who have large shared
file sets but turn sharing off to speed up downloads.

Gtk-Gnutella also uses the Hops Flow feature between ultra nodes to 
inform the remote node about a flow-control condition locally and to
request that the remote node no longer be sending queries that would  
immediately be dropped anyway upon reception.  In that case, the Hops
Flow message is sent ahead of all the other messages in the queue to   
ensure prompt delivery.

Here is a detailed description of the message payload within the 0x31
Gnutella message:

    Byte     Value
     0        'B'       # ASCII code 0x42
     1        'E'       # ASCII code 0x45
     2        'A'       # ASCII code 0x41
     3        'R'       # ASCII code 0x52
     4        0x04      # 4 in little-endian representation
     5        0x00
     6        0x01      # version 1, the only one defined so far
     7        0x00
     8         zz       # the hop value (betwen 0 and 255)

Therefore, the payload length for this 0x31 message is 9 bytes.

Raphael

 

 

 

Home :: Developer :: Press :: Research :: Servents

SourceForge.net Logo