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