Gnutella Protocol Development
Home :: Developer :: Press :: Research :: Servents
2.3 Leaf mode and ultrapeer mode Source - Ultrapeer Proposal v1.0. Originally, all Gnutella nodes were connected to each other randomly. It worked fine for users with broadband connections, but not for users with slow modems. That problem can be solved by organizing the network in a more structured form. 2.3.1 Ultrapeer system [TODO: Describe ultrapeer system here. Handshaking etc. Reference to QRP when used] [TODO: Ultrapeer marked pongs: size field = power of 2] The Ultrapeer system has been found effective for this purpose. It is a scheme to have a hierarchical Gnutella network by categorizing the nodes on the network as leaves and ultrapeers. A leaf keeps only a small number of connections open, and that is to ultrapeers. An ultrapeer acts as a proxy to the Gnutella network for the leaves connected to it. This has an effect of making the Gnutella network scale, by reducing the number of nodes on the network involved in message handling and routing, as well as reducing the actual traffic among them. An ultrapeer only forwards a query to a leaf if it believes the leaf can answer it, and leaves never relay queries between ultrapeers. Ultrapeers are connected to each other and to "normal" Gnutella hosts (hosts that do not implement the Ultrapeer system). An ultrapeer decides what queries to forward to leaf nodes using the Query Routing Protocol, QRP, see 3.8. If both an ultrapeer and a leaf node supports another protocol for deciding which queries are forwarded that MAY be used instead. QRP routing is not used between ultrapeers/normal hosts. It is RECOMMENDED that servents implement the Ultrapeer system, or any future system for decreasing the bandwidth load on modem users. Ultrapeer election is self-organized. Details on the rules to choose between leaf mode and ultrapeer mode are provided in 3.7 Ultrapeer Election Principles. For more information please read the original specification. 2.3.2 Ultrapeer Handshaking Ultrapeer capatibilities and information is exchanged during the handshaking sequence when trying to establishing a new Gnutella connection (see 2.2). The following new headers are used: * X-Ultrapeer: "True" signals that node is an ultrapeer, "False" signals that the node wants to be a shielded leaf node. * X-Ultrapeer-Needed: Used to balance the number of ultrapeers. [TODO: Write more about this one] * X-Try-Ultrapeers: Like X-Try (see 2.1), but contains only addresses of ultrapeers. * X-Query-Routing: Signals support for the Query Routing Protocol (see 3.8). The header value is the QRP version (currently 0.1). It is important to note that headers can be sent in any order. Also, case is ignored in "True" and "False". Here is a sample interaction where a leaf connects to an ultrapeer. Leaf Ultrapeer ----------------------------------------------------------- GNUTELLA CONNECT/0.6User-Agent: LimeWire/1.0 X-Ultrapeer: False X-Query-Routing: 0.1 GNUTELLA/0.6 200 OK User-Agent: LimeWire/1.0 X-Ultrapeer: True X-Ultrapeer-Needed: False X-Query-Routing: 0.1 X-Try: 24.37.144:6346, 193.205.63.22:6346 X-Try-Ultrapeers: 23.35.1.7:6346, 18.207.63.25:6347 GNUTELLA/0.6 200 OK [binary messages] [binary messages] The leaf is now a shielded node of the ultrapeer. The leaf should drop any non ultrapeer connections and send a QRP routing table (assuming QRP is used). If a shielded leaf node receives a connection request, it will refuse to accept the connection by returning a 503 error code together with X-Try and X-Try-Ultrapeer headers to redirect to remote host to other addresses. For example, when a leaf tries to connect to another leaf it may look like this. Non-essential headers have been removed in this and the following examples. Leaf1 Leaf2 ----------------------------------------------------------- GNUTELLA CONNECT/0.6 X-Ultrapeer: False GNUTELLA/0.6 503 I am a leaf X-Ultrapeer: False X-Try: 24.37.144:6346 X-Try-Ultrapeers: 23.35.1.7:6346 [Terminates connection] Sometimes nodes will be ultrapeer-incapable but unable to find an ultrapeer. In this case, they behave exactly like old, unrouted Gnutella 0.4 connections. Leaf1 Leaf2 ----------------------------------------------------------- GNUTELLA CONNECT/0.6 X-Ultrapeer: False GNUTELLA/0.6 200 OK X-Ultrapeer: False GNUTELLA/0.6 200 OK [binary messages] [binary messages] When two ultrapeers meet, both set X-Ultrapeer: true. If both have leaf nodes, they will remain ultrapeers after the interaction. Note that no QRP route table is sent between ultrapeers after the connection is established. Example handshake: UltrapeerA UltrapeerB ----------------------------------------------------------- GNUTELLA CONNECT/0.6 X-Ultrapeer: True GNUTELLA/0.6 200 OK X-Ultrapeer: True GNUTELLA/0.6 200 OK [binary messages] [binary messages] Sometimes there will be too many ultrapeer-capable nodes on the network. Consider the case of an ultrapeer A connecting to an ultrapeer B. If B doesn’t have enough leaves, it may direct A to become a leaf node. If A has no leaf connections, it stops fetching new connections, drops any Gnutella 0.4 connections, and sends a QRP table to B. Then B will shield A from all traffic. If A has leaf c onnections, it ignores the guidance, as in the above case. UltrapeerA UltrapeerB ----------------------------------------------------------- GNUTELLA CONNECT/0.6 X-Ultrapeer: True GNUTELLA/0.6 200 OK X-Ultrapeer: True X-Ultrapeer-Needed: False GNUTELLA/0.6 200 OK X-Ultrapeer: False [binary messages] [binary messages]