Package com.aelitis.azureus.plugins.net.netstatus.swt

Source Code of com.aelitis.azureus.plugins.net.netstatus.swt.NetStatusPluginTester

/*
* Created on Jan 31, 2008
* Created by Paul Gardner
*
* Copyright 2008 Vuze, Inc.  All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/


package com.aelitis.azureus.plugins.net.netstatus.swt;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.*;

import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.ui.swt.shells.CoreWaiterSWT;

import com.aelitis.azureus.core.AzureusCore;
import com.aelitis.azureus.core.AzureusCoreRunningListener;
import com.aelitis.azureus.core.networkmanager.admin.*;
import com.aelitis.azureus.plugins.net.netstatus.NetStatusPlugin;
import com.aelitis.azureus.plugins.net.netstatus.NetStatusProtocolTesterBT;
import com.aelitis.azureus.plugins.net.netstatus.NetStatusProtocolTesterListener;

public class
NetStatusPluginTester
{
  public static final int    TEST_PING_ROUTE    = 0x00000001;
  public static final int    TEST_NAT_PROXIES  = 0x00000002;
  public static final int    TEST_OUTBOUND    = 0x00000004;
  public static final int    TEST_INBOUND    = 0x00000008;
  public static final int    TEST_BT_CONNECT    = 0x00000010;

 
  private static final int  ROUTE_TIMEOUT  = 120*1000;

  private NetStatusPlugin    plugin;
  private int          test_types;
  private loggerProvider    logger;
 
  private volatile boolean  test_cancelled;
 
  public
  NetStatusPluginTester(
    NetStatusPlugin    _plugin,
    int          _test_types,
    loggerProvider    _logger )
  {
    plugin    = _plugin;
    test_types  = _test_types;
    logger    = _logger;
  }
 
  protected boolean
  doTest(
    int    type )
  {
    return((test_types & type ) != 0 );
  }
 
  public void
  run(AzureusCore core)
  {
    final NetworkAdmin  admin = NetworkAdmin.getSingleton();
   
    boolean  checked_public  = false;

    Set<InetAddress>  public_addresses = new HashSet<InetAddress>();
   
    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;
    }
   
    if ( doTest( TEST_PING_ROUTE )){
     
      log( "Testing routing for the following interfaces:" );
     
      NetworkAdminNetworkInterface[] interfaces = admin.getInterfaces();
     
      for (int i=0;i<interfaces.length;i++){
       
        NetworkAdminNetworkInterface  intf = interfaces[i];
       
        NetworkAdminNetworkInterfaceAddress[] addresses = intf.getAddresses();
       
        String  a_str = "";
       
        for (int j=0;j<addresses.length;j++){
         
          NetworkAdminNetworkInterfaceAddress address = addresses[j];
         
          InetAddress ia = address.getAddress();
         
          if ( ia.isLoopbackAddress() || ia instanceof Inet6Address ){
           
          }else{
           
            a_str += (a_str.length()==0?"":",") + ia.getHostAddress();
          }
        }
       
        if ( a_str.length() > 0 ){
         
          log( "    " + intf.getName() + "/" + intf.getDisplayName() + ": " + a_str );
        }
      }
     
      if ( admin.canPing()){
       
        log( "Running ping tests" );
       
        try{
          InetAddress  target_address = InetAddress.getByName( plugin.getPingTarget());
         
          final Map  active_pings = new HashMap();
         
          admin.pingTargets(
            target_address,
            ROUTE_TIMEOUT,
            new NetworkAdminRoutesListener()
            {
              private int  timeouts;
             
              public boolean
              foundNode(
                NetworkAdminNetworkInterfaceAddress    intf,
                NetworkAdminNode[]            route,
                int                    distance,
                int                    rtt )
              {
                if ( test_cancelled ){
                 
                  return( false );
                }
               
                synchronized( active_pings ){
                 
                  active_pings.put( intf, route );
                }
               
                log( "  " + intf.getAddress().getHostAddress() + " -> " + route[route.length-1].getAddress().getHostAddress());
               
                return( false );
              }
             
              public boolean
              timeout(
                NetworkAdminNetworkInterfaceAddress    intf,
                NetworkAdminNode[]            route,
                int                    distance )
              {
                if ( test_cancelled ){
                 
                  return( false );
                }
               
                log( "  " + intf.getAddress().getHostAddress() + " - timeout" );
               
                timeouts++;
               
                if ( timeouts >= 3 ){
                 
                  return( false );
                }
               
                return( true );
              }
            });
   
          if ( test_cancelled ){
           
            return;
          }
         
          int  num_routes = active_pings.size();
         
          if ( num_routes == 0 ){
           
            logError( "No active pings found!" );
           
          }else{
           
            log( "Found " + num_routes + " pings(s)" );
           
            Iterator it = active_pings.entrySet().iterator();
           
            while( it.hasNext()){
             
              Map.Entry entry = (Map.Entry)it.next();
             
              NetworkAdminNetworkInterfaceAddress address = (NetworkAdminNetworkInterfaceAddress)entry.getKey();
             
              NetworkAdminNode[]  route = (NetworkAdminNode[])entry.getValue();
             
              String  node_str = "";
             
              for (int i=0;i<route.length;i++){
               
                node_str += (i==0?"":",") + route[i].getAddress().getHostAddress();
              }
             
              log( "    " + address.getInterface().getName() + "/" + address.getAddress().getHostAddress() + " - " + node_str );
            }
          }
        }catch( Throwable e ){
         
          logError( "Pinging failed: " + Debug.getNestedExceptionMessage(e));
        }
      }else{
       
        logError( "Can't run ping test as not supported" );
      }
     
      if ( test_cancelled ){
       
        return;
      }
     
      if ( admin.canTraceRoute()){
       
        log( "Running trace route tests" );
       
        try{
          InetAddress  target_address = InetAddress.getByName( plugin.getPingTarget());
         
          final Map  active_routes = new HashMap();
         
          admin.getRoutes(
            target_address,
            ROUTE_TIMEOUT,
            new NetworkAdminRoutesListener()
            {
              private String  last_as = "";
             
              public boolean
              foundNode(
                NetworkAdminNetworkInterfaceAddress    intf,
                NetworkAdminNode[]            route,
                int                    distance,
                int                    rtt )
              {
                if ( test_cancelled ){
                 
                  return( false );
                }
               
                synchronized( active_routes ){
                 
                  active_routes.put( intf, route );
                }
               
                InetAddress ia = route[route.length-1].getAddress();
               
                String  as = "";
               
                if ( !ia.isLinkLocalAddress() && !ia.isSiteLocalAddress()){
                 
                  try{
                    NetworkAdminASN asn = admin.lookupASN( ia );
                   
                    as = asn.getString();
                   
                    if ( as.equals( last_as )){
                     
                      as = "";
                     
                    }else{
                     
                      last_as = as;
                    }
                  }catch( Throwable e ){
                   
                  }
                }
               
                log( "  " + intf.getAddress().getHostAddress() + " -> " + ia.getHostAddress() + " (hop=" + distance + ")" + (as.length()==0?"":( " - " + as )));
               
                return( true );
              }
             
              public boolean
              timeout(
                NetworkAdminNetworkInterfaceAddress    intf,
                NetworkAdminNode[]            route,
                int                    distance )
              {
                if ( test_cancelled ){
                 
                  return( false );
                }
               
                log( "  " + intf.getAddress().getHostAddress() + " - timeout (hop=" + distance + ")" );
   
                  // see if we're getting nowhere
               
                if ( route.length == 0 && distance >= 5 ){
               
                  logError( "    giving up, no responses" );
                 
                  return( false );
                }
               
                  // see if we've got far enough
               
                if ( route.length >= 5 && distance > 6 ){
                 
                  log( "    truncating, sufficient responses" );
   
                  return( false );
                }
               
                return( true );
              }
            });
   
          if ( test_cancelled ){
           
            return;
          }
         
          int  num_routes = active_routes.size();
         
          if ( num_routes == 0 ){
           
            logError( "No active routes found!" );
           
          }else{
           
            log( "Found " + num_routes + " route(s)" );
           
            Iterator it = active_routes.entrySet().iterator();
           
            while( it.hasNext()){
             
              Map.Entry entry = (Map.Entry)it.next();
             
              NetworkAdminNetworkInterfaceAddress address = (NetworkAdminNetworkInterfaceAddress)entry.getKey();
             
              NetworkAdminNode[]  route = (NetworkAdminNode[])entry.getValue();
             
              String  node_str = "";
             
              for (int i=0;i<route.length;i++){
               
                node_str += (i==0?"":",") + route[i].getAddress().getHostAddress();
              }
             
              log( "    " + address.getInterface().getName() + "/" + address.getAddress().getHostAddress() + " - " + node_str );
            }
          }
        }catch( Throwable e ){
         
          logError( "Route tracing failed: " + Debug.getNestedExceptionMessage(e));
        }
      }else{
         
        logError( "Can't run trace route test as not supported" );
      }
     
      if ( test_cancelled ){
       
        return;
      }
    }
   
    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()
                {
                  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()
                {
                  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 );
          }
        }
      }
    }
   
    if ( doTest( TEST_BT_CONNECT )){

      log( "Distributed protocol test" );
     
      NetStatusProtocolTesterBT bt_test =
        plugin.getProtocolTester().runTest(
       
          new NetStatusProtocolTesterListener()
          {
            private List  sessions = new ArrayList();
           
            public void
            complete(
              NetStatusProtocolTesterBT  tester )
            {
              log( "Results" );
             
              if ( tester.getOutboundConnects() < 4 ){
               
                log( "    insufficient outbound connects for analysis" );
               
                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());
              }
             
              if ( incoming_connect_ok == 0 ){
               
                logError( "  No incoming connections received, likely NAT problems" );
              }
             
              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" );
              }
            }
           
            public void
            sessionAdded(
              NetStatusProtocolTesterBT.Session  session )
            {
              synchronized( sessions ){
               
                sessions.add( session );
              }
            }
           
            public void
            log(
              String    str )
            {
              NetStatusPluginTester.this.log( "  " + str );
            }
           
            public void
            logError(
              String    str )
            {
              NetStatusPluginTester.this.logError( "  " + str );
            }
           
            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());
      }
    }
  }
 
  protected void
  addPublicAddress(
    Set<InetAddress>  addresses,
    InetAddress      address )
  {
    if ( address == null ){
     
      return;
    }
     
    if (   address.isAnyLocalAddress() ||
        address.isLoopbackAddress() ||
        address.isLinkLocalAddress()||
        address.isSiteLocalAddress()){
     
        return;
    }
   
    addresses.add( address );
  }
 
  public void
  cancel()
  {
    test_cancelled  = true;
  }
 
  public boolean
  isCancelled()
  {
    return( test_cancelled );
  }
 
  protected void
  log(
    String  str )
  {
    logger.log( str );
  }
 
  protected void
  logSuccess(
    String  str )
  {
    logger.logSuccess( str );
  }
 
  protected void
  logInfo(
    String  str )
  {
    logger.logInfo( str );
  }
 
  protected void
  log(
    String    str,
    Throwable  e )
  {
    logger.log( str + ": " + e.getLocalizedMessage());
  }
 
  protected void
  logError(
    String  str )
  {
    logger.logFailure( str );
  }
 
  protected void
  logError(
    String    str,
    Throwable  e )
  {
    logger.logFailure( str + ": " + e.getLocalizedMessage());
  }
 
  public interface
  loggerProvider
  {
    public void
    log(
      String  str );
   
    public void
    logSuccess(
      String  str );
   
    public void
    logInfo(
      String  str );
   
    public void
    logFailure(
      String  str );
  }
 
}
TOP

Related Classes of com.aelitis.azureus.plugins.net.netstatus.swt.NetStatusPluginTester

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.