set shorter timeouts when using direct candidates

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java            |  6 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java        |  7 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java |  2 
src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java   | 13 
4 files changed, 19 insertions(+), 9 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/utils/SocksSocketFactory.java 🔗

@@ -15,8 +15,8 @@ public class SocksSocketFactory {
 	private static final byte[] LOCALHOST = new byte[]{127,0,0,1};
 
 	public static void createSocksConnection(Socket socket, String destination, int port) throws IOException {
-		InputStream proxyIs = socket.getInputStream();
-		OutputStream proxyOs = socket.getOutputStream();
+		final InputStream proxyIs = socket.getInputStream();
+		final OutputStream proxyOs = socket.getOutputStream();
 		proxyOs.write(new byte[]{0x05, 0x01, 0x00});
 		byte[] response = new byte[2];
 		proxyIs.read(response);
@@ -24,7 +24,7 @@ public class SocksSocketFactory {
 			throw new SocksConnectionException("Socks 5 handshake failed");
 		}
 		byte[] dest = destination.getBytes();
-		ByteBuffer request = ByteBuffer.allocate(7 + dest.length);
+		final ByteBuffer request = ByteBuffer.allocate(7 + dest.length);
 		request.put(new byte[]{0x05, 0x01, 0x00, 0x03});
 		request.put((byte) dest.length);
 		request.put(dest);

src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java 🔗

@@ -564,8 +564,11 @@ public class JingleConnection implements Transferable {
             content.setTransportId(this.transportId);
             if (this.initialTransport == Transport.IBB) {
                 content.ibbTransport().setAttribute("block-size", Integer.toString(this.ibbBlockSize));
+                Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": sending IBB offer");
             } else {
-                content.socks5transport().setChildren(getCandidatesAsElements());
+                final List<Element> candidates = getCandidatesAsElements();
+                Log.d(Config.LOGTAG, String.format("%s: sending S5B offer with %d candidates", account.getJid().asBareJid(), candidates.size()));
+                content.socks5transport().setChildren(candidates);
             }
             packet.setContent(content);
             this.sendJinglePacket(packet, (account, response) -> {
@@ -950,7 +953,7 @@ public class JingleConnection implements Transferable {
             this.transport = new JingleInbandTransport(this, this.transportId, this.ibbBlockSize);
 
             if (sid == null || !sid.equals(this.transportId)) {
-                Log.w(Config.LOGTAG,String.format("%s: sid in transport-accept (%s) did not match our sid (%s) ", account.getJid().asBareJid(), sid, transportId));
+                Log.w(Config.LOGTAG, String.format("%s: sid in transport-accept (%s) did not match our sid (%s) ", account.getJid().asBareJid(), sid, transportId));
             }
 
             //might be receive instead if we are not initiating

src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java 🔗

@@ -106,7 +106,7 @@ public class JingleConnectionManager extends AbstractConnectionManager {
 								candidate.setPort(Integer.parseInt(port));
 								candidate.setType(JingleCandidate.TYPE_PROXY);
 								candidate.setJid(proxy);
-								candidate.setPriority(655360 + (initiator ? 10 : 20));
+								candidate.setPriority(655360 + (initiator ? 30 : 0));
 								primaryCandidates.put(account.getJid().asBareJid(),candidate);
 								listener.onPrimaryCandidateFound(true,candidate);
 							} catch (final NumberFormatException e) {

src/main/java/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java 🔗

@@ -26,6 +26,10 @@ import eu.siacs.conversations.utils.WakeLockHelper;
 import eu.siacs.conversations.xmpp.jingle.stanzas.Content;
 
 public class JingleSocks5Transport extends JingleTransport {
+
+    private static final int SOCKET_TIMEOUT_DIRECT = 3000;
+    private static final int SOCKET_TIMEOUT_PROXY = 5000;
+
     private final JingleCandidate candidate;
     private final JingleConnection connection;
     private final String destination;
@@ -92,8 +96,9 @@ public class JingleSocks5Transport extends JingleTransport {
         }
     }
 
-    private void acceptIncomingSocketConnection(Socket socket) throws IOException {
+    private void acceptIncomingSocketConnection(final Socket socket) throws IOException {
         Log.d(Config.LOGTAG, "accepted connection from " + socket.getInetAddress().getHostAddress());
+        socket.setSoTimeout(SOCKET_TIMEOUT_DIRECT);
         final byte[] authBegin = new byte[2];
         final InputStream inputStream = socket.getInputStream();
         final OutputStream outputStream = socket.getOutputStream();
@@ -136,6 +141,7 @@ public class JingleSocks5Transport extends JingleTransport {
             outputStream.flush();
             if (success) {
                 Log.d(Config.LOGTAG,connection.getAccount().getJid().asBareJid()+": successfully processed connection to candidate "+candidate.getHost()+":"+candidate.getPort());
+                socket.setSoTimeout(0);
                 this.socket = socket;
                 this.inputStream = inputStream;
                 this.outputStream = outputStream;
@@ -151,6 +157,7 @@ public class JingleSocks5Transport extends JingleTransport {
 
     public void connect(final OnTransportConnected callback) {
         new Thread(() -> {
+            final int timeout = candidate.getType() == JingleCandidate.TYPE_DIRECT ? SOCKET_TIMEOUT_DIRECT : SOCKET_TIMEOUT_PROXY;
             try {
                 final boolean useTor = connection.getAccount().isOnion() || connection.getConnectionManager().getXmppConnectionService().useTorToConnect();
                 if (useTor) {
@@ -158,11 +165,11 @@ public class JingleSocks5Transport extends JingleTransport {
                 } else {
                     socket = new Socket();
                     SocketAddress address = new InetSocketAddress(candidate.getHost(), candidate.getPort());
-                    socket.connect(address, 5000);
+                    socket.connect(address, timeout);
                 }
                 inputStream = socket.getInputStream();
                 outputStream = socket.getOutputStream();
-                socket.setSoTimeout(5000);
+                socket.setSoTimeout(timeout);
                 SocksSocketFactory.createSocksConnection(socket, destination, 0);
                 socket.setSoTimeout(0);
                 isEstablished = true;