I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 031338d8 authored by human's avatar human Committed by zzz
Browse files

First step for the "connection refused" concept: incoming connections

won't be accepted until the server app actually requires an I2PServerSocket
from the I2PSocketManager.
It allows both to add a little bit of functionality, and to fix a nasty bug: it
was possible to hang an app that connects through the I2PSocketManager but
actually doesn't accept() connections (if 2 connection requests were sent
to the app, the I2PSocketManager got stuck waiting forever on
I2PServerSocketImpl.getNewSocket()).
parent 2a619f3f
No related branches found
No related tags found
No related merge requests found
...@@ -63,7 +63,7 @@ class I2PSocketImpl implements I2PSocket { ...@@ -63,7 +63,7 @@ class I2PSocketImpl implements I2PSocket {
public String getRemoteID(boolean wait, long maxWait) throws InterruptedIOException { public String getRemoteID(boolean wait, long maxWait) throws InterruptedIOException {
long dieAfter = System.currentTimeMillis() + maxWait; long dieAfter = System.currentTimeMillis() + maxWait;
synchronized (remoteIDWaiter) { synchronized (remoteIDWaiter) {
while (wait && remoteID == null) { if (wait) {
try { try {
if (maxWait > 0) if (maxWait > 0)
remoteIDWaiter.wait(maxWait); remoteIDWaiter.wait(maxWait);
...@@ -74,8 +74,7 @@ class I2PSocketImpl implements I2PSocket { ...@@ -74,8 +74,7 @@ class I2PSocketImpl implements I2PSocket {
if ((maxWait > 0) && (System.currentTimeMillis() > dieAfter)) if ((maxWait > 0) && (System.currentTimeMillis() > dieAfter))
throw new InterruptedIOException("Timed out waiting for remote ID"); throw new InterruptedIOException("Timed out waiting for remote ID");
}
if (wait) {
_log.debug("TIMING: RemoteID set to " + I2PSocketManager.getReadableForm(remoteID) + " for " _log.debug("TIMING: RemoteID set to " + I2PSocketManager.getReadableForm(remoteID) + " for "
+ this.hashCode()); + this.hashCode());
} }
...@@ -333,4 +332,4 @@ class I2PSocketImpl implements I2PSocket { ...@@ -333,4 +332,4 @@ class I2PSocketImpl implements I2PSocket {
return sent; return sent;
} }
} }
} }
\ No newline at end of file
...@@ -31,7 +31,7 @@ import net.i2p.util.Log; ...@@ -31,7 +31,7 @@ import net.i2p.util.Log;
public class I2PSocketManager implements I2PSessionListener { public class I2PSocketManager implements I2PSessionListener {
private final static Log _log = new Log(I2PSocketManager.class); private final static Log _log = new Log(I2PSocketManager.class);
private I2PSession _session; private I2PSession _session;
private I2PServerSocketImpl _serverSocket; private I2PServerSocketImpl _serverSocket = null;
private Object lock = new Object(); // for locking socket lists private Object lock = new Object(); // for locking socket lists
private HashMap _outSockets; private HashMap _outSockets;
private HashMap _inSockets; private HashMap _inSockets;
...@@ -41,7 +41,6 @@ public class I2PSocketManager implements I2PSessionListener { ...@@ -41,7 +41,6 @@ public class I2PSocketManager implements I2PSessionListener {
public I2PSocketManager() { public I2PSocketManager() {
_session = null; _session = null;
_serverSocket = new I2PServerSocketImpl(this);
_inSockets = new HashMap(16); _inSockets = new HashMap(16);
_outSockets = new HashMap(16); _outSockets = new HashMap(16);
} }
...@@ -106,14 +105,19 @@ public class I2PSocketManager implements I2PSessionListener { ...@@ -106,14 +105,19 @@ public class I2PSocketManager implements I2PSessionListener {
_log.debug("*Disconnect outgoing!"); _log.debug("*Disconnect outgoing!");
try { try {
s = (I2PSocketImpl) _outSockets.get(id); s = (I2PSocketImpl) _outSockets.get(id);
if (payload.length == 0 && s != null) { if (s != null) {
if (payload.length > 0) {
_log.debug("Disconnect packet had "
+ payload.length + " bytes");
}
if (s.getRemoteID(false) == null) {
s.setRemoteID(null); // Just to wake up socket
return;
}
s.internalClose(); s.internalClose();
_outSockets.remove(id); _outSockets.remove(id);
return;
} else {
if (payload.length > 0) _log.warn("Disconnect packet had " + payload.length + " bytes");
return;
} }
return;
} catch (Exception t) { } catch (Exception t) {
_log.error("Ignoring error on disconnect", t); _log.error("Ignoring error on disconnect", t);
} }
...@@ -136,6 +140,20 @@ public class I2PSocketManager implements I2PSessionListener { ...@@ -136,6 +140,20 @@ public class I2PSocketManager implements I2PSessionListener {
Destination d = new Destination(); Destination d = new Destination();
d.readBytes(new ByteArrayInputStream(payload)); d.readBytes(new ByteArrayInputStream(payload));
if (_serverSocket == null) {
// The app did not instantiate an I2PServerSocket
byte[] packet = makePacket((byte) 0x52, id, newLocalID.getBytes("ISO-8859-1"));
boolean replySentOk = false;
synchronized (_session) {
replySentOk = _session.sendMessage(d, packet);
}
if (!replySentOk) {
_log.error("Error sending close to " + d.calculateHash().toBase64()
+ " in response to a new con message", new Exception("Failed creation"));
}
return;
}
s = new I2PSocketImpl(d, this, false, newLocalID); s = new I2PSocketImpl(d, this, false, newLocalID);
s.setRemoteID(id); s.setRemoteID(id);
if (_serverSocket.getNewSocket(s)) { if (_serverSocket.getNewSocket(s)) {
...@@ -227,6 +245,9 @@ public class I2PSocketManager implements I2PSessionListener { ...@@ -227,6 +245,9 @@ public class I2PSocketManager implements I2PSessionListener {
} }
public I2PServerSocket getServerSocket() { public I2PServerSocket getServerSocket() {
if (_serverSocket == null) {
_serverSocket = new I2PServerSocketImpl(this);
}
return _serverSocket; return _serverSocket;
} }
...@@ -262,6 +283,7 @@ public class I2PSocketManager implements I2PSessionListener { ...@@ -262,6 +283,7 @@ public class I2PSocketManager implements I2PSessionListener {
throw new I2PException("Unable to reach peer"); throw new I2PException("Unable to reach peer");
} }
remoteID = s.getRemoteID(true, options.getConnectTimeout()); remoteID = s.getRemoteID(true, options.getConnectTimeout());
if (remoteID == null) { throw new I2PException("Peer refused connection"); }
if ("".equals(remoteID)) { throw new I2PException("Unable to reach peer"); } if ("".equals(remoteID)) { throw new I2PException("Unable to reach peer"); }
_log.debug("TIMING: s given out for remoteID " + getReadableForm(remoteID)); _log.debug("TIMING: s given out for remoteID " + getReadableForm(remoteID));
return s; return s;
...@@ -326,6 +348,7 @@ public class I2PSocketManager implements I2PSessionListener { ...@@ -326,6 +348,7 @@ public class I2PSocketManager implements I2PSessionListener {
public static String getReadableForm(String id) { public static String getReadableForm(String id) {
try { try {
if (id == null) return "(null)";
if (id.length() != 3) return "Bogus"; if (id.length() != 3) return "Bogus";
return Base64.encode(id.getBytes("ISO-8859-1")); return Base64.encode(id.getBytes("ISO-8859-1"));
} catch (UnsupportedEncodingException ex) { } catch (UnsupportedEncodingException ex) {
...@@ -375,4 +398,4 @@ public class I2PSocketManager implements I2PSessionListener { ...@@ -375,4 +398,4 @@ public class I2PSocketManager implements I2PSessionListener {
return new byte[0]; return new byte[0];
} }
} }
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment