Search in sources :

Example 1 with NetStatusProtocolTesterBT

use of com.biglybt.plugin.net.netstatus.NetStatusProtocolTesterBT in project BiglyBT by BiglySoftware.

the class NetStatusPluginTester method run.

public void run(Core core) {
    final NetworkAdmin admin = NetworkAdmin.getSingleton();
    boolean checked_public = false;
    Set<InetAddress> public_addresses = new HashSet<>();
    InetAddress def_pa = admin.getDefaultPublicAddress();
    if (def_pa != null) {
        log("Default public address is " + def_pa.getHostAddress());
        addPublicAddress(public_addresses, def_pa);
        checked_public = true;
    }
    InetAddress[] bindable = admin.getBindableAddresses();
    String bindable_str = "";
    for (InetAddress b : bindable) {
        bindable_str += (bindable_str.length() == 0 ? "" : ", ") + b.getHostAddress();
    }
    log("Bindable addresses: " + bindable_str);
    if (doTest(TEST_NAT_PROXIES)) {
        checked_public = true;
        NetworkAdminNATDevice[] nat_devices = admin.getNATDevices(core);
        log(nat_devices.length + " NAT device" + (nat_devices.length == 1 ? "" : "s") + " found");
        for (int i = 0; i < nat_devices.length; i++) {
            NetworkAdminNATDevice device = nat_devices[i];
            InetAddress ext_address = device.getExternalAddress();
            addPublicAddress(public_addresses, ext_address);
            log("    " + device.getString());
        }
        NetworkAdminSocksProxy[] socks_proxies = admin.getSocksProxies();
        if (socks_proxies.length == 0) {
            log("No SOCKS proxy found");
        } else if (socks_proxies.length == 1) {
            log("One SOCKS proxy found");
        } else {
            log(socks_proxies.length + " SOCKS proxies found");
        }
        for (int i = 0; i < socks_proxies.length; i++) {
            NetworkAdminSocksProxy proxy = socks_proxies[i];
            log("    " + proxy.getString());
        }
        NetworkAdminHTTPProxy http_proxy = admin.getHTTPProxy();
        if (http_proxy == null) {
            log("No HTTP proxy found");
        } else {
            log("HTTP proxy found");
            log("    " + http_proxy.getString());
        }
    }
    InetAddress[] bind_addresses = admin.getAllBindAddresses(false);
    int num_binds = 0;
    for (int i = 0; i < bind_addresses.length; i++) {
        if (bind_addresses[i] != null) {
            num_binds++;
        }
    }
    if (num_binds == 0) {
        log("No explicit bind address set");
    } else {
        log(num_binds + " bind addresses");
        for (int i = 0; i < bind_addresses.length; i++) {
            if (bind_addresses[i] != null) {
                log("    " + bind_addresses[i].getHostAddress());
            }
        }
    }
    if (doTest(TEST_OUTBOUND)) {
        checked_public = true;
        NetworkAdminProtocol[] outbound_protocols = admin.getOutboundProtocols(core);
        if (outbound_protocols.length == 0) {
            log("No outbound protocols");
        } else {
            for (int i = 0; i < outbound_protocols.length; i++) {
                if (test_cancelled) {
                    return;
                }
                NetworkAdminProtocol protocol = outbound_protocols[i];
                log("Testing " + protocol.getName());
                try {
                    InetAddress public_address = protocol.test(null, new NetworkAdminProgressListener() {

                        @Override
                        public void reportProgress(String task) {
                            log("    " + task);
                        }
                    });
                    logSuccess("    Test successful");
                    addPublicAddress(public_addresses, public_address);
                } catch (Throwable e) {
                    logError("    Test failed", e);
                }
            }
        }
    }
    if (doTest(TEST_INBOUND)) {
        checked_public = true;
        NetworkAdminProtocol[] inbound_protocols = admin.getInboundProtocols(core);
        if (inbound_protocols.length == 0) {
            log("No inbound protocols");
        } else {
            for (int i = 0; i < inbound_protocols.length; i++) {
                if (test_cancelled) {
                    return;
                }
                NetworkAdminProtocol protocol = inbound_protocols[i];
                log("Testing " + protocol.getName());
                try {
                    InetAddress public_address = protocol.test(null, new NetworkAdminProgressListener() {

                        @Override
                        public void reportProgress(String task) {
                            log("    " + task);
                        }
                    });
                    logSuccess("    Test successful");
                    addPublicAddress(public_addresses, public_address);
                } catch (Throwable e) {
                    logError("    Test failed", e);
                    logInfo("    Check your port forwarding for " + protocol.getTypeString() + " " + protocol.getPort());
                }
            }
        }
    }
    if (checked_public) {
        if (public_addresses.size() == 0) {
            log("No public addresses found");
        } else {
            Iterator<InetAddress> it = public_addresses.iterator();
            log(public_addresses.size() + " public/external addresses found");
            while (it.hasNext()) {
                InetAddress pub_address = it.next();
                log("    " + pub_address.getHostAddress());
                try {
                    NetworkAdminASN asn = admin.lookupASN(pub_address);
                    log("    AS details: " + asn.getString());
                } catch (Throwable e) {
                    logError("    failed to lookup AS", e);
                }
            }
        }
    }
    String[][] services = { // directly referenced at index 0 below
    { "BiglyBT Website", Constants.URL_CLIENT_HOME }, { "Version Server", "http://" + Constants.VERSION_SERVER_V4 + "/?dee" }, { "Plugins Website", Constants.PLUGINS_WEB_SITE } };
    if (doTest(TEST_BIGLYBT_SERVICES)) {
        log("BiglyBT Services test");
        for (String[] service : services) {
            if (test_cancelled) {
                return;
            }
            try {
                URL url = new URL(service[1]);
                log("    " + service[0] + " - " + url.getHost());
                boolean is_https = url.getProtocol().equals("https");
                if (is_https) {
                    String[] host_bits = url.getHost().split("\\.");
                    String host_match = "." + host_bits[host_bits.length - 2] + "." + host_bits[host_bits.length - 1];
                    HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
                    con.setHostnameVerifier(new HostnameVerifier() {

                        @Override
                        public boolean verify(String host, SSLSession session) {
                            return (true);
                        }
                    });
                    con.setInstanceFollowRedirects(false);
                    con.setConnectTimeout(30 * 1000);
                    con.setReadTimeout(30 * 1000);
                    con.getResponseCode();
                    con.getInputStream();
                    Certificate[] certs = con.getServerCertificates();
                    if (certs == null || certs.length == 0) {
                        logError("        No certificates returned");
                    } else {
                        Certificate cert = certs[0];
                        java.security.cert.X509Certificate x509_cert;
                        if (cert instanceof java.security.cert.X509Certificate) {
                            x509_cert = (java.security.cert.X509Certificate) cert;
                        } else {
                            java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance("X.509");
                            x509_cert = (java.security.cert.X509Certificate) cf.generateCertificate(new ByteArrayInputStream(cert.getEncoded()));
                        }
                        log("        Certificate: " + x509_cert.getSubjectDN());
                        Collection<List<?>> alt_names = x509_cert.getSubjectAlternativeNames();
                        boolean match = false;
                        for (List<?> alt_name : alt_names) {
                            int type = ((Number) alt_name.get(0)).intValue();
                            if (type == 2) {
                                // DNS name
                                String dns_name = (String) alt_name.get(1);
                                if (dns_name.endsWith(host_match)) {
                                    match = true;
                                    break;
                                }
                            }
                        }
                        if (!match) {
                            logError("        Failed: Host '" + host_match + "' not found in certificate");
                        } else {
                            logSuccess("        Connection result: " + con.getResponseCode() + "/" + con.getResponseMessage());
                        }
                    }
                } else {
                    HttpURLConnection con = (HttpURLConnection) url.openConnection();
                    con.setInstanceFollowRedirects(false);
                    con.setConnectTimeout(30 * 1000);
                    con.setReadTimeout(30 * 1000);
                    if (con.getResponseCode() != 200) {
                        throw (new Exception("Connection failed: " + con.getResponseCode() + "/" + con.getResponseMessage()));
                    }
                    Map resp = BDecoder.decode(new BufferedInputStream(con.getInputStream(), 16 * 1024));
                    if (resp != null && resp.containsKey("version")) {
                        logSuccess("        Connection result: " + con.getResponseCode() + "/" + con.getResponseMessage());
                    } else {
                        logError("        Unexpected reply from server: " + resp);
                    }
                }
            } catch (Throwable e) {
                logError("        Failed: " + Debug.getNestedExceptionMessage(e));
            }
        }
    }
    if (doTest(TEST_PROXY_CONNECT)) {
        log("Indirect Connect test");
        try {
            URL target = new URL(services[0][1]);
            PluginProxy proxy = AEProxyFactory.getPluginProxy("Network Status test", target);
            if (proxy == null) {
                logError("    No plugin proxy available");
                logInfo("    For the plugin installer refer to the 'Tor Helper' plugin");
            } else {
                log("    Connecting to " + target.toExternalForm());
                HttpURLConnection con = (HttpURLConnection) proxy.getURL().openConnection(proxy.getProxy());
                if (con instanceof HttpsURLConnection) {
                    ((HttpsURLConnection) con).setHostnameVerifier(new HostnameVerifier() {

                        @Override
                        public boolean verify(String host, SSLSession session) {
                            return (true);
                        }
                    });
                }
                con.setRequestProperty("HOST", proxy.getURLHostRewrite());
                con.setInstanceFollowRedirects(false);
                con.setConnectTimeout(60 * 1000);
                con.setReadTimeout(30 * 1000);
                try {
                    int resp = con.getResponseCode();
                    if (con instanceof HttpsURLConnection) {
                        Certificate[] certs = ((HttpsURLConnection) con).getServerCertificates();
                        if (certs == null || certs.length == 0) {
                            logError("    No certificates returned");
                        } else {
                            Certificate cert = certs[0];
                            java.security.cert.X509Certificate x509_cert;
                            if (cert instanceof java.security.cert.X509Certificate) {
                                x509_cert = (java.security.cert.X509Certificate) cert;
                            } else {
                                java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance("X.509");
                                x509_cert = (java.security.cert.X509Certificate) cf.generateCertificate(new ByteArrayInputStream(cert.getEncoded()));
                            }
                            log("    Certificate: " + x509_cert.getSubjectDN());
                        }
                    }
                    if (resp == 200) {
                        logSuccess("    Connection result: " + con.getResponseCode() + "/" + con.getResponseMessage());
                    } else {
                        log("    Connection result: " + con.getResponseCode() + "/" + con.getResponseMessage());
                    }
                } finally {
                    proxy.setOK(true);
                }
            }
        } catch (Throwable e) {
            logError("    Failed: " + Debug.getNestedExceptionMessage(e));
            logError("    Check the logs for the 'Tor Helper Plugin' (Tools->Plugins->Log Views)");
        }
    }
    if (doTest(TEST_BT_CONNECT)) {
        log("Distributed protocol test");
        NetStatusProtocolTesterBT bt_test = plugin.getProtocolTester().runTest(new NetStatusProtocolTesterListener() {

            private List sessions = new ArrayList();

            @Override
            public void complete(NetStatusProtocolTesterBT tester) {
                log("Results", false);
                if (tester.getOutboundConnects() < 4) {
                    log("    insufficient outbound connects for analysis", false);
                    return;
                }
                int outgoing_seed_ok = 0;
                int outgoing_leecher_ok = 0;
                int outgoing_seed_bad = 0;
                int outgoing_leecher_bad = 0;
                int incoming_connect_ok = 0;
                for (int i = 0; i < sessions.size(); i++) {
                    NetStatusProtocolTesterBT.Session session = (NetStatusProtocolTesterBT.Session) sessions.get(i);
                    if (session.isOK()) {
                        if (session.isInitiator()) {
                            if (session.isSeed()) {
                                outgoing_seed_ok++;
                            } else {
                                outgoing_leecher_ok++;
                            }
                        } else {
                            incoming_connect_ok++;
                        }
                    } else {
                        if (session.isConnected()) {
                            if (session.isInitiator()) {
                                if (session.isSeed()) {
                                    outgoing_seed_bad++;
                                } else {
                                    outgoing_leecher_bad++;
                                }
                            } else {
                                incoming_connect_ok++;
                            }
                        }
                    }
                    log("  " + (session.isInitiator() ? "Outbound" : "Inbound") + "," + (session.isSeed() ? "Seed" : "Leecher") + "," + session.getProtocolString(), false);
                }
                boolean good = true;
                if (incoming_connect_ok == 0) {
                    logError("  No incoming connections received, likely NAT problems");
                    good = false;
                }
                if (outgoing_leecher_ok > 0 && outgoing_seed_ok == 0 && outgoing_seed_bad > 0) {
                    logError("  Outgoing seed connects appear to be failing while non-seeds succeed");
                    good = false;
                }
                if (good) {
                    logSuccess("    Test successful");
                }
            }

            @Override
            public void sessionAdded(NetStatusProtocolTesterBT.Session session) {
                synchronized (sessions) {
                    sessions.add(session);
                }
            }

            @Override
            public void log(String str, boolean detailed) {
                NetStatusPluginTester.this.log("  " + str, detailed);
            }

            @Override
            public void logError(String str) {
                NetStatusPluginTester.this.logError("  " + str);
            }

            @Override
            public void logError(String str, Throwable e) {
                NetStatusPluginTester.this.logError("  " + str, e);
            }
        });
        while (!bt_test.waitForCompletion(5000)) {
            if (isCancelled()) {
                bt_test.destroy();
                break;
            }
            log("    Status: " + bt_test.getStatus());
        }
    }
    if (doTest(TEST_IPV6)) {
        log("IPv6 test");
        InetAddress ipv6_address = admin.getDefaultPublicAddressV6();
        if (ipv6_address == null) {
            log("    No default public IPv6 address found");
        } else {
            log("    Default public IPv6 address: " + ipv6_address.getHostAddress());
            log("    Testing connectivity...");
            String res = VersionCheckClient.getSingleton().getExternalIpAddress(false, true, true);
            if (res != null && res.length() > 0) {
                logSuccess("        Connect succeeded, reported IPv6 address: " + res);
            } else {
                logError("        Connect failed");
            }
        }
    }
}
Also used : NetStatusProtocolTesterListener(com.biglybt.plugin.net.netstatus.NetStatusProtocolTesterListener) BufferedInputStream(java.io.BufferedInputStream) HostnameVerifier(javax.net.ssl.HostnameVerifier) ByteArrayInputStream(java.io.ByteArrayInputStream) InetAddress(java.net.InetAddress) HttpsURLConnection(javax.net.ssl.HttpsURLConnection) Certificate(java.security.cert.Certificate) PluginProxy(com.biglybt.core.proxy.AEProxyFactory.PluginProxy) URL(java.net.URL) HttpURLConnection(java.net.HttpURLConnection) SSLSession(javax.net.ssl.SSLSession) NetStatusProtocolTesterBT(com.biglybt.plugin.net.netstatus.NetStatusProtocolTesterBT) SSLSession(javax.net.ssl.SSLSession)

Aggregations

PluginProxy (com.biglybt.core.proxy.AEProxyFactory.PluginProxy)1 NetStatusProtocolTesterBT (com.biglybt.plugin.net.netstatus.NetStatusProtocolTesterBT)1 NetStatusProtocolTesterListener (com.biglybt.plugin.net.netstatus.NetStatusProtocolTesterListener)1 BufferedInputStream (java.io.BufferedInputStream)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 HttpURLConnection (java.net.HttpURLConnection)1 InetAddress (java.net.InetAddress)1 URL (java.net.URL)1 Certificate (java.security.cert.Certificate)1 HostnameVerifier (javax.net.ssl.HostnameVerifier)1 HttpsURLConnection (javax.net.ssl.HttpsURLConnection)1 SSLSession (javax.net.ssl.SSLSession)1