-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JENKINS-73889: Cannot reuse an open socket (#204)
* JENKINS-73889: Cannot reuse an open socket * JENKINS-73889: Cannot reuse an open socket * JENKINS-73889: Cannot reuse an open socket --------- Co-authored-by: mpet <[email protected]>
- Loading branch information
Showing
15 changed files
with
871 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,4 +25,5 @@ nbactions.xml | |
nb-configuration.xml | ||
|
||
#vscode | ||
.vscode/ | ||
.vscode/* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.trilead.ssh2.transport; | ||
|
||
import java.io.IOException; | ||
import java.net.SocketTimeoutException; | ||
import java.net.Socket; | ||
import java.net.ServerSocket; | ||
|
||
import com.trilead.ssh2.Connection; | ||
import com.trilead.ssh2.ConnectionInfo; | ||
import com.trilead.ssh2.ServerHostKeyVerifier; | ||
|
||
/** | ||
* This class is similar to {@link Connection} but is | ||
* used to accept incoming connections from clients. | ||
* Example use-cases are 'NETCONF Call Home' or | ||
* 'reverse SSH'. | ||
* | ||
*/ | ||
public class Acceptor extends Connection{ | ||
|
||
/** | ||
* Constuctor | ||
* @param hostname is the hostname that this class is running on. | ||
* @param port is the port that is used for incoming connections. | ||
*/ | ||
public Acceptor(String hostname,int port){ | ||
super(hostname,port); | ||
} | ||
/** | ||
* This method reuses most of methods for {@link Connection#connect(ServerHostKeyVerifier, int, int, int)}. Parameters and descriptions applies here too. | ||
* The main difference between | ||
* this class and {@link Connection} is that we use {@link ServerSocket} and we bind with the port specified in constructor. The {@link ServerSocket#accept()} | ||
* will wait (blocks) for an incoming connection for max {@param connectTimeout} . If connection is completed a {@link Socket} is returned and we set a timeout of this socket using | ||
* {@param readTimeout}. | ||
* | ||
* @throws SocketTimeoutException If there is no incoming connection within {@param connectTimeout}. | ||
* | ||
*/ | ||
public ConnectionInfo accept(ServerHostKeyVerifier verifier, int connectTimeout, int readTimeout, int kexTimeout) throws IOException{ | ||
if (tm != null) { | ||
throw new IOException("Connection to " + hostname + " is already in connected state!"); | ||
} | ||
if (connectTimeout < 0) | ||
throw new IllegalArgumentException("connectTimeout must be non-negative!"); | ||
|
||
if (kexTimeout < 0) | ||
throw new IllegalArgumentException("kexTimeout must be non-negative!"); | ||
|
||
tm = new TransportManager(hostname, port); | ||
tm.setEnabledCallHomeSSH(true); | ||
|
||
tm.setConnectionMonitors(connectionMonitors); | ||
try { | ||
tm.initialize(cryptoWishList, verifier, dhgexpara, connectTimeout, readTimeout, getOrCreateSecureRND(), | ||
proxyData); | ||
} catch (SocketTimeoutException ste) { | ||
throw (SocketTimeoutException) new SocketTimeoutException( | ||
"The accept() operation on the socket timed out.").initCause(ste); | ||
} | ||
|
||
tm.setTcpNoDelay(tcpNoDelay); | ||
|
||
/* Wait until first KEX has finished */ | ||
return tm.getConnectionInfo(1); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package com.trilead.ssh2.transport; | ||
|
||
|
||
import org.assertj.core.util.xml.XmlStringPrettyFormatter; | ||
import org.junit.After; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.testcontainers.Testcontainers; | ||
import org.testcontainers.containers.GenericContainer; | ||
|
||
|
||
import com.trilead.ssh2.log.Logger; | ||
|
||
import static org.xmlunit.assertj3.XmlAssert.assertThat; | ||
|
||
|
||
|
||
public class CallHomeTest { | ||
private static final Logger LOGGER = Logger.getLogger(CallHomeTest.class); | ||
private SshCallHomeClient sshCallHomeClient; | ||
private GenericContainer<?> netopeer2; | ||
|
||
@Before | ||
public void setup() { | ||
//setup logging from java.util.logger used in this project. | ||
JULLoggerSetup.setupJULLogger(); | ||
} | ||
|
||
/** | ||
* This test creates a NETCONF server ( from Dockerfile) and | ||
* configures it and triggers a SSH Call Home ( server acts as client and vice versa). | ||
* Then we start an SSH Client ( using this library). We wait for incoming | ||
* connection from server in accept(). Then when client and server are connected client send | ||
* NETCONF {@code <hello>} message and read the same from NETCONF server. | ||
* For NETCONF server we use Netopeer2. | ||
* | ||
* @see <a href="https://github.com/CESNET/netopeer2">https://github.com/CESNET/netopeer2/a> | ||
* | ||
* @throws Exception if we fail | ||
*/ | ||
@Test() | ||
public void triggerCallHome () throws Exception { | ||
|
||
// https://www.testcontainers.org/features/networking/ | ||
Testcontainers.exposeHostPorts(4334); | ||
|
||
//Start server and trigger SSH Call Home. | ||
netopeer2 = new Netopeer2TestContainer().getNetopeer2Container(); | ||
|
||
//Start client and wait for incoming calls from server | ||
sshCallHomeClient = new SshCallHomeClient(); | ||
sshCallHomeClient.accept(); | ||
//Send hello message from client. | ||
sshCallHomeClient.send(clientHelloMsg()); | ||
//Wait to get a hello message from server. | ||
String message = sshCallHomeClient.read(); | ||
LOGGER.log(50,"Message from node "+message); | ||
assertThat(XmlStringPrettyFormatter.xmlPrettyFormat(message)).and(XmlStringPrettyFormatter.xmlPrettyFormat(serverHelloMsg())).areSimilar(); | ||
|
||
|
||
} | ||
|
||
@After | ||
public void cleanUp() { | ||
sshCallHomeClient.disconnect(); | ||
netopeer2.stop(); | ||
netopeer2.close(); | ||
} | ||
|
||
|
||
private String clientHelloMsg(){ | ||
return """ | ||
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> | ||
<capabilities> | ||
<capability>urn:ietf:params:netconf:base:1.0</capability> | ||
</capabilities> | ||
</hello> | ||
]]>]]> | ||
"""; | ||
} | ||
|
||
private String serverHelloMsg(){ | ||
return """ | ||
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> | ||
<capabilities> | ||
<capability>urn:ietf:params:netconf:base:1.0</capability> | ||
<capability>urn:ietf:params:netconf:base:1.1</capability> | ||
<capability>urn:ietf:params:netconf:capability:writable-running:1.0</capability> | ||
<capability>urn:ietf:params:netconf:capability:candidate:1.0</capability> | ||
<capability>urn:ietf:params:netconf:capability:confirmed-commit:1.1</capability> | ||
<capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability> | ||
<capability>urn:ietf:params:netconf:capability:validate:1.1</capability> | ||
<capability>urn:ietf:params:netconf:capability:startup:1.0</capability> | ||
<capability>urn:ietf:params:netconf:capability:xpath:1.0</capability> | ||
<capability>urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all,report-all-tagged,trim,explicit</capability> | ||
<capability>urn:ietf:params:netconf:capability:notification:1.0</capability> | ||
<capability>urn:ietf:params:netconf:capability:interleave:1.0</capability> | ||
<capability>urn:ietf:params:netconf:capability:url:1.0?scheme=ftp,ftps,http,https,scp,sftp</capability> | ||
<capability>urn:ietf:params:xml:ns:yang:ietf-yang-metadata?module=ietf-yang-metadata&revision=2016-08-05</capability> | ||
<capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2013-07-15</capability> | ||
<capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2013-07-15</capability> | ||
<capability>urn:ietf:params:xml:ns:yang:ietf-netconf-acm?module=ietf-netconf-acm&revision=2018-02-14</capability> | ||
<capability>urn:ietf:params:netconf:capability:yang-library:1.1?revision=2019-01-04&content-id=2008448144</capability> | ||
<capability>urn:sysrepo:plugind?module=sysrepo-plugind&revision=2022-08-26</capability> | ||
<capability>urn:ietf:params:xml:ns:netconf:base:1.0?module=ietf-netconf&revision=2013-09-29&features=writable-running,candidate,confirmed-commit,rollback-on-error,validate,startup,url,xpath</capability> | ||
<capability>urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults?module=ietf-netconf-with-defaults&revision=2011-06-01</capability> | ||
<capability>urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?module=ietf-netconf-notifications&revision=2012-02-06</capability> | ||
<capability>urn:ietf:params:xml:ns:netconf:notification:1.0?module=notifications&revision=2008-07-14</capability> | ||
<capability>urn:ietf:params:xml:ns:netmod:notification?module=nc-notifications&revision=2008-07-14</capability> | ||
<capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04</capability> | ||
<capability>urn:ietf:params:xml:ns:yang:ietf-x509-cert-to-name?module=ietf-x509-cert-to-name&revision=2014-12-10</capability> | ||
<capability>urn:ietf:params:xml:ns:yang:iana-crypt-hash?module=iana-crypt-hash&revision=2014-04-04&features=crypt-hash-md5,crypt-hash-sha-256,crypt-hash-sha-512</capability> | ||
</capabilities> | ||
<session-id>1</session-id> | ||
</hello> | ||
"""; | ||
} | ||
|
||
} |
Oops, something went wrong.