Re: Modern implementations of control messages (ping, pong etc.)

[email protected] Tue, 11 Aug 2009 09:05:40 +0000 (UTC)
Newsgroups gmane.network.gnutella.devel
Organization Home, Grenoble, France
Message-ID <[email protected]>
Quoting rik_saunderson <[email protected]> from ml.gnutella.dev-forum:
:I'm very sorry to be dense, but yes I am.  I know that the client comes with a
:list of addresses to try, which will then be expanded out using pings, pongs etc.
:However, I don't know how to find this list without digging through the source
:code.

You need to refer to well-known UHC (UDP Host Caches) in your code for
bootstrapping purposes.

:I know there are also such things as HeadPings and HeadPongs (although I can't
:find a spec for them, if anyone knows how they work, please tell me).

HEAD Pings and HEAD Pongs are simply a way to perform the equivalent of an
HTTP "HEAD" request over UDP.  I'm appending the documentation that comes
with gtk-gnutella at the end of this message.

:I have also heard that there are GGEP blocks that deal with additional Pings and
:Pongs, but the only GGEP blokcs I can find specs for are PushProxy, H, T ALT, LF
:and u (if anyone knows where the specs of other GGEP blocks are, please tell me).

Ask, and I'll tell you if I have the documentation available.

:So, all in all, yes, how does one determine the initial set of IP and ports to
:connect to?

Via UHCs the very first time.  Then each servent maintains a persistent cache
of the IP:ports it saw and tries to contact theses first when starting again.
Only when this list is exhausted is it allowed to refill it by contacting
an UHC, randomly selected from the list.

Raphael

-----------------------------------------------------------------------

                The "HEAD Ping" Vendor-specific Message
                              Version 1

INTRODUCTION

Please read the Vendor-Messages specifications if you have not done so
already.

SPECIFICATIONS

    Name: "HEAD Ping"
    Vendor: LIME
    ID: 23
    Version: 1
    TTL: 1
    Payload: 1 byte flags followed by clear text URN


DESCRIPTION

The flags:

    Bit 0 (0x01): Request available ranges
    Bit 1 (0x02): Request alternate locations
    Bit 2 (0x04): Request alternate push locations
    Bit 3 (0x08): Request alternate RUDP-capable push locations
    Bit 4 (0x10): Ping carries GGEP data

The URN should be urn:sha1:<base32 hash> but other URNs might be
supported as well.

If flag bit 4 is set, the Ping carries additional GGEP data. If there is
GGEP "PUSH" block, the payload of this block specifies the GUID of the
destination node. Thus GGEP "PUSH" differs in this context and does not
carry addresses of push proxies. Ultrapeers (i.e., push-proxies) should
forward the HEAD Ping to the leaf identified by this GUID. The HEAD
Ping should be forwarded over the TCP connection rather than UDP.

The forwarding peer should never respond to the HEAD Ping itself whether
it shares the file or not. If the GUID matches the receiver's servent
GUID, the receiver should respond with a HEAD Pong. Note that HEAD Pings
are forwarded exactly once even if the TTL is 1.

If the receiver has no leaf with the specified GUID and does not match
its own, the HEAD Ping is simply ignored.

-----------------------------------------------------------------------

                The "HEAD Pong" Vendor-specific Message
                              Version 1


INTRODUCTION

Please read the Vendor-Messages specifications if you have not done so
already.

SPECIFICATIONS

    Name: "HEAD Pong"
    Vendor: LIME
    ID: 24
    Version: 1
    TTL: 1
    Payload: 1 byte flags + 1 byte result code + additional data

DESCRIPTION

The flags (offset 0x00; 1 byte):

    Bit 0 (0x01): Carries available ranges
    Bit 1 (0x02): Carries alternate locations
    Bit 2 (0x04): Carries alternate push locations

The result code (offset 0x01; byte):

    The lower 3 bits report the general status:

    0x00: File not found
    0x01: Complete file
    0x02: Partial file

    The next 2 bits indicate further information:

    Bit 2: (0x04):   Firewalled
    Bit 3: (0x08):   Currently downloading

If the receiver of a HEAD Ping does not share a file with requested
URN (partial or complete), it returns a HEAD Pong which carries only
flags and a zero result code. Otherwise, the HEAD Pong carries further
data:

Vendor code (offset 0x02-0x05; 4 bytes):

This is simply the 4-byte vendor code of the sender for
informational purposes.

Queue status (offset 0x06; 1 byte):

This is signed 8-bit integer. The value 0x7f is special and indicates
a "busy" queue. Otherwise positive values indicate the number of
available upload slots. If the value is negative an immediate upload
request is unlikely to succeed and absolute value indicates how many
requests are queued currently.

Additional data (offset 0x07; variable size):

Note that additional data has a fixed order. Receivers must carefully
check for truncated data.  The sender should only include requested data
and must clear the relevant bit for data not included. Nonetheless
receivers must be able to deal with unrequested items and at least be
able to skip over it. The sender must also be careful to keep the size
of the response sufficiently small especially when it is send over UDP.

First, available ranges:

If flag bit 0 is set, the HEAD Pong carries a list of available ranges.
The next two bytes define the size in bytes of this sub-payload (16-bit
big-endian integer).  This is a multiple of 8 bytes whereas the lower 4
bytes are the 32-bit start offset and the next two are the 32-bit end
offset. It is therefore not possible to indicate ranges beyond the
first 4 GiB in case of large files.

Second, alternate push locations:

If flag bit 2 is set, the HEAD Pong carries a list of alternate push
locations. The next two bytes define the size in bytes of this
sub-payload (16-bit big-endian integer). Alternate push locations are
encoded as a one byte of flags; followed by a 16 byte GUID, optionally
a 6-byte IPv4 peer address[1] and finally up to 7 push proxy adresses
encoded as 6-byte peer addresses. This includes RUDP-capable push locations.
The first byte of a push location is encoded as follows:

Bits  Description
0..2: Number of push proxies (0-7)
3..4: Supported RUDP protocol version (0 means unsupported)
5..7: Other flags

The peer address after the GUID might be omitted. Whether this is the
case can be derived by the size of this sub-payload.

Third, alternate locations:

If flag bit 1 is set, the HEAD Pong carries a list of alternate
locations. The next two bytes define the size in bytes of this
sub-payload (16-bit big-endian integer). Alternate locations are encoded
as a 6-byte IPv4 peer address. This sub-payload size must therefore be a
multiple of 6 bytes.


[1] A 6-byte IPv4 address consists of a 4-byte IPv4 address followed by
2 bytes encoding the 16-bit port number as little-endian integer. This
is the usual format as used elsewhere by the Gnutella protocol.