Skip to content

Commit

Permalink
Fixes thaliproject#115: Support for custom bridges
Browse files Browse the repository at this point in the history
  • Loading branch information
sisbell committed Apr 28, 2019
1 parent f49e1b6 commit 061b7e5
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 1 deletion.
Expand Up @@ -85,6 +85,13 @@ public TorConfigBuilder bridge(String type, String config) {
return this;
}

public TorConfigBuilder bridgeCustom(String config) {
if (!isNullOrEmpty(config)) {
buffer.append("Bridge ").append(config).append('\n');
}
return this;
}

public TorConfigBuilder configurePluggableTransportsFromSettings(File pluggableTransportClient) throws IOException {
List<String> supportedBridges = settings.getListOfSupportedBridges();
if (pluggableTransportClient == null || !settings.hasBridges() || supportedBridges.size() < 1) {
Expand Down Expand Up @@ -487,11 +494,28 @@ public TorConfigBuilder virtualAddressNetworkFromSettings() {

/**
* Adds bridges from a resource stream. This relies on the TorInstaller to know how to obtain this stream.
* These entries may be type-specified like:
*
* <code>
* obfs3 169.229.59.74:31493 AF9F66B7B04F8FF6F32D455F05135250A16543C9
* </code>
*
* Or it may just be a custom entry like
*
* <code>
* 69.163.45.129:443 9F090DE98CA6F67DEEB1F87EFE7C1BFD884E6E2F
* </code>
*
*/
TorConfigBuilder addBridgesFromResources(String type, int maxBridges) throws IOException {
if(settings.hasBridges()) {
InputStream bridgesStream = context.getInstaller().openBridgesStream();
addBridges(bridgesStream, type, maxBridges);
int formatType = bridgesStream.read();
if(formatType == 0) {
addBridges(bridgesStream, type, maxBridges);
} else {
addCustomBridges(bridgesStream);
}
}
return this;
}
Expand All @@ -518,6 +542,24 @@ private void addBridges(InputStream input, String bridgeType, int maxBridges) {
if(hasAddedBridge) useBridges();
}

/**
* Add custom bridges defined by the user. These will have a bridgeType of 'custom' as the first field.
*/
private void addCustomBridges(InputStream input) {
if (input == null) {
return;
}
boolean hasAddedBridge = false;
List<Bridge> bridges = readCustomBridgesFromStream(input);
for (Bridge b : bridges) {
if (b.type.equals("custom")) {
bridgeCustom(b.config);
hasAddedBridge = true;
}
}
if(hasAddedBridge) useBridges();
}

private static List<Bridge> readBridgesFromStream(InputStream input) {
List<Bridge> bridges = new ArrayList<>();
try {
Expand All @@ -536,6 +578,23 @@ private static List<Bridge> readBridgesFromStream(InputStream input) {
return bridges;
}

private static List<Bridge> readCustomBridgesFromStream(InputStream input) {
List<Bridge> bridges = new ArrayList<>();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(input, "UTF-8"));
for (String line = br.readLine(); line != null; line = br.readLine()) {
if(line.isEmpty()) {
continue;
}
bridges.add(new Bridge("custom", line));
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
return bridges;
}

private static class Bridge {
final String type;
final String config;
Expand Down
Expand Up @@ -29,5 +29,20 @@ public final InputStream getAssetOrResourceByName(String fileName) {
return getClass().getResourceAsStream("/" + fileName);
}

/**
* If first byte of stream is 0, then the following stream will have the form
*
* <code>
* ($bridge_type $bridge_info \r\n)*
* </code>
*
* if first byte is 1, the the stream will have the form
* <code>
* ($bridge_info \r\n)*
* </code>
*
* The second form is used for custom bridges from the user.
*
*/
public abstract InputStream openBridgesStream() throws IOException;
}

0 comments on commit 061b7e5

Please sign in to comment.