private IByteStreamConnection connectInternal(String connectionID, JID peer) throws IOException { IByteStreamConnection connection = null; final String connectionIDToken = toConnectionIDToken(connectionID, OUT, peer); synchronized (currentOutgoingConnectionEstablishments) { if (!currentOutgoingConnectionEstablishments.contains(connectionIDToken)) { connection = getCurrentConnection(connectionID, peer); if (connection == null) currentOutgoingConnectionEstablishments.add(connectionIDToken); } if (connection != null) return connection; } connectLock.lock(); try { connection = getCurrentConnection(connectionID, peer); if (connection != null) return connection; JID connectionJID = currentLocalJID; if (connectionJID == null) throw new IOException("not connected to a XMPP server"); ArrayList<ITransport> transportModesToUse = new ArrayList<ITransport>(availableTransports); LOG.debug( "currently used IP addresses for Socks5Proxy: " + Arrays.toString(Socks5Proxy.getSocks5Proxy().getLocalAddresses().toArray())); for (ITransport transport : transportModesToUse) { LOG.info( "establishing connection to " + peer.getBase() + " from " + connectionJID + " using " + transport); try { connection = transport.connect(connectionID, peer); break; } catch (IOException e) { LOG.error(peer + " failed to connect using " + transport + ": " + e.getMessage(), e); } catch (InterruptedException e) { IOException io = new InterruptedIOException("connecting cancelled: " + e.getMessage()); io.initCause(e); throw io; } catch (Exception e) { LOG.error( peer + " failed to connect using " + transport + " because of an unknown error: " + e.getMessage(), e); } } if (connection != null) { byteStreamConnectionListener.connectionChanged(connectionID, peer, connection, false); return connection; } throw new IOException("could not connect to: " + peer); } finally { synchronized (currentOutgoingConnectionEstablishments) { currentOutgoingConnectionEstablishments.remove(connectionIDToken); } connectLock.unlock(); } }