Hi,
I was looking at both LimeWire's and gtk-gnutella's interpretation of
the MinSpeed bits, and they seem to be different:
in gtk-gnutella:
#define QUERY_SPEED_MARK 0x8000 /* Field is special: not a speed */
#define QUERY_SPEED_FIREWALLED 0x4000 /* Issuing servent is firewalled */
#define QUERY_SPEED_NO_XML 0x2000 /* No XML in result set, please */
#define QUERY_SPEED_LEAF_GUIDED 0x1000 /* Leaf-guided query */
#define QUERY_SPEED_GGEP_H 0x0800 /* Recipient understands GGEP "H" */
#define QUERY_SPEED_OOB_REPLY 0x0400 /* Out-of-band reply possible */
k
in LimeWire:
// these specs may seem backwards, but they are not -
// ByteOrder.short2leb puts the low-order byte first, so over the
// network 0x0080 would look like 0x8000
public static final int SPECIAL_MINSPEED_MASK = 0x0080;
public static final int SPECIAL_FIREWALL_MASK = 0x0040;
public static final int SPECIAL_XML_MASK = 0x0020;
public static final int SPECIAL_OUTOFBAND_MASK = 0x0004;
...
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ByteOrder.short2leb((short)MIN_SPEED,baos); // write minspeed
baos.write(QUERY.getBytes()); // write query
baos.write(0); // null
...
public static void short2leb(short x, OutputStream os) throws IOException {
os.write((byte)(x & (short)0x00FF));
os.write((byte)((short)(x>>8) & (short)0x00FF));
}
public final int MIN_SPEED;
...
try {
ByteArrayInputStream bais = new ByteArrayInputStream(this.PAYLOAD);
short sp = ByteOrder.leb2short(bais);
tempMinSpeed = ByteOrder.ubytes2int(sp);
...
MIN_SPEED = tempMinSpeed;
...
public static short leb2short(InputStream is) throws IOException {
int x0=is.read() & 0x000000FF;
int x1=is.read() <<8;
return (short)(x1|x0);
}
At first glance, I thought this was ok, because I thought gtk-gnutella
was using the field in big-endian ordering. But it appears to use it in
little endian ordering:
speed = QUERY_SPEED_MARK; /* Indicates: special speed field */
if (is_firewalled)
speed |= QUERY_SPEED_FIREWALLED;
speed |= QUERY_SPEED_GGEP_H; /* GTKG understands GGEP "H" in hits */
speed |= QUERY_SPEED_NO_XML; /* GTKG does not parse XML in hits */
WRITE_GUINT16_LE(speed, m->search.speed);
So the field is written here in little-endian ordering, just as in
LimeWire. Since the constants used between them are different, LimeWire
and gtk-gnutella are using different bits for the MinSpeed field.
In addition to the byte-ordering, there is a difference in the
interpretation of the XML flag: LimeWire uses the XML flag to indicate
that XML data should be sent, but GTKG uses it to indicate the inverse.
The documentation for this field is arranged in big-endian ordering.
This is counter-intuitive because you would think the QUERY_SPEED_MARK
would be the high-bit of the most significant byte of the old MinSpeed
bytes (which were in little-endian order, right?). But LimeWire didn't
do this -- bit 15 is actually bit 7 (little-endian), and the mark is
instead on the least significant byte. This is probably a mistake but
it's most likely too late to change now.
The documentation for the MinSpeed bytes should probably make a note of
this. I had a feeling something like this would happen, because of the
author of the MinSpeed spec describing the bytes in big-endian order.
It was an unfortunate mistake to do that.
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Gtk-gnutella-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/gtk-gnutella-devel