2004-11-14 jrandom

* Fix a long standing leak in I2PTunnel (hanging on to i2psocket objects)
    * Fix a leak injected into the SimpleTimer
    * Fix a race condition in the tunnel message handling
This commit is contained in:
jrandom
2004-11-15 14:35:16 +00:00
committed by zzz
parent ad7dc66f90
commit 3780d290fa
10 changed files with 62 additions and 19 deletions

View File

@ -56,14 +56,20 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
public long getReadTimeout() { return readTimeout; }
protected void clientConnectionRun(Socket s) {
I2PSocket i2ps = null;
try {
I2PSocket i2ps = createI2PSocket(dest);
i2ps = createI2PSocket(dest);
i2ps.setReadTimeout(readTimeout);
new I2PTunnelRunner(s, i2ps, sockLock, null);
new I2PTunnelRunner(s, i2ps, sockLock, null, mySockets);
} catch (Exception ex) {
_log.info("Error connecting", ex);
l.log(ex.getMessage());
closeSocket(s);
if (i2ps != null) {
synchronized (sockLock) {
mySockets.remove(sockLock);
}
}
}
}
}

View File

@ -39,7 +39,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
protected long _clientId;
protected Object sockLock = new Object(); // Guards sockMgr and mySockets
private I2PSocketManager sockMgr;
private List mySockets = new ArrayList();
protected List mySockets = new ArrayList();
protected Destination dest = null;
private int localPort;
@ -263,6 +263,9 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
} catch (IOException ex) {
_log.error("Error listening for connections", ex);
notifyEvent("openBaseClientResult", "error");
synchronized (sockLock) {
mySockets.clear();
}
}
}

View File

@ -356,7 +356,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
String remoteID;
I2PSocket i2ps = createI2PSocket(dest);
byte[] data = newRequest.toString().getBytes("ISO-8859-1");
I2PTunnelRunner runner = new I2PTunnelRunner(s, i2ps, sockLock, data);
I2PTunnelRunner runner = new I2PTunnelRunner(s, i2ps, sockLock, data, mySockets);
timeoutThread = new InactivityTimeoutThread(runner, out, targetRequest, usingWWWProxy, currentProxy, s, requestId);
timeoutThread.start();
} catch (SocketException ex) {

View File

@ -11,6 +11,7 @@ import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.List;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.data.ByteArray;
@ -44,10 +45,12 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
private long lastActivityOn;
/** when the runner started up */
private long startedOn;
private List sockList;
private volatile long __forwarderId;
public I2PTunnelRunner(Socket s, I2PSocket i2ps, Object slock, byte[] initialData) {
public I2PTunnelRunner(Socket s, I2PSocket i2ps, Object slock, byte[] initialData, List sockList) {
this.sockList = sockList;
this.s = s;
this.i2ps = i2ps;
this.slock = slock;
@ -115,9 +118,7 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
}
// now one connection is dead - kill the other as well.
s.close();
s = null;
i2ps.close();
i2ps = null;
t1.join();
t2.join();
} catch (InterruptedException ex) {
@ -130,16 +131,20 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
if (_log.shouldLog(Log.ERROR))
_log.error("Internal error", e);
} finally {
removeRef();
try {
if (s != null) s.close();
if (i2ps != null) i2ps.close();
if (i2ps != null) {
i2ps.close();
i2ps.setSocketErrorListener(null);
}
} catch (IOException ex) {
if (_log.shouldLog(Log.ERROR))
_log.error("Could not close socket", ex);
}
}
}
public void errorOccurred() {
synchronized (finishLock) {
finished = true;
@ -147,6 +152,16 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
}
}
private void removeRef() {
if (sockList != null) {
synchronized (slock) {
boolean removed = sockList.remove(i2ps);
System.out.println("Removal of i2psocket " + i2ps + " successful? "
+ removed + " remaining: " + sockList.size());
}
}
}
private class StreamForwarder extends I2PThread {
InputStream in;

View File

@ -179,7 +179,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
_handleSocket.setReadTimeout(readTimeout);
Socket s = new Socket(remoteHost, remotePort);
afterSocket = I2PAppContext.getGlobalContext().clock().now();
new I2PTunnelRunner(s, _handleSocket, slock, null);
new I2PTunnelRunner(s, _handleSocket, slock, null, null);
} catch (SocketException ex) {
try {
_handleSocket.close();

View File

@ -47,7 +47,7 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase {
SOCKSServer serv = SOCKSServerFactory.createSOCKSServer(s);
Socket clientSock = serv.getClientSocket();
I2PSocket destSock = serv.getDestinationI2PSocket();
new I2PTunnelRunner(clientSock, destSock, sockLock, null);
new I2PTunnelRunner(clientSock, destSock, sockLock, null, mySockets);
} catch (SOCKSException e) {
_log.error("Error from SOCKS connection: " + e.getMessage());
closeSocket(s);