<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://g2.doxu.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kath</id>
	<title>Gnutella2 - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://g2.doxu.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kath"/>
	<link rel="alternate" type="text/html" href="https://g2.doxu.org/wiki/Special:Contributions/Kath"/>
	<updated>2026-04-28T03:07:41Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.38.4</generator>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Query_Hash_Tables&amp;diff=1647</id>
		<title>Query Hash Tables</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Query_Hash_Tables&amp;diff=1647"/>
		<updated>2005-03-28T11:55:55Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Table Exchange */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Building an efficient network topology is not viable without means to restrict the flow&lt;br /&gt;
of information appropriately. In the Gnutella2 network architecture, neighbouring&lt;br /&gt;
nodes exchange compressed hash filter tables describing the content, which can be&lt;br /&gt;
reached by communicating with them. These tables are updated dynamically as&lt;br /&gt;
necessary.&lt;br /&gt;
&lt;br /&gt;
The concept of filtering hash tables in file sharing was pioneered by Limegroup for&lt;br /&gt;
the LimeWire? Gnutella1 application.&lt;br /&gt;
&lt;br /&gt;
== Table Properties ==&lt;br /&gt;
&lt;br /&gt;
Query hash tables or QHTs provide enough information to know with certainty that a&lt;br /&gt;
particular node (and possibly its descendants) will not be able to provide any&lt;br /&gt;
matching objects for a given query. Conversely, the QHT may reveal that a node or&lt;br /&gt;
its descendants may be able to provide matching objects.&lt;br /&gt;
&lt;br /&gt;
This property means that queries can be discarded confidently when a transmission&lt;br /&gt;
is known to be unnecessary, while not providing the filtering or forwarding node, any&lt;br /&gt;
actual information about the searchable content. Neighbours know what their&lt;br /&gt;
neighbours do not have, but cannot say for sure what they do have. QHTs are also&lt;br /&gt;
very efficient, both in terms of exchange and maintenance and lookup cost.&lt;br /&gt;
&lt;br /&gt;
== Table Content ==&lt;br /&gt;
&lt;br /&gt;
A QHT is a table of 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt; bits, where each bit represents a unique word-hash value.&lt;br /&gt;
For example a table of 20 bits has 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; = 1048576 possible word-hash values. If&lt;br /&gt;
stored uncompressed this table would be 128 KB in size.&lt;br /&gt;
&lt;br /&gt;
In an empty table, every word-hash value bit will be &amp;quot;1&amp;quot;, which represents &amp;quot;empty&amp;quot;.&lt;br /&gt;
To populate the table with searchable content, an application must:&lt;br /&gt;
&lt;br /&gt;
* Locate every plain-text word and URN which could be searched for and produce a match/hit&lt;br /&gt;
* Hash the word with a simple hash function to produce a word-hash value which is 0 &amp;lt;= value &amp;lt; 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt;.&lt;br /&gt;
* Set the appropriate bit in the table to zero, representing &amp;quot;full&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Word Hashing ==&lt;br /&gt;
&lt;br /&gt;
Words are strings of one or more alphanumeric characters which are not all numeric.&lt;br /&gt;
&lt;br /&gt;
To convert a word into a hash value, the following case-insensitive algorithm is used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
// HashWord( string_ptr, char_count, table_bit_count );&lt;br /&gt;
DWORD CQueryHashTable::HashWord(LPCTSTR psz, int nLength, int nBits)&lt;br /&gt;
{&lt;br /&gt;
  DWORD nNumber = 0;&lt;br /&gt;
  int nByte = 0;&lt;br /&gt;
  for ( ; nLength &amp;gt; 0 ; nLength--, psz++ )&lt;br /&gt;
  {&lt;br /&gt;
    int nValue = tolower( *psz ) &amp;amp; 0xFF;&lt;br /&gt;
    nValue = nValue &amp;lt;&amp;lt; ( nByte * 8 );&lt;br /&gt;
    nByte = ( nByte + 1 ) &amp;amp; 3;&lt;br /&gt;
    nNumber = nNumber ^ nValue;&lt;br /&gt;
  }&lt;br /&gt;
  return HashNumber( nNumber, nBits );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DWORD CQueryHashTable::HashNumber(DWORD nNumber, int nBits)&lt;br /&gt;
{&lt;br /&gt;
  WORD64 nProduct = (WORD64)nNumber * (WORD64)0x4F1BBCDC;&lt;br /&gt;
  WORD64 nHash = ( nProduct &amp;lt;&amp;lt; 32 ) &amp;gt;&amp;gt; ( 32 + ( 32 - nBits ) );&lt;br /&gt;
  return (DWORD)nHash;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== URNs - A Special Case ==&lt;br /&gt;
&lt;br /&gt;
URNs are treated as a special case: rather than dividing them up into word tokens,&lt;br /&gt;
they are hashed as a complete fixed length string. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
urn:sha1:WIXYJFVJMIWNMUWPRPBGUTODIV52RMJA&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitprint URNs are actually composite values which include both a SHA1 and&lt;br /&gt;
TigerTree root value. Rather than adding the whole bitprint to the table, each of the&lt;br /&gt;
constituent URNs are added separately. This allows SHA1-only querying and TigerTree-only&lt;br /&gt;
querying. A root TigerTree URN takes the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
urn:tree:tiger/:CN25MLNU3XNN7IHKZMNOA63XG6SKDJ2W7Z3HONA&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other URNs should be expressed in their most natural form before being fed to the&lt;br /&gt;
word hash function.&lt;br /&gt;
&lt;br /&gt;
== Word Prefix Extensions ==&lt;br /&gt;
&lt;br /&gt;
For words consisting of at least five characters, it is often useful to be able to match&lt;br /&gt;
substrings within the word. Unfortunately, adding every possible substring of each&lt;br /&gt;
word would increase the density of the QHT, however, a simple and effective&lt;br /&gt;
compromise is available:&lt;br /&gt;
&lt;br /&gt;
For words with 5 or more characters:&lt;br /&gt;
&lt;br /&gt;
* Hash and add the whole word&lt;br /&gt;
* Hash and add the whole word minus the last character&lt;br /&gt;
* Hash and add the whole word minus the last two characters&lt;br /&gt;
&lt;br /&gt;
This allows searching on prefixes of the word, for example &amp;quot;match&amp;quot; will now match&lt;br /&gt;
&amp;quot;matches&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Table Exchange ==&lt;br /&gt;
&lt;br /&gt;
Nodes must keep their neighbouring hubs up-to-date with their latest local query&lt;br /&gt;
hash table at all times. Rather than sending the whole table whenever it changes,&lt;br /&gt;
nodes may opt to send a &amp;quot;table patch&amp;quot;, which includes only the difference between&lt;br /&gt;
the old and new table.&lt;br /&gt;
&lt;br /&gt;
The /[[QHT]] packet is used to supply a query hash table update to a neighbouring hub.&lt;br /&gt;
Its format is compatible with the Gnutella1 &amp;quot;query routing protocol&amp;quot;, except that&lt;br /&gt;
Gnutella2 requires a 1-bit per value table, while Gnutella1 requires a 4 or 8 bit per&lt;br /&gt;
value table. Gnutella2 supports patch compression using the deflate algorithm,&lt;br /&gt;
however, this should not be applied if the TCP link itself is compressed.&lt;br /&gt;
&lt;br /&gt;
== Table Access ==&lt;br /&gt;
&lt;br /&gt;
A table of 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt; bits can be stored in an array of bytes 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt;/8 long. To resolve a&lt;br /&gt;
hash-value into a byte and bit number, use the following equations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
int nByte = ( nHashValue &amp;gt;&amp;gt; 3 );&lt;br /&gt;
int nBit = ( nHashValue &amp;amp; 7 );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The least significant bit is numbered 0; the most significant bit is numbered 7. To set&lt;br /&gt;
a bit as empty (setting it to 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
table_ptr[ nByte ] |= ( 1 &amp;lt;&amp;lt; nBit );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To set a bit as full (setting it to zero):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
table_ptr[ nByte ] &amp;amp;= ~( 1 &amp;lt;&amp;lt; nBit );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Aggregate or Superset Table ==&lt;br /&gt;
&lt;br /&gt;
Nodes operating in hub mode must maintain an aggregate or superset query hash&lt;br /&gt;
table, consisting of their own searchable content combined with the QHTs supplied&lt;br /&gt;
by all connected leaves. This aggregate table is supplied to neighbouring hubs,&lt;br /&gt;
allowing them to completely filter traffic for the local hub and its leaves.&lt;br /&gt;
&lt;br /&gt;
This has two important implications:&lt;br /&gt;
* When a change is detected in either the local content or a connected leaf node's QHT, the aggregate table must be rebuilt and patches dispatched to neighbouring hubs. This will happen often, so an appropriate minimum time between updates should be used. One minute is effective.&lt;br /&gt;
* An aggregate table representing 400 leaves will be much denser than a table representing one node. This means that all tables must be large enough that the aggregate table remains productively sparse.&lt;br /&gt;
&lt;br /&gt;
To create an aggregate table, start with an empty table of fixed size containing all&lt;br /&gt;
1's. For each contributing table, copy any zero (full) bits to the aggregate table. This&lt;br /&gt;
is effectively an AND operation. If a source table is smaller than the aggregate table,&lt;br /&gt;
a single 0 bit in the source will equate to several zero bits in the aggregate. If the&lt;br /&gt;
source table is larger than the aggregate table, a single zero bit will map to a single&lt;br /&gt;
bit with some loss of accuracy.&lt;br /&gt;
&lt;br /&gt;
It is of great importance that all QHTs in the system be sufficiently large to allow an&lt;br /&gt;
aggregate table to remain suitably sparse. Ideally each leaf node should provide a&lt;br /&gt;
table less than 1% dense.&lt;br /&gt;
&lt;br /&gt;
== Query Filtering ==&lt;br /&gt;
&lt;br /&gt;
Before transmitting a query packet to a connection that has provided a query hash&lt;br /&gt;
table, match the words and URNs in the query against the QHT.&lt;br /&gt;
&lt;br /&gt;
* If any of the lookups based on URNs found a hit, send the query packet&lt;br /&gt;
* If at least two thirds of lookups based on words found a hit, send&lt;br /&gt;
* Otherwise, drop the packet&lt;br /&gt;
&lt;br /&gt;
It is important to apply the &amp;quot;two thirds&amp;quot; rule only for words. URNs must provide an&lt;br /&gt;
automatic match.&lt;br /&gt;
&lt;br /&gt;
Consider all text content in the query, including generic search text and metadata&lt;br /&gt;
search text if it is present. When dealing with simple query language that involves&lt;br /&gt;
quoted phrases and exclusions, apply the following rules:&lt;br /&gt;
&lt;br /&gt;
* Tokenize quoted phrases into words, ignoring the phrase at this level&lt;br /&gt;
* Ignore excluded words - these do not count as table hits or misses&lt;br /&gt;
* Remember to apply exclusion to every word in an excluded phrase&lt;br /&gt;
&lt;br /&gt;
See the section on the simple query language for more information.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Query_Hash_Tables&amp;diff=52</id>
		<title>Query Hash Tables</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Query_Hash_Tables&amp;diff=52"/>
		<updated>2005-03-28T11:54:40Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Word Prefix Extensions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Building an efficient network topology is not viable without means to restrict the flow&lt;br /&gt;
of information appropriately. In the Gnutella2 network architecture, neighbouring&lt;br /&gt;
nodes exchange compressed hash filter tables describing the content, which can be&lt;br /&gt;
reached by communicating with them. These tables are updated dynamically as&lt;br /&gt;
necessary.&lt;br /&gt;
&lt;br /&gt;
The concept of filtering hash tables in file sharing was pioneered by Limegroup for&lt;br /&gt;
the LimeWire? Gnutella1 application.&lt;br /&gt;
&lt;br /&gt;
== Table Properties ==&lt;br /&gt;
&lt;br /&gt;
Query hash tables or QHTs provide enough information to know with certainty that a&lt;br /&gt;
particular node (and possibly its descendants) will not be able to provide any&lt;br /&gt;
matching objects for a given query. Conversely, the QHT may reveal that a node or&lt;br /&gt;
its descendants may be able to provide matching objects.&lt;br /&gt;
&lt;br /&gt;
This property means that queries can be discarded confidently when a transmission&lt;br /&gt;
is known to be unnecessary, while not providing the filtering or forwarding node, any&lt;br /&gt;
actual information about the searchable content. Neighbours know what their&lt;br /&gt;
neighbours do not have, but cannot say for sure what they do have. QHTs are also&lt;br /&gt;
very efficient, both in terms of exchange and maintenance and lookup cost.&lt;br /&gt;
&lt;br /&gt;
== Table Content ==&lt;br /&gt;
&lt;br /&gt;
A QHT is a table of 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt; bits, where each bit represents a unique word-hash value.&lt;br /&gt;
For example a table of 20 bits has 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; = 1048576 possible word-hash values. If&lt;br /&gt;
stored uncompressed this table would be 128 KB in size.&lt;br /&gt;
&lt;br /&gt;
In an empty table, every word-hash value bit will be &amp;quot;1&amp;quot;, which represents &amp;quot;empty&amp;quot;.&lt;br /&gt;
To populate the table with searchable content, an application must:&lt;br /&gt;
&lt;br /&gt;
* Locate every plain-text word and URN which could be searched for and produce a match/hit&lt;br /&gt;
* Hash the word with a simple hash function to produce a word-hash value which is 0 &amp;lt;= value &amp;lt; 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt;.&lt;br /&gt;
* Set the appropriate bit in the table to zero, representing &amp;quot;full&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Word Hashing ==&lt;br /&gt;
&lt;br /&gt;
Words are strings of one or more alphanumeric characters which are not all numeric.&lt;br /&gt;
&lt;br /&gt;
To convert a word into a hash value, the following case-insensitive algorithm is used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
// HashWord( string_ptr, char_count, table_bit_count );&lt;br /&gt;
DWORD CQueryHashTable::HashWord(LPCTSTR psz, int nLength, int nBits)&lt;br /&gt;
{&lt;br /&gt;
  DWORD nNumber = 0;&lt;br /&gt;
  int nByte = 0;&lt;br /&gt;
  for ( ; nLength &amp;gt; 0 ; nLength--, psz++ )&lt;br /&gt;
  {&lt;br /&gt;
    int nValue = tolower( *psz ) &amp;amp; 0xFF;&lt;br /&gt;
    nValue = nValue &amp;lt;&amp;lt; ( nByte * 8 );&lt;br /&gt;
    nByte = ( nByte + 1 ) &amp;amp; 3;&lt;br /&gt;
    nNumber = nNumber ^ nValue;&lt;br /&gt;
  }&lt;br /&gt;
  return HashNumber( nNumber, nBits );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DWORD CQueryHashTable::HashNumber(DWORD nNumber, int nBits)&lt;br /&gt;
{&lt;br /&gt;
  WORD64 nProduct = (WORD64)nNumber * (WORD64)0x4F1BBCDC;&lt;br /&gt;
  WORD64 nHash = ( nProduct &amp;lt;&amp;lt; 32 ) &amp;gt;&amp;gt; ( 32 + ( 32 - nBits ) );&lt;br /&gt;
  return (DWORD)nHash;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== URNs - A Special Case ==&lt;br /&gt;
&lt;br /&gt;
URNs are treated as a special case: rather than dividing them up into word tokens,&lt;br /&gt;
they are hashed as a complete fixed length string. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
urn:sha1:WIXYJFVJMIWNMUWPRPBGUTODIV52RMJA&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitprint URNs are actually composite values which include both a SHA1 and&lt;br /&gt;
TigerTree root value. Rather than adding the whole bitprint to the table, each of the&lt;br /&gt;
constituent URNs are added separately. This allows SHA1-only querying and TigerTree-only&lt;br /&gt;
querying. A root TigerTree URN takes the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
urn:tree:tiger/:CN25MLNU3XNN7IHKZMNOA63XG6SKDJ2W7Z3HONA&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other URNs should be expressed in their most natural form before being fed to the&lt;br /&gt;
word hash function.&lt;br /&gt;
&lt;br /&gt;
== Word Prefix Extensions ==&lt;br /&gt;
&lt;br /&gt;
For words consisting of at least five characters, it is often useful to be able to match&lt;br /&gt;
substrings within the word. Unfortunately, adding every possible substring of each&lt;br /&gt;
word would increase the density of the QHT, however, a simple and effective&lt;br /&gt;
compromise is available:&lt;br /&gt;
&lt;br /&gt;
For words with 5 or more characters:&lt;br /&gt;
&lt;br /&gt;
* Hash and add the whole word&lt;br /&gt;
* Hash and add the whole word minus the last character&lt;br /&gt;
* Hash and add the whole word minus the last two characters&lt;br /&gt;
&lt;br /&gt;
This allows searching on prefixes of the word, for example &amp;quot;match&amp;quot; will now match&lt;br /&gt;
&amp;quot;matches&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Table Exchange ==&lt;br /&gt;
&lt;br /&gt;
Nodes must keep their neighbouring hubs up to date with their latest local query&lt;br /&gt;
hash table at all times. Rather than sending the whole table whenever it changes,&lt;br /&gt;
nodes may opt to send a &amp;quot;table patch&amp;quot;, which includes only the difference between&lt;br /&gt;
the old and new table.&lt;br /&gt;
&lt;br /&gt;
The /[[QHT]] packet is used to supply a query hash table update to a neighbouring hub.&lt;br /&gt;
Its format is compatible with the Gnutella1 &amp;quot;query routing protocol&amp;quot;, except that&lt;br /&gt;
Gnutella2 requires a 1-bit per value table while Gnutella1 requires a 4 or 8 bit per&lt;br /&gt;
value table. Gnutella2 supports patch compression using the deflate algorithm,&lt;br /&gt;
however this should not be applied if the TCP link itself is compressed.&lt;br /&gt;
&lt;br /&gt;
== Table Access ==&lt;br /&gt;
&lt;br /&gt;
A table of 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt; bits can be stored in an array of bytes 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt;/8 long. To resolve a&lt;br /&gt;
hash-value into a byte and bit number, use the following equations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
int nByte = ( nHashValue &amp;gt;&amp;gt; 3 );&lt;br /&gt;
int nBit = ( nHashValue &amp;amp; 7 );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The least significant bit is numbered 0; the most significant bit is numbered 7. To set&lt;br /&gt;
a bit as empty (setting it to 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
table_ptr[ nByte ] |= ( 1 &amp;lt;&amp;lt; nBit );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To set a bit as full (setting it to zero):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
table_ptr[ nByte ] &amp;amp;= ~( 1 &amp;lt;&amp;lt; nBit );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Aggregate or Superset Table ==&lt;br /&gt;
&lt;br /&gt;
Nodes operating in hub mode must maintain an aggregate or superset query hash&lt;br /&gt;
table, consisting of their own searchable content combined with the QHTs supplied&lt;br /&gt;
by all connected leaves. This aggregate table is supplied to neighbouring hubs,&lt;br /&gt;
allowing them to completely filter traffic for the local hub and its leaves.&lt;br /&gt;
&lt;br /&gt;
This has two important implications:&lt;br /&gt;
* When a change is detected in either the local content or a connected leaf node's QHT, the aggregate table must be rebuilt and patches dispatched to neighbouring hubs. This will happen often, so an appropriate minimum time between updates should be used. One minute is effective.&lt;br /&gt;
* An aggregate table representing 400 leaves will be much denser than a table representing one node. This means that all tables must be large enough that the aggregate table remains productively sparse.&lt;br /&gt;
&lt;br /&gt;
To create an aggregate table, start with an empty table of fixed size containing all&lt;br /&gt;
1's. For each contributing table, copy any zero (full) bits to the aggregate table. This&lt;br /&gt;
is effectively an AND operation. If a source table is smaller than the aggregate table,&lt;br /&gt;
a single 0 bit in the source will equate to several zero bits in the aggregate. If the&lt;br /&gt;
source table is larger than the aggregate table, a single zero bit will map to a single&lt;br /&gt;
bit with some loss of accuracy.&lt;br /&gt;
&lt;br /&gt;
It is of great importance that all QHTs in the system be sufficiently large to allow an&lt;br /&gt;
aggregate table to remain suitably sparse. Ideally each leaf node should provide a&lt;br /&gt;
table less than 1% dense.&lt;br /&gt;
&lt;br /&gt;
== Query Filtering ==&lt;br /&gt;
&lt;br /&gt;
Before transmitting a query packet to a connection that has provided a query hash&lt;br /&gt;
table, match the words and URNs in the query against the QHT.&lt;br /&gt;
&lt;br /&gt;
* If any of the lookups based on URNs found a hit, send the query packet&lt;br /&gt;
* If at least two thirds of lookups based on words found a hit, send&lt;br /&gt;
* Otherwise, drop the packet&lt;br /&gt;
&lt;br /&gt;
It is important to apply the &amp;quot;two thirds&amp;quot; rule only for words. URNs must provide an&lt;br /&gt;
automatic match.&lt;br /&gt;
&lt;br /&gt;
Consider all text content in the query, including generic search text and metadata&lt;br /&gt;
search text if it is present. When dealing with simple query language that involves&lt;br /&gt;
quoted phrases and exclusions, apply the following rules:&lt;br /&gt;
&lt;br /&gt;
* Tokenize quoted phrases into words, ignoring the phrase at this level&lt;br /&gt;
* Ignore excluded words - these do not count as table hits or misses&lt;br /&gt;
* Remember to apply exclusion to every word in an excluded phrase&lt;br /&gt;
&lt;br /&gt;
See the section on the simple query language for more information.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Query_Hash_Tables&amp;diff=51</id>
		<title>Query Hash Tables</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Query_Hash_Tables&amp;diff=51"/>
		<updated>2005-03-28T11:52:43Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Table Properties */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Building an efficient network topology is not viable without means to restrict the flow&lt;br /&gt;
of information appropriately. In the Gnutella2 network architecture, neighbouring&lt;br /&gt;
nodes exchange compressed hash filter tables describing the content, which can be&lt;br /&gt;
reached by communicating with them. These tables are updated dynamically as&lt;br /&gt;
necessary.&lt;br /&gt;
&lt;br /&gt;
The concept of filtering hash tables in file sharing was pioneered by Limegroup for&lt;br /&gt;
the LimeWire? Gnutella1 application.&lt;br /&gt;
&lt;br /&gt;
== Table Properties ==&lt;br /&gt;
&lt;br /&gt;
Query hash tables or QHTs provide enough information to know with certainty that a&lt;br /&gt;
particular node (and possibly its descendants) will not be able to provide any&lt;br /&gt;
matching objects for a given query. Conversely, the QHT may reveal that a node or&lt;br /&gt;
its descendants may be able to provide matching objects.&lt;br /&gt;
&lt;br /&gt;
This property means that queries can be discarded confidently when a transmission&lt;br /&gt;
is known to be unnecessary, while not providing the filtering or forwarding node, any&lt;br /&gt;
actual information about the searchable content. Neighbours know what their&lt;br /&gt;
neighbours do not have, but cannot say for sure what they do have. QHTs are also&lt;br /&gt;
very efficient, both in terms of exchange and maintenance and lookup cost.&lt;br /&gt;
&lt;br /&gt;
== Table Content ==&lt;br /&gt;
&lt;br /&gt;
A QHT is a table of 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt; bits, where each bit represents a unique word-hash value.&lt;br /&gt;
For example a table of 20 bits has 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; = 1048576 possible word-hash values. If&lt;br /&gt;
stored uncompressed this table would be 128 KB in size.&lt;br /&gt;
&lt;br /&gt;
In an empty table, every word-hash value bit will be &amp;quot;1&amp;quot;, which represents &amp;quot;empty&amp;quot;.&lt;br /&gt;
To populate the table with searchable content, an application must:&lt;br /&gt;
&lt;br /&gt;
* Locate every plain-text word and URN which could be searched for and produce a match/hit&lt;br /&gt;
* Hash the word with a simple hash function to produce a word-hash value which is 0 &amp;lt;= value &amp;lt; 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt;.&lt;br /&gt;
* Set the appropriate bit in the table to zero, representing &amp;quot;full&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Word Hashing ==&lt;br /&gt;
&lt;br /&gt;
Words are strings of one or more alphanumeric characters which are not all numeric.&lt;br /&gt;
&lt;br /&gt;
To convert a word into a hash value, the following case-insensitive algorithm is used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
// HashWord( string_ptr, char_count, table_bit_count );&lt;br /&gt;
DWORD CQueryHashTable::HashWord(LPCTSTR psz, int nLength, int nBits)&lt;br /&gt;
{&lt;br /&gt;
  DWORD nNumber = 0;&lt;br /&gt;
  int nByte = 0;&lt;br /&gt;
  for ( ; nLength &amp;gt; 0 ; nLength--, psz++ )&lt;br /&gt;
  {&lt;br /&gt;
    int nValue = tolower( *psz ) &amp;amp; 0xFF;&lt;br /&gt;
    nValue = nValue &amp;lt;&amp;lt; ( nByte * 8 );&lt;br /&gt;
    nByte = ( nByte + 1 ) &amp;amp; 3;&lt;br /&gt;
    nNumber = nNumber ^ nValue;&lt;br /&gt;
  }&lt;br /&gt;
  return HashNumber( nNumber, nBits );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DWORD CQueryHashTable::HashNumber(DWORD nNumber, int nBits)&lt;br /&gt;
{&lt;br /&gt;
  WORD64 nProduct = (WORD64)nNumber * (WORD64)0x4F1BBCDC;&lt;br /&gt;
  WORD64 nHash = ( nProduct &amp;lt;&amp;lt; 32 ) &amp;gt;&amp;gt; ( 32 + ( 32 - nBits ) );&lt;br /&gt;
  return (DWORD)nHash;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== URNs - A Special Case ==&lt;br /&gt;
&lt;br /&gt;
URNs are treated as a special case: rather than dividing them up into word tokens,&lt;br /&gt;
they are hashed as a complete fixed length string. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
urn:sha1:WIXYJFVJMIWNMUWPRPBGUTODIV52RMJA&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitprint URNs are actually composite values which include both a SHA1 and&lt;br /&gt;
TigerTree root value. Rather than adding the whole bitprint to the table, each of the&lt;br /&gt;
constituent URNs are added separately. This allows SHA1-only querying and TigerTree-only&lt;br /&gt;
querying. A root TigerTree URN takes the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
urn:tree:tiger/:CN25MLNU3XNN7IHKZMNOA63XG6SKDJ2W7Z3HONA&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other URNs should be expressed in their most natural form before being fed to the&lt;br /&gt;
word hash function.&lt;br /&gt;
&lt;br /&gt;
== Word Prefix Extensions ==&lt;br /&gt;
&lt;br /&gt;
For words consisting of at least five characters, it is often useful to be able to match&lt;br /&gt;
substrings within the word. Unfortunately adding every possible substring of each&lt;br /&gt;
word would increase the density of the QHT, however a simple and effective&lt;br /&gt;
compromise is available:&lt;br /&gt;
&lt;br /&gt;
For words with 5 or more characters:&lt;br /&gt;
&lt;br /&gt;
* Hash and add the whole word&lt;br /&gt;
* Hash and add the whole word minus the last character&lt;br /&gt;
* Hash and add the whole word minus the last two characters&lt;br /&gt;
&lt;br /&gt;
This allows searching on prefixes of the word, for example &amp;quot;match&amp;quot; will now match&lt;br /&gt;
&amp;quot;matches&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Table Exchange ==&lt;br /&gt;
&lt;br /&gt;
Nodes must keep their neighbouring hubs up to date with their latest local query&lt;br /&gt;
hash table at all times. Rather than sending the whole table whenever it changes,&lt;br /&gt;
nodes may opt to send a &amp;quot;table patch&amp;quot;, which includes only the difference between&lt;br /&gt;
the old and new table.&lt;br /&gt;
&lt;br /&gt;
The /[[QHT]] packet is used to supply a query hash table update to a neighbouring hub.&lt;br /&gt;
Its format is compatible with the Gnutella1 &amp;quot;query routing protocol&amp;quot;, except that&lt;br /&gt;
Gnutella2 requires a 1-bit per value table while Gnutella1 requires a 4 or 8 bit per&lt;br /&gt;
value table. Gnutella2 supports patch compression using the deflate algorithm,&lt;br /&gt;
however this should not be applied if the TCP link itself is compressed.&lt;br /&gt;
&lt;br /&gt;
== Table Access ==&lt;br /&gt;
&lt;br /&gt;
A table of 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt; bits can be stored in an array of bytes 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt;/8 long. To resolve a&lt;br /&gt;
hash-value into a byte and bit number, use the following equations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
int nByte = ( nHashValue &amp;gt;&amp;gt; 3 );&lt;br /&gt;
int nBit = ( nHashValue &amp;amp; 7 );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The least significant bit is numbered 0; the most significant bit is numbered 7. To set&lt;br /&gt;
a bit as empty (setting it to 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
table_ptr[ nByte ] |= ( 1 &amp;lt;&amp;lt; nBit );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To set a bit as full (setting it to zero):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
table_ptr[ nByte ] &amp;amp;= ~( 1 &amp;lt;&amp;lt; nBit );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Aggregate or Superset Table ==&lt;br /&gt;
&lt;br /&gt;
Nodes operating in hub mode must maintain an aggregate or superset query hash&lt;br /&gt;
table, consisting of their own searchable content combined with the QHTs supplied&lt;br /&gt;
by all connected leaves. This aggregate table is supplied to neighbouring hubs,&lt;br /&gt;
allowing them to completely filter traffic for the local hub and its leaves.&lt;br /&gt;
&lt;br /&gt;
This has two important implications:&lt;br /&gt;
* When a change is detected in either the local content or a connected leaf node's QHT, the aggregate table must be rebuilt and patches dispatched to neighbouring hubs. This will happen often, so an appropriate minimum time between updates should be used. One minute is effective.&lt;br /&gt;
* An aggregate table representing 400 leaves will be much denser than a table representing one node. This means that all tables must be large enough that the aggregate table remains productively sparse.&lt;br /&gt;
&lt;br /&gt;
To create an aggregate table, start with an empty table of fixed size containing all&lt;br /&gt;
1's. For each contributing table, copy any zero (full) bits to the aggregate table. This&lt;br /&gt;
is effectively an AND operation. If a source table is smaller than the aggregate table,&lt;br /&gt;
a single 0 bit in the source will equate to several zero bits in the aggregate. If the&lt;br /&gt;
source table is larger than the aggregate table, a single zero bit will map to a single&lt;br /&gt;
bit with some loss of accuracy.&lt;br /&gt;
&lt;br /&gt;
It is of great importance that all QHTs in the system be sufficiently large to allow an&lt;br /&gt;
aggregate table to remain suitably sparse. Ideally each leaf node should provide a&lt;br /&gt;
table less than 1% dense.&lt;br /&gt;
&lt;br /&gt;
== Query Filtering ==&lt;br /&gt;
&lt;br /&gt;
Before transmitting a query packet to a connection that has provided a query hash&lt;br /&gt;
table, match the words and URNs in the query against the QHT.&lt;br /&gt;
&lt;br /&gt;
* If any of the lookups based on URNs found a hit, send the query packet&lt;br /&gt;
* If at least two thirds of lookups based on words found a hit, send&lt;br /&gt;
* Otherwise, drop the packet&lt;br /&gt;
&lt;br /&gt;
It is important to apply the &amp;quot;two thirds&amp;quot; rule only for words. URNs must provide an&lt;br /&gt;
automatic match.&lt;br /&gt;
&lt;br /&gt;
Consider all text content in the query, including generic search text and metadata&lt;br /&gt;
search text if it is present. When dealing with simple query language that involves&lt;br /&gt;
quoted phrases and exclusions, apply the following rules:&lt;br /&gt;
&lt;br /&gt;
* Tokenize quoted phrases into words, ignoring the phrase at this level&lt;br /&gt;
* Ignore excluded words - these do not count as table hits or misses&lt;br /&gt;
* Remember to apply exclusion to every word in an excluded phrase&lt;br /&gt;
&lt;br /&gt;
See the section on the simple query language for more information.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Query_Hash_Tables&amp;diff=50</id>
		<title>Query Hash Tables</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Query_Hash_Tables&amp;diff=50"/>
		<updated>2005-03-28T11:51:25Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Building an efficient network topology is not viable without means to restrict the flow&lt;br /&gt;
of information appropriately. In the Gnutella2 network architecture, neighbouring&lt;br /&gt;
nodes exchange compressed hash filter tables describing the content, which can be&lt;br /&gt;
reached by communicating with them. These tables are updated dynamically as&lt;br /&gt;
necessary.&lt;br /&gt;
&lt;br /&gt;
The concept of filtering hash tables in file sharing was pioneered by Limegroup for&lt;br /&gt;
the LimeWire? Gnutella1 application.&lt;br /&gt;
&lt;br /&gt;
== Table Properties ==&lt;br /&gt;
&lt;br /&gt;
Query hash tables or QHTs provide enough information to know with certainty that a&lt;br /&gt;
particular node (and possibly its descendants) will not be able to provide any&lt;br /&gt;
matching objects for a given query. Conversely the QHT may reveal that a node or&lt;br /&gt;
its descendants may be able to provide matching objects.&lt;br /&gt;
&lt;br /&gt;
This property means that queries can be discarded confidently when a transmission&lt;br /&gt;
is known to be unnecessary, while not providing the filtering or forwarding node any&lt;br /&gt;
actual information about the searchable content. Neighbours know what their&lt;br /&gt;
neighbours do not have, but cannot say for sure what they do have. QHTs are also&lt;br /&gt;
very efficient both in terms of exchange and maintenance and lookup cost.&lt;br /&gt;
&lt;br /&gt;
== Table Content ==&lt;br /&gt;
&lt;br /&gt;
A QHT is a table of 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt; bits, where each bit represents a unique word-hash value.&lt;br /&gt;
For example a table of 20 bits has 2&amp;lt;sup&amp;gt;20&amp;lt;/sup&amp;gt; = 1048576 possible word-hash values. If&lt;br /&gt;
stored uncompressed this table would be 128 KB in size.&lt;br /&gt;
&lt;br /&gt;
In an empty table, every word-hash value bit will be &amp;quot;1&amp;quot;, which represents &amp;quot;empty&amp;quot;.&lt;br /&gt;
To populate the table with searchable content, an application must:&lt;br /&gt;
&lt;br /&gt;
* Locate every plain-text word and URN which could be searched for and produce a match/hit&lt;br /&gt;
* Hash the word with a simple hash function to produce a word-hash value which is 0 &amp;lt;= value &amp;lt; 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt;.&lt;br /&gt;
* Set the appropriate bit in the table to zero, representing &amp;quot;full&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Word Hashing ==&lt;br /&gt;
&lt;br /&gt;
Words are strings of one or more alphanumeric characters which are not all numeric.&lt;br /&gt;
&lt;br /&gt;
To convert a word into a hash value, the following case-insensitive algorithm is used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
// HashWord( string_ptr, char_count, table_bit_count );&lt;br /&gt;
DWORD CQueryHashTable::HashWord(LPCTSTR psz, int nLength, int nBits)&lt;br /&gt;
{&lt;br /&gt;
  DWORD nNumber = 0;&lt;br /&gt;
  int nByte = 0;&lt;br /&gt;
  for ( ; nLength &amp;gt; 0 ; nLength--, psz++ )&lt;br /&gt;
  {&lt;br /&gt;
    int nValue = tolower( *psz ) &amp;amp; 0xFF;&lt;br /&gt;
    nValue = nValue &amp;lt;&amp;lt; ( nByte * 8 );&lt;br /&gt;
    nByte = ( nByte + 1 ) &amp;amp; 3;&lt;br /&gt;
    nNumber = nNumber ^ nValue;&lt;br /&gt;
  }&lt;br /&gt;
  return HashNumber( nNumber, nBits );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
DWORD CQueryHashTable::HashNumber(DWORD nNumber, int nBits)&lt;br /&gt;
{&lt;br /&gt;
  WORD64 nProduct = (WORD64)nNumber * (WORD64)0x4F1BBCDC;&lt;br /&gt;
  WORD64 nHash = ( nProduct &amp;lt;&amp;lt; 32 ) &amp;gt;&amp;gt; ( 32 + ( 32 - nBits ) );&lt;br /&gt;
  return (DWORD)nHash;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== URNs - A Special Case ==&lt;br /&gt;
&lt;br /&gt;
URNs are treated as a special case: rather than dividing them up into word tokens,&lt;br /&gt;
they are hashed as a complete fixed length string. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
urn:sha1:WIXYJFVJMIWNMUWPRPBGUTODIV52RMJA&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitprint URNs are actually composite values which include both a SHA1 and&lt;br /&gt;
TigerTree root value. Rather than adding the whole bitprint to the table, each of the&lt;br /&gt;
constituent URNs are added separately. This allows SHA1-only querying and TigerTree-only&lt;br /&gt;
querying. A root TigerTree URN takes the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
urn:tree:tiger/:CN25MLNU3XNN7IHKZMNOA63XG6SKDJ2W7Z3HONA&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other URNs should be expressed in their most natural form before being fed to the&lt;br /&gt;
word hash function.&lt;br /&gt;
&lt;br /&gt;
== Word Prefix Extensions ==&lt;br /&gt;
&lt;br /&gt;
For words consisting of at least five characters, it is often useful to be able to match&lt;br /&gt;
substrings within the word. Unfortunately adding every possible substring of each&lt;br /&gt;
word would increase the density of the QHT, however a simple and effective&lt;br /&gt;
compromise is available:&lt;br /&gt;
&lt;br /&gt;
For words with 5 or more characters:&lt;br /&gt;
&lt;br /&gt;
* Hash and add the whole word&lt;br /&gt;
* Hash and add the whole word minus the last character&lt;br /&gt;
* Hash and add the whole word minus the last two characters&lt;br /&gt;
&lt;br /&gt;
This allows searching on prefixes of the word, for example &amp;quot;match&amp;quot; will now match&lt;br /&gt;
&amp;quot;matches&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Table Exchange ==&lt;br /&gt;
&lt;br /&gt;
Nodes must keep their neighbouring hubs up to date with their latest local query&lt;br /&gt;
hash table at all times. Rather than sending the whole table whenever it changes,&lt;br /&gt;
nodes may opt to send a &amp;quot;table patch&amp;quot;, which includes only the difference between&lt;br /&gt;
the old and new table.&lt;br /&gt;
&lt;br /&gt;
The /[[QHT]] packet is used to supply a query hash table update to a neighbouring hub.&lt;br /&gt;
Its format is compatible with the Gnutella1 &amp;quot;query routing protocol&amp;quot;, except that&lt;br /&gt;
Gnutella2 requires a 1-bit per value table while Gnutella1 requires a 4 or 8 bit per&lt;br /&gt;
value table. Gnutella2 supports patch compression using the deflate algorithm,&lt;br /&gt;
however this should not be applied if the TCP link itself is compressed.&lt;br /&gt;
&lt;br /&gt;
== Table Access ==&lt;br /&gt;
&lt;br /&gt;
A table of 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt; bits can be stored in an array of bytes 2&amp;lt;sup&amp;gt;N&amp;lt;/sup&amp;gt;/8 long. To resolve a&lt;br /&gt;
hash-value into a byte and bit number, use the following equations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
int nByte = ( nHashValue &amp;gt;&amp;gt; 3 );&lt;br /&gt;
int nBit = ( nHashValue &amp;amp; 7 );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The least significant bit is numbered 0; the most significant bit is numbered 7. To set&lt;br /&gt;
a bit as empty (setting it to 1):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
table_ptr[ nByte ] |= ( 1 &amp;lt;&amp;lt; nBit );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To set a bit as full (setting it to zero):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
table_ptr[ nByte ] &amp;amp;= ~( 1 &amp;lt;&amp;lt; nBit );&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The Aggregate or Superset Table ==&lt;br /&gt;
&lt;br /&gt;
Nodes operating in hub mode must maintain an aggregate or superset query hash&lt;br /&gt;
table, consisting of their own searchable content combined with the QHTs supplied&lt;br /&gt;
by all connected leaves. This aggregate table is supplied to neighbouring hubs,&lt;br /&gt;
allowing them to completely filter traffic for the local hub and its leaves.&lt;br /&gt;
&lt;br /&gt;
This has two important implications:&lt;br /&gt;
* When a change is detected in either the local content or a connected leaf node's QHT, the aggregate table must be rebuilt and patches dispatched to neighbouring hubs. This will happen often, so an appropriate minimum time between updates should be used. One minute is effective.&lt;br /&gt;
* An aggregate table representing 400 leaves will be much denser than a table representing one node. This means that all tables must be large enough that the aggregate table remains productively sparse.&lt;br /&gt;
&lt;br /&gt;
To create an aggregate table, start with an empty table of fixed size containing all&lt;br /&gt;
1's. For each contributing table, copy any zero (full) bits to the aggregate table. This&lt;br /&gt;
is effectively an AND operation. If a source table is smaller than the aggregate table,&lt;br /&gt;
a single 0 bit in the source will equate to several zero bits in the aggregate. If the&lt;br /&gt;
source table is larger than the aggregate table, a single zero bit will map to a single&lt;br /&gt;
bit with some loss of accuracy.&lt;br /&gt;
&lt;br /&gt;
It is of great importance that all QHTs in the system be sufficiently large to allow an&lt;br /&gt;
aggregate table to remain suitably sparse. Ideally each leaf node should provide a&lt;br /&gt;
table less than 1% dense.&lt;br /&gt;
&lt;br /&gt;
== Query Filtering ==&lt;br /&gt;
&lt;br /&gt;
Before transmitting a query packet to a connection that has provided a query hash&lt;br /&gt;
table, match the words and URNs in the query against the QHT.&lt;br /&gt;
&lt;br /&gt;
* If any of the lookups based on URNs found a hit, send the query packet&lt;br /&gt;
* If at least two thirds of lookups based on words found a hit, send&lt;br /&gt;
* Otherwise, drop the packet&lt;br /&gt;
&lt;br /&gt;
It is important to apply the &amp;quot;two thirds&amp;quot; rule only for words. URNs must provide an&lt;br /&gt;
automatic match.&lt;br /&gt;
&lt;br /&gt;
Consider all text content in the query, including generic search text and metadata&lt;br /&gt;
search text if it is present. When dealing with simple query language that involves&lt;br /&gt;
quoted phrases and exclusions, apply the following rules:&lt;br /&gt;
&lt;br /&gt;
* Tokenize quoted phrases into words, ignoring the phrase at this level&lt;br /&gt;
* Ignore excluded words - these do not count as table hits or misses&lt;br /&gt;
* Remember to apply exclusion to every word in an excluded phrase&lt;br /&gt;
&lt;br /&gt;
See the section on the simple query language for more information.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Known_Hub_Cache_and_Hub_Cluster_Cache&amp;diff=94</id>
		<title>Known Hub Cache and Hub Cluster Cache</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Known_Hub_Cache_and_Hub_Cluster_Cache&amp;diff=94"/>
		<updated>2005-03-27T17:32:40Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* The Hub Cluster Cache */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Each Gnutella2 node must maintain a non-exhaustive cache of known hubs at the&lt;br /&gt;
global level, and an exhaustive cache of hubs within the neighbouring hub cluster(s).&lt;br /&gt;
&lt;br /&gt;
== The Known Hub Cache ==&lt;br /&gt;
&lt;br /&gt;
The known hub list is used to provide connection hints to the local connection&lt;br /&gt;
manager, and other nodes which connect permanently or transiently. The most&lt;br /&gt;
recent portion of it is exchanged with neighbours regularly.&lt;br /&gt;
&lt;br /&gt;
It is also used when executing a query on the network, which involves iteratively&lt;br /&gt;
contacting hubs representing each hub cluster and simultaneously recording the&lt;br /&gt;
hubs which have been accounted for and adding those newly discovered.&lt;br /&gt;
&lt;br /&gt;
The known hub cache should be highly efficient, addressable by node address and&lt;br /&gt;
timestamp, and sorted by the last seen timestamp of each hub record. Adding fresh&lt;br /&gt;
hubs should push the oldest hubs from the bottom of the cache.&lt;br /&gt;
&lt;br /&gt;
It is suggested that each cached hub entry store:&lt;br /&gt;
&lt;br /&gt;
* Node address&lt;br /&gt;
* Last seen time&lt;br /&gt;
* Query key, if available&lt;br /&gt;
* [[Datatypes|GUID]], if available&lt;br /&gt;
* Vendor information, if desired and available&lt;br /&gt;
* Throttling timing for last query key request, last query, etc&lt;br /&gt;
&lt;br /&gt;
Hubs whose last seen timestamp is too old should be removed from the cache, and&lt;br /&gt;
should certainly never be sent to other nodes.&lt;br /&gt;
&lt;br /&gt;
== The Hub Cluster Cache ==&lt;br /&gt;
&lt;br /&gt;
The hub cluster cache is used to maintain an up-to-date list of neighbouring hubs,&lt;br /&gt;
and the neighbouring hubs of neighbouring hubs. Thinking in terms of hops, it is an&lt;br /&gt;
exhaustive list of every hub which is 1 or 2 hops away from the local node (be the&lt;br /&gt;
local node a hub or a leaf). The cluster cache is really only important when operating&lt;br /&gt;
in hub mode, however, it can be maintained in leaf mode for informational purposes.&lt;br /&gt;
&lt;br /&gt;
The hub cluster cache is used by a hub when responding to a keyed remote query&lt;br /&gt;
request, in the generation of a query acknowledgement packet (/[[QA]]). The /[[QA]]&lt;br /&gt;
packet contains a list of neighbouring hubs and a selection of second degree&lt;br /&gt;
neighbours.&lt;br /&gt;
&lt;br /&gt;
The cluster cache is updated using information from /[[LNI]] and /[[KHL]] packets.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Gnutella2_Standard&amp;diff=835</id>
		<title>Gnutella2 Standard</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Gnutella2_Standard&amp;diff=835"/>
		<updated>2005-03-27T17:21:03Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Common Gnutella2 Standard (All Applications) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is the Gnutella2 Standard? ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 Standard is a set of requirements for building applications which&lt;br /&gt;
operate with the [[Gnutella2 Network]] in different capacities. For example, the&lt;br /&gt;
Gnutella2 Standard for File Sharing specifies a set of features and behaviours which&lt;br /&gt;
must be available in any Gnutella2-connected file-sharing product offered to the&lt;br /&gt;
public.&lt;br /&gt;
&lt;br /&gt;
== Why is a Standard Needed? ==&lt;br /&gt;
&lt;br /&gt;
As an open, general purpose platform, Gnutella2 networks must be able to operate&lt;br /&gt;
with a diverse family of different implementing applications. Every effort has been&lt;br /&gt;
made to limit the ill-effects a non-compliant application can cause (deliberately or&lt;br /&gt;
accidentally), however, when it comes to critical features such as common URN&lt;br /&gt;
schemes and character encodings, minimum standards help to ensure a favourable&lt;br /&gt;
baseline user experience.&lt;br /&gt;
&lt;br /&gt;
== How are Standards Enforced? ==&lt;br /&gt;
&lt;br /&gt;
The open and transparent nature of the Gnutella2 architecture makes technical&lt;br /&gt;
enforcement difficult, so a more viable (and hopefully, more productive) social&lt;br /&gt;
scheme has instead been adopted. Only applications meeting the appropriate&lt;br /&gt;
Gnutella2 Standard may be marked as &amp;quot;Gnutella2-compliant&amp;quot;. Websites containing&lt;br /&gt;
information about Gnutella2 (such as gnutella2.com) are encouraged to list only&lt;br /&gt;
compliant applications, and application developers are encouraged to deny&lt;br /&gt;
communications with known non-compliant applications. Applications which do not&lt;br /&gt;
comply with the standard, or are still in the development process, should never be&lt;br /&gt;
made available to the public, however, private testing is always encouraged.&lt;br /&gt;
&lt;br /&gt;
== How are Applications Tested? ==&lt;br /&gt;
&lt;br /&gt;
Ultimately, it is the responsibility of the developer to ensure their own application&lt;br /&gt;
complies with the relevant standards, both with respect to Gnutella2 and any other&lt;br /&gt;
functionality they may be including. However, as an inter-dependent community,&lt;br /&gt;
developers of Gnutella2-compliant applications are encouraged to take an interest in&lt;br /&gt;
other Gnutella2 applications, and where possible, examine them for compliance.&lt;br /&gt;
Similarly, new developers are strongly encouraged to seek assistance from other&lt;br /&gt;
developers in verifying their work. This need not compromise competitive advantage&lt;br /&gt;
- if the application is sensitive, the important compliance testing phase can be&lt;br /&gt;
performed in the days prior to release.&lt;br /&gt;
&lt;br /&gt;
== What Standards are Available? ==&lt;br /&gt;
&lt;br /&gt;
At the current time, only one Gnutella2 standard has been published: the Gnutella2&lt;br /&gt;
standard for File Sharing Applications. Additional standards for other&lt;br /&gt;
application classes will be published in the future as required.&lt;br /&gt;
&lt;br /&gt;
Developers of new application classes are operating in somewhat untried territory,&lt;br /&gt;
and should review the existing published standards for best practices which can be&lt;br /&gt;
borrowed. In particular, the basic components of the Gnutella2 network architecture&lt;br /&gt;
should always be implemented in full.&lt;br /&gt;
&lt;br /&gt;
== Common Gnutella2 Standard (All Applications) == &lt;br /&gt;
&lt;br /&gt;
All applications making use of Gnutella2 technology for any application class MUST&lt;br /&gt;
IMPLEMENT the following core features:&lt;br /&gt;
&lt;br /&gt;
* Bidirectional TCP stream connections (stream compression OPTIONAL)&lt;br /&gt;
* Bidirectional reliable UDP protocol (Gnutella2 reliability layer and stateless compression REQUIRED)&lt;br /&gt;
* HTTP-style link negotiation, exchanging at least the required headers&lt;br /&gt;
* Gnutella2 protocol support, graceful handling of unknown trees&lt;br /&gt;
* Localised, UTF-8 and UNICODE decode REQUIRED, encoding to each optional&lt;br /&gt;
* Operation in LEAF mode, additional node states OPTIONAL&lt;br /&gt;
* Basic link handshaking and maintenance functionality (PI/PO/LNI/KHL)&lt;br /&gt;
* Global node addressing scheme and routing maintenance, addressing children (TO)&lt;br /&gt;
* Reverse (PUSH) connection response (connecting out)&lt;br /&gt;
* HTTP/1.1 client and server for peer to peer transactions&lt;br /&gt;
* Gnutella2 Standard for File Sharing&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Applications making use of Gnutella2 technology for file sharing MUST IMPLEMENT&lt;br /&gt;
the following features:&lt;br /&gt;
&lt;br /&gt;
* All of the COMMON features listed in the previous section&lt;br /&gt;
* Operation in LEAF mode, additional node states OPTIONAL&lt;br /&gt;
* Some form of bandwidth management scheme, to keep network and transfer bandwidth below 95% of the user's link capacity - be it manually configured or some automatic scheme (very important to avoid flooding local connection)&lt;br /&gt;
* [[SHA1]] and TIGER ROOT [[URN]]s for all shared objects&lt;br /&gt;
* XML metadata, using existing schemas where appropriate (manual entry and peer acquired at minimum, automatic local collection highly recommended, service lookup optional)&lt;br /&gt;
* Universal 1-bit query hash filter, at least 2^20 length, intelligent density management scheme (superset combination required if supporting hub mode)&lt;br /&gt;
* Gnutella2 object search mechanism, all client responsibilities and if supporting hub mode, server responsibilities too&lt;br /&gt;
* Local search processing, including simple query language (Boolean operations, quoted search terms, numeric range searches, interest flagging (I), local rulebased metadata searching)&lt;br /&gt;
* Extensible hit format (URN/DN/MD/URL are REQUIRED, all other extensions OPTIONAL)&lt;br /&gt;
* HTTP/1.1 based upload system, URN based requesting, partial content requests, active queuing, partial file uploading, timestamp protected alternate source cache and exchange&lt;br /&gt;
* [[TigerTree]] volume calculation on shared files, caching on downloads, exchange via [[DIME]]. Local corruption detection OPTIONAL but recommended.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Gnutella2_Standard&amp;diff=47</id>
		<title>Gnutella2 Standard</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Gnutella2_Standard&amp;diff=47"/>
		<updated>2005-03-27T17:16:52Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* How are Applications Tested? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is the Gnutella2 Standard? ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 Standard is a set of requirements for building applications which&lt;br /&gt;
operate with the [[Gnutella2 Network]] in different capacities. For example, the&lt;br /&gt;
Gnutella2 Standard for File Sharing specifies a set of features and behaviours which&lt;br /&gt;
must be available in any Gnutella2-connected file-sharing product offered to the&lt;br /&gt;
public.&lt;br /&gt;
&lt;br /&gt;
== Why is a Standard Needed? ==&lt;br /&gt;
&lt;br /&gt;
As an open, general purpose platform, Gnutella2 networks must be able to operate&lt;br /&gt;
with a diverse family of different implementing applications. Every effort has been&lt;br /&gt;
made to limit the ill-effects a non-compliant application can cause (deliberately or&lt;br /&gt;
accidentally), however, when it comes to critical features such as common URN&lt;br /&gt;
schemes and character encodings, minimum standards help to ensure a favourable&lt;br /&gt;
baseline user experience.&lt;br /&gt;
&lt;br /&gt;
== How are Standards Enforced? ==&lt;br /&gt;
&lt;br /&gt;
The open and transparent nature of the Gnutella2 architecture makes technical&lt;br /&gt;
enforcement difficult, so a more viable (and hopefully, more productive) social&lt;br /&gt;
scheme has instead been adopted. Only applications meeting the appropriate&lt;br /&gt;
Gnutella2 Standard may be marked as &amp;quot;Gnutella2-compliant&amp;quot;. Websites containing&lt;br /&gt;
information about Gnutella2 (such as gnutella2.com) are encouraged to list only&lt;br /&gt;
compliant applications, and application developers are encouraged to deny&lt;br /&gt;
communications with known non-compliant applications. Applications which do not&lt;br /&gt;
comply with the standard, or are still in the development process, should never be&lt;br /&gt;
made available to the public, however, private testing is always encouraged.&lt;br /&gt;
&lt;br /&gt;
== How are Applications Tested? ==&lt;br /&gt;
&lt;br /&gt;
Ultimately, it is the responsibility of the developer to ensure their own application&lt;br /&gt;
complies with the relevant standards, both with respect to Gnutella2 and any other&lt;br /&gt;
functionality they may be including. However, as an inter-dependent community,&lt;br /&gt;
developers of Gnutella2-compliant applications are encouraged to take an interest in&lt;br /&gt;
other Gnutella2 applications, and where possible, examine them for compliance.&lt;br /&gt;
Similarly, new developers are strongly encouraged to seek assistance from other&lt;br /&gt;
developers in verifying their work. This need not compromise competitive advantage&lt;br /&gt;
- if the application is sensitive, the important compliance testing phase can be&lt;br /&gt;
performed in the days prior to release.&lt;br /&gt;
&lt;br /&gt;
== What Standards are Available? ==&lt;br /&gt;
&lt;br /&gt;
At the current time, only one Gnutella2 standard has been published: the Gnutella2&lt;br /&gt;
standard for File Sharing Applications. Additional standards for other&lt;br /&gt;
application classes will be published in the future as required.&lt;br /&gt;
&lt;br /&gt;
Developers of new application classes are operating in somewhat untried territory,&lt;br /&gt;
and should review the existing published standards for best practices which can be&lt;br /&gt;
borrowed. In particular, the basic components of the Gnutella2 network architecture&lt;br /&gt;
should always be implemented in full.&lt;br /&gt;
&lt;br /&gt;
== Common Gnutella2 Standard (All Applications) == &lt;br /&gt;
&lt;br /&gt;
All applications making use of Gnutella2 technology for any application class MUST&lt;br /&gt;
IMPLEMENT the following core features:&lt;br /&gt;
&lt;br /&gt;
* Bidirectional TCP stream connections (stream compression OPTIONAL)&lt;br /&gt;
* Bidirectional reliable UDP protocol (Gnutella2 reliability layer and stateless compression REQUIRED)&lt;br /&gt;
* HTTP-style link negotiation, exchanging at least the required headers&lt;br /&gt;
* Gnutella2 protocol support, graceful handling of unknown trees&lt;br /&gt;
* Localised, UTF-8 and UNICODE decode REQUIRED, encoding to each optional&lt;br /&gt;
* Operation in LEAF mode, additional node states OPTIONAL&lt;br /&gt;
* Basic link handshaking and maintenance functionality (PI/PO/LNI/KHL)&lt;br /&gt;
* Global node addressing scheme and routing maintenance, addressing children (TO)&lt;br /&gt;
* Reverse (PUSH) connection response (connecting out)&lt;br /&gt;
* HTTP/1.1 client and server for peer to peer transactions&lt;br /&gt;
* Gnutella2 Standard for File Sharing&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Applications making use of Gnutella2 technology for file sharing MUST IMPLEMENT&lt;br /&gt;
the following features:&lt;br /&gt;
&lt;br /&gt;
* All of the COMMON features listed in the previous section&lt;br /&gt;
* Operation in LEAF mode, additional node states OPTIONAL&lt;br /&gt;
* Some form of bandwidth management scheme to keep network and transfer bandwidth below 95% of the user's link capacity - be it manually configured or some automatic scheme (very important to avoid flooding local connection)&lt;br /&gt;
* [[SHA1]] and TIGER ROOT [[URN]]s for all shared objects&lt;br /&gt;
* XML metadata using existing schemas where appropriate (manual entry and peer acquired at minimum, automatic local collection highly recommended, service lookup optional)&lt;br /&gt;
* Universal 1-bit query hash filter, at least 2^20 length, intelligent density management scheme (superset combination required if supporting hub mode)&lt;br /&gt;
* Gnutella2 object search mechanism, all client responsibilities and if supporting hub mode, server responsibilities too&lt;br /&gt;
* Local search processing including simple query language (Boolean operations, quoted search terms, numeric range searches, interest flagging (I), local rulebased metadata searching)&lt;br /&gt;
* Extensible hit format (URN/DN/MD/URL are REQUIRED, all other extensions OPTIONAL)&lt;br /&gt;
* HTTP/1.1 based upload system, URN based requesting, partial content requests, active queuing, partial file uploading, timestamp protected alternate source cache and exchange&lt;br /&gt;
* [[TigerTree]] volume calculation on shared files, caching on downloads, exchange via [[DIME]]. Local corruption detection OPTIONAL but recommended.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Gnutella2_Standard&amp;diff=46</id>
		<title>Gnutella2 Standard</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Gnutella2_Standard&amp;diff=46"/>
		<updated>2005-03-27T17:15:52Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* How are Standards Enforced? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is the Gnutella2 Standard? ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 Standard is a set of requirements for building applications which&lt;br /&gt;
operate with the [[Gnutella2 Network]] in different capacities. For example, the&lt;br /&gt;
Gnutella2 Standard for File Sharing specifies a set of features and behaviours which&lt;br /&gt;
must be available in any Gnutella2-connected file-sharing product offered to the&lt;br /&gt;
public.&lt;br /&gt;
&lt;br /&gt;
== Why is a Standard Needed? ==&lt;br /&gt;
&lt;br /&gt;
As an open, general purpose platform, Gnutella2 networks must be able to operate&lt;br /&gt;
with a diverse family of different implementing applications. Every effort has been&lt;br /&gt;
made to limit the ill-effects a non-compliant application can cause (deliberately or&lt;br /&gt;
accidentally), however, when it comes to critical features such as common URN&lt;br /&gt;
schemes and character encodings, minimum standards help to ensure a favourable&lt;br /&gt;
baseline user experience.&lt;br /&gt;
&lt;br /&gt;
== How are Standards Enforced? ==&lt;br /&gt;
&lt;br /&gt;
The open and transparent nature of the Gnutella2 architecture makes technical&lt;br /&gt;
enforcement difficult, so a more viable (and hopefully, more productive) social&lt;br /&gt;
scheme has instead been adopted. Only applications meeting the appropriate&lt;br /&gt;
Gnutella2 Standard may be marked as &amp;quot;Gnutella2-compliant&amp;quot;. Websites containing&lt;br /&gt;
information about Gnutella2 (such as gnutella2.com) are encouraged to list only&lt;br /&gt;
compliant applications, and application developers are encouraged to deny&lt;br /&gt;
communications with known non-compliant applications. Applications which do not&lt;br /&gt;
comply with the standard, or are still in the development process, should never be&lt;br /&gt;
made available to the public, however, private testing is always encouraged.&lt;br /&gt;
&lt;br /&gt;
== How are Applications Tested? ==&lt;br /&gt;
&lt;br /&gt;
Ultimately it is the responsibility of the developer to ensure their own application&lt;br /&gt;
complies with the relevant standards, both with respect to Gnutella2 and any other&lt;br /&gt;
functionality they may be including. However as an inter-dependent community,&lt;br /&gt;
developers of Gnutella2-compliant applications are encouraged to take an interest in&lt;br /&gt;
other Gnutella2 applications, and where possible, examine them for compliance.&lt;br /&gt;
Similarly, new developers are strongly encouraged to seek assistance from other&lt;br /&gt;
developers in verifying their work. This need not compromise competitive advantage&lt;br /&gt;
- if the application is sensitive, the important compliance testing phase can be&lt;br /&gt;
performed in the days prior to release.&lt;br /&gt;
&lt;br /&gt;
== What Standards are Available? ==&lt;br /&gt;
&lt;br /&gt;
At the current time, only one Gnutella2 standard has been published: the Gnutella2&lt;br /&gt;
standard for File Sharing Applications. Additional standards for other&lt;br /&gt;
application classes will be published in the future as required.&lt;br /&gt;
&lt;br /&gt;
Developers of new application classes are operating in somewhat untried territory,&lt;br /&gt;
and should review the existing published standards for best practices which can be&lt;br /&gt;
borrowed. In particular, the basic components of the Gnutella2 network architecture&lt;br /&gt;
should always be implemented in full.&lt;br /&gt;
&lt;br /&gt;
== Common Gnutella2 Standard (All Applications) == &lt;br /&gt;
&lt;br /&gt;
All applications making use of Gnutella2 technology for any application class MUST&lt;br /&gt;
IMPLEMENT the following core features:&lt;br /&gt;
&lt;br /&gt;
* Bidirectional TCP stream connections (stream compression OPTIONAL)&lt;br /&gt;
* Bidirectional reliable UDP protocol (Gnutella2 reliability layer and stateless compression REQUIRED)&lt;br /&gt;
* HTTP-style link negotiation, exchanging at least the required headers&lt;br /&gt;
* Gnutella2 protocol support, graceful handling of unknown trees&lt;br /&gt;
* Localised, UTF-8 and UNICODE decode REQUIRED, encoding to each optional&lt;br /&gt;
* Operation in LEAF mode, additional node states OPTIONAL&lt;br /&gt;
* Basic link handshaking and maintenance functionality (PI/PO/LNI/KHL)&lt;br /&gt;
* Global node addressing scheme and routing maintenance, addressing children (TO)&lt;br /&gt;
* Reverse (PUSH) connection response (connecting out)&lt;br /&gt;
* HTTP/1.1 client and server for peer to peer transactions&lt;br /&gt;
* Gnutella2 Standard for File Sharing&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Applications making use of Gnutella2 technology for file sharing MUST IMPLEMENT&lt;br /&gt;
the following features:&lt;br /&gt;
&lt;br /&gt;
* All of the COMMON features listed in the previous section&lt;br /&gt;
* Operation in LEAF mode, additional node states OPTIONAL&lt;br /&gt;
* Some form of bandwidth management scheme to keep network and transfer bandwidth below 95% of the user's link capacity - be it manually configured or some automatic scheme (very important to avoid flooding local connection)&lt;br /&gt;
* [[SHA1]] and TIGER ROOT [[URN]]s for all shared objects&lt;br /&gt;
* XML metadata using existing schemas where appropriate (manual entry and peer acquired at minimum, automatic local collection highly recommended, service lookup optional)&lt;br /&gt;
* Universal 1-bit query hash filter, at least 2^20 length, intelligent density management scheme (superset combination required if supporting hub mode)&lt;br /&gt;
* Gnutella2 object search mechanism, all client responsibilities and if supporting hub mode, server responsibilities too&lt;br /&gt;
* Local search processing including simple query language (Boolean operations, quoted search terms, numeric range searches, interest flagging (I), local rulebased metadata searching)&lt;br /&gt;
* Extensible hit format (URN/DN/MD/URL are REQUIRED, all other extensions OPTIONAL)&lt;br /&gt;
* HTTP/1.1 based upload system, URN based requesting, partial content requests, active queuing, partial file uploading, timestamp protected alternate source cache and exchange&lt;br /&gt;
* [[TigerTree]] volume calculation on shared files, caching on downloads, exchange via [[DIME]]. Local corruption detection OPTIONAL but recommended.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Gnutella2_Standard&amp;diff=45</id>
		<title>Gnutella2 Standard</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Gnutella2_Standard&amp;diff=45"/>
		<updated>2005-03-27T17:14:42Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Why is a Standard Needed? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is the Gnutella2 Standard? ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 Standard is a set of requirements for building applications which&lt;br /&gt;
operate with the [[Gnutella2 Network]] in different capacities. For example, the&lt;br /&gt;
Gnutella2 Standard for File Sharing specifies a set of features and behaviours which&lt;br /&gt;
must be available in any Gnutella2-connected file-sharing product offered to the&lt;br /&gt;
public.&lt;br /&gt;
&lt;br /&gt;
== Why is a Standard Needed? ==&lt;br /&gt;
&lt;br /&gt;
As an open, general purpose platform, Gnutella2 networks must be able to operate&lt;br /&gt;
with a diverse family of different implementing applications. Every effort has been&lt;br /&gt;
made to limit the ill-effects a non-compliant application can cause (deliberately or&lt;br /&gt;
accidentally), however, when it comes to critical features such as common URN&lt;br /&gt;
schemes and character encodings, minimum standards help to ensure a favourable&lt;br /&gt;
baseline user experience.&lt;br /&gt;
&lt;br /&gt;
== How are Standards Enforced? ==&lt;br /&gt;
&lt;br /&gt;
The open and transparent nature of the Gnutella2 architecture makes technical&lt;br /&gt;
enforcement difficult, so a more viable (and hopefully, more productive) social&lt;br /&gt;
scheme has instead been adopted. Only applications meeting the appropriate&lt;br /&gt;
Gnutella2 Standard may be marked as &amp;quot;Gnutella2-compliant&amp;quot;. Websites containing&lt;br /&gt;
information about Gnutella2 (such as gnutella2.com) are encouraged to list only&lt;br /&gt;
compliant applications, and application developers are encouraged to deny&lt;br /&gt;
communications with known non-compliant applications. Applications which do not&lt;br /&gt;
comply with the standard or are still in the development process should never be&lt;br /&gt;
made available to the public, however private testing is always encouraged.&lt;br /&gt;
&lt;br /&gt;
== How are Applications Tested? ==&lt;br /&gt;
&lt;br /&gt;
Ultimately it is the responsibility of the developer to ensure their own application&lt;br /&gt;
complies with the relevant standards, both with respect to Gnutella2 and any other&lt;br /&gt;
functionality they may be including. However as an inter-dependent community,&lt;br /&gt;
developers of Gnutella2-compliant applications are encouraged to take an interest in&lt;br /&gt;
other Gnutella2 applications, and where possible, examine them for compliance.&lt;br /&gt;
Similarly, new developers are strongly encouraged to seek assistance from other&lt;br /&gt;
developers in verifying their work. This need not compromise competitive advantage&lt;br /&gt;
- if the application is sensitive, the important compliance testing phase can be&lt;br /&gt;
performed in the days prior to release.&lt;br /&gt;
&lt;br /&gt;
== What Standards are Available? ==&lt;br /&gt;
&lt;br /&gt;
At the current time, only one Gnutella2 standard has been published: the Gnutella2&lt;br /&gt;
standard for File Sharing Applications. Additional standards for other&lt;br /&gt;
application classes will be published in the future as required.&lt;br /&gt;
&lt;br /&gt;
Developers of new application classes are operating in somewhat untried territory,&lt;br /&gt;
and should review the existing published standards for best practices which can be&lt;br /&gt;
borrowed. In particular, the basic components of the Gnutella2 network architecture&lt;br /&gt;
should always be implemented in full.&lt;br /&gt;
&lt;br /&gt;
== Common Gnutella2 Standard (All Applications) == &lt;br /&gt;
&lt;br /&gt;
All applications making use of Gnutella2 technology for any application class MUST&lt;br /&gt;
IMPLEMENT the following core features:&lt;br /&gt;
&lt;br /&gt;
* Bidirectional TCP stream connections (stream compression OPTIONAL)&lt;br /&gt;
* Bidirectional reliable UDP protocol (Gnutella2 reliability layer and stateless compression REQUIRED)&lt;br /&gt;
* HTTP-style link negotiation, exchanging at least the required headers&lt;br /&gt;
* Gnutella2 protocol support, graceful handling of unknown trees&lt;br /&gt;
* Localised, UTF-8 and UNICODE decode REQUIRED, encoding to each optional&lt;br /&gt;
* Operation in LEAF mode, additional node states OPTIONAL&lt;br /&gt;
* Basic link handshaking and maintenance functionality (PI/PO/LNI/KHL)&lt;br /&gt;
* Global node addressing scheme and routing maintenance, addressing children (TO)&lt;br /&gt;
* Reverse (PUSH) connection response (connecting out)&lt;br /&gt;
* HTTP/1.1 client and server for peer to peer transactions&lt;br /&gt;
* Gnutella2 Standard for File Sharing&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Applications making use of Gnutella2 technology for file sharing MUST IMPLEMENT&lt;br /&gt;
the following features:&lt;br /&gt;
&lt;br /&gt;
* All of the COMMON features listed in the previous section&lt;br /&gt;
* Operation in LEAF mode, additional node states OPTIONAL&lt;br /&gt;
* Some form of bandwidth management scheme to keep network and transfer bandwidth below 95% of the user's link capacity - be it manually configured or some automatic scheme (very important to avoid flooding local connection)&lt;br /&gt;
* [[SHA1]] and TIGER ROOT [[URN]]s for all shared objects&lt;br /&gt;
* XML metadata using existing schemas where appropriate (manual entry and peer acquired at minimum, automatic local collection highly recommended, service lookup optional)&lt;br /&gt;
* Universal 1-bit query hash filter, at least 2^20 length, intelligent density management scheme (superset combination required if supporting hub mode)&lt;br /&gt;
* Gnutella2 object search mechanism, all client responsibilities and if supporting hub mode, server responsibilities too&lt;br /&gt;
* Local search processing including simple query language (Boolean operations, quoted search terms, numeric range searches, interest flagging (I), local rulebased metadata searching)&lt;br /&gt;
* Extensible hit format (URN/DN/MD/URL are REQUIRED, all other extensions OPTIONAL)&lt;br /&gt;
* HTTP/1.1 based upload system, URN based requesting, partial content requests, active queuing, partial file uploading, timestamp protected alternate source cache and exchange&lt;br /&gt;
* [[TigerTree]] volume calculation on shared files, caching on downloads, exchange via [[DIME]]. Local corruption detection OPTIONAL but recommended.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Node_Route_Cache_and_Addressed_Packet_Forwarding&amp;diff=95</id>
		<title>Node Route Cache and Addressed Packet Forwarding</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Node_Route_Cache_and_Addressed_Packet_Forwarding&amp;diff=95"/>
		<updated>2005-03-27T17:09:24Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Push Handshaking */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Each Gnutella2 node must maintain a dynamic node route cache to map node GUIDs&lt;br /&gt;
to appropriate destinations. The route cache is consulted when a packet needs to be&lt;br /&gt;
dispatched to, or toward a GUID-addressed node. GUID-addressing is used over&lt;br /&gt;
network-addressing in a number of situations.&lt;br /&gt;
&lt;br /&gt;
== Data ==&lt;br /&gt;
&lt;br /&gt;
Each entry in a node route cache will have:&lt;br /&gt;
&lt;br /&gt;
* The GUID of the target node&lt;br /&gt;
* The local TCP connection providing the best route to the node, or&lt;br /&gt;
* A UDP endpoint for the node or the best route to the node&lt;br /&gt;
&lt;br /&gt;
== Performance ==&lt;br /&gt;
&lt;br /&gt;
A route cache needs to be addressable by GUID, and must implement a refresh&lt;br /&gt;
mechanism to store routes for an appropriate amount of time based upon route hits.&lt;br /&gt;
Many schemes exist to engineer efficient lookup systems, such as hash tables, twotable&lt;br /&gt;
exchanges and balanced trees.&lt;br /&gt;
&lt;br /&gt;
The route cache is similar to the several GUID mapping caches involved in old&lt;br /&gt;
Gnutella applications, with two key differences:&lt;br /&gt;
&lt;br /&gt;
* Each entry may map to a local address or a UDP endpoint&lt;br /&gt;
* There is only one unified route cache for all purposes&lt;br /&gt;
&lt;br /&gt;
== Applications ==&lt;br /&gt;
&lt;br /&gt;
GUIDs are used to identify virtual entities within the network, such as nodes (node&lt;br /&gt;
GUIDs), searches (search GUIDs) and other transactional requests. The GUIDs&lt;br /&gt;
associated with these entities can then be committed to the route cache and mapped&lt;br /&gt;
to reflect the easiest route back to the owner of the object.&lt;br /&gt;
&lt;br /&gt;
All nodes should be aware of their directly connected neighbours, and treat these&lt;br /&gt;
node GUIDs as a special case that need never expire.&lt;br /&gt;
&lt;br /&gt;
== Addressed Packet Forwarding ==&lt;br /&gt;
&lt;br /&gt;
Any Gnutella2 packet may be addressed to a particular destination node by GUID.&lt;br /&gt;
Upon receiving an addressed packet, it should be immediately forwarded either to&lt;br /&gt;
the destination, or toward it. Addressed packets should not be interpreted locally,&lt;br /&gt;
unless the destination address matches the local GUID.&lt;br /&gt;
&lt;br /&gt;
Loops are avoided by placing restrictions upon forwarding:&lt;br /&gt;
&lt;br /&gt;
* If received from a leaf via TCP, a packet may be forwarded anywhere&lt;br /&gt;
* If received from a hub, a packet may only be forwarded to a leaf&lt;br /&gt;
* If received via UDP, a packet may not be forwarded via UDP&lt;br /&gt;
&lt;br /&gt;
Note that these restrictions apply only to generically addressed packets. Some packet&lt;br /&gt;
types have specific forwarding rules which override these. These rules allow any&lt;br /&gt;
node to be reached in two hops.&lt;br /&gt;
&lt;br /&gt;
Packets are addressed by including a special child packet as the first child of the root&lt;br /&gt;
packet. The child packet is named &amp;quot;TO&amp;quot;, so its full name would be &amp;quot;/?/TO&amp;quot; where ? is&lt;br /&gt;
the root packet name. The address packet's payload consists of a 16 byte GUID, and&lt;br /&gt;
it has no children defined at the current time.&lt;br /&gt;
&lt;br /&gt;
== Reverse Connection (Push) Requests ==&lt;br /&gt;
&lt;br /&gt;
Addressed packet forwarding can be used to deliver any valid Gnutella2&lt;br /&gt;
communications to leaf nodes that are unable to accept TCP or UDP traffic directly.&lt;br /&gt;
The packet is simply sent to one of the hubs to which the target leaf is attached, or a&lt;br /&gt;
hub in the same hub cluster, and the forwarding rules will allow the packet to reach&lt;br /&gt;
its destination.&lt;br /&gt;
&lt;br /&gt;
This mechanism is used to request that a &amp;quot;firewalled&amp;quot; leaf initiate a &amp;quot;reverse&lt;br /&gt;
connection&amp;quot; or &amp;quot;call-back&amp;quot; to an elected address. The root packet type &amp;quot;/[[PUSH]]&amp;quot; is&lt;br /&gt;
used.&lt;br /&gt;
&lt;br /&gt;
== Push Handshaking ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 push handshake is very simple - it simply identifies the connection as&lt;br /&gt;
originating from a push, and provides the GUID of the initiating node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
PUSH guid:GUIDinHEXguidINhexGUIDinHEXguidI (\r\n)&lt;br /&gt;
(\r\n)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that unlike the Gnutella1 case, no purpose-specific information is provided. The&lt;br /&gt;
pushed connection can now be used for any purpose a normally established TCP link&lt;br /&gt;
could adopt, including, but not limited to:&lt;br /&gt;
&lt;br /&gt;
* Gnutella2 network connection&lt;br /&gt;
* Data transfer&lt;br /&gt;
* Personal communications&lt;br /&gt;
* Etc&lt;br /&gt;
&lt;br /&gt;
Gnutella2 implementations are however, strongly advised to provide backward&lt;br /&gt;
support for the Gnutella1 push handshake, even if not supporting Gnutella1 directly.&lt;br /&gt;
This is because applications supporting both protocols may be unable to determine in&lt;br /&gt;
advance, whether the host they are pushing to is Gnutella1 or Gnutella2.&lt;br /&gt;
The legacy-style push handshake looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GIV 0:GUIDinHEXguidINhexGUIDinHEXguidI/ (\n\n)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The leading zero and trailing slash have task-specific meanings in Gnutella1;&lt;br /&gt;
however Gnutella2 applications can safely ignore them and consider only the GUID.&lt;br /&gt;
Be sure to allow for variable length handshakes, however.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Node_Route_Cache_and_Addressed_Packet_Forwarding&amp;diff=43</id>
		<title>Node Route Cache and Addressed Packet Forwarding</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Node_Route_Cache_and_Addressed_Packet_Forwarding&amp;diff=43"/>
		<updated>2005-03-27T17:06:18Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Addressed Packet Forwarding */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Each Gnutella2 node must maintain a dynamic node route cache to map node GUIDs&lt;br /&gt;
to appropriate destinations. The route cache is consulted when a packet needs to be&lt;br /&gt;
dispatched to, or toward a GUID-addressed node. GUID-addressing is used over&lt;br /&gt;
network-addressing in a number of situations.&lt;br /&gt;
&lt;br /&gt;
== Data ==&lt;br /&gt;
&lt;br /&gt;
Each entry in a node route cache will have:&lt;br /&gt;
&lt;br /&gt;
* The GUID of the target node&lt;br /&gt;
* The local TCP connection providing the best route to the node, or&lt;br /&gt;
* A UDP endpoint for the node or the best route to the node&lt;br /&gt;
&lt;br /&gt;
== Performance ==&lt;br /&gt;
&lt;br /&gt;
A route cache needs to be addressable by GUID, and must implement a refresh&lt;br /&gt;
mechanism to store routes for an appropriate amount of time based upon route hits.&lt;br /&gt;
Many schemes exist to engineer efficient lookup systems, such as hash tables, twotable&lt;br /&gt;
exchanges and balanced trees.&lt;br /&gt;
&lt;br /&gt;
The route cache is similar to the several GUID mapping caches involved in old&lt;br /&gt;
Gnutella applications, with two key differences:&lt;br /&gt;
&lt;br /&gt;
* Each entry may map to a local address or a UDP endpoint&lt;br /&gt;
* There is only one unified route cache for all purposes&lt;br /&gt;
&lt;br /&gt;
== Applications ==&lt;br /&gt;
&lt;br /&gt;
GUIDs are used to identify virtual entities within the network, such as nodes (node&lt;br /&gt;
GUIDs), searches (search GUIDs) and other transactional requests. The GUIDs&lt;br /&gt;
associated with these entities can then be committed to the route cache and mapped&lt;br /&gt;
to reflect the easiest route back to the owner of the object.&lt;br /&gt;
&lt;br /&gt;
All nodes should be aware of their directly connected neighbours, and treat these&lt;br /&gt;
node GUIDs as a special case that need never expire.&lt;br /&gt;
&lt;br /&gt;
== Addressed Packet Forwarding ==&lt;br /&gt;
&lt;br /&gt;
Any Gnutella2 packet may be addressed to a particular destination node by GUID.&lt;br /&gt;
Upon receiving an addressed packet, it should be immediately forwarded either to&lt;br /&gt;
the destination, or toward it. Addressed packets should not be interpreted locally,&lt;br /&gt;
unless the destination address matches the local GUID.&lt;br /&gt;
&lt;br /&gt;
Loops are avoided by placing restrictions upon forwarding:&lt;br /&gt;
&lt;br /&gt;
* If received from a leaf via TCP, a packet may be forwarded anywhere&lt;br /&gt;
* If received from a hub, a packet may only be forwarded to a leaf&lt;br /&gt;
* If received via UDP, a packet may not be forwarded via UDP&lt;br /&gt;
&lt;br /&gt;
Note that these restrictions apply only to generically addressed packets. Some packet&lt;br /&gt;
types have specific forwarding rules which override these. These rules allow any&lt;br /&gt;
node to be reached in two hops.&lt;br /&gt;
&lt;br /&gt;
Packets are addressed by including a special child packet as the first child of the root&lt;br /&gt;
packet. The child packet is named &amp;quot;TO&amp;quot;, so its full name would be &amp;quot;/?/TO&amp;quot; where ? is&lt;br /&gt;
the root packet name. The address packet's payload consists of a 16 byte GUID, and&lt;br /&gt;
it has no children defined at the current time.&lt;br /&gt;
&lt;br /&gt;
== Reverse Connection (Push) Requests ==&lt;br /&gt;
&lt;br /&gt;
Addressed packet forwarding can be used to deliver any valid Gnutella2&lt;br /&gt;
communications to leaf nodes that are unable to accept TCP or UDP traffic directly.&lt;br /&gt;
The packet is simply sent to one of the hubs to which the target leaf is attached, or a&lt;br /&gt;
hub in the same hub cluster, and the forwarding rules will allow the packet to reach&lt;br /&gt;
its destination.&lt;br /&gt;
&lt;br /&gt;
This mechanism is used to request that a &amp;quot;firewalled&amp;quot; leaf initiate a &amp;quot;reverse&lt;br /&gt;
connection&amp;quot; or &amp;quot;call-back&amp;quot; to an elected address. The root packet type &amp;quot;/[[PUSH]]&amp;quot; is&lt;br /&gt;
used.&lt;br /&gt;
&lt;br /&gt;
== Push Handshaking ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 push handshake is very simple - it simply identifies the connection as&lt;br /&gt;
originating from a push, and provides the GUID of the initiating node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
PUSH guid:GUIDinHEXguidINhexGUIDinHEXguidI (\r\n)&lt;br /&gt;
(\r\n)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that unlike the Gnutella1 case, no purpose-specific information is provided. The&lt;br /&gt;
pushed connection can now be used for any purpose a normally established TCP link&lt;br /&gt;
could adopt, including but not limited to:&lt;br /&gt;
&lt;br /&gt;
* Gnutella2 network connection&lt;br /&gt;
* Data transfer&lt;br /&gt;
* Personal communications&lt;br /&gt;
* Etc&lt;br /&gt;
&lt;br /&gt;
Gnutella2 implementations are however strongly advised to provide backward&lt;br /&gt;
support for the Gnutella1 push handshake, even if not supporting Gnutella1 directly.&lt;br /&gt;
This is because applications supporting both protocols may be unable to determine in&lt;br /&gt;
advance whether the host they are pushing to is Gnutella1 or Gnutella2.&lt;br /&gt;
The legacy-style push handshake looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GIV 0:GUIDinHEXguidINhexGUIDinHEXguidI/ (\n\n)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The leading zero and trailing slash have task-specific meanings in Gnutella1;&lt;br /&gt;
however Gnutella2 applications can safely ignore them and consider only the GUID.&lt;br /&gt;
Be sure to allow for variable length handshakes, however.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Node_Route_Cache_and_Addressed_Packet_Forwarding&amp;diff=42</id>
		<title>Node Route Cache and Addressed Packet Forwarding</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Node_Route_Cache_and_Addressed_Packet_Forwarding&amp;diff=42"/>
		<updated>2005-03-27T17:03:11Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Each Gnutella2 node must maintain a dynamic node route cache to map node GUIDs&lt;br /&gt;
to appropriate destinations. The route cache is consulted when a packet needs to be&lt;br /&gt;
dispatched to, or toward a GUID-addressed node. GUID-addressing is used over&lt;br /&gt;
network-addressing in a number of situations.&lt;br /&gt;
&lt;br /&gt;
== Data ==&lt;br /&gt;
&lt;br /&gt;
Each entry in a node route cache will have:&lt;br /&gt;
&lt;br /&gt;
* The GUID of the target node&lt;br /&gt;
* The local TCP connection providing the best route to the node, or&lt;br /&gt;
* A UDP endpoint for the node or the best route to the node&lt;br /&gt;
&lt;br /&gt;
== Performance ==&lt;br /&gt;
&lt;br /&gt;
A route cache needs to be addressable by GUID, and must implement a refresh&lt;br /&gt;
mechanism to store routes for an appropriate amount of time based upon route hits.&lt;br /&gt;
Many schemes exist to engineer efficient lookup systems, such as hash tables, twotable&lt;br /&gt;
exchanges and balanced trees.&lt;br /&gt;
&lt;br /&gt;
The route cache is similar to the several GUID mapping caches involved in old&lt;br /&gt;
Gnutella applications, with two key differences:&lt;br /&gt;
&lt;br /&gt;
* Each entry may map to a local address or a UDP endpoint&lt;br /&gt;
* There is only one unified route cache for all purposes&lt;br /&gt;
&lt;br /&gt;
== Applications ==&lt;br /&gt;
&lt;br /&gt;
GUIDs are used to identify virtual entities within the network, such as nodes (node&lt;br /&gt;
GUIDs), searches (search GUIDs) and other transactional requests. The GUIDs&lt;br /&gt;
associated with these entities can then be committed to the route cache and mapped&lt;br /&gt;
to reflect the easiest route back to the owner of the object.&lt;br /&gt;
&lt;br /&gt;
All nodes should be aware of their directly connected neighbours, and treat these&lt;br /&gt;
node GUIDs as a special case that need never expire.&lt;br /&gt;
&lt;br /&gt;
== Addressed Packet Forwarding ==&lt;br /&gt;
&lt;br /&gt;
Any Gnutella2 packet may be addressed to a particular destination node by GUID.&lt;br /&gt;
Upon receiving an addressed packet, it should be immediately forwarded either to&lt;br /&gt;
the destination, or toward it. Addressed packets should not be interpreted locally&lt;br /&gt;
unless the destination address matches the local GUID.&lt;br /&gt;
&lt;br /&gt;
Loops are avoided by placing restrictions upon forwarding:&lt;br /&gt;
&lt;br /&gt;
* If received from a leaf via TCP, a packet may be forwarded anywhere&lt;br /&gt;
* If received from a hub, a packet may only be forwarded to a leaf&lt;br /&gt;
* If received via UDP, a packet may not be forwarded via UDP&lt;br /&gt;
&lt;br /&gt;
Note that these restrictions apply only to generically addressed packets. Some packet&lt;br /&gt;
types have specific forwarding rules which override these. These rules allow any&lt;br /&gt;
node to be reached in two hops.&lt;br /&gt;
&lt;br /&gt;
Packets are addressed by including a special child packet as the first child of the root&lt;br /&gt;
packet. The child packet is named &amp;quot;TO&amp;quot;, so its full name would be &amp;quot;/?/TO&amp;quot; where ? is&lt;br /&gt;
the root packet name. The address packet's payload consists of a 16 byte GUID, and&lt;br /&gt;
it has no children defined at the current time.&lt;br /&gt;
&lt;br /&gt;
== Reverse Connection (Push) Requests ==&lt;br /&gt;
&lt;br /&gt;
Addressed packet forwarding can be used to deliver any valid Gnutella2&lt;br /&gt;
communications to leaf nodes that are unable to accept TCP or UDP traffic directly.&lt;br /&gt;
The packet is simply sent to one of the hubs to which the target leaf is attached, or a&lt;br /&gt;
hub in the same hub cluster, and the forwarding rules will allow the packet to reach&lt;br /&gt;
its destination.&lt;br /&gt;
&lt;br /&gt;
This mechanism is used to request that a &amp;quot;firewalled&amp;quot; leaf initiate a &amp;quot;reverse&lt;br /&gt;
connection&amp;quot; or &amp;quot;call-back&amp;quot; to an elected address. The root packet type &amp;quot;/[[PUSH]]&amp;quot; is&lt;br /&gt;
used.&lt;br /&gt;
&lt;br /&gt;
== Push Handshaking ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 push handshake is very simple - it simply identifies the connection as&lt;br /&gt;
originating from a push, and provides the GUID of the initiating node:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
PUSH guid:GUIDinHEXguidINhexGUIDinHEXguidI (\r\n)&lt;br /&gt;
(\r\n)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that unlike the Gnutella1 case, no purpose-specific information is provided. The&lt;br /&gt;
pushed connection can now be used for any purpose a normally established TCP link&lt;br /&gt;
could adopt, including but not limited to:&lt;br /&gt;
&lt;br /&gt;
* Gnutella2 network connection&lt;br /&gt;
* Data transfer&lt;br /&gt;
* Personal communications&lt;br /&gt;
* Etc&lt;br /&gt;
&lt;br /&gt;
Gnutella2 implementations are however strongly advised to provide backward&lt;br /&gt;
support for the Gnutella1 push handshake, even if not supporting Gnutella1 directly.&lt;br /&gt;
This is because applications supporting both protocols may be unable to determine in&lt;br /&gt;
advance whether the host they are pushing to is Gnutella1 or Gnutella2.&lt;br /&gt;
The legacy-style push handshake looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GIV 0:GUIDinHEXguidINhexGUIDinHEXguidI/ (\n\n)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The leading zero and trailing slash have task-specific meanings in Gnutella1;&lt;br /&gt;
however Gnutella2 applications can safely ignore them and consider only the GUID.&lt;br /&gt;
Be sure to allow for variable length handshakes, however.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Datatypes&amp;diff=76</id>
		<title>Datatypes</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Datatypes&amp;diff=76"/>
		<updated>2005-03-27T17:01:16Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Strings */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The format of a packet payload is defined by the packet type and can consist of any&lt;br /&gt;
binary data; however, there are a number of conventions in place for serializing&lt;br /&gt;
common datatypes.&lt;br /&gt;
&lt;br /&gt;
== Multi-Byte Integers ==&lt;br /&gt;
&lt;br /&gt;
Multi-byte integers are serialized in the byte-order of the topmost packet. Little endian&lt;br /&gt;
is the default byte-order; however, big-endian byte order can be selected for&lt;br /&gt;
those who want it.&lt;br /&gt;
&lt;br /&gt;
== Network/Node Addresses ==&lt;br /&gt;
&lt;br /&gt;
A network or node address consists of a physical address and a port number, and are&lt;br /&gt;
of variable length, depending on the address family.&lt;br /&gt;
In IPv4, a network/node address is six bytes long: 4 bytes for an IP address and 2&lt;br /&gt;
bytes for a port number as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
BYTE ip[4];&lt;br /&gt;
SHORT port;&lt;br /&gt;
} IPV4_ENDPOINT;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this is considered an array of 4 8-bit integers (bytes), followed by a 16-bit&lt;br /&gt;
integer (short). Byte order does not affect bytes, but it will affect the 16-bit port&lt;br /&gt;
number.&lt;br /&gt;
&lt;br /&gt;
IPv6 addresses are longer and are not yet defined within the scope of Gnutella2,&lt;br /&gt;
however, applications should be aware that if the node address is not 6 bytes, it is of&lt;br /&gt;
a different address family.&lt;br /&gt;
&lt;br /&gt;
== GUIDs ==&lt;br /&gt;
&lt;br /&gt;
Globally unique identifiers (GUIDs) are used to identify nodes on the network. GUIDs&lt;br /&gt;
are serialized as an array of 16 bytes.&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Strings are encoded with UTF-8 encoding and serialized as a zero-terminated&lt;br /&gt;
sequence of 8 bit integers.&lt;br /&gt;
&lt;br /&gt;
A zero character (0x00) marks the end of the string, however, if the string data meets&lt;br /&gt;
the end of the packet (or child packet) payload, the terminator is not required. This&lt;br /&gt;
means that packets whose payload consists of a string, do not need to include a zero&lt;br /&gt;
string terminator and their payload length will be the byte length of the encoded&lt;br /&gt;
string exactly.&lt;br /&gt;
&lt;br /&gt;
UTF-8 encoding is required for all strings present in the packet payload. This means&lt;br /&gt;
that 7-bit characters may be passed as-is, while extended characters are encoded&lt;br /&gt;
with multi-byte sequences.&lt;br /&gt;
&lt;br /&gt;
All applications must be able to parse UTF-8 encoded strings, however, it is up to the&lt;br /&gt;
individual application whether to store the string in Unicode, or convert it to the&lt;br /&gt;
local code page for processing. In situations where a packet must be processed 'and'&lt;br /&gt;
forwarded, the original packet must be forwarded rather than a regenerated version.&lt;br /&gt;
This ensures that both locally unsupported encodings and packet extensions are&lt;br /&gt;
preserved.&lt;br /&gt;
&lt;br /&gt;
Applications should never send ANSI strings directly if they contain extended&lt;br /&gt;
characters with the MSB set. These should be encoded with UTF-8. If this is not&lt;br /&gt;
done, the decoding process may fail and the packet will be discarded or contain&lt;br /&gt;
bogus information.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Datatypes&amp;diff=40</id>
		<title>Datatypes</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Datatypes&amp;diff=40"/>
		<updated>2005-03-27T16:52:23Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Network/Node Addresses */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The format of a packet payload is defined by the packet type and can consist of any&lt;br /&gt;
binary data; however, there are a number of conventions in place for serializing&lt;br /&gt;
common datatypes.&lt;br /&gt;
&lt;br /&gt;
== Multi-Byte Integers ==&lt;br /&gt;
&lt;br /&gt;
Multi-byte integers are serialized in the byte-order of the topmost packet. Little endian&lt;br /&gt;
is the default byte-order; however, big-endian byte order can be selected for&lt;br /&gt;
those who want it.&lt;br /&gt;
&lt;br /&gt;
== Network/Node Addresses ==&lt;br /&gt;
&lt;br /&gt;
A network or node address consists of a physical address and a port number, and are&lt;br /&gt;
of variable length, depending on the address family.&lt;br /&gt;
In IPv4, a network/node address is six bytes long: 4 bytes for an IP address and 2&lt;br /&gt;
bytes for a port number as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
BYTE ip[4];&lt;br /&gt;
SHORT port;&lt;br /&gt;
} IPV4_ENDPOINT;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this is considered an array of 4 8-bit integers (bytes), followed by a 16-bit&lt;br /&gt;
integer (short). Byte order does not affect bytes, but it will affect the 16-bit port&lt;br /&gt;
number.&lt;br /&gt;
&lt;br /&gt;
IPv6 addresses are longer and are not yet defined within the scope of Gnutella2,&lt;br /&gt;
however, applications should be aware that if the node address is not 6 bytes, it is of&lt;br /&gt;
a different address family.&lt;br /&gt;
&lt;br /&gt;
== GUIDs ==&lt;br /&gt;
&lt;br /&gt;
Globally unique identifiers (GUIDs) are used to identify nodes on the network. GUIDs&lt;br /&gt;
are serialized as an array of 16 bytes.&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Strings are encoded with UTF-8 encoding and serialized as a zero-terminated&lt;br /&gt;
sequence of 8 bit integers.&lt;br /&gt;
&lt;br /&gt;
A zero character (0x00) marks the end of the string, however if the string data meets&lt;br /&gt;
the end of the packet (or child packet) payload, the terminator is not required. This&lt;br /&gt;
means that packets whose payload consists of a string do not need to include a zero&lt;br /&gt;
string terminator and their payload length will be the byte length of the encoded&lt;br /&gt;
string exactly.&lt;br /&gt;
&lt;br /&gt;
UTF-8 encoding is required for all strings present in the packet payload. This means&lt;br /&gt;
that 7-bit characters may be passed as-is, while extended characters are encoded&lt;br /&gt;
with multi-byte sequences.&lt;br /&gt;
&lt;br /&gt;
All applications must be able to parse UTF-8 encoded strings, however it is up to the&lt;br /&gt;
individual application whether to store the string in Unicode or convert it to the a&lt;br /&gt;
local code page for processing. In situations where a packet must be processed 'and'&lt;br /&gt;
forwarded, the original packet must be forwarded rather than a regenerated version.&lt;br /&gt;
This ensures that both locally unsupported encodings and packet extensions are&lt;br /&gt;
preserved.&lt;br /&gt;
&lt;br /&gt;
Applications should never send ANSI strings directly if they contain extended&lt;br /&gt;
characters with the MSB set. These should be encoded with UTF-8. If this is not&lt;br /&gt;
done, the decoding process may fail and the packet will be discarded or contain&lt;br /&gt;
bogus information.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Datatypes&amp;diff=39</id>
		<title>Datatypes</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Datatypes&amp;diff=39"/>
		<updated>2005-03-27T16:50:52Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Multi-Byte Integers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The format of a packet payload is defined by the packet type and can consist of any&lt;br /&gt;
binary data; however, there are a number of conventions in place for serializing&lt;br /&gt;
common datatypes.&lt;br /&gt;
&lt;br /&gt;
== Multi-Byte Integers ==&lt;br /&gt;
&lt;br /&gt;
Multi-byte integers are serialized in the byte-order of the topmost packet. Little endian&lt;br /&gt;
is the default byte-order; however, big-endian byte order can be selected for&lt;br /&gt;
those who want it.&lt;br /&gt;
&lt;br /&gt;
== Network/Node Addresses ==&lt;br /&gt;
&lt;br /&gt;
A network or node address consists of a physical address and a port number, and are&lt;br /&gt;
of variable length depending on the address family.&lt;br /&gt;
In IPv4, a network/node address is six bytes long: 4 bytes for an IP address and 2&lt;br /&gt;
bytes for a port number as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
BYTE ip[4];&lt;br /&gt;
SHORT port;&lt;br /&gt;
} IPV4_ENDPOINT;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this is considered an array of 4 8-bit integers (bytes), followed by a 16-bit&lt;br /&gt;
integer (short). Byte order does not affect bytes, but it will affect the 16-bit port&lt;br /&gt;
number.&lt;br /&gt;
&lt;br /&gt;
IPv6 addresses are longer and are not yet defined within the scope of Gnutella2,&lt;br /&gt;
however applications should be aware that if the node address is not 6 bytes it is of&lt;br /&gt;
a different address family.&lt;br /&gt;
&lt;br /&gt;
== GUIDs ==&lt;br /&gt;
&lt;br /&gt;
Globally unique identifiers (GUIDs) are used to identify nodes on the network. GUIDs&lt;br /&gt;
are serialized as an array of 16 bytes.&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Strings are encoded with UTF-8 encoding and serialized as a zero-terminated&lt;br /&gt;
sequence of 8 bit integers.&lt;br /&gt;
&lt;br /&gt;
A zero character (0x00) marks the end of the string, however if the string data meets&lt;br /&gt;
the end of the packet (or child packet) payload, the terminator is not required. This&lt;br /&gt;
means that packets whose payload consists of a string do not need to include a zero&lt;br /&gt;
string terminator and their payload length will be the byte length of the encoded&lt;br /&gt;
string exactly.&lt;br /&gt;
&lt;br /&gt;
UTF-8 encoding is required for all strings present in the packet payload. This means&lt;br /&gt;
that 7-bit characters may be passed as-is, while extended characters are encoded&lt;br /&gt;
with multi-byte sequences.&lt;br /&gt;
&lt;br /&gt;
All applications must be able to parse UTF-8 encoded strings, however it is up to the&lt;br /&gt;
individual application whether to store the string in Unicode or convert it to the a&lt;br /&gt;
local code page for processing. In situations where a packet must be processed 'and'&lt;br /&gt;
forwarded, the original packet must be forwarded rather than a regenerated version.&lt;br /&gt;
This ensures that both locally unsupported encodings and packet extensions are&lt;br /&gt;
preserved.&lt;br /&gt;
&lt;br /&gt;
Applications should never send ANSI strings directly if they contain extended&lt;br /&gt;
characters with the MSB set. These should be encoded with UTF-8. If this is not&lt;br /&gt;
done, the decoding process may fail and the packet will be discarded or contain&lt;br /&gt;
bogus information.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Datatypes&amp;diff=38</id>
		<title>Datatypes</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Datatypes&amp;diff=38"/>
		<updated>2005-03-27T16:50:14Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The format of a packet payload is defined by the packet type and can consist of any&lt;br /&gt;
binary data; however, there are a number of conventions in place for serializing&lt;br /&gt;
common datatypes.&lt;br /&gt;
&lt;br /&gt;
== Multi-Byte Integers ==&lt;br /&gt;
&lt;br /&gt;
Multi-byte integers are serialized in the byte-order of the topmost packet. Little endian&lt;br /&gt;
is the default byte-order; however big-endian byte order can be selected for&lt;br /&gt;
those who want it.&lt;br /&gt;
&lt;br /&gt;
== Network/Node Addresses ==&lt;br /&gt;
&lt;br /&gt;
A network or node address consists of a physical address and a port number, and are&lt;br /&gt;
of variable length depending on the address family.&lt;br /&gt;
In IPv4, a network/node address is six bytes long: 4 bytes for an IP address and 2&lt;br /&gt;
bytes for a port number as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
BYTE ip[4];&lt;br /&gt;
SHORT port;&lt;br /&gt;
} IPV4_ENDPOINT;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this is considered an array of 4 8-bit integers (bytes), followed by a 16-bit&lt;br /&gt;
integer (short). Byte order does not affect bytes, but it will affect the 16-bit port&lt;br /&gt;
number.&lt;br /&gt;
&lt;br /&gt;
IPv6 addresses are longer and are not yet defined within the scope of Gnutella2,&lt;br /&gt;
however applications should be aware that if the node address is not 6 bytes it is of&lt;br /&gt;
a different address family.&lt;br /&gt;
&lt;br /&gt;
== GUIDs ==&lt;br /&gt;
&lt;br /&gt;
Globally unique identifiers (GUIDs) are used to identify nodes on the network. GUIDs&lt;br /&gt;
are serialized as an array of 16 bytes.&lt;br /&gt;
&lt;br /&gt;
== Strings ==&lt;br /&gt;
&lt;br /&gt;
Strings are encoded with UTF-8 encoding and serialized as a zero-terminated&lt;br /&gt;
sequence of 8 bit integers.&lt;br /&gt;
&lt;br /&gt;
A zero character (0x00) marks the end of the string, however if the string data meets&lt;br /&gt;
the end of the packet (or child packet) payload, the terminator is not required. This&lt;br /&gt;
means that packets whose payload consists of a string do not need to include a zero&lt;br /&gt;
string terminator and their payload length will be the byte length of the encoded&lt;br /&gt;
string exactly.&lt;br /&gt;
&lt;br /&gt;
UTF-8 encoding is required for all strings present in the packet payload. This means&lt;br /&gt;
that 7-bit characters may be passed as-is, while extended characters are encoded&lt;br /&gt;
with multi-byte sequences.&lt;br /&gt;
&lt;br /&gt;
All applications must be able to parse UTF-8 encoded strings, however it is up to the&lt;br /&gt;
individual application whether to store the string in Unicode or convert it to the a&lt;br /&gt;
local code page for processing. In situations where a packet must be processed 'and'&lt;br /&gt;
forwarded, the original packet must be forwarded rather than a regenerated version.&lt;br /&gt;
This ensures that both locally unsupported encodings and packet extensions are&lt;br /&gt;
preserved.&lt;br /&gt;
&lt;br /&gt;
Applications should never send ANSI strings directly if they contain extended&lt;br /&gt;
characters with the MSB set. These should be encoded with UTF-8. If this is not&lt;br /&gt;
done, the decoding process may fail and the packet will be discarded or contain&lt;br /&gt;
bogus information.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Packet_Structure&amp;diff=75</id>
		<title>Packet Structure</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Packet_Structure&amp;diff=75"/>
		<updated>2005-03-27T16:48:55Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
All Gnutella2 communications are represented with Gnutella2 lightweight tree&lt;br /&gt;
packets. This applies everywhere from TCP stream communications to reliable UDP&lt;br /&gt;
transmissions to HTTP packet exchanges (where protocol data has been negotiated).&lt;br /&gt;
Each tree packet may contain meaningful payload data and/or one or more child&lt;br /&gt;
packets, allowing complex document structures to be created and extended in a&lt;br /&gt;
backward compatible manner.&lt;br /&gt;
&lt;br /&gt;
The concept can be compared to an XML document tree. The &amp;quot;packets&amp;quot; are&lt;br /&gt;
elements, which can in turn contain zero or more child elements (packets). The&lt;br /&gt;
payload of a packet is like the attributes of an XML element. However, serializing XML&lt;br /&gt;
has a lot of overhead due to all the naming, even in a compact binary form. The&lt;br /&gt;
Gnutella2 packet structure makes a compromise: it names elements (packets),&lt;br /&gt;
allowing them to be globally recognized and understood, without knowledge of their&lt;br /&gt;
format - and stores attributes as binary payloads, requiring knowledge of their&lt;br /&gt;
content to parse them.&lt;br /&gt;
&lt;br /&gt;
Thus the element (packet or child packet) is the finite unit of comprehension. This&lt;br /&gt;
system provides an excellent trade-off between format transparency and&lt;br /&gt;
compactness.&lt;br /&gt;
&lt;br /&gt;
== Fictitious Visual Example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
+ Query Hit Packet&lt;br /&gt;
|&lt;br /&gt;
|-+ Node ID (standard)&lt;br /&gt;
|&lt;br /&gt;
|-+ Server Status (standard)&lt;br /&gt;
| \-+ Shareaza Server Status (private extension)&lt;br /&gt;
|&lt;br /&gt;
|-+ Hit Object&lt;br /&gt;
| |-+ URN (standard)&lt;br /&gt;
| |-+ Descriptive name (standard)&lt;br /&gt;
| | \-+ Alternate name list (extension)&lt;br /&gt;
| |-+ URL (standard)&lt;br /&gt;
| |-+ Priority indicator (private extension)&lt;br /&gt;
| | \-+ Digital signature (private)&lt;br /&gt;
| |-+ Alternate source summary (standard)&lt;br /&gt;
| \-+ Available ranges (standard)&lt;br /&gt;
| . \-+ Estimated completion time (private extension)&lt;br /&gt;
|&lt;br /&gt;
|-+ Selective digital signature (private)&lt;br /&gt;
|&lt;br /&gt;
\-+ Routing tags&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
&lt;br /&gt;
Each Gnutella2 packet contains:&lt;br /&gt;
&lt;br /&gt;
* Control flags&lt;br /&gt;
* A type name meaningful in the namespace of the packet's parent or context&lt;br /&gt;
* A length (or implied length)&lt;br /&gt;
* Payload data of a format specific to the packet type name and namespace&lt;br /&gt;
* Child packets existing in the namespace of this packet&lt;br /&gt;
&lt;br /&gt;
== Namespace Considerations ==&lt;br /&gt;
&lt;br /&gt;
Each packet contains a relative type name of up to 8 bytes in length, which are case&lt;br /&gt;
sensitive. The packet type name is meaningful only in the namespace of the packet's&lt;br /&gt;
parent, or in the absence of a parent, the context of the packet (e.g. root level TCP&lt;br /&gt;
stream).&lt;br /&gt;
&lt;br /&gt;
This means that, for example a packet &amp;quot;A&amp;quot; inside packet &amp;quot;X&amp;quot; is different to a packet&lt;br /&gt;
&amp;quot;A&amp;quot; inside packet &amp;quot;Y&amp;quot;. Packets are of the same type only if their fully qualified&lt;br /&gt;
absolute type names are equal.&lt;br /&gt;
&lt;br /&gt;
As a convention, when discussing packet type names, they will be noted in their&lt;br /&gt;
absolute form with a URL style slash (/) separating each level. In the above example,&lt;br /&gt;
the first packet is &amp;quot;/X/A&amp;quot; while the second is &amp;quot;/Y/A&amp;quot;. It is clear now that the packets&lt;br /&gt;
are of different types.&lt;br /&gt;
&lt;br /&gt;
Packet type names can contain from 1 to 8 bytes inclusive, and none of these bytes&lt;br /&gt;
may be a null (0). Community approved packets are by convention named with&lt;br /&gt;
uppercase characters and digits, for example &amp;quot;PUSH&amp;quot;. Private packet types are by&lt;br /&gt;
convention named with lowercase characters and digits, prefixed with the vendor&lt;br /&gt;
code of the owner, for example &amp;quot;RAZAclr2&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Framing ==&lt;br /&gt;
&lt;br /&gt;
Packets are encoded with a single leading control byte, followed by one or more&lt;br /&gt;
bytes of packet length, followed by one or more bytes of packet name/ID, followed&lt;br /&gt;
by zero or more child packets (framed the same way), followed by zero or more&lt;br /&gt;
bytes of payload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
| Control | Length_| Name___ | children and/or payload |&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All packets can contain a payload only, children and a payload, children only, or&lt;br /&gt;
nothing at all. The total length of the packet header (control, length and type name)&lt;br /&gt;
cannot exceed 12 bytes and cannot be less than 2 bytes.&lt;br /&gt;
&lt;br /&gt;
=== The Control Byte ===&lt;br /&gt;
&lt;br /&gt;
The control byte is always non-zero. A zero control byte identifies the end of a&lt;br /&gt;
stream of packets, and thus has special meaning. It should not be used in root&lt;br /&gt;
packet streams (which do not end).&lt;br /&gt;
Control bytes have the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Bit 7 Bit 0&lt;br /&gt;
| Len_Len | Name_Len - 1 | CF | BE | // |&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Len_Len is the number of bytes in the length field of the packet, which immediately follows the control byte. There are two bits here which means the length field can be up to 3 bytes long. Len_Len? can be zero if the packet has zero length (no children and no payload), in which case there is no need to encode the length.&lt;br /&gt;
* Name_Len is the number of bytes in the packet name field MINUS ONE, which follows the packet length field. There are three bits here which means that packet names can be 1 to 8 bytes long inclusive. Because a 0 here equates to one byte of name, unnamed packets are not possible.&lt;br /&gt;
* The three least significant bits of the control byte are reserved for flags. They have the following meanings:&lt;br /&gt;
* CF is the compound packet flag. If this bit is set, the packet contains one or more child packets. If not set, the packet does not contain any child packets. If the packet is of zero length, this flag is ignored.&lt;br /&gt;
* BE is the big-endian packet flag. If set, all multi-byte values encoded in the packet and its children are encoded in big-endian byte order - including the length in the packet header.&lt;br /&gt;
* Other bits are reserved.&lt;br /&gt;
&lt;br /&gt;
=== The Length Field ===&lt;br /&gt;
&lt;br /&gt;
The length field immediately follows the control byte, and can be 0 to 3 bytes long.&lt;br /&gt;
Length bytes are stored in the byte order of the packet.&lt;br /&gt;
&lt;br /&gt;
The length value includes the payload of this packet AND any child packets in their&lt;br /&gt;
entirety. This is obviously needed so that the entire packet can be detected and&lt;br /&gt;
acquired from a stream. The length does not include the header (control byte,&lt;br /&gt;
length, and name). The length field precedes the name field to allow it to be read&lt;br /&gt;
faster from a stream when acquiring packets.&lt;br /&gt;
&lt;br /&gt;
The length field is in the byte order of the root packet.&lt;br /&gt;
&lt;br /&gt;
=== The Type Name Field ===&lt;br /&gt;
&lt;br /&gt;
The type name field immediately follows the length bytes, and can be from 1 to 8&lt;br /&gt;
bytes long. Its format is detailed in the previous section entitled &amp;quot;Namespace&lt;br /&gt;
Considerations&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Child Packets ===&lt;br /&gt;
&lt;br /&gt;
Child packets are only present if the &amp;quot;compound packet bit&amp;quot; is set in the control byte.&lt;br /&gt;
If set, there is one or more child packet immediately following the end of the header.&lt;br /&gt;
These child packets are included in the total length of their parent (along with the&lt;br /&gt;
payload, which follows the child packets after a packet stream terminator).&lt;br /&gt;
&lt;br /&gt;
Child packets are framed exactly the same way, with a control byte, length, name,&lt;br /&gt;
children and/or payload. When the compound bit is set and the packet is not of zero&lt;br /&gt;
length, the first child packet must exist. Subsequent child packets may also exist, and&lt;br /&gt;
are read in sequentially in the same way that they are read from a root packet&lt;br /&gt;
stream. The end of the child packet stream is signalled by the presence of a zero&lt;br /&gt;
control byte, OR the end of the parent packet's length (in which case there is no&lt;br /&gt;
payload). Including a terminating zero control byte when there is no payload is still&lt;br /&gt;
valid, but unnecessary.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
Payload may exist whenever the length field is non-zero. However, if the compound&lt;br /&gt;
bit is set, one or more child packets must be read before the payload is reached. If&lt;br /&gt;
there is no packet left after the end of the last child, there is no payload.&lt;br /&gt;
&lt;br /&gt;
=== Notes on the Control Byte ===&lt;br /&gt;
Note that there are a number of &amp;quot;marker packet types&amp;quot;, which have no children or&lt;br /&gt;
payload. It is desirable to encode these in as small a space as possible, which means&lt;br /&gt;
omitting the length field and setting the len_len bits to zero in the control byte. This&lt;br /&gt;
creates a potential conflict, as the control byte itself may be zero if the type name is&lt;br /&gt;
one byte long - and as noted above, a zero control byte has special meaning (end of&lt;br /&gt;
packet stream). This must be avoided; luckily it is perfectly legal to set the&lt;br /&gt;
compound packet flag (CF) on zero length packets, thus producing a non-zero&lt;br /&gt;
control byte and the most compact packet possible.&lt;br /&gt;
&lt;br /&gt;
The compound packet bit MUST be checked when decoding every packet. It should&lt;br /&gt;
be done in low-level decoding code to avoid accidental omission. Do not assume that&lt;br /&gt;
a packet will not have children - it might not now, but no packets are sterile.&lt;br /&gt;
Anything could be augmented or extended in some unknown way in the future. If&lt;br /&gt;
you are not interested in children, skip them (which is easy, you don't even need to&lt;br /&gt;
recurs through their children).&lt;br /&gt;
&lt;br /&gt;
=== Simple Packet Decoder in C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BYTE nInput = ReadNextByte();&lt;br /&gt;
&lt;br /&gt;
if ( nInput == 0 ) return S_NO_MORE_CHILDREN;&lt;br /&gt;
&lt;br /&gt;
BYTE nLenLen = ( nInput &amp;amp; 0xC0 ) &amp;gt;&amp;gt; 6;&lt;br /&gt;
BYTE nTypeLen = ( nInput &amp;amp; 0x38 ) &amp;gt;&amp;gt; 3;&lt;br /&gt;
BYTE nFlags = ( nInput &amp;amp; 0x07 );&lt;br /&gt;
&lt;br /&gt;
BOOL bBigEndian = ( nFlags &amp;amp; 0x02 ) ? TRUE : FALSE;&lt;br /&gt;
BOOL bIsCompound = ( nFlags &amp;amp; 0x04 ) ? TRUE : FALSE;&lt;br /&gt;
&lt;br /&gt;
ASSERT( ! bBigEndian );&lt;br /&gt;
&lt;br /&gt;
DWORD nPacketLength = 0;&lt;br /&gt;
&lt;br /&gt;
ReadBytes( (BYTE*)&amp;amp;nPacketLength, nLenLen );&lt;br /&gt;
&lt;br /&gt;
CHAR szType[9];&lt;br /&gt;
ReadBytes( (BYTE*)szType, nTypeLen + 1 );&lt;br /&gt;
szType[ nTypeLen + 1 ] = 0;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=74</id>
		<title>UDP Transceiver</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=74"/>
		<updated>2005-03-27T16:43:22Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Performance Considerations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The User Datagram Protocol (UDP) is invaluable in peer to peer systems because it&lt;br /&gt;
provides a relatively low-cost (low-overhead) method of sending short, irregular&lt;br /&gt;
messages to a very large number of peers on demand. Establishing a TCP stream&lt;br /&gt;
connection to a peer simply to deliver a single packet of information is wasteful in&lt;br /&gt;
data volume and time for the peers involved and state-aware network devices along&lt;br /&gt;
the route, for example, network address translation facilities. When dealing with a&lt;br /&gt;
large number of peers quickly, these costs become unbearable. UDP provides a&lt;br /&gt;
solution and makes this kind of interaction possible.&lt;br /&gt;
&lt;br /&gt;
However, the delivery of UDP packets is not reliable: packets may be lost en-route for&lt;br /&gt;
a number of reasons. Often this behaviour is desirable, for example when the&lt;br /&gt;
destination node's connection is highly congested, UDP packets are likely to be&lt;br /&gt;
discarded. If the content was not critical, this loss is appropriate as the host's&lt;br /&gt;
resources are effectively unavailable. In other scenarios involving critical payloads,&lt;br /&gt;
UDP's lack of reliability is a problem: either the sender needs to make sure the&lt;br /&gt;
receiver gets the payload, or it needs to know definitively that the receiver was&lt;br /&gt;
unavailable.&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 network solves this problem by implementing a selectively engaged&lt;br /&gt;
reliability layer on top of the basic UDP protocol. This reliability layer shares some&lt;br /&gt;
common functionality with TCP, but importantly does not provide any connection&lt;br /&gt;
state and thus retains the efficiency originally sought in UDP.&lt;br /&gt;
&lt;br /&gt;
This allows Gnutella2 to select the most optimal communication medium for each&lt;br /&gt;
and every transmission it needs to perform:&lt;br /&gt;
&lt;br /&gt;
* If a significant volume of data is to be exchanged, or subsequent data will be exchanged with the same destination, a TCP connection is established&lt;br /&gt;
* If a small volume of important data is to be exchanged in a once-off operation or irregularly, reliable UDP is used&lt;br /&gt;
* If a small volume of unimportant data is to be exchanged in a once-off operation or irregularly, unreliable UDP is used&lt;br /&gt;
&lt;br /&gt;
== UDP ==&lt;br /&gt;
&lt;br /&gt;
Gnutella2 semi-reliable communication is transported using the UDP protocol. The&lt;br /&gt;
port number for receiving UDP is the same as the port number listening for TCP&lt;br /&gt;
connections.&lt;br /&gt;
&lt;br /&gt;
== Encoding ==&lt;br /&gt;
&lt;br /&gt;
Implementing an additional reliable protocol within UDP requires a small control&lt;br /&gt;
header before the payload itself. This header is put to good use:&lt;br /&gt;
&lt;br /&gt;
A small signature identifies the packet as a Gnutella2 semi-reliable UDP datagram.&lt;br /&gt;
This allows the same port to be used for receiving UDP traffic for other protocols if&lt;br /&gt;
desired, and offers some simple protection against random, unexpected traffic.&lt;br /&gt;
A content code identifies the payload as a Gnutella2 packet stream, allowing future&lt;br /&gt;
protocols to be added within the same reliability layer if desired. &lt;br /&gt;
Flags allow additional attributes to be specified, such as inline stateless compression&lt;br /&gt;
of the payload (which is a required feature).&lt;br /&gt;
The header has a fixed size of 8 bytes, and is represented by the following C&lt;br /&gt;
structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#pragma pack(1)&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
   CHAR szTag3;&lt;br /&gt;
   BYTE nFlags;&lt;br /&gt;
   WORD nSequence;&lt;br /&gt;
   BYTE nPart;&lt;br /&gt;
   BYTE nCount;&lt;br /&gt;
} GND_HEADER;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The members of the structure are detailed below:&lt;br /&gt;
&lt;br /&gt;
* '''szTag''' - contains a three byte encoding protocol identifier, in this case &amp;quot;GND&amp;quot; for &amp;quot;GNutella Datagram&amp;quot;. If this signature is not present the packet should not be decoded as a Gnutella2 reliability layer transmission.&lt;br /&gt;
* '''nFlags''' - contains flags which modify the content of the packet. The low-order nibble is reserved for critical flags: if one of these bits is set but the decoding software does not understand the meaning, the packet must be discarded. The high-order nibble is reserved for non-critical flags: when set these bits may be interpreted, but an inability to interpret a bit does not cause the packet to be discarded. Currently defined flags are:&lt;br /&gt;
:* '''0x01''' - Deflate&lt;br /&gt;
::  When the deflate bit is set, the entire payload is compressed with the deflate algorithm. The compression method used is the Deflate Compression Data Format (RFC 1951). On top of this compression a ZLIB ‘wrapper’ is applied (RFC 1950, ZLIB Compressed Data Format). The ZLIB wrapper ensures packet integrity, among other things. Note that the entire payload must be reassembled in the correct order before it can be deflated if the packet was fragmented. Fragments are not compressed separately!&lt;br /&gt;
:* '''0x02''' - Acknowledge Me&lt;br /&gt;
:: When the acknowledge me bit is set, the sender is expecting an acknowledgement for this packet.&lt;br /&gt;
&lt;br /&gt;
* '''nSequence''' - contains the sequence number of the packet. This sequence number is unique to the sending host only. It is not unique to the pair of the sending host and receiving host as in TCP, as there is no concept of connection state. Sequence numbers on consecutive packets need not be increasing (although that is convenient) â€“ they must only be different. If a packet is fragmented, all of its fragments will have the same sequence number. Byte order is unimportant here.&lt;br /&gt;
* '''nPart''' - contains the fragment part number (1 &amp;lt;= nPart &amp;lt;= nCount)&lt;br /&gt;
* '''nCount''' - contains the number of fragment parts in this packet. On a transmission, this value will be non-zero (all packets must have at least one fragment). If nCount is zero, this is an acknowledgement (see below).&lt;br /&gt;
&lt;br /&gt;
== Fragmentation ==&lt;br /&gt;
&lt;br /&gt;
Large packets must be fragmented before they can be sent through most network&lt;br /&gt;
interfaces. Different network media have different MTUs, and it is difficult to predict&lt;br /&gt;
what the lowest common size will be. Fragmentation and reassembly is performed by&lt;br /&gt;
the existing Internet protocols, however, there are two important reasons why the&lt;br /&gt;
reliability layer performs its own fragmentation:&lt;br /&gt;
&lt;br /&gt;
* Sockets implementations specify a maximum datagram size. This is adequate for the vast majority of transmissions, but it is desirable to have the transparent ability to send larger packets without worrying about the host implementation.&lt;br /&gt;
* When the Internet protocols fragment, a packet and one or more fragments are lost, it may decide to discard the whole packet in an unreliable datagram protocol. The Gnutella2 reliability layer can compensate by retransmitting the whole packet, which would then be re-fragmented and each fragment resent - however, this wastes the fragments that were successfully received before. Managing fragmentation natively allows this optimisation.&lt;br /&gt;
&lt;br /&gt;
Each node determines its own MTU, often based on a best guess combined with&lt;br /&gt;
information from the host's sockets implementation. Packets exceeding this size are&lt;br /&gt;
fragmented into multiple datagrams of the appropriate size. Each datagram has the&lt;br /&gt;
same sequence number and the same fragment count (nCount), but a different&lt;br /&gt;
fragment number (nPart).&lt;br /&gt;
&lt;br /&gt;
== Transmission Process ==&lt;br /&gt;
&lt;br /&gt;
When a packet is to be transmitted, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* Cache the payload&lt;br /&gt;
* Allocate a new locally and temporally unique sequence number&lt;br /&gt;
* Derive the appropriate number of fragments&lt;br /&gt;
* Queue the fragments for dispatch&lt;br /&gt;
* If the fragments do not need to be acknowledged, the packet can be flushed now&lt;br /&gt;
&lt;br /&gt;
The payload will generally be cached for an appropriate timeout period, or until the&lt;br /&gt;
data cache becomes full, at which time older payloads can be discarded. Fragments&lt;br /&gt;
are dispatched according to the dispatch algorithm of choice, and the sender listens&lt;br /&gt;
for acknowledgements. When an acknowledgement is received:&lt;br /&gt;
&lt;br /&gt;
* Lookup the sent packet by sequence number&lt;br /&gt;
* Mark the nPart fragment as received and cancel any retransmissions of this part&lt;br /&gt;
* If all fragments have been acknowledged, flush this packet from the cache&lt;br /&gt;
&lt;br /&gt;
If a fragment has been transmitted but has not been acknowledged within the&lt;br /&gt;
timeout, it should be retransmitted. A finite number of retransmissions are allowed&lt;br /&gt;
before the packet as a whole expires, at which time it is assumed that the packet&lt;br /&gt;
was not received.&lt;br /&gt;
&lt;br /&gt;
== Receive Process ==&lt;br /&gt;
&lt;br /&gt;
When a new datagram is received, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* If the acknowledge bit was set, send an acknowledge packet for this sequence number and part number, with nCount set to zero (ack)&lt;br /&gt;
* Lookup any existing packet by the sending IP and sequence number &lt;br /&gt;
* If there is no existing packet, create a new packet entry with the IP, sequence number, fragment count and flags&lt;br /&gt;
* If there was an existing packet, make sure it is not marked as done - if so, abort&lt;br /&gt;
* Add the transmitted fragment to the (new or old) packet entry&lt;br /&gt;
* If the packet now has all fragments, mark it as done and decode it and pass it up to the application layer&lt;br /&gt;
* Leave the packet on the cache even if it was finished, in case any parts are retransmitted&lt;br /&gt;
* Expire old packets from the receive buffer after a timeout, or if the buffer is full&lt;br /&gt;
&lt;br /&gt;
== Dispatch Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Fragment datagrams need to be dispatched intelligently, to spread the load on&lt;br /&gt;
network resources and maximise the chance that the receiver will get the message.&lt;br /&gt;
To do this, the dispatch algorithm should take into account several points:&lt;br /&gt;
&lt;br /&gt;
* Prioritize acknowledgements.&lt;br /&gt;
* If fragments are waiting to be sent to a number of hosts, do not send to the same host twice in a row. Alternating, or looping through the target hosts achieves the same data rate locally, but spreads out the load over downstream links.&lt;br /&gt;
* Do not exceed or approach the capacity of the local network connection. If a host has a 128 kb/s outbound bandwidth, dispatching 32 KB of data in one second will likely cause massive packet loss, leading to a retransmission.&lt;br /&gt;
* After considering the above points, prefer fragments that were queued recently to older packets. A LIFO or stack type approach means that even if a transmitter is becoming backed up, some fragments will get there on time, while others will be delayed. A FIFO approach would mean that a backed up host delivers every fragment late.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
The recommended parameters for the reliability layer are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
MTU = 500 bytes&lt;br /&gt;
Transmit Retransmit Interval = 10 seconds&lt;br /&gt;
Transmit Packet Timeout / Expire = 26 seconds (allows for two retransmissions before expiry)&lt;br /&gt;
Receive Packet Expiry = 30 seconds (allows 10 seconds beyond final retransmission)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Performance Considerations ==&lt;br /&gt;
&lt;br /&gt;
Relatively low-level network implementations such as this are reasonably&lt;br /&gt;
complicated, but must operate fast. It is desirable to avoid runtime memory&lt;br /&gt;
allocations in network code as much as possible, and particularly at this level.&lt;br /&gt;
&lt;br /&gt;
It should be noted that in almost all cases, transmissions to &amp;quot;untested&amp;quot; nodes are&lt;br /&gt;
single fragment. Replies on the other hand are often larger, and may be deflated in&lt;br /&gt;
many fragments. This is optimal, because attempting to contact a node which may be&lt;br /&gt;
unavailable, involves a retransmission of only a single fragment.&lt;br /&gt;
&lt;br /&gt;
Flow control is an important topic, however, it is handled at a higher layer. The UDP&lt;br /&gt;
reliability layer is only responsible for guaranteeing delivery of selected datagrams.&lt;br /&gt;
&lt;br /&gt;
Only critical transmissions whose reception cannot otherwise be inferred, should have&lt;br /&gt;
the acknowledge request bit set.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=35</id>
		<title>UDP Transceiver</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=35"/>
		<updated>2005-03-27T16:41:24Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Dispatch Algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The User Datagram Protocol (UDP) is invaluable in peer to peer systems because it&lt;br /&gt;
provides a relatively low-cost (low-overhead) method of sending short, irregular&lt;br /&gt;
messages to a very large number of peers on demand. Establishing a TCP stream&lt;br /&gt;
connection to a peer simply to deliver a single packet of information is wasteful in&lt;br /&gt;
data volume and time for the peers involved and state-aware network devices along&lt;br /&gt;
the route, for example, network address translation facilities. When dealing with a&lt;br /&gt;
large number of peers quickly, these costs become unbearable. UDP provides a&lt;br /&gt;
solution and makes this kind of interaction possible.&lt;br /&gt;
&lt;br /&gt;
However, the delivery of UDP packets is not reliable: packets may be lost en-route for&lt;br /&gt;
a number of reasons. Often this behaviour is desirable, for example when the&lt;br /&gt;
destination node's connection is highly congested, UDP packets are likely to be&lt;br /&gt;
discarded. If the content was not critical, this loss is appropriate as the host's&lt;br /&gt;
resources are effectively unavailable. In other scenarios involving critical payloads,&lt;br /&gt;
UDP's lack of reliability is a problem: either the sender needs to make sure the&lt;br /&gt;
receiver gets the payload, or it needs to know definitively that the receiver was&lt;br /&gt;
unavailable.&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 network solves this problem by implementing a selectively engaged&lt;br /&gt;
reliability layer on top of the basic UDP protocol. This reliability layer shares some&lt;br /&gt;
common functionality with TCP, but importantly does not provide any connection&lt;br /&gt;
state and thus retains the efficiency originally sought in UDP.&lt;br /&gt;
&lt;br /&gt;
This allows Gnutella2 to select the most optimal communication medium for each&lt;br /&gt;
and every transmission it needs to perform:&lt;br /&gt;
&lt;br /&gt;
* If a significant volume of data is to be exchanged, or subsequent data will be exchanged with the same destination, a TCP connection is established&lt;br /&gt;
* If a small volume of important data is to be exchanged in a once-off operation or irregularly, reliable UDP is used&lt;br /&gt;
* If a small volume of unimportant data is to be exchanged in a once-off operation or irregularly, unreliable UDP is used&lt;br /&gt;
&lt;br /&gt;
== UDP ==&lt;br /&gt;
&lt;br /&gt;
Gnutella2 semi-reliable communication is transported using the UDP protocol. The&lt;br /&gt;
port number for receiving UDP is the same as the port number listening for TCP&lt;br /&gt;
connections.&lt;br /&gt;
&lt;br /&gt;
== Encoding ==&lt;br /&gt;
&lt;br /&gt;
Implementing an additional reliable protocol within UDP requires a small control&lt;br /&gt;
header before the payload itself. This header is put to good use:&lt;br /&gt;
&lt;br /&gt;
A small signature identifies the packet as a Gnutella2 semi-reliable UDP datagram.&lt;br /&gt;
This allows the same port to be used for receiving UDP traffic for other protocols if&lt;br /&gt;
desired, and offers some simple protection against random, unexpected traffic.&lt;br /&gt;
A content code identifies the payload as a Gnutella2 packet stream, allowing future&lt;br /&gt;
protocols to be added within the same reliability layer if desired. &lt;br /&gt;
Flags allow additional attributes to be specified, such as inline stateless compression&lt;br /&gt;
of the payload (which is a required feature).&lt;br /&gt;
The header has a fixed size of 8 bytes, and is represented by the following C&lt;br /&gt;
structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#pragma pack(1)&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
   CHAR szTag3;&lt;br /&gt;
   BYTE nFlags;&lt;br /&gt;
   WORD nSequence;&lt;br /&gt;
   BYTE nPart;&lt;br /&gt;
   BYTE nCount;&lt;br /&gt;
} GND_HEADER;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The members of the structure are detailed below:&lt;br /&gt;
&lt;br /&gt;
* '''szTag''' - contains a three byte encoding protocol identifier, in this case &amp;quot;GND&amp;quot; for &amp;quot;GNutella Datagram&amp;quot;. If this signature is not present the packet should not be decoded as a Gnutella2 reliability layer transmission.&lt;br /&gt;
* '''nFlags''' - contains flags which modify the content of the packet. The low-order nibble is reserved for critical flags: if one of these bits is set but the decoding software does not understand the meaning, the packet must be discarded. The high-order nibble is reserved for non-critical flags: when set these bits may be interpreted, but an inability to interpret a bit does not cause the packet to be discarded. Currently defined flags are:&lt;br /&gt;
:* '''0x01''' - Deflate&lt;br /&gt;
::  When the deflate bit is set, the entire payload is compressed with the deflate algorithm. The compression method used is the Deflate Compression Data Format (RFC 1951). On top of this compression a ZLIB ‘wrapper’ is applied (RFC 1950, ZLIB Compressed Data Format). The ZLIB wrapper ensures packet integrity, among other things. Note that the entire payload must be reassembled in the correct order before it can be deflated if the packet was fragmented. Fragments are not compressed separately!&lt;br /&gt;
:* '''0x02''' - Acknowledge Me&lt;br /&gt;
:: When the acknowledge me bit is set, the sender is expecting an acknowledgement for this packet.&lt;br /&gt;
&lt;br /&gt;
* '''nSequence''' - contains the sequence number of the packet. This sequence number is unique to the sending host only. It is not unique to the pair of the sending host and receiving host as in TCP, as there is no concept of connection state. Sequence numbers on consecutive packets need not be increasing (although that is convenient) â€“ they must only be different. If a packet is fragmented, all of its fragments will have the same sequence number. Byte order is unimportant here.&lt;br /&gt;
* '''nPart''' - contains the fragment part number (1 &amp;lt;= nPart &amp;lt;= nCount)&lt;br /&gt;
* '''nCount''' - contains the number of fragment parts in this packet. On a transmission, this value will be non-zero (all packets must have at least one fragment). If nCount is zero, this is an acknowledgement (see below).&lt;br /&gt;
&lt;br /&gt;
== Fragmentation ==&lt;br /&gt;
&lt;br /&gt;
Large packets must be fragmented before they can be sent through most network&lt;br /&gt;
interfaces. Different network media have different MTUs, and it is difficult to predict&lt;br /&gt;
what the lowest common size will be. Fragmentation and reassembly is performed by&lt;br /&gt;
the existing Internet protocols, however, there are two important reasons why the&lt;br /&gt;
reliability layer performs its own fragmentation:&lt;br /&gt;
&lt;br /&gt;
* Sockets implementations specify a maximum datagram size. This is adequate for the vast majority of transmissions, but it is desirable to have the transparent ability to send larger packets without worrying about the host implementation.&lt;br /&gt;
* When the Internet protocols fragment, a packet and one or more fragments are lost, it may decide to discard the whole packet in an unreliable datagram protocol. The Gnutella2 reliability layer can compensate by retransmitting the whole packet, which would then be re-fragmented and each fragment resent - however, this wastes the fragments that were successfully received before. Managing fragmentation natively allows this optimisation.&lt;br /&gt;
&lt;br /&gt;
Each node determines its own MTU, often based on a best guess combined with&lt;br /&gt;
information from the host's sockets implementation. Packets exceeding this size are&lt;br /&gt;
fragmented into multiple datagrams of the appropriate size. Each datagram has the&lt;br /&gt;
same sequence number and the same fragment count (nCount), but a different&lt;br /&gt;
fragment number (nPart).&lt;br /&gt;
&lt;br /&gt;
== Transmission Process ==&lt;br /&gt;
&lt;br /&gt;
When a packet is to be transmitted, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* Cache the payload&lt;br /&gt;
* Allocate a new locally and temporally unique sequence number&lt;br /&gt;
* Derive the appropriate number of fragments&lt;br /&gt;
* Queue the fragments for dispatch&lt;br /&gt;
* If the fragments do not need to be acknowledged, the packet can be flushed now&lt;br /&gt;
&lt;br /&gt;
The payload will generally be cached for an appropriate timeout period, or until the&lt;br /&gt;
data cache becomes full, at which time older payloads can be discarded. Fragments&lt;br /&gt;
are dispatched according to the dispatch algorithm of choice, and the sender listens&lt;br /&gt;
for acknowledgements. When an acknowledgement is received:&lt;br /&gt;
&lt;br /&gt;
* Lookup the sent packet by sequence number&lt;br /&gt;
* Mark the nPart fragment as received and cancel any retransmissions of this part&lt;br /&gt;
* If all fragments have been acknowledged, flush this packet from the cache&lt;br /&gt;
&lt;br /&gt;
If a fragment has been transmitted but has not been acknowledged within the&lt;br /&gt;
timeout, it should be retransmitted. A finite number of retransmissions are allowed&lt;br /&gt;
before the packet as a whole expires, at which time it is assumed that the packet&lt;br /&gt;
was not received.&lt;br /&gt;
&lt;br /&gt;
== Receive Process ==&lt;br /&gt;
&lt;br /&gt;
When a new datagram is received, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* If the acknowledge bit was set, send an acknowledge packet for this sequence number and part number, with nCount set to zero (ack)&lt;br /&gt;
* Lookup any existing packet by the sending IP and sequence number &lt;br /&gt;
* If there is no existing packet, create a new packet entry with the IP, sequence number, fragment count and flags&lt;br /&gt;
* If there was an existing packet, make sure it is not marked as done - if so, abort&lt;br /&gt;
* Add the transmitted fragment to the (new or old) packet entry&lt;br /&gt;
* If the packet now has all fragments, mark it as done and decode it and pass it up to the application layer&lt;br /&gt;
* Leave the packet on the cache even if it was finished, in case any parts are retransmitted&lt;br /&gt;
* Expire old packets from the receive buffer after a timeout, or if the buffer is full&lt;br /&gt;
&lt;br /&gt;
== Dispatch Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Fragment datagrams need to be dispatched intelligently, to spread the load on&lt;br /&gt;
network resources and maximise the chance that the receiver will get the message.&lt;br /&gt;
To do this, the dispatch algorithm should take into account several points:&lt;br /&gt;
&lt;br /&gt;
* Prioritize acknowledgements.&lt;br /&gt;
* If fragments are waiting to be sent to a number of hosts, do not send to the same host twice in a row. Alternating, or looping through the target hosts achieves the same data rate locally, but spreads out the load over downstream links.&lt;br /&gt;
* Do not exceed or approach the capacity of the local network connection. If a host has a 128 kb/s outbound bandwidth, dispatching 32 KB of data in one second will likely cause massive packet loss, leading to a retransmission.&lt;br /&gt;
* After considering the above points, prefer fragments that were queued recently to older packets. A LIFO or stack type approach means that even if a transmitter is becoming backed up, some fragments will get there on time, while others will be delayed. A FIFO approach would mean that a backed up host delivers every fragment late.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
The recommended parameters for the reliability layer are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
MTU = 500 bytes&lt;br /&gt;
Transmit Retransmit Interval = 10 seconds&lt;br /&gt;
Transmit Packet Timeout / Expire = 26 seconds (allows for two retransmissions before expiry)&lt;br /&gt;
Receive Packet Expiry = 30 seconds (allows 10 seconds beyond final retransmission)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Performance Considerations ==&lt;br /&gt;
&lt;br /&gt;
Relatively low-level network implementations such as this are reasonably&lt;br /&gt;
complicated, but must operate fast. It is desirable to avoid runtime memory&lt;br /&gt;
allocations in network code as much as possible, and particularly at this level.&lt;br /&gt;
&lt;br /&gt;
It should be noted that in almost all cases, transmissions to &amp;quot;untested&amp;quot; nodes are&lt;br /&gt;
single fragment. Replies on the other hand are often larger, and may be deflated in&lt;br /&gt;
many fragments. This is optimal because attempting to contact a node which may be&lt;br /&gt;
unavailable involves a retransmission of only a single fragment.&lt;br /&gt;
&lt;br /&gt;
Flow control is an important topic, however it is handled at a higher layer. The UDP&lt;br /&gt;
reliability layer is only responsible for guaranteeing delivery of selected datagrams.&lt;br /&gt;
&lt;br /&gt;
Only critical transmissions whose reception cannot otherwise be inferred should have&lt;br /&gt;
the acknowledge request bit set.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=34</id>
		<title>UDP Transceiver</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=34"/>
		<updated>2005-03-27T16:39:14Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Receive Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The User Datagram Protocol (UDP) is invaluable in peer to peer systems because it&lt;br /&gt;
provides a relatively low-cost (low-overhead) method of sending short, irregular&lt;br /&gt;
messages to a very large number of peers on demand. Establishing a TCP stream&lt;br /&gt;
connection to a peer simply to deliver a single packet of information is wasteful in&lt;br /&gt;
data volume and time for the peers involved and state-aware network devices along&lt;br /&gt;
the route, for example, network address translation facilities. When dealing with a&lt;br /&gt;
large number of peers quickly, these costs become unbearable. UDP provides a&lt;br /&gt;
solution and makes this kind of interaction possible.&lt;br /&gt;
&lt;br /&gt;
However, the delivery of UDP packets is not reliable: packets may be lost en-route for&lt;br /&gt;
a number of reasons. Often this behaviour is desirable, for example when the&lt;br /&gt;
destination node's connection is highly congested, UDP packets are likely to be&lt;br /&gt;
discarded. If the content was not critical, this loss is appropriate as the host's&lt;br /&gt;
resources are effectively unavailable. In other scenarios involving critical payloads,&lt;br /&gt;
UDP's lack of reliability is a problem: either the sender needs to make sure the&lt;br /&gt;
receiver gets the payload, or it needs to know definitively that the receiver was&lt;br /&gt;
unavailable.&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 network solves this problem by implementing a selectively engaged&lt;br /&gt;
reliability layer on top of the basic UDP protocol. This reliability layer shares some&lt;br /&gt;
common functionality with TCP, but importantly does not provide any connection&lt;br /&gt;
state and thus retains the efficiency originally sought in UDP.&lt;br /&gt;
&lt;br /&gt;
This allows Gnutella2 to select the most optimal communication medium for each&lt;br /&gt;
and every transmission it needs to perform:&lt;br /&gt;
&lt;br /&gt;
* If a significant volume of data is to be exchanged, or subsequent data will be exchanged with the same destination, a TCP connection is established&lt;br /&gt;
* If a small volume of important data is to be exchanged in a once-off operation or irregularly, reliable UDP is used&lt;br /&gt;
* If a small volume of unimportant data is to be exchanged in a once-off operation or irregularly, unreliable UDP is used&lt;br /&gt;
&lt;br /&gt;
== UDP ==&lt;br /&gt;
&lt;br /&gt;
Gnutella2 semi-reliable communication is transported using the UDP protocol. The&lt;br /&gt;
port number for receiving UDP is the same as the port number listening for TCP&lt;br /&gt;
connections.&lt;br /&gt;
&lt;br /&gt;
== Encoding ==&lt;br /&gt;
&lt;br /&gt;
Implementing an additional reliable protocol within UDP requires a small control&lt;br /&gt;
header before the payload itself. This header is put to good use:&lt;br /&gt;
&lt;br /&gt;
A small signature identifies the packet as a Gnutella2 semi-reliable UDP datagram.&lt;br /&gt;
This allows the same port to be used for receiving UDP traffic for other protocols if&lt;br /&gt;
desired, and offers some simple protection against random, unexpected traffic.&lt;br /&gt;
A content code identifies the payload as a Gnutella2 packet stream, allowing future&lt;br /&gt;
protocols to be added within the same reliability layer if desired. &lt;br /&gt;
Flags allow additional attributes to be specified, such as inline stateless compression&lt;br /&gt;
of the payload (which is a required feature).&lt;br /&gt;
The header has a fixed size of 8 bytes, and is represented by the following C&lt;br /&gt;
structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#pragma pack(1)&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
   CHAR szTag3;&lt;br /&gt;
   BYTE nFlags;&lt;br /&gt;
   WORD nSequence;&lt;br /&gt;
   BYTE nPart;&lt;br /&gt;
   BYTE nCount;&lt;br /&gt;
} GND_HEADER;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The members of the structure are detailed below:&lt;br /&gt;
&lt;br /&gt;
* '''szTag''' - contains a three byte encoding protocol identifier, in this case &amp;quot;GND&amp;quot; for &amp;quot;GNutella Datagram&amp;quot;. If this signature is not present the packet should not be decoded as a Gnutella2 reliability layer transmission.&lt;br /&gt;
* '''nFlags''' - contains flags which modify the content of the packet. The low-order nibble is reserved for critical flags: if one of these bits is set but the decoding software does not understand the meaning, the packet must be discarded. The high-order nibble is reserved for non-critical flags: when set these bits may be interpreted, but an inability to interpret a bit does not cause the packet to be discarded. Currently defined flags are:&lt;br /&gt;
:* '''0x01''' - Deflate&lt;br /&gt;
::  When the deflate bit is set, the entire payload is compressed with the deflate algorithm. The compression method used is the Deflate Compression Data Format (RFC 1951). On top of this compression a ZLIB ‘wrapper’ is applied (RFC 1950, ZLIB Compressed Data Format). The ZLIB wrapper ensures packet integrity, among other things. Note that the entire payload must be reassembled in the correct order before it can be deflated if the packet was fragmented. Fragments are not compressed separately!&lt;br /&gt;
:* '''0x02''' - Acknowledge Me&lt;br /&gt;
:: When the acknowledge me bit is set, the sender is expecting an acknowledgement for this packet.&lt;br /&gt;
&lt;br /&gt;
* '''nSequence''' - contains the sequence number of the packet. This sequence number is unique to the sending host only. It is not unique to the pair of the sending host and receiving host as in TCP, as there is no concept of connection state. Sequence numbers on consecutive packets need not be increasing (although that is convenient) â€“ they must only be different. If a packet is fragmented, all of its fragments will have the same sequence number. Byte order is unimportant here.&lt;br /&gt;
* '''nPart''' - contains the fragment part number (1 &amp;lt;= nPart &amp;lt;= nCount)&lt;br /&gt;
* '''nCount''' - contains the number of fragment parts in this packet. On a transmission, this value will be non-zero (all packets must have at least one fragment). If nCount is zero, this is an acknowledgement (see below).&lt;br /&gt;
&lt;br /&gt;
== Fragmentation ==&lt;br /&gt;
&lt;br /&gt;
Large packets must be fragmented before they can be sent through most network&lt;br /&gt;
interfaces. Different network media have different MTUs, and it is difficult to predict&lt;br /&gt;
what the lowest common size will be. Fragmentation and reassembly is performed by&lt;br /&gt;
the existing Internet protocols, however, there are two important reasons why the&lt;br /&gt;
reliability layer performs its own fragmentation:&lt;br /&gt;
&lt;br /&gt;
* Sockets implementations specify a maximum datagram size. This is adequate for the vast majority of transmissions, but it is desirable to have the transparent ability to send larger packets without worrying about the host implementation.&lt;br /&gt;
* When the Internet protocols fragment, a packet and one or more fragments are lost, it may decide to discard the whole packet in an unreliable datagram protocol. The Gnutella2 reliability layer can compensate by retransmitting the whole packet, which would then be re-fragmented and each fragment resent - however, this wastes the fragments that were successfully received before. Managing fragmentation natively allows this optimisation.&lt;br /&gt;
&lt;br /&gt;
Each node determines its own MTU, often based on a best guess combined with&lt;br /&gt;
information from the host's sockets implementation. Packets exceeding this size are&lt;br /&gt;
fragmented into multiple datagrams of the appropriate size. Each datagram has the&lt;br /&gt;
same sequence number and the same fragment count (nCount), but a different&lt;br /&gt;
fragment number (nPart).&lt;br /&gt;
&lt;br /&gt;
== Transmission Process ==&lt;br /&gt;
&lt;br /&gt;
When a packet is to be transmitted, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* Cache the payload&lt;br /&gt;
* Allocate a new locally and temporally unique sequence number&lt;br /&gt;
* Derive the appropriate number of fragments&lt;br /&gt;
* Queue the fragments for dispatch&lt;br /&gt;
* If the fragments do not need to be acknowledged, the packet can be flushed now&lt;br /&gt;
&lt;br /&gt;
The payload will generally be cached for an appropriate timeout period, or until the&lt;br /&gt;
data cache becomes full, at which time older payloads can be discarded. Fragments&lt;br /&gt;
are dispatched according to the dispatch algorithm of choice, and the sender listens&lt;br /&gt;
for acknowledgements. When an acknowledgement is received:&lt;br /&gt;
&lt;br /&gt;
* Lookup the sent packet by sequence number&lt;br /&gt;
* Mark the nPart fragment as received and cancel any retransmissions of this part&lt;br /&gt;
* If all fragments have been acknowledged, flush this packet from the cache&lt;br /&gt;
&lt;br /&gt;
If a fragment has been transmitted but has not been acknowledged within the&lt;br /&gt;
timeout, it should be retransmitted. A finite number of retransmissions are allowed&lt;br /&gt;
before the packet as a whole expires, at which time it is assumed that the packet&lt;br /&gt;
was not received.&lt;br /&gt;
&lt;br /&gt;
== Receive Process ==&lt;br /&gt;
&lt;br /&gt;
When a new datagram is received, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* If the acknowledge bit was set, send an acknowledge packet for this sequence number and part number, with nCount set to zero (ack)&lt;br /&gt;
* Lookup any existing packet by the sending IP and sequence number &lt;br /&gt;
* If there is no existing packet, create a new packet entry with the IP, sequence number, fragment count and flags&lt;br /&gt;
* If there was an existing packet, make sure it is not marked as done - if so, abort&lt;br /&gt;
* Add the transmitted fragment to the (new or old) packet entry&lt;br /&gt;
* If the packet now has all fragments, mark it as done and decode it and pass it up to the application layer&lt;br /&gt;
* Leave the packet on the cache even if it was finished, in case any parts are retransmitted&lt;br /&gt;
* Expire old packets from the receive buffer after a timeout, or if the buffer is full&lt;br /&gt;
&lt;br /&gt;
== Dispatch Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Fragment datagrams need to be dispatched intelligently to spread the load on&lt;br /&gt;
network resources and maximise the chance that the receiver will get the message.&lt;br /&gt;
To do this, the dispatch algorithm should take into account several points:&lt;br /&gt;
&lt;br /&gt;
* Prioritize acknowledgements.&lt;br /&gt;
* If fragments are waiting to be sent to a number of hosts, do not send to the same host twice in a row. Alternating or looping through the target hosts achieves the same data rate locally, but spreads out the load over downstream links.&lt;br /&gt;
* Do not exceed or approach the capacity of the local network connection. If a host has a 128 kb/s outbound bandwidth, dispatching 32 KB of data in one second will likely cause massive packet loss, leading to a retransmission.&lt;br /&gt;
* After considering the above points, prefer fragments that were queued recently to older packets. A LIFO or stack type approach means that even if a transmitter is becoming backed up, some fragments will get there on time while others will be delayed. A FIFO approach would mean that a backed up host delivers every fragment late.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
The recommended parameters for the reliability layer are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
MTU = 500 bytes&lt;br /&gt;
Transmit Retransmit Interval = 10 seconds&lt;br /&gt;
Transmit Packet Timeout / Expire = 26 seconds (allows for two retransmissions before expiry)&lt;br /&gt;
Receive Packet Expiry = 30 seconds (allows 10 seconds beyond final retransmission)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Performance Considerations ==&lt;br /&gt;
&lt;br /&gt;
Relatively low-level network implementations such as this are reasonably&lt;br /&gt;
complicated, but must operate fast. It is desirable to avoid runtime memory&lt;br /&gt;
allocations in network code as much as possible, and particularly at this level.&lt;br /&gt;
&lt;br /&gt;
It should be noted that in almost all cases, transmissions to &amp;quot;untested&amp;quot; nodes are&lt;br /&gt;
single fragment. Replies on the other hand are often larger, and may be deflated in&lt;br /&gt;
many fragments. This is optimal because attempting to contact a node which may be&lt;br /&gt;
unavailable involves a retransmission of only a single fragment.&lt;br /&gt;
&lt;br /&gt;
Flow control is an important topic, however it is handled at a higher layer. The UDP&lt;br /&gt;
reliability layer is only responsible for guaranteeing delivery of selected datagrams.&lt;br /&gt;
&lt;br /&gt;
Only critical transmissions whose reception cannot otherwise be inferred should have&lt;br /&gt;
the acknowledge request bit set.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=33</id>
		<title>UDP Transceiver</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=33"/>
		<updated>2005-03-27T16:07:37Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Transmission Process */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The User Datagram Protocol (UDP) is invaluable in peer to peer systems because it&lt;br /&gt;
provides a relatively low-cost (low-overhead) method of sending short, irregular&lt;br /&gt;
messages to a very large number of peers on demand. Establishing a TCP stream&lt;br /&gt;
connection to a peer simply to deliver a single packet of information is wasteful in&lt;br /&gt;
data volume and time for the peers involved and state-aware network devices along&lt;br /&gt;
the route, for example, network address translation facilities. When dealing with a&lt;br /&gt;
large number of peers quickly, these costs become unbearable. UDP provides a&lt;br /&gt;
solution and makes this kind of interaction possible.&lt;br /&gt;
&lt;br /&gt;
However, the delivery of UDP packets is not reliable: packets may be lost en-route for&lt;br /&gt;
a number of reasons. Often this behaviour is desirable, for example when the&lt;br /&gt;
destination node's connection is highly congested, UDP packets are likely to be&lt;br /&gt;
discarded. If the content was not critical, this loss is appropriate as the host's&lt;br /&gt;
resources are effectively unavailable. In other scenarios involving critical payloads,&lt;br /&gt;
UDP's lack of reliability is a problem: either the sender needs to make sure the&lt;br /&gt;
receiver gets the payload, or it needs to know definitively that the receiver was&lt;br /&gt;
unavailable.&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 network solves this problem by implementing a selectively engaged&lt;br /&gt;
reliability layer on top of the basic UDP protocol. This reliability layer shares some&lt;br /&gt;
common functionality with TCP, but importantly does not provide any connection&lt;br /&gt;
state and thus retains the efficiency originally sought in UDP.&lt;br /&gt;
&lt;br /&gt;
This allows Gnutella2 to select the most optimal communication medium for each&lt;br /&gt;
and every transmission it needs to perform:&lt;br /&gt;
&lt;br /&gt;
* If a significant volume of data is to be exchanged, or subsequent data will be exchanged with the same destination, a TCP connection is established&lt;br /&gt;
* If a small volume of important data is to be exchanged in a once-off operation or irregularly, reliable UDP is used&lt;br /&gt;
* If a small volume of unimportant data is to be exchanged in a once-off operation or irregularly, unreliable UDP is used&lt;br /&gt;
&lt;br /&gt;
== UDP ==&lt;br /&gt;
&lt;br /&gt;
Gnutella2 semi-reliable communication is transported using the UDP protocol. The&lt;br /&gt;
port number for receiving UDP is the same as the port number listening for TCP&lt;br /&gt;
connections.&lt;br /&gt;
&lt;br /&gt;
== Encoding ==&lt;br /&gt;
&lt;br /&gt;
Implementing an additional reliable protocol within UDP requires a small control&lt;br /&gt;
header before the payload itself. This header is put to good use:&lt;br /&gt;
&lt;br /&gt;
A small signature identifies the packet as a Gnutella2 semi-reliable UDP datagram.&lt;br /&gt;
This allows the same port to be used for receiving UDP traffic for other protocols if&lt;br /&gt;
desired, and offers some simple protection against random, unexpected traffic.&lt;br /&gt;
A content code identifies the payload as a Gnutella2 packet stream, allowing future&lt;br /&gt;
protocols to be added within the same reliability layer if desired. &lt;br /&gt;
Flags allow additional attributes to be specified, such as inline stateless compression&lt;br /&gt;
of the payload (which is a required feature).&lt;br /&gt;
The header has a fixed size of 8 bytes, and is represented by the following C&lt;br /&gt;
structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#pragma pack(1)&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
   CHAR szTag3;&lt;br /&gt;
   BYTE nFlags;&lt;br /&gt;
   WORD nSequence;&lt;br /&gt;
   BYTE nPart;&lt;br /&gt;
   BYTE nCount;&lt;br /&gt;
} GND_HEADER;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The members of the structure are detailed below:&lt;br /&gt;
&lt;br /&gt;
* '''szTag''' - contains a three byte encoding protocol identifier, in this case &amp;quot;GND&amp;quot; for &amp;quot;GNutella Datagram&amp;quot;. If this signature is not present the packet should not be decoded as a Gnutella2 reliability layer transmission.&lt;br /&gt;
* '''nFlags''' - contains flags which modify the content of the packet. The low-order nibble is reserved for critical flags: if one of these bits is set but the decoding software does not understand the meaning, the packet must be discarded. The high-order nibble is reserved for non-critical flags: when set these bits may be interpreted, but an inability to interpret a bit does not cause the packet to be discarded. Currently defined flags are:&lt;br /&gt;
:* '''0x01''' - Deflate&lt;br /&gt;
::  When the deflate bit is set, the entire payload is compressed with the deflate algorithm. The compression method used is the Deflate Compression Data Format (RFC 1951). On top of this compression a ZLIB ‘wrapper’ is applied (RFC 1950, ZLIB Compressed Data Format). The ZLIB wrapper ensures packet integrity, among other things. Note that the entire payload must be reassembled in the correct order before it can be deflated if the packet was fragmented. Fragments are not compressed separately!&lt;br /&gt;
:* '''0x02''' - Acknowledge Me&lt;br /&gt;
:: When the acknowledge me bit is set, the sender is expecting an acknowledgement for this packet.&lt;br /&gt;
&lt;br /&gt;
* '''nSequence''' - contains the sequence number of the packet. This sequence number is unique to the sending host only. It is not unique to the pair of the sending host and receiving host as in TCP, as there is no concept of connection state. Sequence numbers on consecutive packets need not be increasing (although that is convenient) â€“ they must only be different. If a packet is fragmented, all of its fragments will have the same sequence number. Byte order is unimportant here.&lt;br /&gt;
* '''nPart''' - contains the fragment part number (1 &amp;lt;= nPart &amp;lt;= nCount)&lt;br /&gt;
* '''nCount''' - contains the number of fragment parts in this packet. On a transmission, this value will be non-zero (all packets must have at least one fragment). If nCount is zero, this is an acknowledgement (see below).&lt;br /&gt;
&lt;br /&gt;
== Fragmentation ==&lt;br /&gt;
&lt;br /&gt;
Large packets must be fragmented before they can be sent through most network&lt;br /&gt;
interfaces. Different network media have different MTUs, and it is difficult to predict&lt;br /&gt;
what the lowest common size will be. Fragmentation and reassembly is performed by&lt;br /&gt;
the existing Internet protocols, however, there are two important reasons why the&lt;br /&gt;
reliability layer performs its own fragmentation:&lt;br /&gt;
&lt;br /&gt;
* Sockets implementations specify a maximum datagram size. This is adequate for the vast majority of transmissions, but it is desirable to have the transparent ability to send larger packets without worrying about the host implementation.&lt;br /&gt;
* When the Internet protocols fragment, a packet and one or more fragments are lost, it may decide to discard the whole packet in an unreliable datagram protocol. The Gnutella2 reliability layer can compensate by retransmitting the whole packet, which would then be re-fragmented and each fragment resent - however, this wastes the fragments that were successfully received before. Managing fragmentation natively allows this optimisation.&lt;br /&gt;
&lt;br /&gt;
Each node determines its own MTU, often based on a best guess combined with&lt;br /&gt;
information from the host's sockets implementation. Packets exceeding this size are&lt;br /&gt;
fragmented into multiple datagrams of the appropriate size. Each datagram has the&lt;br /&gt;
same sequence number and the same fragment count (nCount), but a different&lt;br /&gt;
fragment number (nPart).&lt;br /&gt;
&lt;br /&gt;
== Transmission Process ==&lt;br /&gt;
&lt;br /&gt;
When a packet is to be transmitted, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* Cache the payload&lt;br /&gt;
* Allocate a new locally and temporally unique sequence number&lt;br /&gt;
* Derive the appropriate number of fragments&lt;br /&gt;
* Queue the fragments for dispatch&lt;br /&gt;
* If the fragments do not need to be acknowledged, the packet can be flushed now&lt;br /&gt;
&lt;br /&gt;
The payload will generally be cached for an appropriate timeout period, or until the&lt;br /&gt;
data cache becomes full, at which time older payloads can be discarded. Fragments&lt;br /&gt;
are dispatched according to the dispatch algorithm of choice, and the sender listens&lt;br /&gt;
for acknowledgements. When an acknowledgement is received:&lt;br /&gt;
&lt;br /&gt;
* Lookup the sent packet by sequence number&lt;br /&gt;
* Mark the nPart fragment as received and cancel any retransmissions of this part&lt;br /&gt;
* If all fragments have been acknowledged, flush this packet from the cache&lt;br /&gt;
&lt;br /&gt;
If a fragment has been transmitted but has not been acknowledged within the&lt;br /&gt;
timeout, it should be retransmitted. A finite number of retransmissions are allowed&lt;br /&gt;
before the packet as a whole expires, at which time it is assumed that the packet&lt;br /&gt;
was not received.&lt;br /&gt;
&lt;br /&gt;
== Receive Process ==&lt;br /&gt;
&lt;br /&gt;
When a new datagram is received, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* If the acknowledge bit was set, send an acknowledge packet for this sequence number and part number, with nCount set to zero (ack)&lt;br /&gt;
* Lookup any existing packet by the sending IP and sequence number &lt;br /&gt;
* If there is no existing packet, create a new packet entry with the IP, sequence number, fragment count and flags&lt;br /&gt;
* If there was an existing packet, make sure it is not marked as done - if so, abort&lt;br /&gt;
* Add the transmitted fragment to the (new or old) packet entry&lt;br /&gt;
* If the packet now has all fragments, mark it as done and decode it and pass it up to the application layer&lt;br /&gt;
* Leave the packet on the cache even if it was finished, in case any parts are retransmitted&lt;br /&gt;
* Expire old packets from the receive buffer after a timeout or if the buffer is full&lt;br /&gt;
&lt;br /&gt;
== Dispatch Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Fragment datagrams need to be dispatched intelligently to spread the load on&lt;br /&gt;
network resources and maximise the chance that the receiver will get the message.&lt;br /&gt;
To do this, the dispatch algorithm should take into account several points:&lt;br /&gt;
&lt;br /&gt;
* Prioritize acknowledgements.&lt;br /&gt;
* If fragments are waiting to be sent to a number of hosts, do not send to the same host twice in a row. Alternating or looping through the target hosts achieves the same data rate locally, but spreads out the load over downstream links.&lt;br /&gt;
* Do not exceed or approach the capacity of the local network connection. If a host has a 128 kb/s outbound bandwidth, dispatching 32 KB of data in one second will likely cause massive packet loss, leading to a retransmission.&lt;br /&gt;
* After considering the above points, prefer fragments that were queued recently to older packets. A LIFO or stack type approach means that even if a transmitter is becoming backed up, some fragments will get there on time while others will be delayed. A FIFO approach would mean that a backed up host delivers every fragment late.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
The recommended parameters for the reliability layer are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
MTU = 500 bytes&lt;br /&gt;
Transmit Retransmit Interval = 10 seconds&lt;br /&gt;
Transmit Packet Timeout / Expire = 26 seconds (allows for two retransmissions before expiry)&lt;br /&gt;
Receive Packet Expiry = 30 seconds (allows 10 seconds beyond final retransmission)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Performance Considerations ==&lt;br /&gt;
&lt;br /&gt;
Relatively low-level network implementations such as this are reasonably&lt;br /&gt;
complicated, but must operate fast. It is desirable to avoid runtime memory&lt;br /&gt;
allocations in network code as much as possible, and particularly at this level.&lt;br /&gt;
&lt;br /&gt;
It should be noted that in almost all cases, transmissions to &amp;quot;untested&amp;quot; nodes are&lt;br /&gt;
single fragment. Replies on the other hand are often larger, and may be deflated in&lt;br /&gt;
many fragments. This is optimal because attempting to contact a node which may be&lt;br /&gt;
unavailable involves a retransmission of only a single fragment.&lt;br /&gt;
&lt;br /&gt;
Flow control is an important topic, however it is handled at a higher layer. The UDP&lt;br /&gt;
reliability layer is only responsible for guaranteeing delivery of selected datagrams.&lt;br /&gt;
&lt;br /&gt;
Only critical transmissions whose reception cannot otherwise be inferred should have&lt;br /&gt;
the acknowledge request bit set.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=32</id>
		<title>UDP Transceiver</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=32"/>
		<updated>2005-03-27T16:05:50Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Fragmentation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The User Datagram Protocol (UDP) is invaluable in peer to peer systems because it&lt;br /&gt;
provides a relatively low-cost (low-overhead) method of sending short, irregular&lt;br /&gt;
messages to a very large number of peers on demand. Establishing a TCP stream&lt;br /&gt;
connection to a peer simply to deliver a single packet of information is wasteful in&lt;br /&gt;
data volume and time for the peers involved and state-aware network devices along&lt;br /&gt;
the route, for example, network address translation facilities. When dealing with a&lt;br /&gt;
large number of peers quickly, these costs become unbearable. UDP provides a&lt;br /&gt;
solution and makes this kind of interaction possible.&lt;br /&gt;
&lt;br /&gt;
However, the delivery of UDP packets is not reliable: packets may be lost en-route for&lt;br /&gt;
a number of reasons. Often this behaviour is desirable, for example when the&lt;br /&gt;
destination node's connection is highly congested, UDP packets are likely to be&lt;br /&gt;
discarded. If the content was not critical, this loss is appropriate as the host's&lt;br /&gt;
resources are effectively unavailable. In other scenarios involving critical payloads,&lt;br /&gt;
UDP's lack of reliability is a problem: either the sender needs to make sure the&lt;br /&gt;
receiver gets the payload, or it needs to know definitively that the receiver was&lt;br /&gt;
unavailable.&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 network solves this problem by implementing a selectively engaged&lt;br /&gt;
reliability layer on top of the basic UDP protocol. This reliability layer shares some&lt;br /&gt;
common functionality with TCP, but importantly does not provide any connection&lt;br /&gt;
state and thus retains the efficiency originally sought in UDP.&lt;br /&gt;
&lt;br /&gt;
This allows Gnutella2 to select the most optimal communication medium for each&lt;br /&gt;
and every transmission it needs to perform:&lt;br /&gt;
&lt;br /&gt;
* If a significant volume of data is to be exchanged, or subsequent data will be exchanged with the same destination, a TCP connection is established&lt;br /&gt;
* If a small volume of important data is to be exchanged in a once-off operation or irregularly, reliable UDP is used&lt;br /&gt;
* If a small volume of unimportant data is to be exchanged in a once-off operation or irregularly, unreliable UDP is used&lt;br /&gt;
&lt;br /&gt;
== UDP ==&lt;br /&gt;
&lt;br /&gt;
Gnutella2 semi-reliable communication is transported using the UDP protocol. The&lt;br /&gt;
port number for receiving UDP is the same as the port number listening for TCP&lt;br /&gt;
connections.&lt;br /&gt;
&lt;br /&gt;
== Encoding ==&lt;br /&gt;
&lt;br /&gt;
Implementing an additional reliable protocol within UDP requires a small control&lt;br /&gt;
header before the payload itself. This header is put to good use:&lt;br /&gt;
&lt;br /&gt;
A small signature identifies the packet as a Gnutella2 semi-reliable UDP datagram.&lt;br /&gt;
This allows the same port to be used for receiving UDP traffic for other protocols if&lt;br /&gt;
desired, and offers some simple protection against random, unexpected traffic.&lt;br /&gt;
A content code identifies the payload as a Gnutella2 packet stream, allowing future&lt;br /&gt;
protocols to be added within the same reliability layer if desired. &lt;br /&gt;
Flags allow additional attributes to be specified, such as inline stateless compression&lt;br /&gt;
of the payload (which is a required feature).&lt;br /&gt;
The header has a fixed size of 8 bytes, and is represented by the following C&lt;br /&gt;
structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#pragma pack(1)&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
   CHAR szTag3;&lt;br /&gt;
   BYTE nFlags;&lt;br /&gt;
   WORD nSequence;&lt;br /&gt;
   BYTE nPart;&lt;br /&gt;
   BYTE nCount;&lt;br /&gt;
} GND_HEADER;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The members of the structure are detailed below:&lt;br /&gt;
&lt;br /&gt;
* '''szTag''' - contains a three byte encoding protocol identifier, in this case &amp;quot;GND&amp;quot; for &amp;quot;GNutella Datagram&amp;quot;. If this signature is not present the packet should not be decoded as a Gnutella2 reliability layer transmission.&lt;br /&gt;
* '''nFlags''' - contains flags which modify the content of the packet. The low-order nibble is reserved for critical flags: if one of these bits is set but the decoding software does not understand the meaning, the packet must be discarded. The high-order nibble is reserved for non-critical flags: when set these bits may be interpreted, but an inability to interpret a bit does not cause the packet to be discarded. Currently defined flags are:&lt;br /&gt;
:* '''0x01''' - Deflate&lt;br /&gt;
::  When the deflate bit is set, the entire payload is compressed with the deflate algorithm. The compression method used is the Deflate Compression Data Format (RFC 1951). On top of this compression a ZLIB ‘wrapper’ is applied (RFC 1950, ZLIB Compressed Data Format). The ZLIB wrapper ensures packet integrity, among other things. Note that the entire payload must be reassembled in the correct order before it can be deflated if the packet was fragmented. Fragments are not compressed separately!&lt;br /&gt;
:* '''0x02''' - Acknowledge Me&lt;br /&gt;
:: When the acknowledge me bit is set, the sender is expecting an acknowledgement for this packet.&lt;br /&gt;
&lt;br /&gt;
* '''nSequence''' - contains the sequence number of the packet. This sequence number is unique to the sending host only. It is not unique to the pair of the sending host and receiving host as in TCP, as there is no concept of connection state. Sequence numbers on consecutive packets need not be increasing (although that is convenient) â€“ they must only be different. If a packet is fragmented, all of its fragments will have the same sequence number. Byte order is unimportant here.&lt;br /&gt;
* '''nPart''' - contains the fragment part number (1 &amp;lt;= nPart &amp;lt;= nCount)&lt;br /&gt;
* '''nCount''' - contains the number of fragment parts in this packet. On a transmission, this value will be non-zero (all packets must have at least one fragment). If nCount is zero, this is an acknowledgement (see below).&lt;br /&gt;
&lt;br /&gt;
== Fragmentation ==&lt;br /&gt;
&lt;br /&gt;
Large packets must be fragmented before they can be sent through most network&lt;br /&gt;
interfaces. Different network media have different MTUs, and it is difficult to predict&lt;br /&gt;
what the lowest common size will be. Fragmentation and reassembly is performed by&lt;br /&gt;
the existing Internet protocols, however, there are two important reasons why the&lt;br /&gt;
reliability layer performs its own fragmentation:&lt;br /&gt;
&lt;br /&gt;
* Sockets implementations specify a maximum datagram size. This is adequate for the vast majority of transmissions, but it is desirable to have the transparent ability to send larger packets without worrying about the host implementation.&lt;br /&gt;
* When the Internet protocols fragment, a packet and one or more fragments are lost, it may decide to discard the whole packet in an unreliable datagram protocol. The Gnutella2 reliability layer can compensate by retransmitting the whole packet, which would then be re-fragmented and each fragment resent - however, this wastes the fragments that were successfully received before. Managing fragmentation natively allows this optimisation.&lt;br /&gt;
&lt;br /&gt;
Each node determines its own MTU, often based on a best guess combined with&lt;br /&gt;
information from the host's sockets implementation. Packets exceeding this size are&lt;br /&gt;
fragmented into multiple datagrams of the appropriate size. Each datagram has the&lt;br /&gt;
same sequence number and the same fragment count (nCount), but a different&lt;br /&gt;
fragment number (nPart).&lt;br /&gt;
&lt;br /&gt;
== Transmission Process ==&lt;br /&gt;
&lt;br /&gt;
When a packet is to be transmitted the network layer must:&lt;br /&gt;
&lt;br /&gt;
* Cache the payload&lt;br /&gt;
* Allocate a new locally and temporally unique sequence number&lt;br /&gt;
* Derive the appropriate number of fragments&lt;br /&gt;
* Queue the fragments for dispatch&lt;br /&gt;
* If the fragments do not need to be acknowledged, the packet can be flushed now&lt;br /&gt;
&lt;br /&gt;
The payload will generally be cached for an appropriate timeout period, or until the&lt;br /&gt;
data cache becomes full at which time older payloads can be discarded. Fragments&lt;br /&gt;
are dispatched according to the dispatch algorithm of choice, and the sender listens&lt;br /&gt;
for acknowledgements. When an acknowledgement is received:&lt;br /&gt;
&lt;br /&gt;
* Lookup the sent packet by sequence number&lt;br /&gt;
* Mark the nPart fragment as received and cancel any retransmissions of this part&lt;br /&gt;
* If all fragments have been acknowledged, flush this packet from the cache&lt;br /&gt;
&lt;br /&gt;
If a fragment has been transmitted but has not been acknowledged within the&lt;br /&gt;
timeout, it should be retransmitted. A finite number of retransmissions are allowed&lt;br /&gt;
before the packet as a whole expires, at which time it is assumed that the packet&lt;br /&gt;
was not received.&lt;br /&gt;
&lt;br /&gt;
== Receive Process ==&lt;br /&gt;
&lt;br /&gt;
When a new datagram is received, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* If the acknowledge bit was set, send an acknowledge packet for this sequence number and part number, with nCount set to zero (ack)&lt;br /&gt;
* Lookup any existing packet by the sending IP and sequence number &lt;br /&gt;
* If there is no existing packet, create a new packet entry with the IP, sequence number, fragment count and flags&lt;br /&gt;
* If there was an existing packet, make sure it is not marked as done - if so, abort&lt;br /&gt;
* Add the transmitted fragment to the (new or old) packet entry&lt;br /&gt;
* If the packet now has all fragments, mark it as done and decode it and pass it up to the application layer&lt;br /&gt;
* Leave the packet on the cache even if it was finished, in case any parts are retransmitted&lt;br /&gt;
* Expire old packets from the receive buffer after a timeout or if the buffer is full&lt;br /&gt;
&lt;br /&gt;
== Dispatch Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Fragment datagrams need to be dispatched intelligently to spread the load on&lt;br /&gt;
network resources and maximise the chance that the receiver will get the message.&lt;br /&gt;
To do this, the dispatch algorithm should take into account several points:&lt;br /&gt;
&lt;br /&gt;
* Prioritize acknowledgements.&lt;br /&gt;
* If fragments are waiting to be sent to a number of hosts, do not send to the same host twice in a row. Alternating or looping through the target hosts achieves the same data rate locally, but spreads out the load over downstream links.&lt;br /&gt;
* Do not exceed or approach the capacity of the local network connection. If a host has a 128 kb/s outbound bandwidth, dispatching 32 KB of data in one second will likely cause massive packet loss, leading to a retransmission.&lt;br /&gt;
* After considering the above points, prefer fragments that were queued recently to older packets. A LIFO or stack type approach means that even if a transmitter is becoming backed up, some fragments will get there on time while others will be delayed. A FIFO approach would mean that a backed up host delivers every fragment late.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
The recommended parameters for the reliability layer are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
MTU = 500 bytes&lt;br /&gt;
Transmit Retransmit Interval = 10 seconds&lt;br /&gt;
Transmit Packet Timeout / Expire = 26 seconds (allows for two retransmissions before expiry)&lt;br /&gt;
Receive Packet Expiry = 30 seconds (allows 10 seconds beyond final retransmission)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Performance Considerations ==&lt;br /&gt;
&lt;br /&gt;
Relatively low-level network implementations such as this are reasonably&lt;br /&gt;
complicated, but must operate fast. It is desirable to avoid runtime memory&lt;br /&gt;
allocations in network code as much as possible, and particularly at this level.&lt;br /&gt;
&lt;br /&gt;
It should be noted that in almost all cases, transmissions to &amp;quot;untested&amp;quot; nodes are&lt;br /&gt;
single fragment. Replies on the other hand are often larger, and may be deflated in&lt;br /&gt;
many fragments. This is optimal because attempting to contact a node which may be&lt;br /&gt;
unavailable involves a retransmission of only a single fragment.&lt;br /&gt;
&lt;br /&gt;
Flow control is an important topic, however it is handled at a higher layer. The UDP&lt;br /&gt;
reliability layer is only responsible for guaranteeing delivery of selected datagrams.&lt;br /&gt;
&lt;br /&gt;
Only critical transmissions whose reception cannot otherwise be inferred should have&lt;br /&gt;
the acknowledge request bit set.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=31</id>
		<title>UDP Transceiver</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=31"/>
		<updated>2005-03-27T16:03:23Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Encoding */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The User Datagram Protocol (UDP) is invaluable in peer to peer systems because it&lt;br /&gt;
provides a relatively low-cost (low-overhead) method of sending short, irregular&lt;br /&gt;
messages to a very large number of peers on demand. Establishing a TCP stream&lt;br /&gt;
connection to a peer simply to deliver a single packet of information is wasteful in&lt;br /&gt;
data volume and time for the peers involved and state-aware network devices along&lt;br /&gt;
the route, for example, network address translation facilities. When dealing with a&lt;br /&gt;
large number of peers quickly, these costs become unbearable. UDP provides a&lt;br /&gt;
solution and makes this kind of interaction possible.&lt;br /&gt;
&lt;br /&gt;
However, the delivery of UDP packets is not reliable: packets may be lost en-route for&lt;br /&gt;
a number of reasons. Often this behaviour is desirable, for example when the&lt;br /&gt;
destination node's connection is highly congested, UDP packets are likely to be&lt;br /&gt;
discarded. If the content was not critical, this loss is appropriate as the host's&lt;br /&gt;
resources are effectively unavailable. In other scenarios involving critical payloads,&lt;br /&gt;
UDP's lack of reliability is a problem: either the sender needs to make sure the&lt;br /&gt;
receiver gets the payload, or it needs to know definitively that the receiver was&lt;br /&gt;
unavailable.&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 network solves this problem by implementing a selectively engaged&lt;br /&gt;
reliability layer on top of the basic UDP protocol. This reliability layer shares some&lt;br /&gt;
common functionality with TCP, but importantly does not provide any connection&lt;br /&gt;
state and thus retains the efficiency originally sought in UDP.&lt;br /&gt;
&lt;br /&gt;
This allows Gnutella2 to select the most optimal communication medium for each&lt;br /&gt;
and every transmission it needs to perform:&lt;br /&gt;
&lt;br /&gt;
* If a significant volume of data is to be exchanged, or subsequent data will be exchanged with the same destination, a TCP connection is established&lt;br /&gt;
* If a small volume of important data is to be exchanged in a once-off operation or irregularly, reliable UDP is used&lt;br /&gt;
* If a small volume of unimportant data is to be exchanged in a once-off operation or irregularly, unreliable UDP is used&lt;br /&gt;
&lt;br /&gt;
== UDP ==&lt;br /&gt;
&lt;br /&gt;
Gnutella2 semi-reliable communication is transported using the UDP protocol. The&lt;br /&gt;
port number for receiving UDP is the same as the port number listening for TCP&lt;br /&gt;
connections.&lt;br /&gt;
&lt;br /&gt;
== Encoding ==&lt;br /&gt;
&lt;br /&gt;
Implementing an additional reliable protocol within UDP requires a small control&lt;br /&gt;
header before the payload itself. This header is put to good use:&lt;br /&gt;
&lt;br /&gt;
A small signature identifies the packet as a Gnutella2 semi-reliable UDP datagram.&lt;br /&gt;
This allows the same port to be used for receiving UDP traffic for other protocols if&lt;br /&gt;
desired, and offers some simple protection against random, unexpected traffic.&lt;br /&gt;
A content code identifies the payload as a Gnutella2 packet stream, allowing future&lt;br /&gt;
protocols to be added within the same reliability layer if desired. &lt;br /&gt;
Flags allow additional attributes to be specified, such as inline stateless compression&lt;br /&gt;
of the payload (which is a required feature).&lt;br /&gt;
The header has a fixed size of 8 bytes, and is represented by the following C&lt;br /&gt;
structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#pragma pack(1)&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
   CHAR szTag3;&lt;br /&gt;
   BYTE nFlags;&lt;br /&gt;
   WORD nSequence;&lt;br /&gt;
   BYTE nPart;&lt;br /&gt;
   BYTE nCount;&lt;br /&gt;
} GND_HEADER;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The members of the structure are detailed below:&lt;br /&gt;
&lt;br /&gt;
* '''szTag''' - contains a three byte encoding protocol identifier, in this case &amp;quot;GND&amp;quot; for &amp;quot;GNutella Datagram&amp;quot;. If this signature is not present the packet should not be decoded as a Gnutella2 reliability layer transmission.&lt;br /&gt;
* '''nFlags''' - contains flags which modify the content of the packet. The low-order nibble is reserved for critical flags: if one of these bits is set but the decoding software does not understand the meaning, the packet must be discarded. The high-order nibble is reserved for non-critical flags: when set these bits may be interpreted, but an inability to interpret a bit does not cause the packet to be discarded. Currently defined flags are:&lt;br /&gt;
:* '''0x01''' - Deflate&lt;br /&gt;
::  When the deflate bit is set, the entire payload is compressed with the deflate algorithm. The compression method used is the Deflate Compression Data Format (RFC 1951). On top of this compression a ZLIB ‘wrapper’ is applied (RFC 1950, ZLIB Compressed Data Format). The ZLIB wrapper ensures packet integrity, among other things. Note that the entire payload must be reassembled in the correct order before it can be deflated if the packet was fragmented. Fragments are not compressed separately!&lt;br /&gt;
:* '''0x02''' - Acknowledge Me&lt;br /&gt;
:: When the acknowledge me bit is set, the sender is expecting an acknowledgement for this packet.&lt;br /&gt;
&lt;br /&gt;
* '''nSequence''' - contains the sequence number of the packet. This sequence number is unique to the sending host only. It is not unique to the pair of the sending host and receiving host as in TCP, as there is no concept of connection state. Sequence numbers on consecutive packets need not be increasing (although that is convenient) â€“ they must only be different. If a packet is fragmented, all of its fragments will have the same sequence number. Byte order is unimportant here.&lt;br /&gt;
* '''nPart''' - contains the fragment part number (1 &amp;lt;= nPart &amp;lt;= nCount)&lt;br /&gt;
* '''nCount''' - contains the number of fragment parts in this packet. On a transmission, this value will be non-zero (all packets must have at least one fragment). If nCount is zero, this is an acknowledgement (see below).&lt;br /&gt;
&lt;br /&gt;
== Fragmentation ==&lt;br /&gt;
&lt;br /&gt;
Large packets must be fragmented before they can be sent through most network&lt;br /&gt;
interfaces. Different network media have different MTUs, and it is difficult to predict&lt;br /&gt;
what the lowest common size will be. Fragmentation and reassembly is performed by&lt;br /&gt;
the existing Internet protocols, however there are two important reasons why the&lt;br /&gt;
reliability layer performs its own fragmentation:&lt;br /&gt;
&lt;br /&gt;
* Sockets implementations specify a maximum datagram size. This is adequate for the vast majority of transmissions, but it is desirable to have the transparent ability to send larger packets without worrying about the host implementation.&lt;br /&gt;
* When the Internet protocols fragment a packet and one or more fragments are lost, it may decide to discard the whole packet in an unreliable datagram protocol. The Gnutella2 reliability layer can compensate by retransmitting the whole packet, which would then be re-fragmented and each fragment resent - however this wastes the fragments that were successfully received before. Managing fragmentation natively allows this optimisation.&lt;br /&gt;
&lt;br /&gt;
Each node determines its own MTU, often based on a best guess combined with&lt;br /&gt;
information from the host's sockets implementation. Packets exceeding this size are&lt;br /&gt;
fragmented into multiple datagrams of the appropriate size. Each datagram has the&lt;br /&gt;
same sequence number and the same fragment count (nCount), but a different&lt;br /&gt;
fragment number (nPart).&lt;br /&gt;
&lt;br /&gt;
== Transmission Process ==&lt;br /&gt;
&lt;br /&gt;
When a packet is to be transmitted the network layer must:&lt;br /&gt;
&lt;br /&gt;
* Cache the payload&lt;br /&gt;
* Allocate a new locally and temporally unique sequence number&lt;br /&gt;
* Derive the appropriate number of fragments&lt;br /&gt;
* Queue the fragments for dispatch&lt;br /&gt;
* If the fragments do not need to be acknowledged, the packet can be flushed now&lt;br /&gt;
&lt;br /&gt;
The payload will generally be cached for an appropriate timeout period, or until the&lt;br /&gt;
data cache becomes full at which time older payloads can be discarded. Fragments&lt;br /&gt;
are dispatched according to the dispatch algorithm of choice, and the sender listens&lt;br /&gt;
for acknowledgements. When an acknowledgement is received:&lt;br /&gt;
&lt;br /&gt;
* Lookup the sent packet by sequence number&lt;br /&gt;
* Mark the nPart fragment as received and cancel any retransmissions of this part&lt;br /&gt;
* If all fragments have been acknowledged, flush this packet from the cache&lt;br /&gt;
&lt;br /&gt;
If a fragment has been transmitted but has not been acknowledged within the&lt;br /&gt;
timeout, it should be retransmitted. A finite number of retransmissions are allowed&lt;br /&gt;
before the packet as a whole expires, at which time it is assumed that the packet&lt;br /&gt;
was not received.&lt;br /&gt;
&lt;br /&gt;
== Receive Process ==&lt;br /&gt;
&lt;br /&gt;
When a new datagram is received, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* If the acknowledge bit was set, send an acknowledge packet for this sequence number and part number, with nCount set to zero (ack)&lt;br /&gt;
* Lookup any existing packet by the sending IP and sequence number &lt;br /&gt;
* If there is no existing packet, create a new packet entry with the IP, sequence number, fragment count and flags&lt;br /&gt;
* If there was an existing packet, make sure it is not marked as done - if so, abort&lt;br /&gt;
* Add the transmitted fragment to the (new or old) packet entry&lt;br /&gt;
* If the packet now has all fragments, mark it as done and decode it and pass it up to the application layer&lt;br /&gt;
* Leave the packet on the cache even if it was finished, in case any parts are retransmitted&lt;br /&gt;
* Expire old packets from the receive buffer after a timeout or if the buffer is full&lt;br /&gt;
&lt;br /&gt;
== Dispatch Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Fragment datagrams need to be dispatched intelligently to spread the load on&lt;br /&gt;
network resources and maximise the chance that the receiver will get the message.&lt;br /&gt;
To do this, the dispatch algorithm should take into account several points:&lt;br /&gt;
&lt;br /&gt;
* Prioritize acknowledgements.&lt;br /&gt;
* If fragments are waiting to be sent to a number of hosts, do not send to the same host twice in a row. Alternating or looping through the target hosts achieves the same data rate locally, but spreads out the load over downstream links.&lt;br /&gt;
* Do not exceed or approach the capacity of the local network connection. If a host has a 128 kb/s outbound bandwidth, dispatching 32 KB of data in one second will likely cause massive packet loss, leading to a retransmission.&lt;br /&gt;
* After considering the above points, prefer fragments that were queued recently to older packets. A LIFO or stack type approach means that even if a transmitter is becoming backed up, some fragments will get there on time while others will be delayed. A FIFO approach would mean that a backed up host delivers every fragment late.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
The recommended parameters for the reliability layer are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
MTU = 500 bytes&lt;br /&gt;
Transmit Retransmit Interval = 10 seconds&lt;br /&gt;
Transmit Packet Timeout / Expire = 26 seconds (allows for two retransmissions before expiry)&lt;br /&gt;
Receive Packet Expiry = 30 seconds (allows 10 seconds beyond final retransmission)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Performance Considerations ==&lt;br /&gt;
&lt;br /&gt;
Relatively low-level network implementations such as this are reasonably&lt;br /&gt;
complicated, but must operate fast. It is desirable to avoid runtime memory&lt;br /&gt;
allocations in network code as much as possible, and particularly at this level.&lt;br /&gt;
&lt;br /&gt;
It should be noted that in almost all cases, transmissions to &amp;quot;untested&amp;quot; nodes are&lt;br /&gt;
single fragment. Replies on the other hand are often larger, and may be deflated in&lt;br /&gt;
many fragments. This is optimal because attempting to contact a node which may be&lt;br /&gt;
unavailable involves a retransmission of only a single fragment.&lt;br /&gt;
&lt;br /&gt;
Flow control is an important topic, however it is handled at a higher layer. The UDP&lt;br /&gt;
reliability layer is only responsible for guaranteeing delivery of selected datagrams.&lt;br /&gt;
&lt;br /&gt;
Only critical transmissions whose reception cannot otherwise be inferred should have&lt;br /&gt;
the acknowledge request bit set.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=30</id>
		<title>UDP Transceiver</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=30"/>
		<updated>2005-03-27T15:50:08Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The User Datagram Protocol (UDP) is invaluable in peer to peer systems because it&lt;br /&gt;
provides a relatively low-cost (low-overhead) method of sending short, irregular&lt;br /&gt;
messages to a very large number of peers on demand. Establishing a TCP stream&lt;br /&gt;
connection to a peer simply to deliver a single packet of information is wasteful in&lt;br /&gt;
data volume and time for the peers involved and state-aware network devices along&lt;br /&gt;
the route, for example, network address translation facilities. When dealing with a&lt;br /&gt;
large number of peers quickly, these costs become unbearable. UDP provides a&lt;br /&gt;
solution and makes this kind of interaction possible.&lt;br /&gt;
&lt;br /&gt;
However, the delivery of UDP packets is not reliable: packets may be lost en-route for&lt;br /&gt;
a number of reasons. Often this behaviour is desirable, for example when the&lt;br /&gt;
destination node's connection is highly congested, UDP packets are likely to be&lt;br /&gt;
discarded. If the content was not critical, this loss is appropriate as the host's&lt;br /&gt;
resources are effectively unavailable. In other scenarios involving critical payloads,&lt;br /&gt;
UDP's lack of reliability is a problem: either the sender needs to make sure the&lt;br /&gt;
receiver gets the payload, or it needs to know definitively that the receiver was&lt;br /&gt;
unavailable.&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 network solves this problem by implementing a selectively engaged&lt;br /&gt;
reliability layer on top of the basic UDP protocol. This reliability layer shares some&lt;br /&gt;
common functionality with TCP, but importantly does not provide any connection&lt;br /&gt;
state and thus retains the efficiency originally sought in UDP.&lt;br /&gt;
&lt;br /&gt;
This allows Gnutella2 to select the most optimal communication medium for each&lt;br /&gt;
and every transmission it needs to perform:&lt;br /&gt;
&lt;br /&gt;
* If a significant volume of data is to be exchanged, or subsequent data will be exchanged with the same destination, a TCP connection is established&lt;br /&gt;
* If a small volume of important data is to be exchanged in a once-off operation or irregularly, reliable UDP is used&lt;br /&gt;
* If a small volume of unimportant data is to be exchanged in a once-off operation or irregularly, unreliable UDP is used&lt;br /&gt;
&lt;br /&gt;
== UDP ==&lt;br /&gt;
&lt;br /&gt;
Gnutella2 semi-reliable communication is transported using the UDP protocol. The&lt;br /&gt;
port number for receiving UDP is the same as the port number listening for TCP&lt;br /&gt;
connections.&lt;br /&gt;
&lt;br /&gt;
== Encoding ==&lt;br /&gt;
&lt;br /&gt;
Implementing an additional reliable protocol within UDP requires a small control&lt;br /&gt;
header before the payload itself. This header is put to good use:&lt;br /&gt;
&lt;br /&gt;
A small signature identifies the packet as a Gnutella2 semi-reliable UDP datagram.&lt;br /&gt;
This allows the same port to be used for receiving UDP traffic for other protocols if&lt;br /&gt;
desired, and offers some simple protection against random, unexpected traffic.&lt;br /&gt;
A content code identifies the payload as a Gnutella2 packet stream, allowing future&lt;br /&gt;
protocols to be added within the same reliability layer if desired. &lt;br /&gt;
Flags allow additional attributes to be specified, such as inline stateless compression&lt;br /&gt;
of the payload (which is a required feature).&lt;br /&gt;
The header has a fixed size of 8 bytes, and is represented by the following C&lt;br /&gt;
structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#pragma pack(1)&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
   CHAR szTag3;&lt;br /&gt;
   BYTE nFlags;&lt;br /&gt;
   WORD nSequence;&lt;br /&gt;
   BYTE nPart;&lt;br /&gt;
   BYTE nCount;&lt;br /&gt;
} GND_HEADER;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The members of the structure are detailed below:&lt;br /&gt;
&lt;br /&gt;
* '''szTag''' - contains a three byte encoding protocol identifier, in this case &amp;quot;GND&amp;quot; for &amp;quot;GNutella Datagram&amp;quot;. If this signature is not present the packet should not be decoded as a Gnutella2 reliability layer transmission.&lt;br /&gt;
* '''nFlags''' - contains flags which modify the content of the packet. The low-order nibble is reserved for critical flags: if one of these bits is set but the decoding software does not understand the meaning, the packet must be discarded. The high-order nibble is reserved for non-critical flags: when set these bits may be interpreted, but an inability to interpret a bit does not cause the packet to be discarded. Currently defined flags are:&lt;br /&gt;
:* '''0x01''' - Deflate&lt;br /&gt;
::  When the deflate bit is set, the entire payload is compressed with the deflate algorithm. The compression method used is the Deflate Compression Data Format (RFC 1951). On top of this compression a ZLIB ‘wrapper’ is applied (RFC 1950, ZLIB Compressed Data Format.) The ZLIB wrapper ensures packet integrity, among other things. Note that the entire payload must be reassembled in the correct order before it can be deflated if the packet was fragmented. Fragments are not compressed separately!&lt;br /&gt;
:* '''0x02''' - Acknowledge Me&lt;br /&gt;
:: When the acknowledge me bit is set, the sender is expecting an acknowledgement for this packet.&lt;br /&gt;
&lt;br /&gt;
* '''nSequence''' - contains the sequence number of the packet. This sequence number is unique to the sending host only. It is not unique to the pair of the sending host and receiving host as in TCP, as there is no concept of connection state. Sequence numbers on consecutive packets need not be increasing (although that is convenient) â€“ they must only be different. If a packet is fragmented, all of its fragments will have the same sequence number. Byte order is unimportant here.&lt;br /&gt;
* '''nPart''' - contains the fragment part number (1 &amp;lt;= nPart &amp;lt;= nCount)&lt;br /&gt;
* '''nCount''' - contains the number of fragment parts in this packet. On a transmission, this value will be non-zero (all packets must have at least one fragment). If nCount is zero, this is an acknowledgement (see below).&lt;br /&gt;
&lt;br /&gt;
== Fragmentation ==&lt;br /&gt;
&lt;br /&gt;
Large packets must be fragmented before they can be sent through most network&lt;br /&gt;
interfaces. Different network media have different MTUs, and it is difficult to predict&lt;br /&gt;
what the lowest common size will be. Fragmentation and reassembly is performed by&lt;br /&gt;
the existing Internet protocols, however there are two important reasons why the&lt;br /&gt;
reliability layer performs its own fragmentation:&lt;br /&gt;
&lt;br /&gt;
* Sockets implementations specify a maximum datagram size. This is adequate for the vast majority of transmissions, but it is desirable to have the transparent ability to send larger packets without worrying about the host implementation.&lt;br /&gt;
* When the Internet protocols fragment a packet and one or more fragments are lost, it may decide to discard the whole packet in an unreliable datagram protocol. The Gnutella2 reliability layer can compensate by retransmitting the whole packet, which would then be re-fragmented and each fragment resent - however this wastes the fragments that were successfully received before. Managing fragmentation natively allows this optimisation.&lt;br /&gt;
&lt;br /&gt;
Each node determines its own MTU, often based on a best guess combined with&lt;br /&gt;
information from the host's sockets implementation. Packets exceeding this size are&lt;br /&gt;
fragmented into multiple datagrams of the appropriate size. Each datagram has the&lt;br /&gt;
same sequence number and the same fragment count (nCount), but a different&lt;br /&gt;
fragment number (nPart).&lt;br /&gt;
&lt;br /&gt;
== Transmission Process ==&lt;br /&gt;
&lt;br /&gt;
When a packet is to be transmitted the network layer must:&lt;br /&gt;
&lt;br /&gt;
* Cache the payload&lt;br /&gt;
* Allocate a new locally and temporally unique sequence number&lt;br /&gt;
* Derive the appropriate number of fragments&lt;br /&gt;
* Queue the fragments for dispatch&lt;br /&gt;
* If the fragments do not need to be acknowledged, the packet can be flushed now&lt;br /&gt;
&lt;br /&gt;
The payload will generally be cached for an appropriate timeout period, or until the&lt;br /&gt;
data cache becomes full at which time older payloads can be discarded. Fragments&lt;br /&gt;
are dispatched according to the dispatch algorithm of choice, and the sender listens&lt;br /&gt;
for acknowledgements. When an acknowledgement is received:&lt;br /&gt;
&lt;br /&gt;
* Lookup the sent packet by sequence number&lt;br /&gt;
* Mark the nPart fragment as received and cancel any retransmissions of this part&lt;br /&gt;
* If all fragments have been acknowledged, flush this packet from the cache&lt;br /&gt;
&lt;br /&gt;
If a fragment has been transmitted but has not been acknowledged within the&lt;br /&gt;
timeout, it should be retransmitted. A finite number of retransmissions are allowed&lt;br /&gt;
before the packet as a whole expires, at which time it is assumed that the packet&lt;br /&gt;
was not received.&lt;br /&gt;
&lt;br /&gt;
== Receive Process ==&lt;br /&gt;
&lt;br /&gt;
When a new datagram is received, the network layer must:&lt;br /&gt;
&lt;br /&gt;
* If the acknowledge bit was set, send an acknowledge packet for this sequence number and part number, with nCount set to zero (ack)&lt;br /&gt;
* Lookup any existing packet by the sending IP and sequence number &lt;br /&gt;
* If there is no existing packet, create a new packet entry with the IP, sequence number, fragment count and flags&lt;br /&gt;
* If there was an existing packet, make sure it is not marked as done - if so, abort&lt;br /&gt;
* Add the transmitted fragment to the (new or old) packet entry&lt;br /&gt;
* If the packet now has all fragments, mark it as done and decode it and pass it up to the application layer&lt;br /&gt;
* Leave the packet on the cache even if it was finished, in case any parts are retransmitted&lt;br /&gt;
* Expire old packets from the receive buffer after a timeout or if the buffer is full&lt;br /&gt;
&lt;br /&gt;
== Dispatch Algorithm ==&lt;br /&gt;
&lt;br /&gt;
Fragment datagrams need to be dispatched intelligently to spread the load on&lt;br /&gt;
network resources and maximise the chance that the receiver will get the message.&lt;br /&gt;
To do this, the dispatch algorithm should take into account several points:&lt;br /&gt;
&lt;br /&gt;
* Prioritize acknowledgements.&lt;br /&gt;
* If fragments are waiting to be sent to a number of hosts, do not send to the same host twice in a row. Alternating or looping through the target hosts achieves the same data rate locally, but spreads out the load over downstream links.&lt;br /&gt;
* Do not exceed or approach the capacity of the local network connection. If a host has a 128 kb/s outbound bandwidth, dispatching 32 KB of data in one second will likely cause massive packet loss, leading to a retransmission.&lt;br /&gt;
* After considering the above points, prefer fragments that were queued recently to older packets. A LIFO or stack type approach means that even if a transmitter is becoming backed up, some fragments will get there on time while others will be delayed. A FIFO approach would mean that a backed up host delivers every fragment late.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
The recommended parameters for the reliability layer are as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
MTU = 500 bytes&lt;br /&gt;
Transmit Retransmit Interval = 10 seconds&lt;br /&gt;
Transmit Packet Timeout / Expire = 26 seconds (allows for two retransmissions before expiry)&lt;br /&gt;
Receive Packet Expiry = 30 seconds (allows 10 seconds beyond final retransmission)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Performance Considerations ==&lt;br /&gt;
&lt;br /&gt;
Relatively low-level network implementations such as this are reasonably&lt;br /&gt;
complicated, but must operate fast. It is desirable to avoid runtime memory&lt;br /&gt;
allocations in network code as much as possible, and particularly at this level.&lt;br /&gt;
&lt;br /&gt;
It should be noted that in almost all cases, transmissions to &amp;quot;untested&amp;quot; nodes are&lt;br /&gt;
single fragment. Replies on the other hand are often larger, and may be deflated in&lt;br /&gt;
many fragments. This is optimal because attempting to contact a node which may be&lt;br /&gt;
unavailable involves a retransmission of only a single fragment.&lt;br /&gt;
&lt;br /&gt;
Flow control is an important topic, however it is handled at a higher layer. The UDP&lt;br /&gt;
reliability layer is only responsible for guaranteeing delivery of selected datagrams.&lt;br /&gt;
&lt;br /&gt;
Only critical transmissions whose reception cannot otherwise be inferred should have&lt;br /&gt;
the acknowledge request bit set.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=73</id>
		<title>TCP Stream Connection and Handshaking</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=73"/>
		<updated>2005-03-27T14:44:35Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Post Handshake Communication */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
TCP stream connections are established between Gnutella2 nodes when they elect to&lt;br /&gt;
form a permeant link, creating the fundamental network topology of a highly&lt;br /&gt;
interconnected hub network serving dense clusters of leaf nodes.&lt;br /&gt;
&lt;br /&gt;
== Initiation ==&lt;br /&gt;
&lt;br /&gt;
TCP connections are initiated by leaf or hub nodes in an attempt to gain a connection&lt;br /&gt;
to a hub node. Leaf nodes are never the target of an outbound connection. The TCP&lt;br /&gt;
port number is not standardised, and must be stored with the IP address.&lt;br /&gt;
&lt;br /&gt;
== Handshaking ==&lt;br /&gt;
&lt;br /&gt;
Upon the establishment of a TCP stream connection between two Gnutella2 nodes, a&lt;br /&gt;
handshaking phase must be completed to negotiate the nature of the link and&lt;br /&gt;
exchange other necessary information.&lt;br /&gt;
&lt;br /&gt;
This handshaking phase is the only part of the communication which remains&lt;br /&gt;
compatible with the old Gnutella network, allowing new connections to be negotiated&lt;br /&gt;
without fore-knowledge the capabilities of the other node. The handshaking process&lt;br /&gt;
has been well documented elsewhere, however, a short summary is provided here.&lt;br /&gt;
&lt;br /&gt;
=== Handshake Stages ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella handshake process consists of three header blocks. The node which&lt;br /&gt;
initiated the connection sends an initial header block, of the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA CONNECT/0.6&lt;br /&gt;
Listen-IP: 1.2.3.4:6346&lt;br /&gt;
Remote-IP: 6.7.8.9&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The receiver then responds with its own header block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Listen-IP: 6.7.8.9:6346&lt;br /&gt;
Remote-IP: 1.2.3.4&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: True&lt;br /&gt;
X-Ultrapeer-Needed: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, the initiator accepts the receiver's header block, and provides any final&lt;br /&gt;
information:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
The latter two stages may be replaced with an error condition if the connection is&lt;br /&gt;
being rejected. Appropriate error status codes are returned in this case, for example:&lt;br /&gt;
GNUTELLA/0.6 503 Too many connections&lt;br /&gt;
(more headers)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that only the HTTP-style error code should be interpreted by the software: any&lt;br /&gt;
descriptive text provided is for display purposes only and is not standardised.&lt;br /&gt;
&lt;br /&gt;
== Headers ==&lt;br /&gt;
&lt;br /&gt;
Important headers which are required or strongly recommended are detailed in the&lt;br /&gt;
following sections.&lt;br /&gt;
&lt;br /&gt;
=== Addressing Headers ===&lt;br /&gt;
&lt;br /&gt;
Two important headers to send on all connections are &amp;quot;Remote-IP&amp;quot; and &amp;quot;Listen-IP&amp;quot;.&lt;br /&gt;
Both of these headers should be sent on the first transmission, meaning in the first&lt;br /&gt;
and second header blocks in the three block exchange.&lt;br /&gt;
&lt;br /&gt;
The Remote-IP header contains the IP address from which the remote host is&lt;br /&gt;
connecting. This allows a remote host operating through some kind of network&lt;br /&gt;
address translation system, to learn its effective external address.&lt;br /&gt;
&lt;br /&gt;
The Listen-IP header contains the IP address and port number that the local host is&lt;br /&gt;
listening for inbound TCP connections on. It should be listening for UDP datagrams&lt;br /&gt;
on the same port. The format of this header is &amp;quot;IP:PORT&amp;quot;, eg &amp;quot;1.2.3.4:6346&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Identification ===&lt;br /&gt;
&lt;br /&gt;
The User-Agent header is used to identify the client software operating on the&lt;br /&gt;
sending node. It should be sent on the first transmission, meaning in the first and&lt;br /&gt;
second header blocks in the three block exchange. Note that this is a descriptive&lt;br /&gt;
string that often includes a version number, and is not a &amp;quot;vendor code&amp;quot; as described&lt;br /&gt;
elsewhere.&lt;br /&gt;
&lt;br /&gt;
=== Content Type (Protocol) ===&lt;br /&gt;
&lt;br /&gt;
The Accept and Content-Type header exchange is used to negotiate the data&lt;br /&gt;
protocol that will be used in the connection, in this case Gnutella2. The Gnutella2&lt;br /&gt;
content type is &amp;quot;application/x-gnutella2&amp;quot;, and this exchange follows standard HTTP&lt;br /&gt;
rules for negotiating content type.&lt;br /&gt;
&lt;br /&gt;
The first step is to advertise support for the content type (Gnutella2) in the first&lt;br /&gt;
header block with &amp;quot;Accept: application/x-gnutella2&amp;quot;. The responding node will then&lt;br /&gt;
indicate that it will send Gnutella2 content with &amp;quot;Content-Type: application/xgnutella2&amp;quot;,&lt;br /&gt;
and that it also supports Gnutella2 with &amp;quot;Accept: application/x-gnutella2&amp;quot;.&lt;br /&gt;
The initiating host then confirms that it will be sending Gnutella2 with &amp;quot;Content-&lt;br /&gt;
Type: application/x-gnutella2&amp;quot; in the third header block. For more information on the&lt;br /&gt;
Accept/Content-Type exchange, consult a HTTP reference.&lt;br /&gt;
&lt;br /&gt;
Note that the content type negotiation process is designed to be a &amp;quot;one-way&amp;quot;&lt;br /&gt;
process, i.e. a different content type can be negotiated for sending and receiving.&lt;br /&gt;
However, when the gnutella2 protocol is negotiated, both channels must use the&lt;br /&gt;
same content type. This means that a receiving node must not accept Gnutella2 if&lt;br /&gt;
the initiator did not advertise support for it, and if at the end of the handshake,&lt;br /&gt;
bidirectional Gnutella2 was not negotiated, the connection should be terminated.&lt;br /&gt;
&lt;br /&gt;
=== Node State Negotiation ===&lt;br /&gt;
&lt;br /&gt;
There are two node types in a Gnutella2 peer to peer network, a hub and a leaf, as&lt;br /&gt;
described in [[Node Types and Responsibilities]]. During the initial handshake,&lt;br /&gt;
the two parties must exchange their current node type and advise of their&lt;br /&gt;
capabilities, negotiating the node types they will adopt when the connection&lt;br /&gt;
completes, and indeed whether it should complete at all.&lt;br /&gt;
&lt;br /&gt;
As the handshake sequence is compatible with Gnutella1, the headers involved in&lt;br /&gt;
negotiating node types are identical to those used to negotiate Gnutella1 &amp;quot;Ultrapeer&amp;quot;&lt;br /&gt;
states:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Ultrapeer: [True|False]&lt;br /&gt;
X-Ultrapeer-Needed: [True|False]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both headers contain a Boolean value, &amp;quot;true&amp;quot; or &amp;quot;false&amp;quot;, case insensitive.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header indicates whether the transmitting node is currently&lt;br /&gt;
operating as a hub. Hub nodes will send &amp;quot;X-Ultrapeer: True&amp;quot; while leaf nodes will&lt;br /&gt;
send &amp;quot;X-Ultrapeer: False&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer-Needed header indicates whether the transmitting node would like&lt;br /&gt;
(and allow) the receiver to be a hub. A hub which sees no need for additional hubs in&lt;br /&gt;
its area of the network, will send &amp;quot;X-Ultrapeer-Needed: False&amp;quot;, indicating to the&lt;br /&gt;
connecting node that it must operate in leaf mode if it wishes to connect. A hub&lt;br /&gt;
which sees a need for additional hubs, will send &amp;quot;X-Ultrapeer-Needed: True&amp;quot;,&lt;br /&gt;
indicating that the receiving node should become a hub, if it is capable of doing so. A&lt;br /&gt;
leaf may send &amp;quot;X-Ultrapeer-Needed: True&amp;quot; to indicate that it is seeking a connection&lt;br /&gt;
to a hub.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header should be sent on all three of the header blocks to indicate&lt;br /&gt;
the current intended state of the node, while the X-Ultrapeer-Needed header should&lt;br /&gt;
be sent in the first two header blocks only, to indicate the desired status of the&lt;br /&gt;
receiver. If the nodes cannot agree on a satisfactory arrangement, the connection&lt;br /&gt;
will be terminated at or prior to the third header block with an appropriate message,&lt;br /&gt;
for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 503 Too many hub connections&lt;br /&gt;
GNUTELLA/0.6 503 Too many leaves&lt;br /&gt;
GNUTELLA/0.6 503 I have leaves, can't downgrade to leaf mode&lt;br /&gt;
GNUTELLA/0.6 503 Leaf mode disabled&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hub Address Exchange ===&lt;br /&gt;
&lt;br /&gt;
It is desirable for connecting nodes to exchange the node addresses of other hubs on&lt;br /&gt;
the network to facilitate rapid connection. The Gnutella2 protocol includes highly&lt;br /&gt;
efficient methods to share hub addresses with peers once connected, but for a node&lt;br /&gt;
trying to connect and encountering only &amp;quot;full&amp;quot; hubs, learning new hubs to try is&lt;br /&gt;
helpful.&lt;br /&gt;
&lt;br /&gt;
The X-Try-Ultrapeers header was developed for this purpose, and like the rest of&lt;br /&gt;
the handshake is also semi-compatible with Gnutella1. It contains a comma&lt;br /&gt;
separated list of hub node addresses and ports, along with a timestamp recording&lt;br /&gt;
the time the hub was last seen. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Try-Ultrapeers: 1.2.3.4:6346 2003-03-25T23:59Z, [..more..]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hub addresses should not be sent unless the transmitter has reasonable knowledge&lt;br /&gt;
of the hub's existence and the timestamp is not too old. The content type negotiation&lt;br /&gt;
headers should be used to verify that the listed hub addresses are indeed Gnutella2&lt;br /&gt;
hubs.&lt;br /&gt;
&lt;br /&gt;
=== Compression Negotiation and Encoding ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 architecture makes widespread use of &amp;quot;deflate&amp;quot; compression, due to&lt;br /&gt;
its high availability and ease of integration. Support of compressed TCP links is not a&lt;br /&gt;
requirement in the Gnutella2 standard, however, it is strongly recommended.&lt;br /&gt;
&lt;br /&gt;
Deflate compression of a TCP link is negotiated with the pair standard HTTP headers&lt;br /&gt;
&amp;quot;Accept-Encoding&amp;quot; and &amp;quot;Content-Encoding&amp;quot;. For example:&lt;br /&gt;
&lt;br /&gt;
Header block one (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block two (receiver):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block three (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, the initiator advertises support for receiving a deflated connection.&lt;br /&gt;
The receiver then indicates that it too supports receiving a deflated connection, and&lt;br /&gt;
that it intends to transmit deflated data. Finally, the initiator upon noting that the&lt;br /&gt;
receiver supports deflate, indicates that it too will transmit deflated data.&lt;br /&gt;
&lt;br /&gt;
Note that unlike the content-type / protocol negotiation, deflated encoding can be&lt;br /&gt;
applied on either incoming, outgoing, or both channels of a connection.&lt;br /&gt;
&lt;br /&gt;
For performance reasons, nodes should consider whether they can afford to support&lt;br /&gt;
additional deflated connections before advertising support for them, or agreeing to&lt;br /&gt;
provide a deflated data stream. In the Gnutella2 network topology, all links benefit&lt;br /&gt;
from compression, except the leaf to hub channel of the leaf/hub link. Exempting this&lt;br /&gt;
channel from compression, saves the leaf and more importantly, the hub, a&lt;br /&gt;
considerable CPU and RAM investment.&lt;br /&gt;
&lt;br /&gt;
== Post Handshake Communication ==&lt;br /&gt;
&lt;br /&gt;
After the third and final header block has been received by the initiator, subsequent&lt;br /&gt;
communication over the TCP stream occurs in the negotiated protocol, with the&lt;br /&gt;
negotiated encoding. This means that while the handshake sequence was backwards&lt;br /&gt;
compatible with Gnutella1, after Gnutella2 support has been negotiated, all&lt;br /&gt;
subsequent communication occurs in the Gnutella2 common protocol - an entirely&lt;br /&gt;
new system not backwards compatible with any other protocol.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=28</id>
		<title>TCP Stream Connection and Handshaking</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=28"/>
		<updated>2005-03-27T14:42:51Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Compression Negotiation and Encoding */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
TCP stream connections are established between Gnutella2 nodes when they elect to&lt;br /&gt;
form a permeant link, creating the fundamental network topology of a highly&lt;br /&gt;
interconnected hub network serving dense clusters of leaf nodes.&lt;br /&gt;
&lt;br /&gt;
== Initiation ==&lt;br /&gt;
&lt;br /&gt;
TCP connections are initiated by leaf or hub nodes in an attempt to gain a connection&lt;br /&gt;
to a hub node. Leaf nodes are never the target of an outbound connection. The TCP&lt;br /&gt;
port number is not standardised, and must be stored with the IP address.&lt;br /&gt;
&lt;br /&gt;
== Handshaking ==&lt;br /&gt;
&lt;br /&gt;
Upon the establishment of a TCP stream connection between two Gnutella2 nodes, a&lt;br /&gt;
handshaking phase must be completed to negotiate the nature of the link and&lt;br /&gt;
exchange other necessary information.&lt;br /&gt;
&lt;br /&gt;
This handshaking phase is the only part of the communication which remains&lt;br /&gt;
compatible with the old Gnutella network, allowing new connections to be negotiated&lt;br /&gt;
without fore-knowledge the capabilities of the other node. The handshaking process&lt;br /&gt;
has been well documented elsewhere, however, a short summary is provided here.&lt;br /&gt;
&lt;br /&gt;
=== Handshake Stages ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella handshake process consists of three header blocks. The node which&lt;br /&gt;
initiated the connection sends an initial header block, of the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA CONNECT/0.6&lt;br /&gt;
Listen-IP: 1.2.3.4:6346&lt;br /&gt;
Remote-IP: 6.7.8.9&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The receiver then responds with its own header block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Listen-IP: 6.7.8.9:6346&lt;br /&gt;
Remote-IP: 1.2.3.4&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: True&lt;br /&gt;
X-Ultrapeer-Needed: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, the initiator accepts the receiver's header block, and provides any final&lt;br /&gt;
information:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
The latter two stages may be replaced with an error condition if the connection is&lt;br /&gt;
being rejected. Appropriate error status codes are returned in this case, for example:&lt;br /&gt;
GNUTELLA/0.6 503 Too many connections&lt;br /&gt;
(more headers)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that only the HTTP-style error code should be interpreted by the software: any&lt;br /&gt;
descriptive text provided is for display purposes only and is not standardised.&lt;br /&gt;
&lt;br /&gt;
== Headers ==&lt;br /&gt;
&lt;br /&gt;
Important headers which are required or strongly recommended are detailed in the&lt;br /&gt;
following sections.&lt;br /&gt;
&lt;br /&gt;
=== Addressing Headers ===&lt;br /&gt;
&lt;br /&gt;
Two important headers to send on all connections are &amp;quot;Remote-IP&amp;quot; and &amp;quot;Listen-IP&amp;quot;.&lt;br /&gt;
Both of these headers should be sent on the first transmission, meaning in the first&lt;br /&gt;
and second header blocks in the three block exchange.&lt;br /&gt;
&lt;br /&gt;
The Remote-IP header contains the IP address from which the remote host is&lt;br /&gt;
connecting. This allows a remote host operating through some kind of network&lt;br /&gt;
address translation system, to learn its effective external address.&lt;br /&gt;
&lt;br /&gt;
The Listen-IP header contains the IP address and port number that the local host is&lt;br /&gt;
listening for inbound TCP connections on. It should be listening for UDP datagrams&lt;br /&gt;
on the same port. The format of this header is &amp;quot;IP:PORT&amp;quot;, eg &amp;quot;1.2.3.4:6346&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Identification ===&lt;br /&gt;
&lt;br /&gt;
The User-Agent header is used to identify the client software operating on the&lt;br /&gt;
sending node. It should be sent on the first transmission, meaning in the first and&lt;br /&gt;
second header blocks in the three block exchange. Note that this is a descriptive&lt;br /&gt;
string that often includes a version number, and is not a &amp;quot;vendor code&amp;quot; as described&lt;br /&gt;
elsewhere.&lt;br /&gt;
&lt;br /&gt;
=== Content Type (Protocol) ===&lt;br /&gt;
&lt;br /&gt;
The Accept and Content-Type header exchange is used to negotiate the data&lt;br /&gt;
protocol that will be used in the connection, in this case Gnutella2. The Gnutella2&lt;br /&gt;
content type is &amp;quot;application/x-gnutella2&amp;quot;, and this exchange follows standard HTTP&lt;br /&gt;
rules for negotiating content type.&lt;br /&gt;
&lt;br /&gt;
The first step is to advertise support for the content type (Gnutella2) in the first&lt;br /&gt;
header block with &amp;quot;Accept: application/x-gnutella2&amp;quot;. The responding node will then&lt;br /&gt;
indicate that it will send Gnutella2 content with &amp;quot;Content-Type: application/xgnutella2&amp;quot;,&lt;br /&gt;
and that it also supports Gnutella2 with &amp;quot;Accept: application/x-gnutella2&amp;quot;.&lt;br /&gt;
The initiating host then confirms that it will be sending Gnutella2 with &amp;quot;Content-&lt;br /&gt;
Type: application/x-gnutella2&amp;quot; in the third header block. For more information on the&lt;br /&gt;
Accept/Content-Type exchange, consult a HTTP reference.&lt;br /&gt;
&lt;br /&gt;
Note that the content type negotiation process is designed to be a &amp;quot;one-way&amp;quot;&lt;br /&gt;
process, i.e. a different content type can be negotiated for sending and receiving.&lt;br /&gt;
However, when the gnutella2 protocol is negotiated, both channels must use the&lt;br /&gt;
same content type. This means that a receiving node must not accept Gnutella2 if&lt;br /&gt;
the initiator did not advertise support for it, and if at the end of the handshake,&lt;br /&gt;
bidirectional Gnutella2 was not negotiated, the connection should be terminated.&lt;br /&gt;
&lt;br /&gt;
=== Node State Negotiation ===&lt;br /&gt;
&lt;br /&gt;
There are two node types in a Gnutella2 peer to peer network, a hub and a leaf, as&lt;br /&gt;
described in [[Node Types and Responsibilities]]. During the initial handshake,&lt;br /&gt;
the two parties must exchange their current node type and advise of their&lt;br /&gt;
capabilities, negotiating the node types they will adopt when the connection&lt;br /&gt;
completes, and indeed whether it should complete at all.&lt;br /&gt;
&lt;br /&gt;
As the handshake sequence is compatible with Gnutella1, the headers involved in&lt;br /&gt;
negotiating node types are identical to those used to negotiate Gnutella1 &amp;quot;Ultrapeer&amp;quot;&lt;br /&gt;
states:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Ultrapeer: [True|False]&lt;br /&gt;
X-Ultrapeer-Needed: [True|False]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both headers contain a Boolean value, &amp;quot;true&amp;quot; or &amp;quot;false&amp;quot;, case insensitive.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header indicates whether the transmitting node is currently&lt;br /&gt;
operating as a hub. Hub nodes will send &amp;quot;X-Ultrapeer: True&amp;quot; while leaf nodes will&lt;br /&gt;
send &amp;quot;X-Ultrapeer: False&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer-Needed header indicates whether the transmitting node would like&lt;br /&gt;
(and allow) the receiver to be a hub. A hub which sees no need for additional hubs in&lt;br /&gt;
its area of the network, will send &amp;quot;X-Ultrapeer-Needed: False&amp;quot;, indicating to the&lt;br /&gt;
connecting node that it must operate in leaf mode if it wishes to connect. A hub&lt;br /&gt;
which sees a need for additional hubs, will send &amp;quot;X-Ultrapeer-Needed: True&amp;quot;,&lt;br /&gt;
indicating that the receiving node should become a hub, if it is capable of doing so. A&lt;br /&gt;
leaf may send &amp;quot;X-Ultrapeer-Needed: True&amp;quot; to indicate that it is seeking a connection&lt;br /&gt;
to a hub.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header should be sent on all three of the header blocks to indicate&lt;br /&gt;
the current intended state of the node, while the X-Ultrapeer-Needed header should&lt;br /&gt;
be sent in the first two header blocks only, to indicate the desired status of the&lt;br /&gt;
receiver. If the nodes cannot agree on a satisfactory arrangement, the connection&lt;br /&gt;
will be terminated at or prior to the third header block with an appropriate message,&lt;br /&gt;
for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 503 Too many hub connections&lt;br /&gt;
GNUTELLA/0.6 503 Too many leaves&lt;br /&gt;
GNUTELLA/0.6 503 I have leaves, can't downgrade to leaf mode&lt;br /&gt;
GNUTELLA/0.6 503 Leaf mode disabled&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hub Address Exchange ===&lt;br /&gt;
&lt;br /&gt;
It is desirable for connecting nodes to exchange the node addresses of other hubs on&lt;br /&gt;
the network to facilitate rapid connection. The Gnutella2 protocol includes highly&lt;br /&gt;
efficient methods to share hub addresses with peers once connected, but for a node&lt;br /&gt;
trying to connect and encountering only &amp;quot;full&amp;quot; hubs, learning new hubs to try is&lt;br /&gt;
helpful.&lt;br /&gt;
&lt;br /&gt;
The X-Try-Ultrapeers header was developed for this purpose, and like the rest of&lt;br /&gt;
the handshake is also semi-compatible with Gnutella1. It contains a comma&lt;br /&gt;
separated list of hub node addresses and ports, along with a timestamp recording&lt;br /&gt;
the time the hub was last seen. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Try-Ultrapeers: 1.2.3.4:6346 2003-03-25T23:59Z, [..more..]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hub addresses should not be sent unless the transmitter has reasonable knowledge&lt;br /&gt;
of the hub's existence and the timestamp is not too old. The content type negotiation&lt;br /&gt;
headers should be used to verify that the listed hub addresses are indeed Gnutella2&lt;br /&gt;
hubs.&lt;br /&gt;
&lt;br /&gt;
=== Compression Negotiation and Encoding ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 architecture makes widespread use of &amp;quot;deflate&amp;quot; compression, due to&lt;br /&gt;
its high availability and ease of integration. Support of compressed TCP links is not a&lt;br /&gt;
requirement in the Gnutella2 standard, however, it is strongly recommended.&lt;br /&gt;
&lt;br /&gt;
Deflate compression of a TCP link is negotiated with the pair standard HTTP headers&lt;br /&gt;
&amp;quot;Accept-Encoding&amp;quot; and &amp;quot;Content-Encoding&amp;quot;. For example:&lt;br /&gt;
&lt;br /&gt;
Header block one (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block two (receiver):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block three (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, the initiator advertises support for receiving a deflated connection.&lt;br /&gt;
The receiver then indicates that it too supports receiving a deflated connection, and&lt;br /&gt;
that it intends to transmit deflated data. Finally, the initiator upon noting that the&lt;br /&gt;
receiver supports deflate, indicates that it too will transmit deflated data.&lt;br /&gt;
&lt;br /&gt;
Note that unlike the content-type / protocol negotiation, deflated encoding can be&lt;br /&gt;
applied on either incoming, outgoing, or both channels of a connection.&lt;br /&gt;
&lt;br /&gt;
For performance reasons, nodes should consider whether they can afford to support&lt;br /&gt;
additional deflated connections before advertising support for them, or agreeing to&lt;br /&gt;
provide a deflated data stream. In the Gnutella2 network topology, all links benefit&lt;br /&gt;
from compression, except the leaf to hub channel of the leaf/hub link. Exempting this&lt;br /&gt;
channel from compression, saves the leaf and more importantly, the hub, a&lt;br /&gt;
considerable CPU and RAM investment.&lt;br /&gt;
&lt;br /&gt;
== Post Handshake Communication ==&lt;br /&gt;
&lt;br /&gt;
After the third and final header block has been received by the initiator, subsequent&lt;br /&gt;
communication over the TCP stream occurs in the negotiated protocol, with the&lt;br /&gt;
negotiated encoding. This means that while the handshake sequence was backwards&lt;br /&gt;
compatible with Gnutella1, after Gnutella2 support has been negotiated all&lt;br /&gt;
subsequent communication occurs in the Gnutella2 common protocol - an entirely&lt;br /&gt;
new system not backwards compatible with any other protocol.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=27</id>
		<title>TCP Stream Connection and Handshaking</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=27"/>
		<updated>2005-03-27T14:36:39Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Node State Negotiation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
TCP stream connections are established between Gnutella2 nodes when they elect to&lt;br /&gt;
form a permeant link, creating the fundamental network topology of a highly&lt;br /&gt;
interconnected hub network serving dense clusters of leaf nodes.&lt;br /&gt;
&lt;br /&gt;
== Initiation ==&lt;br /&gt;
&lt;br /&gt;
TCP connections are initiated by leaf or hub nodes in an attempt to gain a connection&lt;br /&gt;
to a hub node. Leaf nodes are never the target of an outbound connection. The TCP&lt;br /&gt;
port number is not standardised, and must be stored with the IP address.&lt;br /&gt;
&lt;br /&gt;
== Handshaking ==&lt;br /&gt;
&lt;br /&gt;
Upon the establishment of a TCP stream connection between two Gnutella2 nodes, a&lt;br /&gt;
handshaking phase must be completed to negotiate the nature of the link and&lt;br /&gt;
exchange other necessary information.&lt;br /&gt;
&lt;br /&gt;
This handshaking phase is the only part of the communication which remains&lt;br /&gt;
compatible with the old Gnutella network, allowing new connections to be negotiated&lt;br /&gt;
without fore-knowledge the capabilities of the other node. The handshaking process&lt;br /&gt;
has been well documented elsewhere, however, a short summary is provided here.&lt;br /&gt;
&lt;br /&gt;
=== Handshake Stages ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella handshake process consists of three header blocks. The node which&lt;br /&gt;
initiated the connection sends an initial header block, of the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA CONNECT/0.6&lt;br /&gt;
Listen-IP: 1.2.3.4:6346&lt;br /&gt;
Remote-IP: 6.7.8.9&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The receiver then responds with its own header block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Listen-IP: 6.7.8.9:6346&lt;br /&gt;
Remote-IP: 1.2.3.4&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: True&lt;br /&gt;
X-Ultrapeer-Needed: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, the initiator accepts the receiver's header block, and provides any final&lt;br /&gt;
information:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
The latter two stages may be replaced with an error condition if the connection is&lt;br /&gt;
being rejected. Appropriate error status codes are returned in this case, for example:&lt;br /&gt;
GNUTELLA/0.6 503 Too many connections&lt;br /&gt;
(more headers)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that only the HTTP-style error code should be interpreted by the software: any&lt;br /&gt;
descriptive text provided is for display purposes only and is not standardised.&lt;br /&gt;
&lt;br /&gt;
== Headers ==&lt;br /&gt;
&lt;br /&gt;
Important headers which are required or strongly recommended are detailed in the&lt;br /&gt;
following sections.&lt;br /&gt;
&lt;br /&gt;
=== Addressing Headers ===&lt;br /&gt;
&lt;br /&gt;
Two important headers to send on all connections are &amp;quot;Remote-IP&amp;quot; and &amp;quot;Listen-IP&amp;quot;.&lt;br /&gt;
Both of these headers should be sent on the first transmission, meaning in the first&lt;br /&gt;
and second header blocks in the three block exchange.&lt;br /&gt;
&lt;br /&gt;
The Remote-IP header contains the IP address from which the remote host is&lt;br /&gt;
connecting. This allows a remote host operating through some kind of network&lt;br /&gt;
address translation system, to learn its effective external address.&lt;br /&gt;
&lt;br /&gt;
The Listen-IP header contains the IP address and port number that the local host is&lt;br /&gt;
listening for inbound TCP connections on. It should be listening for UDP datagrams&lt;br /&gt;
on the same port. The format of this header is &amp;quot;IP:PORT&amp;quot;, eg &amp;quot;1.2.3.4:6346&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Identification ===&lt;br /&gt;
&lt;br /&gt;
The User-Agent header is used to identify the client software operating on the&lt;br /&gt;
sending node. It should be sent on the first transmission, meaning in the first and&lt;br /&gt;
second header blocks in the three block exchange. Note that this is a descriptive&lt;br /&gt;
string that often includes a version number, and is not a &amp;quot;vendor code&amp;quot; as described&lt;br /&gt;
elsewhere.&lt;br /&gt;
&lt;br /&gt;
=== Content Type (Protocol) ===&lt;br /&gt;
&lt;br /&gt;
The Accept and Content-Type header exchange is used to negotiate the data&lt;br /&gt;
protocol that will be used in the connection, in this case Gnutella2. The Gnutella2&lt;br /&gt;
content type is &amp;quot;application/x-gnutella2&amp;quot;, and this exchange follows standard HTTP&lt;br /&gt;
rules for negotiating content type.&lt;br /&gt;
&lt;br /&gt;
The first step is to advertise support for the content type (Gnutella2) in the first&lt;br /&gt;
header block with &amp;quot;Accept: application/x-gnutella2&amp;quot;. The responding node will then&lt;br /&gt;
indicate that it will send Gnutella2 content with &amp;quot;Content-Type: application/xgnutella2&amp;quot;,&lt;br /&gt;
and that it also supports Gnutella2 with &amp;quot;Accept: application/x-gnutella2&amp;quot;.&lt;br /&gt;
The initiating host then confirms that it will be sending Gnutella2 with &amp;quot;Content-&lt;br /&gt;
Type: application/x-gnutella2&amp;quot; in the third header block. For more information on the&lt;br /&gt;
Accept/Content-Type exchange, consult a HTTP reference.&lt;br /&gt;
&lt;br /&gt;
Note that the content type negotiation process is designed to be a &amp;quot;one-way&amp;quot;&lt;br /&gt;
process, i.e. a different content type can be negotiated for sending and receiving.&lt;br /&gt;
However, when the gnutella2 protocol is negotiated, both channels must use the&lt;br /&gt;
same content type. This means that a receiving node must not accept Gnutella2 if&lt;br /&gt;
the initiator did not advertise support for it, and if at the end of the handshake,&lt;br /&gt;
bidirectional Gnutella2 was not negotiated, the connection should be terminated.&lt;br /&gt;
&lt;br /&gt;
=== Node State Negotiation ===&lt;br /&gt;
&lt;br /&gt;
There are two node types in a Gnutella2 peer to peer network, a hub and a leaf, as&lt;br /&gt;
described in [[Node Types and Responsibilities]]. During the initial handshake,&lt;br /&gt;
the two parties must exchange their current node type and advise of their&lt;br /&gt;
capabilities, negotiating the node types they will adopt when the connection&lt;br /&gt;
completes, and indeed whether it should complete at all.&lt;br /&gt;
&lt;br /&gt;
As the handshake sequence is compatible with Gnutella1, the headers involved in&lt;br /&gt;
negotiating node types are identical to those used to negotiate Gnutella1 &amp;quot;Ultrapeer&amp;quot;&lt;br /&gt;
states:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Ultrapeer: [True|False]&lt;br /&gt;
X-Ultrapeer-Needed: [True|False]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both headers contain a Boolean value, &amp;quot;true&amp;quot; or &amp;quot;false&amp;quot;, case insensitive.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header indicates whether the transmitting node is currently&lt;br /&gt;
operating as a hub. Hub nodes will send &amp;quot;X-Ultrapeer: True&amp;quot; while leaf nodes will&lt;br /&gt;
send &amp;quot;X-Ultrapeer: False&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer-Needed header indicates whether the transmitting node would like&lt;br /&gt;
(and allow) the receiver to be a hub. A hub which sees no need for additional hubs in&lt;br /&gt;
its area of the network, will send &amp;quot;X-Ultrapeer-Needed: False&amp;quot;, indicating to the&lt;br /&gt;
connecting node that it must operate in leaf mode if it wishes to connect. A hub&lt;br /&gt;
which sees a need for additional hubs, will send &amp;quot;X-Ultrapeer-Needed: True&amp;quot;,&lt;br /&gt;
indicating that the receiving node should become a hub, if it is capable of doing so. A&lt;br /&gt;
leaf may send &amp;quot;X-Ultrapeer-Needed: True&amp;quot; to indicate that it is seeking a connection&lt;br /&gt;
to a hub.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header should be sent on all three of the header blocks to indicate&lt;br /&gt;
the current intended state of the node, while the X-Ultrapeer-Needed header should&lt;br /&gt;
be sent in the first two header blocks only, to indicate the desired status of the&lt;br /&gt;
receiver. If the nodes cannot agree on a satisfactory arrangement, the connection&lt;br /&gt;
will be terminated at or prior to the third header block with an appropriate message,&lt;br /&gt;
for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 503 Too many hub connections&lt;br /&gt;
GNUTELLA/0.6 503 Too many leaves&lt;br /&gt;
GNUTELLA/0.6 503 I have leaves, can't downgrade to leaf mode&lt;br /&gt;
GNUTELLA/0.6 503 Leaf mode disabled&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hub Address Exchange ===&lt;br /&gt;
&lt;br /&gt;
It is desirable for connecting nodes to exchange the node addresses of other hubs on&lt;br /&gt;
the network to facilitate rapid connection. The Gnutella2 protocol includes highly&lt;br /&gt;
efficient methods to share hub addresses with peers once connected, but for a node&lt;br /&gt;
trying to connect and encountering only &amp;quot;full&amp;quot; hubs, learning new hubs to try is&lt;br /&gt;
helpful.&lt;br /&gt;
&lt;br /&gt;
The X-Try-Ultrapeers header was developed for this purpose, and like the rest of&lt;br /&gt;
the handshake is also semi-compatible with Gnutella1. It contains a comma&lt;br /&gt;
separated list of hub node addresses and ports, along with a timestamp recording&lt;br /&gt;
the time the hub was last seen. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Try-Ultrapeers: 1.2.3.4:6346 2003-03-25T23:59Z, [..more..]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hub addresses should not be sent unless the transmitter has reasonable knowledge&lt;br /&gt;
of the hub's existence and the timestamp is not too old. The content type negotiation&lt;br /&gt;
headers should be used to verify that the listed hub addresses are indeed Gnutella2&lt;br /&gt;
hubs.&lt;br /&gt;
&lt;br /&gt;
=== Compression Negotiation and Encoding ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 architecture makes widespread use of &amp;quot;deflate&amp;quot; compression, due to&lt;br /&gt;
its high availability and ease of integration. Support of compressed TCP links is not a&lt;br /&gt;
requirement in the Gnutella2 standard, however it is strongly recommended.&lt;br /&gt;
&lt;br /&gt;
Deflate compression of a TCP link is negotiated with the pair standard HTTP headers&lt;br /&gt;
&amp;quot;Accept-Encoding&amp;quot; and &amp;quot;Content-Encoding&amp;quot;. For example:&lt;br /&gt;
&lt;br /&gt;
Header block one (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block two (receiver):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block three (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the initiator advertises support for receiving a deflated connection.&lt;br /&gt;
The receiver then indicates that it too supports receiving a deflated connection, and&lt;br /&gt;
that it intends to transmit deflated data. Finally, the initiator upon noting that the&lt;br /&gt;
receiver supports deflate indicates that it too will transmit deflated data.&lt;br /&gt;
&lt;br /&gt;
Note that unlike the content-type / protocol negotiation, deflated encoding can be&lt;br /&gt;
applied on either incoming, outgoing or both channels of a connection.&lt;br /&gt;
&lt;br /&gt;
For performance reasons, nodes should consider whether they can afford to support&lt;br /&gt;
additional deflated connections before advertising support for them, or agreeing to&lt;br /&gt;
provide a deflated data stream. In the Gnutella2 network topology, all links benefit&lt;br /&gt;
from compression except the leaf to hub channel of the leaf/hub link. Exempting this&lt;br /&gt;
channel from compression saves the leaf and more importantly the hub a&lt;br /&gt;
considerable CPU and RAM investment.&lt;br /&gt;
&lt;br /&gt;
== Post Handshake Communication ==&lt;br /&gt;
&lt;br /&gt;
After the third and final header block has been received by the initiator, subsequent&lt;br /&gt;
communication over the TCP stream occurs in the negotiated protocol, with the&lt;br /&gt;
negotiated encoding. This means that while the handshake sequence was backwards&lt;br /&gt;
compatible with Gnutella1, after Gnutella2 support has been negotiated all&lt;br /&gt;
subsequent communication occurs in the Gnutella2 common protocol - an entirely&lt;br /&gt;
new system not backwards compatible with any other protocol.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=26</id>
		<title>TCP Stream Connection and Handshaking</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=26"/>
		<updated>2005-03-27T14:28:21Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Content Type (Protocol) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
TCP stream connections are established between Gnutella2 nodes when they elect to&lt;br /&gt;
form a permeant link, creating the fundamental network topology of a highly&lt;br /&gt;
interconnected hub network serving dense clusters of leaf nodes.&lt;br /&gt;
&lt;br /&gt;
== Initiation ==&lt;br /&gt;
&lt;br /&gt;
TCP connections are initiated by leaf or hub nodes in an attempt to gain a connection&lt;br /&gt;
to a hub node. Leaf nodes are never the target of an outbound connection. The TCP&lt;br /&gt;
port number is not standardised, and must be stored with the IP address.&lt;br /&gt;
&lt;br /&gt;
== Handshaking ==&lt;br /&gt;
&lt;br /&gt;
Upon the establishment of a TCP stream connection between two Gnutella2 nodes, a&lt;br /&gt;
handshaking phase must be completed to negotiate the nature of the link and&lt;br /&gt;
exchange other necessary information.&lt;br /&gt;
&lt;br /&gt;
This handshaking phase is the only part of the communication which remains&lt;br /&gt;
compatible with the old Gnutella network, allowing new connections to be negotiated&lt;br /&gt;
without fore-knowledge the capabilities of the other node. The handshaking process&lt;br /&gt;
has been well documented elsewhere, however, a short summary is provided here.&lt;br /&gt;
&lt;br /&gt;
=== Handshake Stages ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella handshake process consists of three header blocks. The node which&lt;br /&gt;
initiated the connection sends an initial header block, of the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA CONNECT/0.6&lt;br /&gt;
Listen-IP: 1.2.3.4:6346&lt;br /&gt;
Remote-IP: 6.7.8.9&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The receiver then responds with its own header block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Listen-IP: 6.7.8.9:6346&lt;br /&gt;
Remote-IP: 1.2.3.4&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: True&lt;br /&gt;
X-Ultrapeer-Needed: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, the initiator accepts the receiver's header block, and provides any final&lt;br /&gt;
information:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
The latter two stages may be replaced with an error condition if the connection is&lt;br /&gt;
being rejected. Appropriate error status codes are returned in this case, for example:&lt;br /&gt;
GNUTELLA/0.6 503 Too many connections&lt;br /&gt;
(more headers)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that only the HTTP-style error code should be interpreted by the software: any&lt;br /&gt;
descriptive text provided is for display purposes only and is not standardised.&lt;br /&gt;
&lt;br /&gt;
== Headers ==&lt;br /&gt;
&lt;br /&gt;
Important headers which are required or strongly recommended are detailed in the&lt;br /&gt;
following sections.&lt;br /&gt;
&lt;br /&gt;
=== Addressing Headers ===&lt;br /&gt;
&lt;br /&gt;
Two important headers to send on all connections are &amp;quot;Remote-IP&amp;quot; and &amp;quot;Listen-IP&amp;quot;.&lt;br /&gt;
Both of these headers should be sent on the first transmission, meaning in the first&lt;br /&gt;
and second header blocks in the three block exchange.&lt;br /&gt;
&lt;br /&gt;
The Remote-IP header contains the IP address from which the remote host is&lt;br /&gt;
connecting. This allows a remote host operating through some kind of network&lt;br /&gt;
address translation system, to learn its effective external address.&lt;br /&gt;
&lt;br /&gt;
The Listen-IP header contains the IP address and port number that the local host is&lt;br /&gt;
listening for inbound TCP connections on. It should be listening for UDP datagrams&lt;br /&gt;
on the same port. The format of this header is &amp;quot;IP:PORT&amp;quot;, eg &amp;quot;1.2.3.4:6346&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Identification ===&lt;br /&gt;
&lt;br /&gt;
The User-Agent header is used to identify the client software operating on the&lt;br /&gt;
sending node. It should be sent on the first transmission, meaning in the first and&lt;br /&gt;
second header blocks in the three block exchange. Note that this is a descriptive&lt;br /&gt;
string that often includes a version number, and is not a &amp;quot;vendor code&amp;quot; as described&lt;br /&gt;
elsewhere.&lt;br /&gt;
&lt;br /&gt;
=== Content Type (Protocol) ===&lt;br /&gt;
&lt;br /&gt;
The Accept and Content-Type header exchange is used to negotiate the data&lt;br /&gt;
protocol that will be used in the connection, in this case Gnutella2. The Gnutella2&lt;br /&gt;
content type is &amp;quot;application/x-gnutella2&amp;quot;, and this exchange follows standard HTTP&lt;br /&gt;
rules for negotiating content type.&lt;br /&gt;
&lt;br /&gt;
The first step is to advertise support for the content type (Gnutella2) in the first&lt;br /&gt;
header block with &amp;quot;Accept: application/x-gnutella2&amp;quot;. The responding node will then&lt;br /&gt;
indicate that it will send Gnutella2 content with &amp;quot;Content-Type: application/xgnutella2&amp;quot;,&lt;br /&gt;
and that it also supports Gnutella2 with &amp;quot;Accept: application/x-gnutella2&amp;quot;.&lt;br /&gt;
The initiating host then confirms that it will be sending Gnutella2 with &amp;quot;Content-&lt;br /&gt;
Type: application/x-gnutella2&amp;quot; in the third header block. For more information on the&lt;br /&gt;
Accept/Content-Type exchange, consult a HTTP reference.&lt;br /&gt;
&lt;br /&gt;
Note that the content type negotiation process is designed to be a &amp;quot;one-way&amp;quot;&lt;br /&gt;
process, i.e. a different content type can be negotiated for sending and receiving.&lt;br /&gt;
However, when the gnutella2 protocol is negotiated, both channels must use the&lt;br /&gt;
same content type. This means that a receiving node must not accept Gnutella2 if&lt;br /&gt;
the initiator did not advertise support for it, and if at the end of the handshake,&lt;br /&gt;
bidirectional Gnutella2 was not negotiated, the connection should be terminated.&lt;br /&gt;
&lt;br /&gt;
=== Node State Negotiation ===&lt;br /&gt;
&lt;br /&gt;
There are two node types in a Gnutella2 peer to peer network, a hub and a leaf as&lt;br /&gt;
described in [[Node Types and Responsibilities]]. During the initial handshake&lt;br /&gt;
the two parties must exchange their current node type and advise of their&lt;br /&gt;
capabilities, negotiating the node types they will adopt when the connection&lt;br /&gt;
completes, and indeed whether it should complete at all.&lt;br /&gt;
&lt;br /&gt;
As the handshake sequence is compatible with Gnutella1, the headers involved in&lt;br /&gt;
negotiating node types are identical to those used to negotiate Gnutella1 &amp;quot;Ultrapeer&amp;quot;&lt;br /&gt;
states:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Ultrapeer: [True|False]&lt;br /&gt;
X-Ultrapeer-Needed: [True|False]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both headers contain a Boolean value, &amp;quot;true&amp;quot; or &amp;quot;false&amp;quot;, case insensitive.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header indicates whether the transmitting node is currently&lt;br /&gt;
operating as a hub. Hub nodes will send &amp;quot;X-Ultrapeer: True&amp;quot; while leaf nodes will&lt;br /&gt;
send &amp;quot;X-Ultrapeer: False&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer-Needed header indicates whether the transmitting node would like&lt;br /&gt;
(and allow) the receiver to be a hub. A hub which sees no need for additional hubs in&lt;br /&gt;
its area of the network will send &amp;quot;X-Ultrapeer-Needed: False&amp;quot;, indicating to the&lt;br /&gt;
connecting node that it must operate in leaf mode if it wishes to connect. A hub&lt;br /&gt;
which sees a need for additional hubs will send &amp;quot;X-Ultrapeer-Needed: True&amp;quot;,&lt;br /&gt;
indicating that the receiving node should become a hub if it is capable of doing so. A&lt;br /&gt;
leaf may send &amp;quot;X-Ultrapeer-Needed: True&amp;quot; to indicate that it is seeking a connection&lt;br /&gt;
to a hub.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header should be sent on all three of the header blocks to indicate&lt;br /&gt;
the current intended state of the node, while the X-Ultrapeer-Needed header should&lt;br /&gt;
be sent in the first two header blocks only to indicate the desired status of the&lt;br /&gt;
receiver. If the nodes cannot agree on a satisfactory arrangement, the connection&lt;br /&gt;
will be terminated at or prior to the third header block with an appropriate message,&lt;br /&gt;
for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 503 Too many hub connections&lt;br /&gt;
GNUTELLA/0.6 503 Too many leaves&lt;br /&gt;
GNUTELLA/0.6 503 I have leaves, can't downgrade to leaf mode&lt;br /&gt;
GNUTELLA/0.6 503 Leaf mode disabled&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hub Address Exchange ===&lt;br /&gt;
&lt;br /&gt;
It is desirable for connecting nodes to exchange the node addresses of other hubs on&lt;br /&gt;
the network to facilitate rapid connection. The Gnutella2 protocol includes highly&lt;br /&gt;
efficient methods to share hub addresses with peers once connected, but for a node&lt;br /&gt;
trying to connect and encountering only &amp;quot;full&amp;quot; hubs, learning new hubs to try is&lt;br /&gt;
helpful.&lt;br /&gt;
&lt;br /&gt;
The X-Try-Ultrapeers header was developed for this purpose, and like the rest of&lt;br /&gt;
the handshake is also semi-compatible with Gnutella1. It contains a comma&lt;br /&gt;
separated list of hub node addresses and ports, along with a timestamp recording&lt;br /&gt;
the time the hub was last seen. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Try-Ultrapeers: 1.2.3.4:6346 2003-03-25T23:59Z, [..more..]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hub addresses should not be sent unless the transmitter has reasonable knowledge&lt;br /&gt;
of the hub's existence and the timestamp is not too old. The content type negotiation&lt;br /&gt;
headers should be used to verify that the listed hub addresses are indeed Gnutella2&lt;br /&gt;
hubs.&lt;br /&gt;
&lt;br /&gt;
=== Compression Negotiation and Encoding ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 architecture makes widespread use of &amp;quot;deflate&amp;quot; compression, due to&lt;br /&gt;
its high availability and ease of integration. Support of compressed TCP links is not a&lt;br /&gt;
requirement in the Gnutella2 standard, however it is strongly recommended.&lt;br /&gt;
&lt;br /&gt;
Deflate compression of a TCP link is negotiated with the pair standard HTTP headers&lt;br /&gt;
&amp;quot;Accept-Encoding&amp;quot; and &amp;quot;Content-Encoding&amp;quot;. For example:&lt;br /&gt;
&lt;br /&gt;
Header block one (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block two (receiver):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block three (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the initiator advertises support for receiving a deflated connection.&lt;br /&gt;
The receiver then indicates that it too supports receiving a deflated connection, and&lt;br /&gt;
that it intends to transmit deflated data. Finally, the initiator upon noting that the&lt;br /&gt;
receiver supports deflate indicates that it too will transmit deflated data.&lt;br /&gt;
&lt;br /&gt;
Note that unlike the content-type / protocol negotiation, deflated encoding can be&lt;br /&gt;
applied on either incoming, outgoing or both channels of a connection.&lt;br /&gt;
&lt;br /&gt;
For performance reasons, nodes should consider whether they can afford to support&lt;br /&gt;
additional deflated connections before advertising support for them, or agreeing to&lt;br /&gt;
provide a deflated data stream. In the Gnutella2 network topology, all links benefit&lt;br /&gt;
from compression except the leaf to hub channel of the leaf/hub link. Exempting this&lt;br /&gt;
channel from compression saves the leaf and more importantly the hub a&lt;br /&gt;
considerable CPU and RAM investment.&lt;br /&gt;
&lt;br /&gt;
== Post Handshake Communication ==&lt;br /&gt;
&lt;br /&gt;
After the third and final header block has been received by the initiator, subsequent&lt;br /&gt;
communication over the TCP stream occurs in the negotiated protocol, with the&lt;br /&gt;
negotiated encoding. This means that while the handshake sequence was backwards&lt;br /&gt;
compatible with Gnutella1, after Gnutella2 support has been negotiated all&lt;br /&gt;
subsequent communication occurs in the Gnutella2 common protocol - an entirely&lt;br /&gt;
new system not backwards compatible with any other protocol.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=25</id>
		<title>TCP Stream Connection and Handshaking</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=25"/>
		<updated>2005-03-27T14:23:05Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Addressing Headers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
TCP stream connections are established between Gnutella2 nodes when they elect to&lt;br /&gt;
form a permeant link, creating the fundamental network topology of a highly&lt;br /&gt;
interconnected hub network serving dense clusters of leaf nodes.&lt;br /&gt;
&lt;br /&gt;
== Initiation ==&lt;br /&gt;
&lt;br /&gt;
TCP connections are initiated by leaf or hub nodes in an attempt to gain a connection&lt;br /&gt;
to a hub node. Leaf nodes are never the target of an outbound connection. The TCP&lt;br /&gt;
port number is not standardised, and must be stored with the IP address.&lt;br /&gt;
&lt;br /&gt;
== Handshaking ==&lt;br /&gt;
&lt;br /&gt;
Upon the establishment of a TCP stream connection between two Gnutella2 nodes, a&lt;br /&gt;
handshaking phase must be completed to negotiate the nature of the link and&lt;br /&gt;
exchange other necessary information.&lt;br /&gt;
&lt;br /&gt;
This handshaking phase is the only part of the communication which remains&lt;br /&gt;
compatible with the old Gnutella network, allowing new connections to be negotiated&lt;br /&gt;
without fore-knowledge the capabilities of the other node. The handshaking process&lt;br /&gt;
has been well documented elsewhere, however, a short summary is provided here.&lt;br /&gt;
&lt;br /&gt;
=== Handshake Stages ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella handshake process consists of three header blocks. The node which&lt;br /&gt;
initiated the connection sends an initial header block, of the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA CONNECT/0.6&lt;br /&gt;
Listen-IP: 1.2.3.4:6346&lt;br /&gt;
Remote-IP: 6.7.8.9&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The receiver then responds with its own header block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Listen-IP: 6.7.8.9:6346&lt;br /&gt;
Remote-IP: 1.2.3.4&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: True&lt;br /&gt;
X-Ultrapeer-Needed: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, the initiator accepts the receiver's header block, and provides any final&lt;br /&gt;
information:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
The latter two stages may be replaced with an error condition if the connection is&lt;br /&gt;
being rejected. Appropriate error status codes are returned in this case, for example:&lt;br /&gt;
GNUTELLA/0.6 503 Too many connections&lt;br /&gt;
(more headers)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that only the HTTP-style error code should be interpreted by the software: any&lt;br /&gt;
descriptive text provided is for display purposes only and is not standardised.&lt;br /&gt;
&lt;br /&gt;
== Headers ==&lt;br /&gt;
&lt;br /&gt;
Important headers which are required or strongly recommended are detailed in the&lt;br /&gt;
following sections.&lt;br /&gt;
&lt;br /&gt;
=== Addressing Headers ===&lt;br /&gt;
&lt;br /&gt;
Two important headers to send on all connections are &amp;quot;Remote-IP&amp;quot; and &amp;quot;Listen-IP&amp;quot;.&lt;br /&gt;
Both of these headers should be sent on the first transmission, meaning in the first&lt;br /&gt;
and second header blocks in the three block exchange.&lt;br /&gt;
&lt;br /&gt;
The Remote-IP header contains the IP address from which the remote host is&lt;br /&gt;
connecting. This allows a remote host operating through some kind of network&lt;br /&gt;
address translation system, to learn its effective external address.&lt;br /&gt;
&lt;br /&gt;
The Listen-IP header contains the IP address and port number that the local host is&lt;br /&gt;
listening for inbound TCP connections on. It should be listening for UDP datagrams&lt;br /&gt;
on the same port. The format of this header is &amp;quot;IP:PORT&amp;quot;, eg &amp;quot;1.2.3.4:6346&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Identification ===&lt;br /&gt;
&lt;br /&gt;
The User-Agent header is used to identify the client software operating on the&lt;br /&gt;
sending node. It should be sent on the first transmission, meaning in the first and&lt;br /&gt;
second header blocks in the three block exchange. Note that this is a descriptive&lt;br /&gt;
string that often includes a version number, and is not a &amp;quot;vendor code&amp;quot; as described&lt;br /&gt;
elsewhere.&lt;br /&gt;
&lt;br /&gt;
=== Content Type (Protocol) ===&lt;br /&gt;
&lt;br /&gt;
The Accept and Content-Type header exchange is used to negotiate the data&lt;br /&gt;
protocol that will be used in the connection, in this case Gnutella2. The Gnutella2&lt;br /&gt;
content type is &amp;quot;application/x-gnutella2&amp;quot;, and this exchange follows standard HTTP&lt;br /&gt;
rules for negotiating content type.&lt;br /&gt;
&lt;br /&gt;
The first step is to advertise support for the content type (Gnutella2) in the first&lt;br /&gt;
header block with &amp;quot;Accept: application/x-gnutella2&amp;quot;. The responding node will then&lt;br /&gt;
indicate that it will send Gnutella2 content with &amp;quot;Content-Type: application/xgnutella2&amp;quot;,&lt;br /&gt;
and that it also supports Gnutella2 with &amp;quot;Accept: application/x-gnutella2&amp;quot;.&lt;br /&gt;
The initiating host then confirms that it will be sending Gnutella2 with &amp;quot;Content-&lt;br /&gt;
Type: application/x-gnutella2&amp;quot; in the third header block. For more information on the&lt;br /&gt;
Accept/Content-Type exchange, consult a HTTP reference.&lt;br /&gt;
&lt;br /&gt;
Note that the content type negotiation process is designed to be a &amp;quot;one way&amp;quot;&lt;br /&gt;
process, i.e. a different content type can be negotiated for sending and receiving.&lt;br /&gt;
However when the gnutella2 protocol is negotiated, both channels must use the&lt;br /&gt;
same content type. This means that a receiving node must not accept Gnutella2 if&lt;br /&gt;
the initiator did not advertise support for it, and if at the end of the handshake&lt;br /&gt;
bidirectional Gnutella2 was not negotiated, the connection should be terminated.&lt;br /&gt;
&lt;br /&gt;
=== Node State Negotiation ===&lt;br /&gt;
&lt;br /&gt;
There are two node types in a Gnutella2 peer to peer network, a hub and a leaf as&lt;br /&gt;
described in [[Node Types and Responsibilities]]. During the initial handshake&lt;br /&gt;
the two parties must exchange their current node type and advise of their&lt;br /&gt;
capabilities, negotiating the node types they will adopt when the connection&lt;br /&gt;
completes, and indeed whether it should complete at all.&lt;br /&gt;
&lt;br /&gt;
As the handshake sequence is compatible with Gnutella1, the headers involved in&lt;br /&gt;
negotiating node types are identical to those used to negotiate Gnutella1 &amp;quot;Ultrapeer&amp;quot;&lt;br /&gt;
states:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Ultrapeer: [True|False]&lt;br /&gt;
X-Ultrapeer-Needed: [True|False]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both headers contain a Boolean value, &amp;quot;true&amp;quot; or &amp;quot;false&amp;quot;, case insensitive.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header indicates whether the transmitting node is currently&lt;br /&gt;
operating as a hub. Hub nodes will send &amp;quot;X-Ultrapeer: True&amp;quot; while leaf nodes will&lt;br /&gt;
send &amp;quot;X-Ultrapeer: False&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer-Needed header indicates whether the transmitting node would like&lt;br /&gt;
(and allow) the receiver to be a hub. A hub which sees no need for additional hubs in&lt;br /&gt;
its area of the network will send &amp;quot;X-Ultrapeer-Needed: False&amp;quot;, indicating to the&lt;br /&gt;
connecting node that it must operate in leaf mode if it wishes to connect. A hub&lt;br /&gt;
which sees a need for additional hubs will send &amp;quot;X-Ultrapeer-Needed: True&amp;quot;,&lt;br /&gt;
indicating that the receiving node should become a hub if it is capable of doing so. A&lt;br /&gt;
leaf may send &amp;quot;X-Ultrapeer-Needed: True&amp;quot; to indicate that it is seeking a connection&lt;br /&gt;
to a hub.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header should be sent on all three of the header blocks to indicate&lt;br /&gt;
the current intended state of the node, while the X-Ultrapeer-Needed header should&lt;br /&gt;
be sent in the first two header blocks only to indicate the desired status of the&lt;br /&gt;
receiver. If the nodes cannot agree on a satisfactory arrangement, the connection&lt;br /&gt;
will be terminated at or prior to the third header block with an appropriate message,&lt;br /&gt;
for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 503 Too many hub connections&lt;br /&gt;
GNUTELLA/0.6 503 Too many leaves&lt;br /&gt;
GNUTELLA/0.6 503 I have leaves, can't downgrade to leaf mode&lt;br /&gt;
GNUTELLA/0.6 503 Leaf mode disabled&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hub Address Exchange ===&lt;br /&gt;
&lt;br /&gt;
It is desirable for connecting nodes to exchange the node addresses of other hubs on&lt;br /&gt;
the network to facilitate rapid connection. The Gnutella2 protocol includes highly&lt;br /&gt;
efficient methods to share hub addresses with peers once connected, but for a node&lt;br /&gt;
trying to connect and encountering only &amp;quot;full&amp;quot; hubs, learning new hubs to try is&lt;br /&gt;
helpful.&lt;br /&gt;
&lt;br /&gt;
The X-Try-Ultrapeers header was developed for this purpose, and like the rest of&lt;br /&gt;
the handshake is also semi-compatible with Gnutella1. It contains a comma&lt;br /&gt;
separated list of hub node addresses and ports, along with a timestamp recording&lt;br /&gt;
the time the hub was last seen. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Try-Ultrapeers: 1.2.3.4:6346 2003-03-25T23:59Z, [..more..]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hub addresses should not be sent unless the transmitter has reasonable knowledge&lt;br /&gt;
of the hub's existence and the timestamp is not too old. The content type negotiation&lt;br /&gt;
headers should be used to verify that the listed hub addresses are indeed Gnutella2&lt;br /&gt;
hubs.&lt;br /&gt;
&lt;br /&gt;
=== Compression Negotiation and Encoding ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 architecture makes widespread use of &amp;quot;deflate&amp;quot; compression, due to&lt;br /&gt;
its high availability and ease of integration. Support of compressed TCP links is not a&lt;br /&gt;
requirement in the Gnutella2 standard, however it is strongly recommended.&lt;br /&gt;
&lt;br /&gt;
Deflate compression of a TCP link is negotiated with the pair standard HTTP headers&lt;br /&gt;
&amp;quot;Accept-Encoding&amp;quot; and &amp;quot;Content-Encoding&amp;quot;. For example:&lt;br /&gt;
&lt;br /&gt;
Header block one (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block two (receiver):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block three (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the initiator advertises support for receiving a deflated connection.&lt;br /&gt;
The receiver then indicates that it too supports receiving a deflated connection, and&lt;br /&gt;
that it intends to transmit deflated data. Finally, the initiator upon noting that the&lt;br /&gt;
receiver supports deflate indicates that it too will transmit deflated data.&lt;br /&gt;
&lt;br /&gt;
Note that unlike the content-type / protocol negotiation, deflated encoding can be&lt;br /&gt;
applied on either incoming, outgoing or both channels of a connection.&lt;br /&gt;
&lt;br /&gt;
For performance reasons, nodes should consider whether they can afford to support&lt;br /&gt;
additional deflated connections before advertising support for them, or agreeing to&lt;br /&gt;
provide a deflated data stream. In the Gnutella2 network topology, all links benefit&lt;br /&gt;
from compression except the leaf to hub channel of the leaf/hub link. Exempting this&lt;br /&gt;
channel from compression saves the leaf and more importantly the hub a&lt;br /&gt;
considerable CPU and RAM investment.&lt;br /&gt;
&lt;br /&gt;
== Post Handshake Communication ==&lt;br /&gt;
&lt;br /&gt;
After the third and final header block has been received by the initiator, subsequent&lt;br /&gt;
communication over the TCP stream occurs in the negotiated protocol, with the&lt;br /&gt;
negotiated encoding. This means that while the handshake sequence was backwards&lt;br /&gt;
compatible with Gnutella1, after Gnutella2 support has been negotiated all&lt;br /&gt;
subsequent communication occurs in the Gnutella2 common protocol - an entirely&lt;br /&gt;
new system not backwards compatible with any other protocol.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=24</id>
		<title>TCP Stream Connection and Handshaking</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=24"/>
		<updated>2005-03-27T14:14:20Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Handshaking */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
TCP stream connections are established between Gnutella2 nodes when they elect to&lt;br /&gt;
form a permeant link, creating the fundamental network topology of a highly&lt;br /&gt;
interconnected hub network serving dense clusters of leaf nodes.&lt;br /&gt;
&lt;br /&gt;
== Initiation ==&lt;br /&gt;
&lt;br /&gt;
TCP connections are initiated by leaf or hub nodes in an attempt to gain a connection&lt;br /&gt;
to a hub node. Leaf nodes are never the target of an outbound connection. The TCP&lt;br /&gt;
port number is not standardised, and must be stored with the IP address.&lt;br /&gt;
&lt;br /&gt;
== Handshaking ==&lt;br /&gt;
&lt;br /&gt;
Upon the establishment of a TCP stream connection between two Gnutella2 nodes, a&lt;br /&gt;
handshaking phase must be completed to negotiate the nature of the link and&lt;br /&gt;
exchange other necessary information.&lt;br /&gt;
&lt;br /&gt;
This handshaking phase is the only part of the communication which remains&lt;br /&gt;
compatible with the old Gnutella network, allowing new connections to be negotiated&lt;br /&gt;
without fore-knowledge the capabilities of the other node. The handshaking process&lt;br /&gt;
has been well documented elsewhere, however, a short summary is provided here.&lt;br /&gt;
&lt;br /&gt;
=== Handshake Stages ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella handshake process consists of three header blocks. The node which&lt;br /&gt;
initiated the connection sends an initial header block, of the form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA CONNECT/0.6&lt;br /&gt;
Listen-IP: 1.2.3.4:6346&lt;br /&gt;
Remote-IP: 6.7.8.9&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The receiver then responds with its own header block:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Listen-IP: 6.7.8.9:6346&lt;br /&gt;
Remote-IP: 1.2.3.4&lt;br /&gt;
User-Agent: Shareaza 1.8.2.0&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
Accept: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: True&lt;br /&gt;
X-Ultrapeer-Needed: False&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, the initiator accepts the receiver's header block, and provides any final&lt;br /&gt;
information:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 200 OK&lt;br /&gt;
Content-Type: application/x-gnutella2&lt;br /&gt;
X-Ultrapeer: False&lt;br /&gt;
The latter two stages may be replaced with an error condition if the connection is&lt;br /&gt;
being rejected. Appropriate error status codes are returned in this case, for example:&lt;br /&gt;
GNUTELLA/0.6 503 Too many connections&lt;br /&gt;
(more headers)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that only the HTTP-style error code should be interpreted by the software: any&lt;br /&gt;
descriptive text provided is for display purposes only and is not standardised.&lt;br /&gt;
&lt;br /&gt;
== Headers ==&lt;br /&gt;
&lt;br /&gt;
Important headers which are required or strongly recommended are detailed in the&lt;br /&gt;
following sections.&lt;br /&gt;
&lt;br /&gt;
=== Addressing Headers ===&lt;br /&gt;
&lt;br /&gt;
Two important headers to send on all connections are &amp;quot;Remote-IP&amp;quot; and &amp;quot;Listen-IP&amp;quot;.&lt;br /&gt;
Both of these headers should be sent on the first transmission, meaning in the first&lt;br /&gt;
and second header blocks in the three block exchange.&lt;br /&gt;
&lt;br /&gt;
The Remote-IP header contains the IP address from which the remote host is&lt;br /&gt;
connecting. This allows a remote host operating through some kind of network&lt;br /&gt;
address translation system to learn its effective external address.&lt;br /&gt;
&lt;br /&gt;
The Listen-IP header contains the IP address and port number that the local host is&lt;br /&gt;
listening for inbound TCP connections on. It should be listening for UDP datagrams&lt;br /&gt;
on the same port. The format of this header is &amp;quot;IP:PORT&amp;quot;, eg &amp;quot;1.2.3.4:6346&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Identification ===&lt;br /&gt;
&lt;br /&gt;
The User-Agent header is used to identify the client software operating on the&lt;br /&gt;
sending node. It should be sent on the first transmission, meaning in the first and&lt;br /&gt;
second header blocks in the three block exchange. Note that this is a descriptive&lt;br /&gt;
string that often includes a version number, and is not a &amp;quot;vendor code&amp;quot; as described&lt;br /&gt;
elsewhere.&lt;br /&gt;
&lt;br /&gt;
=== Content Type (Protocol) ===&lt;br /&gt;
&lt;br /&gt;
The Accept and Content-Type header exchange is used to negotiate the data&lt;br /&gt;
protocol that will be used in the connection, in this case Gnutella2. The Gnutella2&lt;br /&gt;
content type is &amp;quot;application/x-gnutella2&amp;quot;, and this exchange follows standard HTTP&lt;br /&gt;
rules for negotiating content type.&lt;br /&gt;
&lt;br /&gt;
The first step is to advertise support for the content type (Gnutella2) in the first&lt;br /&gt;
header block with &amp;quot;Accept: application/x-gnutella2&amp;quot;. The responding node will then&lt;br /&gt;
indicate that it will send Gnutella2 content with &amp;quot;Content-Type: application/xgnutella2&amp;quot;,&lt;br /&gt;
and that it also supports Gnutella2 with &amp;quot;Accept: application/x-gnutella2&amp;quot;.&lt;br /&gt;
The initiating host then confirms that it will be sending Gnutella2 with &amp;quot;Content-&lt;br /&gt;
Type: application/x-gnutella2&amp;quot; in the third header block. For more information on the&lt;br /&gt;
Accept/Content-Type exchange, consult a HTTP reference.&lt;br /&gt;
&lt;br /&gt;
Note that the content type negotiation process is designed to be a &amp;quot;one way&amp;quot;&lt;br /&gt;
process, i.e. a different content type can be negotiated for sending and receiving.&lt;br /&gt;
However when the gnutella2 protocol is negotiated, both channels must use the&lt;br /&gt;
same content type. This means that a receiving node must not accept Gnutella2 if&lt;br /&gt;
the initiator did not advertise support for it, and if at the end of the handshake&lt;br /&gt;
bidirectional Gnutella2 was not negotiated, the connection should be terminated.&lt;br /&gt;
&lt;br /&gt;
=== Node State Negotiation ===&lt;br /&gt;
&lt;br /&gt;
There are two node types in a Gnutella2 peer to peer network, a hub and a leaf as&lt;br /&gt;
described in [[Node Types and Responsibilities]]. During the initial handshake&lt;br /&gt;
the two parties must exchange their current node type and advise of their&lt;br /&gt;
capabilities, negotiating the node types they will adopt when the connection&lt;br /&gt;
completes, and indeed whether it should complete at all.&lt;br /&gt;
&lt;br /&gt;
As the handshake sequence is compatible with Gnutella1, the headers involved in&lt;br /&gt;
negotiating node types are identical to those used to negotiate Gnutella1 &amp;quot;Ultrapeer&amp;quot;&lt;br /&gt;
states:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Ultrapeer: [True|False]&lt;br /&gt;
X-Ultrapeer-Needed: [True|False]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both headers contain a Boolean value, &amp;quot;true&amp;quot; or &amp;quot;false&amp;quot;, case insensitive.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header indicates whether the transmitting node is currently&lt;br /&gt;
operating as a hub. Hub nodes will send &amp;quot;X-Ultrapeer: True&amp;quot; while leaf nodes will&lt;br /&gt;
send &amp;quot;X-Ultrapeer: False&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer-Needed header indicates whether the transmitting node would like&lt;br /&gt;
(and allow) the receiver to be a hub. A hub which sees no need for additional hubs in&lt;br /&gt;
its area of the network will send &amp;quot;X-Ultrapeer-Needed: False&amp;quot;, indicating to the&lt;br /&gt;
connecting node that it must operate in leaf mode if it wishes to connect. A hub&lt;br /&gt;
which sees a need for additional hubs will send &amp;quot;X-Ultrapeer-Needed: True&amp;quot;,&lt;br /&gt;
indicating that the receiving node should become a hub if it is capable of doing so. A&lt;br /&gt;
leaf may send &amp;quot;X-Ultrapeer-Needed: True&amp;quot; to indicate that it is seeking a connection&lt;br /&gt;
to a hub.&lt;br /&gt;
&lt;br /&gt;
The X-Ultrapeer header should be sent on all three of the header blocks to indicate&lt;br /&gt;
the current intended state of the node, while the X-Ultrapeer-Needed header should&lt;br /&gt;
be sent in the first two header blocks only to indicate the desired status of the&lt;br /&gt;
receiver. If the nodes cannot agree on a satisfactory arrangement, the connection&lt;br /&gt;
will be terminated at or prior to the third header block with an appropriate message,&lt;br /&gt;
for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
GNUTELLA/0.6 503 Too many hub connections&lt;br /&gt;
GNUTELLA/0.6 503 Too many leaves&lt;br /&gt;
GNUTELLA/0.6 503 I have leaves, can't downgrade to leaf mode&lt;br /&gt;
GNUTELLA/0.6 503 Leaf mode disabled&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hub Address Exchange ===&lt;br /&gt;
&lt;br /&gt;
It is desirable for connecting nodes to exchange the node addresses of other hubs on&lt;br /&gt;
the network to facilitate rapid connection. The Gnutella2 protocol includes highly&lt;br /&gt;
efficient methods to share hub addresses with peers once connected, but for a node&lt;br /&gt;
trying to connect and encountering only &amp;quot;full&amp;quot; hubs, learning new hubs to try is&lt;br /&gt;
helpful.&lt;br /&gt;
&lt;br /&gt;
The X-Try-Ultrapeers header was developed for this purpose, and like the rest of&lt;br /&gt;
the handshake is also semi-compatible with Gnutella1. It contains a comma&lt;br /&gt;
separated list of hub node addresses and ports, along with a timestamp recording&lt;br /&gt;
the time the hub was last seen. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
X-Try-Ultrapeers: 1.2.3.4:6346 2003-03-25T23:59Z, [..more..]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hub addresses should not be sent unless the transmitter has reasonable knowledge&lt;br /&gt;
of the hub's existence and the timestamp is not too old. The content type negotiation&lt;br /&gt;
headers should be used to verify that the listed hub addresses are indeed Gnutella2&lt;br /&gt;
hubs.&lt;br /&gt;
&lt;br /&gt;
=== Compression Negotiation and Encoding ===&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 architecture makes widespread use of &amp;quot;deflate&amp;quot; compression, due to&lt;br /&gt;
its high availability and ease of integration. Support of compressed TCP links is not a&lt;br /&gt;
requirement in the Gnutella2 standard, however it is strongly recommended.&lt;br /&gt;
&lt;br /&gt;
Deflate compression of a TCP link is negotiated with the pair standard HTTP headers&lt;br /&gt;
&amp;quot;Accept-Encoding&amp;quot; and &amp;quot;Content-Encoding&amp;quot;. For example:&lt;br /&gt;
&lt;br /&gt;
Header block one (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block two (receiver):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Accept-Encoding: deflate&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Header block three (initiator):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Content-Encoding: deflate&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example the initiator advertises support for receiving a deflated connection.&lt;br /&gt;
The receiver then indicates that it too supports receiving a deflated connection, and&lt;br /&gt;
that it intends to transmit deflated data. Finally, the initiator upon noting that the&lt;br /&gt;
receiver supports deflate indicates that it too will transmit deflated data.&lt;br /&gt;
&lt;br /&gt;
Note that unlike the content-type / protocol negotiation, deflated encoding can be&lt;br /&gt;
applied on either incoming, outgoing or both channels of a connection.&lt;br /&gt;
&lt;br /&gt;
For performance reasons, nodes should consider whether they can afford to support&lt;br /&gt;
additional deflated connections before advertising support for them, or agreeing to&lt;br /&gt;
provide a deflated data stream. In the Gnutella2 network topology, all links benefit&lt;br /&gt;
from compression except the leaf to hub channel of the leaf/hub link. Exempting this&lt;br /&gt;
channel from compression saves the leaf and more importantly the hub a&lt;br /&gt;
considerable CPU and RAM investment.&lt;br /&gt;
&lt;br /&gt;
== Post Handshake Communication ==&lt;br /&gt;
&lt;br /&gt;
After the third and final header block has been received by the initiator, subsequent&lt;br /&gt;
communication over the TCP stream occurs in the negotiated protocol, with the&lt;br /&gt;
negotiated encoding. This means that while the handshake sequence was backwards&lt;br /&gt;
compatible with Gnutella1, after Gnutella2 support has been negotiated all&lt;br /&gt;
subsequent communication occurs in the Gnutella2 common protocol - an entirely&lt;br /&gt;
new system not backwards compatible with any other protocol.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Node_Types_and_Responsibilities&amp;diff=1633</id>
		<title>Node Types and Responsibilities</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Node_Types_and_Responsibilities&amp;diff=1633"/>
		<updated>2005-03-27T14:09:14Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Hub Responsibilities */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 network is an ad-hoc, self-organising collection of interconnected&lt;br /&gt;
nodes cooperating to enable productive distributed activities.&lt;br /&gt;
&lt;br /&gt;
Not all of the nodes participating in the system are equal: there are two primary&lt;br /&gt;
node types, &amp;quot;hubs&amp;quot; and &amp;quot;leaves&amp;quot;. The goal is to maximise the number of leaves&lt;br /&gt;
and minimise the number of hubs, however, due to the limited nature of resources&lt;br /&gt;
the maximum viable ratio of leaves to hubs is limited. This quantity is known as&lt;br /&gt;
the &amp;quot;leaf density&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Nodes ==&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Leaf nodes are the most common node type on the network - they have no&lt;br /&gt;
special responsibilities and do not form a working part of the network&lt;br /&gt;
infrastructure. Nodes with limited resources must operate as leaf nodes: this&lt;br /&gt;
includes limited bandwidth, CPU or RAM, low or unpredictable expected uptime,&lt;br /&gt;
and inability to accept inbound TCP or UDP.&lt;br /&gt;
&lt;br /&gt;
=== Hub Nodes ===&lt;br /&gt;
&lt;br /&gt;
Hub nodes on the other hand form an important and active part of the network&lt;br /&gt;
infrastructure, organising surrounding nodes, filtering and directing traffic over&lt;br /&gt;
several media types. Hub nodes devote substantial resources to the network, and&lt;br /&gt;
as a result their capacity to participate in higher level network functions is limited.&lt;br /&gt;
Only the most capable nodes are selected to act as hubs, based upon the criteria&lt;br /&gt;
in the following section.&lt;br /&gt;
&lt;br /&gt;
== Hub Selection Criteria ==&lt;br /&gt;
&lt;br /&gt;
Hubs are selected based on the following internal criteria:&lt;br /&gt;
&lt;br /&gt;
* Suitable operating system (able to support &amp;gt; 100 sockets)&lt;br /&gt;
* Suitably high CPU and RAM available&lt;br /&gt;
* Long uptime (many hours, at least two), possibly considering historical uptime&lt;br /&gt;
* Adequate bandwidth, primarily inbound bandwidth&lt;br /&gt;
* Ability to accept inbound TCP and UDP&lt;br /&gt;
&lt;br /&gt;
In addition to these internal factors, hubs must also consider the network's need&lt;br /&gt;
for additional hubs. Without a central point of authority, the need for additional&lt;br /&gt;
hubs cannot be determined with absolute certainty; however, it can be&lt;br /&gt;
approximated by examining the state of nearby nodes and specifically the state of&lt;br /&gt;
hubs in the local hub cluster.&lt;br /&gt;
&lt;br /&gt;
== Hub Responsibilities ==&lt;br /&gt;
Nodes operating as Gnutella2 hubs have a set of responsibilities to meet. Hubs&lt;br /&gt;
are highly interconnected, forming a &amp;quot;hub network&amp;quot; or &amp;quot;hub web&amp;quot;, with each hub&lt;br /&gt;
maintaining a connection to 5-30 other &amp;quot;neighbouring&amp;quot; hubs. The number of hub&lt;br /&gt;
interconnections must scale up with the overall size of the network.&lt;br /&gt;
&lt;br /&gt;
Each hub also accepts connections from a large collection of leaf nodes, typically&lt;br /&gt;
200-300 depending on available resources. Leaf nodes are considered to be the&lt;br /&gt;
&amp;quot;edge&amp;quot; of the network. In practice, leaves simultaneously connect to two hubs,&lt;br /&gt;
however, from the point of view of the hubs each leaf is considered a dead end.&lt;br /&gt;
&lt;br /&gt;
The group of hubs within the hub network spanning the local hub and its&lt;br /&gt;
neighbours is termed the &amp;quot;hub cluster&amp;quot;, and is an important grouping. Hub&lt;br /&gt;
clusters maintain constant communication with each other, sharing information&lt;br /&gt;
about network load and statistics, exchanging cache entries and filtering tables.&lt;br /&gt;
The hub cluster is also the smallest searchable unit of the network as far as a&lt;br /&gt;
search client is concerned.&lt;br /&gt;
&lt;br /&gt;
Hub responsibilities include:&lt;br /&gt;
&lt;br /&gt;
* Maintaining up-to-date information about other hubs in the cluster, and their neighbouring hubs, providing updates to neighbours&lt;br /&gt;
* Maintaining a node routing table mapping node GUIDs to shortest route local TCP connections and UDP endpoints&lt;br /&gt;
* Maintaining query hash tables for each connection, including both leaves and hubs so that queries can be executed intelligently&lt;br /&gt;
* Maintaining a superset query hash table including local content and every connected leaf's (not hub's) supplied tables, to supply to neighbouring hubs&lt;br /&gt;
* Monitoring the status of local connections and deciding whether to downgrade to leaf mode, and keeping distributed discovery services such as GWebCaches updated&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Node_Types_and_Responsibilities&amp;diff=22</id>
		<title>Node Types and Responsibilities</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Node_Types_and_Responsibilities&amp;diff=22"/>
		<updated>2005-03-27T13:57:00Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Hub Selection Criteria */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 network is an ad-hoc, self-organising collection of interconnected&lt;br /&gt;
nodes cooperating to enable productive distributed activities.&lt;br /&gt;
&lt;br /&gt;
Not all of the nodes participating in the system are equal: there are two primary&lt;br /&gt;
node types, &amp;quot;hubs&amp;quot; and &amp;quot;leaves&amp;quot;. The goal is to maximise the number of leaves&lt;br /&gt;
and minimise the number of hubs, however, due to the limited nature of resources&lt;br /&gt;
the maximum viable ratio of leaves to hubs is limited. This quantity is known as&lt;br /&gt;
the &amp;quot;leaf density&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Nodes ==&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Leaf nodes are the most common node type on the network - they have no&lt;br /&gt;
special responsibilities and do not form a working part of the network&lt;br /&gt;
infrastructure. Nodes with limited resources must operate as leaf nodes: this&lt;br /&gt;
includes limited bandwidth, CPU or RAM, low or unpredictable expected uptime,&lt;br /&gt;
and inability to accept inbound TCP or UDP.&lt;br /&gt;
&lt;br /&gt;
=== Hub Nodes ===&lt;br /&gt;
&lt;br /&gt;
Hub nodes on the other hand form an important and active part of the network&lt;br /&gt;
infrastructure, organising surrounding nodes, filtering and directing traffic over&lt;br /&gt;
several media types. Hub nodes devote substantial resources to the network, and&lt;br /&gt;
as a result their capacity to participate in higher level network functions is limited.&lt;br /&gt;
Only the most capable nodes are selected to act as hubs, based upon the criteria&lt;br /&gt;
in the following section.&lt;br /&gt;
&lt;br /&gt;
== Hub Selection Criteria ==&lt;br /&gt;
&lt;br /&gt;
Hubs are selected based on the following internal criteria:&lt;br /&gt;
&lt;br /&gt;
* Suitable operating system (able to support &amp;gt; 100 sockets)&lt;br /&gt;
* Suitably high CPU and RAM available&lt;br /&gt;
* Long uptime (many hours, at least two), possibly considering historical uptime&lt;br /&gt;
* Adequate bandwidth, primarily inbound bandwidth&lt;br /&gt;
* Ability to accept inbound TCP and UDP&lt;br /&gt;
&lt;br /&gt;
In addition to these internal factors, hubs must also consider the network's need&lt;br /&gt;
for additional hubs. Without a central point of authority, the need for additional&lt;br /&gt;
hubs cannot be determined with absolute certainty; however, it can be&lt;br /&gt;
approximated by examining the state of nearby nodes and specifically the state of&lt;br /&gt;
hubs in the local hub cluster.&lt;br /&gt;
&lt;br /&gt;
== Hub Responsibilities ==&lt;br /&gt;
Nodes operating as Gnutella2 hubs have a set of responsibilities to meet. Hubs&lt;br /&gt;
are highly interconnected, forming a &amp;quot;hub network&amp;quot; or &amp;quot;hub web&amp;quot;, with each hub&lt;br /&gt;
maintaining a connection to 5-30 other &amp;quot;neighbouring&amp;quot; hubs. The number of hub&lt;br /&gt;
interconnections must scale up with the overall size of the network.&lt;br /&gt;
&lt;br /&gt;
Each hub also accepts connections from a large collection of leaf nodes, typically&lt;br /&gt;
200-300 depending on available resources. Leaf nodes are considered to be the&lt;br /&gt;
&amp;quot;edge&amp;quot; of the network. In practice leaves simultaneously connect to two hubs,&lt;br /&gt;
however from the point of view of the hubs each leaf is considered a dead end.&lt;br /&gt;
&lt;br /&gt;
The group of hubs within the hub network spanning the local hub and its&lt;br /&gt;
neighbours is termed the &amp;quot;hub cluster&amp;quot;, and is an important grouping. Hub&lt;br /&gt;
clusters maintain constant communication with each other, sharing information&lt;br /&gt;
about network load and statistics, exchanging cache entries and filtering tables.&lt;br /&gt;
The hub cluster is also the smallest searchable unit of the network as far as a&lt;br /&gt;
search client is concerned.&lt;br /&gt;
&lt;br /&gt;
Hub responsibilities include:&lt;br /&gt;
&lt;br /&gt;
* Maintaining up to date information about other hubs in the cluster, and their neighbouring hubs, providing updates to neighbours&lt;br /&gt;
* Maintaining a node routing table mapping node GUIDs to shortest route local TCP connections and UDP endpoints&lt;br /&gt;
* Maintaining query hash tables for each connection, including both leaves and hubs so that queries can be executed intelligently&lt;br /&gt;
* Maintaining a superset query hash table including local content and every connected leaf's (not hub's) supplied tables, to supply to neighbouring hubs&lt;br /&gt;
* Monitoring the status of local connections and deciding whether to downgrade to leaf mode, and keeping distributed discovery services such as GWebCaches updated&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Node_Types_and_Responsibilities&amp;diff=21</id>
		<title>Node Types and Responsibilities</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Node_Types_and_Responsibilities&amp;diff=21"/>
		<updated>2005-03-27T13:53:21Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 network is an ad-hoc, self-organising collection of interconnected&lt;br /&gt;
nodes cooperating to enable productive distributed activities.&lt;br /&gt;
&lt;br /&gt;
Not all of the nodes participating in the system are equal: there are two primary&lt;br /&gt;
node types, &amp;quot;hubs&amp;quot; and &amp;quot;leaves&amp;quot;. The goal is to maximise the number of leaves&lt;br /&gt;
and minimise the number of hubs, however, due to the limited nature of resources&lt;br /&gt;
the maximum viable ratio of leaves to hubs is limited. This quantity is known as&lt;br /&gt;
the &amp;quot;leaf density&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Nodes ==&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Leaf nodes are the most common node type on the network - they have no&lt;br /&gt;
special responsibilities and do not form a working part of the network&lt;br /&gt;
infrastructure. Nodes with limited resources must operate as leaf nodes: this&lt;br /&gt;
includes limited bandwidth, CPU or RAM, low or unpredictable expected uptime,&lt;br /&gt;
and inability to accept inbound TCP or UDP.&lt;br /&gt;
&lt;br /&gt;
=== Hub Nodes ===&lt;br /&gt;
&lt;br /&gt;
Hub nodes on the other hand form an important and active part of the network&lt;br /&gt;
infrastructure, organising surrounding nodes, filtering and directing traffic over&lt;br /&gt;
several media types. Hub nodes devote substantial resources to the network, and&lt;br /&gt;
as a result their capacity to participate in higher level network functions is limited.&lt;br /&gt;
Only the most capable nodes are selected to act as hubs, based upon the criteria&lt;br /&gt;
in the following section.&lt;br /&gt;
&lt;br /&gt;
== Hub Selection Criteria ==&lt;br /&gt;
&lt;br /&gt;
Hubs are selected based on the following internal criteria:&lt;br /&gt;
&lt;br /&gt;
* Suitable operating system (able to support &amp;gt; 100 sockets)&lt;br /&gt;
* Suitably high CPU and RAM available&lt;br /&gt;
* Long uptime (many hours, at least two), possibly considering historical uptime&lt;br /&gt;
* Adequate bandwidth, primarily inbound bandwidth&lt;br /&gt;
* Ability to accept inbound TCP and UDP&lt;br /&gt;
&lt;br /&gt;
In addition to these internal factors, hubs must also consider the network's need&lt;br /&gt;
for additional hubs. Without a central point of authority the need for additional&lt;br /&gt;
hubs cannot be determined with absolute certainty; however it can be&lt;br /&gt;
approximated by examining the state of nearby nodes and specifically the state of&lt;br /&gt;
hubs in the local hub cluster.&lt;br /&gt;
&lt;br /&gt;
== Hub Responsibilities ==&lt;br /&gt;
Nodes operating as Gnutella2 hubs have a set of responsibilities to meet. Hubs&lt;br /&gt;
are highly interconnected, forming a &amp;quot;hub network&amp;quot; or &amp;quot;hub web&amp;quot;, with each hub&lt;br /&gt;
maintaining a connection to 5-30 other &amp;quot;neighbouring&amp;quot; hubs. The number of hub&lt;br /&gt;
interconnections must scale up with the overall size of the network.&lt;br /&gt;
&lt;br /&gt;
Each hub also accepts connections from a large collection of leaf nodes, typically&lt;br /&gt;
200-300 depending on available resources. Leaf nodes are considered to be the&lt;br /&gt;
&amp;quot;edge&amp;quot; of the network. In practice leaves simultaneously connect to two hubs,&lt;br /&gt;
however from the point of view of the hubs each leaf is considered a dead end.&lt;br /&gt;
&lt;br /&gt;
The group of hubs within the hub network spanning the local hub and its&lt;br /&gt;
neighbours is termed the &amp;quot;hub cluster&amp;quot;, and is an important grouping. Hub&lt;br /&gt;
clusters maintain constant communication with each other, sharing information&lt;br /&gt;
about network load and statistics, exchanging cache entries and filtering tables.&lt;br /&gt;
The hub cluster is also the smallest searchable unit of the network as far as a&lt;br /&gt;
search client is concerned.&lt;br /&gt;
&lt;br /&gt;
Hub responsibilities include:&lt;br /&gt;
&lt;br /&gt;
* Maintaining up to date information about other hubs in the cluster, and their neighbouring hubs, providing updates to neighbours&lt;br /&gt;
* Maintaining a node routing table mapping node GUIDs to shortest route local TCP connections and UDP endpoints&lt;br /&gt;
* Maintaining query hash tables for each connection, including both leaves and hubs so that queries can be executed intelligently&lt;br /&gt;
* Maintaining a superset query hash table including local content and every connected leaf's (not hub's) supplied tables, to supply to neighbouring hubs&lt;br /&gt;
* Monitoring the status of local connections and deciding whether to downgrade to leaf mode, and keeping distributed discovery services such as GWebCaches updated&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Simple_Query_Language_and_Metadata&amp;diff=1660</id>
		<title>Simple Query Language and Metadata</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Simple_Query_Language_and_Metadata&amp;diff=1660"/>
		<updated>2005-03-27T13:44:07Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* Generic Matching on Metadata */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
An effective search system must provide a query language which is:&lt;br /&gt;
&lt;br /&gt;
* Powerful&lt;br /&gt;
* Intuitive&lt;br /&gt;
* Natural&lt;br /&gt;
&lt;br /&gt;
At the same time, it is desirable for the language to be reasonably easy to parse in&lt;br /&gt;
software.&lt;br /&gt;
&lt;br /&gt;
Gnutella2 employs a simple query language that is familiar to users of web search&lt;br /&gt;
engines and allows most common criteria to be entered intuitively.&lt;br /&gt;
&lt;br /&gt;
Query Language Definition&lt;br /&gt;
&lt;br /&gt;
* Every search string is considered a list of words.&lt;br /&gt;
* Words are identified as sequences of alphanumeric characters. Other symbols and white space are ignored.&lt;br /&gt;
* In the basic case, every word in the list must appear one or more times in a matching string.&lt;br /&gt;
* Words may be marked as negative words or excluded words by prefixing them with a dash (-).&lt;br /&gt;
* In this case, every positive word in the list must appear and every negative word must not appear in a matching string.&lt;br /&gt;
* Words can be grouped together with quotes. The negation operator (-) may not appear inside a quoted string, but it may prefix a quoted string in which case the negation is applied to the quoted string as a whole.&lt;br /&gt;
* The words in a quoted string must appear in the same order in a matching string. Conversely, the words in a negated quoted string must not appear or must not appear in the same order in a matching string.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Cat Dog&lt;br /&gt;
(matches strings with &amp;quot;cat&amp;quot; and &amp;quot;dog&amp;quot;, in any order)&lt;br /&gt;
&lt;br /&gt;
-Cat Dog&lt;br /&gt;
(matches strings with &amp;quot;dog&amp;quot; but not &amp;quot;cat&amp;quot;, in any order)&lt;br /&gt;
&lt;br /&gt;
-Cat -Dog&lt;br /&gt;
(matches strings with neither &amp;quot;cat&amp;quot; nor &amp;quot;dog&amp;quot;, illegal in an external search as there are no positive words)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;cat dog&amp;quot;&lt;br /&gt;
(matches strings with &amp;quot;cat&amp;quot; followed by &amp;quot;dog&amp;quot;, &amp;quot;cat dog&amp;quot; matches, &amp;quot;dog cat&amp;quot; does not)&lt;br /&gt;
&lt;br /&gt;
-&amp;quot;cat dog&amp;quot;&lt;br /&gt;
(matches strings without &amp;quot;cat dog&amp;quot;, &amp;quot;cat dog&amp;quot; does not match, &amp;quot;dog cat&amp;quot; does)&lt;br /&gt;
&lt;br /&gt;
&amp;quot;cat dog&amp;quot; -fish&lt;br /&gt;
(matches strings with &amp;quot;cat dog&amp;quot; and without &amp;quot;fish&amp;quot;)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Metadata Searching ==&lt;br /&gt;
&lt;br /&gt;
Searching metadata involves a set of specific rules:&lt;br /&gt;
&lt;br /&gt;
* If a metadata schema is specified as search criteria, matching objects that have metadata must share the same schema&lt;br /&gt;
* Metadata can only be compared if criteria and object share the same schema&lt;br /&gt;
* Each data member (attribute or element) of metadata is compared separately&lt;br /&gt;
* Where a member is specified in the criteria but not in the object, the match fails&lt;br /&gt;
* Where a member is specified in the object but not in the criteria, the member is ignored&lt;br /&gt;
* The search criteria for each text/string member is in the simple query language defined above&lt;br /&gt;
* The search criteria for numeric members is range based, defined in a subsequent section.&lt;br /&gt;
&lt;br /&gt;
== Numeric Range Matching ==&lt;br /&gt;
&lt;br /&gt;
When comparing numeric values, the match function is specified by the search&lt;br /&gt;
criteria:&lt;br /&gt;
&lt;br /&gt;
* If a value is specified, the value must match exactly&lt;br /&gt;
* If a range (X-Y) is specified, the value must lie within that inclusive range&lt;br /&gt;
* If (X-) is specified, the value must be greater than or equal to X&lt;br /&gt;
* If (-X) is specified, the value must be less than or equal to X&lt;br /&gt;
&lt;br /&gt;
== Generic Matching on Metadata ==&lt;br /&gt;
&lt;br /&gt;
Generic search criteria (/Q2/DN) can be matched against metadata fields, however,&lt;br /&gt;
care must be taken not to match against data members which are not directly&lt;br /&gt;
descriptive to the object. Client-side schema descriptors are a good solution, listing&lt;br /&gt;
the scope of a general search on each recognised schema.&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Main_Page&amp;diff=60</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Main_Page&amp;diff=60"/>
		<updated>2005-03-27T13:19:21Z</updated>

		<summary type="html">&lt;p&gt;Kath: /* What is Gnutella2? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is Gnutella2? ==&lt;br /&gt;
&lt;br /&gt;
Gnutella2 is a modern and efficient peer-to-peer network standard and architecture&lt;br /&gt;
designed to provide a solid foundation for distributed global services such as person&lt;br /&gt;
to person communication, data location &amp;amp; transfer, and other future services.&lt;br /&gt;
&lt;br /&gt;
== Why is it needed? ==&lt;br /&gt;
&lt;br /&gt;
Peer to peer technologies have become mainstream over recent years, and there are&lt;br /&gt;
already a significant number of P2P networks in various stages of development and&lt;br /&gt;
operation. How does yet another network help?&lt;br /&gt;
&lt;br /&gt;
Gnutella2 is unique amongst the currently operating peer to peer networks in several&lt;br /&gt;
important ways:&lt;br /&gt;
&lt;br /&gt;
Many of the most successful networks are &amp;quot;closed&amp;quot;, owned by a single entity with&lt;br /&gt;
restrictions or fees constituting a barrier to participation. This is not a viable model&lt;br /&gt;
for an open, general purpose network. Gnutella2 is an open architecture where&lt;br /&gt;
anyone is welcome to participate and contribute. The network has been designed to&lt;br /&gt;
allow such diversity without the need for messy hacks or compromises in integrity.&lt;br /&gt;
The majority of networks are devoted to a single purpose, often the sharing of files.&lt;br /&gt;
This is certainly a popular application for peer to peer technology, but it is by no&lt;br /&gt;
means the only application. Gnutella2 is designed as a general purpose network&lt;br /&gt;
which can be used as a solid foundation for any number of different peer to peer&lt;br /&gt;
applications - vanilla file sharing, communications tools or other ideas which are yet&lt;br /&gt;
to be conceived.&lt;br /&gt;
&lt;br /&gt;
Some peer to peer networks have been developed with similar general purpose&lt;br /&gt;
goals, however, they have been unable to compete in the most popular application of&lt;br /&gt;
the day, which is file sharing. For a general purpose network to succeed, it must be&lt;br /&gt;
able to compete with purpose-specific networks in the most popular purpose.&lt;br /&gt;
Gnutella2 is not only able to compete with the current popular file sharing specific&lt;br /&gt;
networks, it outperforms them.&lt;br /&gt;
&lt;br /&gt;
== What is the Scope of Gnutella2? ==&lt;br /&gt;
&lt;br /&gt;
The single name &amp;quot;Gnutella2&amp;quot; really refers to two separate components: the [[Gnutella2 Standard]] and the [[Gnutella2 Network]].&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 Network is perhaps the most easily recognised component. It is a new&lt;br /&gt;
high-performance peer to peer network architecture upon which a variety of&lt;br /&gt;
distributed applications can be built, such as file sharing applications, communication&lt;br /&gt;
tools, etc.&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 Standard is a set of requirements for building applications which&lt;br /&gt;
operate on the Gnutella2 network in different capacities. It specifies the minimum&lt;br /&gt;
compliance level required to be recognised as a Gnutella2-compatible application.&lt;br /&gt;
Compliance with a Gnutella2 Standard ensures participating applications provide a&lt;br /&gt;
minimum acceptable level of service to other network participants.&lt;br /&gt;
&lt;br /&gt;
== Indices ==&lt;br /&gt;
&lt;br /&gt;
* [[Main index]]&lt;br /&gt;
* [[Root packets index]]&lt;/div&gt;</summary>
		<author><name>Kath</name></author>
	</entry>
</feed>