mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Separated TCP plugin into LAN and WAN plugins and renamed package.
This commit is contained in:
@@ -10,9 +10,9 @@ public interface PluginManager {
|
||||
/**
|
||||
* Starts the plugins and returns the number of plugins successfully
|
||||
* started. This method must not be called until the database has been
|
||||
* opened.
|
||||
* opened. The appContext argument is null on non-Android platforms.
|
||||
*/
|
||||
int start(Context context);
|
||||
int start(Context appContext);
|
||||
|
||||
/**
|
||||
* Stops the plugins and returns the number of plugins successfully stopped.
|
||||
|
||||
@@ -50,7 +50,8 @@ class PluginManagerImpl implements PluginManager {
|
||||
|
||||
private static final String[] ANDROID_DUPLEX_FACTORIES = new String[] {
|
||||
"net.sf.briar.plugins.droidtooth.DroidtoothPluginFactory",
|
||||
"net.sf.briar.plugins.socket.SimpleSocketPluginFactory"
|
||||
"net.sf.briar.plugins.tcp.LanTcpPluginFactory",
|
||||
"net.sf.briar.plugins.tcp.WanTcpPluginFactory"
|
||||
};
|
||||
|
||||
private static final String[] J2SE_SIMPLEX_FACTORIES = new String[] {
|
||||
@@ -59,7 +60,8 @@ class PluginManagerImpl implements PluginManager {
|
||||
|
||||
private static final String[] J2SE_DUPLEX_FACTORIES = new String[] {
|
||||
"net.sf.briar.plugins.bluetooth.BluetoothPluginFactory",
|
||||
"net.sf.briar.plugins.socket.SimpleSocketPluginFactory",
|
||||
"net.sf.briar.plugins.tcp.LanSocketPluginFactory",
|
||||
"net.sf.briar.plugins.tcp.WanSocketPluginFactory",
|
||||
"net.sf.briar.plugins.tor.TorPluginFactory"
|
||||
};
|
||||
|
||||
|
||||
@@ -1,154 +0,0 @@
|
||||
package net.sf.briar.plugins.socket;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.sf.briar.api.ContactId;
|
||||
import net.sf.briar.api.TransportProperties;
|
||||
import net.sf.briar.api.crypto.PseudoRandom;
|
||||
import net.sf.briar.api.plugins.PluginExecutor;
|
||||
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
|
||||
import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
|
||||
import net.sf.briar.api.protocol.TransportId;
|
||||
import net.sf.briar.util.StringUtils;
|
||||
|
||||
class SimpleSocketPlugin extends SocketPlugin {
|
||||
|
||||
public static final byte[] TRANSPORT_ID =
|
||||
StringUtils.fromHexString("58c66d999e492b85065924acfd739d80"
|
||||
+ "c65a62f87e5a4fc6c284f95908b9007d"
|
||||
+ "512a93ebf89bf68f50a29e96eebf97b6");
|
||||
|
||||
private static final TransportId ID = new TransportId(TRANSPORT_ID);
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(SimpleSocketPlugin.class.getName());
|
||||
|
||||
SimpleSocketPlugin(@PluginExecutor Executor pluginExecutor,
|
||||
DuplexPluginCallback callback, long pollingInterval) {
|
||||
super(pluginExecutor, callback, pollingInterval);
|
||||
}
|
||||
|
||||
public TransportId getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Socket createClientSocket() throws IOException {
|
||||
assert running;
|
||||
return new Socket();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServerSocket createServerSocket() throws IOException {
|
||||
assert running;
|
||||
return new ServerSocket();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress getLocalSocketAddress() {
|
||||
SocketAddress addr = createSocketAddress(callback.getLocalProperties());
|
||||
if(addr == null) {
|
||||
try {
|
||||
return new InetSocketAddress(chooseInterface(false), 0);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
}
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
protected InetAddress chooseInterface(boolean lan) throws IOException {
|
||||
List<NetworkInterface> ifaces =
|
||||
Collections.list(NetworkInterface.getNetworkInterfaces());
|
||||
// Try to find an interface of the preferred type (LAN or WAN)
|
||||
for(NetworkInterface iface : ifaces) {
|
||||
for(InetAddress addr : Collections.list(iface.getInetAddresses())) {
|
||||
if(!addr.isLoopbackAddress()) {
|
||||
boolean link = addr.isLinkLocalAddress();
|
||||
boolean site = addr.isSiteLocalAddress();
|
||||
if(lan == (link || site)) {
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
LOG.info("Choosing interface "
|
||||
+ addr.getHostAddress());
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Settle for an interface that's not of the preferred type
|
||||
for(NetworkInterface iface : ifaces) {
|
||||
for(InetAddress addr : Collections.list(iface.getInetAddresses())) {
|
||||
if(!addr.isLoopbackAddress()) {
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
LOG.info("Accepting interface "
|
||||
+ addr.getHostAddress());
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new IOException("No suitable interfaces");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SocketAddress getRemoteSocketAddress(ContactId c) {
|
||||
TransportProperties p = callback.getRemoteProperties().get(c);
|
||||
return p == null ? null : createSocketAddress(p);
|
||||
}
|
||||
|
||||
private SocketAddress createSocketAddress(TransportProperties p) {
|
||||
assert p != null;
|
||||
String host = p.get("external");
|
||||
if(host == null) host = p.get("internal");
|
||||
String portString = p.get("port");
|
||||
if(host == null || portString == null) return null;
|
||||
int port;
|
||||
try {
|
||||
port = Integer.valueOf(portString);
|
||||
} catch(NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
return new InetSocketAddress(host, port);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setLocalSocketAddress(SocketAddress s) {
|
||||
if(!(s instanceof InetSocketAddress))
|
||||
throw new IllegalArgumentException();
|
||||
InetSocketAddress i = (InetSocketAddress) s;
|
||||
InetAddress addr = i.getAddress();
|
||||
TransportProperties p = new TransportProperties();
|
||||
if(addr.isLinkLocalAddress() || addr.isSiteLocalAddress())
|
||||
p.put("internal", addr.getHostAddress());
|
||||
else p.put("external", addr.getHostAddress());
|
||||
p.put("port", String.valueOf(i.getPort()));
|
||||
callback.mergeLocalProperties(p);
|
||||
}
|
||||
|
||||
public boolean supportsInvitations() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public DuplexTransportConnection sendInvitation(PseudoRandom r,
|
||||
long timeout) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public DuplexTransportConnection acceptInvitation(PseudoRandom r,
|
||||
long timeout) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.sf.briar.plugins.socket;
|
||||
package net.sf.briar.plugins.tcp;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
@@ -8,36 +8,103 @@ import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.sf.briar.api.TransportProperties;
|
||||
import net.sf.briar.api.crypto.PseudoRandom;
|
||||
import net.sf.briar.api.plugins.PluginExecutor;
|
||||
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
|
||||
import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
|
||||
import net.sf.briar.api.protocol.TransportId;
|
||||
import net.sf.briar.util.ByteUtils;
|
||||
import net.sf.briar.util.StringUtils;
|
||||
|
||||
/** A socket plugin that supports exchanging invitations over a LAN. */
|
||||
class LanSocketPlugin extends SimpleSocketPlugin {
|
||||
class LanTcpPlugin extends TcpPlugin {
|
||||
|
||||
public static final byte[] TRANSPORT_ID =
|
||||
StringUtils.fromHexString("0d79357fd7f74d66c2f6f6ad0f7fff81"
|
||||
+ "d21c53a43b90b0507ed0683872d8e2fc"
|
||||
+ "5a88e8f953638228dc26669639757bbf");
|
||||
|
||||
private static final TransportId ID = new TransportId(TRANSPORT_ID);
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(LanSocketPlugin.class.getName());
|
||||
Logger.getLogger(LanTcpPlugin.class.getName());
|
||||
|
||||
LanSocketPlugin(@PluginExecutor Executor pluginExecutor,
|
||||
LanTcpPlugin(@PluginExecutor Executor pluginExecutor,
|
||||
DuplexPluginCallback callback, long pollingInterval) {
|
||||
super(pluginExecutor, callback, pollingInterval);
|
||||
}
|
||||
|
||||
public TransportId getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<SocketAddress> getLocalSocketAddresses() {
|
||||
List<SocketAddress> addrs = new ArrayList<SocketAddress>();
|
||||
// Prefer a previously used address and port if available
|
||||
TransportProperties p = callback.getLocalProperties();
|
||||
String addrString = p.get("address");
|
||||
String portString = p.get("port");
|
||||
InetAddress addr = null;
|
||||
if(addrString != null && portString != null) {
|
||||
try {
|
||||
addr = InetAddress.getByName(addrString);
|
||||
int port = Integer.valueOf(portString);
|
||||
addrs.add(new InetSocketAddress(addr, port));
|
||||
addrs.add(new InetSocketAddress(addr, 0));
|
||||
} catch(NumberFormatException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
} catch(UnknownHostException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
}
|
||||
}
|
||||
List<NetworkInterface> ifaces;
|
||||
try {
|
||||
ifaces = Collections.list(NetworkInterface.getNetworkInterfaces());
|
||||
} catch(SocketException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
return addrs;
|
||||
}
|
||||
// Prefer interfaces with link-local or site-local addresses
|
||||
for(NetworkInterface iface : ifaces) {
|
||||
for(InetAddress a : Collections.list(iface.getInetAddresses())) {
|
||||
if(addr != null && a.equals(addr)) continue;
|
||||
if(a.isLoopbackAddress()) continue;
|
||||
boolean link = a.isLinkLocalAddress();
|
||||
boolean site = a.isSiteLocalAddress();
|
||||
if(link || site) addrs.add(new InetSocketAddress(a, 0));
|
||||
}
|
||||
}
|
||||
// Accept interfaces without link-local or site-local addresses
|
||||
for(NetworkInterface iface : ifaces) {
|
||||
for(InetAddress a : Collections.list(iface.getInetAddresses())) {
|
||||
if(addr != null && a.equals(addr)) continue;
|
||||
if(a.isLoopbackAddress()) continue;
|
||||
boolean link = a.isLinkLocalAddress();
|
||||
boolean site = a.isSiteLocalAddress();
|
||||
if(!link && !site) addrs.add(new InetSocketAddress(a, 0));
|
||||
}
|
||||
}
|
||||
return addrs;
|
||||
}
|
||||
|
||||
public boolean supportsInvitations() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DuplexTransportConnection sendInvitation(PseudoRandom r,
|
||||
long timeout) {
|
||||
synchronized(this) {
|
||||
@@ -48,7 +115,7 @@ class LanSocketPlugin extends SimpleSocketPlugin {
|
||||
// Bind a multicast socket for receiving packets
|
||||
MulticastSocket ms = null;
|
||||
try {
|
||||
InetAddress iface = chooseInterface(true);
|
||||
InetAddress iface = chooseInterface();
|
||||
ms = new MulticastSocket(mcast.getPort());
|
||||
ms.setInterface(iface);
|
||||
ms.joinGroup(mcast.getAddress());
|
||||
@@ -75,7 +142,7 @@ class LanSocketPlugin extends SimpleSocketPlugin {
|
||||
try {
|
||||
// Connect back on the advertised TCP port
|
||||
Socket s = new Socket(packet.getAddress(), port);
|
||||
return new SocketTransportConnection(s);
|
||||
return new TcpTransportConnection(s);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
LOG.warning(e.toString());
|
||||
@@ -99,6 +166,35 @@ class LanSocketPlugin extends SimpleSocketPlugin {
|
||||
return null;
|
||||
}
|
||||
|
||||
private InetAddress chooseInterface() throws IOException {
|
||||
List<NetworkInterface> ifaces =
|
||||
Collections.list(NetworkInterface.getNetworkInterfaces());
|
||||
// Prefer an interface with a link-local or site-local address
|
||||
for(NetworkInterface iface : ifaces) {
|
||||
for(InetAddress addr : Collections.list(iface.getInetAddresses())) {
|
||||
if(addr.isLoopbackAddress()) continue;
|
||||
boolean link = addr.isLinkLocalAddress();
|
||||
boolean site = addr.isSiteLocalAddress();
|
||||
if(link || site) {
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info("Preferring " + addr.getHostAddress());
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Accept an interface without a link-local or site-local address
|
||||
for(NetworkInterface iface : ifaces) {
|
||||
for(InetAddress addr : Collections.list(iface.getInetAddresses())) {
|
||||
if(addr.isLoopbackAddress()) continue;
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info("Accepting " + addr.getHostAddress());
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
// No suitable interfaces
|
||||
return null;
|
||||
}
|
||||
|
||||
private void tryToClose(MulticastSocket ms, InetAddress addr) {
|
||||
try {
|
||||
ms.leaveGroup(addr);
|
||||
@@ -139,7 +235,6 @@ class LanSocketPlugin extends SimpleSocketPlugin {
|
||||
return ByteUtils.readUint16(b, off);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DuplexTransportConnection acceptInvitation(PseudoRandom r,
|
||||
long timeout) {
|
||||
synchronized(this) {
|
||||
@@ -150,7 +245,7 @@ class LanSocketPlugin extends SimpleSocketPlugin {
|
||||
// Bind a TCP socket for receiving connections
|
||||
ServerSocket ss = null;
|
||||
try {
|
||||
InetAddress iface = chooseInterface(true);
|
||||
InetAddress iface = chooseInterface();
|
||||
ss = new ServerSocket();
|
||||
ss.bind(new InetSocketAddress(iface, 0));
|
||||
} catch(IOException e) {
|
||||
@@ -161,7 +256,7 @@ class LanSocketPlugin extends SimpleSocketPlugin {
|
||||
// Bind a multicast socket for sending packets
|
||||
MulticastSocket ms = null;
|
||||
try {
|
||||
InetAddress iface = chooseInterface(true);
|
||||
InetAddress iface = chooseInterface();
|
||||
ms = new MulticastSocket();
|
||||
ms.setInterface(iface);
|
||||
} catch(IOException e) {
|
||||
@@ -185,7 +280,7 @@ class LanSocketPlugin extends SimpleSocketPlugin {
|
||||
try {
|
||||
int wait = (int) (Math.min(end, nextPacket) - now);
|
||||
ss.setSoTimeout(wait < 1 ? 1 : wait);
|
||||
return new SocketTransportConnection(ss.accept());
|
||||
return new TcpTransportConnection(ss.accept());
|
||||
} catch(SocketTimeoutException e) {
|
||||
now = System.currentTimeMillis();
|
||||
if(now < end) {
|
||||
@@ -1,13 +1,17 @@
|
||||
package net.sf.briar.plugins.socket;
|
||||
package net.sf.briar.plugins.tcp;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
@@ -19,10 +23,10 @@ import net.sf.briar.api.plugins.duplex.DuplexPlugin;
|
||||
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
|
||||
import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
|
||||
|
||||
abstract class SocketPlugin implements DuplexPlugin {
|
||||
abstract class TcpPlugin implements DuplexPlugin {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(SocketPlugin.class.getName());
|
||||
Logger.getLogger(TcpPlugin.class.getName());
|
||||
|
||||
protected final Executor pluginExecutor;
|
||||
protected final DuplexPluginCallback callback;
|
||||
@@ -30,16 +34,15 @@ abstract class SocketPlugin implements DuplexPlugin {
|
||||
private final long pollingInterval;
|
||||
|
||||
protected boolean running = false; // Locking: this
|
||||
protected ServerSocket socket = null; // Locking: this
|
||||
private ServerSocket socket = null; // Locking: this
|
||||
|
||||
protected abstract void setLocalSocketAddress(SocketAddress s);
|
||||
/**
|
||||
* Returns zero or more socket addresses on which the plugin should listen,
|
||||
* in order of preference. At most one of the addresses will be bound.
|
||||
*/
|
||||
protected abstract List<SocketAddress> getLocalSocketAddresses();
|
||||
|
||||
protected abstract Socket createClientSocket() throws IOException;
|
||||
protected abstract ServerSocket createServerSocket() throws IOException;
|
||||
protected abstract SocketAddress getLocalSocketAddress();
|
||||
protected abstract SocketAddress getRemoteSocketAddress(ContactId c);
|
||||
|
||||
protected SocketPlugin(@PluginExecutor Executor pluginExecutor,
|
||||
protected TcpPlugin(@PluginExecutor Executor pluginExecutor,
|
||||
DuplexPluginCallback callback, long pollingInterval) {
|
||||
this.pluginExecutor = pluginExecutor;
|
||||
this.callback = callback;
|
||||
@@ -58,21 +61,27 @@ abstract class SocketPlugin implements DuplexPlugin {
|
||||
}
|
||||
|
||||
private void bind() {
|
||||
SocketAddress addr;
|
||||
ServerSocket ss = null;
|
||||
ServerSocket ss;
|
||||
try {
|
||||
addr = getLocalSocketAddress();
|
||||
ss = createServerSocket();
|
||||
ss = new ServerSocket();
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
return;
|
||||
}
|
||||
if(addr == null || ss == null) return;
|
||||
try {
|
||||
ss.bind(addr);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
tryToClose(ss);
|
||||
boolean found = false;
|
||||
for(SocketAddress addr : getLocalSocketAddresses()) {
|
||||
try {
|
||||
ss.bind(addr);
|
||||
found = true;
|
||||
break;
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
tryToClose(ss);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Could not bind server socket");
|
||||
return;
|
||||
}
|
||||
synchronized(this) {
|
||||
@@ -98,6 +107,15 @@ abstract class SocketPlugin implements DuplexPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
private void setLocalSocketAddress(SocketAddress s) {
|
||||
InetSocketAddress i = (InetSocketAddress) s;
|
||||
InetAddress addr = i.getAddress();
|
||||
TransportProperties p = new TransportProperties();
|
||||
p.put("address", addr.getHostAddress());
|
||||
p.put("port", String.valueOf(i.getPort()));
|
||||
callback.mergeLocalProperties(p);
|
||||
}
|
||||
|
||||
private void acceptContactConnections(ServerSocket ss) {
|
||||
while(true) {
|
||||
Socket s;
|
||||
@@ -109,7 +127,7 @@ abstract class SocketPlugin implements DuplexPlugin {
|
||||
tryToClose(ss);
|
||||
return;
|
||||
}
|
||||
SocketTransportConnection conn = new SocketTransportConnection(s);
|
||||
TcpTransportConnection conn = new TcpTransportConnection(s);
|
||||
callback.incomingConnectionCreated(conn);
|
||||
synchronized(this) {
|
||||
if(!running) return;
|
||||
@@ -138,7 +156,7 @@ abstract class SocketPlugin implements DuplexPlugin {
|
||||
if(!running) return;
|
||||
}
|
||||
Map<ContactId, TransportProperties> remote =
|
||||
callback.getRemoteProperties();
|
||||
callback.getRemoteProperties();
|
||||
for(final ContactId c : remote.keySet()) {
|
||||
if(connected.contains(c)) continue;
|
||||
pluginExecutor.execute(new Runnable() {
|
||||
@@ -160,13 +178,32 @@ abstract class SocketPlugin implements DuplexPlugin {
|
||||
}
|
||||
SocketAddress addr = getRemoteSocketAddress(c);
|
||||
try {
|
||||
Socket s = createClientSocket();
|
||||
Socket s = new Socket();
|
||||
if(addr == null || s == null) return null;
|
||||
s.connect(addr);
|
||||
return new SocketTransportConnection(s);
|
||||
return new TcpTransportConnection(s);
|
||||
} catch(IOException e) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private SocketAddress getRemoteSocketAddress(ContactId c) {
|
||||
TransportProperties p = callback.getRemoteProperties().get(c);
|
||||
if(p == null) return null;
|
||||
String addrString = p.get("address");
|
||||
String portString = p.get("port");
|
||||
if(addrString != null && portString != null) {
|
||||
try {
|
||||
InetAddress addr = InetAddress.getByName(addrString);
|
||||
int port = Integer.valueOf(portString);
|
||||
return new InetSocketAddress(addr, port);
|
||||
} catch(NumberFormatException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
} catch(UnknownHostException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.sf.briar.plugins.socket;
|
||||
package net.sf.briar.plugins.tcp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -7,11 +7,11 @@ import java.net.Socket;
|
||||
|
||||
import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
|
||||
|
||||
class SocketTransportConnection implements DuplexTransportConnection {
|
||||
class TcpTransportConnection implements DuplexTransportConnection {
|
||||
|
||||
private final Socket socket;
|
||||
|
||||
SocketTransportConnection(Socket socket) {
|
||||
TcpTransportConnection(Socket socket) {
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
98
src/net/sf/briar/plugins/tcp/WanTcpPlugin.java
Normal file
98
src/net/sf/briar/plugins/tcp/WanTcpPlugin.java
Normal file
@@ -0,0 +1,98 @@
|
||||
package net.sf.briar.plugins.tcp;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.sf.briar.api.TransportProperties;
|
||||
import net.sf.briar.api.crypto.PseudoRandom;
|
||||
import net.sf.briar.api.plugins.PluginExecutor;
|
||||
import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
|
||||
import net.sf.briar.api.plugins.duplex.DuplexTransportConnection;
|
||||
import net.sf.briar.api.protocol.TransportId;
|
||||
import net.sf.briar.util.StringUtils;
|
||||
|
||||
class WanTcpPlugin extends TcpPlugin {
|
||||
|
||||
public static final byte[] TRANSPORT_ID =
|
||||
StringUtils.fromHexString("58c66d999e492b85065924acfd739d80"
|
||||
+ "c65a62f87e5a4fc6c284f95908b9007d"
|
||||
+ "512a93ebf89bf68f50a29e96eebf97b6");
|
||||
|
||||
private static final TransportId ID = new TransportId(TRANSPORT_ID);
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(WanTcpPlugin.class.getName());
|
||||
|
||||
WanTcpPlugin(@PluginExecutor Executor pluginExecutor,
|
||||
DuplexPluginCallback callback, long pollingInterval) {
|
||||
super(pluginExecutor, callback, pollingInterval);
|
||||
}
|
||||
|
||||
public TransportId getId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<SocketAddress> getLocalSocketAddresses() {
|
||||
List<SocketAddress> addrs = new ArrayList<SocketAddress>();
|
||||
// Prefer a previously used address and port if available
|
||||
TransportProperties p = callback.getLocalProperties();
|
||||
String addrString = p.get("address");
|
||||
String portString = p.get("port");
|
||||
InetAddress addr = null;
|
||||
if(addrString != null && portString != null) {
|
||||
try {
|
||||
addr = InetAddress.getByName(addrString);
|
||||
int port = Integer.valueOf(portString);
|
||||
addrs.add(new InetSocketAddress(addr, port));
|
||||
addrs.add(new InetSocketAddress(addr, 0));
|
||||
} catch(NumberFormatException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
} catch(UnknownHostException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
}
|
||||
}
|
||||
List<NetworkInterface> ifaces;
|
||||
try {
|
||||
ifaces = Collections.list(NetworkInterface.getNetworkInterfaces());
|
||||
} catch(SocketException e) {
|
||||
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
|
||||
return addrs;
|
||||
}
|
||||
// Accept interfaces without link-local or site-local addresses
|
||||
for(NetworkInterface iface : ifaces) {
|
||||
for(InetAddress a : Collections.list(iface.getInetAddresses())) {
|
||||
if(addr != null && a.equals(addr)) continue;
|
||||
if(a.isLoopbackAddress()) continue;
|
||||
boolean link = a.isLinkLocalAddress();
|
||||
boolean site = a.isSiteLocalAddress();
|
||||
if(!link && !site) addrs.add(new InetSocketAddress(a, 0));
|
||||
}
|
||||
}
|
||||
return addrs;
|
||||
}
|
||||
|
||||
public boolean supportsInvitations() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public DuplexTransportConnection sendInvitation(PseudoRandom r,
|
||||
long timeout) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public DuplexTransportConnection acceptInvitation(PseudoRandom r,
|
||||
long timeout) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package net.sf.briar.plugins.socket;
|
||||
package net.sf.briar.plugins.tcp;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@@ -9,14 +9,13 @@ import net.sf.briar.api.plugins.duplex.DuplexPluginCallback;
|
||||
import net.sf.briar.api.plugins.duplex.DuplexPluginFactory;
|
||||
import android.content.Context;
|
||||
|
||||
public class SimpleSocketPluginFactory implements DuplexPluginFactory {
|
||||
public class WanTcpPluginFactory implements DuplexPluginFactory {
|
||||
|
||||
private static final long POLLING_INTERVAL = 5L * 60L * 1000L; // 5 mins
|
||||
private static final long POLLING_INTERVAL = 5L * 60L * 1000L; // 5 minutes
|
||||
|
||||
public DuplexPlugin createPlugin(@PluginExecutor Executor pluginExecutor,
|
||||
AndroidExecutor androidExecutor, Context appContext,
|
||||
DuplexPluginCallback callback) {
|
||||
return new SimpleSocketPlugin(pluginExecutor, callback,
|
||||
POLLING_INTERVAL);
|
||||
return new WanTcpPlugin(pluginExecutor, callback, POLLING_INTERVAL);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user