You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2014/09/11 23:21:24 UTC
git commit: [SSHD-69] Unix ssh agent leaks /tmp/mina*apr sockets and
threads
Repository: mina-sshd
Updated Branches:
refs/heads/master 44597914e -> 635de65ff
[SSHD-69] Unix ssh agent leaks /tmp/mina*apr sockets and threads
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/635de65f
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/635de65f
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/635de65f
Branch: refs/heads/master
Commit: 635de65ffcb278e76adddd1be86c6df726537d9e
Parents: 4459791
Author: Guillaume Nodet <gn...@apache.org>
Authored: Thu Sep 11 23:21:14 2014 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Thu Sep 11 23:21:14 2014 +0200
----------------------------------------------------------------------
.../sshd/agent/unix/AgentServerProxy.java | 139 ++++++++++++++-----
1 file changed, 108 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/635de65f/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
index f358740..69322f6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
@@ -18,13 +18,14 @@
*/
package org.apache.sshd.agent.unix;
+import java.io.File;
import java.io.IOException;
import org.apache.sshd.agent.SshAgentServer;
import org.apache.sshd.client.future.OpenFuture;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.session.ConnectionService;
-import org.apache.sshd.server.session.ServerSession;
+import org.apache.sshd.common.util.OsUtils;
import org.apache.tomcat.jni.Local;
import org.apache.tomcat.jni.Pool;
import org.apache.tomcat.jni.Socket;
@@ -40,19 +41,27 @@ public class AgentServerProxy implements SshAgentServer {
private static final Logger LOG = LoggerFactory.getLogger(AgentServerProxy.class);
private final ConnectionService service;
- private String authSocket;
- private long pool;
- private long handle;
- private Thread thread;
- private boolean closed;
+ private final String authSocket;
+ private final long pool;
+ private final long handle;
+ private final Thread thread;
+ private volatile boolean closed;
+ private volatile boolean innerFinished;
+
+ //used to wake the Local.listen() JNI call
+ private static final byte[] END_OF_STREAM_MESSAGE = new byte[] { "END_OF_STREAM".getBytes()[0] };
public AgentServerProxy(ConnectionService service) throws IOException {
this.service = service;
try {
String authSocket = AprLibrary.createLocalSocketAddress();
+
pool = Pool.create(AprLibrary.getInstance().getRootPool());
handle = Local.create(authSocket, pool);
+ this.authSocket = authSocket;
+
int result = Local.bind(handle, 0);
+
if (result != Status.APR_SUCCESS) {
throwException(result);
}
@@ -61,34 +70,39 @@ public class AgentServerProxy implements SshAgentServer {
if (result != Status.APR_SUCCESS) {
throwException(result);
}
- thread = new Thread() {
+ thread = new Thread("sshd-AgentServerProxy-PIPE-" + authSocket) {
+ @Override
public void run() {
- while (!closed) {
- try {
- long clientSock = Local.accept(handle);
- if (closed) {
- break;
- }
- Socket.timeoutSet(clientSock, 10000000);
- AgentForwardedChannel channel = new AgentForwardedChannel(clientSock);
- AgentServerProxy.this.service.registerChannel(channel);
- OpenFuture future = channel.open().await();
- Throwable t = future.getException();
- if (t instanceof Exception) {
- throw (Exception) t;
- } else if (t != null) {
- throw new Exception(t);
- }
- } catch (Exception e) {
- if (!closed) {
- LOG.info("Exchange caught in authentication forwarding", e);
+ try {
+ while (!closed) {
+ try {
+ long clientSock = Local.accept(handle);
+ if (closed) {
+ break;
+ }
+ Socket.timeoutSet(clientSock, 10000000);
+ AgentForwardedChannel channel = new AgentForwardedChannel(clientSock);
+ AgentServerProxy.this.service.registerChannel(channel);
+ OpenFuture future = channel.open().await();
+ Throwable t = future.getException();
+ if (t instanceof Exception) {
+ throw (Exception) t;
+ } else if (t != null) {
+ throw new Exception(t);
+ }
+ } catch (Exception e) {
+ if (!closed) {
+ LOG.info("Exchange caught in authentication forwarding", e);
+ }
}
}
+ } finally {
+ innerFinished = true;
}
}
};
+ thread.setDaemon(true);
thread.start();
- this.authSocket = authSocket;
} catch (IOException e) {
throw e;
} catch (Exception e) {
@@ -101,9 +115,74 @@ public class AgentServerProxy implements SshAgentServer {
}
public synchronized void close() {
+ if (closed) {
+ return;
+ }
closed = true;
+ final boolean isDebug = LOG.isDebugEnabled();
+
if (handle != 0) {
- Socket.close(handle);
+ if (!innerFinished) {
+ try {
+
+ final long tmpPool = Pool.create(AprLibrary.getInstance().getRootPool());
+ final long tmpSocket = Local.create(authSocket, tmpPool);
+ long connectResult = Local.connect(tmpSocket, 0);
+
+ if (connectResult != Status.APR_SUCCESS) {
+ if (isDebug) {
+ LOG.debug("Unable to connect to socket PIPE {}. APR errcode {}", authSocket, connectResult);
+ }
+ }
+
+ //write a single byte -- just wake up the accept()
+ int sendResult = Socket.send(tmpSocket, END_OF_STREAM_MESSAGE, 0, 1);
+ if (sendResult != 1) {
+ if (isDebug) {
+ LOG.debug("Unable to send signal the EOS for {}. APR retcode {} != 1", authSocket,
+ sendResult);
+ }
+ }
+ } catch (Exception e) {
+ //log eventual exceptions in debug mode
+ if (isDebug) {
+ LOG.debug("Exception connecting to the PIPE socket: " + authSocket, e);
+ }
+ }
+ }
+
+ final int closeCode = Socket.close(handle);
+ if (closeCode != Status.APR_SUCCESS) {
+ LOG.warn("Exceptions closing the PIPE: {}. APR error code: {} ", authSocket, closeCode);
+ }
+ }
+
+ try {
+ if (authSocket != null) {
+
+ final File socketFile = new File(authSocket);
+ if (socketFile.exists()) {
+ if (socketFile.delete()) {
+ if (isDebug) {
+ LOG.debug("Deleted PIPE socket {}", socketFile);
+ }
+ }
+
+ if (OsUtils.isUNIX()) {
+ final File parentFile = socketFile.getParentFile();
+ if (parentFile.delete()) {
+ if (isDebug) {
+ LOG.debug("Deleted parent PIPE socket {}", parentFile);
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ //log eventual exceptions in debug mode
+ if (isDebug) {
+ LOG.debug("Exception deleting the PIPE socket: " + authSocket, e);
+ }
}
}
@@ -113,9 +192,7 @@ public class AgentServerProxy implements SshAgentServer {
* @throws java.io.IOException the produced exception for the given APR error number
*/
static void throwException(int code) throws IOException {
- throw new IOException(
- org.apache.tomcat.jni.Error.strerror(-code) +
- " (code: " + code + ")");
+ throw new IOException(org.apache.tomcat.jni.Error.strerror(-code) + " (code: " + code + ")");
}
}