Making Gnutella "IPv6-Ready"
Raphael Manfredi <[email protected]> Wed, 22 Jun 2011 22:00:33 +0200
| Newsgroups | gmane.network.gnutella.devel |
|---|---|
| Organization | Home, Grenoble, France |
| Message-ID | <[email protected]> |
--y09etRhHkCNtips6-d8sup9HpD0JiGa8UsGmZ1d
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Making Gnutella "IPv6-Ready"
Raphael Manfredi
<[email protected]>
June 22nd, 2011
1. Introduction
Now that IPv4 address exhaustion is a fact, there is going to be a
huge incentive to accelerate IPv6 deployment. People equipped with
an IPv4 address are going to be supplied an IPv6 address (actually a
network prefix where they can host several thousands of machines, if
not millions) whilst others are going to only have IPv6, without any
IPv4 address at all.
The Gnutella protocol needs to evolve slightly to make it possible
to run on IPv6 because it architected some of its core fields holding
IP addresses as being 4-byte long, i.e. only capable of storing IPv4
addresses.
However, IPv6 is a totally new network protocol, distinct from IPv4.
Although there are some mechanisms in IPv6 to be able to reach IPv4
addresses, the necessary translation mechanisms may not be available
everywhere. This means Gnutella on IPv6 is going to form a network
overlay completely distinct than the current Gnutella network, which
is IPv4-based.
Fortunately, the fact that many people are going to be given an IPv6
address in addition to a legacy IPv4 one is an opportunity to bootstrap
the IPv6 network nicely, until there are sufficient IPv6 peers to create
a stable Gnutella core.
This article only focuses on the Gnutella network protocol changes
that must be incorporated into the Gnutella servents to make them
"IPv6-Ready", that is capable of being a part of the IPv6-only Gnutella
network tomorrow. Servents that are not IPv6-Ready are condemned to stick
to the IPv4 network, which will be slowly dying first, until a critical
point is reached at which time the stable IPv4 core will disappear,
replaced by the IPv6 core.
These IPv6-Ready Specifications are meant to be totally backward
compatible, so that legacy servents see almost no difference and can
still usefully interact with modern IPv6-Ready servents.
2. Gnutella Messages
This section introduces new GGEP extensions to be used in various Gnutella
messages to be able to transport IPv6 addresses.
2.1 Legacy Messages
The following Gnutella messages have been historically architected to
hold IPv4 addresses only: Pong, Query Hit, Push.
To expand them so that they can hold an additional IPv6 address or simply
a single IPv6 one, two strategic GGEP extensions are introduced:
The "I6" extension holds a full IPv6 address, in raw binary big-endian
format, that is 16 bytes. Its presence in Pong, Push or Query Hit
trailer indicates that the servent is running both on IPv4 and on IPv6.
The "6" extension holds the *leading* 12 bytes of the IPv6 address, the
trailing 4 bytes being held in the legacy IPv4 field of the message.
The IPv6 address needs therefore to be reconstructed by concatenating
the leading 12 bytes (big-endian) of the "6" extension payload with
the trailing 4 bytes (big-endian) of the legacy field to form the 16
bytes (big-endian) of the servent's IPv6 address. The presence of this
extension indicates that the servent only has an IPv6 address.
This design has the following properties:
- It clearly communicates the level of IPv6 support: IPv4 only (neither
"I6" nor "6" present), IPv4 and IPv6 support ("I6" present), IPv6 only
("6" present).
- When parsed by a non IPv6-Ready servent, the IPv4 field will be
meaningful most of the time, excepted when "6" is present.
In that case however, since the address read will be the lowest 4 bytes
of the actual IPv6 address, it is likely that this will be read as an
address in 0/8, which is an invalid IPv4 address block.
- Ultimately when everyone uses IPv6, the legacy 4-byte field will not be
wasted. Everyone will be sending "6" extensions, thereby optimizing the
overhead.
2.2 Extended Messages
Over time, some legacy messages have been extended with GGEP extensions
to transport packed IPv4:port tuples. These are the "IPP", "ALT",
"PUSH" extensions found in pongs or in query hits, forming vectors of
6-byte items.
All the legacy extensions are kept but new ones are introduced
specifically for transporting packed IPv6:port tuples, the IPv6 address
being in big-endian and the port in little-endian, to form a vector of
18-byte items.
The "ALT6" and "ALT6_TLS" extensions are introduced for query hits:
"ALT6" packs IPv6:port alternate locations and "ALT6_TLS" is like
"ALT_TLS" but applies to the "ALT6" vector, indicating which of the
alternate location hosts are known to support TLS.
Likewise, the "IPP6" and "IPP6_TLS" extensions are introduced for UHC
pongs, "PUSH6" and "PUSH6_TLS" for query hits push-proxies.
The "IP" extension in Pongs (used to send back the IP:port of the remote
host) is extended to be able to hold IPv4:port or IPv6:port, as needed.
The size of the extension payload (6 or 18 bytes) will discriminate
between the two forms.
2.3 OOB Queries
Queries requesting Out Of Band hit delivery encode the IPv4 address of
the recipient in the GUID.
Queries requiring that delivery by sent back to an IPv6 address must
use the same splitting technique as described in 2.1: the leading 12
bytes of the address are put in a GGEP "6" extension, the trailing 4
bytes being left in the GUID.
Because there is no guarantee that the servent reporting hits will support
IPv6, the "6" extension should only be used when there is no other choice,
i.e. when the querying party only has access to IPv6.
Otherwise, chances are that the lowest 4 bytes of the IPv6 address will
form an invalid IPv4 address (since this is how a non IPv6-Ready servent
would interpret the IP address) and the hit will simply be sent back
through Gnutella (i.e. the OOB bit will be ignored).
2.4 Vendor Messages
2.4.1 HEAD Ping and HEAD Pong (LIME/23 and LIME/24)
GGEP "A6" and "T6" are introduced for HEAD pongs (v2) to transport IPv6
alt locations and TLS indication (mirroring "A" and "T"). Since HEAD
pongs (v1) cannot be made IPv6-Ready, servents should obsolete HEAD
ping (v1) requests and only send v2 ones (LIME/23v2 vendor messages aka
"HEAD Ping", answered to by LIME/24v2 aka "HEAD Pong").
2.4.2 Connect Back
There is no need to change the connect back messages (BEAR/7 and GTKG/7):
they connect back to the originating address as communicated by the TCP
or UDP layer, be it on top of IPv4 or IPv6.
2.4.3 OOB Reply Indication (LIME/12)
There is no need to change anything in the message: the sender knows to
which address send the message, and the recipient will request results
by contacting the address given by UDP, be it UDP/IPv6 or UDP/IPv4.
2.4.4 UDP Crawler Ping (LIME/5)
There is no provision in the LIME/5v1 to request IPv6 addresses, nor is
there any provision in the UDP Crawler Pong (LIME/6v1) to include them.
These messages therefore need to be extended as v2, using the "features"
byte to include a flag requesting IPv6. A new format will need to be
used for the reply Pong, probably using GGEP keys instead ("U" and "U6"
keys for ultras, "L" and "L6" for leaves, for instance). [To be specified
in another document]
The v1 message will only report IPv4 peers.
3. Header Extensions
All the Gnutella and HTTP headers that can propagate hosts in the form
of IP:port must be extended to allow inclusion of IPv6 addresses as well.
When emitting an ASCII representation for IPv6:port, the IPv6 address
MUST be included between brackets, such as:
[2001:3d4:12aa:200::5]:5400
The impacted headers are: X-Alt, X-Nalt, X-Falt, X-Push-Proxies,
X-FW-Node-Info and X-Try-Ultrapeers.
These headers can freely mix IPv4 and IPv6 addresses, as needed.
For instance:
X-Push-Proxies: [2001:3d4:12aa:200::5]:5400, 5.6.7.8:4600
In X-FW-Node-Info, the local host information is given as port:IP, and
this can also be an IPv6 address, which must be included within brackets
since it is given with a port number:
X-FW-Node-Info: 8ac8d3b457788a906f599b268698b200;fwt/1;
5400:[2001:3d4:12aa:200::5]
All IPv6-Ready servents must be able to parse these IPv6 addresses, but
do not necessarily need to use them. However, as will be described in
section 5, there is a mechanism to negotiate the level of IPv6 support
so that servents unaware of these specification are not impacted.
4. Network Connection
It is essential that servents equipped with both and IPv4 and an IPv6
address be listening on the two networks. Their "primary" IP address
advertised in query hits, pongs, etc... will be the IPv4 one, but they can
also include their IPv6 address to seed the IPv6 Gnutella network as well.
Given that IPv4 still has a solid core of Gnutella users and the IPv6-only
Gnutella network is today close to inexistent (due to lack of IPv6-Ready
specs so far), running Gnutella on IPv6 only is not going to be much
useful.
With time however, the number of servents with two addresses will start
to shrink and by then the IPv6-only network will start to consolidate.
As long as one has two addresses though, it will still be useful to
listen on the two networks, using whichever network is appropriate to
contact sources.
5. Communicating IPv6 Support Level
It would be a waste for servents to make use of the new GGEP extensions
defined
if they are not going to be understood by the recipient.
This section introduces new headers that need to be exchanged during
Gnutella handshaking and HTTP exchanges.
5.1 New Feature
But first, let us define a new feature (to be exchanged via the X-Features
header, defined for Gnutella and HTTP), called "IP".
Advertising the "IP" feature indicates that servent is IPv6-Ready.
All features have the form "NAME/major.minor". Here we define two versions
of the IP feature to convey different meanings:
- "IP/6.0" indicates that the servent has both IPv4 and IPv6 connectivity.
It can accept IPv6 and IPv4 addresses, so one should send back "ALT" or
"ALT6" extensions in query hits for instance, or freely mix IPv4 and
IPv6 addresses in X-Push-Proxies or in X-Try-Ultrapeers headers.
- "IP/6.4" indicates that the servent has only IPv6 connectivity and does
not support IPv4 at all. There should only be IPv6 addresses given in
X-Alt headers for instance, including IPv4 being a waste as the servent
will have no way to validate these alternate locations.
Not seeing the "IP" feature advertised means the servent is not IPv6-Ready
and should only be given IPv4 addresses in headers, and only legacy GGEP
extensions like "IPP", "ALT", etc...
5.2 Gnutella Headers
All Gnutella handshakes made by IPv6-Ready servents MUST include the
"IP" feature at the proper version number.
Here is a sample X-Features line for Gnutella handshakes:
X-Features: tls/1.0, browse/1.0, sflag/0.1, HSEP/0.2, IP/6.0
We see a list of features, all separated by "," (they could also each be
emitted on distinct X-Features: lines, however it would be more verbose).
Since we see "IP/6.0" there, we know we can supply IPv6 addresses in
X-Try-Ultrapeers, should we refuse the Gnutella connection.
In addition to the X-Features line, all IPv6-Ready servents MUST include
a new GUID: header, listing their GUID in hexadecimal format.
The reason for the GUID: header is to be able to detect duplicate
connections. Since a servent can listen to both IPv4 and IPv6, one could
easily end up connecting to the same servent using the two different
network protocols to establish the link. The GUID header is then going
to tell us that we are connecting twice to the same host and we can then
close the connection -- if the remote end does not do it already, since
we also supply our own GUID, hence a remote servent could (and should)
perform the same detection.
Example of a valid GUID header:
GUID: 7c406ae0b8286c939f12fb8b50ed7a0e
5.3 HTTP Headers
All HTTP exchanges should include the X-Features line (at least once,
in the first request, not necessarily for each follow-up request on
the same connection) listing the "IP" feature and the proper version,
as explained in 5.1.
As for GUID exchanges, normally all HTTP servers should include X-GUID
or X-FW-Node-Info (when firewalled, supplying the GUID), so servents
will be able to detect they're trying to download from the same server
(listening on both IPv4 and IPv6). A server not listening to both IPv4
and IPv6 does not need to generate a X-GUID header for that purpose
(but may wish to do so anyway, especially if it is DHT-enabled).
Downloaders are not required to send an X-GUID header but MUST ensure
they are not attempting to download twice the same resource from the
same server using two different networks, in order to be fair to others
and not cannibalize uploading resources. To that end, they must parse
the GUID indication from the server supplied via either the X-GUID or
the X-FW-Node-Info line.
5.4 Ping
The "SCP" payload is extended to include two new flags:
0x4 Node also wants IPv6 addresses
0x8 Node does not want any IPv4
These flags govern whether "IPP" or "IPP6" (or both) will be sent back.
Legacy servents will not supply any of these flags and will therefore
only get back "IPP" in their pongs.
5.5 Queries and HEAD Ping
Gnutella queries and HEAD Ping request must include an empty "I6" GGEP
extension to advertise that they can accept IPv6 addresses. If they
can only accept IPv6, then they must include a 1 byte payload with the
value 1.
Without "I6", queries and HEAD Ping will continue to only return IPv4
addresses, for legacy servents.
IPv6-Ready servents should not include "I6" unless they have an IPv6
address on which they are listening.
Note that for queries, "I6" needs to be inserted regardless of the
presence of "6". Indeed, "6" is tied to OOB replies, and a query can be
OOB-proxied by a servent running both IPv4 and IPv6, in which case there
would be no "6". So "6" and "I6" in queries serve different roles and
should not be confused.
5.6 GUESS Queries
GUESS 0.2 queries can include an "SCP" extension to request more GUESS
hosts returned in a packed "IPP". The same set of flags defined in 5.4
for Ping are applicable there as well.
6. On the Filling Strategy
When a host indicates support for both IPv4 and IPv6 and we have to fill
in vectors of IP:port like "IPP" and "IPP6", what should be the allocation
strategy when we have a large pool of both IPv4 and IPv6 addresses?
Since the long-term goal is to run an IPv6-only network, we should favor
the IPv6 network. Therefore, hosts present on both IPv4 and IPv6 should
get more IPv6 addresses than IPv4 addresses.
Therefore, in our example, one should start filling up the "IPP6"
extension with as many IPv6:port entries as possible. Then, if there
is enough room left or we included too little entries, fill up "IPP".
This filling strategy does not apply to the download mesh exchange where
there are less entries available than in a host cache. It is probably
better for X-Alt to fill up whatever is available and is matching the
requested IP network, randomly picking entries if all cannot fit in the
allocated reply buffer.
For Push Proxies, which are limited to a handful of addresses, simply
select the addresses matching the request (IPv4, IPv6 or both).
7. Additional Considerations
In order to fully support the IPv6 Gnutella core, as it will form, it is
important to make UHC caches (such as GhostWhiteCrab) IPv6-Ready as well,
in order to give IPv6 servents the ability to bootstrap.
The DHT side of Gnutella will need to be made fully IPv6-Ready. This will
be the focus of a separate document, as making the DHT IPv6-Ready requires
that "DOVE" (DHT Open Versatile Extension) be implemented first.
A. Change History
June 22nd, 2011 - initial publishing
--y09etRhHkCNtips6-d8sup9HpD0JiGa8UsGmZ1d
Content-Type: text/html; charset=US-ASCII
Content-Transfer-Encoding: 7bit
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
</head>
<body style="background-color: #fff;">
<span style="display:none"> </span>
<!--~-|**|PrettyHtmlStartT|**|-~-->
<div id="ygrp-mlmsg" style="position:relative;">
<div id="ygrp-msg" style="z-index: 1;">
<!--~-|**|PrettyHtmlEndT|**|-~-->
<div id="ygrp-text" >
<p> Making Gnutella "IPv6-Ready"<br>
<br>
Raphael Manfredi<br>
<<a href="mailto:Raphael_Manfredi%40pobox.com">[email protected]</a>><br>
<br>
June 22nd, 2011<br>
<br>
1. Introduction<br>
<br>
Now that IPv4 address exhaustion is a fact, there is going to be a<br>
huge incentive to accelerate IPv6 deployment. People equipped with<br>
an IPv4 address are going to be supplied an IPv6 address (actually a<br>
network prefix where they can host several thousands of machines, if<br>
not millions) whilst others are going to only have IPv6, without any<br>
IPv4 address at all.<br>
<br>
The Gnutella protocol needs to evolve slightly to make it possible<br>
to run on IPv6 because it architected some of its core fields holding<br>
IP addresses as being 4-byte long, i.e. only capable of storing IPv4<br>
addresses.<br>
<br>
However, IPv6 is a totally new network protocol, distinct from IPv4.<br>
Although there are some mechanisms in IPv6 to be able to reach IPv4<br>
addresses, the necessary translation mechanisms may not be available<br>
everywhere. This means Gnutella on IPv6 is going to form a network<br>
overlay completely distinct than the current Gnutella network, which<br>
is IPv4-based.<br>
<br>
Fortunately, the fact that many people are going to be given an IPv6<br>
address in addition to a legacy IPv4 one is an opportunity to bootstrap<br>
the IPv6 network nicely, until there are sufficient IPv6 peers to create<br>
a stable Gnutella core.<br>
<br>
This article only focuses on the Gnutella network protocol changes<br>
that must be incorporated into the Gnutella servents to make them<br>
"IPv6-Ready", that is capable of being a part of the IPv6-only Gnutella<br>
network tomorrow. Servents that are not IPv6-Ready are condemned to stick<br>
to the IPv4 network, which will be slowly dying first, until a critical<br>
point is reached at which time the stable IPv4 core will disappear,<br>
replaced by the IPv6 core.<br>
<br>
These IPv6-Ready Specifications are meant to be totally backward<br>
compatible, so that legacy servents see almost no difference and can<br>
still usefully interact with modern IPv6-Ready servents.<br>
<br>
2. Gnutella Messages<br>
<br>
This section introduces new GGEP extensions to be used in various Gnutella<br>
messages to be able to transport IPv6 addresses.<br>
<br>
2.1 Legacy Messages<br>
<br>
The following Gnutella messages have been historically architected to<br>
hold IPv4 addresses only: Pong, Query Hit, Push.<br>
<br>
To expand them so that they can hold an additional IPv6 address or simply<br>
a single IPv6 one, two strategic GGEP extensions are introduced:<br>
<br>
The "I6" extension holds a full IPv6 address, in raw binary big-endian<br>
format, that is 16 bytes. Its presence in Pong, Push or Query Hit<br>
trailer indicates that the servent is running both on IPv4 and on IPv6.<br>
<br>
The "6" extension holds the *leading* 12 bytes of the IPv6 address, the<br>
trailing 4 bytes being held in the legacy IPv4 field of the message.<br>
The IPv6 address needs therefore to be reconstructed by concatenating<br>
the leading 12 bytes (big-endian) of the "6" extension payload with<br>
the trailing 4 bytes (big-endian) of the legacy field to form the 16<br>
bytes (big-endian) of the servent's IPv6 address. The presence of this<br>
extension indicates that the servent only has an IPv6 address.<br>
<br>
This design has the following properties:<br>
<br>
- It clearly communicates the level of IPv6 support: IPv4 only (neither<br>
"I6" nor "6" present), IPv4 and IPv6 support ("I6" present), IPv6 only<br>
("6" present).<br>
<br>
- When parsed by a non IPv6-Ready servent, the IPv4 field will be<br>
meaningful most of the time, excepted when "6" is present.<br>
In that case however, since the address read will be the lowest 4 bytes<br>
of the actual IPv6 address, it is likely that this will be read as an<br>
address in 0/8, which is an invalid IPv4 address block.<br>
<br>
- Ultimately when everyone uses IPv6, the legacy 4-byte field will not be<br>
wasted. Everyone will be sending "6" extensions, thereby optimizing the<br>
overhead.<br>
<br>
2.2 Extended Messages<br>
<br>
Over time, some legacy messages have been extended with GGEP extensions<br>
to transport packed IPv4:port tuples. These are the "IPP", "ALT",<br>
"PUSH" extensions found in pongs or in query hits, forming vectors of<br>
6-byte items.<br>
<br>
All the legacy extensions are kept but new ones are introduced<br>
specifically for transporting packed IPv6:port tuples, the IPv6 address<br>
being in big-endian and the port in little-endian, to form a vector of<br>
18-byte items.<br>
<br>
The "ALT6" and "ALT6_TLS" extensions are introduced for query hits:<br>
"ALT6" packs IPv6:port alternate locations and "ALT6_TLS" is like<br>
"ALT_TLS" but applies to the "ALT6" vector, indicating which of the<br>
alternate location hosts are known to support TLS.<br>
<br>
Likewise, the "IPP6" and "IPP6_TLS" extensions are introduced for UHC<br>
pongs, "PUSH6" and "PUSH6_TLS" for query hits push-proxies.<br>
<br>
The "IP" extension in Pongs (used to send back the IP:port of the remote<br>
host) is extended to be able to hold IPv4:port or IPv6:port, as needed.<br>
The size of the extension payload (6 or 18 bytes) will discriminate<br>
between the two forms.<br>
<br>
2.3 OOB Queries<br>
<br>
Queries requesting Out Of Band hit delivery encode the IPv4 address of<br>
the recipient in the GUID.<br>
<br>
Queries requiring that delivery by sent back to an IPv6 address must<br>
use the same splitting technique as described in 2.1: the leading 12<br>
bytes of the address are put in a GGEP "6" extension, the trailing 4<br>
bytes being left in the GUID.<br>
<br>
Because there is no guarantee that the servent reporting hits will support<br>
IPv6, the "6" extension should only be used when there is no other choice,<br>
i.e. when the querying party only has access to IPv6.<br>
<br>
Otherwise, chances are that the lowest 4 bytes of the IPv6 address will<br>
form an invalid IPv4 address (since this is how a non IPv6-Ready servent<br>
would interpret the IP address) and the hit will simply be sent back<br>
through Gnutella (i.e. the OOB bit will be ignored).<br>
<br>
2.4 Vendor Messages<br>
<br>
2.4.1 HEAD Ping and HEAD Pong (LIME/23 and LIME/24)<br>
<br>
GGEP "A6" and "T6" are introduced for HEAD pongs (v2) to transport IPv6<br>
alt locations and TLS indication (mirroring "A" and "T"). Since HEAD<br>
pongs (v1) cannot be made IPv6-Ready, servents should obsolete HEAD<br>
ping (v1) requests and only send v2 ones (LIME/23v2 vendor messages aka<br>
"HEAD Ping", answered to by LIME/24v2 aka "HEAD Pong").<br>
<br>
2.4.2 Connect Back<br>
<br>
There is no need to change the connect back messages (BEAR/7 and GTKG/7):<br>
they connect back to the originating address as communicated by the TCP<br>
or UDP layer, be it on top of IPv4 or IPv6.<br>
<br>
2.4.3 OOB Reply Indication (LIME/12)<br>
<br>
There is no need to change anything in the message: the sender knows to<br>
which address send the message, and the recipient will request results<br>
by contacting the address given by UDP, be it UDP/IPv6 or UDP/IPv4.<br>
<br>
2.4.4 UDP Crawler Ping (LIME/5)<br>
<br>
There is no provision in the LIME/5v1 to request IPv6 addresses, nor is<br>
there any provision in the UDP Crawler Pong (LIME/6v1) to include them.<br>
<br>
These messages therefore need to be extended as v2, using the "features"<br>
byte to include a flag requesting IPv6. A new format will need to be<br>
used for the reply Pong, probably using GGEP keys instead ("U" and "U6"<br>
keys for ultras, "L" and "L6" for leaves, for instance). [To be specified<br>
in another document]<br>
<br>
The v1 message will only report IPv4 peers.<br>
<br>
3. Header Extensions<br>
<br>
All the Gnutella and HTTP headers that can propagate hosts in the form<br>
of IP:port must be extended to allow inclusion of IPv6 addresses as well.<br>
<br>
When emitting an ASCII representation for IPv6:port, the IPv6 address<br>
MUST be included between brackets, such as:<br>
<br>
[2001:3d4:12aa:200::5]:5400<br>
<br>
The impacted headers are: X-Alt, X-Nalt, X-Falt, X-Push-Proxies,<br>
X-FW-Node-Info and X-Try-Ultrapeers.<br>
<br>
These headers can freely mix IPv4 and IPv6 addresses, as needed.<br>
For instance:<br>
<br>
X-Push-Proxies: [2001:3d4:12aa:200::5]:5400, 5.6.7.8:4600<br>
<br>
In X-FW-Node-Info, the local host information is given as port:IP, and<br>
this can also be an IPv6 address, which must be included within brackets<br>
since it is given with a port number:<br>
<br>
X-FW-Node-Info: 8ac8d3b457788a906f599b268698b200;fwt/1;<br>
5400:[2001:3d4:12aa:200::5]<br>
<br>
All IPv6-Ready servents must be able to parse these IPv6 addresses, but<br>
do not necessarily need to use them. However, as will be described in<br>
section 5, there is a mechanism to negotiate the level of IPv6 support<br>
so that servents unaware of these specification are not impacted.<br>
<br>
4. Network Connection<br>
<br>
It is essential that servents equipped with both and IPv4 and an IPv6<br>
address be listening on the two networks. Their "primary" IP address<br>
advertised in query hits, pongs, etc... will be the IPv4 one, but they can<br>
also include their IPv6 address to seed the IPv6 Gnutella network as well.<br>
<br>
Given that IPv4 still has a solid core of Gnutella users and the IPv6-only<br>
Gnutella network is today close to inexistent (due to lack of IPv6-Ready<br>
specs so far), running Gnutella on IPv6 only is not going to be much<br>
useful.<br>
<br>
With time however, the number of servents with two addresses will start<br>
to shrink and by then the IPv6-only network will start to consolidate.<br>
As long as one has two addresses though, it will still be useful to<br>
listen on the two networks, using whichever network is appropriate to<br>
contact sources.<br>
<br>
5. Communicating IPv6 Support Level<br>
<br>
It would be a waste for servents to make use of the new GGEP extensions<br>
defined<br>
<br>
if they are not going to be understood by the recipient.<br>
<br>
This section introduces new headers that need to be exchanged during<br>
Gnutella handshaking and HTTP exchanges.<br>
<br>
5.1 New Feature<br>
<br>
But first, let us define a new feature (to be exchanged via the X-Features<br>
header, defined for Gnutella and HTTP), called "IP".<br>
<br>
Advertising the "IP" feature indicates that servent is IPv6-Ready.<br>
<br>
All features have the form "NAME/major.minor". Here we define two versions<br>
of the IP feature to convey different meanings:<br>
<br>
- "IP/6.0" indicates that the servent has both IPv4 and IPv6 connectivity.<br>
It can accept IPv6 and IPv4 addresses, so one should send back "ALT" or<br>
"ALT6" extensions in query hits for instance, or freely mix IPv4 and<br>
IPv6 addresses in X-Push-Proxies or in X-Try-Ultrapeers headers.<br>
<br>
- "IP/6.4" indicates that the servent has only IPv6 connectivity and does<br>
not support IPv4 at all. There should only be IPv6 addresses given in<br>
X-Alt headers for instance, including IPv4 being a waste as the servent<br>
will have no way to validate these alternate locations.<br>
<br>
Not seeing the "IP" feature advertised means the servent is not IPv6-Ready<br>
and should only be given IPv4 addresses in headers, and only legacy GGEP<br>
extensions like "IPP", "ALT", etc...<br>
<br>
5.2 Gnutella Headers<br>
<br>
All Gnutella handshakes made by IPv6-Ready servents MUST include the<br>
"IP" feature at the proper version number.<br>
<br>
Here is a sample X-Features line for Gnutella handshakes:<br>
<br>
X-Features: tls/1.0, browse/1.0, sflag/0.1, HSEP/0.2, IP/6.0<br>
<br>
We see a list of features, all separated by "," (they could also each be<br>
emitted on distinct X-Features: lines, however it would be more verbose).<br>
<br>
Since we see "IP/6.0" there, we know we can supply IPv6 addresses in<br>
X-Try-Ultrapeers, should we refuse the Gnutella connection.<br>
<br>
In addition to the X-Features line, all IPv6-Ready servents MUST include<br>
a new GUID: header, listing their GUID in hexadecimal format.<br>
<br>
The reason for the GUID: header is to be able to detect duplicate<br>
connections. Since a servent can listen to both IPv4 and IPv6, one could<br>
easily end up connecting to the same servent using the two different<br>
network protocols to establish the link. The GUID header is then going<br>
to tell us that we are connecting twice to the same host and we can then<br>
close the connection -- if the remote end does not do it already, since<br>
we also supply our own GUID, hence a remote servent could (and should)<br>
perform the same detection.<br>
<br>
Example of a valid GUID header:<br>
<br>
GUID: 7c406ae0b8286c939f12fb8b50ed7a0e<br>
<br>
5.3 HTTP Headers<br>
<br>
All HTTP exchanges should include the X-Features line (at least once,<br>
in the first request, not necessarily for each follow-up request on<br>
the same connection) listing the "IP" feature and the proper version,<br>
as explained in 5.1.<br>
<br>
As for GUID exchanges, normally all HTTP servers should include X-GUID<br>
or X-FW-Node-Info (when firewalled, supplying the GUID), so servents<br>
will be able to detect they're trying to download from the same server<br>
(listening on both IPv4 and IPv6). A server not listening to both IPv4<br>
and IPv6 does not need to generate a X-GUID header for that purpose<br>
(but may wish to do so anyway, especially if it is DHT-enabled).<br>
<br>
Downloaders are not required to send an X-GUID header but MUST ensure<br>
they are not attempting to download twice the same resource from the<br>
same server using two different networks, in order to be fair to others<br>
and not cannibalize uploading resources. To that end, they must parse<br>
the GUID indication from the server supplied via either the X-GUID or<br>
the X-FW-Node-Info line.<br>
<br>
5.4 Ping<br>
<br>
The "SCP" payload is extended to include two new flags:<br>
<br>
0x4 Node also wants IPv6 addresses<br>
0x8 Node does not want any IPv4<br>
<br>
These flags govern whether "IPP" or "IPP6" (or both) will be sent back.<br>
Legacy servents will not supply any of these flags and will therefore<br>
only get back "IPP" in their pongs.<br>
<br>
5.5 Queries and HEAD Ping<br>
<br>
Gnutella queries and HEAD Ping request must include an empty "I6" GGEP<br>
extension to advertise that they can accept IPv6 addresses. If they<br>
can only accept IPv6, then they must include a 1 byte payload with the<br>
value 1.<br>
<br>
Without "I6", queries and HEAD Ping will continue to only return IPv4<br>
addresses, for legacy servents.<br>
<br>
IPv6-Ready servents should not include "I6" unless they have an IPv6<br>
address on which they are listening.<br>
<br>
Note that for queries, "I6" needs to be inserted regardless of the<br>
presence of "6". Indeed, "6" is tied to OOB replies, and a query can be<br>
OOB-proxied by a servent running both IPv4 and IPv6, in which case there<br>
would be no "6". So "6" and "I6" in queries serve different roles and<br>
should not be confused.<br>
<br>
5.6 GUESS Queries<br>
<br>
GUESS 0.2 queries can include an "SCP" extension to request more GUESS<br>
hosts returned in a packed "IPP". The same set of flags defined in 5.4<br>
for Ping are applicable there as well.<br>
<br>
6. On the Filling Strategy<br>
<br>
When a host indicates support for both IPv4 and IPv6 and we have to fill<br>
in vectors of IP:port like "IPP" and "IPP6", what should be the allocation<br>
strategy when we have a large pool of both IPv4 and IPv6 addresses?<br>
<br>
Since the long-term goal is to run an IPv6-only network, we should favor<br>
the IPv6 network. Therefore, hosts present on both IPv4 and IPv6 should<br>
get more IPv6 addresses than IPv4 addresses.<br>
<br>
Therefore, in our example, one should start filling up the "IPP6"<br>
extension with as many IPv6:port entries as possible. Then, if there<br>
is enough room left or we included too little entries, fill up "IPP".<br>
<br>
This filling strategy does not apply to the download mesh exchange where<br>
there are less entries available than in a host cache. It is probably<br>
better for X-Alt to fill up whatever is available and is matching the<br>
requested IP network, randomly picking entries if all cannot fit in the<br>
allocated reply buffer.<br>
<br>
For Push Proxies, which are limited to a handful of addresses, simply<br>
select the addresses matching the request (IPv4, IPv6 or both).<br>
<br>
7. Additional Considerations<br>
<br>
In order to fully support the IPv6 Gnutella core, as it will form, it is<br>
important to make UHC caches (such as GhostWhiteCrab) IPv6-Ready as well,<br>
in order to give IPv6 servents the ability to bootstrap.<br>
<br>
The DHT side of Gnutella will need to be made fully IPv6-Ready. This will<br>
be the focus of a separate document, as making the DHT IPv6-Ready requires<br>
that "DOVE" (DHT Open Versatile Extension) be implemented first.<br>
<br>
A. Change History<br>
<br>
June 22nd, 2011 - initial publishing<br>
</p>
</div>
<!--~-|**|PrettyHtmlStart|**|-~-->
<div style="color: #fff; height: 0;">__._,_.___</div>
<div id="ygrp-actbar" style="clear: both; margin-bottom: 10px; white-space: nowrap; color: #666; padding-top: 15px;">
<div>
<a href="mailto:[email protected]?subject=Re%3A%20Making%20Gnutella%20%22IPv6-Ready%22" style="margin-right: 0; padding-right: 0;">
Reply to <span style="font-weight: 700;">sender</span></a> |
<a href="mailto:[email protected]?subject=Re%3A%20Making%20Gnutella%20%22IPv6-Ready%22">
Reply to <span style="font-weight: 700;">group</span></a> |
<a href="http://groups.yahoo.com/group/the_gdf/post;_ylc=X3oDMTJxZGJ2MnZoBF9TAzk3MzU5NzE0BGdycElkAzI2ODQyNTMEZ3Jwc3BJZAMxNzA1MDE2MDYxBG1zZ0lkAzIzNzg2BHNlYwNmdHIEc2xrA3JwbHkEc3RpbWUDMTMwODc3MzI2OA--?act=reply&messageNum=23786">Reply <span style="font-weight: 700;">via web post</span></a> |
<a href="http://groups.yahoo.com/group/the_gdf/post;_ylc=X3oDMTJldDZscWcwBF9TAzk3MzU5NzE0BGdycElkAzI2ODQyNTMEZ3Jwc3BJZAMxNzA1MDE2MDYxBHNlYwNmdHIEc2xrA250cGMEc3RpbWUDMTMwODc3MzI2OA--" style="font-weight: 700;">Start a New Topic</a>
</div>
<a href="http://groups.yahoo.com/group/the_gdf/message/23786;_ylc=X3oDMTM2MDMxOGttBF9TAzk3MzU5NzE0BGdycElkAzI2ODQyNTMEZ3Jwc3BJZAMxNzA1MDE2MDYxBG1zZ0lkAzIzNzg2BHNlYwNmdHIEc2xrA3Z0cGMEc3RpbWUDMTMwODc3MzI2OAR0cGNJZAMyMzc4Ng--">Messages in this topic</a>
(<span style="font-weight: 700;">1</span>)
</div>
<!------- Start Nav Bar ------>
<!-- |**|begin egp html banner|**| -->
<div id="ygrp-vital" style="background-color: #e0ecee; font-family: Verdana; font-size: 10px; margin-bottom: 10px; padding: 10px;">
<span id="vithd" style="font-weight: bold; color: #333; text-transform: uppercase; ">Recent Activity:</span>
<ul style="list-style-type: none; margin: 0; padding: 0; display: inline;">
<li style="border-right: 1px solid #000; font-weight: 700; display: inline; padding: 0 5px; margin-left: 0;">
<span class="cat"><a href="http://groups.yahoo.com/group/the_gdf/members;_ylc=X3oDMTJmZHBndXRmBF9TAzk3MzU5NzE0BGdycElkAzI2ODQyNTMEZ3Jwc3BJZAMxNzA1MDE2MDYxBHNlYwN2dGwEc2xrA3ZtYnJzBHN0aW1lAzEzMDg3NzMyNjg-?o=6" style="text-decoration: none;">New Members</a></span>
<span class="ct" style="color: #ff7900;">2</span>
</li>
<li style="border-right: 1px solid #000; font-weight: 700; display: inline; padding: 0 5px; margin-left: 0;">
<span class="cat"><a href="http://groups.yahoo.com/group/the_gdf/links;_ylc=X3oDMTJnNW9vOWFzBF9TAzk3MzU5NzE0BGdycElkAzI2ODQyNTMEZ3Jwc3BJZAMxNzA1MDE2MDYxBHNlYwN2dGwEc2xrA3ZsaW5rcwRzdGltZQMxMzA4NzczMjY4" style="text-decoration: none;">New Links</a></span>
<span class="ct" style="color: #ff7900;">1</span>
</li>
</ul>
<div style="clear: both; padding-top: 2px; color: #1e66ae;">
<a href="http://groups.yahoo.com/group/the_gdf;_ylc=X3oDMTJlaTFpdm1nBF9TAzk3MzU5NzE0BGdycElkAzI2ODQyNTMEZ3Jwc3BJZAMxNzA1MDE2MDYxBHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTMwODc3MzI2OA--" style="text-decoration: none;">Visit Your Group</a>
</div>
</div>
<div id="ft" style="font-family: Arial; font-size: 11px; margin-top: 5px; padding: 0 2px 0 0; clear: both;">
<a href="http://groups.yahoo.com/;_ylc=X3oDMTJkN2Fzc2RlBF9TAzk3MzU5NzE0BGdycElkAzI2ODQyNTMEZ3Jwc3BJZAMxNzA1MDE2MDYxBHNlYwNmdHIEc2xrA2dmcARzdGltZQMxMzA4NzczMjY4" style="float: left;"><img src="http://l.yimg.com/a/i/us/yg/logo/us.gif" height="15" width="137" alt="Yahoo! Groups" style="border: 0;"/></a>
<div style="color: #747575; float: right;">Switch to: <a href="mailto:[email protected]?subject=Change Delivery Format: Traditional" style="text-decoration: none;">Text-Only</a>, <a href="mailto:[email protected]?subject=Email Delivery: Digest" class="margin-rt" style="text-decoration: none;">Daily Digest</a> • <a href="mailto:[email protected]?subject=Unsubscribe" style="text-decoration: none;">Unsubscribe</a> • <a href="http://docs.yahoo.com/info/terms/" style="text-decoration: none;">Terms of Use</a></div>
</div>
<!-- |**|end egp html banner|**| -->
</div> <!-- ygrp-msg -->
<!-- Sponsor -->
<!-- |**|begin egp html banner|**| -->
<div id="ygrp-sponsor" style="width:160px; float:right; clear:none; margin:0 0 25px 0; background: #fff;">
<!-- Start Recommendations -->
<div id="ygrp-reco">
</div>
<!-- End Recommendations -->
</div> <!-- |**|end egp html banner|**| -->
<div style="clear:both; color: #FFF; font-size:1px;">.</div>
</div>
<img src="http://geo.yahoo.com/serv?s=97359714/grpId=2684253/grpspId=1705016061/msgId=23786/stime=1308773268/nc1=1/nc2=2/nc3=3" width="1" height="1"> <br>
<div style="color: #fff; height: 0;">__,_._,___</div>
<!--~-|**|PrettyHtmlEnd|**|-~-->
</body>
<!--~-|**|PrettyHtmlStart|**|-~-->
<head>
<style type="text/css">
<!--
#ygrp-mkp {
border: 1px solid #d8d8d8;
font-family: Arial;
margin: 10px 0;
padding: 0 10px;
}
#ygrp-mkp hr {
border: 1px solid #d8d8d8;
}
#ygrp-mkp #hd {
color: #628c2a;
font-size: 85%;
font-weight: 700;
line-height: 122%;
margin: 10px 0;
}
#ygrp-mkp #ads {
margin-bottom: 10px;
}
#ygrp-mkp .ad {
padding: 0 0;
}
#ygrp-mkp .ad p {
margin: 0;
}
#ygrp-mkp .ad a {
color: #0000ff;
text-decoration: none;
}
#ygrp-sponsor #ygrp-lc {
font-family: Arial;
}
#ygrp-sponsor #ygrp-lc #hd {
margin: 10px 0px;
font-weight: 700;
font-size: 78%;
line-height: 122%;
}
#ygrp-sponsor #ygrp-lc .ad {
margin-bottom: 10px;
padding: 0 0;
}
a {
color: #1e66ae;
}
#actions {
font-family: Verdana;
font-size: 11px;
padding: 10px 0;
}
#activity {
background-color: #e0ecee;
float: left;
font-family: Verdana;
font-size: 10px;
padding: 10px;
}
#activity span {
font-weight: 700;
}
#activity span:first-child {
text-transform: uppercase;
}
#activity span a {
color: #5085b6;
text-decoration: none;
}
#activity span span {
color: #ff7900;
}
#activity span .underline {
text-decoration: underline;
}
.attach {
clear: both;
display: table;
font-family: Arial;
font-size: 12px;
padding: 10px 0;
width: 400px;
}
.attach div a {
text-decoration: none;
}
.attach img {
border: none;
padding-right: 5px;
}
.attach label {
display: block;
margin-bottom: 5px;
}
.attach label a {
text-decoration: none;
}
blockquote {
margin: 0 0 0 4px;
}
.bold {
font-family: Arial;
font-size: 13px;
font-weight: 700;
}
.bold a {
text-decoration: none;
}
dd.last p a {
font-family: Verdana;
font-weight: 700;
}
dd.last p span {
margin-right: 10px;
font-family: Verdana;
font-weight: 700;
}
dd.last p span.yshortcuts {
margin-right: 0;
}
div.attach-table div div a {
text-decoration: none;
}
div.attach-table {
width: 400px;
}
div.file-title a, div.file-title a:active, div.file-title a:hover, div.file-title a:visited {
text-decoration: none;
}
div.photo-title a, div.photo-title a:active, div.photo-title a:hover, div.photo-title a:visited {
text-decoration: none;
}
div#ygrp-mlmsg #ygrp-msg p a span.yshortcuts {
font-family: Verdana;
font-size: 10px;
font-weight: normal;
}
.green {
color: #628c2a;
}
.MsoNormal {
margin: 0 0 0 0;
}
o {
font-size: 0;
}
#photos div {
float: left;
width: 72px;
}
#photos div div {
border: 1px solid #666666;
height: 62px;
overflow: hidden;
width: 62px;
}
#photos div label {
color: #666666;
font-size: 10px;
overflow: hidden;
text-align: center;
white-space: nowrap;
width: 64px;
}
#reco-category {
font-size: 77%;
}
#reco-desc {
font-size: 77%;
}
.replbq {
margin: 4px;
}
#ygrp-actbar div a:first-child {
/* border-right: 0px solid #000;*/
margin-right: 2px;
padding-right: 5px;
}
#ygrp-mlmsg {
font-size: 13px;
font-family: Arial, helvetica,clean, sans-serif;
*font-size: small;
*font: x-small;
}
#ygrp-mlmsg table {
font-size: inherit;
font: 100%;
}
#ygrp-mlmsg select, input, textarea {
font: 99% Arial, Helvetica, clean, sans-serif;
}
#ygrp-mlmsg pre, code {
font:115% monospace;
*font-size:100%;
}
#ygrp-mlmsg * {
line-height: 1.22em;
}
#ygrp-mlmsg #logo {
padding-bottom: 10px;
}
#ygrp-mlmsg a {
color: #1E66AE;
}
#ygrp-msg p a {
font-family: Verdana;
}
#ygrp-msg p#attach-count span {
color: #1E66AE;
font-weight: 700;
}
#ygrp-reco #reco-head {
color: #ff7900;
font-weight: 700;
}
#ygrp-reco {
margin-bottom: 20px;
padding: 0px;
}
#ygrp-sponsor #ov li a {
font-size: 130%;
text-decoration: none;
}
#ygrp-sponsor #ov li {
font-size: 77%;
list-style-type: square;
padding: 6px 0;
}
#ygrp-sponsor #ov ul {
margin: 0;
padding: 0 0 0 8px;
}
#ygrp-text {
font-family: Georgia;
}
#ygrp-text p {
margin: 0 0 1em 0;
}
#ygrp-text tt {
font-size: 120%;
}
#ygrp-vital ul li:last-child {
border-right: none !important;
}
-->
</style>
</head>
<!--~-|**|PrettyHtmlEnd|**|-~-->
</html>
<!-- end group email -->
--y09etRhHkCNtips6-d8sup9HpD0JiGa8UsGmZ1d--