mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-20 14:49:53 +01:00
Use a single NetLayer instance for all connections.
This commit is contained in:
@@ -17,6 +17,7 @@ import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
|
|||||||
import net.sf.briar.api.protocol.TransportId;
|
import net.sf.briar.api.protocol.TransportId;
|
||||||
import net.sf.briar.util.StringUtils;
|
import net.sf.briar.util.StringUtils;
|
||||||
|
|
||||||
|
import org.silvertunnel.netlib.api.NetAddress;
|
||||||
import org.silvertunnel.netlib.api.NetFactory;
|
import org.silvertunnel.netlib.api.NetFactory;
|
||||||
import org.silvertunnel.netlib.api.NetLayer;
|
import org.silvertunnel.netlib.api.NetLayer;
|
||||||
import org.silvertunnel.netlib.api.NetLayerIDs;
|
import org.silvertunnel.netlib.api.NetLayerIDs;
|
||||||
@@ -43,9 +44,9 @@ class TorPlugin implements DuplexPlugin {
|
|||||||
private final DuplexPluginCallback callback;
|
private final DuplexPluginCallback callback;
|
||||||
private final long pollingInterval;
|
private final long pollingInterval;
|
||||||
|
|
||||||
private boolean running = false; // Locking: this
|
private boolean running = false, connected = false; // Locking: this
|
||||||
private NetServerSocket socket = null; // Locking: this
|
|
||||||
private NetLayer netLayer = null; // Locking: this
|
private NetLayer netLayer = null; // Locking: this
|
||||||
|
private NetServerSocket socket = null; // Locking: this
|
||||||
|
|
||||||
TorPlugin(@PluginExecutor Executor pluginExecutor,
|
TorPlugin(@PluginExecutor Executor pluginExecutor,
|
||||||
DuplexPluginCallback callback, long pollingInterval) {
|
DuplexPluginCallback callback, long pollingInterval) {
|
||||||
@@ -72,18 +73,18 @@ class TorPlugin implements DuplexPlugin {
|
|||||||
private void bind() {
|
private void bind() {
|
||||||
// Retrieve the hidden service address, or create one if necessary
|
// Retrieve the hidden service address, or create one if necessary
|
||||||
TorHiddenServicePrivateNetAddress addr;
|
TorHiddenServicePrivateNetAddress addr;
|
||||||
|
TorNetLayerUtil util = TorNetLayerUtil.getInstance();
|
||||||
TransportConfig c = callback.getConfig();
|
TransportConfig c = callback.getConfig();
|
||||||
String privateKey = c.get("privateKey");
|
String privateKey = c.get("privateKey");
|
||||||
if(privateKey == null) {
|
if(privateKey == null) {
|
||||||
addr = createHiddenServiceAddress(c);
|
addr = createHiddenServiceAddress(util, c);
|
||||||
} else {
|
} else {
|
||||||
TorNetLayerUtil util = TorNetLayerUtil.getInstance();
|
|
||||||
try {
|
try {
|
||||||
addr = util.parseTorHiddenServicePrivateNetAddressFromStrings(
|
addr = util.parseTorHiddenServicePrivateNetAddressFromStrings(
|
||||||
privateKey, "", false);
|
privateKey, "", false);
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
|
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
|
||||||
addr = createHiddenServiceAddress(c);
|
addr = createHiddenServiceAddress(util, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TorHiddenServicePortPrivateNetAddress addrPort =
|
TorHiddenServicePortPrivateNetAddress addrPort =
|
||||||
@@ -92,6 +93,15 @@ class TorPlugin implements DuplexPlugin {
|
|||||||
NetFactory netFactory = NetFactory.getInstance();
|
NetFactory netFactory = NetFactory.getInstance();
|
||||||
NetLayer nl = netFactory.getNetLayerById(NetLayerIDs.TOR);
|
NetLayer nl = netFactory.getNetLayerById(NetLayerIDs.TOR);
|
||||||
nl.waitUntilReady();
|
nl.waitUntilReady();
|
||||||
|
synchronized(this) {
|
||||||
|
if(!running) {
|
||||||
|
tryToClear(nl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
netLayer = nl;
|
||||||
|
connected = true;
|
||||||
|
notifyAll();
|
||||||
|
}
|
||||||
// Publish the hidden service
|
// Publish the hidden service
|
||||||
NetServerSocket ss;
|
NetServerSocket ss;
|
||||||
try {
|
try {
|
||||||
@@ -106,7 +116,6 @@ class TorPlugin implements DuplexPlugin {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
socket = ss;
|
socket = ss;
|
||||||
netLayer = nl;
|
|
||||||
}
|
}
|
||||||
String onion = addr.getPublicOnionHostname();
|
String onion = addr.getPublicOnionHostname();
|
||||||
if(LOG.isLoggable(Level.INFO)) LOG.info("Listening on " + onion);
|
if(LOG.isLoggable(Level.INFO)) LOG.info("Listening on " + onion);
|
||||||
@@ -117,8 +126,7 @@ class TorPlugin implements DuplexPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private TorHiddenServicePrivateNetAddress createHiddenServiceAddress(
|
private TorHiddenServicePrivateNetAddress createHiddenServiceAddress(
|
||||||
TransportConfig c) {
|
TorNetLayerUtil util, TransportConfig c) {
|
||||||
TorNetLayerUtil util = TorNetLayerUtil.getInstance();
|
|
||||||
TorHiddenServicePrivateNetAddress addr =
|
TorHiddenServicePrivateNetAddress addr =
|
||||||
util.createNewTorHiddenServicePrivateNetAddress();
|
util.createNewTorHiddenServicePrivateNetAddress();
|
||||||
RSAKeyPair keyPair = addr.getKeyPair();
|
RSAKeyPair keyPair = addr.getKeyPair();
|
||||||
@@ -128,6 +136,14 @@ class TorPlugin implements DuplexPlugin {
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tryToClear(NetLayer nl) {
|
||||||
|
try {
|
||||||
|
nl.clear();
|
||||||
|
} catch(IOException e) {
|
||||||
|
if(LOG.isLoggable(Level.WARNING)) LOG.warning(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void tryToClose(NetServerSocket ss) {
|
private void tryToClose(NetServerSocket ss) {
|
||||||
try {
|
try {
|
||||||
ss.close();
|
ss.close();
|
||||||
@@ -156,15 +172,17 @@ class TorPlugin implements DuplexPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void stop() throws IOException {
|
public synchronized void stop() throws IOException {
|
||||||
running = false;
|
|
||||||
if(socket != null) {
|
|
||||||
tryToClose(socket);
|
|
||||||
socket = null;
|
|
||||||
}
|
|
||||||
if(netLayer != null) {
|
if(netLayer != null) {
|
||||||
netLayer.clear();
|
netLayer.clear();
|
||||||
netLayer = null;
|
netLayer = null;
|
||||||
}
|
}
|
||||||
|
if(socket != null) {
|
||||||
|
tryToClose(socket);
|
||||||
|
socket = null;
|
||||||
|
}
|
||||||
|
running = false;
|
||||||
|
connected = false;
|
||||||
|
notifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean shouldPoll() {
|
public boolean shouldPoll() {
|
||||||
@@ -201,19 +219,28 @@ class TorPlugin implements DuplexPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DuplexTransportConnection createConnection(ContactId c) {
|
public DuplexTransportConnection createConnection(ContactId c) {
|
||||||
|
NetLayer nl;
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
if(!running) return null;
|
while(!connected) {
|
||||||
|
if(!running) return null;
|
||||||
|
try {
|
||||||
|
wait();
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
if(LOG.isLoggable(Level.INFO))
|
||||||
|
LOG.info("Interrupted while waiting to connect");
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nl = netLayer;
|
||||||
}
|
}
|
||||||
TransportProperties p = callback.getRemoteProperties().get(c);
|
TransportProperties p = callback.getRemoteProperties().get(c);
|
||||||
if(p == null) return null;
|
if(p == null) return null;
|
||||||
String onion = p.get("onion");
|
String onion = p.get("onion");
|
||||||
if(onion == null) return null;
|
if(onion == null) return null;
|
||||||
|
NetAddress addr = new TcpipNetAddress(onion, 80);
|
||||||
try {
|
try {
|
||||||
TcpipNetAddress addr = new TcpipNetAddress(onion, 80);
|
NetSocket s = nl.createNetSocket(null, null, addr);
|
||||||
NetFactory netFactory = NetFactory.getInstance();
|
|
||||||
NetLayer netLayer = netFactory.getNetLayerById(NetLayerIDs.TOR);
|
|
||||||
netLayer.waitUntilReady();
|
|
||||||
NetSocket s = netLayer.createNetSocket(null, null, addr);
|
|
||||||
return new TorTransportConnection(s);
|
return new TorTransportConnection(s);
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
if(LOG.isLoggable(Level.INFO)) LOG.info(e.toString());
|
if(LOG.isLoggable(Level.INFO)) LOG.info(e.toString());
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package net.sf.briar.plugins.tor;
|
package net.sf.briar.plugins.tor;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Scanner;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
@@ -40,10 +42,20 @@ public class TorPluginTest extends BriarTestCase {
|
|||||||
TorPlugin clientPlugin = new TorPlugin(e, clientCallback, 0L);
|
TorPlugin clientPlugin = new TorPlugin(e, clientCallback, 0L);
|
||||||
clientPlugin.start();
|
clientPlugin.start();
|
||||||
// Connect to the server's hidden service
|
// Connect to the server's hidden service
|
||||||
DuplexTransportConnection c = clientPlugin.createConnection(contactId);
|
DuplexTransportConnection clientEnd =
|
||||||
assertNotNull(c);
|
clientPlugin.createConnection(contactId);
|
||||||
c.dispose(false, false);
|
assertNotNull(clientEnd);
|
||||||
assertEquals(1, serverCallback.incomingConnections);
|
DuplexTransportConnection serverEnd = serverCallback.incomingConnection;
|
||||||
|
assertNotNull(serverEnd);
|
||||||
|
// Send some data through the Tor connection
|
||||||
|
PrintStream out = new PrintStream(clientEnd.getOutputStream());
|
||||||
|
out.println("Hello world");
|
||||||
|
out.flush();
|
||||||
|
Scanner in = new Scanner(serverEnd.getInputStream());
|
||||||
|
assertTrue(in.hasNextLine());
|
||||||
|
assertEquals("Hello world", in.nextLine());
|
||||||
|
serverEnd.dispose(false, false);
|
||||||
|
clientEnd.dispose(false, false);
|
||||||
// Stop the plugins
|
// Stop the plugins
|
||||||
serverPlugin.stop();
|
serverPlugin.stop();
|
||||||
clientPlugin.stop();
|
clientPlugin.stop();
|
||||||
@@ -89,7 +101,7 @@ public class TorPluginTest extends BriarTestCase {
|
|||||||
private TransportConfig config = new TransportConfig();
|
private TransportConfig config = new TransportConfig();
|
||||||
private TransportProperties local = new TransportProperties();
|
private TransportProperties local = new TransportProperties();
|
||||||
|
|
||||||
private volatile int incomingConnections = 0;
|
private volatile DuplexTransportConnection incomingConnection = null;
|
||||||
|
|
||||||
public TransportConfig getConfig() {
|
public TransportConfig getConfig() {
|
||||||
return config;
|
return config;
|
||||||
@@ -108,8 +120,8 @@ public class TorPluginTest extends BriarTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setLocalProperties(TransportProperties p) {
|
public void setLocalProperties(TransportProperties p) {
|
||||||
latch.countDown();
|
|
||||||
local = p;
|
local = p;
|
||||||
|
latch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int showChoice(String[] options, String... message) {
|
public int showChoice(String[] options, String... message) {
|
||||||
@@ -123,7 +135,7 @@ public class TorPluginTest extends BriarTestCase {
|
|||||||
public void showMessage(String... message) {}
|
public void showMessage(String... message) {}
|
||||||
|
|
||||||
public void incomingConnectionCreated(DuplexTransportConnection d) {
|
public void incomingConnectionCreated(DuplexTransportConnection d) {
|
||||||
incomingConnections++;
|
incomingConnection = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void outgoingConnectionCreated(ContactId c,
|
public void outgoingConnectionCreated(ContactId c,
|
||||||
|
|||||||
Reference in New Issue
Block a user