Download Implementation of the Gnutella protocol in Python

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

RapidIO wikipedia , lookup

Lag wikipedia , lookup

Asynchronous Transfer Mode wikipedia , lookup

Airborne Networking wikipedia , lookup

TCP congestion control wikipedia , lookup

Deep packet inspection wikipedia , lookup

Wake-on-LAN wikipedia , lookup

Point-to-Point Protocol over Ethernet wikipedia , lookup

Internet protocol suite wikipedia , lookup

Zero-configuration networking wikipedia , lookup

AppleTalk wikipedia , lookup

List of wireless community networks by region wikipedia , lookup

I²C wikipedia , lookup

IEEE 802.1aq wikipedia , lookup

Recursive InterNetwork Architecture (RINA) wikipedia , lookup

Cracking of wireless networks wikipedia , lookup

CAN bus wikipedia , lookup

Kademlia wikipedia , lookup

UniPro protocol stack wikipedia , lookup

Routing in delay-tolerant networking wikipedia , lookup

Real-Time Messaging Protocol wikipedia , lookup

Transcript
Implementation of the Gnutella
protocol in Python
Israel Herraiz Tabernero
[email protected]
(cc) 2005 Israel Herraiz Tabernero
Some rights reserved.
This work is licensed under the
Creative Commons Attribution-ShareAlike License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/2.0/
or send a letter to
Creative Commons, 559 Nathan Abbot Way, Stanford, California 94305, USA
2
Contents
1 Introduction
1
1.1 Description of the protocol . . . . . . . . . . . . . . . . . . . .
1
1.2 Payloads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.2.1
Ping . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.2.2
Pong . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.2.3
Query . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
1.2.4
QueryHit . . . . . . . . . . . . . . . . . . . . . . . . .
4
1.2.5
Push . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
1.3 Routing algorithm . . . . . . . . . . . . . . . . . . . . . . . .
6
1.4 File downloads . . . . . . . . . . . . . . . . . . . . . . . . . .
7
2 Examples of use
7
2.1 How to create a new servent . . . . . . . . . . . . . . . . . . .
7
2.2 Video examples . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.1
First video . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.2
Second video . . . . . . . . . . . . . . . . . . . . . . . 12
3 Description of the library
13
4 Analyzing the traffic with Ethereal
14
A pyGnutella traffic analyzed with Ethereal
16
References
24
i
1
Introduction
This work describes the Gnutella protocol, and how it was implemented in the
Python language. The implemented version is 0.4 (document revision 1.2).
There is a project in SourceForge.net, for those who are willing to collaborate
in the development. The project is at http://sf.net/projects/pygnutella. The
last version of the library is available in the CVS repository of that project.
As the protocol specification says [1], Gnutella is a protocol for distributed
search. Each node of the network is at the same time a server and a client,
and so they are named in the specification servents. The algorithm to try
to find a resource in the network is flooding; each time a servent receives a
query, it resends the query to the rest of nodes to which are connected, and if
the resource is available in that node, sends a reply following the same path
than the initial query.
There are currently two versions of the protocol: the stable one, 0.4, which
is the version implemented and described in this document, and the unstable
one (when this document was written), 0.6, which includes some improvements (intelligent query routing [2], SHA-1 checksums, query hit transmission via UDP, querying via UDP, dynamic queries via UDP, file transfers via
UDP, XML meta data, parallel downloading in slices).
The version 0.4 is quite simple, and it is not intended to share files over a
net, rather to look for that files.
1.1
Description of the protocol
There are five descriptors which define the possible communications between
the nodes:
• Ping
Used to actively discover hosts on the network. A servent receiving a
Ping descriptor should respond with one or more Pong descriptors, and
resend the ping to the rest of nodes.
• Pong
The response to a Ping. Includes the address of a connected Gnutella
servent and information
1
• Query
Used to look for resources (f.e., files) over the network. A servent
receiving a Query, should respond with a QueryHit if the search criteria
match with any resource of that node, and resend the query to the rest
of nodes.
• QueryHit
The response to a Query. This descriptor provides the necessary information to obtain the searched resource from the source node.
• Push
A mechanism that allows a firewalled servent to provide resources to
the network.
A servent must connect to an existing node, in order to be part of the network.
How to solve the address of an existing node is not part of the protocol,
although hosts cache servers exist [3].
Once the address of an existing node is known, the node must establish a
TCP/IP connection to the servent, and send the following ASCII string:
GNUTELLA CONNECT/0.4\n\n
If the existing node is ready, should respond with
GNUTELLA OK\n\n
Any other response means that the node has rejected the connection.
The annotated version of the protocol [4] remarks that the servent should
accept not only \n characters, but also \r or \r\n characters at the end of
each string.
In the version 0.6, this handshaking mechanism is a bit more complex, including some metadata (for example, User Agent). In theory, 0.6 version
compliant nodes can accept connections from 0.4 compliant nodes, but in
practice these nodes used to accept only connections from 0.6 nodes1 .
1
As the 0.6 specification says (section 2.1) [5], the details for how to accept connection
requests, as well as how to select what other Gnutella hosts to connect to, are included in
the appendix 4 of the specification, but at this moment that appendix is missing in the
document.
2
Once the servent is connected to the network, it can send descriptors to the
rest of nodes. Each descriptor has a header of 23 bytes, with the following
fields:
• Descriptor ID (16 bytes). Each descriptor should have an unique id.
• Payload descriptor (1 byte). Ping, Pong, Push, Query or QueryHit.
• Time to live (1 byte). It should be less than 127 if the node is on the
Internet.
• Hops (1 byte). It should be less than 127 if the node is on the Internet.
• Payload length (4 bytes). The length of the descriptor immediately
following this header.
The packets are dropped when the Time to Live (TTL) expires. If the TTL
is excessive, the amount of traffic in the network will be high, and then the
performance low.
The payload length is fundamental to identify the descriptors in the input
stream. There are not characters remarking the beginning or end of the
headers and descriptors. If a node loose the sync with the input stream, it
should drop the connection and try to establish a new one.
1.2
1.2.1
Payloads
Ping
The descriptor for this payload is 0x00. Its length is zero.
If a node receives a ping, should respond with a Pong, and try to resend the
Ping to the rest of nodes if the TTL has not expired.
1.2.2
Pong
The descriptor for this payload is 0x01. Its length is 14 bytes. It contains
the following fields:
3
• Port (2 bytes). The port number on which the responding host can
accept incoming connections.
• IP (4 bytes). The IP address of the responding host (IPv4 format).
• Number of files shared (4 bytes).
• Number of kilobytes shared (4 bytes).
Pong descriptors are only sent in response to a Ping descriptor. The servent
can send more than one Pong descriptor; this is useful, for example, if the
servent has cached the addresses of other nodes, because it can send one
Pong for each address.
The descriptor id in the header should be the same than the descriptor id in
the original Ping.
1.2.3
Query
The descriptor for this payload is 0x80. It has not a fixed length. It contains
the following fields:
• Minimum speed (2 bytes). The minimum speed (in kbps) of servents
that should respond to this message.
• Search criteria. A null (0x00) terminated string.
The length of the payload (in spite of the null terminated string, that could
be helpful to identify the end of the payload) should match the payload
length field in the header.
1.2.4
QueryHit
The descriptor for this payload is 0x81. It has not a fixed length. It contains
the following fields:
• Number of hits (1 byte).
4
• Port (2 bytes).
• IP address (4 bytes).
• Speed (4 bytes). The speed of the responding host, in kbps.
• Result set. A set of responses to the corresponding query, with the
following fields:
– File index (4 bytes). An index assigned by the responding host.
– File size (4 bytes). In bytes.
– File name. A string finished in a double null (0x0000).
This result set contains that structure as many times as the first field
in the payload (Number of hits).
• Servent identifier (16 bytes). This identifier should be unique for each
host. It can be some function of the IP address of the host.
This descriptor should be sent only in response to Query descriptors. The
QueryHit is sent following the same path than the original Query.
The descriptor id in the header should be the same than the descriptor id in
the original Query.
1.2.5
Push
The descriptor for this payload is 0x40. Its size is 26 bytes. It contains the
following fields:
• Servent identifier (16 bytes). This identifier should be unique for each
host. It can be some function of the IP address of the host. In this
case, it must be the identifier of the node that is behind the firewall.
• File index (4 bytes). The index of the file that can not be shared
because this node is behind a firewall.
• IP address (4 bytes).
• Port (2 bytes).
5
QueryHit
Node
server
Node
client
Firewall
Push
Figure 1: Pushing procedure. A node behind a firewall can not act as a server
but can act as a client. The QueryHit and the Push descriptors are sent by
the same socket, corresponding to the initial connection from the firewalled
servent to one node in the Gnutella network.
A client node A sends a Query. The Query reaches a server node B which is
behind a firewall. B responds with a QueryHit, but as it is behind a firewall,
it can not share files2 , so the connection from A to B is not possible. Then A
sends a Push to B, and then B begins the connection to A, in order to share
the file that is in B. More details are given in the specification document [1].
1.3
Routing algorithm
Each servent must route each descriptor to the rest of nodes. The algorithm
is quite simple. Ping and Query descriptors are send to all the nodes directly
connected to the each node (except the one that delivered the incoming
2
Because this require to create a new connection from A to B, because the file downloads
are made by a direct HTTP connection between the nodes, and not in the Gnutella
network.
6
descriptor), until the TTL expires.
Pong descriptors must be sent only along the same path than the incoming
Ping. The Pong must have the same identifier than the incoming Ping.
The same procedure applies to QueryHit and Query.
In the case of Push descriptors, they must be sent following the same path
than the incoming QueryHit descriptor.
In each node, the TTL of each descriptor must be decremented in one unit,
and the hops must be increased in one unit. If the TTL is zero, the node
must drop that descriptor.
If a servent receives a descriptor that it has received before, it should avoid
to resend to other nodes, to avoid waste traffic in the network. If a servent
receives a Pong or a QueryHit descriptor, and it has not seen a Ping or Query
with the same identifier, it should drop the Pong or QueryHit descriptor.
1.4
File downloads
The file downloads are made out of the Gnutella network. The client node
establish a HTTP connection with the server node, in order to obtain the
file. More details are given in the specification document [1].
2
Examples of use
In this section we show some examples of use of the library. The full documentation of the library is available at [6].
For the examples is required a Python console, and the pyGnutella module
in one of the directories of the PYTHONPATH environment variable.
2.1
How to create a new servent
First of all, let’s initiate a new Python console:
7
herraiz@arenales:~ $ python
Python 2.4.1 (#2, Mar 30 2005, 21:51:10)
[GCC 3.3.5 (Debian 1:3.3.5-8ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
From the console, let’s call the pyGnutella module, and create a new Servent:
>>> from pygnutella import *
>>> a = Servent()
This node can act as a client and as a server. To begin the server, we must
use the beginServer method:
>>> a.beginServer()
>>> DEBUG: *1* Server started
By default, debug messages are shown.
Now we can try to connect to this server using any client. For example, with
a Telnet session from another console:
herraiz@arenales:~ $ telnet localhost 6346
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is ’^]’.
At the same moment, in the Python console we must obtain a debug message:
DEBUG: *1* Client connected to this server
If we try to connect
GNUTELLA CONNECT/0.4
(pressing Enter twice)
another message is shown in the Python console
8
DEBUG: *1* Connection request succeded
and in the Telnet session we obtain the next message
GNUTELLA OK
(plus two end of line characters)
Each servent can accept any number of clients. For example, let’s create
another servent from the Python console:
>>> b = Servent()
>>> b.connect(a.host_address)
The following debug messages are shown:
>>> DEBUG:
DEBUG: *2*
DEBUG: *1*
DEBUG: *1*
*2* Begin connection
Trying to connect to (’127.0.0.1’, 6346)
Client connected to this server
Connection request succeded
Now, if we send a Ping from a, the Telnet session and the b servent should
receive the descriptor. In the Telnet session, we obtain:
(Ping descriptor)
(the string may differ, because the 16 byte identifier is random)
and in the Python console, we can see the debug messages:
>>> DEBUG: *2* Pong response because it is not mine, and it is the first time I s
DEBUG: *2* Ping routing
DEBUG: *1* Catched pong from socket 127.0.0.1:6346
The b servent has sent a Pong, which has been catched by a. The Telnet
session has not responded.
If the Ping is sent by b,
9
the Telnet session should also receive the Ping:
(Ping descriptor)
and in the Python console we obtain the next messages:
>>> DEBUG: *1* Pong response because it is not mine, and it is the first time I s
DEBUG: *1* Ping routing
DEBUG: *2* Catched pong from socket 127.0.0.1:6346
As we can see, the two servents initiated in the Python console have the same
address. As we have not initiated a server in b, there is not an immediate
conflict, but the two servents could not share files because of this error. So
let’s change the address of b, and initiate a new server on b
>>> b.host_address = (’127.0.0.1’,6345)
>>> b.beginServer()
>>> DEBUG: *2* Server started
Now, for example, we can begin a new Telnet session, to connect to this new
server
herraiz@arenales:~ $ telnet localhost 6345
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is ’^]’.
And in the Python console
>>> DEBUG: *2* Client connected to this server
By default, the servers wait until the connection is succeeded:
10
DEBUG: *2* Timeout while waiting for connection request
DEBUG: *2* Timeout while waiting for connection request
DEBUG: *2* Connection request succeded
(in this case, some seconds have elapsed since the beginning of the session,
and the request for a new connection to the servent).
As all the nodes are connected, each Ping or Query should be received by all
the nodes. For example:
>>> b.sendQuery("mp3",512)
DEBUG: *2* Query sent
>>> DEBUG: *1* Query proccesed
DEBUG: *1* 512
DEBUG: *1* mp3
DEBUG: *1* Query sent
DEBUG: *1* Query routing
DEBUG: *2* QueryHit processed
DEBUG: Query Hit processed because it’s mine
The descriptors have been received also in the two Telnet sessions:
(Query descriptor)mp3
2.2
Video examples
There are some videos showing the usage of the library. The videos are
available at http://pygnutella.sf.net/videos/.
2.2.1
First video
In the first video there are three nodes:
• arenales
• calibre
11
• gsyc016
In this case, arenales can not respond to the connection requests because
it is overloaded3 .
In the first step, we have opened a Python shell in each node, and created
the Servents. Then, we started a server in gsyc016 and in arenales. After
that, we tried to connect to these servers from calibre. The connection from
calibre to gsyc016 is successful, but the one to arenales is not. Finally,
a Ping is sent from calibre, and only gsyc016 is responding with a Pong.
The Ping is not routed because the server is only attending one socket, which
is the incoming socket.
2.2.2
Second video
In the second video there are also three nodes:
• gsyc048
• gsyc016
• calibre
gsyc048 is acting as a server, and connections are initiated from gsyc016
and from calibre.
gsyc016 is sending a Ping, and catching Pongs from gsyc048 and calibre.
The Ping is routed by gsy048 to calibre, then calibre has sent a Pong
following the same socket than the incoming Ping, the Pong has reached
gsyc048, which has sent again the Pong following the same socket than the
original Ping, and so finally the Pong descriptor has been received by the
node which sent the Ping. Moreover, gsyc048 itself responds to the Ping
with another Pong descriptor.
calibre sends also another Ping, obtaining Pongs from the other two nodes.
The algorithm is the same, but in this case the descriptors follow the opposite
way.
3
It is recording the video.
12
After that the two nodes send Queries to the rest of the network, obtaining
responses from the rest of nodes. The routing algorithm is the same than
above (with Query and QueryHit instead of Ping and Pong).
As Ping as Query descriptors are dropped when all the nodes have received
the descriptors.
The next step is a loop of five iterations, sending Pings from calibre. For
each iteration, calibre receives a Pong from the each node of the rest of the
network. The Ping descriptors are appropriately routed by gsyc048, which
is the node in the middle.
And again, the loop is repeated, this time with Query descriptors instead of
Ping descriptors.
3
Description of the library
The library has been implemented in Python language. The library is object
oriented, and has five classes. Moreover, the library is multithread, so an
arbitrary number of sockets can be handled in parallel.
The classes of the library are the following:
• AttendConnectionThread
Objects of this type attend the incoming petitions, which a servent
receive via each socket, once the connection has been established. Each
object creates a new thread, so the main thread is not locked to attend
the petitions of each socket, and so an arbitrary number of sockets can
be attended in parallel by each servent.
• ClientThread
Objects of this type try to establish a new connection to a servent in
a Gnutella network. Each object creates a new thread, so while the
node is waiting for the response of the servent, the main thread is not
locked.
• ListenToConnectionsThread
Objects of this type attend the petitions of each new connection. Each
object creates a new thread, just after the first connection is estab13
lished. The number of simultaneous connections can be configured.
Default value is 5.
• Servent
This is the main class of the library. Each object represents a node in a
Gnutella network. Each node is able to accept incoming connections, to
connect to other nodes, and to respond to the petitions included in the
specification of the Gnutella protocol. Each object creates new threads
when they are needed, in a transparent way (the developer should not
care about the thread that are started or stopped).
• ServerThread
Each object of this type prepares the node to accept incoming connections, and accepts the first connection. Once the first connection
is accepted and established, it creates two threads, one of the type
AttendConnectionThread to attend the incoming petitions of the first
connection, and one of the type ListenToConnectionsThread to accept new connections. The parent thread finish after the creation of
these two threads.
4
Analyzing the traffic with Ethereal
In this section, some data obtained using the protocol’s analyzer Ethereal
are shown. Moreover, some comparisons with well known Gnutella clients are
made. For capturing the data from pygnutella a few nodes were launched
in an unique host, each node listening in a different port. Then some Pings
and Queries were sent by some nodes, and the rest of nodes responded to
that petitions. The whole traffic was captured meanwhile.
In the appendix A a sample of packets generated by pyGnutella servents
are shown:
• The first is a Ping packet. In the Gnutella protocol section we can
see that the TTL is 4 and the number of hops is 1, so the initial TTL
was 5, and this packet has been resent by a node different than the
node which originated the Ping.
• The second is a Pong packet, with a TTL of 5 and a number of hops of
0, so it comes from its original servent. We can see that the responding
node is sharing 0 files (for a total amount of 0 bytes).
14
• The third is a Query. We can see that the servent which created this
petition is looking for “mp3”, but only coming from nodes which can
serve at least at 512 kbps.
• The next is a combination of a Pong and a Query. As the source and
origin of the two descriptors were the same, and the time of generation
was almost the same, Ethereal has joined the two descriptors in only
one packet. But if we see the section Gnutella protocol, we can
notice that in effect there are two descriptors with different headers.
• The last packet is a QueryHit. In this case, the responding node is not
sharing files, because the QueryHit was generated only due to debugging purposes.
We captured also the traffic of some well known Gnutella clients. All the files
are available at http://pygnutella.sf.net/ethereal/, but the clients tested were
implementing the version 0.6 of the protocol. So we could not connect these
clients with pyGnutella servents. Moreover, Ethereal (version 0.10.10) did
not recognise the 0.6 traffic4 .
In any case, Ethereal has recognised the traffic generated by pyGnutella as
Gnutella traffic, and was able to extract the information from each packet,
so we can think that our implementation is according to the specification.
4
It only remarked that it was Gnutella traffic, but it was not able to extract the
information from the packet
15
A
No.
pyGnutella traffic analyzed with Ethereal
Time
50 5.015690
Source
Destination
Protocol Info
localhost.localdomain localhost.localdomain Gnutella Ping
Frame 50 (77 bytes on wire, 77 bytes captured)
Arrival Time: Aug 3, 2005 17:49:37.323556000
Time delta from previous packet: 5.015690000 seconds
Time since reference or first frame: 5.015690000 seconds
Frame Number: 50
Packet Length: 77 bytes
Capture Length: 77 bytes
Protocols in frame: eth:ip:tcp:gnutella
Ethernet II, Src: 00:00:00:00:00:00, Dst: 00:00:00:00:00:00
Destination: 00:00:00:00:00:00 (00:00:00_00:00:00)
Source: 00:00:00:00:00:00 (00:00:00_00:00:00)
Type: IP (0x0800)
Internet Protocol, Src Addr: localhost.localdomain (127.0.0.1), Dst Addr: localhost.localdomain
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 63
Identification: 0xa229 (41513)
Flags: 0x04 (Don’t Fragment)
0... = Reserved bit: Not set
.1.. = Don’t fragment: Set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 64
Protocol: TCP (0x06)
Header checksum: 0x9a8d (correct)
Source: localhost.localdomain (127.0.0.1)
Destination: localhost.localdomain (127.0.0.1)
Transmission Control Protocol, Src Port: 48228 (48228), Dst Port: gnutella-svc (6346), Seq: 23,
Source port: 48228 (48228)
Destination port: gnutella-svc (6346)
Sequence number: 23
(relative sequence number)
Next sequence number: 46
(relative sequence number)
Acknowledgement number: 14
(relative ack number)
Header length: 20 bytes
Flags: 0x0018 (PSH, ACK)
0... .... = Congestion Window Reduced (CWR): Not set
.0.. .... = ECN-Echo: Not set
..0. .... = Urgent: Not set
...1 .... = Acknowledgment: Set
16
.... 1... = Push: Set
.... .0.. = Reset: Not set
.... ..0. = Syn: Not set
.... ...0 = Fin: Not set
Window size: 32767
Checksum: 0x5796 (correct)
Gnutella Protocol
Descriptor Header
ID: 8F1157FEB71AA70BF76FFA578EAB34AE
Payload: 0 (Ping)
TTL: 4
Hops: 1
Length: 0
No.
Time
57 5.018522
Source
Destination
Protocol Info
localhost.localdomain localhost.localdomain Gnutella Pong
Frame 57 (91 bytes on wire, 91 bytes captured)
Arrival Time: Aug 3, 2005 17:49:37.326388000
Time delta from previous packet: 0.001166000 seconds
Time since reference or first frame: 5.018522000 seconds
Frame Number: 57
Packet Length: 91 bytes
Capture Length: 91 bytes
Protocols in frame: eth:ip:tcp:gnutella
Ethernet II, Src: 00:00:00:00:00:00, Dst: 00:00:00:00:00:00
Destination: 00:00:00:00:00:00 (00:00:00_00:00:00)
Source: 00:00:00:00:00:00 (00:00:00_00:00:00)
Type: IP (0x0800)
Internet Protocol, Src Addr: localhost.localdomain (127.0.0.1), Dst Addr: localhost.localdomain
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 77
Identification: 0x5eab (24235)
Flags: 0x04 (Don’t Fragment)
0... = Reserved bit: Not set
.1.. = Don’t fragment: Set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 64
Protocol: TCP (0x06)
Header checksum: 0xddfd (correct)
Source: localhost.localdomain (127.0.0.1)
Destination: localhost.localdomain (127.0.0.1)
Transmission Control Protocol, Src Port: gnutella-svc (6346), Dst Port: 48225 (48225), Seq: 14,
17
Source port: gnutella-svc (6346)
Destination port: 48225 (48225)
Sequence number: 14
(relative sequence number)
Next sequence number: 51
(relative sequence number)
Acknowledgement number: 46
(relative ack number)
Header length: 20 bytes
Flags: 0x0018 (PSH, ACK)
0... .... = Congestion Window Reduced (CWR): Not set
.0.. .... = ECN-Echo: Not set
..0. .... = Urgent: Not set
...1 .... = Acknowledgment: Set
.... 1... = Push: Set
.... .0.. = Reset: Not set
.... ..0. = Syn: Not set
.... ...0 = Fin: Not set
Window size: 32767
Checksum: 0xdaa6 (correct)
Gnutella Protocol
Descriptor Header
ID: 8F1157FEB71AA70BF76FFA578EAB34AE
Payload: 1 (Pong)
TTL: 5
Hops: 0
Length: 14
Pong
Port: 6346
IP: localhost.localdomain (127.0.0.1)
Files Shared: 0
KBytes Shared: 0
No.
Time
76 10.018983
Source
Destination
Protocol Info
localhost.localdomain localhost.localdomain Gnutella Query
Frame 76 (83 bytes on wire, 83 bytes captured)
Arrival Time: Aug 3, 2005 17:49:42.326849000
Time delta from previous packet: 0.000171000 seconds
Time since reference or first frame: 10.018983000 seconds
Frame Number: 76
Packet Length: 83 bytes
Capture Length: 83 bytes
Protocols in frame: eth:ip:tcp:gnutella
Ethernet II, Src: 00:00:00:00:00:00, Dst: 00:00:00:00:00:00
Destination: 00:00:00:00:00:00 (00:00:00_00:00:00)
Source: 00:00:00:00:00:00 (00:00:00_00:00:00)
Type: IP (0x0800)
Internet Protocol, Src Addr: localhost.localdomain (127.0.0.1), Dst Addr: localhost.localdomain
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
18
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 69
Identification: 0x5eaf (24239)
Flags: 0x04 (Don’t Fragment)
0... = Reserved bit: Not set
.1.. = Don’t fragment: Set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 64
Protocol: TCP (0x06)
Header checksum: 0xde01 (correct)
Source: localhost.localdomain (127.0.0.1)
Destination: localhost.localdomain (127.0.0.1)
Transmission Control Protocol, Src Port: gnutella-svc (6346), Dst Port: 48225 (48225), Seq: 74,
Source port: gnutella-svc (6346)
Destination port: 48225 (48225)
Sequence number: 74
(relative sequence number)
Next sequence number: 103
(relative sequence number)
Acknowledgement number: 46
(relative ack number)
Header length: 20 bytes
Flags: 0x0018 (PSH, ACK)
0... .... = Congestion Window Reduced (CWR): Not set
.0.. .... = ECN-Echo: Not set
..0. .... = Urgent: Not set
...1 .... = Acknowledgment: Set
.... 1... = Push: Set
.... .0.. = Reset: Not set
.... ..0. = Syn: Not set
.... ...0 = Fin: Not set
Window size: 32767
Checksum: 0x1e53 (correct)
Gnutella Protocol
Descriptor Header
ID: EB98BB6A75D7318D4D3783CD31598E61
Payload: 128 (Query)
TTL: 5
Hops: 0
Length: 6
Query
Min Speed: 512
Search: mp3
No.
Time
94 10.023551
Source
Destination
Protocol Info
localhost.localdomain localhost.localdomain Gnutella Pong, Query
Frame 94 (121 bytes on wire, 121 bytes captured)
19
Arrival Time: Aug 3, 2005 17:49:42.331417000
Time delta from previous packet: 0.000017000 seconds
Time since reference or first frame: 10.023551000 seconds
Frame Number: 94
Packet Length: 121 bytes
Capture Length: 121 bytes
Protocols in frame: eth:ip:tcp:gnutella
Ethernet II, Src: 00:00:00:00:00:00, Dst: 00:00:00:00:00:00
Destination: 00:00:00:00:00:00 (00:00:00_00:00:00)
Source: 00:00:00:00:00:00 (00:00:00_00:00:00)
Type: IP (0x0800)
Internet Protocol, Src Addr: localhost.localdomain (127.0.0.1), Dst Addr: localhost.localdomain
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 107
Identification: 0x55de (21982)
Flags: 0x04 (Don’t Fragment)
0... = Reserved bit: Not set
.1.. = Don’t fragment: Set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 64
Protocol: TCP (0x06)
Header checksum: 0xe6ac (correct)
Source: localhost.localdomain (127.0.0.1)
Destination: localhost.localdomain (127.0.0.1)
Transmission Control Protocol, Src Port: 48225 (48225), Dst Port: gnutella-svc (6346), Seq: 69,
Source port: 48225 (48225)
Destination port: gnutella-svc (6346)
Sequence number: 69
(relative sequence number)
Next sequence number: 136
(relative sequence number)
Acknowledgement number: 133
(relative ack number)
Header length: 20 bytes
Flags: 0x0018 (PSH, ACK)
0... .... = Congestion Window Reduced (CWR): Not set
.0.. .... = ECN-Echo: Not set
..0. .... = Urgent: Not set
...1 .... = Acknowledgment: Set
.... 1... = Push: Set
.... .0.. = Reset: Not set
.... ..0. = Syn: Not set
.... ...0 = Fin: Not set
Window size: 32767
Checksum: 0xbb4b (correct)
SEQ/ACK analysis
20
This is an ACK to the segment in frame: 93
The RTT to ACK the segment was: 0.000017000 seconds
Gnutella Protocol
Descriptor Header
ID: FE0F5EEC9765B0C07F10D6F165C309E7
Payload: 1 (Pong)
TTL: 5
Hops: 0
Length: 14
Pong
Port: 6344
IP: localhost.localdomain (127.0.0.1)
Files Shared: 0
KBytes Shared: 0
Gnutella Protocol
Descriptor Header
ID: DE1E2A7E5D6D9A3CA3222C1598A67F28
Payload: 128 (Query)
TTL: 4
Hops: 1
Length: 7
Query
Min Speed: 128
Search: hola
No.
Time
98 10.024246
Source
Destination
Protocol Info
localhost.localdomain localhost.localdomain Gnutella QueryHit[Unreassembled
Frame 98 (119 bytes on wire, 119 bytes captured)
Arrival Time: Aug 3, 2005 17:49:42.332112000
Time delta from previous packet: 0.000017000 seconds
Time since reference or first frame: 10.024246000 seconds
Frame Number: 98
Packet Length: 119 bytes
Capture Length: 119 bytes
Protocols in frame: eth:ip:tcp:gnutella
Ethernet II, Src: 00:00:00:00:00:00, Dst: 00:00:00:00:00:00
Destination: 00:00:00:00:00:00 (00:00:00_00:00:00)
Source: 00:00:00:00:00:00 (00:00:00_00:00:00)
Type: IP (0x0800)
Internet Protocol, Src Addr: localhost.localdomain (127.0.0.1), Dst Addr: localhost.localdomain
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
0000 00.. = Differentiated Services Codepoint: Default (0x00)
.... ..0. = ECN-Capable Transport (ECT): 0
.... ...0 = ECN-CE: 0
Total Length: 105
21
Identification: 0xb6bf (46783)
Flags: 0x04 (Don’t Fragment)
0... = Reserved bit: Not set
.1.. = Don’t fragment: Set
..0. = More fragments: Not set
Fragment offset: 0
Time to live: 64
Protocol: TCP (0x06)
Header checksum: 0x85cd (correct)
Source: localhost.localdomain (127.0.0.1)
Destination: localhost.localdomain (127.0.0.1)
Transmission Control Protocol, Src Port: gnutella-svc (6346), Dst Port: 48227 (48227), Seq: 89,
Source port: gnutella-svc (6346)
Destination port: 48227 (48227)
Sequence number: 89
(relative sequence number)
Next sequence number: 154
(relative sequence number)
Acknowledgement number: 113
(relative ack number)
Header length: 20 bytes
Flags: 0x0018 (PSH, ACK)
0... .... = Congestion Window Reduced (CWR): Not set
.0.. .... = ECN-Echo: Not set
..0. .... = Urgent: Not set
...1 .... = Acknowledgment: Set
.... 1... = Push: Set
.... .0.. = Reset: Not set
.... ..0. = Syn: Not set
.... ...0 = Fin: Not set
Window size: 32767
Checksum: 0x3489 (correct)
SEQ/ACK analysis
This is an ACK to the segment in frame: 97
The RTT to ACK the segment was: 0.000017000 seconds
Gnutella Protocol
Descriptor Header
ID: DE1E2A7E5D6D9A3CA3222C1598A67F28
Payload: 129 (QueryHit)
TTL: 5
Hops: 0
Length: 42
QueryHit
Count: 1
Port: 6346
IP: localhost.localdomain (127.0.0.1)
Speed: 128
Hit
Index: 0
Size: 0
Name: null
Extra: 3030CA187F
22
[Unreassembled Packet: GNUTELLA]
23
References
[1] Clip2 Distributed Search Services, Gnutella Protocol Specification v0.4.
http://www.stanford.edu/class/cs244b/gnutella protocol 0.4.pdf.
[2] M. T. Prinkey, “An efficient scheme for query processing on
peer-to-peer networks,” tech. rep., Aeolus Research, Inc., 2000.
http://aeolusres.homestead.com/files/.
[3] http://qtella.sourceforge.net/hosts.php.
[4] The
Gnutella
Developer
Forum,
The
Gnutella
Protocol
Specification
v0.4.
gnutella.sourceforge.net/developer/stable/index.html.
Annotated
http://rfc-
[5] The Gnutella Developer Forum, The Gnutella Protocl Specification v0.6,.
http://rfc-gnutella.sourceforge.net/developer/testing/index.html.
[6] http://pygnutella.sourceforge.net/doc/refdoc.html.
24