Author: toad
Date: 2006-12-12 01:57:41 +0000 (Tue, 12 Dec 2006)
New Revision: 11349
Modified:
trunk/freenet/src/freenet/io/comm/DummyPeerContext.java
trunk/freenet/src/freenet/io/comm/FreenetInetAddress.java
trunk/freenet/src/freenet/io/comm/Message.java
trunk/freenet/src/freenet/io/comm/Peer.java
trunk/freenet/src/freenet/io/comm/PeerContext.java
trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
trunk/freenet/src/freenet/node/FNPPacketMangler.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/PeerNode.java
trunk/freenet/src/freenet/support/Serializer.java
Log:
Fix #620.
Modified: trunk/freenet/src/freenet/io/comm/DummyPeerContext.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/DummyPeerContext.java 2006-12-12
00:25:21 UTC (rev 11348)
+++ trunk/freenet/src/freenet/io/comm/DummyPeerContext.java 2006-12-12
01:57:41 UTC (rev 11349)
@@ -36,4 +36,8 @@
public void reportOutgoingBytes(int length) {
// Ignore
}
+
+ public int getVersionNumber() {
+ return -1;
+ }
}
Modified: trunk/freenet/src/freenet/io/comm/FreenetInetAddress.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/FreenetInetAddress.java 2006-12-12
00:25:21 UTC (rev 11348)
+++ trunk/freenet/src/freenet/io/comm/FreenetInetAddress.java 2006-12-12
01:57:41 UTC (rev 11349)
@@ -31,8 +31,24 @@
* Create from serialized form on a DataInputStream.
*/
public FreenetInetAddress(DataInputStream dis) throws IOException {
- byte[] ba = new byte[4];
- dis.readFully(ba);
+ int firstByte = dis.readUnsignedByte();
+ byte[] ba;
+ if(firstByte == 255) {
+ if(Logger.shouldLog(Logger.MINOR, this))
Logger.minor(this, "New format IPv6 address");
+ // New format IPv6 address
+ ba = new byte[16];
+ dis.readFully(ba);
+ } else if(firstByte == 0) {
+ if(Logger.shouldLog(Logger.MINOR, this))
Logger.minor(this, "New format IPv4 address");
+ // New format IPv4 address
+ ba = new byte[4];
+ dis.readFully(ba);
+ } else {
+ // Old format IPv4 address
+ ba = new byte[4];
+ ba[0] = (byte)firstByte;
+ dis.readFully(ba, 1, 3);
+ }
_address = InetAddress.getByAddress(ba);
String name = null;
String s = dis.readUTF();
@@ -233,12 +249,19 @@
}
}
- public void writeToDataOutputStream(DataOutputStream dos) throws
IOException {
+ public void writeToDataOutputStream(DataOutputStream dos, boolean
oldForm) throws IOException {
InetAddress addr = this.getAddress();
if (addr == null) throw new UnknownHostException();
byte[] data = addr.getAddress();
- if(data.length > 4)
- throw new IllegalArgumentException("IPv6 not supported
at present");
+ if(oldForm) {
+ if(data.length != 4)
+ throw new IllegalArgumentException("IPv6 not
supported at present");
+ } else {
+ if(data.length == 4)
+ dos.write(0);
+ else
+ dos.write(255);
+ }
dos.write(data);
if(hostname != null)
dos.writeUTF(hostname);
Modified: trunk/freenet/src/freenet/io/comm/Message.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/Message.java 2006-12-12 00:25:21 UTC
(rev 11348)
+++ trunk/freenet/src/freenet/io/comm/Message.java 2006-12-12 01:57:41 UTC
(rev 11349)
@@ -41,7 +41,7 @@
public final long localInstantiationTime;
final int _receivedByteCount;
- public static Message decodeFromPacket(byte[] buf, int offset, int
length, PeerContext peer, int overhead) {
+ public static Message decodeMessageFromPacket(byte[] buf, int offset,
int length, PeerContext peer, int overhead) {
DataInputStream dis
= new DataInputStream(new ByteArrayInputStream(buf,
offset, length));
@@ -168,7 +168,7 @@
dos.writeInt(_spec.getName().hashCode());
for (Iterator i = _spec.getOrderedFields().iterator();
i.hasNext();) {
String name = (String) i.next();
-
Serializer.writeToDataOutputStream(_payload.get(name), dos);
+
Serializer.writeToDataOutputStream(_payload.get(name), dos, destination);
}
dos.flush();
} catch (IOException e) {
Modified: trunk/freenet/src/freenet/io/comm/Peer.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/Peer.java 2006-12-12 00:25:21 UTC (rev
11348)
+++ trunk/freenet/src/freenet/io/comm/Peer.java 2006-12-12 01:57:41 UTC (rev
11349)
@@ -19,10 +19,12 @@
package freenet.io.comm;
-import java.io.*;
-import java.net.*;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
-import freenet.io.WritableToDataOutputStream;
import freenet.support.transport.ip.IPUtil;
/**
@@ -31,7 +33,7 @@
* To change the template for this generated type comment go to Window -
Preferences - Java - Code Generation - Code and
* Comments
*/
-public class Peer implements WritableToDataOutputStream {
+public class Peer {
public static class LocalAddressException extends Exception {
private static final long serialVersionUID = -1;
@@ -180,8 +182,8 @@
return addr.toString() + ':' + _port;
}
- public void writeToDataOutputStream(DataOutputStream dos) throws
IOException {
- addr.writeToDataOutputStream(dos);
+ public void writeToDataOutputStream(DataOutputStream dos, boolean
oldForm) throws IOException {
+ addr.writeToDataOutputStream(dos, oldForm);
dos.writeInt(_port);
}
Modified: trunk/freenet/src/freenet/io/comm/PeerContext.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/PeerContext.java 2006-12-12 00:25:21 UTC
(rev 11348)
+++ trunk/freenet/src/freenet/io/comm/PeerContext.java 2006-12-12 01:57:41 UTC
(rev 11349)
@@ -21,4 +21,7 @@
/** Is the peer connected? are we able to route requests to it? */
boolean isRoutable();
+
+ /** Peer version, if this is supported, else -1 */
+ int getVersionNumber();
}
Modified: trunk/freenet/src/freenet/io/comm/UdpSocketManager.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/UdpSocketManager.java 2006-12-12
00:25:21 UTC (rev 11348)
+++ trunk/freenet/src/freenet/io/comm/UdpSocketManager.java 2006-12-12
01:57:41 UTC (rev 11349)
@@ -246,7 +246,7 @@
}
} else {
// Create a bogus context since no filter
- Message m = decodePacket(data, offset, length,
+ Message m = decodeSingleMessage(data, offset,
length,
new DummyPeerContext(peer), 0);
if (m != null) {
checkFilters(m);
@@ -263,9 +263,9 @@
* @param length
* @param peer
*/
- public Message decodePacket(byte[] data, int offset, int length,
PeerContext peer, int overhead) {
+ public Message decodeSingleMessage(byte[] data, int offset, int length,
PeerContext peer, int overhead) {
try {
- return Message.decodeFromPacket(data, offset, length, peer,
overhead);
+ return Message.decodeMessageFromPacket(data, offset, length, peer,
overhead);
} catch (Throwable t) {
Logger.error(this, "Could not decode packet: "+t, t);
return null;
Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java 2006-12-12
00:25:21 UTC (rev 11348)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java 2006-12-12
01:57:41 UTC (rev 11349)
@@ -888,7 +888,7 @@
return;
}
if(logMINOR) Logger.minor(this, "Message "+i+" length "+length+",
hash code: "+Fields.hashCode(decrypted, ptr, length));
- Message m = usm.decodePacket(decrypted, ptr, length, tracker.pn, 1
+ (overhead / messages));
+ Message m = usm.decodeSingleMessage(decrypted, ptr, length,
tracker.pn, 1 + (overhead / messages));
ptr+=length;
if(m != null) {
//Logger.minor(this, "Dispatching packet: "+m);
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-12-12 00:25:21 UTC (rev
11348)
+++ trunk/freenet/src/freenet/node/Node.java 2006-12-12 01:57:41 UTC (rev
11349)
@@ -1650,7 +1650,7 @@
}
fs.put("identity", Base64.encode(myIdentity)); // FIXME
!forSetup after 11104 is mandatory
fs.put("location",
Double.toString(lm.getLocation().getValue())); // FIXME maybe !forSetup; see
#943
- fs.put("version", Version.getVersionString()); // Keep, vital
that peer know our version
+ fs.put("version", Version.getVersionString()); // Keep, vital
that peer know our version. For example, some messages may be interpreted
differently depending on version.
fs.put("testnet", Boolean.toString(testnetEnabled)); // Vital
that peer know this!
fs.put("lastGoodVersion", Version.getLastGoodVersionString());
// Also vital
if(testnetEnabled)
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2006-12-12 00:25:21 UTC
(rev 11348)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2006-12-12 01:57:41 UTC
(rev 11349)
@@ -3050,4 +3050,8 @@
}
return ((double) hadRoutableConnectionCount) /
routableConnectionCheckCount;
}
+
+ public int getVersionNumber() {
+ return Version.getArbitraryBuildNumber(getVersion());
+ }
}
Modified: trunk/freenet/src/freenet/support/Serializer.java
===================================================================
--- trunk/freenet/src/freenet/support/Serializer.java 2006-12-12 00:25:21 UTC
(rev 11348)
+++ trunk/freenet/src/freenet/support/Serializer.java 2006-12-12 01:57:41 UTC
(rev 11349)
@@ -28,6 +28,7 @@
import freenet.io.WritableToDataOutputStream;
import freenet.io.comm.Peer;
+import freenet.io.comm.PeerContext;
import freenet.keys.Key;
import freenet.keys.NodeCHK;
import freenet.keys.NodeSSK;
@@ -94,7 +95,18 @@
}
}
- public static void writeToDataOutputStream(Object object,
DataOutputStream dos) throws IOException {
+ private static boolean needOldPeerFormat(PeerContext ctx) {
+ int ver = ctx.getVersionNumber();
+ if(ver >= 1008) {
+ if(Logger.shouldLog(Logger.MINOR, Serializer.class))
Logger.minor(Serializer.class, "New format peer: "+ver+" : "+ctx);
+ } else {
+ if(Logger.shouldLog(Logger.MINOR, Serializer.class))
Logger.minor(Serializer.class, "Old format peer: "+ver+" : "+ctx);
+ }
+
+ return ver < 1008;
+ }
+
+ public static void writeToDataOutputStream(Object object,
DataOutputStream dos, PeerContext ctx) throws IOException {
Class type = object.getClass();
if (type.equals(Boolean.class)) {
dos.write(((Boolean) object).booleanValue() ? 1 : 0);
@@ -119,9 +131,11 @@
dos.writeInt(ll.size());
synchronized (ll) {
for (Iterator i = ll.iterator(); i.hasNext();) {
- writeToDataOutputStream(i.next(), dos);
+ writeToDataOutputStream(i.next(), dos,
ctx);
}
}
+ } else if (type.equals(Peer.class)) {
+ ((Peer)object).writeToDataOutputStream(dos,
needOldPeerFormat(ctx));
} else if
(WritableToDataOutputStream.class.isAssignableFrom(type)) {
WritableToDataOutputStream b =
(WritableToDataOutputStream) object;
b.writeToDataOutputStream(dos);