Author: zothar
Date: 2006-05-11 04:24:24 +0000 (Thu, 11 May 2006)
New Revision: 8652
Modified:
trunk/freenet/src/freenet/io/NetworkInterface.java
trunk/freenet/src/freenet/io/comm/Peer.java
trunk/freenet/src/freenet/node/FNPPacketMangler.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/PeerNode.java
Log:
When no IP addresses are available for handshake, reset the handshake timer.
Only do DNS lookups during handshake and store the result. Explicitly set
Java's negative DNS cache TTL. Factored out the repeated use of some address
lookup methods within a few lines of each other. Fixed an NPE caused by trying
to call the canGetCipher() method on a null DHContext. Added another
short-circuit to getHandshakeIPs().
Modified: trunk/freenet/src/freenet/io/NetworkInterface.java
===================================================================
--- trunk/freenet/src/freenet/io/NetworkInterface.java 2006-05-11 01:07:59 UTC
(rev 8651)
+++ trunk/freenet/src/freenet/io/NetworkInterface.java 2006-05-11 04:24:24 UTC
(rev 8652)
@@ -257,6 +257,7 @@
try {
Socket clientSocket =
serverSocket.accept();
InetAddress clientAddress =
clientSocket.getInetAddress();
+ Logger.minor(Acceptor.class,
"Connection from " + clientAddress);
String clientHostName =
clientAddress.getHostName();
/* check if the ip address is allowed */
Modified: trunk/freenet/src/freenet/io/comm/Peer.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/Peer.java 2006-05-11 01:07:59 UTC (rev
8651)
+++ trunk/freenet/src/freenet/io/comm/Peer.java 2006-05-11 04:24:24 UTC (rev
8652)
@@ -39,7 +39,7 @@
// hostname - only set if we were created with a hostname
// and not an address
private final String hostname;
- private final InetAddress _address;
+ private InetAddress _address;
private final int _port;
// Create a null peer
@@ -135,22 +135,49 @@
if (_address != null) {
return _address;
} else {
- Logger.minor(this, "Looking up '"+hostname+"' in DNS");
- /*
- * Peers are constructed from an address once
- * a handshake has been completed, so this
- * lookup will only be performed during a
- * handshake - it doesn't mean we perform
- * a DNS lookup with every packet we send.
- */
- try {
- return InetAddress.getByName(hostname);
- } catch (UnknownHostException e) {
- return null;
- }
+ InetAddress addr = getHandshakeAddress();
+ if( addr != null ) {
+ this._address = addr;
+ }
+ return addr;
}
}
+ public InetAddress getHandshakeAddress() {
+ // Since we're handshaking, hostname-to-IP may have changed
+ if (_address != null && hostname == null) {
+ return _address;
+ } else {
+ Logger.minor(this, "Looking up '"+hostname+"' in DNS");
+ /*
+ * Peers are constructed from an address once a
+ * handshake has been completed, so this lookup
+ * will only be performed during a handshake
+ * (this method should normally only be called
+ * from PeerNode.getHandshakeIPs() and once
+ * each connection from this.getAddress()
+ * otherwise) - it doesn't mean we perform a
+ * DNS lookup with every packet we send.
+ */
+ try {
+ InetAddress addr = InetAddress.getByName(hostname);
+ //Logger.normal(this, "Look up got '"+addr+"'");
+ if( addr != null ) {
+ /*
+ * cache the answer since getHandshakeAddress()
+ * doesn't use the cached value, thus
+ * getHandshakeIPs() should always get the
+ * latest value from DNS (minus Java's caching)
+ */
+ this._address = addr;
+ }
+ return addr;
+ } catch (UnknownHostException e) {
+ return null;
+ }
+ }
+ }
+
public int hashCode() {
if (_address != null) {
return _address.hashCode() + _port;
Modified: trunk/freenet/src/freenet/node/FNPPacketMangler.java
===================================================================
--- trunk/freenet/src/freenet/node/FNPPacketMangler.java 2006-05-11
01:07:59 UTC (rev 8651)
+++ trunk/freenet/src/freenet/node/FNPPacketMangler.java 2006-05-11
04:24:24 UTC (rev 8652)
@@ -381,7 +381,7 @@
*/
private DiffieHellmanContext processDHTwoOrThree(int i, byte[] payload,
PeerNode pn, Peer replyTo, boolean sendCompletion) {
DiffieHellmanContext ctx = pn.getDHContext();
- if(!ctx.canGetCipher()) {
+ if(ctx == null || !ctx.canGetCipher()) {
if(shouldLogErrorInHandshake()) {
Logger.error(this, "Cannot get cipher");
}
@@ -1286,20 +1286,28 @@
public void sendHandshake(PeerNode pn) {
Logger.minor(this, "Possibly sending handshake to "+pn);
DiffieHellmanContext ctx;
+ Peer[] handshakeIPs;
synchronized(pn) {
- if((!pn.shouldSendHandshake()) || pn.getHandshakeIPs().length ==
0) {
+ if(!pn.shouldSendHandshake()) return;
+ handshakeIPs = pn.getHandshakeIPs();
+ if(handshakeIPs.length == 0) {
+ pn.couldNotSendHandshake();
return;
} else {
ctx = DiffieHellman.generateContext();
pn.setDHContext(ctx);
}
}
-
- for(int i=0;i<pn.getHandshakeIPs().length;i++){
- if( pn.getHandshakeIPs()[i].getAddress() == null ) continue;
- sendFirstHalfDHPacket(0, ctx.getOurExponential(), pn,
pn.getHandshakeIPs()[i]);
+ int sentCount = 0;
+ for(int i=0;i<handshakeIPs.length;i++){
+ if( handshakeIPs[i].getAddress() == null ) continue;
+ sendFirstHalfDHPacket(0, ctx.getOurExponential(), pn,
handshakeIPs[i]);
pn.sentHandshake();
+ sentCount += 1;
}
+ if(sentCount==0) {
+ pn.couldNotSendHandshake();
+ }
}
public boolean isDisconnected(PeerContext context) {
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-05-11 01:07:59 UTC (rev
8651)
+++ trunk/freenet/src/freenet/node/Node.java 2006-05-11 04:24:24 UTC (rev
8652)
@@ -497,6 +497,9 @@
// use dyndns hostnames
java.security.Security.setProperty("networkaddress.cache.ttl" , "300");
+ // set Java's negative DNS cache to 1 minute rather than the default 10
seconds
+ java.security.Security.setProperty("networkaddress.cache.negative.ttl"
, "60");
+
FilePersistentConfig cfg = new FilePersistentConfig(configFilename);
// First, set up logging. It is global, and may be shared between
several nodes.
@@ -1593,7 +1596,7 @@
Peer p = peerList[i].getRemoteDetectedPeer();
if(p == null || p.isNull()) continue;
InetAddress ip = p.getAddress();
- if(!IPUtil.checkAddress(p.getAddress()))
continue;
+ if(!IPUtil.checkAddress(ip)) continue;
if(countsByPeer.containsKey(ip)) {
Integer count = (Integer)
countsByPeer.get(ip);
Integer newCount = new
Integer(count.intValue()+1);
Modified: trunk/freenet/src/freenet/node/PeerNode.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerNode.java 2006-05-11 01:07:59 UTC
(rev 8651)
+++ trunk/freenet/src/freenet/node/PeerNode.java 2006-05-11 04:24:24 UTC
(rev 8652)
@@ -358,8 +358,12 @@
Peer[] p=null;
if(detectedPeer == null && nominalPeer.size() == 0) return new Peer[0];
+
+ InetAddress peerIP = detectedPeer.getHandshakeAddress();
+
+ if(peerIP == null && nominalPeer.size() == 0) return new Peer[0];
- if( ! nominalPeer.contains(detectedPeer)){
+ if( peerIP != null && ! nominalPeer.contains(detectedPeer)){
p= new Peer[1+nominalPeer.size()];
p[0]=detectedPeer;
for(int i=1;i<nominalPeer.size()+1;i++)
@@ -371,7 +375,6 @@
InetAddress localhost = node.localhostAddress;
InetAddress nodeIP = node.getPrimaryIPAddress();
if(nodeIP != null && nodeIP.equals(localhost)) return p;
- InetAddress peerIP = detectedPeer.getAddress();
if(peerIP != null && peerIP.equals(localhost)) return p;
if(nodeIP != null && nodeIP.equals(peerIP)) {
Peer[] newPeers = new Peer[p.length+1];
@@ -530,6 +533,7 @@
* sent.
*/
public synchronized void sentHandshake() {
+ Logger.debug(this, "sentHandshake(): "+this);
long now = System.currentTimeMillis();
if(invalidVersion() && !firstHandshake) {
sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_VERSION_PROBES
@@ -540,6 +544,24 @@
}
firstHandshake = false;
}
+
+ /**
+ * Call this method when a handshake request could not be sent (i.e. no IP
address available)
+ * sent.
+ */
+ public synchronized void couldNotSendHandshake() {
+ Logger.minor(this, "couldNotSendHandshake(): "+this);
+ long now = System.currentTimeMillis();
+ if(invalidVersion() && !firstHandshake) {
+ sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_VERSION_PROBES
+ +
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_PROBES)
+ +
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_VERSION_PROBES);
+ } else {
+ sendHandshakeTime = now + Node.MIN_TIME_BETWEEN_HANDSHAKE_SENDS
+ +
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_HANDSHAKE_SENDS)
+ +
node.random.nextInt(Node.RANDOMIZED_TIME_BETWEEN_HANDSHAKE_SENDS);
+ }
+ }
/**
* @return The maximum time between received packets.