<?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=Spooky</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=Spooky"/>
	<link rel="alternate" type="text/html" href="https://g2.doxu.org/wiki/Special:Contributions/Spooky"/>
	<updated>2026-04-28T03:08:37Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.38.4</generator>
	<entry>
		<id>https://g2.doxu.org/index.php?title=CRAWLR&amp;diff=896</id>
		<title>CRAWLR</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=CRAWLR&amp;diff=896"/>
		<updated>2005-09-08T10:38:28Z</updated>

		<summary type="html">&lt;p&gt;Spooky: /* Receiving */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CRAWLA|&amp;lt;&amp;lt; CRAWLA]] | [[HAW|HAW &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
= /CRAWLR - Crawler Request =&lt;br /&gt;
&lt;br /&gt;
The crawler request packet is sent by a Gnutella2 crawler in order to gather information about the Gnutella2 network.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLR packet ... TODO&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
Upon receiving a /CRAWLR packet a [[CRAWLA|/CAWLA]] packet containing the requested information should be sent.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLR packet has the following child packets defined:&lt;br /&gt;
&lt;br /&gt;
* /CRAWLR/RLEAF - Request leaf information&lt;br /&gt;
* /CRAWLR/RNAME - Request Nickname&lt;br /&gt;
* /CRAWLR/RGPS - Request GPS data&lt;br /&gt;
* /CRAWLR/REXT - Request version information&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=CRAWLA&amp;diff=1897</id>
		<title>CRAWLA</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=CRAWLA&amp;diff=1897"/>
		<updated>2005-09-07T12:21:19Z</updated>

		<summary type="html">&lt;p&gt;Spooky: /* Children */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CRAWLR|CRAWLR &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /CRAWLA - Crawler Answer =&lt;br /&gt;
&lt;br /&gt;
The crawl answer packet is the response to a [[CRAWLR|crawl request packet]]. It contains information about the current node for a Gnutella2 crawler.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLA packet ... TODO&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
A /CRAWLA packet should only be received by a crawler in response to a [[CRAWLR|/CRAWLR]] packet, which should use it to gather information about the Gnutella2 network.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLA packet has the following child packets defined:&lt;br /&gt;
&lt;br /&gt;
* /CRAWLA/SELF - Vendor Code and Version&lt;br /&gt;
* /CRAWLA/NA - Network Address&lt;br /&gt;
* /CRAWLA/HS - Hub Status&lt;br /&gt;
* /CRAWLA/HUB - Only present if the host is a hub&lt;br /&gt;
* /CRAWLA/LEAF - Only present if the host is a leaf&lt;br /&gt;
* /CRAWLA/GPS - GPS information&lt;br /&gt;
* /CRAWLA/NH - Neighbouring Hub&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=KHL&amp;diff=1643</id>
		<title>KHL</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=KHL&amp;diff=1643"/>
		<updated>2005-09-07T09:24:56Z</updated>

		<summary type="html">&lt;p&gt;Spooky: navi&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[HAW|&amp;lt;&amp;lt; HAW]] | [[LNI|LNI &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /KHL =&lt;br /&gt;
&lt;br /&gt;
The known hub list packet is used to exchange a list of known Gnutella2 hubs with&lt;br /&gt;
neighbouring nodes. It is exchanged regularly over all TCP connections, between&lt;br /&gt;
hubs and between hubs and leaves (and vice versa). It enables a completely up to&lt;br /&gt;
date picture of the local hub cluster, and the gradual propagation of cached hub&lt;br /&gt;
records.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
This packet should be sent through TCP links at regular intervals. One minute is&lt;br /&gt;
suggested for busy links, leaves may send to hubs less often. Note that unlike /LNI,&lt;br /&gt;
/KHL must be sent regularly even if the information does not change in order to&lt;br /&gt;
refresh timestamps and keep time-sorted caches in the correct order.&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
Upon receiving a known hub list, the detailed hubs should be stored in appropriate&lt;br /&gt;
data structures. Neighbouring hubs must be retained in the hub cluster records,&lt;br /&gt;
while cached hubs should be merged with the local accessible hub cache.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
This packet has several child packet types defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /KHL/TS - Timestamp&lt;br /&gt;
* /KHL/NH - Neighbouring Hub&lt;br /&gt;
* /KHL/CH - Cached Hub&lt;br /&gt;
&lt;br /&gt;
== /KHL/TS - Timestamp ==&lt;br /&gt;
&lt;br /&gt;
The /KHL/TS child provides a timestamp representing the current universal time at&lt;br /&gt;
the sending node. This can be used as a reference when considering other&lt;br /&gt;
timestamps in the packet, allowing them to be adjusted to eliminate differences&lt;br /&gt;
between the time setting on the local and remote node.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child is optional but recommended.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
A 32-bit integer representing the current UNIX time, or time (NULL).&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /KHL/NH - Neighbouring Hub ==&lt;br /&gt;
&lt;br /&gt;
This child packet represents a neighbouring hub.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
One should be included for each Gnutella2 neighbour hub, with the possible&lt;br /&gt;
exception of the one to which this packet is being sent.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
The node address of the hub. See datatypes for more information.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has several child packet types defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /KHL/NH/GU - GUID&lt;br /&gt;
* /KHL/NH/V - Vendor Code&lt;br /&gt;
* /KHL/NH/LS - Library Statistics&lt;br /&gt;
* /KHL/NH/HS - Hub Status&lt;br /&gt;
&lt;br /&gt;
=== /KHL/NH/GU - GUID ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/NH/GU child packet specifies the globally unique identifier of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
The 16 byte globally unique node identifier of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/NH/V - Vendor Code ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/NH/V child packet specifies the vendor code of the software operating the&lt;br /&gt;
hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
A four byte vendor code.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/NH/LS - Library Statistics ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/NH/LS packet provides information about the content library of the hub&lt;br /&gt;
and its connected leaves.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Two 32-bit integers representing the number of files, and the total KB of available&lt;br /&gt;
content in the hub's own library and the libraries of its connected leaves. The&lt;br /&gt;
payload may grow beyond 8 bytes in the future.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/NH/HS - Hub Status ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/NH/HS packet contains the status of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Two 16-bit integers representing the current leaf count and the maximum leaf count&lt;br /&gt;
respectively. This packet may grow beyond 4 bytes in the future.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /KHL/CH - Cached Hub ==&lt;br /&gt;
&lt;br /&gt;
This child packet represents a hub from the hub cache.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
An arbitrary number of these children should be included, constrained by space and&lt;br /&gt;
the number of available cached hubs. A selection of freshly time stamped but&lt;br /&gt;
previously unknown hubs should be included, and the list should not include hubs in&lt;br /&gt;
the local cluster.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
The node address of the hub, followed by the time this hub was last seen as a 32-bit&lt;br /&gt;
timestamp. The last seen time can be adjusted based on the difference between the&lt;br /&gt;
/KHL/TS timestamp and the local time. Note that the node address is of variable&lt;br /&gt;
length, so it is important to consider the last 4 bytes as the timestamp rather than&lt;br /&gt;
assuming a fixed length node address.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has several child packet types defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /KHL/CH/GU - GUID&lt;br /&gt;
* /KHL/CH/V - Vendor Code&lt;br /&gt;
* /KHL/CH/LS - Library Statistics&lt;br /&gt;
* /KHL/CH/HS - Hub Status&lt;br /&gt;
&lt;br /&gt;
This extra information is considered less relevant for a cached hub because it is&lt;br /&gt;
unlikely to be up to date enough to be useful.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/CH/GU - GUID ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/CH/GU child packet specifies the globally unique identifier of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
The 16 byte globally unique node identifier of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/CH/V - Vendor Code ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/CH/V child packet specifies the vendor code of the software operating the&lt;br /&gt;
hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
A four byte vendor code.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/CH/LS - Library Statistics ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/NH/LS packet provides information about the content library of the hub&lt;br /&gt;
and its connected leaves.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Two 32-bit integers representing the number of files, and the total KB of available&lt;br /&gt;
content in the hub's own library and the libraries of its connected leaves. The&lt;br /&gt;
payload may grow beyond 8 bytes in the future.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/CH/HS - Hub Status ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/CH/HS packet contains the status of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Two 16-bit integers representing the current leaf count and the maximum leaf count&lt;br /&gt;
respectively. This packet may grow beyond 4 bytes in the future.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=HAW&amp;diff=1901</id>
		<title>HAW</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=HAW&amp;diff=1901"/>
		<updated>2005-09-06T01:01:57Z</updated>

		<summary type="html">&lt;p&gt;Spooky: initial version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CRAWLR|&amp;lt;&amp;lt; CRAWLR]] | [[KHL|KHL &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
= /HAW - Hub Advertising Walker =&lt;br /&gt;
&lt;br /&gt;
The HAW packet ...&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
The /HAW packet ... TODO&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
A 16 bit GUID&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The /HAW packet has the following child packets defined:&lt;br /&gt;
&lt;br /&gt;
* /HAW/NA - Network Address&lt;br /&gt;
* /HAW/HS - Hub Status&lt;br /&gt;
* /HAW/V - Vendor Code&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=CRAWLA&amp;diff=893</id>
		<title>CRAWLA</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=CRAWLA&amp;diff=893"/>
		<updated>2005-09-06T00:47:07Z</updated>

		<summary type="html">&lt;p&gt;Spooky: /* Children */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CRAWLR|CRAWLR &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /CRAWLA - Crawler Answer =&lt;br /&gt;
&lt;br /&gt;
The crawl answer packet is the response to a [[CRAWLR|crawl request packet]]. It contains information about the current node for a Gnutella2 crawler.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLA packet ... TODO&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
A /CRAWLA packet should only be received by a crawler in response to a [[CRAWLR|/CRAWLR]] packet, which should use it to gather information about the Gnutella2 network.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLA packet has the following child packets defined:&lt;br /&gt;
&lt;br /&gt;
* /CRAWLA/SELF - Vendor Code and Version&lt;br /&gt;
* /CRAWLA/NA - Network Address&lt;br /&gt;
* /CRAWLA/HS - Hub Status&lt;br /&gt;
* /CRAWLA/NAME - User Nickname&lt;br /&gt;
* /CRAWLA/V - Vendor Code&lt;br /&gt;
* /CRAWLA/CV - Current Version&lt;br /&gt;
* /CRAWLA/HUB - Only present if the host is a hub&lt;br /&gt;
* /CRAWLA/LEAF - Only present if the host is a leaf&lt;br /&gt;
* /CRAWLA/GPS - GPS information&lt;br /&gt;
* /CRAWLA/NH - Neighbouring Hub&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=CRAWLR&amp;diff=895</id>
		<title>CRAWLR</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=CRAWLR&amp;diff=895"/>
		<updated>2005-09-06T00:46:12Z</updated>

		<summary type="html">&lt;p&gt;Spooky: initial version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CRAWLA|&amp;lt;&amp;lt; CRAWLA]] | [[HAW|HAW &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
= /CRAWLR - Crawler Request =&lt;br /&gt;
&lt;br /&gt;
The crawler request packet is sent by a Gnutella2 crawler in order to gather information about the Gnutella2 network.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLR packet ... TODO&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
Upon receiving a /CRAWLR packet a [[CRAWLA|/CAWLA]] packet conating the requested information should be sent.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLR packet has the following child packets defined:&lt;br /&gt;
&lt;br /&gt;
* /CRAWLR/RLEAF - Request leaf information&lt;br /&gt;
* /CRAWLR/RNAME - Request Nickname&lt;br /&gt;
* /CRAWLR/RGPS - Request GPS data&lt;br /&gt;
* /CRAWLR/REXT - Request version information&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=CRAWLA&amp;diff=891</id>
		<title>CRAWLA</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=CRAWLA&amp;diff=891"/>
		<updated>2005-09-06T00:40:06Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CRAWLR|CRAWLR &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /CRAWLA - Crawler Answer =&lt;br /&gt;
&lt;br /&gt;
The crawl answer packet is the response to a [[CRAWLR|crawl request packet]]. It contains information about the current node for a Gnutella2 crawler.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLA packet ... TODO&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
A /CRAWLA packet should only be received by a crawler in response to a [[CRAWLR|/CRAWLR]] packet, which should use it to gather information about the Gnutella2 network.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLA packet has the following child packets defined:&lt;br /&gt;
&lt;br /&gt;
* /CRAWLA/SELF - Vendor Code and Version&lt;br /&gt;
* /CRAWLA/NA - Network Address&lt;br /&gt;
* /CRAWLA/HS - Hub Status&lt;br /&gt;
* /CRAWLA/NAME - User Nickname&lt;br /&gt;
* /CRAWLA/V - Vendor Code&lt;br /&gt;
* /CRAWLA/CV - Current Version&lt;br /&gt;
* /CRAWLA/HUB - Only present if the host is a hub&lt;br /&gt;
* /CRAWLA/LEAF - Only present if the host is a leaf&lt;br /&gt;
* /CRAWLA/GPS - &lt;br /&gt;
* /CRAWLA/NH - Neighbour Host&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=CRAWLA&amp;diff=890</id>
		<title>CRAWLA</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=CRAWLA&amp;diff=890"/>
		<updated>2005-09-06T00:37:50Z</updated>

		<summary type="html">&lt;p&gt;Spooky: /* Sending */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CRAWLR|CRAWLR &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /CRAWLA - Local Node Information =&lt;br /&gt;
&lt;br /&gt;
The crawl answer packet is the response to a [[CRAWLR|crawl request packet]]. It contains information about the current node for a Gnutella2 crawler.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLA packet ... TODO&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
A /CRAWLA packet should only be received by a crawler in response to a [[CRAWLR|/CRAWLR]] packet, which should use it to gather information about the Gnutella2 network.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLA packet has the following child packets defined:&lt;br /&gt;
&lt;br /&gt;
* /CRAWLA/SELF - Vendor Code and Version&lt;br /&gt;
* /CRAWLA/NA - Network Address&lt;br /&gt;
* /CRAWLA/HS - Hub Status&lt;br /&gt;
* /CRAWLA/NAME - User Nickname&lt;br /&gt;
* /CRAWLA/V - Vendor Code&lt;br /&gt;
* /CRAWLA/CV - Current Version&lt;br /&gt;
* /CRAWLA/HUB - Only present if the host is a hub&lt;br /&gt;
* /CRAWLA/LEAF - Only present if the host is a leaf&lt;br /&gt;
* /CRAWLA/GPS - &lt;br /&gt;
* /CRAWLA/NH - Neighbour Host&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=CRAWLA&amp;diff=889</id>
		<title>CRAWLA</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=CRAWLA&amp;diff=889"/>
		<updated>2005-09-06T00:36:24Z</updated>

		<summary type="html">&lt;p&gt;Spooky: initial version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[CRAWLR|CRAWLR &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /CRAWLA - Local Node Information =&lt;br /&gt;
&lt;br /&gt;
The crawl answer packet is the response to a [[CRAWLR|crawl request packet]]. It contains information about the current node for a Gnutella2 crawler.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
The /LNI packet should be sent to a TCP neighbour upon connection, and at regular&lt;br /&gt;
intervals following that if the information within it has changed. A minimum update&lt;br /&gt;
time of one minute is recommended.&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
A /CRAWLA packet should only be received by a crawler in response to a [[CRAWLR|/CRAWLR]] packet, which should use it to gather information about the Gnutella2 network.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The /CRAWLA packet has the following child packets defined:&lt;br /&gt;
&lt;br /&gt;
* /CRAWLA/SELF - Vendor Code and Version&lt;br /&gt;
* /CRAWLA/NA - Network Address&lt;br /&gt;
* /CRAWLA/HS - Hub Status&lt;br /&gt;
* /CRAWLA/NAME - User Nickname&lt;br /&gt;
* /CRAWLA/V - Vendor Code&lt;br /&gt;
* /CRAWLA/CV - Current Version&lt;br /&gt;
* /CRAWLA/HUB - Only present if the host is a hub&lt;br /&gt;
* /CRAWLA/LEAF - Only present if the host is a leaf&lt;br /&gt;
* /CRAWLA/GPS - &lt;br /&gt;
* /CRAWLA/NH - Neighbour Host&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Template:Root_packet_list&amp;diff=2916</id>
		<title>Template:Root packet list</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Template:Root_packet_list&amp;diff=2916"/>
		<updated>2005-09-06T00:15:37Z</updated>

		<summary type="html">&lt;p&gt;Spooky: haw packet added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* /[[CRAWLA]] - Crawler Answer&lt;br /&gt;
* /[[CRAWLR]] - Crawler Request&lt;br /&gt;
* /[[HAW]] - Hub Advertisement Walker&lt;br /&gt;
* /[[KHL]] - Known Hub List&lt;br /&gt;
* /[[LNI]] - Local Node Information&lt;br /&gt;
* /[[PI]] - Ping&lt;br /&gt;
* /[[PO]] - Pong&lt;br /&gt;
* /[[PUSH]] - Push&lt;br /&gt;
* /[[QKA]] - Query Key Acknowledgement&lt;br /&gt;
* /[[QKR]] - Query Key Request&lt;br /&gt;
* /[[Q2]] - Gnutella2 Query&lt;br /&gt;
* /[[QA]] - Query Acknowledgement&lt;br /&gt;
* /[[QH2]] - Gnutella2 Query Hit&lt;br /&gt;
* /[[QHT]] - Query Hash Table&lt;br /&gt;
* /[[UPROC]] - User Profile Challenge&lt;br /&gt;
* /[[UPROD]] - User Profile Delivery&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Template:Root_packet_list&amp;diff=2915</id>
		<title>Template:Root packet list</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Template:Root_packet_list&amp;diff=2915"/>
		<updated>2005-09-06T00:08:23Z</updated>

		<summary type="html">&lt;p&gt;Spooky: crawler packets added to list&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* /[[CRAWLA]] - Crawler Answer&lt;br /&gt;
* /[[CRAWLR]] - Crawler Request&lt;br /&gt;
* /[[KHL]] - Known Hub List&lt;br /&gt;
* /[[LNI]] - Local Node Information&lt;br /&gt;
* /[[PI]] - Ping&lt;br /&gt;
* /[[PO]] - Pong&lt;br /&gt;
* /[[PUSH]] - Push&lt;br /&gt;
* /[[QKA]] - Query Key Acknowledgement&lt;br /&gt;
* /[[QKR]] - Query Key Request&lt;br /&gt;
* /[[Q2]] - Gnutella2 Query&lt;br /&gt;
* /[[QA]] - Query Acknowledgement&lt;br /&gt;
* /[[QH2]] - Gnutella2 Query Hit&lt;br /&gt;
* /[[QHT]] - Query Hash Table&lt;br /&gt;
* /[[UPROC]] - User Profile Challenge&lt;br /&gt;
* /[[UPROD]] - User Profile Delivery&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=QKR&amp;diff=1651</id>
		<title>QKR</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=QKR&amp;diff=1651"/>
		<updated>2005-09-05T23:40:25Z</updated>

		<summary type="html">&lt;p&gt;Spooky: navi&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[QKA|&amp;lt;&amp;lt; QKA]] | [[Q2|Q2 &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /QKR - Query Key Request =&lt;br /&gt;
&lt;br /&gt;
The query key request asks a destination hub to provide a query key that the&lt;br /&gt;
requesting node can use to securely perform queries. This mechanism ensures that&lt;br /&gt;
the network cannot be used to direct unsolicited packets to external hosts.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
A query key request should be sent to a hub via the connectionless transport if a key&lt;br /&gt;
is not already available for that hub for the local node address, or if a previously&lt;br /&gt;
acquired key no longer works or has expired. There is no reason to request a query&lt;br /&gt;
key via a TCP link.&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
Upon receiving a query key request, a hub should respond with a query key answer&lt;br /&gt;
(/[[QKA]]) packet if it is willing to supply a query key. The answer packet should be&lt;br /&gt;
dispatched to the return address indicated in the request packet only, and the&lt;br /&gt;
allocated key should be locked to that address.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The QKR packet has one child packet defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /QKR/RNA&lt;br /&gt;
&lt;br /&gt;
== /QKR/RNA - Requesting Node Address ==&lt;br /&gt;
&lt;br /&gt;
A query key may be requested for a node address other than that of the sender, for&lt;br /&gt;
example when a UDP-firewalled leaf node wishes to acquire a query key for a remote&lt;br /&gt;
hub that it will route through a locally connected hub. In this case it must request a&lt;br /&gt;
query key for the node address of a connected hub.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child is required to ensure that the sender knows its address.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
The network address of the requesting node. See [[Datatypes]] for more information.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=QKA&amp;diff=1652</id>
		<title>QKA</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=QKA&amp;diff=1652"/>
		<updated>2005-09-05T23:39:24Z</updated>

		<summary type="html">&lt;p&gt;Spooky: navi&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[PUSH|&amp;lt;&amp;lt; PUSH]] | [[QKR|QKR &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /QKA - Query Key Answer =&lt;br /&gt;
&lt;br /&gt;
The query key answer packet is sent in response to a [[QKR|query key request]] or in the&lt;br /&gt;
event that a query with an incorrect or omitted query key is received. It advises the&lt;br /&gt;
receiver of the correct query key to be used when contacting the sending hub to&lt;br /&gt;
execute a remote cluster query.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
The query key answer packet should be sent by a hub when a query key has been&lt;br /&gt;
requested. It should contain a key unique to the local hub and the requesting node&lt;br /&gt;
address supplied in the request, and should be sent to that address only.&lt;br /&gt;
The query key answer packet may also be sent upon receiving a query with a&lt;br /&gt;
missing or invalid query key. In this case no query should be performed.&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
Upon receiving a query key answer packet, the supplied query key should be stored&lt;br /&gt;
for later use. If the answer packet contains a sending node address (/QKA/SNA) child&lt;br /&gt;
which does not match the local node address, it may be forwarded to a connected&lt;br /&gt;
leaf node via TCP with a matching address. In the forwarding case, a query node&lt;br /&gt;
address (/QKA/QNA) child is added prior to forwarding to retain the remote (queried)&lt;br /&gt;
hub's address.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The QKA packet has three child packets defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /QKA/QK&lt;br /&gt;
* /QKA/SNA&lt;br /&gt;
* /QKA/QNA&lt;br /&gt;
&lt;br /&gt;
== /QKA/QK - Query Key ==&lt;br /&gt;
&lt;br /&gt;
The /QKA/QK child contains the query key that was requested.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child is required if a key is being issued. Sending a /QKA without a /QKA/QK&lt;br /&gt;
indicates that the hub does not wish to authorise the requesting node to query it or&lt;br /&gt;
its cluster.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
A 32-bit query key which is unique to the hub and the sending node address.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /QKA/SNA - Sending Node Address ==&lt;br /&gt;
&lt;br /&gt;
This child specifies the node address for which the key has been issued. This is not&lt;br /&gt;
necessarily the node that physically transmitted the key request or the query.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child is required.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
The node address (with port number optional) of the node which requested the&lt;br /&gt;
query key.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /QKA/QNA - Queried Node Address ==&lt;br /&gt;
&lt;br /&gt;
If this query key answer packet has been forwarded to a firewalled leaf from a&lt;br /&gt;
connected hub, a /QKA/QNA child will have been added to indicate the address of&lt;br /&gt;
the remote hub.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child should be added by a hub when relaying a received query key answer on&lt;br /&gt;
to a leaf via TCP.&lt;br /&gt;
&lt;br /&gt;
=== Receiving ===&lt;br /&gt;
&lt;br /&gt;
If this child is present, the query key answer should be treated as if it originated&lt;br /&gt;
from the stored address rather than the TCP neighbour.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
The node address (with port number optional) of the remote hub.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=PUSH&amp;diff=1646</id>
		<title>PUSH</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=PUSH&amp;diff=1646"/>
		<updated>2005-09-05T23:38:34Z</updated>

		<summary type="html">&lt;p&gt;Spooky: navi&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[PO|&amp;lt;&amp;lt; PO]] | [[QKA|QKA &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /PUSH =&lt;br /&gt;
&lt;br /&gt;
The push packet is used to request that a node initiate a TCP connection to a&lt;br /&gt;
specified node address. It is useful where the receiving node is unable to accept TCP&lt;br /&gt;
connections naturally.&lt;br /&gt;
&lt;br /&gt;
For more information about when to use PUSH packets: [[Node_Route_Cache_and_Addressed_Packet_Forwarding#Reverse_Connection_.28Push.29_Requests|Reverse Connection (Push) Requests]]&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
An addressed /PUSH packet should be sent to a hub with direct or proxy access to&lt;br /&gt;
the destination leaf node. It can be sent directly by a hub to one of its leaves without&lt;br /&gt;
the need for addressing.&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
Upon receiving a /PUSH packet, the local node should initiate a TCP connection to&lt;br /&gt;
the elected node address and issue a &amp;quot;push handshake&amp;quot;, documented below.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
The network address of the node to contact, including of course the port number.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time, however it is often used with&lt;br /&gt;
the generic addressing child packet &amp;quot;/?/TO&amp;quot; to indicate that it should be forwarded to&lt;br /&gt;
a destination.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=PO&amp;diff=1641</id>
		<title>PO</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=PO&amp;diff=1641"/>
		<updated>2005-09-05T23:37:53Z</updated>

		<summary type="html">&lt;p&gt;Spooky: navi&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[PI|&amp;lt;&amp;lt; PI]] | [[PUSH|PUSH &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /PO - Pong =&lt;br /&gt;
&lt;br /&gt;
The pong packet serves as a reply to a one or two hop ping (/PI) packet. It indicates&lt;br /&gt;
that the pinged node received and processed the ping, and in the case of UDP, that&lt;br /&gt;
the local node was able to received UDP from the sender.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
Send a pong packet in response to a direct or relayed ping request.&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
No action is required in response to a pong packet. If the packet contains a&lt;br /&gt;
/PO/RELAY marker child, test the sender's network address against the list of active&lt;br /&gt;
TCP connections and if there is no match, consider the local node able to receive&lt;br /&gt;
UDP.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The ping packet has one child packet type defined at the current time:&lt;br /&gt;
* /PO/RELAY&lt;br /&gt;
&lt;br /&gt;
== /PO/RELAY - Relayed Pong Marker ==&lt;br /&gt;
&lt;br /&gt;
If a /PO packet contains a /PO/RELAY child marker, the pong was sent in response to&lt;br /&gt;
a relayed ping.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
The /PO/RELAY child marker should be added to a /PO if the pong is being sent in&lt;br /&gt;
response to a relayed ping.&lt;br /&gt;
&lt;br /&gt;
=== Receiving ===&lt;br /&gt;
&lt;br /&gt;
No specific action is required for a relayed pong.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=PI&amp;diff=1639</id>
		<title>PI</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=PI&amp;diff=1639"/>
		<updated>2005-09-05T23:37:02Z</updated>

		<summary type="html">&lt;p&gt;Spooky: nav&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[LNI|&amp;lt;&amp;lt; LNI]] | [[PO|PO &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /PI - Ping =&lt;br /&gt;
&lt;br /&gt;
The ping packet is used to verify the presence of the addressed node, testing that:&lt;br /&gt;
&lt;br /&gt;
* The destination node is online&lt;br /&gt;
* The destination node can receive the transmission&lt;br /&gt;
* The local node can receive the reply&lt;br /&gt;
&lt;br /&gt;
Aside from performing a &amp;quot;keep-alive&amp;quot; function on TCP links, pings can be used to&lt;br /&gt;
solicit inbound UDP datagrams to test the local node's ability to receive UDP. Many&lt;br /&gt;
NAT systems will route UDP traffic from nodes with whom a persistent TCP stream&lt;br /&gt;
has been established, so it is necessary to test inbound traffic from nodes with which&lt;br /&gt;
there is no TCP connection. This is achieved by sending a ping with a /PI/UDP packet&lt;br /&gt;
to a connected hub via TCP, which will forward the request to its neighbours who&lt;br /&gt;
then reply to the originator via UDP.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
On a TCP stream connection, if one end has not received a valid packet from the&lt;br /&gt;
other after an internally determined period of time, it has the option of sending a&lt;br /&gt;
keep-alive ping to verify the other end's presence. If a pong is not received in a&lt;br /&gt;
timeout period it may close the connection.&lt;br /&gt;
&lt;br /&gt;
If a node needs to verify that it is able to receive UDP datagrams from nodes with&lt;br /&gt;
which it does not have a TCP stream connection, it may send a ping packet with a&lt;br /&gt;
/PI/UDP child packet. If it then receives a /PO (pong) packet with a /PO/RELAY child&lt;br /&gt;
tag and there is no TCP connection to the sender, it can assume it is able to receive&lt;br /&gt;
UDP.&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
Upon receiving a keep-alive ping, a node should respond with a keep-alive pong&lt;br /&gt;
immediately.&lt;br /&gt;
&lt;br /&gt;
If the ping was received from a TCP neighbour and contains a /PI/UDP child packet,&lt;br /&gt;
but no /PI/RELAY tag, a /PI/RELAY tag should be added and the packet forwarded to&lt;br /&gt;
all neighbouring hubs. If a /PI/RELAY tag was present, the node should send a /PO&lt;br /&gt;
packet with a /PO/RELAY tag to the UDP address identified in the /PI/UDP child&lt;br /&gt;
packet.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The ping packet has two child packets defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /PI/RELAY&lt;br /&gt;
* /PI/UDP&lt;br /&gt;
&lt;br /&gt;
== /PI/RELAY - Relayed Ping Marker ==&lt;br /&gt;
&lt;br /&gt;
If a /PI packet contains a /PI/RELAY child marker, the ping has been relayed for a&lt;br /&gt;
third party. The receiving node should reply to the original party rather than the&lt;br /&gt;
sender. The original party should be contacted via UDP with the address contained in&lt;br /&gt;
the /PI/UDP child. If the /PI/UDP child is absent, the packet is invalid.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
The /PI/RELAY child should be added to a /PI packet when relaying a ping to hub&lt;br /&gt;
neighbours at the request of a leaf.&lt;br /&gt;
&lt;br /&gt;
=== Receiving ===&lt;br /&gt;
&lt;br /&gt;
Upon receiving a /PI packet with a /PI/RELAY tag, a /PO (pong) packet should be&lt;br /&gt;
sent via UDP to the node identified in the /PI/UDP child.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== /PI/UDP - Ping Response Address ==&lt;br /&gt;
&lt;br /&gt;
The /PI/UDP child packet specifies the return address for a relay able or relayed&lt;br /&gt;
ping.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
Add a /PI/UDP child packet to a /PI packet to request a relayed &amp;quot;two hop&amp;quot; ping.&lt;br /&gt;
&lt;br /&gt;
=== Receiving ===&lt;br /&gt;
&lt;br /&gt;
The /PI/UDP child packet indicates that a /PI packet needs to be relayed.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
The /PI/UDP packet contains an endpoint address.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Main_Page&amp;diff=867</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Main_Page&amp;diff=867"/>
		<updated>2005-07-04T00:30:53Z</updated>

		<summary type="html">&lt;p&gt;Spooky: link changed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;table width=&amp;quot;100%&amp;quot; &amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
== Gnutella2 Developer Network ==&lt;br /&gt;
Welcome to the Gnutella2 Developer Network.&lt;br /&gt;
The Gnutella2 Developer Network (or G2DN) is a convenient central location for discussing, developing and documenting all aspects of Gnutella2. Like the Gnutella2 platform itself, this website is designed to evolve through community support and participation. Everyone is free to contribute discussion, proposal documents, developer resources or any other relevant material.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Although the G2DN is primarily geared toward developers and technical enthusiasts, users of Gnutella2-enabled software are also welcome to participate. Those who are new to Gnutella2 may wish to check out some of the [[Gnutella2-powered software]].&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td width=&amp;quot;20px&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;right&amp;quot; valign=&amp;quot;bottom&amp;quot; width=&amp;quot;200px&amp;quot;&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==News==&lt;br /&gt;
* ''10th, April, 2005'' - '''Gnutella2 website re-opened'''&lt;br /&gt;
&amp;lt;p&amp;gt;After server problems we're proud to re-launch the Gnutella2 website. It is now based on MediaWiki (like Wikipedia). The forums are gone, but we now have a [[mailing list]] for Gnutella2 related discussion. Feel free to contribute to the wiki after reading [[Gnutella2:Community Portal]] to learn about editing policy.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Mailing List==&lt;br /&gt;
To allow communication among developers of Gnutella2 clients, there exists a [[mailing list]]. You can access it too via regular news reader at the news-to-mail gateway [http://www.gmane.org Gmane] (list page [http://dir.gmane.org/gmane.network.gnutella2.devel here]).&lt;br /&gt;
&lt;br /&gt;
== The Gnutella 2 Network==&lt;br /&gt;
# [[Gnutella2|What is Gnutella2]]&lt;br /&gt;
# [[Gnutella2 Standard]]&lt;br /&gt;
# [[Network Architecture]]&lt;br /&gt;
# [[Node Types and Responsibilities]]&lt;br /&gt;
# [[Background|Background / Archive]]&lt;br /&gt;
&lt;br /&gt;
== The Protocol==&lt;br /&gt;
# [[TCP Stream Connection and Handshaking]]&lt;br /&gt;
# [[UDP Transceiver]]&lt;br /&gt;
# [[Packet Structure]]&lt;br /&gt;
# [[Datatypes]]&lt;br /&gt;
# [[Basic Network Maintenance]]&lt;br /&gt;
# [[Known Hub Cache and Hub Cluster Cache]]&lt;br /&gt;
# [[Node Route Cache and Addressed Packet Forwarding]]&lt;br /&gt;
# [[Query Hash Tables]]&lt;br /&gt;
# [[Object Search Mechanism]]&lt;br /&gt;
# [[Search Security]]&lt;br /&gt;
# [[Search Description]]&lt;br /&gt;
# [[Search Acknowledgement]]&lt;br /&gt;
# [[Search Results]]&lt;br /&gt;
# [[Simple Query Language and Metadata]]&lt;br /&gt;
# [[Server for Uploading]]&lt;br /&gt;
# [[Client for Downloading]]&lt;br /&gt;
# [[User Profile Challenge and Delivery]]&lt;br /&gt;
&lt;br /&gt;
== Root Packets ==&lt;br /&gt;
{{Root packets}}&lt;br /&gt;
&lt;br /&gt;
== Proposals==&lt;br /&gt;
* [[Active Source Exchange]] (ASE) by Kevin O'Toole&lt;br /&gt;
&lt;br /&gt;
*HTTPCache and G3Net proposal (Open for [[User_talk:F5inet|Discussion]])&lt;br /&gt;
&lt;br /&gt;
== Additional Information==&lt;br /&gt;
Since Gnutella2 somehow evolved from the original Gnutella protocol you might find the following links useful:&lt;br /&gt;
* [http://www.the-gdf.org The GDF Wiki]&lt;br /&gt;
* [http://groups.yahoo.com/group/the_gdf/ Gnutella Developer forum]&lt;br /&gt;
* [http://rfc-gnutella.sourceforge.net/ RFC Gnutella]&lt;br /&gt;
* [http://draketo.de/inhalt/krude-ideen/gnufu_en.html Gnutella for Users (GnuFU)]&lt;br /&gt;
* [http://crawler.instantnetworks.net/ Gnutella2 Crawler]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Mailing_list&amp;diff=1679</id>
		<title>Mailing list</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Mailing_list&amp;diff=1679"/>
		<updated>2005-05-20T21:15:53Z</updated>

		<summary type="html">&lt;p&gt;Spooky: Added Gmane info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==G2DN Mailing List==&lt;br /&gt;
&lt;br /&gt;
This is the mailing list for communication between Gnutella2 developers and other interested people. This is not for help on how to use Gnutella2 applications.&lt;br /&gt;
&lt;br /&gt;
'''Subscribe''' to the list by sending an email to g2-dev-request@gnutella2.com with 'subscribe' in the subject line.  Alternatively subscribe here: http://www.gnutella2.com/mailman/listinfo/g2-dev_gnutella2.com&lt;br /&gt;
&lt;br /&gt;
To post on the mailinglist send an email to g2-dev@gnutella2.com&lt;br /&gt;
&lt;br /&gt;
Message archives: http://www.gnutella2.com/pipermail/g2-dev_gnutella2.com/&lt;br /&gt;
&lt;br /&gt;
===Gmane===&lt;br /&gt;
The list can also be accessed through the news-to-mail gateway [http://www.gmane.org Gmane]:&amp;lt;br&amp;gt;&lt;br /&gt;
[http://dir.gmane.org/gmane.network.gnutella2.devel G2DN at Gmane]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Talk:Gnutella2_Standard&amp;diff=837</id>
		<title>Talk:Gnutella2 Standard</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Talk:Gnutella2_Standard&amp;diff=837"/>
		<updated>2005-05-13T16:31:20Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;May 12, 2005: &lt;br /&gt;
&lt;br /&gt;
The article says:&lt;br /&gt;
&lt;br /&gt;
All applications making use of Gnutella2 technology for any application class MUST IMPLEMENT the following core features:&lt;br /&gt;
&lt;br /&gt;
 Bidirectional TCP stream connections (stream compression OPTIONAL)&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
 Gnutella2 Standard for File Sharing&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
I don't think every gnutella2 application ought to necessarily implement the Gnutella2 Standard for file sharing. Only G2 filesharing applications must implement the Gnutella2 Standard for file sharing. The way it is worded, every G2 application must also be a file sharing app.&lt;br /&gt;
&lt;br /&gt;
Perhaps someone could edit this page to fix this apparent mistake.&lt;br /&gt;
&lt;br /&gt;
Hm you are probably right. So feel free to edit the page yourself. That's how a wiki works.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=QA&amp;diff=1657</id>
		<title>QA</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=QA&amp;diff=1657"/>
		<updated>2005-04-05T19:11:39Z</updated>

		<summary type="html">&lt;p&gt;Spooky: typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= /QA - Query Acknowledgement =&lt;br /&gt;
&lt;br /&gt;
The query acknowledgement packet is used to inform a search client that a target&lt;br /&gt;
hub has received its [[Q2|query]] and is processing it. It also provides information for the&lt;br /&gt;
search client's hub cache, expanding knowledge of the network and ensuring hubs&lt;br /&gt;
are not searched more than once in a given query.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
Send a query acknowledgement packet only when operating in hub mode, and only&lt;br /&gt;
when the query was not received from a hub via a TCP link. Acknowledgements&lt;br /&gt;
should only be sent after verifying the query key authentication.&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
When a query acknowledgement is received, update the local hub cache as&lt;br /&gt;
necessary:&lt;br /&gt;
&lt;br /&gt;
* Hubs which have been searched should not be sent this query again&lt;br /&gt;
* New suggested hubs should be added and refreshed&lt;br /&gt;
* Any &amp;quot;back-off&amp;quot; time should be recorded and honoured.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
A GUID identifying the query being acknowledged.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
This packet has several child packet types defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /QA/TS - Timestamp&lt;br /&gt;
* /QA/D - &amp;quot;Done&amp;quot; or Completed Hub&lt;br /&gt;
* /QA/S - &amp;quot;Search&amp;quot; or New Hub&lt;br /&gt;
* /QA/RA - Retry After&lt;br /&gt;
* /QA/FR - From Address&lt;br /&gt;
&lt;br /&gt;
== /QA/TS - Timestamp ==&lt;br /&gt;
&lt;br /&gt;
The /QA/TS child provides a timestamp representing the current universal time at the&lt;br /&gt;
sending node. This can be used as a reference when considering other timestamps in&lt;br /&gt;
the packet, allowing them to be adjusted to eliminate differences between the time&lt;br /&gt;
setting on the local and remote node.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child is optional but recommended.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
A 32-bit integer representing the current UNIX time, or time(NULL).&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /QA/D - Done Hub ==&lt;br /&gt;
&lt;br /&gt;
References a hub which has now been queried, and should not be queried again.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
Send a /QA/D child for the local hub and each neighbouring hub, whether or not the&lt;br /&gt;
hub has actually forwarded the query. If a hub has not forwarded the query, it was&lt;br /&gt;
still effectively searched as the QHT indicated it could not field a matching object.&lt;br /&gt;
&lt;br /&gt;
=== Receiving ===&lt;br /&gt;
&lt;br /&gt;
Upon receiving a /QA/D child, add the hub to the cache, freshen its timestamp and&lt;br /&gt;
mark it as queried in this search. Do not query this node again for several minutes.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
A network/node address followed by a 16-bit leaf count.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /QA/S - Search Hub ==&lt;br /&gt;
&lt;br /&gt;
References a hub which was not searched in this operation, but could be searched&lt;br /&gt;
later if it has not already been touched.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
Send a /QA/S child for every unique hub in the local hub cluster which is not a direct&lt;br /&gt;
neighbour. Optionally select some recent cached hubs and send /QA/S children for&lt;br /&gt;
them also, to make up at least 10 in total.&lt;br /&gt;
&lt;br /&gt;
=== Receiving ===&lt;br /&gt;
&lt;br /&gt;
Upon receiving a /QA/S child, add the hub to the cache and/or freshen its&lt;br /&gt;
timestamp.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
A network/node address, optionally followed by a 32-bit last-seen timestamp. This&lt;br /&gt;
makes detecting the address family slightly harder, but the compactness is&lt;br /&gt;
worthwhile. Timestamps are omitted for hubs in the local hub cluster, which should&lt;br /&gt;
make up the majority.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /QA/RA - Retry After ==&lt;br /&gt;
&lt;br /&gt;
Advises the search client that the hub does not wish to be contacted again for a&lt;br /&gt;
specified period of time. Queries earlier than this time may result in a longer-term&lt;br /&gt;
ban.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
Send this child, with or without executing the search if the hub's resources are&lt;br /&gt;
becoming saturated. It provides an indirect means of flow control.&lt;br /&gt;
&lt;br /&gt;
=== Receiving ===&lt;br /&gt;
&lt;br /&gt;
Upon receiving a /QA/RA child, record the retry after interval and do not send any&lt;br /&gt;
requests to the hub until the period has expired.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
A 16 bit or 32 bit integer specifying the delay in seconds until the hub may be&lt;br /&gt;
contacted again.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /QA/FR - From Address ==&lt;br /&gt;
&lt;br /&gt;
This child is used when a query acknowledgement is forwarded from a proxy hub to&lt;br /&gt;
a firewalled leaf node. It advises the leaf of the original sender.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
When a hub receives a /QA packet for a search originated by one of its leaves, it&lt;br /&gt;
should forward the /QA to the appropriate leaf after adding a /QA/FR child with the&lt;br /&gt;
remote hub's network address.&lt;br /&gt;
&lt;br /&gt;
=== Receiving ===&lt;br /&gt;
&lt;br /&gt;
If this child is present and the /QA packet was received via TCP from a local hub, the&lt;br /&gt;
node address within should be used as the remote hub's node address. This&lt;br /&gt;
information is often reflected in the first /QA/D child, however this is not always&lt;br /&gt;
present.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
A network address which may omit the port number.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Node_Route_Cache_and_Addressed_Packet_Forwarding&amp;diff=1645</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=1645"/>
		<updated>2005-04-05T18:39:07Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Known Hub Cache and Hub Cluster Cache|&amp;lt;&amp;lt; Known Hub Cache and Hub Cluster Cache]] | [[Query Hash Tables|Query Hash Tables &amp;gt;&amp;gt;]] | [[Main_Page|Main Page]]&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&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>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Known_Hub_Cache_and_Hub_Cluster_Cache&amp;diff=1644</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=1644"/>
		<updated>2005-04-05T18:35:12Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Basic Network Maintenance|&amp;lt;&amp;lt; Basic Network Maintenance]] | [[Node Route Cache and Addressed Packet Forwarding|Node Route Cache and Addressed Packet Forwarding &amp;gt;&amp;gt;]] | [[Main_Page|Main Page]]&lt;br /&gt;
&lt;br /&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>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Search_Description&amp;diff=1653</id>
		<title>Search Description</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Search_Description&amp;diff=1653"/>
		<updated>2005-04-05T18:30:49Z</updated>

		<summary type="html">&lt;p&gt;Spooky: Query throttle chapter added,s hould there be a detailed description of how a search works on this page ?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 object search mechanism defines a powerful query descriptor capable&lt;br /&gt;
of specifying a number of different extensible search criteria, and requesting a subset&lt;br /&gt;
of information about matching objects.&lt;br /&gt;
&lt;br /&gt;
/[[Q2]] - Gnutella2 Query&lt;br /&gt;
&lt;br /&gt;
== Query Throttle ==&lt;br /&gt;
Querying the Gnutella2 network can lead to '''a lot''' of results, putting a resource strain on both the network as a whole nad the querying party itself. Therfore a client SHOULD NOT send any more queries after he has received about 100 results. The client should also not send too many query packets at the same time&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Active_Source_Exchange&amp;diff=821</id>
		<title>Active Source Exchange</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Active_Source_Exchange&amp;diff=821"/>
		<updated>2005-04-05T18:05:16Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Active Source Exchange (ASE) 1.0==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; &amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;Written By: Kevin O'Toole&amp;lt;br&amp;gt;&lt;br /&gt;
kevo@napjunk.net&amp;lt;br&amp;gt;&lt;br /&gt;
Shareaza Alpha Team&amp;lt;br&amp;gt;&lt;br /&gt;
2003.06.14&lt;br /&gt;
&lt;br /&gt;
Edited By: Jonathan C. Nilson&amp;lt;br&amp;gt;&lt;br /&gt;
JCNilson@myrealbox.com&amp;lt;br&amp;gt;&lt;br /&gt;
Shareaza Alpha Team&amp;lt;br&amp;gt;&lt;br /&gt;
2003.06.16&amp;lt;/small&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;__TOC__&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Status===&lt;br /&gt;
This proosal is currently not implemented by any client.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
This proposal addresses the current flaws in the alternate source mesh by not passing on sources that are &amp;quot;old&amp;quot; and client identification for whom to receive sources from. This does not eliminate alternate sources but should make the current system better because it will help keep the mesh (exchange) of sources clean of dead hosts. The proposal has the added benefit of reducing the effects of a Gnutella-style Denial-of-Service attack by reducing the number of bad sources a Shareaza node has, thus keeping that Shareaza node from pestering as many dead sources.&lt;br /&gt;
&lt;br /&gt;
===Why is it needed?===&lt;br /&gt;
ASE removes the need to requery frequently to gather a list of new sources. By sharing only current sources, users will not ...&lt;br /&gt;
&lt;br /&gt;
* get flooded with more dead hosts than live ones&lt;br /&gt;
* receive connection attempts for a long time after&lt;br /&gt;
* have to clean out a long list of bad hosts&lt;br /&gt;
* expericence hangs in the client as frequently&lt;br /&gt;
* attempt as many connections on a random port/dynamic IP user&lt;br /&gt;
* participte unwittingly in a DoS attack on another user&lt;br /&gt;
* requery the network as frequently&lt;br /&gt;
* pass a firewalled source to a firewalled client&lt;br /&gt;
&lt;br /&gt;
There are still problems ASE does address but cannot completely solve, which include ...&lt;br /&gt;
&lt;br /&gt;
* hostile clients passing on fake or dead hosts&lt;br /&gt;
* hostile clients passing on expired sources&lt;br /&gt;
&lt;br /&gt;
===What's different?===&lt;br /&gt;
ASE changes the way a client chooses which alternate sources to pass and how long each will be active. In effect, a complying client would pass on only active sources in the mesh, each with an expiry time which should be between 10 and 15 minutes. Active sources are defined as sources which have successfully been Queued or Uploading at some time in the last expiry time block (10~15 minutes). This timeout is critical. If clients simply maintain a list, the dead hosts will take longer to populate the ASE, but will still eventually spread and the same problems will occur.&lt;br /&gt;
&lt;br /&gt;
To avoid this fiasco, a client in the ASE passes the address and the timeout (at its current value) to the recipient. This timeout is only reset if the address is successfully contacted and Queued or Uploading before the timeout value expires. Therefore, unless a client sees the source in a successful queue or upload, the address will expire (no matter how many clients have received the source) at the same time. If one client does reset the expiry counter, only sources which receive the source in the ASE subsequently will still have the source. No messages are sent back to clients who have an entry that is about to expire.&lt;br /&gt;
&lt;br /&gt;
If a client wishes to maintain a list of sources that have expired from the ASE, these sources shall not be passed on to subsequent hosts, with or without a timeout. At this point, the sources shall remain knowlegable to the local host alone.&lt;br /&gt;
&lt;br /&gt;
===Firewalls===&lt;br /&gt;
To avoid the propogation of firewalled sources to firewalled clients, each source shall have a header identification indicating the source as a firewalled client which would be sent with the address and timeout. The uploader sends any sources to normal clients, while push sources are not sent to firewalled clients. IANA Reserved IP ranges will not be passed along.&lt;br /&gt;
&lt;br /&gt;
===Security===&lt;br /&gt;
If every client played by these rules, security would be no problem, unfortunately we have to plan for the contingency that we may have hostile, buggy, or poorly-programmed clients. Keeping this system secure would perhaps be a more difficult task than implementing it. Options for achieving this would be either client identification (which can easily be spoofed) or client-to-client authentication. Without client identification or authentication, users run the same risks involved in the alternate-source mesh now.&lt;br /&gt;
&lt;br /&gt;
With client identification security, a user would only receive hosts from chosen vendors (filtered by reported user-agent strings) but still send hosts to any client. This would be a simple solution to the problem if everyone obeyed the rules. Unfortunately, hostile clients such as Qtrax change their user-agent identification to match that of their downloader, which would make the system useless against such clients (fortunately, few exist).&lt;br /&gt;
&lt;br /&gt;
A more complex (perhaps neglible) solution would be client-to-client authentication. Although this should completely solve the problem, it would require a large amount of work for minimal gain, and some valuable alternate sources from unsupporting clients would be lost. This authentication method would, by definition, be closed to only trusted clients, which also defeats the spirit of the Gnutella community. While it solves some problems very well, this course of action is not recommended.&lt;br /&gt;
&lt;br /&gt;
===Scenario===&lt;br /&gt;
To properly illustrate this new system, consider the following scenario. We will assume for the sake of illustration that the expiry threshold is at 15 minutes.&lt;br /&gt;
&lt;br /&gt;
ClientA, ClientB, and Client C all support ASE in its current form. ClientA and ClientB are both downloading File1. Client A knows of the following sources for File1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;111.111.111.1 (Queued 3 of 10 Now) &lt;br /&gt;
111.111.111.2 (Downloading Now)&lt;br /&gt;
111.111.111.3 (Queued 10 minutes ago)&lt;br /&gt;
111.111.111.5 (Downloading Now)&lt;br /&gt;
192.168.0.1 (Push) (Never contacted)&lt;br /&gt;
0.0.0.0 (Push) (Downloaded 5 minutes ago)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ClientB knows of the following sources for File1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;222.222.222.4 (Queued 20 minutes ago)&lt;br /&gt;
ClientA (Never contacted)&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As ClientB contacts ClientA for the file in question, it refuses to transmit the single known source it has because that source has expired from the ASE. While ClientB may choose to keep that source for its own use, it will not transmit that source to other clients, with or without an expiry timeout.&lt;br /&gt;
&lt;br /&gt;
When ClientA returns the handshake, it transmits a list of ASE sources to ClientB:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;111.111.111.1; Timeout=15m&lt;br /&gt;
111.111.111.2; Timeout=15m&lt;br /&gt;
111.111.111.3; Timeout=5m&lt;br /&gt;
111.111.111.5; Timeout=15m; Push&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since 0.0.0.0 is an IANA Private Range, the address is not passed to ClientB, although it is a valid source with a timeout at 10m. 192.168.0.1 is not passed because it has never been contacted.&lt;br /&gt;
&lt;br /&gt;
After ClientB receives this list of sources and is sent a Busy reply by ClientA, ClientB reattempts a connection with 222.222.222.4. This connection results in a successful download. One minute has passed since the ASE list from ClientA was received by ClientB.&lt;br /&gt;
&lt;br /&gt;
ClientC is firewalled, and after searching and finding ClientB as a source for File1, it attempts a connection. Since it has no sources, none are passed to ClientB, however, ClientB passes the same list of known sources to ClientC as ClientA did to ClientB. ClientB also adds its own experience by transimtting 222.222.222.4 because that source is now active and omiting 111.111.111.5 because that is a firewalled source and ClientC is firewalled, so the final list transmitted from ClientB to ClientC is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;111.111.111.1; Timeout=14m&lt;br /&gt;
111.111.111.2; Timeout=14m&lt;br /&gt;
111.111.111.3; Timeout=4m&lt;br /&gt;
222.222.222.4; Timeout=15m&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please note that Timeout values are listed in minutes for the sake of human understanding and will probably be coded in seconds instead.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
While this does not solve every problem of the current alternate source mesh, it would be beneficial for anyone who currently uses this system. ASE offers a simple solution to the problems with the alternate source mesh. If implemented on a wide-scale, it could reduce traffic substantially and increase file transfer efficiency tenfold.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Main_Page&amp;diff=101</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Main_Page&amp;diff=101"/>
		<updated>2005-04-05T18:02:51Z</updated>

		<summary type="html">&lt;p&gt;Spooky: News added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;table width=&amp;quot;100%&amp;quot; &amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
== Gnutella2 Developer Network ==&lt;br /&gt;
Welcome to the Gnutella2 Developer Network&lt;br /&gt;
The Gnutella2 Developers' Network (or G2DN) is a convenient central location for discussing, developing and documenting all aspects of Gnutella2. Like the Gnutella2 platform itself, this website is designed to evolve through community support and participation. Everyone is free to contibute discussion, proposal documents, developer resources or any other relevant material.&lt;br /&gt;
&lt;br /&gt;
Although the G2DN is primarily geared toward developers and technical enthusiests, users of Gnutella2-enabled software are also welcome to participate. Those who are new to Gnutella2 may wish to check out some of the [[Gnutella2-powered software]].&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td width=&amp;quot;20px&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align=&amp;quot;right&amp;quot; valign=&amp;quot;bottom&amp;quot; width=&amp;quot;200px&amp;quot;&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==News==&lt;br /&gt;
* ''5th, April, 2005'' - '''Gnutella2 website re-opened'''&amp;lt;br&amp;gt;After server problems we're proud to re-launch the Gnutella2 website. It is now based on MediaWiki (like Wikipedia). The forums are gone, but we now have a [[mailing list]] for Gnutella2 related discussion. Feel free to contribute to the wiki.&lt;br /&gt;
&lt;br /&gt;
==Mailing List==&lt;br /&gt;
To allow communication among developers of Gnutella2 clients, there exists a [[mailing list]]&lt;br /&gt;
&lt;br /&gt;
== The Gnutella 2 Network==&lt;br /&gt;
# [[Gnutella2|What is Gnutella2]]&lt;br /&gt;
# [[Gnutella2 Standard]]&lt;br /&gt;
# [[Network Architecture]]&lt;br /&gt;
# [[Node Types and Responsibilities]]&lt;br /&gt;
# [[Background|Background / Archive]]&lt;br /&gt;
&lt;br /&gt;
== The Protocol==&lt;br /&gt;
# [[TCP Stream Connection and Handshaking]]&lt;br /&gt;
# [[UDP Transceiver]]&lt;br /&gt;
# [[Packet Structure]]&lt;br /&gt;
# [[Datatypes]]&lt;br /&gt;
# [[Basic Network Maintenance]]&lt;br /&gt;
# [[Known Hub Cache and Hub Cluster Cache]]&lt;br /&gt;
# [[Node Route Cache and Addressed Packet Forwarding]]&lt;br /&gt;
# [[Query Hash Tables]]&lt;br /&gt;
# [[Object Search Mechanism]]&lt;br /&gt;
# [[Search Security]]&lt;br /&gt;
# [[Search Description]]&lt;br /&gt;
# [[Search Acknowledgement]]&lt;br /&gt;
# [[Search Results]]&lt;br /&gt;
# [[Simple Query Language and Metadata]]&lt;br /&gt;
# [[Server for Uploading]]&lt;br /&gt;
# [[Client for Downloading]]&lt;br /&gt;
# [[User Profile Challenge and Delivery]]&lt;br /&gt;
&lt;br /&gt;
== Root Packets ==&lt;br /&gt;
{{Root packets}}&lt;br /&gt;
&lt;br /&gt;
== Proposals==&lt;br /&gt;
* [[Active Source Exchange]] (ASE) by Kevin O'Toole&lt;br /&gt;
&lt;br /&gt;
== Additional Information==&lt;br /&gt;
Since Gnutella2 somehow evolved from the original Gnutella protocol you might find the following links useful:&lt;br /&gt;
* [http://www.the-gdf.org The GDF Wiki]&lt;br /&gt;
* [http://groups.yahoo.com/group/the_gdf/ Gnutella Developer forum]&lt;br /&gt;
* [http://rfc-gnutella.sourceforge.net/ RFC Gnutella]&lt;br /&gt;
* [http://draketo.de/inhalt/krude-ideen/gnufu_en.html Gnutella for Users (GnuFU)]&lt;br /&gt;
* [http://crawler.instantnetworks.net/ Gnutella2 Crawler]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Gnutella2-powered_software&amp;diff=876</id>
		<title>Gnutella2-powered software</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Gnutella2-powered_software&amp;diff=876"/>
		<updated>2005-04-05T17:45:35Z</updated>

		<summary type="html">&lt;p&gt;Spooky: Updated&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Gnutella2 Clients==&lt;br /&gt;
&lt;br /&gt;
The following clients support Gnutella2:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;6&amp;quot; cellspacing=&amp;quot;1&amp;quot; bgcolor=&amp;quot;#A5CAD2&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt; &lt;br /&gt;
    &amp;lt;th width=&amp;quot;55%&amp;quot;&amp;gt;Client Name&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;23%&amp;quot;&amp;gt;Platform&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;22%&amp;quot;&amp;gt;Support&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;[http://www.shareaza.com Shareaza]&amp;lt;br&amp;gt;&lt;br /&gt;
Shareaza pioneered the Gnutella2 platform and continues to play an active role in its development.  Connects to several additional networks as well.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Full 1.0 Support&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;[http://www.mldonkey.net/ MLDonkey]&amp;lt;br&amp;gt;&lt;br /&gt;
An open source deamon client. Has many different GUI's you can use. Also connects to many other networks in addition to Gnutella2.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;Cross-Platform&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;1.0 Support (Beta)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;[http://caribou.epitech.net/ Caribou]&amp;lt;br&amp;gt;&lt;br /&gt;
Caribou is a peer to peer software design for general purpose p2p communication (file sharing, news, messaging), based on Gnutella2 network&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Windows, Linux, Mac OS X, etc.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;pre-alpha&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;[http://www.filescope.com/ FileScope]&amp;lt;br&amp;gt;&lt;br /&gt;
FileScope is a file sharing program that connects to multiple peer-to-peer (P2P) networks and allows for finding and downloading all types of files. Written in C#.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;N/A&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;[http://sourceforge.net/projects/agio/ Adagio]&amp;lt;br&amp;gt;&lt;br /&gt;
Adagio is a Gnutella2 server which aims to provide a very configurable, highly reliable cross-platform daemon.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Cross-Platform&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;1.0 Support&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;[http://www.gnucleus.com/ Gnucleus]&amp;lt;br&amp;gt;&lt;br /&gt;
Gnucleus is one of the first Gnutella clients and is an open source Gnutella2 client. It is based on GnucDNA, a Gnutella2 library.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;Full 1.0 support&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;[http://www.kiwialpha.com/ Kiwi]&amp;lt;br&amp;gt;&lt;br /&gt;
Lightweight client, based on GnucDNA&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Uses GnucDNA&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot; class=&amp;quot;normal&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;[http://www.morpheus.com/ Morpheus]&amp;lt;br&amp;gt;&lt;br /&gt;
Morpheus is a mainstram P2P client which switched from the FastTrack network to the Gnutella network and now to the Gnutella2 network.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;Uses GnucDNA&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Mailing_list&amp;diff=98</id>
		<title>Mailing list</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Mailing_list&amp;diff=98"/>
		<updated>2005-04-05T17:31:34Z</updated>

		<summary type="html">&lt;p&gt;Spooky: dcat: feel free to put info about the real mailinglist on this page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==G2DN Mailing List==&lt;br /&gt;
&lt;br /&gt;
This is the mailing list for communication between Gnutella2 developers and other interested people. This is not for help on how to use Gnutella2 applications.&lt;br /&gt;
&lt;br /&gt;
To '''subscribe''' to this list send an e-mail to g2dn-request@freelists.org with 'subscribe' in the subject line.&lt;br /&gt;
&lt;br /&gt;
To post on this mailinglist send an e-mail to g2dn@freelists.org&lt;br /&gt;
&lt;br /&gt;
This mailinglist is powered by FreeLists.org and runs on Ecartis. You can login to your account at http://www.freelists.org&lt;br /&gt;
&lt;br /&gt;
For help on how to use advanced features of this list refer to http://www.freelists.org/help/index.html . You can also send an e-mail with 'help' in the subject line to g2dn-request@freelists.org&lt;br /&gt;
&lt;br /&gt;
You can find the message archives at http://www.freelists.org/archives/g2dn/&lt;br /&gt;
&lt;br /&gt;
If you want to '''unsubscribe''' from the list you can do so through the web interface, or by sending email to the following address: g2dn-request@freelists.org with 'unsubscribe' in the Subject line.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Active_Source_Exchange&amp;diff=92</id>
		<title>Active Source Exchange</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Active_Source_Exchange&amp;diff=92"/>
		<updated>2005-04-05T17:19:39Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Active Source Exchange (ASE) 1.0==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; &amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td allign=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;Written By: Kevin O'Toole&amp;lt;br&amp;gt;&lt;br /&gt;
kevo@napjunk.net&amp;lt;br&amp;gt;&lt;br /&gt;
Shareaza Alpha Team&amp;lt;br&amp;gt;&lt;br /&gt;
2003.06.14&lt;br /&gt;
&lt;br /&gt;
Edited By: Jonathan C. Nilson&amp;lt;br&amp;gt;&lt;br /&gt;
JCNilson@myrealbox.com&amp;lt;br&amp;gt;&lt;br /&gt;
Shareaza Alpha Team&amp;lt;br&amp;gt;&lt;br /&gt;
2003.06.16&amp;lt;/small&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td allign=&amp;quot;right&amp;quot;&amp;gt;__TOC__&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Status===&lt;br /&gt;
This proosal is currently not implemented by any client.&lt;br /&gt;
&lt;br /&gt;
===Introduction===&lt;br /&gt;
This proposal addresses the current flaws in the alternate source mesh by not passing on sources that are &amp;quot;old&amp;quot; and client identification for whom to receive sources from. This does not eliminate alternate sources but should make the current system better because it will help keep the mesh (exchange) of sources clean of dead hosts. The proposal has the added benefit of reducing the effects of a Gnutella-style Denial-of-Service attack by reducing the number of bad sources a Shareaza node has, thus keeping that Shareaza node from pestering as many dead sources.&lt;br /&gt;
&lt;br /&gt;
===Why is it needed?===&lt;br /&gt;
ASE removes the need to requery frequently to gather a list of new sources. By sharing only current sources, users will not ...&lt;br /&gt;
&lt;br /&gt;
* get flooded with more dead hosts than live ones&lt;br /&gt;
* receive connection attempts for a long time after&lt;br /&gt;
* have to clean out a long list of bad hosts&lt;br /&gt;
* expericence hangs in the client as frequently&lt;br /&gt;
* attempt as many connections on a random port/dynamic IP user&lt;br /&gt;
* participte unwittingly in a DoS attack on another user&lt;br /&gt;
* requery the network as frequently&lt;br /&gt;
* pass a firewalled source to a firewalled client&lt;br /&gt;
&lt;br /&gt;
There are still problems ASE does address but cannot completely solve, which include ...&lt;br /&gt;
&lt;br /&gt;
* hostile clients passing on fake or dead hosts&lt;br /&gt;
* hostile clients passing on expired sources&lt;br /&gt;
&lt;br /&gt;
===What's different?===&lt;br /&gt;
ASE changes the way a client chooses which alternate sources to pass and how long each will be active. In effect, a complying client would pass on only active sources in the mesh, each with an expiry time which should be between 10 and 15 minutes. Active sources are defined as sources which have successfully been Queued or Uploading at some time in the last expiry time block (10~15 minutes). This timeout is critical. If clients simply maintain a list, the dead hosts will take longer to populate the ASE, but will still eventually spread and the same problems will occur.&lt;br /&gt;
&lt;br /&gt;
To avoid this fiasco, a client in the ASE passes the address and the timeout (at its current value) to the recipient. This timeout is only reset if the address is successfully contacted and Queued or Uploading before the timeout value expires. Therefore, unless a client sees the source in a successful queue or upload, the address will expire (no matter how many clients have received the source) at the same time. If one client does reset the expiry counter, only sources which receive the source in the ASE subsequently will still have the source. No messages are sent back to clients who have an entry that is about to expire.&lt;br /&gt;
&lt;br /&gt;
If a client wishes to maintain a list of sources that have expired from the ASE, these sources shall not be passed on to subsequent hosts, with or without a timeout. At this point, the sources shall remain knowlegable to the local host alone.&lt;br /&gt;
&lt;br /&gt;
===Firewalls===&lt;br /&gt;
To avoid the propogation of firewalled sources to firewalled clients, each source shall have a header identification indicating the source as a firewalled client which would be sent with the address and timeout. The uploader sends any sources to normal clients, while push sources are not sent to firewalled clients. IANA Reserved IP ranges will not be passed along.&lt;br /&gt;
&lt;br /&gt;
===Security===&lt;br /&gt;
If every client played by these rules, security would be no problem, unfortunately we have to plan for the contingency that we may have hostile, buggy, or poorly-programmed clients. Keeping this system secure would perhaps be a more difficult task than implementing it. Options for achieving this would be either client identification (which can easily be spoofed) or client-to-client authentication. Without client identification or authentication, users run the same risks involved in the alternate-source mesh now.&lt;br /&gt;
&lt;br /&gt;
With client identification security, a user would only receive hosts from chosen vendors (filtered by reported user-agent strings) but still send hosts to any client. This would be a simple solution to the problem if everyone obeyed the rules. Unfortunately, hostile clients such as Qtrax change their user-agent identification to match that of their downloader, which would make the system useless against such clients (fortunately, few exist).&lt;br /&gt;
&lt;br /&gt;
A more complex (perhaps neglible) solution would be client-to-client authentication. Although this should completely solve the problem, it would require a large amount of work for minimal gain, and some valuable alternate sources from unsupporting clients would be lost. This authentication method would, by definition, be closed to only trusted clients, which also defeats the spirit of the Gnutella community. While it solves some problems very well, this course of action is not recommended.&lt;br /&gt;
&lt;br /&gt;
===Scenario===&lt;br /&gt;
To properly illustrate this new system, consider the following scenario. We will assume for the sake of illustration that the expiry threshold is at 15 minutes.&lt;br /&gt;
&lt;br /&gt;
ClientA, ClientB, and Client C all support ASE in its current form. ClientA and ClientB are both downloading File1. Client A knows of the following sources for File1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;111.111.111.1 (Queued 3 of 10 Now) &lt;br /&gt;
111.111.111.2 (Downloading Now)&lt;br /&gt;
111.111.111.3 (Queued 10 minutes ago)&lt;br /&gt;
111.111.111.5 (Downloading Now)&lt;br /&gt;
192.168.0.1 (Push) (Never contacted)&lt;br /&gt;
0.0.0.0 (Push) (Downloaded 5 minutes ago)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ClientB knows of the following sources for File1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;222.222.222.4 (Queued 20 minutes ago)&lt;br /&gt;
ClientA (Never contacted)&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As ClientB contacts ClientA for the file in question, it refuses to transmit the single known source it has because that source has expired from the ASE. While ClientB may choose to keep that source for its own use, it will not transmit that source to other clients, with or without an expiry timeout.&lt;br /&gt;
&lt;br /&gt;
When ClientA returns the handshake, it transmits a list of ASE sources to ClientB:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;111.111.111.1; Timeout=15m&lt;br /&gt;
111.111.111.2; Timeout=15m&lt;br /&gt;
111.111.111.3; Timeout=5m&lt;br /&gt;
111.111.111.5; Timeout=15m; Push&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since 0.0.0.0 is an IANA Private Range, the address is not passed to ClientB, although it is a valid source with a timeout at 10m. 192.168.0.1 is not passed because it has never been contacted.&lt;br /&gt;
&lt;br /&gt;
After ClientB receives this list of sources and is sent a Busy reply by ClientA, ClientB reattempts a connection with 222.222.222.4. This connection results in a successful download. One minute has passed since the ASE list from ClientA was received by ClientB.&lt;br /&gt;
&lt;br /&gt;
ClientC is firewalled, and after searching and finding ClientB as a source for File1, it attempts a connection. Since it has no sources, none are passed to ClientB, however, ClientB passes the same list of known sources to ClientC as ClientA did to ClientB. ClientB also adds its own experience by transimtting 222.222.222.4 because that source is now active and omiting 111.111.111.5 because that is a firewalled source and ClientC is firewalled, so the final list transmitted from ClientB to ClientC is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;111.111.111.1; Timeout=14m&lt;br /&gt;
111.111.111.2; Timeout=14m&lt;br /&gt;
111.111.111.3; Timeout=4m&lt;br /&gt;
222.222.222.4; Timeout=15m&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please note that Timeout values are listed in minutes for the sake of human understanding and will probably be coded in seconds instead.&lt;br /&gt;
&lt;br /&gt;
===Conclusion===&lt;br /&gt;
While this does not solve every problem of the current alternate source mesh, it would be beneficial for anyone who currently uses this system. ASE offers a simple solution to the problems with the alternate source mesh. If implemented on a wide-scale, it could reduce traffic substantially and increase file transfer efficiency tenfold.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Active_Source_Exchange&amp;diff=89</id>
		<title>Active Source Exchange</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Active_Source_Exchange&amp;diff=89"/>
		<updated>2005-04-05T17:17:24Z</updated>

		<summary type="html">&lt;p&gt;Spooky: first version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Active Source Exchange (ASE) 1.0==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; &amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td allign=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;small&amp;gt;Written By: Kevin O'Toole&amp;lt;br&amp;gt;&lt;br /&gt;
kevo@napjunk.net&amp;lt;br&amp;gt;&lt;br /&gt;
Shareaza Alpha Team&amp;lt;br&amp;gt;&lt;br /&gt;
2003.06.14&lt;br /&gt;
&lt;br /&gt;
Edited By: Jonathan C. Nilson&amp;lt;br&amp;gt;&lt;br /&gt;
JCNilson@myrealbox.com&amp;lt;br&amp;gt;&lt;br /&gt;
Shareaza Alpha Team&amp;lt;br&amp;gt;&lt;br /&gt;
2003.06.16&amp;lt;/small&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;td allign=&amp;quot;right&amp;quot;&amp;gt;__TOC__&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===1. Introduction===&lt;br /&gt;
This proposal addresses the current flaws in the alternate source mesh by not passing on sources that are &amp;quot;old&amp;quot; and client identification for whom to receive sources from. This does not eliminate alternate sources but should make the current system better because it will help keep the mesh (exchange) of sources clean of dead hosts. The proposal has the added benefit of reducing the effects of a Gnutella-style Denial-of-Service attack by reducing the number of bad sources a Shareaza node has, thus keeping that Shareaza node from pestering as many dead sources.&lt;br /&gt;
&lt;br /&gt;
===2. Why is it needed?===&lt;br /&gt;
ASE removes the need to requery frequently to gather a list of new sources. By sharing only current sources, users will not ...&lt;br /&gt;
&lt;br /&gt;
* get flooded with more dead hosts than live ones&lt;br /&gt;
* receive connection attempts for a long time after&lt;br /&gt;
* have to clean out a long list of bad hosts&lt;br /&gt;
* expericence hangs in the client as frequently&lt;br /&gt;
* attempt as many connections on a random port/dynamic IP user&lt;br /&gt;
* participte unwittingly in a DoS attack on another user&lt;br /&gt;
* requery the network as frequently&lt;br /&gt;
* pass a firewalled source to a firewalled client&lt;br /&gt;
&lt;br /&gt;
There are still problems ASE does address but cannot completely solve, which include ...&lt;br /&gt;
&lt;br /&gt;
* hostile clients passing on fake or dead hosts&lt;br /&gt;
* hostile clients passing on expired sources&lt;br /&gt;
&lt;br /&gt;
===3. What's different?===&lt;br /&gt;
ASE changes the way a client chooses which alternate sources to pass and how long each will be active. In effect, a complying client would pass on only active sources in the mesh, each with an expiry time which should be between 10 and 15 minutes. Active sources are defined as sources which have successfully been Queued or Uploading at some time in the last expiry time block (10~15 minutes). This timeout is critical. If clients simply maintain a list, the dead hosts will take longer to populate the ASE, but will still eventually spread and the same problems will occur.&lt;br /&gt;
&lt;br /&gt;
To avoid this fiasco, a client in the ASE passes the address and the timeout (at its current value) to the recipient. This timeout is only reset if the address is successfully contacted and Queued or Uploading before the timeout value expires. Therefore, unless a client sees the source in a successful queue or upload, the address will expire (no matter how many clients have received the source) at the same time. If one client does reset the expiry counter, only sources which receive the source in the ASE subsequently will still have the source. No messages are sent back to clients who have an entry that is about to expire.&lt;br /&gt;
&lt;br /&gt;
If a client wishes to maintain a list of sources that have expired from the ASE, these sources shall not be passed on to subsequent hosts, with or without a timeout. At this point, the sources shall remain knowlegable to the local host alone.&lt;br /&gt;
&lt;br /&gt;
===4. Firewalls===&lt;br /&gt;
To avoid the propogation of firewalled sources to firewalled clients, each source shall have a header identification indicating the source as a firewalled client which would be sent with the address and timeout. The uploader sends any sources to normal clients, while push sources are not sent to firewalled clients. IANA Reserved IP ranges will not be passed along.&lt;br /&gt;
&lt;br /&gt;
===5. Security===&lt;br /&gt;
If every client played by these rules, security would be no problem, unfortunately we have to plan for the contingency that we may have hostile, buggy, or poorly-programmed clients. Keeping this system secure would perhaps be a more difficult task than implementing it. Options for achieving this would be either client identification (which can easily be spoofed) or client-to-client authentication. Without client identification or authentication, users run the same risks involved in the alternate-source mesh now.&lt;br /&gt;
&lt;br /&gt;
With client identification security, a user would only receive hosts from chosen vendors (filtered by reported user-agent strings) but still send hosts to any client. This would be a simple solution to the problem if everyone obeyed the rules. Unfortunately, hostile clients such as Qtrax change their user-agent identification to match that of their downloader, which would make the system useless against such clients (fortunately, few exist).&lt;br /&gt;
&lt;br /&gt;
A more complex (perhaps neglible) solution would be client-to-client authentication. Although this should completely solve the problem, it would require a large amount of work for minimal gain, and some valuable alternate sources from unsupporting clients would be lost. This authentication method would, by definition, be closed to only trusted clients, which also defeats the spirit of the Gnutella community. While it solves some problems very well, this course of action is not recommended.&lt;br /&gt;
&lt;br /&gt;
===6. Scenario===&lt;br /&gt;
To properly illustrate this new system, consider the following scenario. We will assume for the sake of illustration that the expiry threshold is at 15 minutes.&lt;br /&gt;
&lt;br /&gt;
ClientA, ClientB, and Client C all support ASE in its current form. ClientA and ClientB are both downloading File1. Client A knows of the following sources for File1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;111.111.111.1 (Queued 3 of 10 Now) &lt;br /&gt;
111.111.111.2 (Downloading Now)&lt;br /&gt;
111.111.111.3 (Queued 10 minutes ago)&lt;br /&gt;
111.111.111.5 (Downloading Now)&lt;br /&gt;
192.168.0.1 (Push) (Never contacted)&lt;br /&gt;
0.0.0.0 (Push) (Downloaded 5 minutes ago)&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ClientB knows of the following sources for File1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;222.222.222.4 (Queued 20 minutes ago)&lt;br /&gt;
ClientA (Never contacted)&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As ClientB contacts ClientA for the file in question, it refuses to transmit the single known source it has because that source has expired from the ASE. While ClientB may choose to keep that source for its own use, it will not transmit that source to other clients, with or without an expiry timeout.&lt;br /&gt;
&lt;br /&gt;
When ClientA returns the handshake, it transmits a list of ASE sources to ClientB:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;111.111.111.1; Timeout=15m&lt;br /&gt;
111.111.111.2; Timeout=15m&lt;br /&gt;
111.111.111.3; Timeout=5m&lt;br /&gt;
111.111.111.5; Timeout=15m; Push&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Since 0.0.0.0 is an IANA Private Range, the address is not passed to ClientB, although it is a valid source with a timeout at 10m. 192.168.0.1 is not passed because it has never been contacted.&lt;br /&gt;
&lt;br /&gt;
After ClientB receives this list of sources and is sent a Busy reply by ClientA, ClientB reattempts a connection with 222.222.222.4. This connection results in a successful download. One minute has passed since the ASE list from ClientA was received by ClientB.&lt;br /&gt;
&lt;br /&gt;
ClientC is firewalled, and after searching and finding ClientB as a source for File1, it attempts a connection. Since it has no sources, none are passed to ClientB, however, ClientB passes the same list of known sources to ClientC as ClientA did to ClientB. ClientB also adds its own experience by transimtting 222.222.222.4 because that source is now active and omiting 111.111.111.5 because that is a firewalled source and ClientC is firewalled, so the final list transmitted from ClientB to ClientC is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;111.111.111.1; Timeout=14m&lt;br /&gt;
111.111.111.2; Timeout=14m&lt;br /&gt;
111.111.111.3; Timeout=4m&lt;br /&gt;
222.222.222.4; Timeout=15m&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please note that Timeout values are listed in minutes for the sake of human understanding and will probably be coded in seconds instead.&lt;br /&gt;
&lt;br /&gt;
===7. Conclusion===&lt;br /&gt;
While this does not solve every problem of the current alternate source mesh, it would be beneficial for anyone who currently uses this system. ASE offers a simple solution to the problems with the alternate source mesh. If implemented on a wide-scale, it could reduce traffic substantially and increase file transfer efficiency tenfold.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Main_Page&amp;diff=91</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Main_Page&amp;diff=91"/>
		<updated>2005-04-05T17:02:20Z</updated>

		<summary type="html">&lt;p&gt;Spooky: /* Proposals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Gnutella2 Developer Network ==&lt;br /&gt;
Welcome to the Gnutella2 Developer Network&lt;br /&gt;
The Gnutella2 Developers' Network (or G2DN) is a convenient central location for discussing, developing and documenting all aspects of Gnutella2. Like the Gnutella2 platform itself, this website is designed to evolve through community support and participation. Everyone is free to contibute discussion, proposal documents, developer resources or any other relevant material.&lt;br /&gt;
&lt;br /&gt;
Although the G2DN is primarily geared toward developers and technical enthusiests, users of Gnutella2-enabled software are also welcome to participate. Those who are new to Gnutella2 may wish to check out some of the [[Gnutella2-powered software]].&lt;br /&gt;
&lt;br /&gt;
===Mailing List===&lt;br /&gt;
To allow communication among developers of Gnutella2 clients, there exists a [[mailing list]]&lt;br /&gt;
&lt;br /&gt;
== The Gnutella 2 Network==&lt;br /&gt;
# [[Gnutella2|What is Gnutella2]]&lt;br /&gt;
# [[Gnutella2 Standard]]&lt;br /&gt;
# [[Network Architecture]]&lt;br /&gt;
# [[Node Types and Responsibilities]]&lt;br /&gt;
# [[Background|Background / Archive]]&lt;br /&gt;
&lt;br /&gt;
== The Protocol==&lt;br /&gt;
# [[TCP Stream Connection and Handshaking]]&lt;br /&gt;
# [[UDP Transceiver]]&lt;br /&gt;
# [[Packet Structure]]&lt;br /&gt;
# [[Datatypes]]&lt;br /&gt;
# [[Basic Network Maintenance]]&lt;br /&gt;
# [[Known Hub Cache and Hub Cluster Cache]]&lt;br /&gt;
# [[Node Route Cache and Addressed Packet Forwarding]]&lt;br /&gt;
# [[Query Hash Tables]]&lt;br /&gt;
# [[Object Search Mechanism]]&lt;br /&gt;
# [[Search Security]]&lt;br /&gt;
# [[Search Description]]&lt;br /&gt;
# [[Search Acknowledgement]]&lt;br /&gt;
# [[Search Results]]&lt;br /&gt;
# [[Simple Query Language and Metadata]]&lt;br /&gt;
# [[Server for Uploading]]&lt;br /&gt;
# [[Client for Downloading]]&lt;br /&gt;
# [[User Profile Challenge and Delivery]]&lt;br /&gt;
&lt;br /&gt;
== Root Packets ==&lt;br /&gt;
{{Root packets}}&lt;br /&gt;
&lt;br /&gt;
== Proposals==&lt;br /&gt;
* [[Active Source Exchange]] (ASE) by Kevin O'Toole&lt;br /&gt;
&lt;br /&gt;
== Additional Information==&lt;br /&gt;
Since Gnutella2 somehow evolved from the original Gnutella protocol you might find the following links useful:&lt;br /&gt;
* [http://www.the-gdf.org The GDF Wiki]&lt;br /&gt;
* [http://groups.yahoo.com/group/the_gdf/ Gnutella Developer forum]&lt;br /&gt;
* [http://rfc-gnutella.sourceforge.net/ RFC Gnutella]&lt;br /&gt;
* [http://draketo.de/inhalt/krude-ideen/gnufu_en.html Gnutella for Users (GnuFU)]&lt;br /&gt;
* [http://crawler.instantnetworks.net/ Gnutella2 Crawler]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Main_Page&amp;diff=88</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Main_Page&amp;diff=88"/>
		<updated>2005-04-05T17:01:37Z</updated>

		<summary type="html">&lt;p&gt;Spooky: ASE added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Gnutella2 Developer Network ==&lt;br /&gt;
Welcome to the Gnutella2 Developer Network&lt;br /&gt;
The Gnutella2 Developers' Network (or G2DN) is a convenient central location for discussing, developing and documenting all aspects of Gnutella2. Like the Gnutella2 platform itself, this website is designed to evolve through community support and participation. Everyone is free to contibute discussion, proposal documents, developer resources or any other relevant material.&lt;br /&gt;
&lt;br /&gt;
Although the G2DN is primarily geared toward developers and technical enthusiests, users of Gnutella2-enabled software are also welcome to participate. Those who are new to Gnutella2 may wish to check out some of the [[Gnutella2-powered software]].&lt;br /&gt;
&lt;br /&gt;
===Mailing List===&lt;br /&gt;
To allow communication among developers of Gnutella2 clients, there exists a [[mailing list]]&lt;br /&gt;
&lt;br /&gt;
== The Gnutella 2 Network==&lt;br /&gt;
# [[Gnutella2|What is Gnutella2]]&lt;br /&gt;
# [[Gnutella2 Standard]]&lt;br /&gt;
# [[Network Architecture]]&lt;br /&gt;
# [[Node Types and Responsibilities]]&lt;br /&gt;
# [[Background|Background / Archive]]&lt;br /&gt;
&lt;br /&gt;
== The Protocol==&lt;br /&gt;
# [[TCP Stream Connection and Handshaking]]&lt;br /&gt;
# [[UDP Transceiver]]&lt;br /&gt;
# [[Packet Structure]]&lt;br /&gt;
# [[Datatypes]]&lt;br /&gt;
# [[Basic Network Maintenance]]&lt;br /&gt;
# [[Known Hub Cache and Hub Cluster Cache]]&lt;br /&gt;
# [[Node Route Cache and Addressed Packet Forwarding]]&lt;br /&gt;
# [[Query Hash Tables]]&lt;br /&gt;
# [[Object Search Mechanism]]&lt;br /&gt;
# [[Search Security]]&lt;br /&gt;
# [[Search Description]]&lt;br /&gt;
# [[Search Acknowledgement]]&lt;br /&gt;
# [[Search Results]]&lt;br /&gt;
# [[Simple Query Language and Metadata]]&lt;br /&gt;
# [[Server for Uploading]]&lt;br /&gt;
# [[Client for Downloading]]&lt;br /&gt;
# [[User Profile Challenge and Delivery]]&lt;br /&gt;
&lt;br /&gt;
== Root Packets ==&lt;br /&gt;
{{Root packets}}&lt;br /&gt;
&lt;br /&gt;
== Proposals==&lt;br /&gt;
* Active Source Exchange (ASE) by Kevin O'Toole&lt;br /&gt;
&lt;br /&gt;
== Additional Information==&lt;br /&gt;
Since Gnutella2 somehow evolved from the original Gnutella protocol you might find the following links useful:&lt;br /&gt;
* [http://www.the-gdf.org The GDF Wiki]&lt;br /&gt;
* [http://groups.yahoo.com/group/the_gdf/ Gnutella Developer forum]&lt;br /&gt;
* [http://rfc-gnutella.sourceforge.net/ RFC Gnutella]&lt;br /&gt;
* [http://draketo.de/inhalt/krude-ideen/gnufu_en.html Gnutella for Users (GnuFU)]&lt;br /&gt;
* [http://crawler.instantnetworks.net/ Gnutella2 Crawler]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Main_Page&amp;diff=85</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Main_Page&amp;diff=85"/>
		<updated>2005-04-03T02:10:56Z</updated>

		<summary type="html">&lt;p&gt;Spooky: Crawler link added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Gnutella2 Developer Network ==&lt;br /&gt;
Welcome to the Gnutella2 Developer Network&lt;br /&gt;
The Gnutella2 Developers' Network (or G2DN) is a convenient central location for discussing, developing and documenting all aspects of Gnutella2. Like the Gnutella2 platform itself, this website is designed to evolve through community support and participation. Everyone is free to contibute discussion, proposal documents, developer resources or any other relevant material.&lt;br /&gt;
&lt;br /&gt;
Although the G2DN is primarily geared toward developers and technical enthusiests, users of Gnutella2-enabled software are also welcome to participate. Those who are new to Gnutella2 may wish to check out some of the [[Gnutella2-powered software]].&lt;br /&gt;
&lt;br /&gt;
===Mailing List===&lt;br /&gt;
To allow communication among develoeprs of Gnutella2 clients, there exists a [[mailing list]]&lt;br /&gt;
&lt;br /&gt;
==1. The Gnutella 2 Network==&lt;br /&gt;
# [[Gnutella2|What is Gnutella2]]&lt;br /&gt;
# [[Gnutella2 Standard]]&lt;br /&gt;
# [[Network Architecture]]&lt;br /&gt;
# [[Node Types and Responsibilities]]&lt;br /&gt;
# [[Background|Background / Archive]]&lt;br /&gt;
&lt;br /&gt;
==2. The Protocol==&lt;br /&gt;
# [[TCP Stream Connection and Handshaking]]&lt;br /&gt;
# [[UDP Transceiver]]&lt;br /&gt;
# [[Packet Structure]]&lt;br /&gt;
# [[Datatypes]]&lt;br /&gt;
# [[Basic Network Maintenance]]&lt;br /&gt;
# [[Known Hub Cache and Hub Cluster Cache]]&lt;br /&gt;
# [[Node Route Cache and Addressed Packet Forwarding]]&lt;br /&gt;
# [[Query Hash Tables]]&lt;br /&gt;
# [[Object Search Mechanism]]&lt;br /&gt;
# [[Search Security]]&lt;br /&gt;
# [[Search Description]]&lt;br /&gt;
# [[Search Acknowledgement]]&lt;br /&gt;
# [[Search Results]]&lt;br /&gt;
# [[Simple Query Language and Metadata]]&lt;br /&gt;
# [[Server for Uploading]]&lt;br /&gt;
# [[Client for Downloading]]&lt;br /&gt;
# [[User Profile Challenge and Delivery]]&lt;br /&gt;
&lt;br /&gt;
==3. Proposals==&lt;br /&gt;
&lt;br /&gt;
==4. Additional Information==&lt;br /&gt;
Since Gnutella2 somehow evolved from the original Gnutella protocol you might find the following links useful:&lt;br /&gt;
* [http://www.the-gdf.org The GDF Wiki]&lt;br /&gt;
* [http://groups.yahoo.com/group/the_gdf/ Gnutella Developer forum]&lt;br /&gt;
* [http://rfc-gnutella.sourceforge.net/ RFC Gnutella]&lt;br /&gt;
* [http://draketo.de/inhalt/krude-ideen/gnufu_en.html Gnutella for Users (GnuFU)]&lt;br /&gt;
* [http://crawler.instantnetworks.net/ Gnutella2 Crawler]&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>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Background&amp;diff=82</id>
		<title>Background</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Background&amp;diff=82"/>
		<updated>2005-04-03T02:03:37Z</updated>

		<summary type="html">&lt;p&gt;Spooky: /* History */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==History==&lt;br /&gt;
The Gnutella2 protocol has been developed by [[Wikipedia:Michael_Stokes|Michael Stokes]] in the year 2002. It has been discussed quite controversial and some people prefer to refer to the Gnutella2 protocal by the name ''Mike's Protocol'' (MP). You might want to read the [[Wikipedia:Gnutella2|Wikipedia article]] on Gnutella2.&lt;br /&gt;
&lt;br /&gt;
==Old Publications==&lt;br /&gt;
* [[G2_specs_part1|Gnutella2 Specifications part ONE]]&lt;br /&gt;
* [[G2_specs_part2|Gnutella2 Specifications part TWO]]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Gnutella2-powered_software&amp;diff=90</id>
		<title>Gnutella2-powered software</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Gnutella2-powered_software&amp;diff=90"/>
		<updated>2005-04-03T02:02:16Z</updated>

		<summary type="html">&lt;p&gt;Spooky: First version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Gnutella2 Clients==&lt;br /&gt;
&lt;br /&gt;
The following clients support Gnutella2:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;6&amp;quot; cellspacing=&amp;quot;1&amp;quot; bgcolor=&amp;quot;#A5CAD2&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt; &lt;br /&gt;
    &amp;lt;th width=&amp;quot;55%&amp;quot;&amp;gt;Client Name&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;23%&amp;quot;&amp;gt;Platform&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;22%&amp;quot;&amp;gt;Support&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;[http://www.shareaza.com Shareaza]&amp;lt;br&amp;gt;&lt;br /&gt;
Shareaza pioneered the Gnutella2 platform and continues to play an active role in its development.  Connects to several additional networks as well.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Full 1.0 Support&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;[http://www.mldonkey.net/ MLDonkey]&amp;lt;br&amp;gt;&lt;br /&gt;
An open source deamon client. Has many different GUI's you can use. Also connects to many other networks in addition to Gnutella2.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;Cross-Platform&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;1.0 Support (Beta)&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;[http://shinobu.sourceforge.net/ Shinobu]&amp;lt;br&amp;gt;&lt;br /&gt;
Shinobu is the first Linux-only Gnutella2 client. It's written in C, uses GTK 2.0, and attempts to be easy-to-use without using a large amount of memory&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Linux&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;N/A&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;[http://sourceforge.net/projects/agio/ Adagio]&amp;lt;br&amp;gt;&lt;br /&gt;
Adagio is a Gnutella2 server which aims to provide a very configurable, highly reliable cross-platform daemon.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;Cross-Platform&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;1.0 Support&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;[http://www.gnucleus.com/ Gnucleus]&amp;lt;br&amp;gt;&lt;br /&gt;
Gnucleus is one of the first Gnutella clients and is an open source Gnutella2 client. It is based on GnucDNA, a Gnutella2 library.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#FFFFFF&amp;quot;&amp;gt;Full 1.0 support&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;tr align=&amp;quot;left&amp;quot; valign=&amp;quot;top&amp;quot; class=&amp;quot;normal&amp;quot;&amp;gt; &lt;br /&gt;
    &amp;lt;td bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;[http://www.morpheus.com/ Morpheus]&amp;lt;br&amp;gt;&lt;br /&gt;
Morpheus is a mainstram P2P client which switched from the FastTrack network to the Gnutella network and now to the Gnutella2 network.&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;Windows&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td align=&amp;quot;center&amp;quot; valign=&amp;quot;middle&amp;quot; bgcolor=&amp;quot;#F2F2F2&amp;quot;&amp;gt;Uses GnucDNA&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=LNI&amp;diff=1642</id>
		<title>LNI</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=LNI&amp;diff=1642"/>
		<updated>2005-04-02T22:32:30Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[KHL|&amp;lt;&amp;lt; KHL]] | [[PI|PI &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /LNI - Local Node Information =&lt;br /&gt;
&lt;br /&gt;
The local node information packet is used to convey essential information about the&lt;br /&gt;
node on either end of a TCP stream connection.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
The /LNI packet should be sent to a TCP neighbour upon connection, and at regular&lt;br /&gt;
intervals following that if the information within it has changed. A minimum update&lt;br /&gt;
time of one minute is recommended.&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
Upon receiving a /LNI packet, the information within should be stored for subsequent&lt;br /&gt;
use.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
The /LNI packet has many child packet types defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /LNI/NA - Node Address&lt;br /&gt;
* /LNI/GU - GUID&lt;br /&gt;
* /LNI/V - Vendor Code&lt;br /&gt;
* /LNI/LS - Library Statistics&lt;br /&gt;
* /LNI/HS - Hub Status&lt;br /&gt;
&lt;br /&gt;
== /LNI/NA - Node Address ==&lt;br /&gt;
&lt;br /&gt;
The /LNI/NA child packet specifies the node or network address of the sending node.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child is required.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
The physical network address of the sending node. See datatypes for more&lt;br /&gt;
information.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /LNI/GU - GUID ==&lt;br /&gt;
&lt;br /&gt;
The /LNI/GU child packet specifies the globally unique identifier of the sending node.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child is required.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
The 16 byte globally unique node identifier of the sending node.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /LNI/V - Vendor Code ==&lt;br /&gt;
&lt;br /&gt;
The /LNI/V child packet specifies the vendor code of the software operating the&lt;br /&gt;
sending node.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
A four byte vendor code.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /LNI/LS - Library Statistics ==&lt;br /&gt;
&lt;br /&gt;
The /LNI/LS packet provides information about the content library of the sending&lt;br /&gt;
node.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
Two 32-bit integers representing the number of files in the local library, and the total&lt;br /&gt;
KB in the local library respectively. If the sending node is a hub these statistics are&lt;br /&gt;
combined with the known statistics from all connected leaves. The payload may grow&lt;br /&gt;
beyond 8 bytes in the future.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /LNI/HS - Hub Status ==&lt;br /&gt;
&lt;br /&gt;
The /LNI/HS packet is included only if the sending node is a hub, and contains the&lt;br /&gt;
status of the hub.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child packet should only be sent by hub nodes. Leaf nodes should not transmit&lt;br /&gt;
it, and if it is received from a leaf node, it should be ignored.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
Two 16-bit integers representing the current leaf count and the maximum leaf count&lt;br /&gt;
respectively. This packet may grow beyond 4 bytes in the future.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=KHL&amp;diff=892</id>
		<title>KHL</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=KHL&amp;diff=892"/>
		<updated>2005-04-02T22:30:47Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[LNI|LNI &amp;gt;&amp;gt;]] | [[Root_packets_index|Packet Index]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= /KHL =&lt;br /&gt;
&lt;br /&gt;
The known hub list packet is used to exchange a list of known Gnutella2 hubs with&lt;br /&gt;
neighbouring nodes. It is exchanged regularly over all TCP connections, between&lt;br /&gt;
hubs and between hubs and leaves (and vice versa). It enables a completely up to&lt;br /&gt;
date picture of the local hub cluster, and the gradual propagation of cached hub&lt;br /&gt;
records.&lt;br /&gt;
&lt;br /&gt;
== Sending ==&lt;br /&gt;
&lt;br /&gt;
This packet should be sent through TCP links at regular intervals. One minute is&lt;br /&gt;
suggested for busy links, leaves may send to hubs less often. Note that unlike /LNI,&lt;br /&gt;
/KHL must be sent regularly even if the information does not change in order to&lt;br /&gt;
refresh timestamps and keep time-sorted caches in the correct order.&lt;br /&gt;
&lt;br /&gt;
== Receiving ==&lt;br /&gt;
&lt;br /&gt;
Upon receiving a known hub list, the detailed hubs should be stored in appropriate&lt;br /&gt;
data structures. Neighbouring hubs must be retained in the hub cluster records,&lt;br /&gt;
while cached hubs should be merged with the local accessible hub cache.&lt;br /&gt;
&lt;br /&gt;
== Payload ==&lt;br /&gt;
&lt;br /&gt;
This packet has no payload at the current time.&lt;br /&gt;
&lt;br /&gt;
== Children ==&lt;br /&gt;
&lt;br /&gt;
This packet has several child packet types defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /KHL/TS - Timestamp&lt;br /&gt;
* /KHL/NH - Neighbouring Hub&lt;br /&gt;
* /KHL/CH - Cached Hub&lt;br /&gt;
&lt;br /&gt;
== /KHL/TS - Timestamp ==&lt;br /&gt;
&lt;br /&gt;
The /KHL/TS child provides a timestamp representing the current universal time at&lt;br /&gt;
the sending node. This can be used as a reference when considering other&lt;br /&gt;
timestamps in the packet, allowing them to be adjusted to eliminate differences&lt;br /&gt;
between the time setting on the local and remote node.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
This child is optional but recommended.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
A 32-bit integer representing the current UNIX time, or time (NULL).&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /KHL/NH - Neighbouring Hub ==&lt;br /&gt;
&lt;br /&gt;
This child packet represents a neighbouring hub.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
One should be included for each Gnutella2 neighbour hub, with the possible&lt;br /&gt;
exception of the one to which this packet is being sent.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
The node address of the hub. See datatypes for more information.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has several child packet types defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /KHL/NH/GU - GUID&lt;br /&gt;
* /KHL/NH/V - Vendor Code&lt;br /&gt;
* /KHL/NH/LS - Library Statistics&lt;br /&gt;
* /KHL/NH/HS - Hub Status&lt;br /&gt;
&lt;br /&gt;
=== /KHL/NH/GU - GUID ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/NH/GU child packet specifies the globally unique identifier of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
The 16 byte globally unique node identifier of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/NH/V - Vendor Code ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/NH/V child packet specifies the vendor code of the software operating the&lt;br /&gt;
hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
A four byte vendor code.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/NH/LS - Library Statistics ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/NH/LS packet provides information about the content library of the hub&lt;br /&gt;
and its connected leaves.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Two 32-bit integers representing the number of files, and the total KB of available&lt;br /&gt;
content in the hub's own library and the libraries of its connected leaves. The&lt;br /&gt;
payload may grow beyond 8 bytes in the future.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/NH/HS - Hub Status ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/NH/HS packet contains the status of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Two 16-bit integers representing the current leaf count and the maximum leaf count&lt;br /&gt;
respectively. This packet may grow beyond 4 bytes in the future.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
== /KHL/CH - Cached Hub ==&lt;br /&gt;
&lt;br /&gt;
This child packet represents a hub from the hub cache.&lt;br /&gt;
&lt;br /&gt;
=== Sending ===&lt;br /&gt;
&lt;br /&gt;
An arbitrary number of these children should be included, constrained by space and&lt;br /&gt;
the number of available cached hubs. A selection of freshly time stamped but&lt;br /&gt;
previously unknown hubs should be included, and the list should not include hubs in&lt;br /&gt;
the local cluster.&lt;br /&gt;
&lt;br /&gt;
=== Payload ===&lt;br /&gt;
&lt;br /&gt;
The node address of the hub, followed by the time this hub was last seen as a 32-bit&lt;br /&gt;
timestamp. The last seen time can be adjusted based on the difference between the&lt;br /&gt;
/KHL/TS timestamp and the local time. Note that the node address is of variable&lt;br /&gt;
length, so it is important to consider the last 4 bytes as the timestamp rather than&lt;br /&gt;
assuming a fixed length node address.&lt;br /&gt;
&lt;br /&gt;
=== Children ===&lt;br /&gt;
&lt;br /&gt;
This packet has several child packet types defined at the current time:&lt;br /&gt;
&lt;br /&gt;
* /KHL/CH/GU - GUID&lt;br /&gt;
* /KHL/CH/V - Vendor Code&lt;br /&gt;
* /KHL/CH/LS - Library Statistics&lt;br /&gt;
* /KHL/CH/HS - Hub Status&lt;br /&gt;
&lt;br /&gt;
This extra information is considered less relevant for a cached hub because it is&lt;br /&gt;
unlikely to be up to date enough to be useful.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/CH/GU - GUID ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/CH/GU child packet specifies the globally unique identifier of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
The 16 byte globally unique node identifier of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/CH/V - Vendor Code ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/CH/V child packet specifies the vendor code of the software operating the&lt;br /&gt;
hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
A four byte vendor code.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/CH/LS - Library Statistics ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/NH/LS packet provides information about the content library of the hub&lt;br /&gt;
and its connected leaves.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Two 32-bit integers representing the number of files, and the total KB of available&lt;br /&gt;
content in the hub's own library and the libraries of its connected leaves. The&lt;br /&gt;
payload may grow beyond 8 bytes in the future.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;br /&gt;
&lt;br /&gt;
=== /KHL/CH/HS - Hub Status ===&lt;br /&gt;
&lt;br /&gt;
The /KHL/CH/HS packet contains the status of the hub.&lt;br /&gt;
&lt;br /&gt;
==== Sending ====&lt;br /&gt;
&lt;br /&gt;
This child is optional.&lt;br /&gt;
&lt;br /&gt;
==== Payload ====&lt;br /&gt;
&lt;br /&gt;
Two 16-bit integers representing the current leaf count and the maximum leaf count&lt;br /&gt;
respectively. This packet may grow beyond 4 bytes in the future.&lt;br /&gt;
&lt;br /&gt;
==== Children ====&lt;br /&gt;
&lt;br /&gt;
This packet has no known children at the current time.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Basic_Network_Maintenance&amp;diff=1638</id>
		<title>Basic Network Maintenance</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Basic_Network_Maintenance&amp;diff=1638"/>
		<updated>2005-04-02T22:28:46Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datatypes|&amp;lt;&amp;lt; Datatypes]] | [[Known_Hub_Cache_and_Hub_Cluster_Cache|Known Hub Cache and Hub Cluster Cache &amp;gt;&amp;gt;]] | [[Main_Page|Main Page]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Once TCP stream connections have been established forming the overall network&lt;br /&gt;
topology, a set of basic packet types and behaviours are used to keep the network&lt;br /&gt;
together and perform maintenance functions.&lt;br /&gt;
These maintenance packets are documented in this section, each with name,&lt;br /&gt;
payload, children and behaviours.&lt;br /&gt;
&lt;br /&gt;
== Packet Types ==&lt;br /&gt;
&lt;br /&gt;
/[[PI]] - Ping&lt;br /&gt;
&lt;br /&gt;
/[[PO]] - Pong&lt;br /&gt;
&lt;br /&gt;
/[[LNI]] - Local Node Information&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Datatypes&amp;diff=1637</id>
		<title>Datatypes</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Datatypes&amp;diff=1637"/>
		<updated>2005-04-02T22:26:52Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Packet_Structure|&amp;lt;&amp;lt; Packet Structure]] | [[Basic_Network_Maintenance|Basic Network Maintenance &amp;gt;&amp;gt;]] | [[Main_Page|Main Page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&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>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Packet_Structure&amp;diff=831</id>
		<title>Packet Structure</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Packet_Structure&amp;diff=831"/>
		<updated>2005-04-02T22:25:21Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[UDP_Transceiver |&amp;lt;&amp;lt; UDP Transceiver]] | [[Datatypes|Datatypes &amp;gt;&amp;gt;]] | [[Main_Page|Main Page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&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>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=830</id>
		<title>UDP Transceiver</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=UDP_Transceiver&amp;diff=830"/>
		<updated>2005-04-02T22:23:07Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[TCP_Stream_Connection_and_Handshaking|&amp;lt;&amp;lt; TCP Stream Connection and Handshaking]] | [[Packet_Structure|Packet Structure &amp;gt;&amp;gt;]] | [[Main_Page|Main Page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&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>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=TCP_Stream_Connection_and_Handshaking&amp;diff=1634</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=1634"/>
		<updated>2005-04-02T22:21:33Z</updated>

		<summary type="html">&lt;p&gt;Spooky: Nav element added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[UDP_Transceiver|UDP Transceiver &amp;gt;&amp;gt;]] | [[Main_Page|Main Page]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&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>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Server_for_Uploading&amp;diff=1661</id>
		<title>Server for Uploading</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Server_for_Uploading&amp;diff=1661"/>
		<updated>2005-04-02T22:17:35Z</updated>

		<summary type="html">&lt;p&gt;Spooky: typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is not a core part of the Gnutella2 architecture, and is discussed in depth&lt;br /&gt;
elsewhere. {TODO: it should still be documented here eventually or link to appropriate documents}&lt;br /&gt;
&lt;br /&gt;
Filetransfer is basically the same as in the original Gnutella protocol. See the documentation [http://www.the-gdf.org/wiki/index.php?title=File_Transfer_%28was:_Requesting_a_download%29 here]&lt;br /&gt;
&lt;br /&gt;
[[X-Queue|Gnutella2's Queue System (X-Queue)]]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Client_for_Downloading&amp;diff=894</id>
		<title>Client for Downloading</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Client_for_Downloading&amp;diff=894"/>
		<updated>2005-04-02T22:17:03Z</updated>

		<summary type="html">&lt;p&gt;Spooky: typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is not a core part of the Gnutella2 architecture, and is discussed in depth&lt;br /&gt;
elsewhere. {TODO: it should still be documented here eventually or link to appropriate documents}&lt;br /&gt;
&lt;br /&gt;
Filetransfer is basically the same as in the original Gnutella protocol. See the documentation [http://www.the-gdf.org/wiki/index.php?title=File_Transfer_%28was:_Requesting_a_download%29 here]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Client_for_Downloading&amp;diff=71</id>
		<title>Client for Downloading</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Client_for_Downloading&amp;diff=71"/>
		<updated>2005-04-02T22:16:39Z</updated>

		<summary type="html">&lt;p&gt;Spooky: Added link to GDF docs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is not a core part of the Gnutella2 architecture, and is discussed in depth&lt;br /&gt;
elsewhere. {TODO: it should still be documented here eventually or link to appropriate documents}&lt;br /&gt;
&lt;br /&gt;
Filetransfer is basically the same as in the original Gnutella protocol. See the ducumentation [http://www.the-gdf.org/wiki/index.php?title=File_Transfer_%28was:_Requesting_a_download%29 here]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Server_for_Uploading&amp;diff=72</id>
		<title>Server for Uploading</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Server_for_Uploading&amp;diff=72"/>
		<updated>2005-04-02T22:15:47Z</updated>

		<summary type="html">&lt;p&gt;Spooky: Link to GDF docs added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is not a core part of the Gnutella2 architecture, and is discussed in depth&lt;br /&gt;
elsewhere. {TODO: it should still be documented here eventually or link to appropriate documents}&lt;br /&gt;
&lt;br /&gt;
Filetransfer is basically the same as in the original Gnutella protocol. See the ducumentation [http://www.the-gdf.org/wiki/index.php?title=File_Transfer_%28was:_Requesting_a_download%29 here]&lt;br /&gt;
&lt;br /&gt;
[[X-Queue|Gnutella2's Queue System (X-Queue)]]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Help:Editing&amp;diff=1670</id>
		<title>Help:Editing</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Help:Editing&amp;diff=1670"/>
		<updated>2005-04-02T22:13:45Z</updated>

		<summary type="html">&lt;p&gt;Spooky: typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&lt;br /&gt;
Hello, New User!&lt;br /&gt;
  If you want to test out editing pages, please&lt;br /&gt;
  use the &amp;quot;Sandbox&amp;quot; for your tests.  To go to the&lt;br /&gt;
  sandbox, type &amp;quot;WP:SB&amp;quot; in the search box on the&lt;br /&gt;
  left, and hit &amp;quot;Go&amp;quot;. Or click the link at the &lt;br /&gt;
  beginning of the article. &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a copy of the How to edit pages page from Wikipedia. Since both are based on [[Wikipedia:MediaWiki|MediaWiki]] it also applies to the Gnutella2 Developer Network wiki.&lt;br /&gt;
&lt;br /&gt;
[[Main_Page|Gnutella 2 Developer Network]] is a [[Wikipedia:WikiWiki|Wiki]], which means that anyone can easily edit any [[Wikipedia:Protected page|unprotected]] [[Wikipedia:What is an article|article]] and have those changes posted immediately to that page.  &lt;br /&gt;
&lt;br /&gt;
Editing a Wiki page is very easy. Simply click on the &amp;quot;'''Edit this page'''&amp;quot; tab at the top (or the edit link on the right or bottom) of a Wiki page. This will bring you to a page with a text box containing the editable text of that page. '''If you just want to experiment, please do so in the [[Wikipedia:sandbox|sandbox]]''', not here. You should write a short [[Wikipedia:Edit summary|edit summary]] in the small field below the edit-box. You may use shorthand to describe your changes, as described in the [[Wikipedia:Edit summary legend|legend]], and when you've finished, press [[Wikipedia:Show preview|preview]] to see how your changes will look. If you're happy with what you see, then press &amp;quot;Save&amp;quot; and your changes will be immediately applied to the article.&lt;br /&gt;
&lt;br /&gt;
You can also click on the &amp;quot;'''Discussion'''&amp;quot; tab to see the corresponding [[Wikipedia:Talk page|talk page]], which contains comments about the page from other Wikipedia users. Click on the &amp;quot;'''+'''&amp;quot; tab to add a new section, or edit the page in the same way as an article page.&lt;br /&gt;
&lt;br /&gt;
== Minor edits ==&lt;br /&gt;
''See also [[Wikipedia:Minor edit]]''&lt;br /&gt;
&lt;br /&gt;
When editing a page, a [[Wikipedia:How to log in|logged-in]] user can mark that edit as being &amp;quot;minor&amp;quot;. Minor edits generally mean spelling corrections, formatting, and minor rearrangement of text. It is possible to ''hide'' minor edits when viewing [[Wikipedia:Recent Changes]]. Marking a significant change as a minor edit is considered bad behavior, and even more so if it involves the deletion of some text. If one has accidentally marked an edit as minor, the person should edit the source once more, mark it major (or, rather, ensure that the check-box for &amp;quot;This is a minor edit&amp;quot; is not checked), and, in the summary, state that the previous change was a major one.&lt;br /&gt;
&lt;br /&gt;
== Wiki markup ==&lt;br /&gt;
&lt;br /&gt;
The '''wiki markup''' is the syntax system you can use to format a Wikipedia page.&lt;br /&gt;
&lt;br /&gt;
In the left column of the table below, you can see what effects are possible. In the right column, you can see how those effects were achieved. In other words, to make text look like it looks in the left column, type it in the format you see in the right column.&lt;br /&gt;
&lt;br /&gt;
You may want to keep this page open in a separate browser window for reference. '''If you want to try out things without danger of doing any harm, you can do so in the [[Wikipedia:Sandbox|Sandbox]]'''. Try opening the Sandbox in a separate window or tab and keeping this page open for reference.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
:'''The rest of this page is deprecated but will be updated periodically.''' &lt;br /&gt;
:'''Please direct edits to the [[meta:MediaWiki User's Guide: Editing overview|Meta-Wikimedia version of this page]]'''&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
=== Sections, paragraphs, lists and lines ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! What it looks like&lt;br /&gt;
! What you type&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
Start your [[Wikipedia:Manual of Style (headings)|sections]] as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- The following code messes up the table of contents&lt;br /&gt;
     and makes the section edit links much less useful,&lt;br /&gt;
     so please do not use it.&lt;br /&gt;
==New section==&lt;br /&gt;
===Subsection===&lt;br /&gt;
====Sub-subsection====&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!-- The following should look almost the same, using&lt;br /&gt;
     HTML headings markup instead of wiki headings.&lt;br /&gt;
     However, it messes up the section edit links,&lt;br /&gt;
     so please do not use it.&lt;br /&gt;
&amp;lt;h2&amp;gt;New section&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h3&amp;gt;Subsection&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Sub-subsection&amp;lt;/h4&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!-- The following just uses bolding and font changes,&lt;br /&gt;
     so it should be safe.  However, it might not&lt;br /&gt;
     look exactly right, especially when people&lt;br /&gt;
     use non-standard CSS stylesheets.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
'''&amp;lt;font style=&amp;quot;font-size:120%&amp;quot;&amp;gt;New section&amp;lt;/font&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;font style=&amp;quot;font-size:110%&amp;quot;&amp;gt;Subsection&amp;lt;/font&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
'''&amp;lt;font style=&amp;quot;font-size:100%&amp;quot;&amp;gt;Sub-subsection&amp;lt;/font&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
* Start with a second-level heading (&amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;==&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;); do not use first-level headings (=).&lt;br /&gt;
* Do not skip levels (e.g., second-level followed by fourth-level).&lt;br /&gt;
* A [[#Placement_of_the_Table_of_Contents_.28TOC.29|Table of Contents]] will automatically be added to an article that has four or more sections. &lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
==New section==&lt;br /&gt;
&lt;br /&gt;
===Subsection===&lt;br /&gt;
&lt;br /&gt;
====Sub-subsection====&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
A single [[newline]]&lt;br /&gt;
generally has no effect on the layout.&lt;br /&gt;
These can be used to separate&lt;br /&gt;
sentences within a paragraph.&lt;br /&gt;
Some editors find that this aids editing&lt;br /&gt;
and improves the function ''diff'' &lt;br /&gt;
(used internally to compare&lt;br /&gt;
different versions of a page).&lt;br /&gt;
&lt;br /&gt;
But an empty line&lt;br /&gt;
starts a new paragraph.&lt;br /&gt;
&lt;br /&gt;
* When used in a list, a newline ''does'' affect the layout ([[#lists|see below]]).&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
A single [[newline]]&lt;br /&gt;
generally has no effect on the layout. &lt;br /&gt;
These can be used to separate&lt;br /&gt;
sentences within a paragraph.&lt;br /&gt;
Some editors find that this aids editing&lt;br /&gt;
and improves the function ''diff'' &lt;br /&gt;
(used internally to compare&lt;br /&gt;
different versions of a page).&lt;br /&gt;
&lt;br /&gt;
But an empty line&lt;br /&gt;
starts a new paragraph.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
You can break lines&amp;lt;br&amp;gt;&lt;br /&gt;
without starting a new paragraph.&lt;br /&gt;
&lt;br /&gt;
* Please use this sparingly.&lt;br /&gt;
* Close markup between lines, don't start a [[link]] or ''italics'' or '''bold''' on one line and close it on the next.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
You can break lines&amp;lt;br&amp;gt;&lt;br /&gt;
without starting a new paragraph.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- id=&amp;quot;lists&amp;quot; valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
* Lists are easy to do:&lt;br /&gt;
** Start every line with a star (= [[asterisk]]).&lt;br /&gt;
*** More stars means deeper levels.&lt;br /&gt;
**** A newline in a list&lt;br /&gt;
marks the end of a list item.&lt;br /&gt;
&lt;br /&gt;
* An empty line starts a new list.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
* Lists are easy to do:&lt;br /&gt;
** Start every line with a star.&lt;br /&gt;
*** More stars means deeper levels.&lt;br /&gt;
**** A newline in a list&lt;br /&gt;
marks the end of a list item.&lt;br /&gt;
&lt;br /&gt;
* An empty line starts a new list.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
# Numbered lists are also good&lt;br /&gt;
## very organized&lt;br /&gt;
## easy to follow&lt;br /&gt;
### easier still&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
# Numbered lists are also good&lt;br /&gt;
## very organized&lt;br /&gt;
## easy to follow&lt;br /&gt;
### easier still&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
* You can even do mixed lists&lt;br /&gt;
*# and nest them&lt;br /&gt;
*#* like this&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
* You can even do mixed lists&lt;br /&gt;
*# and nest them&lt;br /&gt;
*#* like this&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
; Definition list : list of definitions&lt;br /&gt;
; item : the item's definition&lt;br /&gt;
; another item&lt;br /&gt;
: the other item's definition&lt;br /&gt;
&lt;br /&gt;
* One item per line; a newline can appear before the colon, but using a space before the colon improves parsing.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
; Definition list : list of definitions&lt;br /&gt;
; item : the item's definition&lt;br /&gt;
; another item&lt;br /&gt;
: the other item's definition&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
: A colon indents a line or paragraph.&lt;br /&gt;
A manual newline starts a new paragraph.&lt;br /&gt;
&lt;br /&gt;
* This is primarily for displayed material, but is also used for discussion on [[Wikipedia:Talk page|Talk page]]s.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
: A colon indents a line or paragraph.&lt;br /&gt;
A manual newline starts a new paragraph.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=top&lt;br /&gt;
|&lt;br /&gt;
 IF a line starts with a space THEN&lt;br /&gt;
 it will be formatted exactly&lt;br /&gt;
 as typed;&lt;br /&gt;
 in a fixed-width font;&lt;br /&gt;
 lines won't wrap;&lt;br /&gt;
 ENDIF&lt;br /&gt;
&lt;br /&gt;
*This is useful for:&lt;br /&gt;
** pasting preformatted text;&lt;br /&gt;
** algorithm descriptions;&lt;br /&gt;
** program source code;&lt;br /&gt;
** [[ASCII art]];&lt;br /&gt;
** chemical structures;&lt;br /&gt;
* '''WARNING''': If you make it wide, you [[page widening|force the whole page to be wide]] and hence less readable, especially for people who use lower resolutions. Never start ordinary lines with spaces.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
 IF a line starts with a space THEN&lt;br /&gt;
 it will be formatted exactly&lt;br /&gt;
 as typed;&lt;br /&gt;
 in a fixed-width font;&lt;br /&gt;
 lines won't wrap;&lt;br /&gt;
 ENDIF&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;center&amp;gt;Centered text.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note the American spelling of &amp;quot;center&amp;quot;.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;center&amp;gt;Centered text.&amp;lt;/center&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
A [[horizontal dividing line]]:&lt;br /&gt;
this is above it&lt;br /&gt;
----&lt;br /&gt;
and this is below it.&lt;br /&gt;
&lt;br /&gt;
* Mainly useful for separating threads on Talk pages.&lt;br /&gt;
* Also used to [[Wikipedia:Disambiguation|disambiguate]] within an article without creating a separate page.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
A [[horizontal dividing line]]:&lt;br /&gt;
this is above it&lt;br /&gt;
----&lt;br /&gt;
and this is below it.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links and URLs ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! What it looks like&lt;br /&gt;
! What you type&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
London has [[public transport]].&lt;br /&gt;
&lt;br /&gt;
* A link to another Wikipedia article.&lt;br /&gt;
* Internally, the first letter of the target page is automatically capitalized and spaces are represented as underscores (typing an underscore in the link has the same effect as typing a space, but is not recommended).&lt;br /&gt;
* Thus the link above is to the [[URL]] http://www.wikipedia.org/wiki/Public_transport, which is the Wikipedia article with the name &amp;quot;Public transport&amp;quot;. See also [[Wikipedia:Canonicalization]].&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
London has [[public transport]].&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
San Francisco also has&lt;br /&gt;
[[public transport|public transportation]].&lt;br /&gt;
&lt;br /&gt;
* Same target, different name.&lt;br /&gt;
* This is a [[piped link]].&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
San Francisco also has&lt;br /&gt;
[[public transport|public transportation]].&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
San Francisco also has&lt;br /&gt;
[[public transport]]ation.&lt;br /&gt;
&lt;br /&gt;
Examples include [[bus]]es, [[taxi]]s&lt;br /&gt;
and [[streetcar]]s.&lt;br /&gt;
&lt;br /&gt;
* Endings are blended into the link.&lt;br /&gt;
* Preferred style is to use this instead of a piped link, if possible.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
San Francisco also has&lt;br /&gt;
[[public transport]]ation.&lt;br /&gt;
&lt;br /&gt;
Examples include [[bus]]es, [[taxi]]s&lt;br /&gt;
and [[streetcar]]s.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
See the [[Wikipedia:Manual of Style]].&lt;br /&gt;
&lt;br /&gt;
* A link to another [[Wikipedia:namespace|namespace]].&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
See the [[Wikipedia:Manual of Style]].&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- id=&amp;quot;link-to-section&amp;quot; valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
[[Economics#See also]] is a link&lt;br /&gt;
to a section within another page.&lt;br /&gt;
&lt;br /&gt;
[[#Links and URLs]] is a link&lt;br /&gt;
to a section on the current page.&lt;br /&gt;
&lt;br /&gt;
[[#example]] is a link to an&lt;br /&gt;
anchor that was created using&lt;br /&gt;
&amp;lt;div id=&amp;quot;example&amp;quot;&amp;gt;an id attribute&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The part after the number sign (#) must match a section heading on the page. Matches must be exact in terms of spelling, case and punctuation.  Links to non-existent sections aren't broken; they are treated as links to the top of the page.&lt;br /&gt;
* Identifiers may be created by attaching an &amp;lt;code&amp;gt;id=&amp;quot;...&amp;quot;&amp;gt;&amp;lt;/code&amp;gt; attribute to almost any HTML element.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
[[Economics#See also]] is a link&lt;br /&gt;
to a section within another page.&lt;br /&gt;
&lt;br /&gt;
[[#Links and URLs]] is a link&lt;br /&gt;
to a section on the current page.&lt;br /&gt;
&lt;br /&gt;
[[#example]] is a link to an&lt;br /&gt;
anchor that was created using&lt;br /&gt;
&amp;lt;div id=&amp;quot;example&amp;quot;&amp;gt;an id attribute&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
Automatically hide stuff in parentheses:&lt;br /&gt;
[[kingdom (biology)|kingdom]].&lt;br /&gt;
&lt;br /&gt;
Automatically hide namespace:&lt;br /&gt;
[[Wikipedia:Village Pump|Village Pump]]. &lt;br /&gt;
&lt;br /&gt;
Or both:&lt;br /&gt;
[[Wikipedia:Manual of Style (headings)|Manual of Style]]&lt;br /&gt;
&lt;br /&gt;
But not:&lt;br /&gt;
[[Wikipedia:Manual of Style#Links|]]&lt;br /&gt;
&lt;br /&gt;
* The server fills in the part after the pipe character (|) when you save the page. The next time you open the edit box you will see the expanded piped link. When [[Wikipedia:Show preview|preview]]ing your edits, you will not see the expanded form until you press '''Save''' and '''Edit''' again. The same applies to links to sections within the same page ([[#link-to-section|see previous entry]]).&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Automatically hide stuff in parentheses:&lt;br /&gt;
[[kingdom (biology)|]].&lt;br /&gt;
&lt;br /&gt;
Automatically hide namespace: &lt;br /&gt;
[[Wikipedia:Village Pump|]].&lt;br /&gt;
&lt;br /&gt;
Or both:&lt;br /&gt;
[[Wikipedia:Manual of Style (headings)|]]&lt;br /&gt;
&lt;br /&gt;
But not:&lt;br /&gt;
[[Wikipedia:Manual of Style#Links|]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
[[The weather in London]] is a page&lt;br /&gt;
that doesn't exist yet.&lt;br /&gt;
&lt;br /&gt;
* You can create it by clicking on the link (but please don't do so with this particular link).&lt;br /&gt;
* To create a new page: &lt;br /&gt;
*# Create a link to it on some other (related) page.&lt;br /&gt;
*# Save that page.&lt;br /&gt;
*# Click on the link you just made. The new page will open for editing.&lt;br /&gt;
* For more information, see [[Wikipedia:How to start a page|How to start a page]] and check out Wikipedia's [[Wikipedia:Naming conventions|naming conventions]].&lt;br /&gt;
* Please do not create a new article without linking to it from at least one other article.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
[[The weather in London]] is a page &lt;br /&gt;
that doesn't exist yet.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
[[Wikipedia:How to edit a page]] is this page.&lt;br /&gt;
&lt;br /&gt;
* [[Self link]]s appear as bold text when the article is viewed.&lt;br /&gt;
* Do not use this technique to make the article name bold in the first paragraph; see the [[Wikipedia:Manual of Style#Article titles|Manual of Style]].&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
[[Wikipedia:How to edit a page]] is this page.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
When adding a comment to a Talk page,&lt;br /&gt;
you should sign it by adding&lt;br /&gt;
three tildes to add your user name:&lt;br /&gt;
: [[User:Brockert|Ben Brockert]]&lt;br /&gt;
or four to add user name plus date/time:&lt;br /&gt;
: [[User:Brockert|Ben Brockert]] 00:18, Nov 19, 2004 (UTC)&lt;br /&gt;
Five tildes gives the date/time alone:&lt;br /&gt;
: 00:18, Nov 19, 2004 (UTC)&lt;br /&gt;
&lt;br /&gt;
* The first two both provide a link to your [[Wikipedia:user page|user page]].&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
When adding a comment to a Talk page,&lt;br /&gt;
you should sign it by adding&lt;br /&gt;
three tildes to add your user name:&lt;br /&gt;
: ~~~&lt;br /&gt;
or four for user name plus date/time:&lt;br /&gt;
: ~~~~&lt;br /&gt;
Five tildes gives the date/time alone:&lt;br /&gt;
: ~~~~~&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
* [[Wikipedia:Redirect|Redirect]] one article title to another by placing a directive like the one shown to the right on the ''first'' line of the article (such as at a page titled &amp;quot;[[USA]]&amp;quot;).&lt;br /&gt;
* Note that, while it is possible to link to a section, it is not possible to redirect to a section. For example, &amp;quot;&amp;lt;nowiki&amp;gt;#REDIRECT [[United States#History]]&amp;lt;/nowiki&amp;gt;&amp;quot; will redirect to the [[United States]] page, but not to any particular section on it. This feature '''will not''' be implemented in the future, so such redirects should not be used.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
#REDIRECT [[United States]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
* Link to a page on the same subject in another language by using a link of the form: &amp;lt;nowiki&amp;gt;[[language code:Title]]&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
* It does not matter where you put these links while editing as they will always show up in the same place when you save the page, but placement at the end of the edit box is recommended.&lt;br /&gt;
* Please see [[Wikipedia:Interlanguage links]] and the [[Wikipedia:Complete list of language wikis available|list of languages and codes]].&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
[[fr:Wikipédia:Aide]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''What links here''' and '''Related changes'''&lt;br /&gt;
pages can be linked as:&lt;br /&gt;
[[Special:Whatlinkshere/Wikipedia:How to edit a page]]&lt;br /&gt;
and&lt;br /&gt;
[[Special:Recentchangeslinked/Wikipedia:How to edit a page]]&lt;br /&gt;
&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
'''What links here''' and '''Related changes'''&lt;br /&gt;
pages can be linked as:&lt;br /&gt;
[[Special:Whatlinkshere/Wikipedia:How to edit a page]]&lt;br /&gt;
and&lt;br /&gt;
[[Special:Recentchangeslinked/Wikipedia:How to edit a page]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
A user's '''Contributions''' page can be linked as:&lt;br /&gt;
[[Special:Contributions/UserName]]&lt;br /&gt;
or&lt;br /&gt;
[[Special:Contributions/192.0.2.0]]&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
A user's '''Contributions''' page can be linked as:&lt;br /&gt;
[[Special:Contributions/UserName]]&lt;br /&gt;
or&lt;br /&gt;
[[Special:Contributions/192.0.2.0]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
* To put an article in a [[Wikipedia:Category]], place a link like the one to the right anywhere in the article. As with interlanguage links, it does not matter where you put these links while editing as they will always show up in the same place when you save the page, but placement at the end of the edit box is recommended.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
[[Category:Character sets]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
* To ''link'' to a [[Wikipedia:Category]] page without putting the article into the category, use an initial colon (:) in the link.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
[[:Category:Character sets]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- id=&amp;quot;link-external&amp;quot; valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
Three ways to link to external (non-wiki) sources:&lt;br /&gt;
# Bare URL: http://www.nupedia.com/ (bad style)&lt;br /&gt;
# Unnamed link: [http://www.nupedia.com/] ('''very bad style''')&lt;br /&gt;
# Named link: [http://www.nupedia.com Nupedia]&lt;br /&gt;
&lt;br /&gt;
:See [[MetaWikiPedia:Interwiki_map]] for the list of shortcuts.&lt;br /&gt;
&lt;br /&gt;
* Square brackets indicate an external link. Note the use of a ''space'' (not a pipe) to separate the URL from the link text in the &amp;quot;named&amp;quot; version.&lt;br /&gt;
* In the [[URL]], all symbols must be among:&amp;lt;br/&amp;gt;'''A-Z a-z 0-9 . _ \ / ~ % - + &amp;amp;amp; # ? ! = ( ) @ \x80-\xFF'''&lt;br /&gt;
* If a URL contains a character not in this list, it should be encoded by using a percent sign (%) followed by the [[hexadecimal|hex]] code of the character, which can be found in the table of [[ASCII#ASCII printable characters|ASCII printable characters]]. For example, the caret character (^) would be encoded in a URL as '''%5E'''.&lt;br /&gt;
* See [[Wikipedia:External links]] for style issues.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Three ways to link to external (non-wiki) sources:&lt;br /&gt;
# Bare URL: http://www.nupedia.com/ (bad style)&lt;br /&gt;
# Unnamed link: [http://www.nupedia.com/] ('''very bad style''')&lt;br /&gt;
# Named link: [http://www.nupedia.com Nupedia]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
Linking to other wikis:&lt;br /&gt;
# [[Interwiki]] link: [[Wiktionary:Hello]]&lt;br /&gt;
# Named interwiki link: [[Wiktionary:Hello|Hello]]&lt;br /&gt;
# Interwiki link without prefix: [[Wiktionary:Hello|Hello]]&lt;br /&gt;
&lt;br /&gt;
* All of these forms lead to the URL http://en.wiktionary.org/wiki/Hello&lt;br /&gt;
* Note that interwiki links use the ''internal'' link style.&lt;br /&gt;
* See [[MetaWikiPedia:Interwiki_map]] for the list of shortcuts; if the site you want to link to isn't on the list, use an external link ([[#link-external|see above]]).&lt;br /&gt;
* See also [[Wikipedia:How to link to Wikimedia projects]].&lt;br /&gt;
&lt;br /&gt;
Linking to another language's wiktionary:&lt;br /&gt;
# [[Wiktionary:fr:bonjour]]&lt;br /&gt;
# [[Wiktionary:fr:bonjour|bonjour]]&lt;br /&gt;
# [[Wiktionary:fr:bonjour|fr:bonjour]]&lt;br /&gt;
&lt;br /&gt;
* All of these forms lead to the URL http://fr.wiktionary.org/wiki/bonjour&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Linking to other wikis:&lt;br /&gt;
# [[Interwiki]] link: [[Wiktionary:Hello]]&lt;br /&gt;
# Named interwiki link: [[Wiktionary:Hello|Hello]]&lt;br /&gt;
# Interwiki link without prefix: [[Wiktionary:Hello|]]&lt;br /&gt;
&lt;br /&gt;
Linking to another language's wiktionary:&lt;br /&gt;
# [[Wiktionary:fr:bonjour]]&lt;br /&gt;
# [[Wiktionary:fr:bonjour|bonjour]]&lt;br /&gt;
# [[Wiktionary:fr:bonjour|]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
ISBN 012345678X&lt;br /&gt;
&lt;br /&gt;
ISBN 0-123-45678-X&lt;br /&gt;
&lt;br /&gt;
* Link to books using their [[Wikipedia:ISBN|ISBN]] numbers. This is preferred to linking to a specific online bookstore, because it gives the reader a choice of vendors.&lt;br /&gt;
* ISBN links do not need any extra markup, provided you use one of the indicated formats.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
ISBN 012345678X&lt;br /&gt;
&lt;br /&gt;
ISBN 0-123-45678-X&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=top&lt;br /&gt;
|&lt;br /&gt;
Date formats:&lt;br /&gt;
# [[July 20]], [[1969]]&lt;br /&gt;
# [[20 July]] [[1969]]&lt;br /&gt;
# [[1969]]-[[07-20]]&lt;br /&gt;
&lt;br /&gt;
* Link dates in one of the above formats, so that everyone can set their own display order. If [[Special:Userlogin|logged in]], you can use [[Special:Preferences]] to change your own date display setting.&lt;br /&gt;
* All of the above dates will appear as &amp;quot;[[20 July|20 July]] [[1969|1969]]&amp;quot; if you set your date display preference to &amp;quot;15 January 2001&amp;quot;, but as &amp;quot;[[20 July|July 20]], [[1969|1969]]&amp;quot; if you set it to &amp;quot;January 15, 2001&amp;quot;.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Date formats:&lt;br /&gt;
# [[July 20]], [[1969]]&lt;br /&gt;
# [[20 July]] [[1969]]&lt;br /&gt;
# [[1969]]-[[07-20]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
[[media:Sg_mrob.ogg|Sound]]&lt;br /&gt;
&lt;br /&gt;
*To include links to non-image uploads such as sounds, use a &amp;quot;media&amp;quot; link. For images, [[#Images|see next section]].&lt;br /&gt;
&lt;br /&gt;
Some uploaded sounds are listed at [[Wikipedia:Sound]].&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
[[media:Sg_mrob.ogg|Sound]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Images ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! What it looks like&lt;br /&gt;
! What you type&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| A picture: [[Image:Wiki.png]]&lt;br /&gt;
&lt;br /&gt;
or, with alternative text:&lt;br /&gt;
[[Image:Wiki.png|jigsaw globe]]&lt;br /&gt;
&lt;br /&gt;
or, floating to the right side of the page and with a caption:&lt;br /&gt;
[[Image:Wiki.png|frame|Wikipedia Encyclopedia]]&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or, floating to the right side of the page ''without'' a caption:&lt;br /&gt;
[[Image:Wiki.png|right|Wikipedia Encyclopedia]]&amp;lt;br clear=all&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Only images that have been uploaded to Wikipedia can be used. To upload images, use the [[Special:Upload|upload page]]. You can find the uploaded image on the [[Special:Imagelist|image list]].&lt;br /&gt;
* See the [[Wikipedia:Image use policy|image use policy]] and [[Wikipedia:Image markup|extended image markup/syntax]] pages for more hints.&lt;br /&gt;
* Alternative text, used when the image isn't loaded, in a text-only browser, or when spoken aloud, is '''strongly''' encouraged. See [[Wikipedia:Alternate text for images|Alternate text for images]] for help on choosing it.&lt;br /&gt;
* The frame tag automatically floats the image right.&lt;br /&gt;
| &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
A picture: [[Image:Wiki.png]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or, with alternative text:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[Image:Wiki.png|jigsaw globe]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or, floating to the right side of the page and with a caption:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[Image:Wiki.png|frame|Wikipedia Encyclopedia]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or, floating to the right side of the page ''without'' a caption:&lt;br /&gt;
&amp;lt;nowiki&amp;gt;[[Image:Wiki.png|right|Wikipedia Encyclopedia]]&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
Clicking on an uploaded image displays a description page, which you can also link directly to: [[:Image:Wiki.png]]&lt;br /&gt;
| &amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[:Image:Wiki.png]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
To include links to images shown as links instead of drawn on the page, use a &amp;quot;media&amp;quot; link.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;[[media:Tornado.jpg|Image of a Tornado]]&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[media:Tornado.jpg|Image of a Tornado]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Character formatting ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
! What it looks like&lt;br /&gt;
! What you type&lt;br /&gt;
|- id=&amp;quot;emph&amp;quot; valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
''Emphasize'', '''strongly''', '''''very strongly'''''.&lt;br /&gt;
* These are double, triple, and quintuple apostrophes (single-quote marks), not double-quote marks.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
''Emphasize'', '''strongly''', '''''very strongly'''''.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;math&amp;gt;\sin x + \ln y&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
sin''x'' + ln''y''&lt;br /&gt;
&amp;lt;!-- no space between roman &amp;quot;sin&amp;quot; and italic &amp;quot;x&amp;quot; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{x} = 0&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''x''' = 0&lt;br /&gt;
&lt;br /&gt;
Ordinary text should use [[#emph|wiki markup for emphasis]], and should not use &amp;lt;code&amp;gt;&amp;amp;lt;i&amp;amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;lt;b&amp;amp;gt;&amp;lt;/code&amp;gt;.  However, mathematical formulas often use italics, and sometimes use bold, for reasons unrelated to emphasis.  Complex formulas should use [[Help:Formula|&amp;lt;code&amp;gt;&amp;amp;lt;math&amp;amp;gt;&amp;lt;/code&amp;gt; markup]], and simple formulas may use &amp;lt;code&amp;gt;&amp;amp;lt;math&amp;amp;gt;&amp;lt;/code&amp;gt;; or &amp;lt;code&amp;gt;&amp;amp;lt;i&amp;amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;amp;lt;b&amp;amp;gt;&amp;lt;/code&amp;gt;; or &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;''&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;'''&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;.  According to [[Wikipedia:WikiProject Mathematics#Italicization and bolding|WikiProject Mathematics]], wiki markup is preferred over HTML markup like &amp;lt;code&amp;gt;&amp;amp;lt;i&amp;amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;amp;lt;b&amp;amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\sin x + \ln y&amp;lt;/math&amp;gt;&lt;br /&gt;
sin''x'' + ln''y''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathbf{x} = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
'''x''' = 0&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
A typewriter font for &amp;lt;tt&amp;gt;monospace text&amp;lt;/tt&amp;gt;&lt;br /&gt;
or for computer code: &amp;lt;code&amp;gt;int main()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* For semantic reasons, using &amp;lt;code&amp;gt;&amp;amp;lt;code&amp;amp;gt;&amp;lt;/code&amp;gt; where applicable is preferable to using &amp;lt;code&amp;gt;&amp;amp;lt;tt&amp;amp;gt;&amp;lt;/code&amp;gt;.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
A typewriter font for &amp;lt;tt&amp;gt;monospace text&amp;lt;/tt&amp;gt;&lt;br /&gt;
or for computer code: &amp;lt;code&amp;gt;int main()&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
You can use &amp;lt;small&amp;gt;small text&amp;lt;/small&amp;gt; for captions.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
You can use &amp;lt;small&amp;gt;small text&amp;lt;/small&amp;gt; for captions.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
You can &amp;lt;s&amp;gt;strike out deleted material&amp;lt;/s&amp;gt;&lt;br /&gt;
and &amp;lt;u&amp;gt;underline new material&amp;lt;/u&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can also mark &amp;lt;del&amp;gt;deleted material&amp;lt;/del&amp;gt; and&lt;br /&gt;
&amp;lt;ins&amp;gt;inserted material&amp;lt;/ins&amp;gt; using logical markup&lt;br /&gt;
rather than visual markup.&lt;br /&gt;
&lt;br /&gt;
* When editing regular Wikipedia articles, just make your changes and don't mark them up in any special way.&lt;br /&gt;
* When editing your own previous remarks in talk pages, it is sometimes appropriate to mark up deleted or inserted material.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
You can &amp;lt;s&amp;gt;strike out deleted material&amp;lt;/s&amp;gt;&lt;br /&gt;
and &amp;lt;u&amp;gt;underline new material&amp;lt;/u&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can also mark &amp;lt;del&amp;gt;deleted material&amp;lt;/del&amp;gt; and&lt;br /&gt;
&amp;lt;ins&amp;gt;inserted material&amp;lt;/ins&amp;gt; using logical markup&lt;br /&gt;
rather than visual markup.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''Diacritical marks:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
À Á Â Ã Ä Å &amp;lt;br/&amp;gt;&lt;br /&gt;
Æ Ç È É Ê Ë &amp;lt;br/&amp;gt;&lt;br /&gt;
Ì Í&lt;br /&gt;
Î Ï Ñ Ò &amp;lt;br/&amp;gt;&lt;br /&gt;
Ó Ô Õ&lt;br /&gt;
Ö Ø Ù &amp;lt;br/&amp;gt;&lt;br /&gt;
Ú Û Ü ß&lt;br /&gt;
à á &amp;lt;br/&amp;gt;&lt;br /&gt;
â ã ä å æ&lt;br /&gt;
ç &amp;lt;br/&amp;gt;&lt;br /&gt;
è é ê ë ì í&amp;lt;br/&amp;gt;&lt;br /&gt;
î ï ñ ò ó ô &amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;oelig; õ&lt;br /&gt;
ö ø ù ú &amp;lt;br/&amp;gt;&lt;br /&gt;
û ü ÿ&lt;br /&gt;
&lt;br /&gt;
* See [[meta:Help:Special characters|special characters]].&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;amp;amp;Agrave; &amp;amp;amp;Aacute; &amp;amp;amp;Acirc; &amp;amp;amp;Atilde; &amp;amp;amp;Auml; &amp;amp;amp;Aring; &lt;br /&gt;
&amp;amp;amp;AElig; &amp;amp;amp;Ccedil; &amp;amp;amp;Egrave; &amp;amp;amp;Eacute; &amp;amp;amp;Ecirc; &amp;amp;amp;Euml; &lt;br /&gt;
&amp;amp;amp;Igrave; &amp;amp;amp;Iacute; &amp;amp;amp;Icirc; &amp;amp;amp;Iuml; &amp;amp;amp;Ntilde; &amp;amp;amp;Ograve; &lt;br /&gt;
&amp;amp;amp;Oacute; &amp;amp;amp;Ocirc; &amp;amp;amp;Otilde; &amp;amp;amp;Ouml; &amp;amp;amp;Oslash; &amp;amp;amp;Ugrave; &lt;br /&gt;
&amp;amp;amp;Uacute; &amp;amp;amp;Ucirc; &amp;amp;amp;Uuml; &amp;amp;amp;szlig; &amp;amp;amp;agrave; &amp;amp;amp;aacute; &lt;br /&gt;
&amp;amp;amp;acirc; &amp;amp;amp;atilde; &amp;amp;amp;auml; &amp;amp;amp;aring; &amp;amp;amp;aelig; &amp;amp;amp;ccedil; &lt;br /&gt;
&amp;amp;amp;egrave; &amp;amp;amp;eacute; &amp;amp;amp;ecirc; &amp;amp;amp;euml; &amp;amp;amp;igrave; &amp;amp;amp;iacute;&lt;br /&gt;
&amp;amp;amp;icirc; &amp;amp;amp;iuml; &amp;amp;amp;ntilde; &amp;amp;amp;ograve; &amp;amp;amp;oacute; &amp;amp;amp;ocirc; &lt;br /&gt;
&amp;amp;amp;oelig; &amp;amp;amp;otilde; &amp;amp;amp;ouml; &amp;amp;amp;oslash; &amp;amp;amp;ugrave; &amp;amp;amp;uacute; &lt;br /&gt;
&amp;amp;amp;ucirc; &amp;amp;amp;uuml; &amp;amp;amp;yuml;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''Punctuation:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
¿ ¡ § ¶&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;dagger; &amp;amp;Dagger; &amp;amp;bull; &amp;amp;ndash; &amp;amp;mdash;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;lsaquo; &amp;amp;rsaquo; « »&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;lsquo; &amp;amp;rsquo; &amp;amp;ldquo; &amp;amp;rdquo;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;amp;amp;iquest; &amp;amp;amp;iexcl; &amp;amp;amp;sect; &amp;amp;amp;para;&lt;br /&gt;
&amp;amp;amp;dagger; &amp;amp;amp;Dagger; &amp;amp;amp;bull; &amp;amp;amp;ndash; &amp;amp;amp;mdash;&lt;br /&gt;
&amp;amp;amp;lsaquo; &amp;amp;amp;rsaquo; &amp;amp;amp;laquo; &amp;amp;amp;raquo;&lt;br /&gt;
&amp;amp;amp;lsquo; &amp;amp;amp;rsquo; &amp;amp;amp;ldquo; &amp;amp;amp;rdquo;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''Commercial symbols:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;trade; © ® ¢ &amp;amp;euro; ¥&amp;lt;br/&amp;gt;&lt;br /&gt;
£ ¤&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;amp;amp;trade; &amp;amp;amp;copy; &amp;amp;amp;reg; &amp;amp;amp;cent; &amp;amp;amp;euro; &amp;amp;amp;yen; &lt;br /&gt;
&amp;amp;amp;pound; &amp;amp;amp;curren;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''Subscripts:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
x&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; x&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; x&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; or&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
x&amp;amp;#8320; x&amp;amp;#8321; x&amp;amp;#8322; x&amp;amp;#8323; x&amp;amp;#8324;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
x&amp;amp;#8325; x&amp;amp;#8326; x&amp;amp;#8327; x&amp;amp;#8328; x&amp;amp;#8329;&lt;br /&gt;
&lt;br /&gt;
'''Superscripts:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
x&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt; x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; x&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; or&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
x&amp;amp;#8304; x&amp;amp;sup1; x&amp;amp;sup2; x&amp;amp;sup3; x&amp;amp;#8308;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
x&amp;amp;#8309; x&amp;amp;#8310; x&amp;amp;#8311; x&amp;amp;#8312; x&amp;amp;#8313;&lt;br /&gt;
&lt;br /&gt;
*The latter methods of sub/superscripting can't be used in the most general context, as they rely on Unicode support which may not be present on all users' machines. For the 1-2-3 superscripts, it is nevertheless preferred when possible (as with units of measurement) because most browsers have an easier time formatting lines with it.&lt;br /&gt;
&lt;br /&gt;
&amp;amp;epsilon;&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; =&lt;br /&gt;
8.85 &amp;amp;times; 10&amp;lt;sup&amp;gt;&amp;amp;minus;12&amp;lt;/sup&amp;gt;&lt;br /&gt;
C&amp;amp;sup2; / J m.&lt;br /&gt;
&lt;br /&gt;
1 [[hectare]] = [[1 E4 m&amp;amp;sup2;]]&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
x&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; x&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; x&amp;lt;sub&amp;gt;3&amp;lt;/sub&amp;gt; or&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
x&amp;amp;amp;#8320; x&amp;amp;amp;#8321; x&amp;amp;amp;#8322; x&amp;amp;amp;#8323; x&amp;amp;amp;#8324;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
x&amp;amp;amp;#8325; x&amp;amp;amp;#8326; x&amp;amp;amp;#8327; x&amp;amp;amp;#8328; x&amp;amp;amp;#8329;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
x&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt; x&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt; x&amp;lt;sup&amp;gt;3&amp;lt;/sup&amp;gt; or&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
x&amp;amp;amp;#8304; x&amp;amp;amp;sup1; x&amp;amp;amp;sup2; x&amp;amp;amp;sup3; x&amp;amp;amp;#8308;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
x&amp;amp;amp;#8309; x&amp;amp;amp;#8310; x&amp;amp;amp;#8311; x&amp;amp;amp;#8312; x&amp;amp;amp;#8313;&lt;br /&gt;
&lt;br /&gt;
&amp;amp;amp;epsilon;&amp;lt;sub&amp;gt;0&amp;lt;/sub&amp;gt; =&lt;br /&gt;
8.85 &amp;amp;amp;times; 10&amp;lt;sup&amp;gt;&amp;amp;amp;minus;12&amp;lt;/sup&amp;gt;&lt;br /&gt;
C&amp;amp;amp;sup2; / J m.&lt;br /&gt;
&lt;br /&gt;
1 [[hectare]] = [[1 E4 m&amp;amp;amp;sup2;]]&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''Greek characters:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;alpha; &amp;amp;beta; &amp;amp;gamma; &amp;amp;delta; &amp;amp;epsilon; &amp;amp;zeta;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;eta; &amp;amp;theta; &amp;amp;iota; &amp;amp;kappa; &amp;amp;lambda; &amp;amp;mu; &amp;amp;nu;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;xi; &amp;amp;omicron; &amp;amp;pi; &amp;amp;rho; &amp;amp;sigma; &amp;amp;sigmaf;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;tau; &amp;amp;upsilon; &amp;amp;phi; &amp;amp;chi; &amp;amp;psi; &amp;amp;omega;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;Gamma; &amp;amp;Delta; &amp;amp;Theta; &amp;amp;Lambda; &amp;amp;Xi; &amp;amp;Pi;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;Sigma; &amp;amp;Phi; &amp;amp;Psi; &amp;amp;Omega;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;amp;amp;alpha; &amp;amp;amp;beta; &amp;amp;amp;gamma; &amp;amp;amp;delta; &amp;amp;amp;epsilon; &amp;amp;amp;zeta; &lt;br /&gt;
&amp;amp;amp;eta; &amp;amp;amp;theta; &amp;amp;amp;iota; &amp;amp;amp;kappa; &amp;amp;amp;lambda; &amp;amp;amp;mu; &amp;amp;amp;nu; &lt;br /&gt;
&amp;amp;amp;xi; &amp;amp;amp;omicron; &amp;amp;amp;pi; &amp;amp;amp;rho; &amp;amp;amp;sigma; &amp;amp;amp;sigmaf;&lt;br /&gt;
&amp;amp;amp;tau; &amp;amp;amp;upsilon; &amp;amp;amp;phi; &amp;amp;amp;chi; &amp;amp;amp;psi; &amp;amp;amp;omega;&lt;br /&gt;
&amp;amp;amp;Gamma; &amp;amp;amp;Delta; &amp;amp;amp;Theta; &amp;amp;amp;Lambda; &amp;amp;amp;Xi; &amp;amp;amp;Pi; &lt;br /&gt;
&amp;amp;amp;Sigma; &amp;amp;amp;Phi; &amp;amp;amp;Psi; &amp;amp;amp;Omega;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''Mathematical characters:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;int; &amp;amp;sum; &amp;amp;prod; &amp;amp;radic; &amp;amp;minus; &amp;amp;plusmn; &amp;amp;infin;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;asymp; &amp;amp;prop; &amp;amp;equiv; &amp;amp;ne; &amp;amp;le; &amp;amp;ge;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;times; &amp;amp;middot; &amp;amp;divide; &amp;amp;part; &amp;amp;prime; &amp;amp;Prime;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;nabla; &amp;amp;permil; &amp;amp;deg; &amp;amp;there4; &amp;amp;alefsym; &amp;amp;oslash;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;isin; &amp;amp;notin; &amp;amp;cap; &amp;amp;cup; &amp;amp;sub; &amp;amp;sup; &amp;amp;sube; &amp;amp;supe;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;not; &amp;amp;and; &amp;amp;or; &amp;amp;exist; &amp;amp;forall; &amp;amp;rArr; &amp;amp;hArr;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;amp;rarr; &amp;amp;harr;&amp;lt;br/&amp;gt;&lt;br /&gt;
* See also [[Wikipedia:WikiProject Mathematics|WikiProject Mathematics]].&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;amp;amp;int; &amp;amp;amp;sum; &amp;amp;amp;prod; &amp;amp;amp;radic; &amp;amp;amp;minus; &amp;amp;amp;plusmn; &amp;amp;amp;infin;&lt;br /&gt;
&amp;amp;amp;asymp; &amp;amp;amp;prop; &amp;amp;amp;equiv; &amp;amp;amp;ne; &amp;amp;amp;le; &amp;amp;amp;ge;&lt;br /&gt;
&amp;amp;amp;times; &amp;amp;amp;middot; &amp;amp;amp;divide; &amp;amp;amp;part; &amp;amp;amp;prime; &amp;amp;amp;Prime;&lt;br /&gt;
&amp;amp;amp;nabla; &amp;amp;amp;permil; &amp;amp;amp;deg; &amp;amp;amp;there4; &amp;amp;amp;alefsym; &amp;amp;amp;oslash;&lt;br /&gt;
&amp;amp;amp;isin; &amp;amp;amp;notin; &amp;amp;amp;cap; &amp;amp;amp;cup; &amp;amp;amp;sub; &amp;amp;amp;sup; &amp;amp;amp;sube; &amp;amp;amp;supe;&lt;br /&gt;
&amp;amp;amp;not; &amp;amp;amp;and; &amp;amp;amp;or; &amp;amp;amp;exist; &amp;amp;amp;forall; &amp;amp;amp;rArr; &amp;amp;amp;hArr;&lt;br /&gt;
&amp;amp;amp;rarr; &amp;amp;amp;harr;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''Spacing in simple math formulas:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Obviously, ''x''&amp;amp;sup2;&amp;amp;nbsp;&amp;amp;ge;&amp;amp;nbsp;0 is true.&lt;br /&gt;
*To space things out without allowing line breaks to interrupt the formula, use non-breaking spaces: &amp;lt;tt&amp;gt;&amp;amp;amp;nbsp;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Obviously, ''x''&amp;amp;amp;sup2;&amp;amp;amp;nbsp;&amp;amp;amp;ge;&amp;amp;amp;nbsp;0 is true.&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''Complicated formulas:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;\sum_{n=0}^\infty \frac{x^n}{n!}&amp;lt;/math&amp;gt;&lt;br /&gt;
* See [[Help:Formula]] for how to use &amp;lt;tt&amp;gt;&amp;amp;lt;math&amp;gt;&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* A formula displayed on a line by itself should probably be indented by using the colon (:) character.&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
: &amp;lt;math&amp;gt;\sum_{n=0}^\infty \frac{x^n}{n!}&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''Suppressing interpretation of markup:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;Link &amp;amp;rarr; (''to'') the [[Wikipedia FAQ]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* Used to show literal data that would otherwise have special meaning.&lt;br /&gt;
* Escape all wiki markup, including that which looks like HTML tags.&lt;br /&gt;
* Does not escape HTML character references.&lt;br /&gt;
* To escape HTML character references such as &amp;lt;tt&amp;gt;&amp;amp;amp;rarr;&amp;lt;/tt&amp;gt; use &amp;lt;tt&amp;gt;&amp;amp;amp;amp;rarr;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;amp;lt;nowiki&amp;gt;Link &amp;amp;amp;rarr; (''to'') &lt;br /&gt;
the [[Wikipedia FAQ]]&amp;amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
'''Commenting page source:'''&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
''not shown when viewing page''&lt;br /&gt;
* Used to leave comments in a page for future editors.&lt;br /&gt;
* Note that most comments should go on the appropriate [[Wikipedia:Talk page|Talk page]].&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&amp;amp;lt;!-- comment here --&amp;gt;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
''(see also: [[Chess symbols in Unicode]])''&lt;br /&gt;
&lt;br /&gt;
=== Table of Contents ===&lt;br /&gt;
==== Placement of the Table of Contents (TOC) ====&lt;br /&gt;
At the current status of the wiki markup language, having at least four headers on a page triggers the TOC to appear in front of the first header (or after introductory sections).  Putting &amp;lt;nowiki&amp;gt;__TOC__&amp;lt;/nowiki&amp;gt; anywhere forces the TOC to appear at that point (instead of just before the first header).  Putting &amp;lt;nowiki&amp;gt;__NOTOC__&amp;lt;/nowiki&amp;gt; anywhere forces the TOC to disappear.  See also [[Wikipedia:Section#Compact_TOC|compact TOC]] for alphabet and year headings.&lt;br /&gt;
&lt;br /&gt;
==== Keeping headings out of the Table of Contents ====&lt;br /&gt;
&lt;br /&gt;
If you want some subheadings to not appear in the Table of Contents, then make the following replacements.&lt;br /&gt;
&lt;br /&gt;
Replace  &amp;lt;nowiki&amp;gt; == Header 2 == with &amp;lt;h2&amp;gt; Header 2 &amp;lt;/h2&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replace  &amp;lt;nowiki&amp;gt; === Header 3 === with &amp;lt;h3&amp;gt; Header 3 &amp;lt;/h3&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And so forth.&lt;br /&gt;
&lt;br /&gt;
For example, notice that the following header has the same font as the other subheaders to this &amp;quot;Tables&amp;quot; section, but the following header does not appear in the Table of Contents for this page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h4&amp;gt; This header has the h4 font, but is NOT in the Table of Contents &amp;lt;/h4&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This effect is obtained by the following line of code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;h4&amp;gt; This header has the h4 font, but is NOT in the Table of Contents &amp;lt;/h4&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tables ===&lt;br /&gt;
There are two ways to build tables: &lt;br /&gt;
*in special Wiki-markup (see [[Help:Table]])&lt;br /&gt;
*with the usual HTML elements: &amp;amp;lt;table&amp;amp;gt;, &amp;amp;lt;tr&amp;amp;gt;, &amp;amp;lt;td&amp;amp;gt; or &amp;amp;lt;th&amp;amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the latter, and a discussion on when tables are appropriate, see [[Wikipedia:How to use tables]].&lt;br /&gt;
&lt;br /&gt;
===Variables===&lt;br /&gt;
&lt;br /&gt;
''(See also [[Help:Variable]])''&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
! Code&lt;br /&gt;
! Effect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{CURRENTMONTH}}&amp;lt;/nowiki&amp;gt; || {{CURRENTMONTH}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{CURRENTMONTHNAME}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| {{CURRENTMONTHNAME}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{CURRENTMONTHNAMEGEN}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| {{CURRENTMONTHNAMEGEN}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{CURRENTDAY}}&amp;lt;/nowiki&amp;gt; || {{CURRENTDAY}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{CURRENTDAYNAME}}&amp;lt;/nowiki&amp;gt; || {{CURRENTDAYNAME}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{CURRENTYEAR}}&amp;lt;/nowiki&amp;gt; || {{CURRENTYEAR}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{CURRENTTIME}}&amp;lt;/nowiki&amp;gt; || {{CURRENTTIME}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{NUMBEROFARTICLES}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| {{NUMBEROFARTICLES}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{PAGENAME}}&amp;lt;/nowiki&amp;gt; || {{PAGENAME}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{NAMESPACE}}&amp;lt;/nowiki&amp;gt; || {{NAMESPACE}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{localurl:pagename}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| {{localurl:pagename}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{localurl:&amp;lt;/nowiki&amp;gt;''Wikipedia:Sandbox''&amp;lt;nowiki&amp;gt;|action=edit}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
| {{localurl:Wikipedia:Sandbox|action=edit}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{SERVER}}&amp;lt;/nowiki&amp;gt; || {{SERVER}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:1}}&amp;lt;/nowiki&amp;gt; || {{ns:1}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:2}}&amp;lt;/nowiki&amp;gt; || {{ns:2}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:3}}&amp;lt;/nowiki&amp;gt; || {{ns:3}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:4}}&amp;lt;/nowiki&amp;gt; || {{ns:4}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:5}}&amp;lt;/nowiki&amp;gt; || {{ns:5}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:6}}&amp;lt;/nowiki&amp;gt; || {{ns:6}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:7}}&amp;lt;/nowiki&amp;gt; || {{ns:7}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:8}}&amp;lt;/nowiki&amp;gt; || {{ns:8}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:9}}&amp;lt;/nowiki&amp;gt; || {{ns:9}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:10}}&amp;lt;/nowiki&amp;gt; || {{ns:10}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:11}}&amp;lt;/nowiki&amp;gt; || {{ns:11}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:12}}&amp;lt;/nowiki&amp;gt; || {{ns:12}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:13}}&amp;lt;/nowiki&amp;gt; || {{ns:13}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:14}}&amp;lt;/nowiki&amp;gt; || {{ns:14}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{ns:15}}&amp;lt;/nowiki&amp;gt; || {{ns:15}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;{{SITENAME}}&amp;lt;/nowiki&amp;gt; || {{SITENAME}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''NUMBEROFARTICLES''' is the number of pages in the main namespace which contain a link and are not a redirect, i.e. number of articles, stubs containing a link, and disambiguation pages.&lt;br /&gt;
&lt;br /&gt;
'''CURRENTMONTHNAMEGEN''' is the genitive (possessive) grammatical form of the month name, as used in some languages; '''CURRENTMONTHNAME''' is the nominative (subject) form, as usually seen in English.&lt;br /&gt;
&lt;br /&gt;
In languages where it makes a difference, you can use constructs like &amp;lt;nowiki&amp;gt;{{grammar:case|word}}&amp;lt;/nowiki&amp;gt; to convert a word from the nominative case to some other case.  For example, &amp;lt;nowiki&amp;gt;{{grammar:genitive|{{CURRENTMONTHNAME}}}}&amp;lt;/nowiki&amp;gt; means the same as &amp;lt;nowiki&amp;gt;{{CURRENTMONTHNAMEGEN}}&amp;lt;/nowiki&amp;gt;. &amp;lt;!-- Is there a reference for this, other than the source code (for example, phase3/languages/Lnaguage*.php) ? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Templates===&lt;br /&gt;
&lt;br /&gt;
The [[Wikipedia:MediaWiki|MediaWiki]] software used by Wikipedia has support for templates. This means standardized text chunks (such as [[Wikipedia:Template messages|boilerplate]] text) can be inserted into articles. For example, typing &amp;lt;nowiki&amp;gt;{{stub}}&amp;lt;/nowiki&amp;gt; will appear as &amp;quot;''This article is a [[Wikipedia:The perfect stub article|stub]]. You can help Wikipedia by [[Wikipedia:Find or fix a stub|expanding it]].''&amp;quot; when the page is saved. See [[Wikipedia:Template messages]] for the complete list. Other commonly used ones are: &amp;lt;nowiki&amp;gt;{{disambig}}&amp;lt;/nowiki&amp;gt; for disambiguation pages, &amp;lt;nowiki&amp;gt;{{spoiler}}&amp;lt;/nowiki&amp;gt; for spoiler warnings and &amp;lt;nowiki&amp;gt;{{sectstub}}&amp;lt;/nowiki&amp;gt; like an article stub but for a section. There are many subject-specific stubs e.g.: &amp;lt;nowiki&amp;gt; {{Geo-stub}}, {{Hist-stub}} and {{Linux-stub}}&amp;lt;/nowiki&amp;gt;. For a complete list of stubs see [[Wikipedia:Template messages/Stubs]].&lt;br /&gt;
&lt;br /&gt;
===Hiding the edit links===&lt;br /&gt;
&lt;br /&gt;
Insert '''&amp;lt;nowiki&amp;gt;__NOEDITSECTION__&amp;lt;/nowiki&amp;gt;''' into the document to suppress the edit links that appear next to every section header.&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=G2_specs_part1&amp;diff=83</id>
		<title>G2 specs part1</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=G2_specs_part1&amp;diff=83"/>
		<updated>2005-04-02T22:03:31Z</updated>

		<summary type="html">&lt;p&gt;Spooky: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;h1&amp;gt;Gnutella2 Specifications part one&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I realise this has been quite a long time in coming, however I'm a&lt;br /&gt;
strong believer in getting some field experience with new ideas&lt;br /&gt;
before asserting that they will work (especially in a distributed&lt;br /&gt;
environment). This has been productive and as a direct result of&lt;br /&gt;
the experience gained, several significant changes have been evolved&lt;br /&gt;
into the proposal over the past few weeks. That process of testing&lt;br /&gt;
is not yet complete, however I'm now confident that the basic ideas&lt;br /&gt;
are relatively sound.&lt;br /&gt;
&lt;br /&gt;
I'm also very interested in the thoughts of everyone here in the&lt;br /&gt;
GDF. I tend to have strongly held views of how things should work,&lt;br /&gt;
but the problem with a lone designer is that you rarely cover all&lt;br /&gt;
the possible angles. It's only by working with a group of&lt;br /&gt;
appropriately qualified people that there is any hope of exploring a&lt;br /&gt;
problem fully. So, I invite everyone to comment, criticise and&lt;br /&gt;
discuss.&lt;br /&gt;
&lt;br /&gt;
Finally, to reiterate some of the stuff I posted last week: the&lt;br /&gt;
entire Gnutella2 concept is intended to be an open advancement in&lt;br /&gt;
the Gnutella world. I recognise that the GDF is not a standards&lt;br /&gt;
body and our purpose here is not to flesh out a new specification,&lt;br /&gt;
however I hope that this effort will spark some intelligent&lt;br /&gt;
discussion of the ideas contained within.&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 concept contains four parts:&lt;br /&gt;
&lt;br /&gt;
* A new protocol&lt;br /&gt;
* A new data transport architecture&lt;br /&gt;
* New base services, including search&lt;br /&gt;
* An implementation standard&lt;br /&gt;
&lt;br /&gt;
While I feel that all four parts are important to move forward with,&lt;br /&gt;
I suspect that the third part, the new base services and in&lt;br /&gt;
particular the new search mechanism is likely to be the area of&lt;br /&gt;
greatest interest for everyone here. Thus I'll focus on the&lt;br /&gt;
searching aspect of Gnutella2 in this post, and save discussion of&lt;br /&gt;
the other items for later.&lt;br /&gt;
&lt;br /&gt;
(A final word on the first two points in this post: I do acknowledge&lt;br /&gt;
that it is entirely possible to implement most if not all new&lt;br /&gt;
features within the framework of the original Gnutella spec, working&lt;br /&gt;
around its limitations with things like GGEP. However I would argue&lt;br /&gt;
that in doing that we are limiting ourselves unnecessarily, not to&lt;br /&gt;
mention producing less than elegant designs and increasing overall&lt;br /&gt;
complexity. The original specification united us as developers&lt;br /&gt;
however if we are unable to move logically beyond it now, I think&lt;br /&gt;
that reflects an inability on our part to work together.)&lt;br /&gt;
&lt;br /&gt;
In any case, this post is focused on the search architecture of&lt;br /&gt;
Gnutella2. The search framework is built upon the previous two&lt;br /&gt;
levels of implementation, however it is possible (and more&lt;br /&gt;
meaningful) to discuss it at a higher level now. I'll detail the&lt;br /&gt;
specifics of my implementation later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
It's important to take a step back and analyse exactly what a search&lt;br /&gt;
system should be able to do. In an ideal world of unlimited&lt;br /&gt;
bandwidth and CPU resources, it should be possible to execute a&lt;br /&gt;
search and locate every matching object present on the network&lt;br /&gt;
instantly. In the real world compromises must be made, but the&lt;br /&gt;
choice of compromise is important.&lt;br /&gt;
&lt;br /&gt;
=== An Analysis of Gnutella1 ===&lt;br /&gt;
&lt;br /&gt;
In the original (Gnutella1) architecture, the compromise is one of&lt;br /&gt;
search scope. Performing a search has a more or less fixed cost,&lt;br /&gt;
occurs over a more or less fixed time interval and covers an area of&lt;br /&gt;
more or less fixed size (but which is randomly selected).&lt;br /&gt;
Unfortunately, when mapped from the technical view to the outcome&lt;br /&gt;
view, it is evident that this compromise is not very desirable: In&lt;br /&gt;
an ideal scenario, Gnutella1 searches tend to find every matching&lt;br /&gt;
result within a fixed (but unknown) area of the network. There is&lt;br /&gt;
little or no opportunity to scale the search to match the rarity of&lt;br /&gt;
the target object (TTL and number of injection points can be scaled,&lt;br /&gt;
but have a high cost).&lt;br /&gt;
&lt;br /&gt;
=== An Optimal Search System ===&lt;br /&gt;
&lt;br /&gt;
It is my view that an optimal search system, under real world&lt;br /&gt;
limitations should have the following properties:&lt;br /&gt;
&lt;br /&gt;
* It should be able to guarantee that if a matching object exists somewhere, it can be found&lt;br /&gt;
* It should have a means of scaling to match the rarity of the object that is not associated with a high cost to the network&lt;br /&gt;
* In a situation of limited resources, the ability to find at least some instances of a rare object should be of higher importance than the ability to find every instance of a common object.&lt;br /&gt;
&lt;br /&gt;
In other words, the principal difference between my &amp;quot;optimal&amp;quot; search&lt;br /&gt;
objectives and the Gnutella1 model is that I am placing a higher&lt;br /&gt;
priority on the ability to find an object anywhere, than the ability&lt;br /&gt;
to find every object in a limited range. My rationale for this is&lt;br /&gt;
that:&lt;br /&gt;
&lt;br /&gt;
* The ability to locate at least one instance of an object is very important, because without it no further action is possible&lt;br /&gt;
* Having located one instance of an object, there are other means of finding additional locations (if desired), such as a download mesh&lt;br /&gt;
* In a distributed hash table environment, a general search system only needs to locate a URN matching a search, after which the DHT can efficiently provide additional locations where that object may be found.&lt;br /&gt;
* Last but not least, the inability to find an object is demoralising for users&lt;br /&gt;
&lt;br /&gt;
The third point there is quite important – I'm very keen on the use&lt;br /&gt;
of a large scale distributed hash table within Gnutella in the near&lt;br /&gt;
future (some work is going on there already). Thus the design of&lt;br /&gt;
this search system is such that it is not superseded, but rather&lt;br /&gt;
forms a part of, a DHT-enhanced search solution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== A search model meeting these objectives ===&lt;br /&gt;
&lt;br /&gt;
It is well understood that in order to design a distributed search&lt;br /&gt;
system which has at least one scalable variable, there needs to be a&lt;br /&gt;
means of controlling the progress of the search. (Gnutella1 of&lt;br /&gt;
course fails on this principle as it involves &amp;quot;unleashing&amp;quot; a search&lt;br /&gt;
and waiting for the results) Controlled searches thus lend&lt;br /&gt;
themselves to an iterative, rather than recursive, approach. There&lt;br /&gt;
are three commonly known approaches:&lt;br /&gt;
&lt;br /&gt;
* The random walker approach, in which the search maintains periodic contact with its originator, allowing the originator to continue or abort progress.&lt;br /&gt;
* The random or crawling mesh approach, in which the originator iteratively contacts nodes on the network until all nodes have been contacted or a desired condition has been reached.&lt;br /&gt;
* The guided mesh approach, in which the originator iteratively contacts nodes seeking a particular node which is responsible for a particular URN (DHT).&lt;br /&gt;
&lt;br /&gt;
At the most simplistic level, the Gnutella2 network search model&lt;br /&gt;
takes the second approach: an iterative crawl of all nodes on the&lt;br /&gt;
network until a desired condition is reached. It also makes use of&lt;br /&gt;
the random walker model for another, non-search function, however&lt;br /&gt;
that is outside the scope of this discussion. It is envisioned that&lt;br /&gt;
the third DHT approach will be incorporated in the future as a more&lt;br /&gt;
efficient way of locating nodes with an instance of a URN obtained&lt;br /&gt;
from the current search model.&lt;br /&gt;
&lt;br /&gt;
In this respect, the use of an iterative crawl is similar to the&lt;br /&gt;
GUESS proposal. The differences between this implementation and&lt;br /&gt;
GUESS become apparent in the process and optimisations described&lt;br /&gt;
below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Real World Considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Generic Viability ===&lt;br /&gt;
&lt;br /&gt;
Implementing a node crawl directly is not viable for a public, large&lt;br /&gt;
scale network for several reasons:&lt;br /&gt;
&lt;br /&gt;
* There are too many nodes to contact&lt;br /&gt;
* The cost of contacting a node is too high for the expected number of matching objects on that node (the probability of one match is often a lot lower than 1%)&lt;br /&gt;
* Not all nodes can be contacted directly (NATs, firewalls)&lt;br /&gt;
* Most nodes do not have the resources to handle and respond to queries from every other node&lt;br /&gt;
&lt;br /&gt;
=== Increasing Network Density ===&lt;br /&gt;
&lt;br /&gt;
One of the solutions is of course something we have been using for&lt;br /&gt;
some time in the Gnutella world – organising nodes into a two level&lt;br /&gt;
hierarchy, in which &amp;quot;high capacity&amp;quot; nodes shield &amp;quot;low capacity&amp;quot;&lt;br /&gt;
nodes. High capacity nodes have been called Ultrapeers&lt;br /&gt;
or &amp;quot;Supernodes&amp;quot; in the past, although I have used the term &amp;quot;Hubs&amp;quot; as&lt;br /&gt;
it seems to make the purpose much more clear to the general user&lt;br /&gt;
population.&lt;br /&gt;
&lt;br /&gt;
Hubs solve several issues:&lt;br /&gt;
&lt;br /&gt;
* Hubs can effectively answer queries for their leaves, so:&lt;br /&gt;
* Only hubs need to be contacted in a mesh crawl, reducing the number of nodes to contact&lt;br /&gt;
* Contacting one hub allows a large number of nodes to be searched, increasing the probability of locating an object and thus reducing the relative cost of contact&lt;br /&gt;
* Hubs must be able to be contacted directly, allowing un-contactable nodes to exist and participate as leaves&lt;br /&gt;
* Hubs can shield their leaves from the bulk of the bandwidth and CPU requirements&lt;br /&gt;
&lt;br /&gt;
These facts are not new, and many of them apply to traditional&lt;br /&gt;
Gnutella1 as well. However in the Gnutella2 world, the reduced cost&lt;br /&gt;
of contact becomes a positive factor where it previously was not.&lt;br /&gt;
Similarly, the total number of nodes (now hubs) which could be&lt;br /&gt;
contacted for a complete network-wide search is reduced.&lt;br /&gt;
&lt;br /&gt;
=== Problems with Gnutella Hubs ===&lt;br /&gt;
&lt;br /&gt;
It is interesting to note that several other successful distributed&lt;br /&gt;
networks use a similar model, grouping a large number of leaf nodes&lt;br /&gt;
under a hub node, although different terminology is often used. The&lt;br /&gt;
server-based model is obviously the extreme version of this, where&lt;br /&gt;
all participants in the searchable area are connected to a common&lt;br /&gt;
server. Moving away from this to a more distributed model,&lt;br /&gt;
additional servers (-&amp;gt; hubs) are employed, with searches being&lt;br /&gt;
processed by each.&lt;br /&gt;
&lt;br /&gt;
What these other networks tend to rely upon, however, is having a&lt;br /&gt;
very large number of leaf nodes per hub. This very high leaf&lt;br /&gt;
density makes searching very efficient, because the relative cost of&lt;br /&gt;
contacting each hub and the total number of hubs are both low. In&lt;br /&gt;
the Gnutella world, our ultrapeers/hubs tend to have far fewer&lt;br /&gt;
leaves. This presents a problem: there are too many hubs to&lt;br /&gt;
contact, and the relative cost per hub is too high.&lt;br /&gt;
&lt;br /&gt;
These problems must be solved, or the time necessary to execute a&lt;br /&gt;
search will be far too high for reasonably rare and very rare&lt;br /&gt;
objects.&lt;br /&gt;
&lt;br /&gt;
== Gnutella2 Solutions ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 model solves the &amp;quot;too many hubs&amp;quot; problem in two ways.&lt;br /&gt;
&lt;br /&gt;
=== Optimising Hub to Leaf Communication ===&lt;br /&gt;
&lt;br /&gt;
The first solution tackles the problem at its cause – to reduce the&lt;br /&gt;
number of hubs; the number of leaves per hub must be increased. The&lt;br /&gt;
limiting factor on the number of leaves per hub is the capacity of a&lt;br /&gt;
particular hub to support a large number of leaves. Some aspects of&lt;br /&gt;
this limitation are fixed, for example the amount of CPU power and&lt;br /&gt;
bandwidth available to a particular hub. This can only be addressed&lt;br /&gt;
by choosing better hubs (which is also important)&lt;br /&gt;
&lt;br /&gt;
However, other aspects are highly variable and good targets for&lt;br /&gt;
optimisation: the cost of each additional leaf can be reduced.&lt;br /&gt;
Gnutella2 does this by:&lt;br /&gt;
&lt;br /&gt;
* Leaves send their hub an extremely large query hash table which applies to all query traffic. This results in a substantially lower bandwidth requirement for each leaf, at the cost of additional memory on the hub. The latter is reduced by storing the tables in compressed hierarchical form to balance memory and CPU requirements. Patch tables are sent in simple 1-bit packed form, and the necessary levels are generated and compressed by the hub upon receipt of new or patch data.&lt;br /&gt;
&lt;br /&gt;
* All hub to leaf traffic is compressed using the deflate algorithm. This provides a significant reduction in bandwidth requirement for each leaf, once again at the cost of state memory and some CPU on the hub. The CPU requirement is not as significant as might be expected, as the large query hash tables filter the majority of traffic leaving only a vast minority for compression. The combination of these two systems really squeezes the absolute most out of hub to leaf bandwidth. The memory requirement can be halved by not compressing leaf to hub bandwidth, which is almost non-existent in Gnutella2.&lt;br /&gt;
&lt;br /&gt;
* Leaves are given the option of uploading a compressed snapshot of their library to their hub. I have not finished experimenting with this yet, but to spell out the obvious advantages and disadvantages: hub to leaf traffic is eliminated, memory and CPU requirements on the hub increase. By using a similar compressed hierarchical storage and access system I expect to be able to make the impact manageable.&lt;br /&gt;
&lt;br /&gt;
The savings in bandwidth requirement per leaf provided by these&lt;br /&gt;
optimisations, at minimal extra cost to the hub in terms of CPU and&lt;br /&gt;
memory requirements, allow a typical hub to serve a much larger&lt;br /&gt;
number of leaves that it would normally be able to. This helps to&lt;br /&gt;
increase the average leaves per hub, and with appropriate hub&lt;br /&gt;
promotion control, reduce the total number of hubs. To map that&lt;br /&gt;
back to the original assertion, it reduces the relative cost of&lt;br /&gt;
contacting each hub and therefore also the amount of time taken to&lt;br /&gt;
perform a search.&lt;br /&gt;
&lt;br /&gt;
=== Leveraging Inter-Hub Communication ===&lt;br /&gt;
&lt;br /&gt;
Gnutella2 also makes another key optimisation. Assuming the total&lt;br /&gt;
number of hubs cannot easily be reduced any further, there are other&lt;br /&gt;
ways to reduce the relative cost of contacting each hub and reduce&lt;br /&gt;
the effective number of hubs which actually need to be contacted.&lt;br /&gt;
&lt;br /&gt;
In the Gnutella2 search model, when a particular hub receives a&lt;br /&gt;
query from a query originator, it not only processes it locally and&lt;br /&gt;
forwards it to its leaves (where relevant), it also forwards it to&lt;br /&gt;
its neighbouring hubs. These hubs in turn process the query locally&lt;br /&gt;
and forward it to their leaves (where relevant), however they do not&lt;br /&gt;
forward it any further. To make a comparison with the Gnutella1&lt;br /&gt;
broadcast model, this is similar to executing a query with TTL=2.&lt;br /&gt;
In Gnutella2 there are no TTLs involved, rather fixed routing rules&lt;br /&gt;
are used to ensure that any hub receiving a query will always&lt;br /&gt;
forward it to its leaves, and may forward it to its neighbouring&lt;br /&gt;
hubs if the origin was not already a neighbouring hub. The &amp;quot;two&lt;br /&gt;
level&amp;quot; approach is not arbitrarily chosen, and its significance is&lt;br /&gt;
detailed later.&lt;br /&gt;
&lt;br /&gt;
This behaviour means that for the cost of sending a query to a&lt;br /&gt;
single hub, a small &amp;quot;cluster&amp;quot; of connected hubs are actually&lt;br /&gt;
searched. For a typical hub with 5 neighbours, 6 hubs and their&lt;br /&gt;
leaves are searched at once. In essence, &amp;quot;hub clustering&amp;quot; offsets&lt;br /&gt;
Gnutella's lower average leaves per hub. The elimination of&lt;br /&gt;
broadcast &amp;quot;flood&amp;quot; traffic also means that hubs could actually have a&lt;br /&gt;
higher number of neighbour hubs, further increasing the cluster size&lt;br /&gt;
and lowering the cost per contact.&lt;br /&gt;
&lt;br /&gt;
At first examination the cluster effect would appear only to benefit&lt;br /&gt;
the search originator by reducing the amount of outbound query&lt;br /&gt;
traffic and the time taken to contact every node (if required). In&lt;br /&gt;
the unoptimised case, every hub would still need to receive every&lt;br /&gt;
query, even if it was forwarded by an intermediary hub. The&lt;br /&gt;
benefits to the search originator are important, however further&lt;br /&gt;
optimisations allow the cluster effect to benefit hubs as well.&lt;br /&gt;
&lt;br /&gt;
At the first level, hub to hub links are compressed using the&lt;br /&gt;
deflate algorithm in both directions. This is an important effect,&lt;br /&gt;
as the nature of UDP query traffic is that it cannot generally be&lt;br /&gt;
compressed (it's too small and there is no reliable context). Thus&lt;br /&gt;
receiving a query via UDP is much less efficient in terms of&lt;br /&gt;
bandwidth than receiving one via TCP. But as we know, UDP has other&lt;br /&gt;
benefits. A compromise must be struck, and the retransmission of&lt;br /&gt;
query packets within the hub cluster provides an excellent&lt;br /&gt;
opportunity. A single inbound UDP (inefficient) query is received&lt;br /&gt;
by one hub, which is then forwarded to the other 4+ hubs in the&lt;br /&gt;
cluster via TCP (efficient). One (random) hub takes the extra load;&lt;br /&gt;
the other (majority) receive the benefit.&lt;br /&gt;
&lt;br /&gt;
At the next level up, query retransmission within the hub cluster is&lt;br /&gt;
filtered by very large query hash tables. Gnutella2 hubs regularly&lt;br /&gt;
exchange query hash table data, which is a composite of the hub's&lt;br /&gt;
own available objects and the hash tables of its leaves. Because&lt;br /&gt;
retransmission is restricted to a neighbour and its leaves, the use&lt;br /&gt;
of filtering tables at this level is perfectly acceptable (and&lt;br /&gt;
accurate). The hash table associated with a particular hub at an&lt;br /&gt;
instant in time is the same no matter which neighbour views it.&lt;br /&gt;
&lt;br /&gt;
The use of query hash tables in hub to hub links makes it possible&lt;br /&gt;
to filter out query traffic which would not result in a hit,&lt;br /&gt;
reducing the hub to hub bandwidth requirements. This not only makes&lt;br /&gt;
the hub cluster concept more efficient, but also allows hubs to have&lt;br /&gt;
more leaves. Through clever hash table tricks, the size of the hash&lt;br /&gt;
tables employed on hub to hub links can be larger than that retained&lt;br /&gt;
on hub to leaf links (to offset the higher density). Methods of&lt;br /&gt;
patching hash tables as they change to reduce update bandwidth are&lt;br /&gt;
well documented also.&lt;br /&gt;
&lt;br /&gt;
=== Summary ===&lt;br /&gt;
&lt;br /&gt;
The primary focus of these solutions has been to increase the&lt;br /&gt;
efficiency of the system, in a situation of limited resources.&lt;br /&gt;
Decreasing the number of hubs to be contacted and decreasing the&lt;br /&gt;
effective cost of each contact (which includes both reducing the&lt;br /&gt;
cost of sending the query, and the cost of receiving and processing&lt;br /&gt;
it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calculations ==&lt;br /&gt;
&lt;br /&gt;
While the optimisations described previously provide significant&lt;br /&gt;
performance improvements, they also add complexity. For a small&lt;br /&gt;
network this complexity is not particularly necessary. However as&lt;br /&gt;
the number of nodes on the network grows, the benefits of higher&lt;br /&gt;
leaf density and lower cost of contact become much greater.&lt;br /&gt;
&lt;br /&gt;
For a 500,000 node network with presently loaded ultrapeers&lt;br /&gt;
averaging about 150 leaves each, there will be approximately 3333&lt;br /&gt;
ultrapeers. Every one of these 3333 ultrapeers must be contacted to&lt;br /&gt;
achieve a global search, incurring the cost of transmission on the&lt;br /&gt;
search originator and the cost of receiving on each ultrapeer (plus&lt;br /&gt;
leaf costs depending on how that is set up). None of these queries&lt;br /&gt;
can be compressed.&lt;br /&gt;
&lt;br /&gt;
If the same network is built with optimised hubs averaging 500 nodes&lt;br /&gt;
each, there will be approximately 1000 hubs. If each hub is&lt;br /&gt;
connected to an average of 5 neighbours, less than 170 hubs need to&lt;br /&gt;
be contacted by the search originator via UDP. The originator can&lt;br /&gt;
do that faster and more reliably. The other approximately 830 hubs&lt;br /&gt;
and their leaves are still effectively searched, but incur a reduced&lt;br /&gt;
(compressed) penalty, if any at all (QHT filtering).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hub Management ==&lt;br /&gt;
&lt;br /&gt;
This section deals with some of the more mundane but important&lt;br /&gt;
aspects of operation.&lt;br /&gt;
&lt;br /&gt;
=== Crawling the Network ===&lt;br /&gt;
&lt;br /&gt;
It is not viable for every node to maintain an accurate table of&lt;br /&gt;
every hub on the network, if the network is of any reasonable size.&lt;br /&gt;
The storage requirement is not significant, but the overhead in&lt;br /&gt;
maintaining it is. It makes more sense to progressively discover&lt;br /&gt;
the extent of the network as it is traversed. This provides a sweep&lt;br /&gt;
of the current extent over a period of time (i.e. not a snapshot),&lt;br /&gt;
but its good enough.&lt;br /&gt;
&lt;br /&gt;
To achieve this, each hub which is contacted must provide additional&lt;br /&gt;
information about where the search originator might look next. In a&lt;br /&gt;
simple system this is quite straight forward, however the use of the&lt;br /&gt;
hub clustering technique (while vastly increasing efficiency)&lt;br /&gt;
complicates matters somewhat.&lt;br /&gt;
&lt;br /&gt;
=== Query Acknowledgements ===&lt;br /&gt;
&lt;br /&gt;
Upon receiving a valid query from a search originator, a hub&lt;br /&gt;
immediately returns a query acknowledgement. The acknowledgement is&lt;br /&gt;
tagged for the specific search ID and includes two lists of&lt;br /&gt;
information: the hubs which have received the query (including the&lt;br /&gt;
current hub itself), and a selection of hubs to try.&lt;br /&gt;
&lt;br /&gt;
The list of hubs which received the query will be every neighbouring&lt;br /&gt;
Gnutella2 hub, including hubs for which the query failed the QHT&lt;br /&gt;
test. The query originator adds these hubs to the &amp;quot;done list&amp;quot;, and&lt;br /&gt;
avoids sending them direct queries. Note that additional&lt;br /&gt;
information is also returned, such as the leaf count for each hub,&lt;br /&gt;
so that the originator can display search statistics.&lt;br /&gt;
&lt;br /&gt;
The list of other hubs to try is more complex. The hubs in the list&lt;br /&gt;
must be accurate, or time and resources are wasted on a large&lt;br /&gt;
scale. The only hubs which the hub can be 100% sure of are its&lt;br /&gt;
neighbours, but they are not eligible because they have already been&lt;br /&gt;
queried. To solve this problem, every Gnutella2 node knows every&lt;br /&gt;
neighbour, and every neighbour's neighbour. This applies partially&lt;br /&gt;
to leaves too, in that leaves must know their neighbours and their&lt;br /&gt;
neighbours' neighbours; however only hubs are included in the data&lt;br /&gt;
(leaf addresses are of no use). This information is kept up to date&lt;br /&gt;
quite stringently.&lt;br /&gt;
&lt;br /&gt;
As a result, a hub sending a query acknowledgement packet can&lt;br /&gt;
include its neighbours as &amp;quot;searched&amp;quot;, and its neighbours' neighbours&lt;br /&gt;
as &amp;quot;try these&amp;quot;. This allows a logical crawling process to occur&lt;br /&gt;
unimpeded by hub clusters.&lt;br /&gt;
&lt;br /&gt;
=== General Hub Discovery ===&lt;br /&gt;
&lt;br /&gt;
Crawling through the network logically has some benefits; however a&lt;br /&gt;
more random approach can also be beneficial. To aid this, a few&lt;br /&gt;
random hubs from the active hub cache are also returned in query&lt;br /&gt;
acknowledgements. Random cached hubs are exchanged between all&lt;br /&gt;
nodes on the network, much like the &amp;quot;X-Try-Ultrapeers&amp;quot; header,&lt;br /&gt;
except as a continual process. Finally, hub walker advertisements&lt;br /&gt;
use a random walker approach to advertise long-running hubs to&lt;br /&gt;
distant points in the web. All indirect hub references are covered&lt;br /&gt;
by a last seen time allowing more recently confirmed hubs to be&lt;br /&gt;
prioritised and limiting the impact of lost hubs. (Connection&lt;br /&gt;
attempts on former ultrapeer IPs has been a significant problem in&lt;br /&gt;
Gnutella1).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Security ==&lt;br /&gt;
&lt;br /&gt;
The term &amp;quot;security&amp;quot; can have many meanings in a peer-to-peer context:&lt;br /&gt;
&lt;br /&gt;
* Preventing denial of service attack upon the network&lt;br /&gt;
* Preventing the network from being used to launch an attack on other hosts&lt;br /&gt;
* Preventing the originator of a search from being identified&lt;br /&gt;
* Preventing the originator of a shared object from being identified&lt;br /&gt;
* Preventing false shared objects from being propagated&lt;br /&gt;
&lt;br /&gt;
The first two points relate to securing the network structure&lt;br /&gt;
against misuse. The next two relate to anonymity, while the last is&lt;br /&gt;
more difficult to classify. As a developer I am most interested in&lt;br /&gt;
the first two items, and also to some extent the last item.&lt;br /&gt;
&lt;br /&gt;
=== Risks Associated With UDP ===&lt;br /&gt;
&lt;br /&gt;
Any distributed network (and particularly those which involve the&lt;br /&gt;
trading of host addresses) must take special consideration of&lt;br /&gt;
possible misuse of its nodes. In the original Gnutella network&lt;br /&gt;
there is already a significant potential to launch denial of service&lt;br /&gt;
attacks upon third party hosts by misrepresenting host addresses,&lt;br /&gt;
which then propagate through the network, resulting in thousands of&lt;br /&gt;
unsolicited connection attempts. Gnutella2 attempts to address this&lt;br /&gt;
somewhat by keeping track of last seen times for all hub addresses,&lt;br /&gt;
however there is a larger security concern: UDP.&lt;br /&gt;
&lt;br /&gt;
At the lowest level, TCP connections are reasonably protected by the&lt;br /&gt;
need to establish a stream between two hosts. Forging the return&lt;br /&gt;
address of a connection establishment packet results only in a&lt;br /&gt;
single (small) response packet being directed at the target host.&lt;br /&gt;
Once the stream is established, traffic cannot be directed to other&lt;br /&gt;
hosts.&lt;br /&gt;
&lt;br /&gt;
UDP on the other hand does not benefit from the security of a stream&lt;br /&gt;
connection. A received datagram may not necessarily have originated&lt;br /&gt;
from where its header would suggest. In a distributed search&lt;br /&gt;
scenario this can have a very serious consequence: forging a query&lt;br /&gt;
packet for a common object and sending it to a hub could result in a&lt;br /&gt;
large volume of search results being delivered to the forged, third&lt;br /&gt;
party host address. The more common the query term and the more&lt;br /&gt;
leaves attached to the hubs (including the effects of hub&lt;br /&gt;
clustering) and the larger the volume of return traffic. In this&lt;br /&gt;
situation the network is acting as a traffic amplifier, allowing the&lt;br /&gt;
attacker to anonymously transmit a small volume, but hit their&lt;br /&gt;
target with a large and untraceable amount of traffic.&lt;br /&gt;
&lt;br /&gt;
Similarly, attacks can be directed upon the network itself. A&lt;br /&gt;
malicious host could flood one or more hubs with query traffic using&lt;br /&gt;
random return addresses to thwart any flood control mechanism,&lt;br /&gt;
causing an overload. While nothing can be done about unsolicited&lt;br /&gt;
traffic to a node on the network (which is completely independent&lt;br /&gt;
from the peer to peer system anyway), the use of UDP can eliminate&lt;br /&gt;
the important ability to detect and ignore such abuse.&lt;br /&gt;
&lt;br /&gt;
=== Gnutella2 Solution – Query Keys ===&lt;br /&gt;
&lt;br /&gt;
A solution is built into the Gnutella2 query model. Before a search&lt;br /&gt;
originator can transmit a query to a particular hub, it must obtain&lt;br /&gt;
a &amp;quot;query key&amp;quot; for that hub and include it in the transmission.&lt;br /&gt;
Query keys are unique to the hub generating them and the return&lt;br /&gt;
address with which they are associated and generally expire after a&lt;br /&gt;
relatively long period of time.&lt;br /&gt;
&lt;br /&gt;
Originators request a query key by sending a query key request to a&lt;br /&gt;
hub, which includes the intended return address for the key. The&lt;br /&gt;
hub generates a key unique to that return address and dispatches it&lt;br /&gt;
there. This makes it impossible to get a query key for an IP which&lt;br /&gt;
you do not control, and prevents keys from being shared between two&lt;br /&gt;
nodes (key stealing).&lt;br /&gt;
&lt;br /&gt;
When receiving a query from a foreign node, Gntuella2 hubs check the&lt;br /&gt;
query key against the one they have issued for the query's requested&lt;br /&gt;
return address and proceed only if there is a match. If and only if&lt;br /&gt;
the query key matches will the query acknowledgement be sent, or the&lt;br /&gt;
search processed locally and forwarded to local leaves and&lt;br /&gt;
neighbouring hubs.&lt;br /&gt;
&lt;br /&gt;
This has several positive effects. If a query does not have a valid&lt;br /&gt;
key for the receiving hub, it will not be processed and will thus&lt;br /&gt;
not generate a traffic amplification effect which may be used in a&lt;br /&gt;
denial of service attack on a third party host. Secondly, the query&lt;br /&gt;
key mechanism ensures that queries are only processed if they were&lt;br /&gt;
transmitted from a host which has control over the host in the&lt;br /&gt;
return address (in the normal case, this is the same host). This&lt;br /&gt;
means that flood control mechanisms can remain just as effective as&lt;br /&gt;
in the TCP case. Similarly, host blocking is possible and more&lt;br /&gt;
viable than in Gnutella1 (where the source of a query could not be&lt;br /&gt;
verified).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
This document has covered the high level search model used in&lt;br /&gt;
Gnutella2, as currently deployed in the Shareaza 1.7 betas. I've&lt;br /&gt;
focused purely on search related issues here, as I think that&lt;br /&gt;
searching is probably the area of most interest to everyone at the&lt;br /&gt;
moment, and is definitely the area where there is likely to be some&lt;br /&gt;
interesting discussion.&lt;br /&gt;
&lt;br /&gt;
Gnutella2 consists of a lot more than just a revised search system,&lt;br /&gt;
which I will cover soon. The actual implementation of the query&lt;br /&gt;
model allows for a lot more flexibility than we have in the&lt;br /&gt;
Gnutella1 framework, in terms of the way information is requested&lt;br /&gt;
and the way it is returned, as well as what kinda of information is&lt;br /&gt;
dealt with. Also:&lt;br /&gt;
&lt;br /&gt;
* A new generic and extensible packet format, on which all of the&lt;br /&gt;
new functionality is built&lt;br /&gt;
* The unreliable and semi-reliable UDP transports, including encapsulation, fragmentation, retransmission, etc&lt;br /&gt;
* The specific packets involved in the search system&lt;br /&gt;
* Other base services&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Michael Stokes&amp;lt;br&amp;gt;&lt;br /&gt;
mike@shareaza.com&amp;lt;br&amp;gt;&lt;br /&gt;
November 17, 2002&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=G2_specs_part2&amp;diff=84</id>
		<title>G2 specs part2</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=G2_specs_part2&amp;diff=84"/>
		<updated>2005-04-02T22:01:40Z</updated>

		<summary type="html">&lt;p&gt;Spooky: First version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;h1&amp;gt;Gnutella2 Specifications Part Two&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
&lt;br /&gt;
There has been some interesting discussion about the merits of moving to a fresh new protocol vs. grafting things onto the original beta protocol through encoding extensions.  I’m glad the issue is getting some consideration, because at times in the past it has almost seemed like a taboo subject.  I firmly believe that a new protocol the right thing to do at this time, and have made a number of arguments for that case recently which I will summarise below.  Of course there are also good arguments against it, so it’s a question of weighing everything up.&lt;br /&gt;
&lt;br /&gt;
One thing I’m not questioning is that you don’t NEED a new protocol to do new things.  The major changes that fall under the “Gnutella2” umbrella are fundamental architectural changes relating to search and other services, and the specifics of how you express them in bytes are of somewhat less importance.  But when creating a whole new “high level” system, why would you want to express it using an old, limited format?  Redesigning the “top” of Gnutella provides the perfect and logical opportunity to redesign the “bottom” too.  And doing so allows us to break free from the strange idiosyncrasies we had to work with in the Gnutella1 beta protocol.&lt;br /&gt;
&lt;br /&gt;
===What This Document Covers===&lt;br /&gt;
&lt;br /&gt;
This document discusses the base-level packet structure upon which higher level services are built.  It details the limitations of Gnutella1, the goals of a flexible new base protocol, the way Gnutella2 packets are structured and the way these structures are serialized in binary streams.&lt;br /&gt;
&lt;br /&gt;
That’s the first half of the picture.  The second half (which will follow soon) documents a set of base packet types using the new extensible tree structure.  These are used to deliver distributed host discovery and object search services, and a few other interesting things.  The general operation of the search algorithm itself has been set out in the previous document; however the new packet tree structures which implement it also contain a number of key optimisations and improvements over Gnutella1. &lt;br /&gt;
&lt;br /&gt;
==The Gnutella1 Protocol==&lt;br /&gt;
&lt;br /&gt;
The original Gnutella beta protocol is not the worst protocol in the world by any stretch, but it is far from optimal.  It is, understandably, the type of protocol that software engineers create when they want to test an idea.  The fact that it has been so widely adopted despite that fact reflects very well upon its many good points.&lt;br /&gt;
&lt;br /&gt;
However, the purpose for which it was designed is quite different from the realities of Gnutella today.  I’m referring not so much to its use of a broadcast architecture (as that’s a higher level construct), but more toward the changes in “Gnutella politics”.  The original protocol was designed to communicate between distributed applications with a common origin.  There was no need for interoperability between independent vendors doing slightly different things, only a theoretical need for backward compatibility within the one development stream.&lt;br /&gt;
&lt;br /&gt;
When you have complete control over a protocol, things are obviously a lot simpler.  You decide when and how new things are coded, you (should) know exactly how various changes or improvements you make will affect everyone else, because you coded the software everyone else is using.  That’s the kind of scene the Gnutella protocol was designed for.  But as we know, that’s not what happened – it became an open protocol.  And problems arose.&lt;br /&gt;
&lt;br /&gt;
The fact that these problems were largely overcome is a testament to the efforts of the GDF.  Establishing reasonably standard ways of tacking new data onto old constructs without disturbing the existing parsing code of many different vendors in an environment lacking strong version control was a very impressive achievement.  But the point is this – with an appropriately designed base protocol, these problems would never have arisen. &lt;br /&gt;
&lt;br /&gt;
Granted, issues of incompatibility have been largely solved or avoided through the development of new extension encoding techniques.  These new techniques are great, but they’re tacking their new stuff on to the old structures, sometimes going to unnecessary lengths to do so.  Why don’t we just lose the old stuff and keep the new, well thought out stuff?&lt;br /&gt;
&lt;br /&gt;
I believe that Gnutella is an ideal and a community, not a protocol.  If the protocol should be better, we should change it.  That doesn’t destroy what this community is; it just helps it get better.&lt;br /&gt;
&lt;br /&gt;
==Gnutella2 Protocol Objectives==&lt;br /&gt;
&lt;br /&gt;
So, if there was an ideal protocol for a distributed network of nodes running software developed by many different vendors, what would it be like?  I drew up a list of key objectives (please feel free to add to them!):&lt;br /&gt;
&lt;br /&gt;
===It Should Not Be Too Specific===&lt;br /&gt;
&lt;br /&gt;
G1 was designed to support a broadcast and narrow return architecture, which is a specific model we are now departing from.  Every packet has a GUID, a TTL and a hop count, which are all useful in that model and useless ballast in most other models.&lt;br /&gt;
&lt;br /&gt;
An ideal protocol should focus on a standard way of expressing information, rather than worrying about what kind of information.  If a GUID is needed in a particular packet type, put it in that packet, not in the header of every packet.  In other words, it should be minimal and compact.&lt;br /&gt;
&lt;br /&gt;
===It Should Involve a Namespace===&lt;br /&gt;
&lt;br /&gt;
In a closed protocol with one controlled implementer, numeric op-codes or function numbers are meaningful.  In an open environment with many different implementers working independently, namespaces become necessary.  This is one of the key innovations in things like GGEP and vendor messages.&lt;br /&gt;
&lt;br /&gt;
===It Should Be Hierarchical===&lt;br /&gt;
&lt;br /&gt;
Hierarchical document structures are extremely powerful (eg XML), and if you can make them compact enough, make ideal packets.  Why?  Because they allow any piece of information – anywhere – to be extended or duplicated without disturbing its value.  That means that any implementer can extend the work of any other implementer without compromising it.  Take the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
+ Query Hit Packet&lt;br /&gt;
&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
|-+ Node ID (standard)&lt;br /&gt;
&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
|-+ Server Status (standard)&lt;br /&gt;
| \-+ Shareaza Server Status (private extension)&lt;br /&gt;
&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
|-+ Hit Object&lt;br /&gt;
&lt;br /&gt;
| |-+ URN (standard)&lt;br /&gt;
&lt;br /&gt;
| |-+ Descriptive name (standard)&lt;br /&gt;
&lt;br /&gt;
| | \-+ Alternate name list (extension)&lt;br /&gt;
&lt;br /&gt;
| |-+ URL (standard)&lt;br /&gt;
&lt;br /&gt;
| |-+ Priority indicator (private extension)&lt;br /&gt;
&lt;br /&gt;
| | \-+ Digital signature (private)&lt;br /&gt;
&lt;br /&gt;
| |-+ Alternate source summary (standard)&lt;br /&gt;
&lt;br /&gt;
| \-+ Available ranges (standard)&lt;br /&gt;
&lt;br /&gt;
| . \-+ Estimated completion time (private extension)&lt;br /&gt;
&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
|-+ Selective digital signature (private?)&lt;br /&gt;
&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
\-+ Routing tags&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I made that example up (clearly), but it shows how a hierarchical/tree model is perfectly suited to structured expressions of information, such as those we find in P2P (collections of query results, for example).  You can approximate the same effect with fixed structures, but a true tree allows you to add anything anywhere anytime, enabling types of extensions that were not anticipated.&lt;br /&gt;
 &lt;br /&gt;
===It Should Be Independently Extensible===&lt;br /&gt;
&lt;br /&gt;
If developer A creates a child packet which expresses support for peer to peer chat, developer B may want to support it.  But developer B has a voice chat feature too, and wants to be able to detect it.  Does developer B create a whole new packet to advertise their specific type of chat, even though it’s compatible?  Why not re-use developer A’s, but modify it?  Modifying someone else’s packet endangers compatibility.  The solution is to create a “voice chat capability” child node and re-use A’s “chat capability” packet.&lt;br /&gt;
&lt;br /&gt;
The tree structure allows the format of individual packets (or nodes in tree-speak) to be owned by developers, while allowing other developers to transparently extend them.  Any party can invent new concepts and share them with other developers without (necessarily) losing control over them.&lt;br /&gt;
&lt;br /&gt;
===It Should Be International===&lt;br /&gt;
&lt;br /&gt;
It makes sense to design for international character set support from the beginning, even if not all clients currently support it.  Shareaza 1.7 for example is still ANSI, but supports Unicode in the protocol and performs the necessary conversion.  If Unicode protocol support is required from the word go, we’re free to implement it independently at leisure with no incompatibility problems.&lt;br /&gt;
&lt;br /&gt;
===It Should Probably Support IPv6===&lt;br /&gt;
&lt;br /&gt;
This is a new one based on the discussion the other day – I don’t know much about IPv6 but this is a good opportunity to do something about it.&lt;br /&gt;
 &lt;br /&gt;
==Proposed Gnutella2 Protocol==&lt;br /&gt;
&lt;br /&gt;
===Overview===&lt;br /&gt;
&lt;br /&gt;
The low-level Gnutella2 protocol used by the current Shareaza 1.7 betas is a cross between GGEP and vendor messages, without the (now unnecessary) overheads, and in a freeform tree structure.&lt;br /&gt;
&lt;br /&gt;
Every Gnutella2 packet has a qualified name, length and other flags.  It can contain a payload and/or one or more child packets.  Child packets are identical to their parents in capability, i.e. you can nest packets to infinity.  Multiple instances of a packet type can occur at any level (for example, lists of nodes, queries, hits, people, etc).&lt;br /&gt;
&lt;br /&gt;
The concept can be compared to an XML document tree.  The “packets” are elements, which can in turn contain zero or more child elements (packets).  The payload of a packet is like the attributes of an XML element.  However as we know, serializing XML has a lot of overhead due to all the naming, even in a compact binary form.  The Gnutella2 packet structure makes a compromise: it names elements (packets), allowing them to be globally recognized and understood without knowledge of their format – and stores attributes as binary payloads, requiring knowledge of their content to parse them.&lt;br /&gt;
&lt;br /&gt;
Thus the element (packet or child packet) is the finite unit of comprehension.  This system provides an excellent tradeoff between format transparency and compactness.&lt;br /&gt;
&lt;br /&gt;
===Packet Framing===&lt;br /&gt;
&lt;br /&gt;
Packets are encoded with a single leading control byte, followed by one or more bytes of packet length, followed by one or more bytes of packet name/ID, followed by zero or more child packets (framed the same way), followed by zero or more bytes of payload:&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
+---------+----/----+----/----+---&lt;br /&gt;
&lt;br /&gt;
| Control | Length_ | Name___ | children and/or payload&lt;br /&gt;
&lt;br /&gt;
+---------+----/----+----/----+---&lt;br /&gt;
&amp;lt;/nowiki&amp;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 nothing at all.  The total length of the packet header cannot exceed 12 bytes and cannot be less than 3 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 stream of packets, and thus has special meaning.  It should not be used in root packet streams (which do not end).&lt;br /&gt;
&lt;br /&gt;
Control bytes have the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Bit 7 &amp;lt; - &amp;gt; Bit 0&lt;br /&gt;
&lt;br /&gt;
+----+----+----+----+----+----+----+----+&lt;br /&gt;
&lt;br /&gt;
| Len_Len | Name_Len – 1 | // | // | CF |&lt;br /&gt;
&lt;br /&gt;
+----+----+----+----+----+----+----+----+&lt;br /&gt;
&amp;lt;/nowiki&amp;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.  Note that Len_Len cannot be zero, which protects the control byte from ever being zero.&lt;br /&gt;
&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.&lt;br /&gt;
&lt;br /&gt;
The three least significant bits of the control byte are reserved for flags.  The LSB is defined as the compound packet flag.  If this bit is set, the packet contains one or more child packets.  If not set, the packet contains only its own payload (or nothing).&lt;br /&gt;
&lt;br /&gt;
I am considering using the next bit to flag packets included in the digital signature, allowing selective signing of some parts of a packet tree – i.e. one signature which covers certain parts only.  This allows other parts to be changed, added and removed without disturbing the integrity of the signature, which allows for some neat routing tricks.&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 1 to 3 bytes long.  Length bytes are stored least significant first, which allows them to be read very easily on little-endian machines.&lt;br /&gt;
&lt;br /&gt;
The length value includes the payload of this packet AND any child packets in their entirety.  This is obviously needed so that the entire packet can be detected and acquired from a stream.  The length does not include the header (control byte, length, and name).  The length field precedes the name field to allow it to be read faster from a stream when acquiring packets.&lt;br /&gt;
 &lt;br /&gt;
===The Name Field===&lt;br /&gt;
&lt;br /&gt;
The name field immediately follows the length bytes, and can be from 1 to 8 bytes long.  It follows a similar convention to the GGEP naming standard – bytes can be any value, but are generally alphanumeric.&lt;br /&gt;
&lt;br /&gt;
Public packet types which form the core of important services should be agreed upon, and can use short names consisting of capital letters. For example general-purpose keep-alive ping/pongs use the names “PI” and “PO” (note that these are very different to G1 ping/pongs).&lt;br /&gt;
&lt;br /&gt;
Private packet types or extensions should be prefixed with a namespace equal to the four letter vendor code, followed by lowercase.  For example “RAZAgrp4”.&lt;br /&gt;
&lt;br /&gt;
Naming convention is most important in the root namespace, and at other common points in common public packet types.&lt;br /&gt;
&lt;br /&gt;
===Child Packets=== &lt;br /&gt;
&lt;br /&gt;
Child packets are only present if the “compound packet bit” is set in the control byte.  If set, there is one or more child packet immediately following the end of the header.  These child packets are included in the total length of their parent (along with the payload, which follows the child packets).&lt;br /&gt;
&lt;br /&gt;
Child packets are framed exactly the same way, with a control byte, length, name, children and/or payload.  When the compound bit is set, the first child packet must exist.  Existing child packets may also exist, and are read in sequentially in the same way that they are read from a root packet stream.  The end of the child packet stream is signaled by the presence of a zero control byte, OR the end of the parent packet’s length (in which case there is no payload).  Including a terminating zero control byte when there is no payload is still 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 bit is set, one or more child packets must be read before the payload is reached.  If there is no packet left after the end of the last child, there is no payload.&lt;br /&gt;
&lt;br /&gt;
VERY IMPORTANT: The compound packet bit MUST be checked on every packet.  It should be done in low-level decoding code to avoid accidental omission.  Do not assume that a packet will not have children – it might not now, but no packets are sterile.  Anything could be augmented.  If you are not interested in children, skip them (which is easy, you don’t even need to recurse through their children).&lt;br /&gt;
&lt;br /&gt;
===Payload Format===&lt;br /&gt;
&lt;br /&gt;
The format of the payload is defined by the packet type, and may include various types of binary data.  Payloads may or may not be a fixed length for a given packet type.&lt;br /&gt;
&lt;br /&gt;
Multi-byte integers should always be expressed little-endian first, as the vast majority of users are using little-endian systems, and that is unlikely to change.&lt;br /&gt;
&lt;br /&gt;
Strings can be expressed in Gnutella1 style, i.e. with a terminating null character.  Alternatively the string is said to terminate if it reaches the end of the payload, avoiding an unnecessary null.&lt;br /&gt;
&lt;br /&gt;
ALL STRINGS may be ANSI or Unicode.  All software supporting the protocol must be prepared to accept either, performing appropriate conversion if necessary.  Unicode software everywhere would be nice, but that’s easier said than done.  Note that if you convert Unicode back to local ANSI, don’t retransmit it.  Let the Unicode pass through.&lt;br /&gt;
&lt;br /&gt;
ANSI strings are stored as consecutive bytes followed by a null byte (or end of packet).  Unicode strings are stored as a 0xFF (255) marker byte, followed by 16-bit Unicode characters in little-endian form.  The string is terminated by 0x0000 or the end of the payload.  ALWAYS check for 0xFF and convert if not using Unicode strings internally.&lt;br /&gt;
&lt;br /&gt;
In generating strings it is acceptable to check for extended characters and fall back to ANSI if none are present, to conserve space.&lt;br /&gt;
 &lt;br /&gt;
==Samples==&lt;br /&gt;
 &lt;br /&gt;
===Example Packets===&lt;br /&gt;
&lt;br /&gt;
A simple ping (“PI”) packet with no payload:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Packet Length: 0&lt;br /&gt;
Packet Name: PI&lt;br /&gt;
Control Byte: 01 001 000 = 0x48 (lenlen=1,namelen=2,cmp=0)&lt;br /&gt;
Packet: 48 00 ‘P’ ‘I’&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A pong packet containing a ping child (nonsensical but good example):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Packet Length: 4&lt;br /&gt;
Packet Name: PO&lt;br /&gt;
Control Byte: 01 001 001 = 0x49 (lenlen=1,namelen=2,cmp=1)&lt;br /&gt;
Packet: 49 04 ‘P’ ‘O’ 48 00 ‘P’ ‘I’&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, what if it contains two ping children:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Packet: 49 08 ‘P’ ‘O’ 48 00 ‘P’ ‘I’ 48 00 ‘P’ ‘I’&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a payload of “test” to the pong:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Packet: 49 0D ‘P’ ‘O’ 48 00 ‘P’ ‘I’ 48 00 ‘P’ ‘I’ 00 ‘t’ ‘e’ ‘s’ ‘t’&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Note the 00 terminating control byte after the children but before the payload)&lt;br /&gt;
&lt;br /&gt;
===Simple Packet Decoder Logic===&lt;br /&gt;
&lt;br /&gt;
The following is a simple packet header decoder in C that will work on any root or child packet.  It assumes that the packet is present or that its input functions will block.  In a production situation there would of course need to be more failure cases (data not available, malformatted packet).  In particular, child packet bounds must not exceed the extent of the parent.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
BYTE nInput       = ReadNextByte();&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;
DWORD nPacketLength = 0;&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;
&lt;br /&gt;
BOOL bIsCompound = ( nFlags &amp;amp; 0x01 ) ? TRUE : FALSE;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
==Higher Level Structures==&lt;br /&gt;
&lt;br /&gt;
This document has covered the basic packet framing and structuring stuff only, without going into the higher level constructs to support discovery, identification, searching, etc.  I will document that soon for further discussion, as there is definitely some cool stuff in there which takes advantage of the tree packet structures to deliver flexible and extensible services.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Michael Stokes&amp;lt;br&amp;gt;&lt;br /&gt;
mike@shareaza.com&amp;lt;br&amp;gt;&lt;br /&gt;
November 20, 2002&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=G2_specs_part1&amp;diff=67</id>
		<title>G2 specs part1</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=G2_specs_part1&amp;diff=67"/>
		<updated>2005-04-02T21:35:30Z</updated>

		<summary type="html">&lt;p&gt;Spooky: First version&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;h1&amp;gt;Gnutella2 Specifications part one&amp;lt;/h1&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I realise this has been quite a long time in coming, however I'm a&lt;br /&gt;
strong believer in getting some field experience with new ideas&lt;br /&gt;
before asserting that they will work (especially in a distributed&lt;br /&gt;
environment). This has been productive and as a direct result of&lt;br /&gt;
the experience gained, several significant changes have been evolved&lt;br /&gt;
into the proposal over the past few weeks. That process of testing&lt;br /&gt;
is not yet complete, however I'm now confident that the basic ideas&lt;br /&gt;
are relatively sound.&lt;br /&gt;
&lt;br /&gt;
I'm also very interested in the thoughts of everyone here in the&lt;br /&gt;
GDF. I tend to have strongly held views of how things should work,&lt;br /&gt;
but the problem with a lone designer is that you rarely cover all&lt;br /&gt;
the possible angles. It's only by working with a group of&lt;br /&gt;
appropriately qualified people that there is any hope of exploring a&lt;br /&gt;
problem fully. So, I invite everyone to comment, criticise and&lt;br /&gt;
discuss.&lt;br /&gt;
&lt;br /&gt;
Finally, to reiterate some of the stuff I posted last week: the&lt;br /&gt;
entire Gnutella2 concept is intended to be an open advancement in&lt;br /&gt;
the Gnutella world. I recognise that the GDF is not a standards&lt;br /&gt;
body and our purpose here is not to flesh out a new specification,&lt;br /&gt;
however I hope that this effort will spark some intelligent&lt;br /&gt;
discussion of the ideas contained within.&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 concept contains four parts:&lt;br /&gt;
&lt;br /&gt;
* A new protocol&lt;br /&gt;
* A new data transport architecture&lt;br /&gt;
* New base services, including search&lt;br /&gt;
* An implementation standard&lt;br /&gt;
&lt;br /&gt;
While I feel that all four parts are important to move forward with,&lt;br /&gt;
I suspect that the third part, the new base services and in&lt;br /&gt;
particular the new search mechanism is likely to be the area of&lt;br /&gt;
greatest interest for everyone here. Thus I'll focus on the&lt;br /&gt;
searching aspect of Gnutella2 in this post, and save discussion of&lt;br /&gt;
the other items for later.&lt;br /&gt;
&lt;br /&gt;
(A final word on the first two points in this post: I do acknowledge&lt;br /&gt;
that it is entirely possible to implement most if not all new&lt;br /&gt;
features within the framework of the original Gnutella spec, working&lt;br /&gt;
around its limitations with things like GGEP. However I would argue&lt;br /&gt;
that in doing that we are limiting ourselves unnecessarily, not to&lt;br /&gt;
mention producing less than elegant designs and increasing overall&lt;br /&gt;
complexity. The original specification united us as developers&lt;br /&gt;
however if we are unable to move logically beyond it now, I think&lt;br /&gt;
that reflects an inability on our part to work together.)&lt;br /&gt;
&lt;br /&gt;
In any case, this post is focused on the search architecture of&lt;br /&gt;
Gnutella2. The search framework is built upon the previous two&lt;br /&gt;
levels of implementation, however it is possible (and more&lt;br /&gt;
meaningful) to discuss it at a higher level now. I'll detail the&lt;br /&gt;
specifics of my implementation later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
It's important to take a step back and analyse exactly what a search&lt;br /&gt;
system should be able to do. In an ideal world of unlimited&lt;br /&gt;
bandwidth and CPU resources, it should be possible to execute a&lt;br /&gt;
search and locate every matching object present on the network&lt;br /&gt;
instantly. In the real world compromises must be made, but the&lt;br /&gt;
choice of compromise is important.&lt;br /&gt;
&lt;br /&gt;
=== An Analysis of Gnutella1 ===&lt;br /&gt;
&lt;br /&gt;
In the original (Gnutella1) architecture, the compromise is one of&lt;br /&gt;
search scope. Performing a search has a more or less fixed cost,&lt;br /&gt;
occurs over a more or less fixed time interval and covers an area of&lt;br /&gt;
more or less fixed size (but which is randomly selected).&lt;br /&gt;
Unfortunately, when mapped from the technical view to the outcome&lt;br /&gt;
view, it is evident that this compromise is not very desirable: In&lt;br /&gt;
an ideal scenario, Gnutella1 searches tend to find every matching&lt;br /&gt;
result within a fixed (but unknown) area of the network. There is&lt;br /&gt;
little or no opportunity to scale the search to match the rarity of&lt;br /&gt;
the target object (TTL and number of injection points can be scaled,&lt;br /&gt;
but have a high cost).&lt;br /&gt;
&lt;br /&gt;
=== An Optimal Search System ===&lt;br /&gt;
&lt;br /&gt;
It is my view that an optimal search system, under real world&lt;br /&gt;
limitations should have the following properties:&lt;br /&gt;
&lt;br /&gt;
* It should be able to guarantee that if a matching object exists somewhere, it can be found&lt;br /&gt;
* It should have a means of scaling to match the rarity of the object that is not associated with a high cost to the network&lt;br /&gt;
* In a situation of limited resources, the ability to find at least some instances of a rare object should be of higher importance than the ability to find every instance of a common object.&lt;br /&gt;
&lt;br /&gt;
In other words, the principal difference between my &amp;quot;optimal&amp;quot; search&lt;br /&gt;
objectives and the Gnutella1 model is that I am placing a higher&lt;br /&gt;
priority on the ability to find an object anywhere, than the ability&lt;br /&gt;
to find every object in a limited range. My rationale for this is&lt;br /&gt;
that:&lt;br /&gt;
&lt;br /&gt;
* The ability to locate at least one instance of an object is very important, because without it no further action is possible&lt;br /&gt;
* Having located one instance of an object, there are other means of finding additional locations (if desired), such as a download mesh&lt;br /&gt;
* In a distributed hash table environment, a general search system only needs to locate a URN matching a search, after which the DHT can efficiently provide additional locations where that object may be found.&lt;br /&gt;
* Last but not least, the inability to find an object is demoralising for users&lt;br /&gt;
&lt;br /&gt;
The third point there is quite important – I'm very keen on the use&lt;br /&gt;
of a large scale distributed hash table within Gnutella in the near&lt;br /&gt;
future (some work is going on there already). Thus the design of&lt;br /&gt;
this search system is such that it is not superseded, but rather&lt;br /&gt;
forms a part of, a DHT-enhanced search solution.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== A search model meeting these objectives ===&lt;br /&gt;
&lt;br /&gt;
It is well understood that in order to design a distributed search&lt;br /&gt;
system which has at least one scalable variable, there needs to be a&lt;br /&gt;
means of controlling the progress of the search. (Gnutella1 of&lt;br /&gt;
course fails on this principle as it involves &amp;quot;unleashing&amp;quot; a search&lt;br /&gt;
and waiting for the results) Controlled searches thus lend&lt;br /&gt;
themselves to an iterative, rather than recursive, approach. There&lt;br /&gt;
are three commonly known approaches:&lt;br /&gt;
&lt;br /&gt;
* The random walker approach, in which the search maintains periodic contact with its originator, allowing the originator to continue or abort progress.&lt;br /&gt;
* The random or crawling mesh approach, in which the originator iteratively contacts nodes on the network until all nodes have been contacted or a desired condition has been reached.&lt;br /&gt;
* The guided mesh approach, in which the originator iteratively contacts nodes seeking a particular node which is responsible for a particular URN (DHT).&lt;br /&gt;
&lt;br /&gt;
At the most simplistic level, the Gnutella2 network search model&lt;br /&gt;
takes the second approach: an iterative crawl of all nodes on the&lt;br /&gt;
network until a desired condition is reached. It also makes use of&lt;br /&gt;
the random walker model for another, non-search function, however&lt;br /&gt;
that is outside the scope of this discussion. It is envisioned that&lt;br /&gt;
the third DHT approach will be incorporated in the future as a more&lt;br /&gt;
efficient way of locating nodes with an instance of a URN obtained&lt;br /&gt;
from the current search model.&lt;br /&gt;
&lt;br /&gt;
In this respect, the use of an iterative crawl is similar to the&lt;br /&gt;
GUESS proposal. The differences between this implementation and&lt;br /&gt;
GUESS become apparent in the process and optimisations described&lt;br /&gt;
below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Real World Considerations ==&lt;br /&gt;
&lt;br /&gt;
=== Generic Viability ===&lt;br /&gt;
&lt;br /&gt;
Implementing a node crawl directly is not viable for a public, large&lt;br /&gt;
scale network for several reasons:&lt;br /&gt;
&lt;br /&gt;
* There are too many nodes to contact&lt;br /&gt;
* The cost of contacting a node is too high for the expected number of matching objects on that node (the probability of one match is often a lot lower than 1%)&lt;br /&gt;
* Not all nodes can be contacted directly (NATs, firewalls)&lt;br /&gt;
* Most nodes do not have the resources to handle and respond to queries from every other node&lt;br /&gt;
&lt;br /&gt;
=== Increasing Network Density ===&lt;br /&gt;
&lt;br /&gt;
One of the solutions is of course something we have been using for&lt;br /&gt;
some time in the Gnutella world – organising nodes into a two level&lt;br /&gt;
hierarchy, in which &amp;quot;high capacity&amp;quot; nodes shield &amp;quot;low capacity&amp;quot;&lt;br /&gt;
nodes. High capacity nodes have been called Ultrapeers&lt;br /&gt;
or &amp;quot;Supernodes&amp;quot; in the past, although I have used the term &amp;quot;Hubs&amp;quot; as&lt;br /&gt;
it seems to make the purpose much more clear to the general user&lt;br /&gt;
population.&lt;br /&gt;
&lt;br /&gt;
Hubs solve several issues:&lt;br /&gt;
&lt;br /&gt;
* Hubs can effectively answer queries for their leaves, so:&lt;br /&gt;
* Only hubs need to be contacted in a mesh crawl, reducing the number of nodes to contact&lt;br /&gt;
* Contacting one hub allows a large number of nodes to be searched, increasing the probability of locating an object and thus reducing the relative cost of contact&lt;br /&gt;
* Hubs must be able to be contacted directly, allowing un-contactable nodes to exist and participate as leaves&lt;br /&gt;
* Hubs can shield their leaves from the bulk of the bandwidth and CPU requirements&lt;br /&gt;
&lt;br /&gt;
These facts are not new, and many of them apply to traditional&lt;br /&gt;
Gnutella1 as well. However in the Gnutella2 world, the reduced cost&lt;br /&gt;
of contact becomes a positive factor where it previously was not.&lt;br /&gt;
Similarly, the total number of nodes (now hubs) which could be&lt;br /&gt;
contacted for a complete network-wide search is reduced.&lt;br /&gt;
&lt;br /&gt;
=== Problems with Gnutella Hubs ===&lt;br /&gt;
&lt;br /&gt;
It is interesting to note that several other successful distributed&lt;br /&gt;
networks use a similar model, grouping a large number of leaf nodes&lt;br /&gt;
under a hub node, although different terminology is often used. The&lt;br /&gt;
server-based model is obviously the extreme version of this, where&lt;br /&gt;
all participants in the searchable area are connected to a common&lt;br /&gt;
server. Moving away from this to a more distributed model,&lt;br /&gt;
additional servers (-&amp;gt; hubs) are employed, with searches being&lt;br /&gt;
processed by each.&lt;br /&gt;
&lt;br /&gt;
What these other networks tend to rely upon, however, is having a&lt;br /&gt;
very large number of leaf nodes per hub. This very high leaf&lt;br /&gt;
density makes searching very efficient, because the relative cost of&lt;br /&gt;
contacting each hub and the total number of hubs are both low. In&lt;br /&gt;
the Gnutella world, our ultrapeers/hubs tend to have far fewer&lt;br /&gt;
leaves. This presents a problem: there are too many hubs to&lt;br /&gt;
contact, and the relative cost per hub is too high.&lt;br /&gt;
&lt;br /&gt;
These problems must be solved, or the time necessary to execute a&lt;br /&gt;
search will be far too high for reasonably rare and very rare&lt;br /&gt;
objects.&lt;br /&gt;
&lt;br /&gt;
== Gnutella2 Solutions ==&lt;br /&gt;
&lt;br /&gt;
The Gnutella2 model solves the &amp;quot;too many hubs&amp;quot; problem in two ways.&lt;br /&gt;
&lt;br /&gt;
=== Optimising Hub to Leaf Communication ===&lt;br /&gt;
&lt;br /&gt;
The first solution tackles the problem at its cause – to reduce the&lt;br /&gt;
number of hubs; the number of leaves per hub must be increased. The&lt;br /&gt;
limiting factor on the number of leaves per hub is the capacity of a&lt;br /&gt;
particular hub to support a large number of leaves. Some aspects of&lt;br /&gt;
this limitation are fixed, for example the amount of CPU power and&lt;br /&gt;
bandwidth available to a particular hub. This can only be addressed&lt;br /&gt;
by choosing better hubs (which is also important)&lt;br /&gt;
&lt;br /&gt;
However, other aspects are highly variable and good targets for&lt;br /&gt;
optimisation: the cost of each additional leaf can be reduced.&lt;br /&gt;
Gnutella2 does this by:&lt;br /&gt;
&lt;br /&gt;
* Leaves send their hub an extremely large query hash table which applies to all query traffic. This results in a substantially lower bandwidth requirement for each leaf, at the cost of additional memory on the hub. The latter is reduced by storing the tables in compressed hierarchical form to balance memory and CPU requirements. Patch tables are sent in simple 1-bit packed form, and the necessary levels are generated and compressed by the hub upon receipt of new or patch data.&lt;br /&gt;
&lt;br /&gt;
* All hub to leaf traffic is compressed using the deflate algorithm. This provides a significant reduction in bandwidth requirement for each leaf, once again at the cost of state memory and some CPU on the hub. The CPU requirement is not as significant as might be expected, as the large query hash tables filter the majority of traffic leaving only a vast minority for compression. The combination of these two systems really squeezes the absolute most out of hub to leaf bandwidth. The memory requirement can be halved by not compressing leaf to hub bandwidth, which is almost non-existent in Gnutella2.&lt;br /&gt;
&lt;br /&gt;
* Leaves are given the option of uploading a compressed snapshot of their library to their hub. I have not finished experimenting with this yet, but to spell out the obvious advantages and disadvantages: hub to leaf traffic is eliminated, memory and CPU requirements on the hub increase. By using a similar compressed hierarchical storage and access system I expect to be able to make the impact manageable.&lt;br /&gt;
&lt;br /&gt;
The savings in bandwidth requirement per leaf provided by these&lt;br /&gt;
optimisations, at minimal extra cost to the hub in terms of CPU and&lt;br /&gt;
memory requirements, allow a typical hub to serve a much larger&lt;br /&gt;
number of leaves that it would normally be able to. This helps to&lt;br /&gt;
increase the average leaves per hub, and with appropriate hub&lt;br /&gt;
promotion control, reduce the total number of hubs. To map that&lt;br /&gt;
back to the original assertion, it reduces the relative cost of&lt;br /&gt;
contacting each hub and therefore also the amount of time taken to&lt;br /&gt;
perform a search.&lt;br /&gt;
&lt;br /&gt;
=== Leveraging Inter-Hub Communication ===&lt;br /&gt;
&lt;br /&gt;
Gnutella2 also makes another key optimisation. Assuming the total&lt;br /&gt;
number of hubs cannot easily be reduced any further, there are other&lt;br /&gt;
ways to reduce the relative cost of contacting each hub and reduce&lt;br /&gt;
the effective number of hubs which actually need to be contacted.&lt;br /&gt;
&lt;br /&gt;
In the Gnutella2 search model, when a particular hub receives a&lt;br /&gt;
query from a query originator, it not only processes it locally and&lt;br /&gt;
forwards it to its leaves (where relevant), it also forwards it to&lt;br /&gt;
its neighbouring hubs. These hubs in turn process the query locally&lt;br /&gt;
and forward it to their leaves (where relevant), however they do not&lt;br /&gt;
forward it any further. To make a comparison with the Gnutella1&lt;br /&gt;
broadcast model, this is similar to executing a query with TTL=2.&lt;br /&gt;
In Gnutella2 there are no TTLs involved, rather fixed routing rules&lt;br /&gt;
are used to ensure that any hub receiving a query will always&lt;br /&gt;
forward it to its leaves, and may forward it to its neighbouring&lt;br /&gt;
hubs if the origin was not already a neighbouring hub. The &amp;quot;two&lt;br /&gt;
level&amp;quot; approach is not arbitrarily chosen, and its significance is&lt;br /&gt;
detailed later.&lt;br /&gt;
&lt;br /&gt;
This behaviour means that for the cost of sending a query to a&lt;br /&gt;
single hub, a small &amp;quot;cluster&amp;quot; of connected hubs are actually&lt;br /&gt;
searched. For a typical hub with 5 neighbours, 6 hubs and their&lt;br /&gt;
leaves are searched at once. In essence, &amp;quot;hub clustering&amp;quot; offsets&lt;br /&gt;
Gnutella's lower average leaves per hub. The elimination of&lt;br /&gt;
broadcast &amp;quot;flood&amp;quot; traffic also means that hubs could actually have a&lt;br /&gt;
higher number of neighbour hubs, further increasing the cluster size&lt;br /&gt;
and lowering the cost per contact.&lt;br /&gt;
&lt;br /&gt;
At first examination the cluster effect would appear only to benefit&lt;br /&gt;
the search originator by reducing the amount of outbound query&lt;br /&gt;
traffic and the time taken to contact every node (if required). In&lt;br /&gt;
the unoptimised case, every hub would still need to receive every&lt;br /&gt;
query, even if it was forwarded by an intermediary hub. The&lt;br /&gt;
benefits to the search originator are important, however further&lt;br /&gt;
optimisations allow the cluster effect to benefit hubs as well.&lt;br /&gt;
&lt;br /&gt;
At the first level, hub to hub links are compressed using the&lt;br /&gt;
deflate algorithm in both directions. This is an important effect,&lt;br /&gt;
as the nature of UDP query traffic is that it cannot generally be&lt;br /&gt;
compressed (it's too small and there is no reliable context). Thus&lt;br /&gt;
receiving a query via UDP is much less efficient in terms of&lt;br /&gt;
bandwidth than receiving one via TCP. But as we know, UDP has other&lt;br /&gt;
benefits. A compromise must be struck, and the retransmission of&lt;br /&gt;
query packets within the hub cluster provides an excellent&lt;br /&gt;
opportunity. A single inbound UDP (inefficient) query is received&lt;br /&gt;
by one hub, which is then forwarded to the other 4+ hubs in the&lt;br /&gt;
cluster via TCP (efficient). One (random) hub takes the extra load;&lt;br /&gt;
the other (majority) receive the benefit.&lt;br /&gt;
&lt;br /&gt;
At the next level up, query retransmission within the hub cluster is&lt;br /&gt;
filtered by very large query hash tables. Gnutella2 hubs regularly&lt;br /&gt;
exchange query hash table data, which is a composite of the hub's&lt;br /&gt;
own available objects and the hash tables of its leaves. Because&lt;br /&gt;
retransmission is restricted to a neighbour and its leaves, the use&lt;br /&gt;
of filtering tables at this level is perfectly acceptable (and&lt;br /&gt;
accurate). The hash table associated with a particular hub at an&lt;br /&gt;
instant in time is the same no matter which neighbour views it.&lt;br /&gt;
&lt;br /&gt;
The use of query hash tables in hub to hub links makes it possible&lt;br /&gt;
to filter out query traffic which would not result in a hit,&lt;br /&gt;
reducing the hub to hub bandwidth requirements. This not only makes&lt;br /&gt;
the hub cluster concept more efficient, but also allows hubs to have&lt;br /&gt;
more leaves. Through clever hash table tricks, the size of the hash&lt;br /&gt;
tables employed on hub to hub links can be larger than that retained&lt;br /&gt;
on hub to leaf links (to offset the higher density). Methods of&lt;br /&gt;
patching hash tables as they change to reduce update bandwidth are&lt;br /&gt;
well documented also.&lt;br /&gt;
&lt;br /&gt;
=== Summary ===&lt;br /&gt;
&lt;br /&gt;
The primary focus of these solutions has been to increase the&lt;br /&gt;
efficiency of the system, in a situation of limited resources.&lt;br /&gt;
Decreasing the number of hubs to be contacted and decreasing the&lt;br /&gt;
effective cost of each contact (which includes both reducing the&lt;br /&gt;
cost of sending the query, and the cost of receiving and processing&lt;br /&gt;
it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Calculations ==&lt;br /&gt;
&lt;br /&gt;
While the optimisations described previously provide significant&lt;br /&gt;
performance improvements, they also add complexity. For a small&lt;br /&gt;
network this complexity is not particularly necessary. However as&lt;br /&gt;
the number of nodes on the network grows, the benefits of higher&lt;br /&gt;
leaf density and lower cost of contact become much greater.&lt;br /&gt;
&lt;br /&gt;
For a 500,000 node network with presently loaded ultrapeers&lt;br /&gt;
averaging about 150 leaves each, there will be approximately 3333&lt;br /&gt;
ultrapeers. Every one of these 3333 ultrapeers must be contacted to&lt;br /&gt;
achieve a global search, incurring the cost of transmission on the&lt;br /&gt;
search originator and the cost of receiving on each ultrapeer (plus&lt;br /&gt;
leaf costs depending on how that is set up). None of these queries&lt;br /&gt;
can be compressed.&lt;br /&gt;
&lt;br /&gt;
If the same network is built with optimised hubs averaging 500 nodes&lt;br /&gt;
each, there will be approximately 1000 hubs. If each hub is&lt;br /&gt;
connected to an average of 5 neighbours, less than 170 hubs need to&lt;br /&gt;
be contacted by the search originator via UDP. The originator can&lt;br /&gt;
do that faster and more reliably. The other approximately 830 hubs&lt;br /&gt;
and their leaves are still effectively searched, but incur a reduced&lt;br /&gt;
(compressed) penalty, if any at all (QHT filtering).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hub Management ==&lt;br /&gt;
&lt;br /&gt;
This section deals with some of the more mundane but important&lt;br /&gt;
aspects of operation.&lt;br /&gt;
&lt;br /&gt;
=== Crawling the Network ===&lt;br /&gt;
&lt;br /&gt;
It is not viable for every node to maintain an accurate table of&lt;br /&gt;
every hub on the network, if the network is of any reasonable size.&lt;br /&gt;
The storage requirement is not significant, but the overhead in&lt;br /&gt;
maintaining it is. It makes more sense to progressively discover&lt;br /&gt;
the extent of the network as it is traversed. This provides a sweep&lt;br /&gt;
of the current extent over a period of time (i.e. not a snapshot),&lt;br /&gt;
but its good enough.&lt;br /&gt;
&lt;br /&gt;
To achieve this, each hub which is contacted must provide additional&lt;br /&gt;
information about where the search originator might look next. In a&lt;br /&gt;
simple system this is quite straight forward, however the use of the&lt;br /&gt;
hub clustering technique (while vastly increasing efficiency)&lt;br /&gt;
complicates matters somewhat.&lt;br /&gt;
&lt;br /&gt;
=== Query Acknowledgements ===&lt;br /&gt;
&lt;br /&gt;
Upon receiving a valid query from a search originator, a hub&lt;br /&gt;
immediately returns a query acknowledgement. The acknowledgement is&lt;br /&gt;
tagged for the specific search ID and includes two lists of&lt;br /&gt;
information: the hubs which have received the query (including the&lt;br /&gt;
current hub itself), and a selection of hubs to try.&lt;br /&gt;
&lt;br /&gt;
The list of hubs which received the query will be every neighbouring&lt;br /&gt;
Gnutella2 hub, including hubs for which the query failed the QHT&lt;br /&gt;
test. The query originator adds these hubs to the &amp;quot;done list&amp;quot;, and&lt;br /&gt;
avoids sending them direct queries. Note that additional&lt;br /&gt;
information is also returned, such as the leaf count for each hub,&lt;br /&gt;
so that the originator can display search statistics.&lt;br /&gt;
&lt;br /&gt;
The list of other hubs to try is more complex. The hubs in the list&lt;br /&gt;
must be accurate, or time and resources are wasted on a large&lt;br /&gt;
scale. The only hubs which the hub can be 100% sure of are its&lt;br /&gt;
neighbours, but they are not eligible because they have already been&lt;br /&gt;
queried. To solve this problem, every Gnutella2 node knows every&lt;br /&gt;
neighbour, and every neighbour's neighbour. This applies partially&lt;br /&gt;
to leaves too, in that leaves must know their neighbours and their&lt;br /&gt;
neighbours' neighbours; however only hubs are included in the data&lt;br /&gt;
(leaf addresses are of no use). This information is kept up to date&lt;br /&gt;
quite stringently.&lt;br /&gt;
&lt;br /&gt;
As a result, a hub sending a query acknowledgement packet can&lt;br /&gt;
include its neighbours as &amp;quot;searched&amp;quot;, and its neighbours' neighbours&lt;br /&gt;
as &amp;quot;try these&amp;quot;. This allows a logical crawling process to occur&lt;br /&gt;
unimpeded by hub clusters.&lt;br /&gt;
&lt;br /&gt;
=== General Hub Discovery ===&lt;br /&gt;
&lt;br /&gt;
Crawling through the network logically has some benefits; however a&lt;br /&gt;
more random approach can also be beneficial. To aid this, a few&lt;br /&gt;
random hubs from the active hub cache are also returned in query&lt;br /&gt;
acknowledgements. Random cached hubs are exchanged between all&lt;br /&gt;
nodes on the network, much like the &amp;quot;X-Try-Ultrapeers&amp;quot; header,&lt;br /&gt;
except as a continual process. Finally, hub walker advertisements&lt;br /&gt;
use a random walker approach to advertise long-running hubs to&lt;br /&gt;
distant points in the web. All indirect hub references are covered&lt;br /&gt;
by a last seen time allowing more recently confirmed hubs to be&lt;br /&gt;
prioritised and limiting the impact of lost hubs. (Connection&lt;br /&gt;
attempts on former ultrapeer IPs has been a significant problem in&lt;br /&gt;
Gnutella1).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Security ==&lt;br /&gt;
&lt;br /&gt;
The term &amp;quot;security&amp;quot; can have many meanings in a peer-to-peer context:&lt;br /&gt;
&lt;br /&gt;
* Preventing denial of service attack upon the network&lt;br /&gt;
* Preventing the network from being used to launch an attack on other hosts&lt;br /&gt;
* Preventing the originator of a search from being identified&lt;br /&gt;
* Preventing the originator of a shared object from being identified&lt;br /&gt;
* Preventing false shared objects from being propagated&lt;br /&gt;
&lt;br /&gt;
The first two points relate to securing the network structure&lt;br /&gt;
against misuse. The next two relate to anonymity, while the last is&lt;br /&gt;
more difficult to classify. As a developer I am most interested in&lt;br /&gt;
the first two items, and also to some extent the last item.&lt;br /&gt;
&lt;br /&gt;
=== Risks Associated With UDP ===&lt;br /&gt;
&lt;br /&gt;
Any distributed network (and particularly those which involve the&lt;br /&gt;
trading of host addresses) must take special consideration of&lt;br /&gt;
possible misuse of its nodes. In the original Gnutella network&lt;br /&gt;
there is already a significant potential to launch denial of service&lt;br /&gt;
attacks upon third party hosts by misrepresenting host addresses,&lt;br /&gt;
which then propagate through the network, resulting in thousands of&lt;br /&gt;
unsolicited connection attempts. Gnutella2 attempts to address this&lt;br /&gt;
somewhat by keeping track of last seen times for all hub addresses,&lt;br /&gt;
however there is a larger security concern: UDP.&lt;br /&gt;
&lt;br /&gt;
At the lowest level, TCP connections are reasonably protected by the&lt;br /&gt;
need to establish a stream between two hosts. Forging the return&lt;br /&gt;
address of a connection establishment packet results only in a&lt;br /&gt;
single (small) response packet being directed at the target host.&lt;br /&gt;
Once the stream is established, traffic cannot be directed to other&lt;br /&gt;
hosts.&lt;br /&gt;
&lt;br /&gt;
UDP on the other hand does not benefit from the security of a stream&lt;br /&gt;
connection. A received datagram may not necessarily have originated&lt;br /&gt;
from where its header would suggest. In a distributed search&lt;br /&gt;
scenario this can have a very serious consequence: forging a query&lt;br /&gt;
packet for a common object and sending it to a hub could result in a&lt;br /&gt;
large volume of search results being delivered to the forged, third&lt;br /&gt;
party host address. The more common the query term and the more&lt;br /&gt;
leaves attached to the hubs (including the effects of hub&lt;br /&gt;
clustering) and the larger the volume of return traffic. In this&lt;br /&gt;
situation the network is acting as a traffic amplifier, allowing the&lt;br /&gt;
attacker to anonymously transmit a small volume, but hit their&lt;br /&gt;
target with a large and untraceable amount of traffic.&lt;br /&gt;
&lt;br /&gt;
Similarly, attacks can be directed upon the network itself. A&lt;br /&gt;
malicious host could flood one or more hubs with query traffic using&lt;br /&gt;
random return addresses to thwart any flood control mechanism,&lt;br /&gt;
causing an overload. While nothing can be done about unsolicited&lt;br /&gt;
traffic to a node on the network (which is completely independent&lt;br /&gt;
from the peer to peer system anyway), the use of UDP can eliminate&lt;br /&gt;
the important ability to detect and ignore such abuse.&lt;br /&gt;
&lt;br /&gt;
=== Gnutella2 Solution – Query Keys ===&lt;br /&gt;
&lt;br /&gt;
A solution is built into the Gnutella2 query model. Before a search&lt;br /&gt;
originator can transmit a query to a particular hub, it must obtain&lt;br /&gt;
a &amp;quot;query key&amp;quot; for that hub and include it in the transmission.&lt;br /&gt;
Query keys are unique to the hub generating them and the return&lt;br /&gt;
address with which they are associated and generally expire after a&lt;br /&gt;
relatively long period of time.&lt;br /&gt;
&lt;br /&gt;
Originators request a query key by sending a query key request to a&lt;br /&gt;
hub, which includes the intended return address for the key. The&lt;br /&gt;
hub generates a key unique to that return address and dispatches it&lt;br /&gt;
there. This makes it impossible to get a query key for an IP which&lt;br /&gt;
you do not control, and prevents keys from being shared between two&lt;br /&gt;
nodes (key stealing).&lt;br /&gt;
&lt;br /&gt;
When receiving a query from a foreign node, Gntuella2 hubs check the&lt;br /&gt;
query key against the one they have issued for the query's requested&lt;br /&gt;
return address and proceed only if there is a match. If and only if&lt;br /&gt;
the query key matches will the query acknowledgement be sent, or the&lt;br /&gt;
search processed locally and forwarded to local leaves and&lt;br /&gt;
neighbouring hubs.&lt;br /&gt;
&lt;br /&gt;
This has several positive effects. If a query does not have a valid&lt;br /&gt;
key for the receiving hub, it will not be processed and will thus&lt;br /&gt;
not generate a traffic amplification effect which may be used in a&lt;br /&gt;
denial of service attack on a third party host. Secondly, the query&lt;br /&gt;
key mechanism ensures that queries are only processed if they were&lt;br /&gt;
transmitted from a host which has control over the host in the&lt;br /&gt;
return address (in the normal case, this is the same host). This&lt;br /&gt;
means that flood control mechanisms can remain just as effective as&lt;br /&gt;
in the TCP case. Similarly, host blocking is possible and more&lt;br /&gt;
viable than in Gnutella1 (where the source of a query could not be&lt;br /&gt;
verified).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
This document has covered the high level search model used in&lt;br /&gt;
Gnutella2, as currently deployed in the Shareaza 1.7 betas. I've&lt;br /&gt;
focused purely on search related issues here, as I think that&lt;br /&gt;
searching is probably the area of most interest to everyone at the&lt;br /&gt;
moment, and is definitely the area where there is likely to be some&lt;br /&gt;
interesting discussion.&lt;br /&gt;
&lt;br /&gt;
Gnutella2 consists of a lot more than just a revised search system,&lt;br /&gt;
which I will cover soon. The actual implementation of the query&lt;br /&gt;
model allows for a lot more flexibility than we have in the&lt;br /&gt;
Gnutella1 framework, in terms of the way information is requested&lt;br /&gt;
and the way it is returned, as well as what kinda of information is&lt;br /&gt;
dealt with. Also:&lt;br /&gt;
&lt;br /&gt;
* A new generic and extensible packet format, on which all of the&lt;br /&gt;
new functionality is built&lt;br /&gt;
* The unreliable and semi-reliable UDP transports, including encapsulation, fragmentation, retransmission, etc&lt;br /&gt;
* The specific packets involved in the search system&lt;br /&gt;
* Other base services&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Michael Stokes&lt;br /&gt;
mike@...&lt;br /&gt;
November 17, 2002&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
	<entry>
		<id>https://g2.doxu.org/index.php?title=Background&amp;diff=80</id>
		<title>Background</title>
		<link rel="alternate" type="text/html" href="https://g2.doxu.org/index.php?title=Background&amp;diff=80"/>
		<updated>2005-04-02T21:20:49Z</updated>

		<summary type="html">&lt;p&gt;Spooky: /* History */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==History==&lt;br /&gt;
The Gnutella2 protocol has been developed by [[Wikipedia:Michael_Stokes|Michael Stokes]] in the year 2002. It has been discussed quite controversial and some people prefer to refer to the Gnutella2 protocal by the name ''Mike's Protoco'' (MP). You might want to read the [[Wikipedia:Gnutella2|Wikipedia article]] on Gnutella2.&lt;br /&gt;
&lt;br /&gt;
==Old Publications==&lt;br /&gt;
* [[G2_specs_part1|Gnutella2 Specifications part ONE]]&lt;br /&gt;
* [[G2_specs_part2|Gnutella2 Specifications part TWO]]&lt;/div&gt;</summary>
		<author><name>Spooky</name></author>
	</entry>
</feed>