📄 rfc-0_6-draft.html
字号:
field" and "this is the value of the second field" (leading spaces ofthe continuation were collapsed). Note that the leading space between the ":" ending the field name and the start of the value string does not count.Multiple header lines with the same field name are identical to oneheader line where all the values of the fields would be separated by ",". This means: Field: first<cr><lf> Field: second<cr><lf>is strictly equivalent to saying: Field: first,second<cr><lf>In other words, order matters in that case.Here is a sample interaction between a client and a server. Data sent from client to server is shown on the left; data sent from server to client is shown on the right. Client Server ----------------------------------------------------------- GNUTELLA CONNECT/0.6<cr><lf> User-Agent: BearShare/1.0<cr><lf> Pong-Caching: 0.1<cr><lf> GGEP: 0.5<cr><lf> <cr><lf> GNUTELLA/0.6 200 OK<cr><lf> User-Agent: BearShare/1.0<cr><lf> Pong-Caching: 0.1<cr><lf> GGEP: 0.5<cr><lf> Private-Data: 5ef89a<cr><lf> <cr><lf> GNUTELLA/0.6 200 OK<cr><lf> Private-Data: a04fce<cr><lf> <cr><lf> [binary messages] [binary messages]A few notes about the responses: first, the client (server) SHOULDdisconnect if receiving any response other than "200" at step 4(6). There is no need to define these error codes now. Second,servents SHOULD ignore higher version numbers in steps (2), (4), and(6). For example, it is perfectly legal for a future client toconnect to a server and send "GNUTELLA CONNECT/0.7". The serverSHOULD respond with "GNUTELLA/0.7 200 OK" if it supports the 0.7protocol, or "GNUTELLA/0.6 200 OK" otherwise.A few notes about the headers: servents SHOULD use standard HTTPheaders whenever appropriate. For example, servents SHOULD use thestandard "User-Agent" header rather than make up a "Servent-Vendor"header. However, it is perfectly legal to add new headers (e.g.,"Query-Routing") when no appropriate HTTP header exists, as long asthey follow HTTP syntax. Headers unknown to the servent MUST be ignored.Some older servents will initiate the handshake by sending "GNUTELLA CONNECT/0.4<lf><lf>". The server SHOULD then reply with "GNUTELLA OK<lf><lf>" followed by binary messages, if it can accept the connection. Servents MAY retry using the 0.4 connect string ifthe 0.6 connection attempt were rejected. No handshaking headers can be used in 0.4 handshaking.When rejecting a connection, a servent MUST, if possible, provide theremote host with a list of other Gnutella hosts, so it can try connecting to them. This SHOULD be done using the X-Try header.An X-Try header can look like: X-Try:1.2.3.4:1234,3.4.5.6:3456There MAY be a space after the colon and after each comma. There MAY be multiple X-Try headers in one header set. The header MAY end withan extra comma. The header MAY be formatted on several lines usingcontinuations.Each item in the X-Try header gives the IP address of a serventand its listening port number. This is sometimes referred to asbeing a "connection pong". If the server sending the X-Try implements Pong-Caching, then the connection pongs being sent must befresh ones.The normal status code for rejecting a connection because the serventis busy is "503 " followed by "Busy" or another description string.2.2 Gnutella MessagesOnce a servent has connected successfully to the network, it communicates with other servents by sending and receiving Gnutella protocol messages. Each message is preceded by a Message Header with the byte structure given below.Note 1: One IP packet may contain several Gnutella messages, and one Gnutella message may be split up on multiple IP-packets. This means one can never assume a Gnutella message ends when the chunk of data read from the socket ends.Note 2: All fields in the following structures are in little-endian byte order unless otherwise specified.Note 3: All IP addresses in the following structures are in IPv4 format. For example, the IPv4 byte array 0xD0 0x11 0x32 0x04 byte 0 byte 1 byte 2 byte 3represents the dotted address 208.17.50.4.2.2.1 Message HeaderThe message header is 23 bytes divided into the following fields. Bytes: Description: 0-15 Message ID/GUID (Globally Unique ID) 16 Payload Type 17 TTL (Time To Live) 18 Hops 19-22 Payload LengthMessage ID A 16-byte string (GUID) uniquely identifying the message on the network. Servents SHOULD store all 1's (0xff) in byte 8 of the GUID. (Bytes are numbered 0-15, inclusive.) This serves to tag the GUID as being from a modern servent. Servents SHOULD initially store all 0's in byte 15 of the GUID. This is reserved for future use. The other bytes SHOULD have random values.Payload Indicates the type of messageType 0x00 = Ping 0x01 = Pong 0x02 = Bye 0x40 = Push 0x80 = Query 0x81 = Query Hit Other Gnutella messages can be used, but if so the servent MUST first make sure that the remote host supports this new message type. This can be done using handshaking headers.TTL Time To Live. The number of times the message will be forwarded by Gnutella servents before it is removed from the network. Each servent will decrement the TTL before passing it on to another servent. When the TTL reaches 0, the message will no longer be forwarded (and MUST not).Hops The number of times the message has been forwarded. As a message is passed from servent to servent, the TTL and Hops fields of the header must satisfy the following condition: TTL(0) = TTL(i) + Hops(i) Where TTL(i) and Hops(i) are the value of the TTL and Hops fields of the message, and TTL(0) is maximum number of hops a message will travel (usually 7).Payload The length of the message immediately following Length this header. The next message header is located exactly this number of bytes from the end of this header i.e. there are no gaps or pad bytes in the Gnutella data stream. Messages SHOULD NOT be larger than 4 kB.The Payload Length field is the only reliable way for a servent to find the beginning of the next message in the input stream. Therefore, servents SHOULD rigorously validate the Payload Length field for each message received. If a servent becomes out of synch with its input stream, it SHOULD close the connection associated withthe stream since the upstream servent is either generating, or forwarding, invalid messages.Abuse of the TTL field in broadcasted messages (Query) will lead to an unnecessary amount of network traffic and poor network performance. Therefore, servents SHOULD carefully check the TTL fields of received query messages and lower them as necessary. Assuming the servent's maximum admissible Query message life is 7 hops, then if TTL + Hops > 7, TTL SHOULD be decreased so that TTL + Hops = 7. Broadcasted messages with very high TTL values (>15) SHOULD be dropped.Immediately following the message header, is a payload consisting of one of the following messages.2.2.2 Ping (0x00)Ping messages MAY contain a GGEP extension block (see Section 2.3),but no other payload.2.2.3 Pong (0x01)Pong messages contains information about a Gnutella host. The message has the following fields Bytes: Description: 0-1 Port number. The port number on which the responding host can accept incoming connections. 2-5 IP Address. The IP address of the responding host. Note: This field is in big-endian format. 6-9 Number of shared files. The number of files that the servent with the given IP address and port is sharing on the network. 10-13 Number of kilobytes shared. The number of kilobytes of data that the servent with the given IP address and port is sharing on the network. 14- OPTIONAL GGEP extension block. (see Section 2.3)Pong messages are only sent in response to an incoming Ping message. It is valid for more than one Pong message to be sent in response to a single Ping message. This enables host caches to send cached servent address information in response to a Ping request.The Message ID of a Pong message MUST be the Message ID of the Ping message it is sent in reply to.The fields specifying the number of shared files and the number of kilobytes shared was intended to allow one to measure the amount of data available on the network. With a very large Gnutella network, and minimized Ping and Pong message traffic, this can no longer be done. Still, these fields SHOULD be filled out correctly. 2.2.4 Use of Ping and Pong messagesIn early versions Gnutella, Ping messages were broadcasted over thenetwork. Pong messages were then routed back to the originator of the Ping message the same way as Query Hits messages are routed(se section 2.2.7). That system consumed a lot of network bandwidth, so modern Gnutella servents cache Pong messages, or use other means of minimizing the bandwidth used by Ping and Pong messages. There are different systems for handling Ping and Pong messages, but what they have in common is: * When a Ping message is received (TTL>1 and it was at least one second since another Ping was received on that connection), a servent MUST, if possible, respond with a number of Pong Messages. These pongs MUST have the same message ID as the incoming ping, and a TTL no lower than the hops value of the ping. The number of pongs returned may vary, but 10 is a reasonable number. Servents that are able to accept incoming Gnutella SHOULD reply to these Ping messages. * The pongs sent SHOULD have a good quality. That includes high probability that they are connectable and a good spread of hosts from across the network * The bandwidth used by Ping and Pong messages SHOULD be minimized. Servents MUST never output very high quantities of Ping and Pong messages. * An incoming Ping message with TTL = 1 and Hops = 0 or 1 is used to probe the remote host of a connection, and MUST always be replied to with a pong having information about the host who received the ping. * An incoming Ping message with TTL = 2 and Hops = 0 is a "Crawler Ping" used to scan the network. It and SHOULD be replied to with pongs containing information about the host receiving the ping and all other hosts it is connected to. The information about neighbour nodes can be provided either by creating pongs on their behalf, or by forwarding the ping to them, and forward the pongs returned to the crawler.Servents fulfilling these requirements MUST provide a the header"Pong-Caching: 0.1" (or a higher number if a later version is used) during the handshake. That allows other nodes to know if pong caching in any form is supported. Note that this applies to servents do not really cache pong messages as well, as long as the rules aboveapplies. Servents are strongly RECOMMENDED to follow the rules above,and provide the Pong-Caching header.When storing or forwarding Pong messages, any GGEP payload SHOULD beincluded. When sending a Ping message, one cannot know if it will reach only the neighbour host, or many hosts on the network. It depends on what system for handling Ping and Pong messages other servents are using. Servents MUST NOT make assumptions of how far a Ping message (and its payload) will reach.2.2.4.1 A simple pong caching schemeThis is one system for handling Ping and Pong messages. There are others available (see sect. 2.2.4.2), and any system that abides to the rules in sect. 2.2.4 is ok.For each connection an array of Pong Messages are stored. 10 may be a good number. When a pong comes in, it overwrites the oldest stored pong in array of he connection the pong came from. The information that must be stored for each pong is: * IP Address
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -