abort socks candidate search if peer selected something with higher priority

This commit is contained in:
Daniel Gultsch 2023-12-20 11:23:04 +01:00
parent eec01c9e7b
commit aeb805a3ca
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2

View file

@ -54,6 +54,7 @@ import java.util.Comparator;
import java.util.Locale; import java.util.Locale;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -145,7 +146,8 @@ public class SocksByteStreamsTransport implements Transport {
this.transportCallback != null, "transport callback needs to be set"); this.transportCallback != null, "transport callback needs to be set");
// TODO this needs to go into a variable so we can cancel it // TODO this needs to go into a variable so we can cancel it
final var connectionFinder = final var connectionFinder =
new ConnectionFinder(theirCandidates, theirDestination, useTor); new ConnectionFinder(
theirCandidates, theirDestination, selectedByThemCandidate, useTor);
new Thread(connectionFinder).start(); new Thread(connectionFinder).start();
Futures.addCallback( Futures.addCallback(
connectionFinder.connectionFuture, connectionFinder.connectionFuture,
@ -281,7 +283,8 @@ public class SocksByteStreamsTransport implements Transport {
proxyFuture, proxyFuture,
proxy -> { proxy -> {
final var connectionFinder = final var connectionFinder =
new ConnectionFinder(ImmutableList.of(proxy), ourDestination, useTor); new ConnectionFinder(
ImmutableList.of(proxy), ourDestination, null, useTor);
new Thread(connectionFinder).start(); new Thread(connectionFinder).start();
return Futures.transform( return Futures.transform(
connectionFinder.connectionFuture, connectionFinder.connectionFuture,
@ -703,22 +706,36 @@ public class SocksByteStreamsTransport implements Transport {
private final ImmutableList<Candidate> candidates; private final ImmutableList<Candidate> candidates;
private final String destination; private final String destination;
private final ListenableFuture<Connection> selectedByThemCandidate;
private final boolean useTor; private final boolean useTor;
private ConnectionFinder( private ConnectionFinder(
final ImmutableList<Candidate> candidates, final ImmutableList<Candidate> candidates,
final String destination, final String destination,
final ListenableFuture<Connection> selectedByThemCandidate,
final boolean useTor) { final boolean useTor) {
this.candidates = candidates; this.candidates = candidates;
this.destination = destination; this.destination = destination;
this.selectedByThemCandidate = selectedByThemCandidate;
this.useTor = useTor; this.useTor = useTor;
} }
@Override @Override
public void run() { public void run() {
for (final Candidate candidate : this.candidates) { for (final Candidate candidate : this.candidates) {
// TODO we can check if there is already something in `selectedByThemCandidate` with final Integer selectedByThemCandidatePriority =
// a higher priority and abort getSelectedByThemCandidatePriority();
if (selectedByThemCandidatePriority != null
&& selectedByThemCandidatePriority > candidate.priority) {
Log.d(
Config.LOGTAG,
"The candidate selected by peer had a higher priority then anything we could try");
connectionFuture.setException(
new CandidateErrorException(
"The candidate selected by peer had a higher priority then anything we could try"));
return;
}
try { try {
connectionFuture.set(connect(candidate)); connectionFuture.set(connect(candidate));
Log.d(Config.LOGTAG, "connected to " + candidate); Log.d(Config.LOGTAG, "connected to " + candidate);
@ -751,6 +768,20 @@ public class SocksByteStreamsTransport implements Transport {
socket.setSoTimeout(0); socket.setSoTimeout(0);
return new Connection(candidate, socket); return new Connection(candidate, socket);
} }
private Integer getSelectedByThemCandidatePriority() {
final var future = this.selectedByThemCandidate;
if (future != null && future.isDone()) {
try {
final var connection = future.get();
return connection.candidate.priority;
} catch (ExecutionException | InterruptedException e) {
return null;
}
} else {
return null;
}
}
} }
public static class CandidateErrorException extends IllegalStateException { public static class CandidateErrorException extends IllegalStateException {