Add manual port forwarding support

This commit is contained in:
Manfred Karrer 2014-11-15 18:06:58 +01:00
parent 3811cabba1
commit dc464b36e4
7 changed files with 41 additions and 8 deletions

View File

@ -45,6 +45,8 @@ public class BitsquareAppMain extends BitsquareExecutable {
.defaultsTo(DEFAULT_APP_DATA_DIR);
parser.accepts(NAME_KEY, "Name of this node").withRequiredArg();
parser.accepts(PORT_KEY, "Port to listen on").withRequiredArg().ofType(int.class).defaultsTo(Node.DEFAULT_PORT);
parser.accepts(USE_MANUAL_PORT_FORWARDING_KEY, "Use manual port forwarding")
.withRequiredArg().ofType(boolean.class).defaultsTo(false);
parser.accepts(BitcoinNetwork.KEY).withRequiredArg().ofType(BitcoinNetwork.class)
.withValuesConvertedBy(new EnumValueConverter(BitcoinNetwork.class))
.defaultsTo(BitcoinNetwork.DEFAULT);

View File

@ -56,7 +56,6 @@ import net.tomp2p.peers.PeerAddress;
import net.tomp2p.peers.PeerMapChangeListener;
import net.tomp2p.peers.PeerStatistic;
import net.tomp2p.replication.IndirectReplication;
import net.tomp2p.utils.Utils;
import org.jetbrains.annotations.NotNull;
@ -73,9 +72,11 @@ class BootstrappedPeerFactory {
static final String BOOTSTRAP_NODE_KEY = "bootstrapNode";
static final String NETWORK_INTERFACE_KEY = "interface";
static final String NETWORK_INTERFACE_UNSPECIFIED = "<unspecified>";
static final String USE_MANUAL_PORT_FORWARDING_KEY = "node.useManualPortForwarding";
private KeyPair keyPair;
private final int port;
private boolean useManualPortForwarding;
private final Node bootstrapNode;
private final String networkInterface;
private final Persistence persistence;
@ -94,10 +95,12 @@ class BootstrappedPeerFactory {
@Inject
public BootstrappedPeerFactory(Persistence persistence,
@Named(Node.PORT_KEY) int port,
@Named(USE_MANUAL_PORT_FORWARDING_KEY) boolean useManualPortForwarding,
@Named(BOOTSTRAP_NODE_KEY) Node bootstrapNode,
@Named(NETWORK_INTERFACE_KEY) String networkInterface) {
this.persistence = persistence;
this.port = port;
this.useManualPortForwarding = useManualPortForwarding;
this.bootstrapNode = bootstrapNode;
this.networkInterface = networkInterface;
}
@ -120,12 +123,25 @@ class BootstrappedPeerFactory {
try {
setState(BootstrapState.PEER_CREATION, "We create a P2P node.");
Number160 peerId = Utils.makeSHAHash(keyPair.getPublic().getEncoded());
Bindings bindings = new Bindings();
if (!NETWORK_INTERFACE_UNSPECIFIED.equals(networkInterface))
bindings.addInterface(networkInterface);
peer = new PeerBuilder(keyPair).ports(port).bindings(bindings).start();
if (useManualPortForwarding) {
peer = new PeerBuilder(keyPair)
.ports(port)
.bindings(bindings)
.tcpPortForwarding(port)
.udpPortForwarding(port)
.start();
}
else {
peer = new PeerBuilder(keyPair)
.ports(port)
.bindings(bindings)
.start();
}
peerDHT = new PeerBuilderDHT(peer).start();
new IndirectReplication(peerDHT).start();
@ -203,8 +219,16 @@ class BootstrappedPeerFactory {
@Override
public void operationComplete(BaseFuture future) throws Exception {
if (future.isSuccess()) {
setState(BootstrapState.DIRECT_SUCCESS, "We are directly connected and visible to other peers.");
bootstrap(BootstrapState.DIRECT_SUCCESS);
if (useManualPortForwarding) {
setState(BootstrapState.MANUAL_PORT_FORWARDING_SUCCESS,
"We use manual port forwarding and are visible to other peers.");
bootstrap(BootstrapState.MANUAL_PORT_FORWARDING_SUCCESS);
}
else {
setState(BootstrapState.DIRECT_SUCCESS,
"We are directly connected and visible to other peers.");
bootstrap(BootstrapState.DIRECT_SUCCESS);
}
}
else {
setState(BootstrapState.DIRECT_NOT_SUCCEEDED, "We are probably behind a NAT and not reachable to " +

View File

@ -37,6 +37,7 @@ public class TomP2PMessageModule extends MessageModule {
public static final String BOOTSTRAP_NODE_IP_KEY = "bootstrap.node.ip";
public static final String BOOTSTRAP_NODE_PORT_KEY = "bootstrap.node.port";
public static final String NETWORK_INTERFACE_KEY = BootstrappedPeerFactory.NETWORK_INTERFACE_KEY;
public static final String USE_MANUAL_PORT_FORWARDING_KEY = BootstrappedPeerFactory.USE_MANUAL_PORT_FORWARDING_KEY;
public TomP2PMessageModule(Environment env) {
super(env);
@ -45,7 +46,10 @@ public class TomP2PMessageModule extends MessageModule {
@Override
protected void doConfigure() {
bind(int.class).annotatedWith(Names.named(Node.PORT_KEY)).toInstance(
env.getProperty(Node.PORT_KEY, Integer.class, Node.DEFAULT_PORT));
env.getProperty(Node.PORT_KEY, int.class, Node.DEFAULT_PORT));
bind(boolean.class).annotatedWith(Names.named(USE_MANUAL_PORT_FORWARDING_KEY)).toInstance(
env.getProperty(USE_MANUAL_PORT_FORWARDING_KEY, boolean.class, false));
bind(TomP2PNode.class).in(Singleton.class);
bind(ClientNode.class).to(TomP2PNode.class);

View File

@ -380,6 +380,8 @@ public class TomP2PNode implements ClientNode {
switch (bootstrapState) {
case DIRECT_SUCCESS:
return ConnectionType.DIRECT;
case MANUAL_PORT_FORWARDING_SUCCESS:
return ConnectionType.MANUAL_PORT_FORWARDING;
case NAT_SUCCESS:
return ConnectionType.NAT;
case RELAY_SUCCESS:

View File

@ -27,6 +27,7 @@ public enum BootstrapState {
DIRECT_SUCCESS,
DIRECT_NOT_SUCCEEDED,
DIRECT_FAILED,
MANUAL_PORT_FORWARDING_SUCCESS,
NAT_INIT,
NAT_SETUP_DONE,
NAT_SUCCESS,

View File

@ -18,5 +18,5 @@
package io.bitsquare.network;
public enum ConnectionType {
UNKNOWN, DIRECT, NAT, RELAY
UNKNOWN, DIRECT, MANUAL_PORT_FORWARDING, NAT, RELAY
}

View File

@ -22,7 +22,7 @@ import com.google.common.base.Objects;
public final class Node {
public static final String NAME_KEY = "node.name";
public static final String PORT_KEY = "node.port";
/**
* Default port is one <a
* href="https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?&page=103">