also reply with direct connections on response

This commit is contained in:
Daniel Gultsch 2019-09-01 20:42:07 +02:00
parent 1c413edf06
commit 10b1365264
3 changed files with 40 additions and 24 deletions

View File

@ -101,6 +101,7 @@ public final class Config {
public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb public static final boolean DISABLE_PROXY_LOOKUP = false; //useful to debug ibb
public static final boolean USE_DIRECT_JINGLE_CANDIDATES = false;
public static final boolean DISABLE_HTTP_UPLOAD = false; public static final boolean DISABLE_HTTP_UPLOAD = false;
public static final boolean EXTENDED_SM_LOGGING = false; // log stanza counts public static final boolean EXTENDED_SM_LOGGING = false; // log stanza counts
public static final boolean BACKGROUND_STANZA_LOGGING = false; //log all stanzas that were received while the app is in background public static final boolean BACKGROUND_STANZA_LOGGING = false; //log all stanzas that were received while the app is in background

View File

@ -171,7 +171,8 @@ public class JingleConnection implements Transferable {
@Override @Override
public void failed() { public void failed() {
Log.d(Config.LOGTAG, "proxy activation failed"); Log.d(Config.LOGTAG, account.getJid().asBareJid()+": proxy activation failed");
//TODO: when initiating send fallback to ibb
} }
}; };
@ -303,14 +304,7 @@ public class JingleConnection implements Transferable {
if (this.initialTransport == Transport.IBB) { if (this.initialTransport == Transport.IBB) {
this.sendInitRequest(); this.sendInitRequest();
} else { } else {
gatherAndConnectDirectCandidates();
final List<JingleCandidate> directCandidates = DirectConnectionUtils.getLocalCandidates(account.getJid());
for (JingleCandidate directCandidate : directCandidates) {
final JingleSocks5Transport socksConnection = new JingleSocks5Transport(this, directCandidate);
connections.put(directCandidate.getCid(), socksConnection);
candidates.add(directCandidate);
}
this.mJingleConnectionManager.getPrimaryCandidate(account, (success, candidate) -> { this.mJingleConnectionManager.getPrimaryCandidate(account, (success, candidate) -> {
if (success) { if (success) {
final JingleSocks5Transport socksConnection = new JingleSocks5Transport(this, candidate); final JingleSocks5Transport socksConnection = new JingleSocks5Transport(this, candidate);
@ -342,6 +336,24 @@ public class JingleConnection implements Transferable {
} }
private void gatherAndConnectDirectCandidates() {
final List<JingleCandidate> directCandidates;
if (Config.USE_DIRECT_JINGLE_CANDIDATES) {
if (account.isOnion() || mXmppConnectionService.useTorToConnect()) {
directCandidates = Collections.emptyList();
} else {
directCandidates = DirectConnectionUtils.getLocalCandidates(account.getJid());
}
} else {
directCandidates = Collections.emptyList();
}
for (JingleCandidate directCandidate : directCandidates) {
final JingleSocks5Transport socksConnection = new JingleSocks5Transport(this, directCandidate);
connections.put(directCandidate.getCid(), socksConnection);
candidates.add(directCandidate);
}
}
private void upgradeNamespace() { private void upgradeNamespace() {
List<String> features = getRemoteFeatures(); List<String> features = getRemoteFeatures();
if (features.contains(Content.Version.FT_5.getNamespace())) { if (features.contains(Content.Version.FT_5.getNamespace())) {
@ -570,6 +582,7 @@ public class JingleConnection implements Transferable {
} }
private void sendAcceptSocks() { private void sendAcceptSocks() {
gatherAndConnectDirectCandidates();
this.mJingleConnectionManager.getPrimaryCandidate(this.account, (success, candidate) -> { this.mJingleConnectionManager.getPrimaryCandidate(this.account, (success, candidate) -> {
final JinglePacket packet = bootstrapPacket("session-accept"); final JinglePacket packet = bootstrapPacket("session-accept");
final Content content = new Content(contentCreator, contentName); final Content content = new Content(contentCreator, contentName);
@ -600,7 +613,7 @@ public class JingleConnection implements Transferable {
} }
}); });
} else { } else {
Log.d(Config.LOGTAG, "did not find a primary candidate for ourself"); Log.d(Config.LOGTAG, "did not find a primary candidate for ourselves");
content.socks5transport().setChildren(getCandidatesAsElements()); content.socks5transport().setChildren(getCandidatesAsElements());
packet.setContent(content); packet.setContent(content);
sendJinglePacket(packet); sendJinglePacket(packet);
@ -762,6 +775,7 @@ public class JingleConnection implements Transferable {
if (response.getType() != IqPacket.TYPE.RESULT) { if (response.getType() != IqPacket.TYPE.RESULT) {
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": " + response.toString()); Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": " + response.toString());
onProxyActivated.failed(); onProxyActivated.failed();
//TODO send proxy-error
} else { } else {
onProxyActivated.success(); onProxyActivated.success();
sendProxyActivated(connection.getCandidate().getCid()); sendProxyActivated(connection.getCandidate().getCid());

View File

@ -76,7 +76,7 @@ public class JingleSocks5Transport extends JingleTransport {
try { try {
acceptIncomingSocketConnection(socket); acceptIncomingSocketConnection(socket);
} catch (IOException e) { } catch (IOException e) {
Log.d(Config.LOGTAG,"unable to read from socket",e); Log.d(Config.LOGTAG, "unable to read from socket", e);
} }
}).start(); }).start();
@ -87,43 +87,43 @@ public class JingleSocks5Transport extends JingleTransport {
} }
}).start(); }).start();
} catch (IOException e) { } catch (IOException e) {
Log.d(Config.LOGTAG,"unable to bind server socket ",e); Log.d(Config.LOGTAG, "unable to bind server socket ", e);
} }
} }
private void acceptIncomingSocketConnection(Socket socket) throws IOException { private void acceptIncomingSocketConnection(Socket socket) throws IOException {
Log.d(Config.LOGTAG, "accepted connection from " + socket.getInetAddress().getHostAddress()); Log.d(Config.LOGTAG, "accepted connection from " + socket.getInetAddress().getHostAddress());
byte[] authBegin = new byte[2]; final byte[] authBegin = new byte[2];
InputStream inputStream = socket.getInputStream(); final InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream(); final OutputStream outputStream = socket.getOutputStream();
inputStream.read(authBegin); inputStream.read(authBegin);
if (authBegin[0] != 0x5) { if (authBegin[0] != 0x5) {
socket.close(); socket.close();
} }
short methodCount = authBegin[1]; final short methodCount = authBegin[1];
byte[] methods = new byte[methodCount]; final byte[] methods = new byte[methodCount];
inputStream.read(methods); inputStream.read(methods);
if (SocksSocketFactory.contains((byte) 0x00, methods)) { if (SocksSocketFactory.contains((byte) 0x00, methods)) {
outputStream.write(new byte[]{0x05,0x00}); outputStream.write(new byte[]{0x05, 0x00});
} else { } else {
outputStream.write(new byte[]{0x05,(byte) 0xff}); outputStream.write(new byte[]{0x05, (byte) 0xff});
} }
byte[] connectCommand = new byte[4]; byte[] connectCommand = new byte[4];
inputStream.read(connectCommand); inputStream.read(connectCommand);
if (connectCommand[0] == 0x05 && connectCommand[1] == 0x01 && connectCommand[3] == 0x03) { if (connectCommand[0] == 0x05 && connectCommand[1] == 0x01 && connectCommand[3] == 0x03) {
int destinationCount = inputStream.read(); int destinationCount = inputStream.read();
byte[] destination = new byte[destinationCount]; final byte[] destination = new byte[destinationCount];
inputStream.read(destination); inputStream.read(destination);
int port = inputStream.read(); final int port = inputStream.read();
final String receivedDestination = new String(destination); final String receivedDestination = new String(destination);
Log.d(Config.LOGTAG, "received destination " + receivedDestination + ":" + port + " - expected " + this.destination);
final ByteBuffer response = ByteBuffer.allocate(7 + destination.length); final ByteBuffer response = ByteBuffer.allocate(7 + destination.length);
final byte[] responseHeader; final byte[] responseHeader;
final boolean success; final boolean success;
if (receivedDestination.equals(this.destination)) { if (receivedDestination.equals(this.destination) && this.socket == null) {
responseHeader = new byte[]{0x05, 0x00, 0x00, 0x03}; responseHeader = new byte[]{0x05, 0x00, 0x00, 0x03};
success = true; success = true;
} else { } else {
Log.d(Config.LOGTAG,connection.getAccount().getJid().asBareJid()+": destination mismatch. received "+receivedDestination+" (expected "+this.destination+")");
responseHeader = new byte[]{0x05, 0x04, 0x00, 0x03}; responseHeader = new byte[]{0x05, 0x04, 0x00, 0x03};
success = false; success = false;
} }
@ -138,6 +138,7 @@ public class JingleSocks5Transport extends JingleTransport {
this.inputStream = inputStream; this.inputStream = inputStream;
this.outputStream = outputStream; this.outputStream = outputStream;
this.isEstablished = true; this.isEstablished = true;
FileBackend.close(serverSocket);
} }
} else { } else {
socket.close(); socket.close();
@ -153,7 +154,7 @@ public class JingleSocks5Transport extends JingleTransport {
} else { } else {
socket = new Socket(); socket = new Socket();
SocketAddress address = new InetSocketAddress(candidate.getHost(), candidate.getPort()); SocketAddress address = new InetSocketAddress(candidate.getHost(), candidate.getPort());
socket.connect(address, Config.SOCKET_TIMEOUT * 1000); socket.connect(address, 5000);
} }
inputStream = socket.getInputStream(); inputStream = socket.getInputStream();
outputStream = socket.getOutputStream(); outputStream = socket.getOutputStream();