From 1368e75183da8e70b8aace1debf4ed214d89a51d Mon Sep 17 00:00:00 2001 From: fireduck64 Date: Sat, 18 Jan 2020 10:13:17 -0800 Subject: [PATCH] Mostly working tor more --- WORKSPACE | 2 +- src/ChannelNode.java | 6 +++- src/NetworkExaminer.java | 70 +++++++++++++++++++++++++++++----------- src/PeerLink.java | 51 ++++++++++++++++++++++++++--- test/ChannelTest.java | 3 ++ 5 files changed, 107 insertions(+), 25 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 3933be3..15d78a1 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -70,7 +70,7 @@ pinned_maven_install() git_repository( name = "snowblossom", remote = "https://github.com/snowblossomcoin/snowblossom", - commit = "413cfa6863986f219f55325d18242c95e1540a4b", + commit = "454b5c52cf12366070515abc33d3b2fad0629d01", shallow_since = "1579208444 -0800" ) diff --git a/src/ChannelNode.java b/src/ChannelNode.java index 55a2dbe..3f34bba 100644 --- a/src/ChannelNode.java +++ b/src/ChannelNode.java @@ -152,7 +152,11 @@ else if (db_type.equals("lobstack")) channel_outsider_sender.start(); channel_subscriber.loadFromDB(); - local_peer_finder.start(); + + if (!net_ex.isTorOnly()) + { + local_peer_finder.start(); + } if (config.isSet("web_port")) { diff --git a/src/NetworkExaminer.java b/src/NetworkExaminer.java index 72bd0ac..94aa8a0 100644 --- a/src/NetworkExaminer.java +++ b/src/NetworkExaminer.java @@ -3,7 +3,9 @@ import duckutil.NetUtil; import java.net.InetAddress; import java.net.InterfaceAddress; +import java.net.SocketAddress; import java.net.NetworkInterface; +import java.net.InetSocketAddress; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; @@ -22,32 +24,40 @@ public class NetworkExaminer private String onion_host; private ChannelNode node; + private InetSocketAddress tor_http_relay; + + private final boolean tor_only; + public NetworkExaminer(ChannelNode node) { this.node = node; + + tor_only = node.getConfig().getBoolean("tor_only"); + updateHosts(); } - - // TODO - on failure of this, might want to use getAllAddresses(). // Any non-link-local ipv6 address is a good bet for IPV6. // Any non-private ipv4 address is also probably good. private void updateHosts() { + + if(!isTorOnly()) + { + try{ + ipv4_host = NetUtil.getUrlLine("http://ipv4-lookup.snowblossom.org/myip"); + } + catch(Throwable t){ipv4_host=null;} - try{ - ipv4_host = NetUtil.getUrlLine("http://ipv4-lookup.snowblossom.org/myip"); - } - catch(Throwable t){ipv4_host=null;} - - try{ - ipv6_host = NetUtil.getUrlLine("http://ipv6-lookup.snowblossom.org/myip"); - } - catch(Throwable t){ipv6_host=null;} + try{ + ipv6_host = NetUtil.getUrlLine("http://ipv6-lookup.snowblossom.org/myip"); + } + catch(Throwable t){ipv6_host=null;} - logger.info("IPV4: " + ipv4_host); - logger.info("IPV6: " + ipv6_host); + logger.info("IPV4: " + ipv4_host); + logger.info("IPV6: " + ipv6_host); + } if (node.getConfig().isSet("tor_advertise")) { @@ -62,14 +72,26 @@ private void updateHosts() } } - - try + if (node.getConfig().isSet("tor_http_relay")) { - tryUpnp(); + String[] split = node.getConfig().get("tor_http_relay").split(":"); + int port = Integer.parseInt(split[1]); + String host = split[0]; + + tor_http_relay = new InetSocketAddress(host, port); + logger.info("Tor HTTP relay: " + tor_http_relay); } - catch(Exception e) + + if (!isTorOnly()) { - logger.info("UPNP failure: " + e); + try + { + tryUpnp(); + } + catch(Exception e) + { + logger.info("UPNP failure: " + e); + } } } @@ -141,6 +163,18 @@ public Set getAllAddresses() public boolean hasIpv4() { return ipv4_host != null; } public boolean hasIpv6() { return ipv6_host != null; } + public boolean canConnectToIpv4() {return hasIpv4();} + public boolean canConnectToIpv6() {return hasIpv6();} + public boolean canConnectToTor() { return tor_http_relay!=null;} + + public InetSocketAddress getTorHttpRelay(){return tor_http_relay;} + + public boolean isTorOnly() + { + return tor_only; + } + + public ChannelPeerInfo createPeerInfo() { ChannelPeerInfo.Builder info = ChannelPeerInfo.newBuilder(); diff --git a/src/PeerLink.java b/src/PeerLink.java index 16b1e48..050111c 100644 --- a/src/PeerLink.java +++ b/src/PeerLink.java @@ -1,10 +1,16 @@ package snowblossom.channels; +import io.grpc.HttpConnectProxiedSocketAddress; import io.grpc.ManagedChannel; +import io.grpc.ProxiedSocketAddress; +import io.grpc.ProxyDetector; import io.grpc.netty.GrpcSslContexts; import io.grpc.netty.NettyChannelBuilder; import io.grpc.stub.StreamObserver; import io.netty.handler.ssl.SslContext; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -58,11 +64,17 @@ public PeerLink(ChannelPeerInfo info, ChannelNode node) .trustManager(SnowTrustManagerFactorySpi.getFactory(remote_node_id)) .build(); - channel = NettyChannelBuilder + NettyChannelBuilder chan_builder = NettyChannelBuilder .forAddress(conn_info.getHost(), conn_info.getPort()) .useTransportSecurity() - .sslContext(ssl_ctx) - .build(); + .sslContext(ssl_ctx); + + if (conn_info.getProtocol().equals("onion")) + { + chan_builder = chan_builder.proxyDetector(new OnionProxyDetector()); + } + + channel = chan_builder.build(); stargate_stub = StargateServiceGrpc.newStub(channel); stargate_blocking_stub = StargateServiceGrpc.newBlockingStub(channel); @@ -112,7 +124,7 @@ private ConnectInfo findConnectInfo() .build(); } - if (net_ex.hasIpv6()) + if (net_ex.canConnectToIpv6()) { ConnectInfo conn_info = info.getConnectInfosMap().get("ipv6"); if (conn_info != null) @@ -121,7 +133,7 @@ private ConnectInfo findConnectInfo() } } - if (net_ex.hasIpv4()) + if (net_ex.canConnectToIpv4()) { ConnectInfo conn_info = info.getConnectInfosMap().get("ipv4"); if (conn_info != null) @@ -129,6 +141,18 @@ private ConnectInfo findConnectInfo() return conn_info; } } + if (net_ex.canConnectToTor()) + { + ConnectInfo conn_info = info.getConnectInfosMap().get("onion"); + if (conn_info != null) { return conn_info; } + + // We can do anything via tor + conn_info = info.getConnectInfosMap().get("ipv6"); + if (conn_info != null) { return ConnectInfo.newBuilder().mergeFrom(conn_info).setProtocol("onion").build(); } + + conn_info = info.getConnectInfosMap().get("ipv4"); + if (conn_info != null) { return ConnectInfo.newBuilder().mergeFrom(conn_info).setProtocol("onion").build(); } + } return null; } @@ -186,5 +210,22 @@ public void onNext(PeerList peer_list) } } + /** + * Doesn't detect so much as just uses the proxy + */ + public class OnionProxyDetector implements ProxyDetector + { + @Override + public ProxiedSocketAddress proxyFor(SocketAddress targetServerAddress) + throws IOException + { + return HttpConnectProxiedSocketAddress.newBuilder() + .setProxyAddress(node.getNetworkExaminer().getTorHttpRelay()) + .setTargetAddress((InetSocketAddress) targetServerAddress) + .build(); + } + + } + } diff --git a/test/ChannelTest.java b/test/ChannelTest.java index 045e798..8adb81e 100644 --- a/test/ChannelTest.java +++ b/test/ChannelTest.java @@ -40,6 +40,9 @@ public void testChannelDB() node_a.getChannelDB(cid); } + // Give the DB a few seconds to settle + Thread.sleep(5000); + }