Changeset 17a1b11


Ignore:
Timestamp:
Apr 10, 2004 11:45:02 AM (17 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
51c49d7c
Parents:
8a8e681
git-author:
shendaras <shendaras> (04/10/04 11:45:02)
git-committer:
zzz <zzz@…> (04/10/04 11:45:02)
Message:

beginning of format, updated imports. (shendaras)

Location:
apps
Files:
36 edited

Legend:

Unmodified
Added
Removed
  • apps/heartbeat/java/src/net/i2p/heartbeat/ClientEngine.java

    r8a8e681 r17a1b11  
    2525    private int _id;
    2626    private static PeerDataWriter writer = new PeerDataWriter();
    27            
     27
    2828    /**
    2929     * Create a new engine that will send its pings through the given heartbeat
     
    3333     */
    3434    public ClientEngine(Heartbeat heartbeat, ClientConfig config) {
    35         _heartbeat = heartbeat;
    36         _data = new PeerData(config);
    37         _active = false;
    38         _id = ++__id;
     35        _heartbeat = heartbeat;
     36        _data = new PeerData(config);
     37        _active = false;
     38        _id = ++__id;
    3939    }
    40    
     40
    4141    /** stop sending any more pings or writing any more state */
    4242    public void stopEngine() {
    43         _active = false;
    44         if (_log.shouldLog(Log.INFO))
    45             _log.info("Stopping engine talking to peer " + _data.getConfig().getPeer().calculateHash().toBase64());
     43        _active = false;
     44        if (_log.shouldLog(Log.INFO))
     45            _log.info("Stopping engine talking to peer " + _data.getConfig().getPeer().calculateHash().toBase64());
    4646    }
     47
    4748    /** start up the test (this does not block, as it fires up the test thread) */
    4849    public void startEngine() {
    49         _active = true;
    50         I2PThread t = new I2PThread(new ClientRunner());
    51         t.setName("HeartbeatClient " + _id);
    52         t.start();
     50        _active = true;
     51        I2PThread t = new I2PThread(new ClientRunner());
     52        t.setName("HeartbeatClient " + _id);
     53        t.start();
    5354    }
     55
    5456    /**
    5557     * Who are we testing?
    5658     * @return the Destination (peer) we're testing
    5759     */
    58     public Destination getPeer() { return _data.getConfig().getPeer(); }
     60    public Destination getPeer() {
     61        return _data.getConfig().getPeer();
     62    }
    5963
    6064    /**
     
    6266     * @return the series identifier
    6367     */
    64     public int getSeriesNum() { return _id; }
     68    public int getSeriesNum() {
     69        return _id;
     70    }
    6571
    6672    /**
     
    7278     */
    7379    public void receivePong(long sentOn, long replyOn) {
    74         _data.pongReceived(sentOn, replyOn);
     80        _data.pongReceived(sentOn, replyOn);
    7581    }
    76  
     82
    7783    /** fire off a new ping */
    7884    private void doSend() {
    79         long now = Clock.getInstance().now();
    80         _heartbeat.sendPing(_data.getConfig().getPeer(), _id, now, _data.getConfig().getSendSize());
    81         _data.addPing(now);
     85        long now = Clock.getInstance().now();
     86        _heartbeat.sendPing(_data.getConfig().getPeer(), _id, now, _data.getConfig().getSendSize());
     87        _data.addPing(now);
    8288    }
    83    
     89
    8490    /** our actual heartbeat pumper - this drives the test */
    8591    private class ClientRunner implements Runnable {
    86        
    87     /* (non-Javadoc)
    88          * @see java.lang.Runnable#run()
    89          */
    90         public void run() {
    91             if (_log.shouldLog(Log.INFO))
    92                 _log.info("Starting engine talking to peer " + _data.getConfig().getPeer().calculateHash().toBase64());
    93            
    94             // when do we need to send the next PING?
    95             long nextSend = Clock.getInstance().now();
    96             // when do we need to write out the next state data?
    97             long nextWrite = Clock.getInstance().now();
    98            
    99             while (_active) {
    100                
    101                 if (Clock.getInstance().now() >= nextSend) {
    102                     doSend();
    103                     nextSend = Clock.getInstance().now() + _data.getConfig().getSendFrequency()*1000;
    104                 }
    105                
    106                 if (Clock.getInstance().now() >= nextWrite) {
    107                     boolean written = writer.persist(_data);
    108                     if (!written) {
    109                         if (_log.shouldLog(Log.ERROR))
    110                             _log.error("Unable to write the client state data");
    111                     } else {
    112                         if (_log.shouldLog(Log.DEBUG))
    113                             _log.debug("Client state data written");
    114                     }
    115                 }
    116                
    117                 _data.cleanup();
    118                
    119                 try { Thread.sleep(1000); } catch (InterruptedException ie) {}
    120             }
    121         }
     92
     93        /* (non-Javadoc)
     94         * @see java.lang.Runnable#run()
     95         */
     96        public void run() {
     97            if (_log.shouldLog(Log.INFO))
     98                _log.info("Starting engine talking to peer " + _data.getConfig().getPeer().calculateHash().toBase64());
     99
     100            // when do we need to send the next PING?
     101            long nextSend = Clock.getInstance().now();
     102            // when do we need to write out the next state data?
     103            long nextWrite = Clock.getInstance().now();
     104
     105            while (_active) {
     106
     107                if (Clock.getInstance().now() >= nextSend) {
     108                    doSend();
     109                    nextSend = Clock.getInstance().now() + _data.getConfig().getSendFrequency() * 1000;
     110                }
     111
     112                if (Clock.getInstance().now() >= nextWrite) {
     113                    boolean written = writer.persist(_data);
     114                    if (!written) {
     115                        if (_log.shouldLog(Log.ERROR)) _log.error("Unable to write the client state data");
     116                    } else {
     117                        if (_log.shouldLog(Log.DEBUG)) _log.debug("Client state data written");
     118                    }
     119                }
     120
     121                _data.cleanup();
     122
     123                try {
     124                    Thread.sleep(1000);
     125                } catch (InterruptedException ie) {
     126                }
     127            }
     128        }
    122129    }
    123130}
  • apps/heartbeat/java/src/net/i2p/heartbeat/Heartbeat.java

    r8a8e681 r17a1b11  
    5656 *
    5757 */
    58 public class Heartbeat  {
     58public class Heartbeat {
    5959    private static final Log _log = new Log(Heartbeat.class);
    6060    /** location containing this heartbeat's config */
     
    6868    /** our own callback that the I2PAdapter notifies on ping or pong messages */
    6969    private PingPongAdapter _eventAdapter;
    70    
     70
    7171    /** if there are no command line arguments, load the config from "heartbeat.config" */
    7272    public static final String CONFIG_FILE_DEFAULT = "heartbeat.config";
    73    
     73
    7474    /**
    7575     * build up a new heartbeat manager, but don't actually do anything
     
    7777     */
    7878    public Heartbeat(String configFile) {
    79         _configFile = configFile;
    80         _clientConfigs = new HashMap();
    81         _clientEngines = new HashMap();
    82         _eventAdapter = new PingPongAdapter();
    83         _adapter = new I2PAdapter();
    84         _adapter.setListener(_eventAdapter);
    85     }
    86     private Heartbeat() {}
    87    
     79        _configFile = configFile;
     80        _clientConfigs = new HashMap();
     81        _clientEngines = new HashMap();
     82        _eventAdapter = new PingPongAdapter();
     83        _adapter = new I2PAdapter();
     84        _adapter.setListener(_eventAdapter);
     85    }
     86
     87    private Heartbeat() {
     88    }
     89
    8890    /** load up the config data (but don't build any engines or start them up) */
    8991    public void loadConfig() {
    90         Properties props = new Properties();
    91         FileInputStream fin = null;
    92         File configFile = new File (_configFile);
    93         if (configFile.exists()) {
    94             try {
    95                 fin = new FileInputStream(_configFile);
    96                 props.load(fin);
    97             } catch (IOException ioe) {
    98                 if (_log.shouldLog(Log.ERROR)) {
    99                     _log.error("Error reading the config data", ioe);
    100         }
    101             } finally {
    102                 if (fin != null) try { fin.close(); } catch (IOException ioe) {}
    103             }
    104         }
    105        
    106         loadBaseConfig(props);
    107         loadClientConfigs(props);
    108     }
    109    
    110    
     92        Properties props = new Properties();
     93        FileInputStream fin = null;
     94        File configFile = new File(_configFile);
     95        if (configFile.exists()) {
     96            try {
     97                fin = new FileInputStream(_configFile);
     98                props.load(fin);
     99            } catch (IOException ioe) {
     100                if (_log.shouldLog(Log.ERROR)) {
     101                    _log.error("Error reading the config data", ioe);
     102                }
     103            } finally {
     104                if (fin != null) try {
     105                    fin.close();
     106                } catch (IOException ioe) {
     107                }
     108            }
     109        }
     110
     111        loadBaseConfig(props);
     112        loadClientConfigs(props);
     113    }
     114
    111115    /**
    112116     * send a ping message to the peer
     
    118122     */
    119123    void sendPing(Destination peer, int seriesNum, long now, int size) {
    120         if (_adapter.getIsConnected())
    121             _adapter.sendPing(peer, seriesNum, now, size);
    122     }
    123    
     124        if (_adapter.getIsConnected()) _adapter.sendPing(peer, seriesNum, now, size);
     125    }
     126
    124127    /**
    125128     * load up the base data (I2CP config, etc)
     
    127130     */
    128131    private void loadBaseConfig(Properties props) {
    129         _adapter.loadConfig(props);
    130     }
    131    
     132        _adapter.loadConfig(props);
     133    }
     134
    132135    /**
    133136     * load up all of the test config data
     
    135138     * */
    136139    private void loadClientConfigs(Properties props) {
    137         int i = 0;
    138         while (true) {
    139             ClientConfig config = new ClientConfig();
    140             if (!config.load(props, i)) {
    141                     break;
    142         }
    143             _clientConfigs.put(new Integer(i), config);
    144             i++;
    145         }
     140        int i = 0;
     141        while (true) {
     142            ClientConfig config = new ClientConfig();
     143            if (!config.load(props, i)) {
     144                break;
     145            }
     146            _clientConfigs.put(new Integer(i), config);
     147            i++;
     148        }
    146149    }
    147150
    148151    /** connect to the network */
    149152    private void connect() {
    150         boolean connected = _adapter.connect();
    151         if (!connected)
    152             _log.error("Unable to connect to the router");
    153     }
     153        boolean connected = _adapter.connect();
     154        if (!connected) _log.error("Unable to connect to the router");
     155    }
     156
    154157    /** disconnect from the network */
    155158    private void disconnect() {
    156         _adapter.disconnect();
    157     }
    158    
     159        _adapter.disconnect();
     160    }
     161
    159162    /** start up all of the tests */
    160163    public void startEngines() {
    161         for (Iterator iter = _clientConfigs.values().iterator(); iter.hasNext(); ) {
    162             ClientConfig config = (ClientConfig)iter.next();
    163             ClientEngine engine = new ClientEngine(this, config);
    164             config.setUs(_adapter.getLocalDestination());
    165             config.setNumHops(_adapter.getNumHops());
    166             _clientEngines.put(new Integer(engine.getSeriesNum()), engine);
    167             engine.startEngine();
    168         }
    169     }
     164        for (Iterator iter = _clientConfigs.values().iterator(); iter.hasNext();) {
     165            ClientConfig config = (ClientConfig) iter.next();
     166            ClientEngine engine = new ClientEngine(this, config);
     167            config.setUs(_adapter.getLocalDestination());
     168            config.setNumHops(_adapter.getNumHops());
     169            _clientEngines.put(new Integer(engine.getSeriesNum()), engine);
     170            engine.startEngine();
     171        }
     172    }
     173
    170174    /** stop all of the tests */
    171175    public void stopEngines() {
    172         for (Iterator iter = _clientEngines.values().iterator(); iter.hasNext(); ) {
    173             ClientEngine engine = (ClientEngine)iter.next();
    174             engine.stopEngine();
    175         }
    176         _clientEngines.clear();
    177     }
    178    
     176        for (Iterator iter = _clientEngines.values().iterator(); iter.hasNext();) {
     177            ClientEngine engine = (ClientEngine) iter.next();
     178            engine.stopEngine();
     179        }
     180        _clientEngines.clear();
     181    }
     182
    179183    /**
    180184     * Fire up a new heartbeat system, waiting until, well, forever.  Builds
     
    187191     */
    188192    public static void main(String args[]) {
    189         String configFile = CONFIG_FILE_DEFAULT;
    190         if (args.length == 1) {
    191             configFile = args[0];
    192     }
    193        
    194         if (_log.shouldLog(Log.INFO)) {
    195             _log.info("Starting up with config file " + configFile);
    196     }
    197         Heartbeat heartbeat = new Heartbeat(configFile);
    198         heartbeat.loadConfig();
    199         heartbeat.connect();
    200         heartbeat.startEngines();
    201         Object o = new Object();
    202         while (true) {
    203             try {
    204                 synchronized (o) {
    205                     o.wait();
    206                 }
    207             } catch (InterruptedException ie) {}
    208         }
    209     }
    210  
     193        String configFile = CONFIG_FILE_DEFAULT;
     194        if (args.length == 1) {
     195            configFile = args[0];
     196        }
     197
     198        if (_log.shouldLog(Log.INFO)) {
     199            _log.info("Starting up with config file " + configFile);
     200        }
     201        Heartbeat heartbeat = new Heartbeat(configFile);
     202        heartbeat.loadConfig();
     203        heartbeat.connect();
     204        heartbeat.startEngines();
     205        Object o = new Object();
     206        while (true) {
     207            try {
     208                synchronized (o) {
     209                    o.wait();
     210                }
     211            } catch (InterruptedException ie) {
     212            }
     213        }
     214    }
     215
    211216    /**
    212217     * Receive event notification from the I2PAdapter
     
    214219     */
    215220    private class PingPongAdapter implements I2PAdapter.PingPongEventListener {
    216         /**
    217         * We were pinged, so always just send a pong back.
    218         *
    219         * @param from who sent us the ping?
    220         * @param seriesNum what series did the sender specify?
    221         * @param sentOn when did the sender say they sent their ping?
    222         * @param data arbitrary payload data
    223         */
    224         public void receivePing(Destination from, int seriesNum, Date sentOn, byte[] data) {
    225             if (_adapter.getIsConnected()) {
    226                     _adapter.sendPong(from, seriesNum, sentOn, data);
    227         }
    228         }
    229 
    230         /**
    231         * We received a pong, so find the right client engine and tell it about the pong.
    232         *
    233         * @param from who sent us the pong
    234         * @param seriesNum our client ID
    235         * @param sentOn when did we send the ping?
    236         * @param replyOn when did they send their pong?
    237         * @param data the arbitrary data we sent in the ping (that they sent back in the pong)
    238         */
    239         public void receivePong(Destination from, int seriesNum, Date sentOn, Date replyOn, byte[] data) {
    240             ClientEngine engine = (ClientEngine)_clientEngines.get(new Integer(seriesNum));
    241             if (engine.getPeer().equals(from)) {
    242                     engine.receivePong(sentOn.getTime(), replyOn.getTime());
    243         }
    244         }
    245     }
    246    
     221        /**
     222        * We were pinged, so always just send a pong back.
     223        *
     224        * @param from who sent us the ping?
     225        * @param seriesNum what series did the sender specify?
     226        * @param sentOn when did the sender say they sent their ping?
     227        * @param data arbitrary payload data
     228        */
     229        public void receivePing(Destination from, int seriesNum, Date sentOn, byte[] data) {
     230            if (_adapter.getIsConnected()) {
     231                _adapter.sendPong(from, seriesNum, sentOn, data);
     232            }
     233        }
     234
     235        /**
     236        * We received a pong, so find the right client engine and tell it about the pong.
     237        *
     238        * @param from who sent us the pong
     239        * @param seriesNum our client ID
     240        * @param sentOn when did we send the ping?
     241        * @param replyOn when did they send their pong?
     242        * @param data the arbitrary data we sent in the ping (that they sent back in the pong)
     243        */
     244        public void receivePong(Destination from, int seriesNum, Date sentOn, Date replyOn, byte[] data) {
     245            ClientEngine engine = (ClientEngine) _clientEngines.get(new Integer(seriesNum));
     246            if (engine.getPeer().equals(from)) {
     247                engine.receivePong(sentOn.getTime(), replyOn.getTime());
     248            }
     249        }
     250    }
     251
    247252}
  • apps/heartbeat/java/src/net/i2p/heartbeat/I2PAdapter.java

    r8a8e681 r17a1b11  
    6262    /** by default, the I2CP port is 7654 */
    6363    private static final int I2CP_PORT_DEFAULT = 7654;
    64    
     64
    6565    /** This property defines how many hops we want in our tunnels. */
    6666    public static final String NUMHOPS_PROP = "numHops";
    6767    /** by default, use 2 hop tunnels */
    6868    public static final int NUMHOPS_DEFAULT = 2;
    69    
     69
    7070    /**
    7171     * Constructs an I2PAdapter . . .
    7272     */
    7373    public I2PAdapter() {
    74         _privateDestFile = null;
    75         _i2cpHost = null;
    76         _i2cpPort = -1;
    77         _localDest = null;
    78         _listener = null;
    79         _session = null;
    80         _numHops = 0;
    81     }
    82    
     74        _privateDestFile = null;
     75        _i2cpHost = null;
     76        _i2cpPort = -1;
     77        _localDest = null;
     78        _listener = null;
     79        _session = null;
     80        _numHops = 0;
     81    }
     82
    8383    /**
    8484     * who are we?
    8585     * @return the destination (us)
    8686     */
    87     public Destination getLocalDestination() { return _localDest; }
    88    
     87    public Destination getLocalDestination() {
     88        return _localDest;
     89    }
     90
    8991    /**
    9092     * who gets notified when we receive a ping or a pong?
    9193     * @return the event listener who gets notified
    9294     */
    93     public PingPongEventListener getListener() { return _listener; }
    94    
    95    
     95    public PingPongEventListener getListener() {
     96        return _listener;
     97    }
     98
    9699    /**
    97100     * Sets who gets notified when we receive a ping or a pong
    98101     * @param listener the event listener to get notified
    99102     */
    100     public void setListener(PingPongEventListener listener) { _listener = listener; }
    101    
     103    public void setListener(PingPongEventListener listener) {
     104        _listener = listener;
     105    }
     106
    102107    /**
    103108     * how many hops do we want in our tunnels?
    104109     * @return the number of hops
    105110     */
    106     public int getNumHops() { return _numHops; }
    107    
     111    public int getNumHops() {
     112        return _numHops;
     113    }
     114
    108115    /**
    109116     * are we connected?
    110117     * @return true or false . . .
    111118     */
    112     public boolean getIsConnected() { return _session != null; }
    113    
     119    public boolean getIsConnected() {
     120        return _session != null;
     121    }
     122
    114123    /**
    115124     * Read in all of the config data
     
    117126     */
    118127    void loadConfig(Properties props) {
    119         String privDestFile = props.getProperty(DEST_FILE_PROP, DEST_FILE_DEFAULT);
    120         String host = props.getProperty(I2CP_HOST_PROP, I2CP_HOST_DEFAULT);
    121         String port = props.getProperty(I2CP_PORT_PROP, ""+I2CP_PORT_DEFAULT);
    122         String numHops = props.getProperty(NUMHOPS_PROP, ""+NUMHOPS_DEFAULT);
    123        
    124         int portNum = -1;
    125         try {
    126             portNum = Integer.parseInt(port);
    127         } catch (NumberFormatException nfe) {
    128             if (_log.shouldLog(Log.WARN)) {
    129                     _log.warn("Invalid I2CP port specified [" + port + "]");
    130         }
    131             portNum = I2CP_PORT_DEFAULT;
    132         }
    133         int hops = -1;
    134         try {
    135             hops = Integer.parseInt(numHops);
    136         } catch (NumberFormatException nfe) {
    137             if (_log.shouldLog(Log.WARN)) {
    138                     _log.warn("Invalid # hops specified [" + numHops + "]");
    139         }
    140             hops = NUMHOPS_DEFAULT;
    141         }
    142        
    143         _numHops = hops;
    144         _privateDestFile = privDestFile;
    145         _i2cpHost = host;
    146         _i2cpPort = portNum;
    147     }
    148    
     128        String privDestFile = props.getProperty(DEST_FILE_PROP, DEST_FILE_DEFAULT);
     129        String host = props.getProperty(I2CP_HOST_PROP, I2CP_HOST_DEFAULT);
     130        String port = props.getProperty(I2CP_PORT_PROP, "" + I2CP_PORT_DEFAULT);
     131        String numHops = props.getProperty(NUMHOPS_PROP, "" + NUMHOPS_DEFAULT);
     132
     133        int portNum = -1;
     134        try {
     135            portNum = Integer.parseInt(port);
     136        } catch (NumberFormatException nfe) {
     137            if (_log.shouldLog(Log.WARN)) {
     138                _log.warn("Invalid I2CP port specified [" + port + "]");
     139            }
     140            portNum = I2CP_PORT_DEFAULT;
     141        }
     142        int hops = -1;
     143        try {
     144            hops = Integer.parseInt(numHops);
     145        } catch (NumberFormatException nfe) {
     146            if (_log.shouldLog(Log.WARN)) {
     147                _log.warn("Invalid # hops specified [" + numHops + "]");
     148            }
     149            hops = NUMHOPS_DEFAULT;
     150        }
     151
     152        _numHops = hops;
     153        _privateDestFile = privDestFile;
     154        _i2cpHost = host;
     155        _i2cpPort = portNum;
     156    }
     157
    149158    /**
    150159     * write out the config to the props
     
    152161     */
    153162    void storeConfig(Properties props) {
    154         if (_privateDestFile != null) {
    155             props.setProperty(DEST_FILE_PROP, _privateDestFile);
    156     } else {
    157             props.setProperty(DEST_FILE_PROP, DEST_FILE_DEFAULT);
    158     }
    159 
    160     if (_i2cpHost != null) {
    161             props.setProperty(I2CP_HOST_PROP, _i2cpHost);
    162     } else {
    163             props.setProperty(I2CP_HOST_PROP, I2CP_HOST_DEFAULT);
    164     }
    165        
    166     if (_i2cpPort > 0) {
    167             props.setProperty(I2CP_PORT_PROP, ""+_i2cpPort);
    168     } else {
    169             props.setProperty(I2CP_PORT_PROP, ""+I2CP_PORT_DEFAULT);
    170     }
    171        
    172     props.setProperty(NUMHOPS_PROP, ""+_numHops);
     163        if (_privateDestFile != null) {
     164            props.setProperty(DEST_FILE_PROP, _privateDestFile);
     165        } else {
     166            props.setProperty(DEST_FILE_PROP, DEST_FILE_DEFAULT);
     167        }
     168
     169        if (_i2cpHost != null) {
     170            props.setProperty(I2CP_HOST_PROP, _i2cpHost);
     171        } else {
     172            props.setProperty(I2CP_HOST_PROP, I2CP_HOST_DEFAULT);
     173        }
     174
     175        if (_i2cpPort > 0) {
     176            props.setProperty(I2CP_PORT_PROP, "" + _i2cpPort);
     177        } else {
     178            props.setProperty(I2CP_PORT_PROP, "" + I2CP_PORT_DEFAULT);
     179        }
     180
     181        props.setProperty(NUMHOPS_PROP, "" + _numHops);
    173182    }
    174183
    175184    private static final int TYPE_PING = 0;
    176185    private static final int TYPE_PONG = 1;
    177    
     186
    178187    /**
    179188     * send a ping message to the peer
     
    187196     */
    188197    public void sendPing(Destination peer, int seriesNum, long now, int size) {
    189         if (_session == null) throw new IllegalStateException("Not connected to the router");
    190         ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
    191         try {
    192             _localDest.writeBytes(baos);
    193             DataHelper.writeLong(baos, 2, seriesNum);
    194             DataHelper.writeLong(baos, 1, TYPE_PING);
    195             DataHelper.writeDate(baos, new Date(now));
    196             int padding = size - baos.size();
    197             byte paddingData[] = new byte[padding];
    198             Arrays.fill(paddingData, (byte)0x2A);
    199             DataHelper.writeLong(baos, 2, padding);
    200             baos.write(paddingData);
    201             boolean sent = _session.sendMessage(peer, baos.toByteArray());
    202             if (!sent) {
    203                 if (_log.shouldLog(Log.ERROR)) {
    204                     _log.error("Error sending the ping to " + peer.calculateHash().toBase64() + " for series " + seriesNum);
    205         }
    206             } else {
    207                 if (_log.shouldLog(Log.INFO)) {
    208                     _log.info("Ping sent to " + peer.calculateHash().toBase64() + " for series " + seriesNum);
    209         }
    210             }
    211         } catch (IOException ioe) {
    212             if (_log.shouldLog(Log.ERROR)) {
    213                     _log.error("Error sending the ping", ioe);
    214         }
    215         } catch (DataFormatException dfe) {
    216             if (_log.shouldLog(Log.ERROR)) {
    217                     _log.error("Error writing out the ping message", dfe);
    218         }
    219         } catch (I2PSessionException ise) {
    220             if (_log.shouldLog(Log.ERROR)) {
    221                     _log.error("Error writing out the ping message", ise);
    222         }
    223         }
    224     }
    225    
     198        if (_session == null) throw new IllegalStateException("Not connected to the router");
     199        ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
     200        try {
     201            _localDest.writeBytes(baos);
     202            DataHelper.writeLong(baos, 2, seriesNum);
     203            DataHelper.writeLong(baos, 1, TYPE_PING);
     204            DataHelper.writeDate(baos, new Date(now));
     205            int padding = size - baos.size();
     206            byte paddingData[] = new byte[padding];
     207            Arrays.fill(paddingData, (byte) 0x2A);
     208            DataHelper.writeLong(baos, 2, padding);
     209            baos.write(paddingData);
     210            boolean sent = _session.sendMessage(peer, baos.toByteArray());
     211            if (!sent) {
     212                if (_log.shouldLog(Log.ERROR)) {
     213                    _log.error("Error sending the ping to " + peer.calculateHash().toBase64() + " for series "
     214                               + seriesNum);
     215                }
     216            } else {
     217                if (_log.shouldLog(Log.INFO)) {
     218                    _log.info("Ping sent to " + peer.calculateHash().toBase64() + " for series " + seriesNum);
     219                }
     220            }
     221        } catch (IOException ioe) {
     222            if (_log.shouldLog(Log.ERROR)) {
     223                _log.error("Error sending the ping", ioe);
     224            }
     225        } catch (DataFormatException dfe) {
     226            if (_log.shouldLog(Log.ERROR)) {
     227                _log.error("Error writing out the ping message", dfe);
     228            }
     229        } catch (I2PSessionException ise) {
     230            if (_log.shouldLog(Log.ERROR)) {
     231                _log.error("Error writing out the ping message", ise);
     232            }
     233        }
     234    }
     235
    226236    /**
    227237     * send a pong message to the peer
     
    235245     */
    236246    public void sendPong(Destination peer, int seriesNum, Date sentOn, byte data[]) {
    237         if (_session == null) throw new IllegalStateException("Not connected to the router");
    238         ByteArrayOutputStream baos = new ByteArrayOutputStream(data.length + 768);
    239         try {
    240             _localDest.writeBytes(baos);
    241             DataHelper.writeLong(baos, 2, seriesNum);
    242             DataHelper.writeLong(baos, 1, TYPE_PONG);
    243             DataHelper.writeDate(baos, sentOn);
    244             DataHelper.writeDate(baos, new Date(Clock.getInstance().now()));
    245             DataHelper.writeLong(baos, 2, data.length);
    246             baos.write(data);
    247             boolean sent = _session.sendMessage(peer, baos.toByteArray());
    248             if (!sent) {
    249                 if (_log.shouldLog(Log.ERROR)) {
    250                     _log.error("Error sending the pong to " + peer.calculateHash().toBase64() + " for series " + seriesNum + " which was sent on " + sentOn);
    251         }
    252             } else {
    253                 if (_log.shouldLog(Log.INFO)) {
    254                     _log.info("Pong sent to " + peer.calculateHash().toBase64() + " for series " + seriesNum + " which was sent on " + sentOn);
    255         }
    256             }
    257         } catch (IOException ioe) {
    258             if (_log.shouldLog(Log.ERROR)) {
    259                     _log.error("Error sending the ping", ioe);
    260         }
    261         } catch (DataFormatException dfe) {
    262             if (_log.shouldLog(Log.ERROR)) {
    263                     _log.error("Error writing out the pong message", dfe);
    264         }
    265         } catch (I2PSessionException ise) {
    266             if (_log.shouldLog(Log.ERROR)) {
    267                     _log.error("Error writing out the pong message", ise);
    268         }
    269         }
    270     }
    271    
     247        if (_session == null) throw new IllegalStateException("Not connected to the router");
     248        ByteArrayOutputStream baos = new ByteArrayOutputStream(data.length + 768);
     249        try {
     250            _localDest.writeBytes(baos);
     251            DataHelper.writeLong(baos, 2, seriesNum);
     252            DataHelper.writeLong(baos, 1, TYPE_PONG);
     253            DataHelper.writeDate(baos, sentOn);
     254            DataHelper.writeDate(baos, new Date(Clock.getInstance().now()));
     255            DataHelper.writeLong(baos, 2, data.length);
     256            baos.write(data);
     257            boolean sent = _session.sendMessage(peer, baos.toByteArray());
     258            if (!sent) {
     259                if (_log.shouldLog(Log.ERROR)) {
     260                    _log.error("Error sending the pong to " + peer.calculateHash().toBase64() + " for series "
     261                               + seriesNum + " which was sent on " + sentOn);
     262                }
     263            } else {
     264                if (_log.shouldLog(Log.INFO)) {
     265                    _log.info("Pong sent to " + peer.calculateHash().toBase64() + " for series " + seriesNum
     266                              + " which was sent on " + sentOn);
     267                }
     268            }
     269        } catch (IOException ioe) {
     270            if (_log.shouldLog(Log.ERROR)) {
     271                _log.error("Error sending the ping", ioe);
     272            }
     273        } catch (DataFormatException dfe) {
     274            if (_log.shouldLog(Log.ERROR)) {
     275                _log.error("Error writing out the pong message", dfe);
     276            }
     277        } catch (I2PSessionException ise) {
     278            if (_log.shouldLog(Log.ERROR)) {
     279                _log.error("Error writing out the pong message", ise);
     280            }
     281        }
     282    }
     283
    272284    /**
    273285     * We've received this data from I2P - parse it into a ping or a pong
     
    276288     */
    277289    private void handleMessage(byte data[]) {
    278         ByteArrayInputStream bais = new ByteArrayInputStream(data);
    279         try {
    280             Destination from = new Destination();
    281             from.readBytes(bais);
    282             int series = (int)DataHelper.readLong(bais, 2);
    283             long type = DataHelper.readLong(bais, 1);
    284             Date sentOn = DataHelper.readDate(bais);
    285             Date receivedOn = null;
    286             if (type == TYPE_PONG) {
    287                     receivedOn = DataHelper.readDate(bais);
    288             }
    289             int size = (int)DataHelper.readLong(bais, 2);
    290             byte payload[] = new byte[size];
    291             int read = DataHelper.read(bais, payload);
    292             if (read != size) {
    293                     throw new IOException("Malformed payload - read " + read + " instead of " + size);
    294         }
    295            
    296             if (_listener == null) {
    297                 if (_log.shouldLog(Log.ERROR)) {
    298                     _log.error("Listener isn't set, but we received a valid message of type " + type + " sent from " + from.calculateHash().toBase64());
    299         }
    300                 return;
    301             }
    302            
    303             if (type == TYPE_PING) {
    304                 if (_log.shouldLog(Log.INFO)) {
    305                     _log.info("Ping received from " + from.calculateHash().toBase64() + " on series " + series + " sent on " + sentOn + " containing " + size + " bytes");
    306         }
    307                 _listener.receivePing(from, series, sentOn, payload);
    308             } else if (type == TYPE_PONG) {
    309                 if (_log.shouldLog(Log.INFO)) {
    310                     _log.info("Pong received from " + from.calculateHash().toBase64() + " on series " + series + " sent on " + sentOn + " with pong sent on " + receivedOn + " containing " + size + " bytes");
    311         }
    312                 _listener.receivePong(from, series, sentOn, receivedOn, payload);
    313             } else {
    314                     throw new IOException("Invalid message type " + type);
    315             }
    316            
    317         } catch (IOException ioe) {
    318             if (_log.shouldLog(Log.ERROR)) {
    319                     _log.error("Error handling the message", ioe);
    320         }
    321         } catch (DataFormatException dfe) {
    322             if (_log.shouldLog(Log.ERROR)) {
    323                     _log.error("Error parsing the message", dfe);
    324         }
    325         }
    326     }
    327    
    328    
     290        ByteArrayInputStream bais = new ByteArrayInputStream(data);
     291        try {
     292            Destination from = new Destination();
     293            from.readBytes(bais);
     294            int series = (int) DataHelper.readLong(bais, 2);
     295            long type = DataHelper.readLong(bais, 1);
     296            Date sentOn = DataHelper.readDate(bais);
     297            Date receivedOn = null;
     298            if (type == TYPE_PONG) {
     299                receivedOn = DataHelper.readDate(bais);
     300            }
     301            int size = (int) DataHelper.readLong(bais, 2);
     302            byte payload[] = new byte[size];
     303            int read = DataHelper.read(bais, payload);
     304            if (read != size) { throw new IOException("Malformed payload - read " + read + " instead of " + size); }
     305
     306            if (_listener == null) {
     307                if (_log.shouldLog(Log.ERROR)) {
     308                    _log.error("Listener isn't set, but we received a valid message of type " + type + " sent from "
     309                               + from.calculateHash().toBase64());
     310                }
     311                return;
     312            }
     313
     314            if (type == TYPE_PING) {
     315                if (_log.shouldLog(Log.INFO)) {
     316                    _log.info("Ping received from " + from.calculateHash().toBase64() + " on series " + series
     317                              + " sent on " + sentOn + " containing " + size + " bytes");
     318                }
     319                _listener.receivePing(from, series, sentOn, payload);
     320            } else if (type == TYPE_PONG) {
     321                if (_log.shouldLog(Log.INFO)) {
     322                    _log.info("Pong received from " + from.calculateHash().toBase64() + " on series " + series
     323                              + " sent on " + sentOn + " with pong sent on " + receivedOn + " containing " + size
     324                              + " bytes");
     325                }
     326                _listener.receivePong(from, series, sentOn, receivedOn, payload);
     327            } else {
     328                throw new IOException("Invalid message type " + type);
     329            }
     330
     331        } catch (IOException ioe) {
     332            if (_log.shouldLog(Log.ERROR)) {
     333                _log.error("Error handling the message", ioe);
     334            }
     335        } catch (DataFormatException dfe) {
     336            if (_log.shouldLog(Log.ERROR)) {
     337                _log.error("Error parsing the message", dfe);
     338            }
     339        }
     340    }
     341
    329342    /**
    330343     * connect to the I2P router and either authenticate ourselves with the
     
    335348     */
    336349    boolean connect() {
    337         I2PClient client = I2PClientFactory.createClient();
    338         Destination us = null;
    339         File destFile = new File(_privateDestFile);
    340         us = verifyDestination(client, destFile);
    341         if (us == null) return false;
    342        
    343         // if we're here, we got a destination.  lets connect
    344         FileInputStream fin = null;
    345         try {
    346             fin = new FileInputStream(destFile);
    347             Properties options = getOptions();
    348             I2PSession session = client.createSession(fin, options);
    349             I2PListener lsnr = new I2PListener();
    350             session.setSessionListener(lsnr);
    351             session.connect();
    352             _localDest = session.getMyDestination();
    353             if (_log.shouldLog(Log.INFO)) {
    354                     _log.info("I2CP Session created and connected as " + _localDest.calculateHash().toBase64());
    355         }
    356             _session = session;
    357             _i2pListener = lsnr;
    358         } catch (I2PSessionException ise) {
    359             if (_log.shouldLog(Log.ERROR)) {
    360                     _log.error("Error connecting", ise);
    361         }
    362             return false;
    363         } catch (IOException ioe) {
    364             if (_log.shouldLog(Log.ERROR)) {
    365                     _log.error("Error loading the destionation", ioe);
    366         }
    367             return false;
    368         } finally {
    369             if (fin != null) try { fin.close(); } catch (IOException ioe) {}
    370         }
    371            
    372         return true;
    373     }
    374    
     350        I2PClient client = I2PClientFactory.createClient();
     351        Destination us = null;
     352        File destFile = new File(_privateDestFile);
     353        us = verifyDestination(client, destFile);
     354        if (us == null) return false;
     355
     356        // if we're here, we got a destination.  lets connect
     357        FileInputStream fin = null;
     358        try {
     359            fin = new FileInputStream(destFile);
     360            Properties options = getOptions();
     361            I2PSession session = client.createSession(fin, options);
     362            I2PListener lsnr = new I2PListener();
     363            session.setSessionListener(lsnr);
     364            session.connect();
     365            _localDest = session.getMyDestination();
     366            if (_log.shouldLog(Log.INFO)) {
     367                _log.info("I2CP Session created and connected as " + _localDest.calculateHash().toBase64());
     368            }
     369            _session = session;
     370            _i2pListener = lsnr;
     371        } catch (I2PSessionException ise) {
     372            if (_log.shouldLog(Log.ERROR)) {
     373                _log.error("Error connecting", ise);
     374            }
     375            return false;
     376        } catch (IOException ioe) {
     377            if (_log.shouldLog(Log.ERROR)) {
     378                _log.error("Error loading the destionation", ioe);
     379            }
     380            return false;
     381        } finally {
     382            if (fin != null) try {
     383                fin.close();
     384            } catch (IOException ioe) {
     385            }
     386        }
     387
     388        return true;
     389    }
     390
    375391    /**
    376392     * load, verify, or create a destination
     
    381397     */
    382398    private Destination verifyDestination(I2PClient client, File destFile) {
    383         Destination us = null;
    384         FileInputStream fin = null;
    385         if (destFile.exists()) {
    386             try {
    387                 fin = new FileInputStream(destFile);
    388                 us = new Destination();
    389                 us.readBytes(fin);
    390                 if (_log.shouldLog(Log.INFO)) {
    391                     _log.info("Existing destination loaded: [" + us.toBase64() + "]");
    392         }
    393             } catch (IOException ioe) {
    394                 if (fin != null) try { fin.close(); } catch (IOException ioe2) {}
    395                 fin = null;
    396                 destFile.delete();
    397                 us = null;
    398             } catch (DataFormatException dfe) {
    399                 if (fin != null) try { fin.close(); } catch (IOException ioe2) {}
    400                 fin = null;
    401                 destFile.delete();
    402                 us = null;
    403             } finally {
    404                 if (fin != null) try { fin.close(); } catch (IOException ioe2) {}
    405                 fin = null;
    406             }
    407         }
    408        
    409         if (us == null) {
    410             // need to create a new one
    411             FileOutputStream fos = null;
    412             try {
    413                 fos = new FileOutputStream(destFile);
    414                 us = client.createDestination(fos);
    415                 if (_log.shouldLog(Log.INFO)) {
    416                     _log.info("New destination created: [" + us.toBase64() + "]");
    417         }
    418             } catch (IOException ioe) {
    419                 if (_log.shouldLog(Log.ERROR)) {
    420                     _log.error("Error writing out the destination keys being created", ioe);
    421         }
    422                 return null;
    423             } catch (I2PException ie) {
    424                 if (_log.shouldLog(Log.ERROR)) {
    425                     _log.error("Error creating the destination", ie);
    426         }
    427                 return null;
    428             } finally {
    429                 if (fos != null) try { fos.close(); } catch (IOException ioe) {}
    430             }
    431         }
    432         return us;
    433     }
    434    
     399        Destination us = null;
     400        FileInputStream fin = null;
     401        if (destFile.exists()) {
     402            try {
     403                fin = new FileInputStream(destFile);
     404                us = new Destination();
     405                us.readBytes(fin);
     406                if (_log.shouldLog(Log.INFO)) {
     407                    _log.info("Existing destination loaded: [" + us.toBase64() + "]");
     408                }
     409            } catch (IOException ioe) {
     410                if (fin != null) try {
     411                    fin.close();
     412                } catch (IOException ioe2) {
     413                }
     414                fin = null;
     415                destFile.delete();
     416                us = null;
     417            } catch (DataFormatException dfe) {
     418                if (fin != null) try {
     419                    fin.close();
     420                } catch (IOException ioe2) {
     421                }
     422                fin = null;
     423                destFile.delete();
     424                us = null;
     425            } finally {
     426                if (fin != null) try {
     427                    fin.close();
     428                } catch (IOException ioe2) {
     429                }
     430                fin = null;
     431            }
     432        }
     433
     434        if (us == null) {
     435            // need to create a new one
     436            FileOutputStream fos = null;
     437            try {
     438                fos = new FileOutputStream(destFile);
     439                us = client.createDestination(fos);
     440                if (_log.shouldLog(Log.INFO)) {
     441                    _log.info("New destination created: [" + us.toBase64() + "]");
     442                }
     443            } catch (IOException ioe) {
     444                if (_log.shouldLog(Log.ERROR)) {
     445                    _log.error("Error writing out the destination keys being created", ioe);
     446                }
     447                return null;
     448            } catch (I2PException ie) {
     449                if (_log.shouldLog(Log.ERROR)) {
     450                    _log.error("Error creating the destination", ie);
     451                }
     452                return null;
     453            } finally {
     454                if (fos != null) try {
     455                    fos.close();
     456                } catch (IOException ioe) {
     457                }
     458            }
     459        }
     460        return us;
     461    }
     462
    435463    /**
    436464     * I2PSession connect options
    437465     * @return the options as Properties
    438466     */
    439     private Properties getOptions() { 
    440         Properties props = new Properties();
    441         props.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_BEST_EFFORT);
    442         props.setProperty(I2PClient.PROP_TCP_HOST, _i2cpHost);
    443         props.setProperty(I2PClient.PROP_TCP_PORT, _i2cpPort + "");
    444         props.setProperty("tunnels.depthInbound", ""+_numHops);
    445         props.setProperty("tunnels.depthOutbound", ""+_numHops);
    446         return props;
    447     }
    448    
     467    private Properties getOptions() {
     468        Properties props = new Properties();
     469        props.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_BEST_EFFORT);
     470        props.setProperty(I2PClient.PROP_TCP_HOST, _i2cpHost);
     471        props.setProperty(I2PClient.PROP_TCP_PORT, _i2cpPort + "");
     472        props.setProperty("tunnels.depthInbound", "" + _numHops);
     473        props.setProperty("tunnels.depthOutbound", "" + _numHops);
     474        return props;
     475    }
     476
    449477    /** disconnect from the I2P router */
    450478    void disconnect() {
    451         if (_session != null) {
    452             try {
    453                 _session.destroySession();
    454             } catch (I2PSessionException ise) {
    455                 if (_log.shouldLog(Log.ERROR)) {
    456                     _log.error("Error destroying the session", ise);
    457         }
    458             }
    459             _session = null;
    460         }
     479        if (_session != null) {
     480            try {
     481                _session.destroySession();
     482            } catch (I2PSessionException ise) {
     483                if (_log.shouldLog(Log.ERROR)) {
     484                    _log.error("Error destroying the session", ise);
     485                }
     486            }
     487            _session = null;
     488        }
    461489    }
    462490
     
    466494     */
    467495    public interface PingPongEventListener {
    468         /**
    469         * receive a ping message from the peer
    470         *
    471         * @param from peer that sent us the ping
    472         * @param seriesNum id the peer sent us in the ping
    473         * @param sentOn date the peer said they sent us the message
    474         * @param data payload from the ping
    475         */
    476         void receivePing(Destination from, int seriesNum, Date sentOn, byte data[]);
    477        
    478         /**
    479         * receive a pong message from the peer
    480         *
    481         * @param from peer that sent us the pong
    482         * @param seriesNum id the peer sent us in the pong (that we sent them in the ping)
    483         * @param sentOn when we sent out the ping
    484         * @param replyOn when they sent out the pong
    485         * @param data payload from the ping/pong
    486         */
    487         void receivePong(Destination from, int seriesNum, Date sentOn, Date replyOn, byte data[]);
    488     }
    489    
     496        /**
     497        * receive a ping message from the peer
     498        *
     499        * @param from peer that sent us the ping
     500        * @param seriesNum id the peer sent us in the ping
     501        * @param sentOn date the peer said they sent us the message
     502        * @param data payload from the ping
     503        */
     504        void receivePing(Destination from, int seriesNum, Date sentOn, byte data[]);
     505
     506        /**
     507        * receive a pong message from the peer
     508        *
     509        * @param from peer that sent us the pong
     510        * @param seriesNum id the peer sent us in the pong (that we sent them in the ping)
     511        * @param sentOn when we sent out the ping
     512        * @param replyOn when they sent out the pong
     513        * @param data payload from the ping/pong
     514        */
     515        void receivePong(Destination from, int seriesNum, Date sentOn, Date replyOn, byte data[]);
     516    }
     517
    490518    /**
    491519     * Receive data from the session and pass it along to handleMessage for parsing/dispersal
     
    493521     */
    494522    private class I2PListener implements I2PSessionListener {
    495        
    496     /* (non-Javadoc)
    497      * @see net.i2p.client.I2PSessionListener#disconnected(net.i2p.client.I2PSession)
    498      */
    499     public void disconnected(I2PSession session) {
    500             if (_log.shouldLog(Log.ERROR)) {
    501                     _log.error("Session disconnected");
    502         }
    503             disconnect();
    504         }
    505         /* (non-Javadoc)
    506          * @see net.i2p.client.I2PSessionListener#errorOccurred(net.i2p.client.I2PSession, java.lang.String, java.lang.Throwable)
    507          */
    508         public void errorOccurred(I2PSession session, String message, Throwable error) {
    509             if (_log.shouldLog(Log.ERROR))
    510                 _log.error("Error occurred", error);
    511         }
    512         /* (non-Javadoc)
    513          * @see net.i2p.client.I2PSessionListener#reportAbuse(net.i2p.client.I2PSession, int)
    514          */
    515         public void reportAbuse(I2PSession session, int severity) {
    516             if (_log.shouldLog(Log.ERROR))
    517                 _log.error("Abuse reported");
    518         }
    519        
    520         /* (non-Javadoc)
    521          * @see net.i2p.client.I2PSessionListener#messageAvailable(net.i2p.client.I2PSession, int, long)
    522          */
    523         public void messageAvailable(I2PSession session, int msgId, long size) {
    524             try {
    525                 byte data[] = session.receiveMessage(msgId);
    526                 handleMessage(data);
    527             } catch (I2PSessionException ise) {
    528                 if (_log.shouldLog(Log.ERROR))
    529                     _log.error("Error receiving the message", ise);
    530                 disconnect();
    531             }
    532         }
     523
     524        /* (non-Javadoc)
     525         * @see net.i2p.client.I2PSessionListener#disconnected(net.i2p.client.I2PSession)
     526         */
     527        public void disconnected(I2PSession session) {
     528            if (_log.shouldLog(Log.ERROR)) {
     529                _log.error("Session disconnected");
     530            }
     531            disconnect();
     532        }
     533
     534        /* (non-Javadoc)
     535         * @see net.i2p.client.I2PSessionListener#errorOccurred(net.i2p.client.I2PSession, java.lang.String, java.lang.Throwable)
     536         */
     537        public void errorOccurred(I2PSession session, String message, Throwable error) {
     538            if (_log.shouldLog(Log.ERROR)) _log.error("Error occurred", error);
     539        }
     540
     541        /* (non-Javadoc)
     542         * @see net.i2p.client.I2PSessionListener#reportAbuse(net.i2p.client.I2PSession, int)
     543         */
     544        public void reportAbuse(I2PSession session, int severity) {
     545            if (_log.shouldLog(Log.ERROR)) _log.error("Abuse reported");
     546        }
     547
     548        /* (non-Javadoc)
     549         * @see net.i2p.client.I2PSessionListener#messageAvailable(net.i2p.client.I2PSession, int, long)
     550         */
     551        public void messageAvailable(I2PSession session, int msgId, long size) {
     552            try {
     553                byte data[] = session.receiveMessage(msgId);
     554                handleMessage(data);
     555            } catch (I2PSessionException ise) {
     556                if (_log.shouldLog(Log.ERROR)) _log.error("Error receiving the message", ise);
     557                disconnect();
     558            }
     559        }
    533560    }
    534561}
  • apps/heartbeat/java/src/net/i2p/heartbeat/PeerData.java

    r8a8e681 r17a1b11  
    3636    /** rate averaging the frequency of lost messages over a variety of periods */
    3737    private RateStat _lostRate;
    38    
     38
    3939    /** how long we wait before timing out pending pings (30 seconds) */
    40     private static final long TIMEOUT_PERIOD = 30*1000;
    41    
     40    private static final long TIMEOUT_PERIOD = 30 * 1000;
     41
    4242    /** synchronize on this when updating _dataPoints or _pendingPings */
    4343    private Object _updateLock = new Object();
    44    
     44
    4545    /**
    4646     * Creates a PeerData . . .
     
    4848     */
    4949    public PeerData(ClientConfig config) {
    50         _peer = config;
    51         _dataPoints = new TreeMap();
    52         _pendingPings = new TreeMap();
    53         _sessionStart = Clock.getInstance().now();
    54         _lifetimeSent = 0;
    55         _lifetimeReceived = 0;
    56         _sendRate = new RateStat("sendRate", "How long it takes to send", "peer", getPeriods(config.getAveragePeriods()));
    57         _receiveRate = new RateStat("receiveRate", "How long it takes to receive", "peer", getPeriods(config.getAveragePeriods()));
    58         _lostRate = new RateStat("lostRate", "How frequently we lose messages", "peer", getPeriods(config.getAveragePeriods()));
    59     }
    60    
     50        _peer = config;
     51        _dataPoints = new TreeMap();
     52        _pendingPings = new TreeMap();
     53        _sessionStart = Clock.getInstance().now();
     54        _lifetimeSent = 0;
     55        _lifetimeReceived = 0;
     56        _sendRate = new RateStat("sendRate", "How long it takes to send", "peer",
     57                                 getPeriods(config.getAveragePeriods()));
     58        _receiveRate = new RateStat("receiveRate", "How long it takes to receive", "peer",
     59                                    getPeriods(config.getAveragePeriods()));
     60        _lostRate = new RateStat("lostRate", "How frequently we lose messages", "peer",
     61                                 getPeriods(config.getAveragePeriods()));
     62    }
     63
    6164    /**
    6265     * turn the periods (# minutes) into rate periods (# milliseconds)
     
    6568     */
    6669    private static long[] getPeriods(int periods[]) {
    67         long rv[] = null;
    68         if (periods == null) periods = new int[0];
    69         rv = new long[periods.length];
    70         for (int i = 0; i < periods.length; i++)
    71             rv[i] = (long)periods[i] * 60*1000; // they're in minutes
    72         Arrays.sort(rv);
    73         return rv;
    74     }
    75    
     70        long rv[] = null;
     71        if (periods == null) periods = new int[0];
     72        rv = new long[periods.length];
     73        for (int i = 0; i < periods.length; i++)
     74            rv[i] = (long) periods[i] * 60 * 1000; // they're in minutes
     75        Arrays.sort(rv);
     76        return rv;
     77    }
     78
    7679    /**
    7780     * how many pings are still outstanding?
    7881     * @return the number of pings outstanding
    7982     */
    80     public int getPendingCount() { synchronized (_updateLock) { return _pendingPings.size(); } }
    81    
     83    public int getPendingCount() {
     84        synchronized (_updateLock) {
     85            return _pendingPings.size();
     86        }
     87    }
     88
    8289    /**
    8390     * how many data points are available in the current window?
    8491     * @return the number of datapoints available
    8592     */
    86     public int getDataPointCount() { synchronized (_updateLock) { return _dataPoints.size(); } }
    87    
     93    public int getDataPointCount() {
     94        synchronized (_updateLock) {
     95            return _dataPoints.size();
     96        }
     97    }
     98
    8899    /**
    89100     * when did this test begin?
    90101     * @return when the test began 
    91102     */
    92     public long getSessionStart() { return _sessionStart; }
    93    
     103    public long getSessionStart() {
     104        return _sessionStart;
     105    }
     106
    94107    /**
    95108     * how many pings have we sent for this test?
    96109     * @return the number of pings sent
    97110     */
    98     public long getLifetimeSent() { return _lifetimeSent; }
    99    
     111    public long getLifetimeSent() {
     112        return _lifetimeSent;
     113    }
     114
    100115    /**
    101116     * how many pongs have we received for this test?
    102117     * @return the number of pings received
    103118     */
    104     public long getLifetimeReceived() { return _lifetimeReceived; }
    105    
    106    
     119    public long getLifetimeReceived() {
     120        return _lifetimeReceived;
     121    }
     122
    107123    /**
    108124     * @return the client configuration
    109125     */
    110     public ClientConfig getConfig() { return _peer; }
    111    
     126    public ClientConfig getConfig() {
     127        return _peer;
     128    }
     129
    112130    /**
    113131     * What periods are we averaging the data over (in minutes)?
    114132     * @return the periods as an array of ints (in minutes)
    115133     */
    116     public int[] getAveragePeriods() { return (_peer.getAveragePeriods() != null ? _peer.getAveragePeriods() : new int[0]); }
    117    
     134    public int[] getAveragePeriods() {
     135        return (_peer.getAveragePeriods() != null ? _peer.getAveragePeriods() : new int[0]);
     136    }
     137
    118138    /**
    119139     * average time to send over the given period.
     
    122142     * @return milliseconds average, or -1 if we dont track that period
    123143     */
    124     public double getAverageSendTime(int period) { return getAverage(_sendRate, period); }
    125    
     144    public double getAverageSendTime(int period) {
     145        return getAverage(_sendRate, period);
     146    }
     147
    126148    /**
    127149     * average time to receive over the given period.
     
    130152     * @return milliseconds average, or -1 if we dont track that period
    131153     */
    132     public double getAverageReceiveTime(int period) { return getAverage(_receiveRate, period); }
    133    
     154    public double getAverageReceiveTime(int period) {
     155        return getAverage(_receiveRate, period);
     156    }
     157
    134158    /**
    135159     * number of lost messages over the given period.
     
    138162     * @return number of lost messages in the period, or -1 if we dont track that period
    139163     */
    140     public double getLostMessages(int period) {
    141         Rate rate = _lostRate.getRate(period * 60*1000);
    142         if (rate == null)
    143             return -1;
    144         return rate.getCurrentTotalValue();
    145     }
    146    
     164    public double getLostMessages(int period) {
     165        Rate rate = _lostRate.getRate(period * 60 * 1000);
     166        if (rate == null) return -1;
     167        return rate.getCurrentTotalValue();
     168    }
     169
    147170    private double getAverage(RateStat stat, int period) {
    148         Rate rate = stat.getRate(period * 60*1000);
    149         if (rate == null)
    150             return -1;
    151         return rate.getAverageValue();
    152     }
    153    
     171        Rate rate = stat.getRate(period * 60 * 1000);
     172        if (rate == null) return -1;
     173        return rate.getAverageValue();
     174    }
     175
    154176    /**
    155177     * Return an ordered list of data points in the current window (after doing a cleanup)
     
    158180     */
    159181    public List getDataPoints() {
    160         cleanup();
    161         synchronized (_updateLock) {
    162             return new ArrayList(_dataPoints.values());
    163         }
    164     }
    165    
     182        cleanup();
     183        synchronized (_updateLock) {
     184            return new ArrayList(_dataPoints.values());
     185        }
     186    }
     187
    166188    /**
    167189     * We have sent the peer a ping on this series (using the send time as given)
     
    169191     */
    170192    public void addPing(long dateSent) {
    171         EventDataPoint sent = new EventDataPoint(dateSent);
    172         synchronized (_updateLock) {
    173             _pendingPings.put(new Long(dateSent), sent);
    174         }
    175         _lifetimeSent++;
    176     }
    177    
     193        EventDataPoint sent = new EventDataPoint(dateSent);
     194        synchronized (_updateLock) {
     195            _pendingPings.put(new Long(dateSent), sent);
     196        }
     197        _lifetimeSent++;
     198    }
     199
    178200    /**
    179201     * we have received a pong from the peer on this series
     
    183205     */
    184206    public void pongReceived(long dateSent, long pongSent) {
    185         long now = Clock.getInstance().now();
    186         synchronized (_updateLock) {
    187             EventDataPoint data = (EventDataPoint)_pendingPings.remove(new Long(dateSent));
    188             if (data != null) {
    189                 data.setPongReceived(now);
    190                 data.setPongSent(pongSent);
    191                 data.setWasPonged(true);
    192                 _dataPoints.put(new Long(dateSent), data);
    193             }
    194         }
    195         _sendRate.addData(pongSent-dateSent, 0);
    196         _receiveRate.addData(now-pongSent, 0);
    197         _lifetimeReceived++;
    198     }
    199    
     207        long now = Clock.getInstance().now();
     208        synchronized (_updateLock) {
     209            EventDataPoint data = (EventDataPoint) _pendingPings.remove(new Long(dateSent));
     210            if (data != null) {
     211                data.setPongReceived(now);
     212                data.setPongSent(pongSent);
     213                data.setWasPonged(true);
     214                _dataPoints.put(new Long(dateSent), data);
     215            }
     216        }
     217        _sendRate.addData(pongSent - dateSent, 0);
     218        _receiveRate.addData(now - pongSent, 0);
     219        _lifetimeReceived++;
     220    }
     221
    200222    /**
    201223     * drop all datapoints outside the window we're watching, and timeout all
     
    205227     */
    206228    public void cleanup() {
    207         long dropBefore = Clock.getInstance().now() - _peer.getStatDuration() * 60*1000;
    208         long timeoutBefore = Clock.getInstance().now() - TIMEOUT_PERIOD;
    209         long numDropped = 0;
    210         long numTimedOut = 0;
    211        
    212         synchronized (_updateLock) {
    213             List toTimeout = new ArrayList(4);
    214             List toDrop = new ArrayList(4);
    215             for (Iterator iter = _pendingPings.keySet().iterator(); iter.hasNext(); ) {
    216                 Long when = (Long)iter.next();
    217                 if (when.longValue() < dropBefore)
    218                     toDrop.add(when);
    219                 else if (when.longValue() < timeoutBefore)
    220                     toTimeout.add(when);
    221                 else
    222                     break; // its ordered, so once we are past timeoutBefore, no need
    223             }
    224             for (Iterator iter = toDrop.iterator(); iter.hasNext(); ) {
    225                 _pendingPings.remove(iter.next());
    226             }
    227            
    228             List toAdd = new ArrayList(toTimeout.size());
    229             for (Iterator iter = toTimeout.iterator(); iter.hasNext(); ) {
    230                 Long when = (Long)iter.next();
    231                 EventDataPoint data = (EventDataPoint)_pendingPings.remove(when);
    232                 data.setWasPonged(false);
    233                 toAdd.add(data);
    234             }
    235            
    236             numDropped = toDrop.size();
    237             numTimedOut = toDrop.size();
    238             toDrop.clear();
    239            
    240             for (Iterator iter = _dataPoints.keySet().iterator(); iter.hasNext(); ) {
    241                 Long when = (Long)iter.next();
    242                 if (when.longValue() < dropBefore)
    243                     toDrop.add(when);
    244                 else
    245                     break; // ordered
    246             }
    247             for (Iterator iter = toDrop.iterator(); iter.hasNext(); ) {
    248                 _dataPoints.remove(iter.next());
    249             }
    250            
    251             numDropped += toDrop.size();
    252            
    253             for (Iterator iter = toAdd.iterator(); iter.hasNext(); ) {
    254                 EventDataPoint data = (EventDataPoint)iter.next();
    255                 _dataPoints.put(new Long(data.getPingSent()), data);
    256             }
    257            
    258             numTimedOut += toAdd.size();
    259         }
    260        
    261         _lostRate.addData(numTimedOut, 0);
    262        
    263         _receiveRate.coallesceStats();
    264         _sendRate.coallesceStats();
    265         _lostRate.coallesceStats();
    266        
    267         if (_log.shouldLog(Log.DEBUG))
    268             _log.debug("Peer data cleaned up " + numTimedOut + " timed out pings and removed " + numDropped + " old entries");
    269     }
    270    
     229        long dropBefore = Clock.getInstance().now() - _peer.getStatDuration() * 60 * 1000;
     230        long timeoutBefore = Clock.getInstance().now() - TIMEOUT_PERIOD;
     231        long numDropped = 0;
     232        long numTimedOut = 0;
     233
     234        synchronized (_updateLock) {
     235            List toTimeout = new ArrayList(4);
     236            List toDrop = new ArrayList(4);
     237            for (Iterator iter = _pendingPings.keySet().iterator(); iter.hasNext();) {
     238                Long when = (Long) iter.next();
     239                if (when.longValue() < dropBefore)
     240                    toDrop.add(when);
     241                else if (when.longValue() < timeoutBefore)
     242                    toTimeout.add(when);
     243                else
     244                    break; // its ordered, so once we are past timeoutBefore, no need
     245            }
     246            for (Iterator iter = toDrop.iterator(); iter.hasNext();) {
     247                _pendingPings.remove(iter.next());
     248            }
     249
     250            List toAdd = new ArrayList(toTimeout.size());
     251            for (Iterator iter = toTimeout.iterator(); iter.hasNext();) {
     252                Long when = (Long) iter.next();
     253                EventDataPoint data = (EventDataPoint) _pendingPings.remove(when);
     254                data.setWasPonged(false);
     255                toAdd.add(data);
     256            }
     257
     258            numDropped = toDrop.size();
     259            numTimedOut = toDrop.size();
     260            toDrop.clear();
     261
     262            for (Iterator iter = _dataPoints.keySet().iterator(); iter.hasNext();) {
     263                Long when = (Long) iter.next();
     264                if (when.longValue() < dropBefore)
     265                    toDrop.add(when);
     266                else
     267                    break; // ordered
     268            }
     269            for (Iterator iter = toDrop.iterator(); iter.hasNext();) {
     270                _dataPoints.remove(iter.next());
     271            }
     272
     273            numDropped += toDrop.size();
     274
     275            for (Iterator iter = toAdd.iterator(); iter.hasNext();) {
     276                EventDataPoint data = (EventDataPoint) iter.next();
     277                _dataPoints.put(new Long(data.getPingSent()), data);
     278            }
     279
     280            numTimedOut += toAdd.size();
     281        }
     282
     283        _lostRate.addData(numTimedOut, 0);
     284
     285        _receiveRate.coallesceStats();
     286        _sendRate.coallesceStats();
     287        _lostRate.coallesceStats();
     288
     289        if (_log.shouldLog(Log.DEBUG))
     290            _log.debug("Peer data cleaned up " + numTimedOut + " timed out pings and removed " + numDropped
     291                       + " old entries");
     292    }
     293
    271294    /** actual data point for the peer */
    272295    public class EventDataPoint {
    273         private boolean _wasPonged;
    274         private long _pingSent;
    275         private long _pongSent;
    276         private long _pongReceived;
    277        
    278         /**
    279          * Creates an EventDataPoint
    280          */
    281         public EventDataPoint() {
    282             this(-1);
    283         }
    284    
    285         /**
    286      * Creates an EventDataPoint with pingtime associated with it =)
    287          * @param pingSentOn the time a ping was sent
    288          */
    289         public EventDataPoint(long pingSentOn) {
    290             _wasPonged = false;
    291             _pingSent = pingSentOn;
    292             _pongSent = -1;
    293             _pongReceived = -1;
    294         }
    295        
    296         /**
    297      * when did we send this ping?
    298      * @return the time the ping was sent
    299      */
    300         public long getPingSent() { return _pingSent; }
    301        
    302     /**
    303      * Set the time the ping was sent
    304      * @param when time to set
    305      */
    306     public void setPingSent(long when) { _pingSent = when; }
    307        
    308         /**
    309      * when did the peer receive the ping?
    310      * @return the time the ping was receieved
    311      */
    312         public long getPongSent() { return _pongSent; }
    313    
    314         /**
    315      * Set the time the peer received the ping
    316          * @param when the time to set
    317          */
    318         public void setPongSent(long when) { _pongSent = when; }
    319        
    320         /**
    321      * when did we receive the peer's pong?
    322      * @return the time we receieved the pong
    323      */
    324         public long getPongReceived() { return _pongReceived; }
    325    
    326     /**
    327      * Set the time the peer's pong was receieved
    328          * @param when the time to set
    329          */
    330         public void setPongReceived(long when) { _pongReceived = when; }
    331        
    332         /**
    333      * did the peer reply in time?
    334      * @return true or false, whether we got a reply in time */
    335         public boolean getWasPonged() { return _wasPonged; }
    336    
    337     /**
    338      * Set whether we receieved the peer's reply in time
    339          * @param pong true or false
    340          */
    341         public void setWasPonged(boolean pong) { _wasPonged = pong; }
     296        private boolean _wasPonged;
     297        private long _pingSent;
     298        private long _pongSent;
     299        private long _pongReceived;
     300
     301        /**
     302         * Creates an EventDataPoint
     303         */
     304        public EventDataPoint() {
     305            this(-1);
     306        }
     307
     308        /**
     309         * Creates an EventDataPoint with pingtime associated with it =)
     310         * @param pingSentOn the time a ping was sent
     311         */
     312        public EventDataPoint(long pingSentOn) {
     313            _wasPonged = false;
     314            _pingSent = pingSentOn;
     315            _pongSent = -1;
     316            _pongReceived = -1;
     317        }
     318
     319        /**
     320         * when did we send this ping?
     321         * @return the time the ping was sent
     322         */
     323        public long getPingSent() {
     324            return _pingSent;
     325        }
     326
     327        /**
     328         * Set the time the ping was sent
     329         * @param when time to set
     330         */
     331        public void setPingSent(long when) {
     332            _pingSent = when;
     333        }
     334
     335        /**
     336         * when did the peer receive the ping?
     337         * @return the time the ping was receieved
     338         */
     339        public long getPongSent() {
     340            return _pongSent;
     341        }
     342
     343        /**
     344         * Set the time the peer received the ping
     345         * @param when the time to set
     346         */
     347        public void setPongSent(long when) {
     348            _pongSent = when;
     349        }
     350
     351        /**
     352         * when did we receive the peer's pong?
     353         * @return the time we receieved the pong
     354         */
     355        public long getPongReceived() {
     356            return _pongReceived;
     357        }
     358
     359        /**
     360         * Set the time the peer's pong was receieved
     361         * @param when the time to set
     362         */
     363        public void setPongReceived(long when) {
     364            _pongReceived = when;
     365        }
     366
     367        /**
     368         * did the peer reply in time?
     369         * @return true or false, whether we got a reply in time */
     370        public boolean getWasPonged() {
     371            return _wasPonged;
     372        }
     373
     374        /**
     375         * Set whether we receieved the peer's reply in time
     376         * @param pong true or false
     377         */
     378        public void setWasPonged(boolean pong) {
     379            _wasPonged = pong;
     380        }
    342381    }
    343382}
  • apps/heartbeat/java/src/net/i2p/heartbeat/PeerDataWriter.java

    r8a8e681 r17a1b11  
    2020class PeerDataWriter {
    2121    private final static Log _log = new Log(PeerDataWriter.class);
    22    
     22
    2323    /**
    2424     * persist the peer state to the location specified in the peer config
     
    2828     */
    2929    public boolean persist(PeerData data) {
    30         String filename = data.getConfig().getStatFile();
    31         String header = getHeader(data);
    32         File statFile = new File(filename);
    33         FileOutputStream fos = null;
    34         try {
    35             fos = new FileOutputStream(statFile);
    36             fos.write(header.getBytes());
    37             fos.write("#action\tstatus\tdate and time sent   \tsendMs\treplyMs\n".getBytes());
    38             for (Iterator iter = data.getDataPoints().iterator(); iter.hasNext(); ) {
    39                 PeerData.EventDataPoint point = (PeerData.EventDataPoint)iter.next();
    40                 String line = getEvent(point);
    41                 fos.write(line.getBytes());
    42             }
    43         } catch (IOException ioe) {
    44             if (_log.shouldLog(Log.ERROR))
    45                 _log.error("Error persisting the peer data for " + data.getConfig().getPeer().calculateHash().toBase64(), ioe);
    46             return false;
    47         } finally {
    48             if (fos != null) try { fos.close(); } catch (IOException ioe) {}
    49         }
    50         return true;
     30        String filename = data.getConfig().getStatFile();
     31        String header = getHeader(data);
     32        File statFile = new File(filename);
     33        FileOutputStream fos = null;
     34        try {
     35            fos = new FileOutputStream(statFile);
     36            fos.write(header.getBytes());
     37            fos.write("#action\tstatus\tdate and time sent   \tsendMs\treplyMs\n".getBytes());
     38            for (Iterator iter = data.getDataPoints().iterator(); iter.hasNext();) {
     39                PeerData.EventDataPoint point = (PeerData.EventDataPoint) iter.next();
     40                String line = getEvent(point);
     41                fos.write(line.getBytes());
     42            }
     43        } catch (IOException ioe) {
     44            if (_log.shouldLog(Log.ERROR))
     45                _log.error("Error persisting the peer data for "
     46                           + data.getConfig().getPeer().calculateHash().toBase64(), ioe);
     47            return false;
     48        } finally {
     49            if (fos != null) try {
     50                fos.close();
     51            } catch (IOException ioe) {
     52            }
     53        }
     54        return true;
    5155    }
    52    
    53     private String getHeader(PeerData data) { 
    54         StringBuffer buf = new StringBuffer(1024);
    55         buf.append("peer         \t").append(data.getConfig().getPeer().calculateHash().toBase64()).append('\n');
    56         buf.append("local        \t").append(data.getConfig().getUs().calculateHash().toBase64()).append('\n');
    57         buf.append("peerDest     \t").append(data.getConfig().getPeer().toBase64()).append('\n');
    58         buf.append("localDest    \t").append(data.getConfig().getUs().toBase64()).append('\n');
    59         buf.append("numTunnelHops\t").append(data.getConfig().getNumHops()).append('\n');
    60         buf.append("comment      \t").append(data.getConfig().getComment()).append('\n');
    61         buf.append("sendFrequency\t").append(data.getConfig().getSendFrequency()).append('\n');
    62         buf.append("sendSize     \t").append(data.getConfig().getSendSize()).append('\n');
    63         buf.append("sessionStart \t").append(getTime(data.getSessionStart())).append('\n');
    64         buf.append("currentTime  \t").append(getTime(Clock.getInstance().now())).append('\n');
    65         buf.append("numPending   \t").append(data.getPendingCount()).append('\n');
    66         buf.append("lifetimeSent \t").append(data.getLifetimeSent()).append('\n');
    67         buf.append("lifetimeRecv \t").append(data.getLifetimeReceived()).append('\n');
    68         int periods[] = data.getAveragePeriods();
    69         buf.append("#averages\tminutes\tsendMs\trecvMs\tnumLost\n");
    70         for (int i = 0; i < periods.length; i++) {
    71             buf.append("periodAverage\t").append(periods[i]).append('\t');
    72             buf.append(getNum(data.getAverageSendTime(periods[i]))).append('\t');
    73             buf.append(getNum(data.getAverageReceiveTime(periods[i]))).append('\t');
    74             buf.append(getNum(data.getLostMessages(periods[i]))).append('\n');
    75         }
    76         return buf.toString();
     56
     57    private String getHeader(PeerData data) {
     58        StringBuffer buf = new StringBuffer(1024);
     59        buf.append("peer         \t").append(data.getConfig().getPeer().calculateHash().toBase64()).append('\n');
     60        buf.append("local        \t").append(data.getConfig().getUs().calculateHash().toBase64()).append('\n');
     61        buf.append("peerDest     \t").append(data.getConfig().getPeer().toBase64()).append('\n');
     62        buf.append("localDest    \t").append(data.getConfig().getUs().toBase64()).append('\n');
     63        buf.append("numTunnelHops\t").append(data.getConfig().getNumHops()).append('\n');
     64        buf.append("comment      \t").append(data.getConfig().getComment()).append('\n');
     65        buf.append("sendFrequency\t").append(data.getConfig().getSendFrequency()).append('\n');
     66        buf.append("sendSize     \t").append(data.getConfig().getSendSize()).append('\n');
     67        buf.append("sessionStart \t").append(getTime(data.getSessionStart())).append('\n');
     68        buf.append("currentTime  \t").append(getTime(Clock.getInstance().now())).append('\n');
     69        buf.append("numPending   \t").append(data.getPendingCount()).append('\n');
     70        buf.append("lifetimeSent \t").append(data.getLifetimeSent()).append('\n');
     71        buf.append("lifetimeRecv \t").append(data.getLifetimeReceived()).append('\n');
     72        int periods[] = data.getAveragePeriods();
     73        buf.append("#averages\tminutes\tsendMs\trecvMs\tnumLost\n");
     74        for (int i = 0; i < periods.length; i++) {
     75            buf.append("periodAverage\t").append(periods[i]).append('\t');
     76            buf.append(getNum(data.getAverageSendTime(periods[i]))).append('\t');
     77            buf.append(getNum(data.getAverageReceiveTime(periods[i]))).append('\t');
     78            buf.append(getNum(data.getLostMessages(periods[i]))).append('\n');
     79        }
     80        return buf.toString();
    7781    }
    78    
     82
    7983    private String getEvent(PeerData.EventDataPoint point) {
    80         StringBuffer buf = new StringBuffer(128);
    81         buf.append("EVENT\t");
    82         if (point.getWasPonged())
    83             buf.append("OK\t");
    84         else
    85             buf.append("LOST\t");
    86         buf.append(getTime(point.getPingSent())).append('\t');
    87         if (point.getWasPonged()) {
    88             buf.append(point.getPongSent() - point.getPingSent()).append('\t');
    89             buf.append(point.getPongReceived() - point.getPongSent()).append('\t');
    90         }
    91         buf.append('\n');
    92         return buf.toString();
     84        StringBuffer buf = new StringBuffer(128);
     85        buf.append("EVENT\t");
     86        if (point.getWasPonged())
     87            buf.append("OK\t");
     88        else
     89            buf.append("LOST\t");
     90        buf.append(getTime(point.getPingSent())).append('\t');
     91        if (point.getWasPonged()) {
     92            buf.append(point.getPongSent() - point.getPingSent()).append('\t');
     93            buf.append(point.getPongReceived() - point.getPongSent()).append('\t');
     94        }
     95        buf.append('\n');
     96        return buf.toString();
    9397    }
    94    
     98
    9599    private static final SimpleDateFormat _fmt = new SimpleDateFormat("yyyyMMdd.HH:mm:ss.SSS", Locale.UK);
    96100
     
    101105     */
    102106    public String getTime(long when) {
    103         synchronized (_fmt) {
    104             return _fmt.format(new Date(when));
    105         }
     107        synchronized (_fmt) {
     108            return _fmt.format(new Date(when));
     109        }
    106110    }
    107111
     
    114118     */
    115119    public String getNum(double val) {
    116         synchronized (_numFmt) {
    117             return _numFmt.format(val);
    118         }
     120        synchronized (_numFmt) {
     121            return _numFmt.format(val);
     122        }
    119123    }
    120124}
  • apps/heartbeat/java/src/net/i2p/heartbeat/gui/PeerPlotConfig.java

    r8a8e681 r17a1b11  
    99class PeerPlotConfig {
    1010    private ClientConfig _config;
    11    
     11
    1212    private final static void foo() {
    13         // bar
    14         if (true) {
    15             // baz
    16         }
    17         // baf
    18     }
     13        // bar
     14        if (true) {
     15            // baz
     16        }
     17        // baf
     18    }
     19
    1920    // moo
    20    
     21
    2122    private final static void biff() {
    2223        // b0nk
  • apps/httptunnel/java/src/net/i2p/httptunnel/HTTPListener.java

    r8a8e681 r17a1b11  
    2828     * @param listenHost A host, to connect to.
    2929     */
    30    
    31     public HTTPListener(SocketManagerProducer smp, int port,
    32                         String listenHost) {
    33         this.smp = smp;
    34         this.port = port;
    35         start();
     30
     31    public HTTPListener(SocketManagerProducer smp, int port, String listenHost) {
     32        this.smp = smp;
     33        this.port = port;
     34        start();
    3635    }
    37    
     36
    3837    /* (non-Javadoc)
    3938     * @see java.lang.Thread#run()
    4039     */
    4140    public void run() {
    42         try {
    43             InetAddress lh = listenHost == null
    44                 ? null
    45                 : InetAddress.getByName(listenHost);
    46             ServerSocket ss = new ServerSocket(port, 0, lh);
    47             while(true) {
    48                 Socket s = ss.accept();
    49                 new HTTPSocketHandler(this, s);
    50             }
    51         } catch (IOException ex) {
    52             _log.error("Error while accepting connections", ex);
    53         }
     41        try {
     42            InetAddress lh = listenHost == null ? null : InetAddress.getByName(listenHost);
     43            ServerSocket ss = new ServerSocket(port, 0, lh);
     44            while (true) {
     45                Socket s = ss.accept();
     46                new HTTPSocketHandler(this, s);
     47            }
     48        } catch (IOException ex) {
     49            _log.error("Error while accepting connections", ex);
     50        }
    5451    }
    5552
    56     private boolean proxyUsed=false;
    57    
     53    private boolean proxyUsed = false;
     54
    5855    /**
    5956     * Query whether this is the first use of the proxy or not . . .
     
    6158     */
    6259    public boolean firstProxyUse() {
    63         // FIXME: check a config option here
    64         if (true) return false;
    65         if (proxyUsed) {
    66             return false;
    67         } else {
    68             proxyUsed=true;
    69             return true;
    70         }
     60        // FIXME: check a config option here
     61        if (true) return false;
     62        if (proxyUsed) {
     63            return false;
     64        } else {
     65            proxyUsed = true;
     66            return true;
     67        }
    7168    }
    7269
     
    7572     */
    7673    public SocketManagerProducer getSMP() {
    77         return smp;
     74        return smp;
    7875    }
    7976
     
    8582     */
    8683    public void handleNotImplemented(OutputStream out) throws IOException {
    87         out.write(("HTTP/1.1 200 Document following\n\n"+
    88                   "<h1>Feature not implemented</h1>").getBytes("ISO-8859-1"));
    89         out.flush();
     84        out.write(("HTTP/1.1 200 Document following\n\n" + "<h1>Feature not implemented</h1>").getBytes("ISO-8859-1"));
     85        out.flush();
    9086    }
    9187}
  • apps/httptunnel/java/src/net/i2p/httptunnel/HTTPSocketHandler.java

    r8a8e681 r17a1b11  
    2828     */
    2929    public HTTPSocketHandler(HTTPListener httpl, Socket s) {
    30         this.httpl = httpl;
    31         this.s=s;
    32         h = RootHandler.getInstance();
    33         start();
     30        this.httpl = httpl;
     31        this.s = s;
     32        h = RootHandler.getInstance();
     33        start();
    3434    }
    35    
    36    
     35
    3736    /* (non-Javadoc)
    3837     * @see java.lang.Thread#run()
    3938     */
    4039    public void run() {
    41         InputStream in = null;
    42         OutputStream out = null;
    43         try {
    44             in = new BufferedInputStream(s.getInputStream());
    45             out = new BufferedOutputStream(s.getOutputStream());
    46             Request req = new Request(in);
    47             h.handle(req, httpl, out);
    48         } catch (IOException ex) {
    49             _log.error("Error while handling data", ex);
    50         } finally {
    51             try {
    52                 if (in != null) in.close();
    53                 if (out != null) {
    54                     out.flush();
    55                     out.close();
    56                 }
    57                 s.close();
    58             } catch (IOException ex) {
    59                 _log.error("IOException in finalizer", ex);
    60             }
    61         }
     40        InputStream in = null;
     41        OutputStream out = null;
     42        try {
     43            in = new BufferedInputStream(s.getInputStream());
     44            out = new BufferedOutputStream(s.getOutputStream());
     45            Request req = new Request(in);
     46            h.handle(req, httpl, out);
     47        } catch (IOException ex) {
     48            _log.error("Error while handling data", ex);
     49        } finally {
     50            try {
     51                if (in != null) in.close();
     52                if (out != null) {
     53                    out.flush();
     54                    out.close();
     55                }
     56                s.close();
     57            } catch (IOException ex) {
     58                _log.error("IOException in finalizer", ex);
     59            }
     60        }
    6261    }
    6362}
  • apps/httptunnel/java/src/net/i2p/httptunnel/HTTPTunnel.java

    r8a8e681 r17a1b11  
    4545     * @param listenPort which port to listen on
    4646     */
    47     public HTTPTunnel(I2PSocketManager[] initialManagers, int maxManagers,
    48                       boolean shouldThrowAwayManagers, int listenPort) {
    49         this(initialManagers, maxManagers, shouldThrowAwayManagers, listenPort,
    50              "127.0.0.1", 7654);
     47    public HTTPTunnel(I2PSocketManager[] initialManagers, int maxManagers, boolean shouldThrowAwayManagers,
     48                      int listenPort) {
     49        this(initialManagers, maxManagers, shouldThrowAwayManagers, listenPort, "127.0.0.1", 7654);
    5150    }
    5251
     
    6160     * @param i2cpPort the I2CP port
    6261     */
    63     public HTTPTunnel(I2PSocketManager[] initialManagers, int maxManagers,
    64                       boolean shouldThrowAwayManagers, int listenPort,
    65                       String i2cpAddress, int i2cpPort) {
    66         SocketManagerProducer smp =
    67             new SocketManagerProducer(initialManagers, maxManagers,
    68                                       shouldThrowAwayManagers, i2cpAddress, i2cpPort);
    69         new HTTPListener(smp, listenPort, "127.0.0.1");
     62    public HTTPTunnel(I2PSocketManager[] initialManagers, int maxManagers, boolean shouldThrowAwayManagers,
     63                      int listenPort, String i2cpAddress, int i2cpPort) {
     64        SocketManagerProducer smp = new SocketManagerProducer(initialManagers, maxManagers, shouldThrowAwayManagers,
     65                                                              i2cpAddress, i2cpPort);
     66        new HTTPListener(smp, listenPort, "127.0.0.1");
    7067    }
    71    
     68
    7269    /**
    7370     * The all important main function, allowing HTTPTunnel to be
     
    7673     */
    7774    public static void main(String[] args) {
    78         String host = "127.0.0.1";
    79         int port = 7654, max = 1;
    80         boolean throwAwayManagers = false;
    81         if (args.length >1) {
    82             if (args.length == 4) {
    83                 host = args[2];
    84                 port = Integer.parseInt(args[3]);
    85             } else if (args.length != 2) {
    86                 showInfo(); return;
    87             }
    88             max = Integer.parseInt(args[1]);
    89         } else if (args.length != 1) {
    90             showInfo(); return;
    91         }
    92         if (max == 0) {
    93             max = 1;
    94         } else if (max <0) {
    95             max = -max;
    96             throwAwayManagers = true;
    97         }
    98         new HTTPTunnel(null, max, throwAwayManagers, Integer.parseInt(args[0]), host, port);
     75        String host = "127.0.0.1";
     76        int port = 7654, max = 1;
     77        boolean throwAwayManagers = false;
     78        if (args.length > 1) {
     79            if (args.length == 4) {
     80                host = args[2];
     81                port = Integer.parseInt(args[3]);
     82            } else if (args.length != 2) {
     83                showInfo();
     84                return;
     85            }
     86            max = Integer.parseInt(args[1]);
     87        } else if (args.length != 1) {
     88            showInfo();
     89            return;
     90        }
     91        if (max == 0) {
     92            max = 1;
     93        } else if (max < 0) {
     94            max = -max;
     95            throwAwayManagers = true;
     96        }
     97        new HTTPTunnel(null, max, throwAwayManagers, Integer.parseInt(args[0]), host, port);
    9998    }
    100            
     99
    101100    private static void showInfo() {
    102         System.out.println
    103             ("Usage: java HTTPTunnel <listenPort> [<max> "+
    104              "[<i2cphost> <i2cpport>]]\n"+
    105              "  <listenPort>  port to listen for browsers\n"+
    106              "  <max>         max number of SocketMangers in pool, "+
    107              "use neg. number\n"+
    108              "                to use each SocketManager only once "+
    109              "(default: 1)\n"+
    110              "  <i2cphost>    host to connect to the router "+
    111              "(default: 127.0.0.1)\n"+
    112              "  <i2cpport>    port to connect to the router "+
    113              "(default: 7654)");
     101        System.out.println("Usage: java HTTPTunnel <listenPort> [<max> " + "[<i2cphost> <i2cpport>]]\n"
     102                           + "  <listenPort>  port to listen for browsers\n"
     103                           + "  <max>         max number of SocketMangers in pool, " + "use neg. number\n"
     104                           + "                to use each SocketManager only once " + "(default: 1)\n"
     105                           + "  <i2cphost>    host to connect to the router " + "(default: 127.0.0.1)\n"
     106                           + "  <i2cpport>    port to connect to the router " + "(default: 7654)");
    114107    }
    115108}
  • apps/httptunnel/java/src/net/i2p/httptunnel/Request.java

    r8a8e681 r17a1b11  
    2323    private String params;
    2424    private String postData;
    25    
     25
    2626    /**
    2727     * A constructor, creating a request from an InputStream
     
    3030     */
    3131    public Request(InputStream in) throws IOException {
    32         BufferedReader br = new BufferedReader
    33             (new InputStreamReader(in, "ISO-8859-1"));
    34         String line = br.readLine();
    35         if (line == null) { // no data at all
    36             method = null;
    37             _log.error("Connection but no data");
    38             return;
    39         }
    40         int pos = line.indexOf(" ");
    41         if (pos == -1) {
    42             method = line;
    43             url="";
    44             _log.error("Malformed HTTP request: "+line);
    45         } else {
    46             method = line.substring(0,pos);
    47             url=line.substring(pos+1);
    48         }
    49         proto="";
    50         pos = url.indexOf(" ");
    51         if (pos != -1) {
    52             proto=url.substring(pos); // leading space intended
    53             url = url.substring(0,pos);
    54         }
    55         StringBuffer sb = new StringBuffer(512);
    56         while((line=br.readLine()) != null) {
    57             if (line.length() == 0) break;
    58             sb.append(line).append("\r\n");
    59         }
    60         params = sb.toString(); // no leading empty line!
    61         sb = new StringBuffer();
    62         // hack for POST requests, ripped from HttpClient
    63         // this won't work for large POSTDATA
    64         // FIXME: do this better, please.
    65         if (!method.equals("GET")) {
    66             while (br.ready()) { // empty the buffer (POST requests)
    67                 int i=br.read();
    68                 if (i != -1) {
    69                     sb.append((char)i);
    70                     }
    71             }
    72             postData = sb.toString();
    73         } else {
    74             postData="";
    75         }
     32        BufferedReader br = new BufferedReader(new InputStreamReader(in, "ISO-8859-1"));
     33        String line = br.readLine();
     34        if (line == null) { // no data at all
     35            method = null;
     36            _log.error("Connection but no data");
     37            return;
     38        }
     39        int pos = line.indexOf(" ");
     40        if (pos == -1) {
     41            method = line;
     42            url = "";
     43            _log.error("Malformed HTTP request: " + line);
     44        } else {
     45            method = line.substring(0, pos);
     46            url = line.substring(pos + 1);
     47        }
     48        proto = "";
     49        pos = url.indexOf(" ");
     50        if (pos != -1) {
     51            proto = url.substring(pos); // leading space intended
     52            url = url.substring(0, pos);
     53        }
     54        StringBuffer sb = new StringBuffer(512);
     55        while ((line = br.readLine()) != null) {
     56            if (line.length() == 0) break;
     57            sb.append(line).append("\r\n");
     58        }
     59        params = sb.toString(); // no leading empty line!
     60        sb = new StringBuffer();
     61        // hack for POST requests, ripped from HttpClient
     62        // this won't work for large POSTDATA
     63        // FIXME: do this better, please.
     64        if (!method.equals("GET")) {
     65            while (br.ready()) { // empty the buffer (POST requests)
     66                int i = br.read();
     67                if (i != -1) {
     68                    sb.append((char) i);
     69                }
     70            }
     71            postData = sb.toString();
     72        } else {
     73            postData = "";
     74        }
    7675    }
    7776
     
    8180     */
    8281    public byte[] toByteArray() throws IOException {
    83         if (method == null) return null;
    84         return toISO8859_1String().getBytes("ISO-8859-1");
     82        if (method == null) return null;
     83        return toISO8859_1String().getBytes("ISO-8859-1");
    8584
    8685    }
    8786
    8887    private String toISO8859_1String() throws IOException {
    89         if (method == null) return null;
    90         return method+" "+url+proto+"\r\n"+params+"\r\n"+postData;
     88        if (method == null) return null;
     89        return method + " " + url + proto + "\r\n" + params + "\r\n" + postData;
    9190    }
    9291
     
    9594     */
    9695    public String getURL() {
    97         return url;
     96        return url;
    9897    }
    9998
     
    103102     */
    104103    public void setURL(String newURL) {
    105         url=newURL;
     104        url = newURL;
    106105    }
    107106
     
    112111     */
    113112    public String getParam(String name) {
    114         try {
    115             BufferedReader br= new BufferedReader(new StringReader(params));
    116             String line;
    117             while ((line = br.readLine()) != null) {
    118                 if (line.startsWith(name)) {
    119                     return line.substring(name.length());
    120                 }
    121             }
    122             return null;
    123         } catch (IOException ex) {
    124             _log.error("Error getting parameter", ex);
    125             return null;
    126         }
     113        try {
     114            BufferedReader br = new BufferedReader(new StringReader(params));
     115            String line;
     116            while ((line = br.readLine()) != null) {
     117                if (line.startsWith(name)) { return line.substring(name.length()); }
     118            }
     119            return null;
     120        } catch (IOException ex) {
     121            _log.error("Error getting parameter", ex);
     122            return null;
     123        }
    127124    }
    128125
     
    133130     */
    134131    public void setParam(String name, String value) {
    135         try {
    136             StringBuffer sb = new StringBuffer(params.length()+value.length());
    137             BufferedReader br= new BufferedReader(new StringReader(params));
    138             String line;
    139             boolean replaced = false;
    140             while((line=br.readLine()) != null) {
    141                 if (line.startsWith(name)) {
    142                     replaced=true;
    143                     if (value == null) continue; // kill param
    144                     line = name+value;
    145                 }
    146                 sb.append(line).append("\r\n");
    147             }
    148             if (!replaced && value != null) {
    149                 sb.append(name).append(value).append("\r\n");
    150             }
    151             params=sb.toString();
    152         } catch (IOException ex) {
    153             _log.error("Error getting parameter", ex);
    154         }
     132        try {
     133            StringBuffer sb = new StringBuffer(params.length() + value.length());
     134            BufferedReader br = new BufferedReader(new StringReader(params));
     135            String line;
     136            boolean replaced = false;
     137            while ((line = br.readLine()) != null) {
     138                if (line.startsWith(name)) {
     139                    replaced = true;
     140                    if (value == null) continue; // kill param
     141                    line = name + value;
     142                }
     143                sb.append(line).append("\r\n");
     144            }
     145            if (!replaced && value != null) {
     146                sb.append(name).append(value).append("\r\n");
     147            }
     148            params = sb.toString();
     149        } catch (IOException ex) {
     150            _log.error("Error getting parameter", ex);
     151        }
    155152    }
    156153}
  • apps/httptunnel/java/src/net/i2p/httptunnel/SocketManagerProducer.java

    r8a8e681 r17a1b11  
    3030     * @param port which port to listen on
    3131     */
    32     public SocketManagerProducer(I2PSocketManager[] initialManagers,
    33                                  int maxManagers,
    34                                  boolean shouldThrowAwayManagers,
    35                                  String host, int port) {
    36         if (maxManagers < 1) {
    37             throw new IllegalArgumentException("maxManagers < 1");
    38         }
    39         this.host=host;
    40         this.port=port;
    41         this.shouldThrowAwayManagers=shouldThrowAwayManagers;
    42         if (initialManagers != null) {
    43             myManagers.addAll(Arrays.asList(initialManagers));
    44         }
    45         this.maxManagers=maxManagers;
    46         this.shouldThrowAwayManagers=shouldThrowAwayManagers;
    47         setDaemon(true);
    48         start();
     32    public SocketManagerProducer(I2PSocketManager[] initialManagers, int maxManagers, boolean shouldThrowAwayManagers,
     33                                 String host, int port) {
     34        if (maxManagers < 1) { throw new IllegalArgumentException("maxManagers < 1"); }
     35        this.host = host;
     36        this.port = port;
     37        this.shouldThrowAwayManagers = shouldThrowAwayManagers;
     38        if (initialManagers != null) {
     39            myManagers.addAll(Arrays.asList(initialManagers));
     40        }
     41        this.maxManagers = maxManagers;
     42        this.shouldThrowAwayManagers = shouldThrowAwayManagers;
     43        setDaemon(true);
     44        start();
    4945    }
    5046
    51    
    5247    /**
    5348     * Thread producing new SocketManagers.
    5449     */
    5550    public void run() {
    56         while (true) {
    57             synchronized(this) {
    58                 // without mcDonalds mode, we most probably need no
    59                 // new managers.
    60                 while (!shouldThrowAwayManagers && myManagers.size() == maxManagers) {
    61                     myWait();
    62                 }
    63             }
    64             // produce a new manager, regardless whether it is needed
    65             // or not. Do not synchronized this part, since it can be
    66             // quite time-consuming.
    67             I2PSocketManager newManager =
    68                 I2PSocketManagerFactory.createManager(host, port,
    69                                                       new Properties());
    70             // when done, check if it is needed.
    71             synchronized(this) {
    72                 while(myManagers.size() == maxManagers) {
    73                     myWait();
    74                 }
    75                 myManagers.add(newManager);
    76                 notifyAll();
    77             }
    78         }
     51        while (true) {
     52            synchronized (this) {
     53                // without mcDonalds mode, we most probably need no
     54                // new managers.
     55                while (!shouldThrowAwayManagers && myManagers.size() == maxManagers) {
     56                    myWait();
     57                }
     58            }
     59            // produce a new manager, regardless whether it is needed
     60            // or not. Do not synchronized this part, since it can be
     61            // quite time-consuming.
     62            I2PSocketManager newManager = I2PSocketManagerFactory.createManager(host, port, new Properties());
     63            // when done, check if it is needed.
     64            synchronized (this) {
     65                while (myManagers.size() == maxManagers) {
     66                    myWait();
     67                }
     68                myManagers.add(newManager);
     69                notifyAll();
     70            }
     71        }
    7972    }
    80    
     73
    8174    /**
    8275     * Get a manager for connecting to a given destination. Each
     
    8780     */
    8881    public synchronized I2PSocketManager getManager(String dest) {
    89         I2PSocketManager result = (I2PSocketManager) usedManagers.get(dest);
    90         if (result == null) {
    91             result = getManager();
    92             usedManagers.put(dest,result);
    93         }
    94         return result;
     82        I2PSocketManager result = (I2PSocketManager) usedManagers.get(dest);
     83        if (result == null) {
     84            result = getManager();
     85            usedManagers.put(dest, result);
     86        }
     87        return result;
    9588    }
    9689
     
    10396     */
    10497    public synchronized I2PSocketManager getManager() {
    105         while (myManagers.size() == 0) {
    106             myWait(); // no manager here, so wait until one is produced
    107         }
    108         int which = (int)(Math.random()*myManagers.size());
    109         I2PSocketManager result = (I2PSocketManager) myManagers.get(which);
    110         if (shouldThrowAwayManagers) {
    111             myManagers.remove(which);
    112             notifyAll();
    113         }
    114         return result;
     98        while (myManagers.size() == 0) {
     99            myWait(); // no manager here, so wait until one is produced
     100        }
     101        int which = (int) (Math.random() * myManagers.size());
     102        I2PSocketManager result = (I2PSocketManager) myManagers.get(which);
     103        if (shouldThrowAwayManagers) {
     104            myManagers.remove(which);
     105            notifyAll();
     106        }
     107        return result;
    115108    }
    116109
     
    119112     */
    120113    public void myWait() {
    121         try {
    122             wait();
    123         } catch (InterruptedException ex) {
    124             ex.printStackTrace();
    125         }
     114        try {
     115            wait();
     116        } catch (InterruptedException ex) {
     117            ex.printStackTrace();
     118        }
    126119    }
    127120}
  • apps/httptunnel/java/src/net/i2p/httptunnel/filter/ChainFilter.java

    r8a8e681 r17a1b11  
    1414
    1515    private static final Log _log = new Log(ChainFilter.class);
    16    
    17     private Collection filters;  // perhaps protected?
    18    
    19    
     16
     17    private Collection filters; // perhaps protected?
     18
    2019    /**
    2120     * @param filters A collection (list) of filters to chain to
    2221     */
    2322    public ChainFilter(Collection filters) {
    24         this.filters=filters;
     23        this.filters = filters;
    2524    }
    2625
     
    2928     */
    3029    public byte[] filter(byte[] toFilter) {
    31         byte[] buf = toFilter;
    32         for (Iterator it = filters.iterator(); it.hasNext();) {
    33             Filter f = (Filter) it.next();
    34             buf = f.filter(buf);
    35         }
    36         return buf;
     30        byte[] buf = toFilter;
     31        for (Iterator it = filters.iterator(); it.hasNext();) {
     32            Filter f = (Filter) it.next();
     33            buf = f.filter(buf);
     34        }
     35        return buf;
    3736    }
    3837
     
    4140     */
    4241    public byte[] finish() {
    43         // this is a bit complicated. Think about it...
    44         try {
    45             byte[] buf = EMPTY;
    46             for (Iterator it = filters.iterator(); it.hasNext();) {
    47                 Filter f = (Filter) it.next();
    48                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
    49                 if (buf.length != 0) {
    50                     baos.write(f.filter(buf));
    51                 }
    52                 baos.write(f.finish());
    53             buf = baos.toByteArray();
    54             }
    55             return buf;
    56         } catch (IOException ex) {
    57             _log.error("Error chaining filters", ex);
    58             return EMPTY;
    59         }
     42        // this is a bit complicated. Think about it...
     43        try {
     44            byte[] buf = EMPTY;
     45            for (Iterator it = filters.iterator(); it.hasNext();) {
     46                Filter f = (Filter) it.next();
     47                ByteArrayOutputStream baos = new ByteArrayOutputStream();
     48                if (buf.length != 0) {
     49                    baos.write(f.filter(buf));
     50                }
     51                baos.write(f.finish());
     52                buf = baos.toByteArray();
     53            }
     54            return buf;
     55        } catch (IOException ex) {
     56            _log.error("Error chaining filters", ex);
     57            return EMPTY;
     58        }
    6059    }
    61        
     60
    6261}
  • apps/httptunnel/java/src/net/i2p/httptunnel/filter/NullFilter.java

    r8a8e681 r17a1b11  
    1010     */
    1111    public byte[] filter(byte[] toFilter) {
    12         return toFilter;
     12        return toFilter;
    1313    }
    1414
     
    1717     */
    1818    public byte[] finish() {
    19         return EMPTY;
     19        return EMPTY;
    2020    }
    2121}
  • apps/httptunnel/java/src/net/i2p/httptunnel/handler/EepHandler.java

    r8a8e681 r17a1b11  
    11package net.i2p.httptunnel.handler;
     2
    23import java.io.BufferedInputStream;
    34import java.io.BufferedOutputStream;
     
    2728
    2829    protected ErrorHandler errorHandler;
    29    
    30     /* package private */ EepHandler(ErrorHandler eh) {
    31         errorHandler=eh;
     30
     31    /* package private */EepHandler(ErrorHandler eh) {
     32        errorHandler = eh;
    3233    }
    33    
     34
    3435    /**
    3536     * @param req the Request
     
    4142     */
    4243    public void handle(Request req, HTTPListener httpl, OutputStream out,
    43                        /* boolean fromProxy, */ String destination)
    44         throws IOException {
    45         SocketManagerProducer smp = httpl.getSMP();
    46         Destination dest = NamingService.getInstance().lookup(destination);
    47         if (dest == null) {
    48             errorHandler.handle(req, httpl, out,
    49                                 "Could not lookup host: "+destination);
    50             return;
    51         }
    52         I2PSocketManager sm = smp.getManager(destination);
    53         Filter f = new NullFilter(); //FIXME: use other filter
    54         req.setParam("Host: ", dest.toBase64());
    55         if (!handle(req, f, out, dest, sm)) {
    56             errorHandler.handle(req, httpl, out, "Unable to reach peer");
    57         }
     44    /* boolean fromProxy, */String destination) throws IOException {
     45        SocketManagerProducer smp = httpl.getSMP();
     46        Destination dest = NamingService.getInstance().lookup(destination);
     47        if (dest == null) {
     48            errorHandler.handle(req, httpl, out, "Could not lookup host: " + destination);
     49            return;
     50        }
     51        I2PSocketManager sm = smp.getManager(destination);
     52        Filter f = new NullFilter(); //FIXME: use other filter
     53        req.setParam("Host: ", dest.toBase64());
     54        if (!handle(req, f, out, dest, sm)) {
     55            errorHandler.handle(req, httpl, out, "Unable to reach peer");
     56        }
    5857    }
    5958
     
    6766     * @throws IOException
    6867     */
    69     public boolean handle(Request req, Filter f, OutputStream out,
    70                        Destination dest, I2PSocketManager sm)
    71     throws IOException {
    72         I2PSocket s = null;
    73         boolean written = false;
    74         try {
    75             synchronized(sm) {
    76                 s = sm.connect(dest, new I2PSocketOptions());
    77             }
    78             InputStream in = new BufferedInputStream(s.getInputStream());
    79             OutputStream sout = new BufferedOutputStream(s.getOutputStream());
    80             sout.write(req.toByteArray());
    81             sout.flush();
    82             byte[] buffer = new byte[16384], filtered;
    83             int len;
    84             while ((len=in.read(buffer)) != -1) {
    85                 if (len != buffer.length) {
    86                     byte[] b2 = new byte[len];
    87                     System.arraycopy(buffer, 0, b2, 0, len);
    88                     filtered=f.filter(b2);
    89                 } else {
    90                     filtered=f.filter(buffer);
    91                 }
    92                 written=true;
    93                 out.write(filtered);
    94             }
    95             filtered=f.finish();
    96             written=true;
    97             out.write(filtered);
    98             out.flush();
    99         } catch (IOException ex) {
    100             _log.error("Error while handling eepsite request");
    101             return written;
    102         } catch (I2PException ex) {
    103             _log.error("Error while handling eepsite request");
    104             return written;
    105         } finally {
    106             if (s != null) s.close();
    107         }
    108         return true;
     68    public boolean handle(Request req, Filter f, OutputStream out, Destination dest, I2PSocketManager sm)
     69                                                                                                         throws IOException {
     70        I2PSocket s = null;
     71        boolean written = false;
     72        try {
     73            synchronized (sm) {
     74                s = sm.connect(dest, new I2PSocketOptions());
     75            }
     76            InputStream in = new BufferedInputStream(s.getInputStream());
     77            OutputStream sout = new BufferedOutputStream(s.getOutputStream());
     78            sout.write(req.toByteArray());
     79            sout.flush();
     80            byte[] buffer = new byte[16384], filtered;
     81            int len;
     82            while ((len = in.read(buffer)) != -1) {
     83                if (len != buffer.length) {
     84                    byte[] b2 = new byte[len];
     85                    System.arraycopy(buffer, 0, b2, 0, len);
     86                    filtered = f.filter(b2);
     87                } else {
     88                    filtered = f.filter(buffer);
     89                }
     90                written = true;
     91                out.write(filtered);
     92            }
     93            filtered = f.finish();
     94            written = true;
     95            out.write(filtered);
     96            out.flush();
     97        } catch (IOException ex) {
     98            _log.error("Error while handling eepsite request");
     99            return written;
     100        } catch (I2PException ex) {
     101            _log.error("Error while handling eepsite request");
     102            return written;
     103        } finally {
     104            if (s != null) s.close();
     105        }
     106        return true;
    109107    }
    110108}
  • apps/httptunnel/java/src/net/i2p/httptunnel/handler/ErrorHandler.java

    r8a8e681 r17a1b11  
    11package net.i2p.httptunnel.handler;
     2
    23import java.io.IOException;
    34import java.io.OutputStream;
     
    1415    private static final Log _log = new Log(ErrorHandler.class);
    1516
    16     /* package private */ ErrorHandler() {
     17    /* package private */ErrorHandler() {
    1718
    1819    }
    19    
     20
    2021    /**
    2122     * @param req the Request
     
    2526     * @throws IOException
    2627     */
    27     public void handle(Request req, HTTPListener httpl,
    28                        OutputStream out, String error) throws IOException {
    29         // FIXME: Make nicer messages for more likely errors.
    30         out.write(("HTTP/1.1 500 Internal Server Error\r\n"+
    31                    "Content-Type: text/html; charset=iso-8859-1\r\n\r\n")
    32                   .getBytes("ISO-8859-1"));
    33         out.write(("<html><head><title>"+error+"</title></head><body><h1>"+
    34                    error+"</h1>An internal error occurred while "+
    35                    "handling a request by HTTPTunnel:<br><b>"+error+
    36                    "</b><h2>Complete request:</h2><b>---</b><br><i><pre>\r\n")
    37                   .getBytes("ISO-8859-1"));
    38         out.write(req.toByteArray());
    39         out.write(("</pre></i><br><b>---</b></body></html>")
    40                   .getBytes("ISO-8859-1"));
    41         out.flush();
     28    public void handle(Request req, HTTPListener httpl, OutputStream out, String error) throws IOException {
     29        // FIXME: Make nicer messages for more likely errors.
     30        out
     31           .write(("HTTP/1.1 500 Internal Server Error\r\n" + "Content-Type: text/html; charset=iso-8859-1\r\n\r\n")
     32                                                                                                                    .getBytes("ISO-8859-1"));
     33        out
     34           .write(("<html><head><title>" + error + "</title></head><body><h1>" + error
     35                   + "</h1>An internal error occurred while " + "handling a request by HTTPTunnel:<br><b>" + error + "</b><h2>Complete request:</h2><b>---</b><br><i><pre>\r\n")
     36                                                                                                                                                                                .getBytes("ISO-8859-1"));
     37        out.write(req.toByteArray());
     38        out.write(("</pre></i><br><b>---</b></body></html>").getBytes("ISO-8859-1"));
     39        out.flush();
    4240    }
    4341}
  • apps/httptunnel/java/src/net/i2p/httptunnel/handler/LocalHandler.java

    r8a8e681 r17a1b11  
    11package net.i2p.httptunnel.handler;
     2
    23import java.io.IOException;
    34import java.io.OutputStream;
     
    1516    private static final Log _log = new Log(LocalHandler.class);
    1617
    17     /* package private */ LocalHandler() {
     18    /* package private */LocalHandler() {
    1819    }
    19    
     20
    2021    /**
    2122     * @param req the Request
     
    2526     */
    2627    public void handle(Request req, HTTPListener httpl, OutputStream out
    27                        /*, boolean fromProxy */) throws IOException {
    28         //FIXME: separate multiple pages, not only a start page
    29         //FIXME: provide some info on this page
    30         out.write(("HTTP/1.1 200 Document following\r\n"+
    31                    "Content-Type: text/html; charset=iso-8859-1\r\n\r\n"+
    32                    "<html><head><title>Welcome to I2P HTTPTunnel</title>"+
    33                    "</head><body><h1>Welcome to I2P HTTPTunnel</h1>You can "+
    34                    "browse Eepsites by adding an eepsite name to the request."+
    35                    "</body></html>").getBytes("ISO-8859-1"));
    36         out.flush();
     28    /*, boolean fromProxy */) throws IOException {
     29        //FIXME: separate multiple pages, not only a start page
     30        //FIXME: provide some info on this page
     31        out
     32           .write(("HTTP/1.1 200 Document following\r\n" + "Content-Type: text/html; charset=iso-8859-1\r\n\r\n"
     33                   + "<html><head><title>Welcome to I2P HTTPTunnel</title>"
     34                   + "</head><body><h1>Welcome to I2P HTTPTunnel</h1>You can "
     35                   + "browse Eepsites by adding an eepsite name to the request." + "</body></html>")
     36                                                                                                    .getBytes("ISO-8859-1"));
     37        out.flush();
    3738    }
    3839
     
    4445     * @throws IOException
    4546     */
    46     public void handleProxyConfWarning(Request req, HTTPListener httpl,
    47                                        OutputStream out) throws IOException {
    48         //FIXME
     47    public void handleProxyConfWarning(Request req, HTTPListener httpl, OutputStream out) throws IOException {
     48        //FIXME
    4949        throw new IOException("jrandom ate the deprecated method. mooo");
    50         //httpl.handleNotImplemented(out);
     50        //httpl.handleNotImplemented(out);
    5151
    5252    }
     
    5959     * @throws IOException
    6060     */
    61     public void handleHTTPWarning(Request req, HTTPListener httpl,
    62                                   OutputStream out /*, boolean fromProxy */)
    63     throws IOException {
    64         // FIXME
     61    public void handleHTTPWarning(Request req, HTTPListener httpl, OutputStream out /*, boolean fromProxy */)
     62                                                                                                              throws IOException {
     63        // FIXME
    6564        throw new IOException("jrandom ate the deprecated method. mooo");
    66         //httpl.handleNotImplemented(out);
     65        //httpl.handleNotImplemented(out);
    6766    }
    6867}
  • apps/httptunnel/java/src/net/i2p/httptunnel/handler/ProxyHandler.java

    r8a8e681 r17a1b11  
    11package net.i2p.httptunnel.handler;
     2
    23import java.io.IOException;
    34import java.io.OutputStream;
     
    2021    private static final Log _log = new Log(ErrorHandler.class);
    2122
    22     /* package private */ ProxyHandler(ErrorHandler eh) {
    23         super(eh);
     23    /* package private */ProxyHandler(ErrorHandler eh) {
     24        super(eh);
    2425    }
    25    
     26
    2627    /**
    2728     * @param req a Request
     
    3132     */
    3233    public void handle(Request req, HTTPListener httpl, OutputStream out
    33                        /*, boolean fromProxy */) throws IOException {
    34         SocketManagerProducer smp = httpl.getSMP();
    35         Destination dest = findProxy();
    36         if (dest == null) {
    37             errorHandler.handle(req, httpl, out,
    38                                 "Could not find proxy");
    39             return;
    40         }
    41         // one manager for all proxy requests
    42         I2PSocketManager sm = smp.getManager("--proxy--");
    43         Filter f = new NullFilter(); //FIXME: use other filter
    44         if (!handle(req, f, out, dest, sm)) {
    45             errorHandler.handle(req, httpl, out, "Unable to reach peer");
    46         }
     34    /*, boolean fromProxy */) throws IOException {
     35        SocketManagerProducer smp = httpl.getSMP();
     36        Destination dest = findProxy();
     37        if (dest == null) {
     38            errorHandler.handle(req, httpl, out, "Could not find proxy");
     39            return;
     40        }
     41        // one manager for all proxy requests
     42        I2PSocketManager sm = smp.getManager("--proxy--");
     43        Filter f = new NullFilter(); //FIXME: use other filter
     44        if (!handle(req, f, out, dest, sm)) {
     45            errorHandler.handle(req, httpl, out, "Unable to reach peer");
     46        }
    4747    }
    4848
    4949    private Destination findProxy() {
    50         //FIXME!
    51         return NamingService.getInstance().lookup("squid.i2p");
     50        //FIXME!
     51        return NamingService.getInstance().lookup("squid.i2p");
    5252    }
    5353}
  • apps/httptunnel/java/src/net/i2p/httptunnel/handler/RootHandler.java

    r8a8e681 r17a1b11  
    11package net.i2p.httptunnel.handler;
     2
    23import java.io.IOException;
    34import java.io.OutputStream;
     
    1516
    1617    private RootHandler() {
    17         errorHandler=new ErrorHandler();
    18         localHandler=new LocalHandler();
    19         proxyHandler=new ProxyHandler(errorHandler);
    20         eepHandler=new EepHandler(errorHandler);
     18        errorHandler = new ErrorHandler();
     19        localHandler = new LocalHandler();
     20        proxyHandler = new ProxyHandler(errorHandler);
     21        eepHandler = new EepHandler(errorHandler);
    2122    }
    2223
     
    2526    private LocalHandler localHandler;
    2627    private EepHandler eepHandler;
    27    
     28
    2829    private static RootHandler instance;
    2930
     
    3334     */
    3435    public static synchronized RootHandler getInstance() {
    35         if (instance == null) {
    36             instance = new RootHandler();
    37         }
    38         return instance;
     36        if (instance == null) {
     37            instance = new RootHandler();
     38        }
     39        return instance;
    3940    }
    40    
     41
    4142    /**
    4243     * The _ROOT_ handler:  it passes its workload off to the other handlers.
     
    4647     * @throws IOException
    4748     */
    48     public void handle(Request req, HTTPListener httpl,
    49                        OutputStream out) throws IOException {
    50         String url=req.getURL();
    51         System.out.println(url);
    52         /* boolean byProxy = false; */
    53         int pos;
    54         if (url.startsWith("http://")) { // access via proxy
    55             /* byProxy=true; */
    56             if (httpl.firstProxyUse()) {
    57                 localHandler.handleProxyConfWarning(req,httpl,out);
    58                 return;
    59             }
    60             url = url.substring(7);
    61             pos = url.indexOf("/");
    62             String host;
    63             String rest;
    64             if (pos == -1) {
    65                 errorHandler.handle(req, httpl, out, "No host end in URL");
    66                 return;
    67             } else {
    68                 host = url.substring(0,pos);
    69                 url = url.substring(pos);
    70                 if ("i2p".equals(host) || "i2p.i2p".equals(host)) {
    71                     // normal request; go on below...
    72                 } else if (host.endsWith(".i2p")) {
    73                     // "old" service request, send a redirect...
    74                     out.write(("HTTP/1.1 302 Moved\r\nLocation: "+
    75                                "http://i2p.i2p/"+host+url+
    76                                "\r\n\r\n").getBytes("ISO-8859-1"));
    77                     return;
    78                 } else {
    79                     // this is for proxying to the real web
    80                     proxyHandler.handle(req, httpl, out /*, true */);
    81                     return;
    82                 }
    83             }
    84         }
    85         if (url.equals("/")) { // main page
    86             url="/_/local/index";
    87         } else if (!url.startsWith("/")) {
    88             errorHandler.handle(req, httpl, out,
    89                                 "No leading slash in URL: "+url);
    90             return;
    91         }
    92         String dest;
    93         url=url.substring(1);
    94         pos = url.indexOf("/");
    95         if (pos == -1) {
    96             dest=url;
    97             url="/";
    98         } else {
    99             dest = url.substring(0,pos);
    100             url=url.substring(pos);
    101         }
    102         req.setURL(url);
    103         if (dest.equals("_")) { // no eepsite
    104             if (url.startsWith("/local/")) { // local request
    105                 req.setURL(url.substring(6));
    106                 localHandler.handle(req, httpl, out /*, byProxy */);
    107             } else if (url.startsWith("/http/")) {  // http warning
    108                 localHandler.handleHTTPWarning(req, httpl, out /*, byProxy */);
    109             } else if (url.startsWith("/proxy/")) { // http proxying
    110                 req.setURL("http://"+url.substring(7));
    111                 proxyHandler.handle(req, httpl, out /*, byProxy */);
    112             } else {
    113                 errorHandler.handle(req, httpl, out,
    114                                     "No local handler for this URL: "+url);
    115             }
    116         } else {
    117             eepHandler.handle(req, httpl, out, /* byProxy, */ dest);
    118         }
     49    public void handle(Request req, HTTPListener httpl, OutputStream out) throws IOException {
     50        String url = req.getURL();
     51        System.out.println(url);
     52        /* boolean byProxy = false; */
     53        int pos;
     54        if (url.startsWith("http://")) { // access via proxy
     55            /* byProxy=true; */
     56            if (httpl.firstProxyUse()) {
     57                localHandler.handleProxyConfWarning(req, httpl, out);
     58                return;
     59            }
     60            url = url.substring(7);
     61            pos = url.indexOf("/");
     62            String host;
     63            String rest;
     64            if (pos == -1) {
     65                errorHandler.handle(req, httpl, out, "No host end in URL");
     66                return;
     67            } else {
     68                host = url.substring(0, pos);
     69                url = url.substring(pos);
     70                if ("i2p".equals(host) || "i2p.i2p".equals(host)) {
     71                    // normal request; go on below...
     72                } else if (host.endsWith(".i2p")) {
     73                    // "old" service request, send a redirect...
     74                    out
     75                       .write(("HTTP/1.1 302 Moved\r\nLocation: " + "http://i2p.i2p/" + host + url + "\r\n\r\n")
     76                                                                                                                .getBytes("ISO-8859-1"));
     77                    return;
     78                } else {
     79                    // this is for proxying to the real web
     80                    proxyHandler.handle(req, httpl, out /*, true */);
     81                    return;
     82                }
     83            }
     84        }
     85        if (url.equals("/")) { // main page
     86            url = "/_/local/index";
     87        } else if (!url.startsWith("/")) {
     88            errorHandler.handle(req, httpl, out, "No leading slash in URL: " + url);
     89            return;
     90        }
     91        String dest;
     92        url = url.substring(1);
     93        pos = url.indexOf("/");
     94        if (pos == -1) {
     95            dest = url;
     96            url = "/";
     97        } else {
     98            dest = url.substring(0, pos);
     99            url = url.substring(pos);
     100        }
     101        req.setURL(url);
     102        if (dest.equals("_")) { // no eepsite
     103            if (url.startsWith("/local/")) { // local request
     104                req.setURL(url.substring(6));
     105                localHandler.handle(req, httpl, out /*, byProxy */);
     106            } else if (url.startsWith("/http/")) { // http warning
     107                localHandler.handleHTTPWarning(req, httpl, out /*, byProxy */);
     108            } else if (url.startsWith("/proxy/")) { // http proxying
     109                req.setURL("http://" + url.substring(7));
     110                proxyHandler.handle(req, httpl, out /*, byProxy */);
     111            } else {
     112                errorHandler.handle(req, httpl, out, "No local handler for this URL: " + url);
     113            }
     114        } else {
     115            eepHandler.handle(req, httpl, out, /* byProxy, */dest);
     116        }
    119117    }
    120118}
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/BufferLogger.java

    r8a8e681 r17a1b11  
    1717    private ByteArrayOutputStream _baos;
    1818    private boolean _ignore;
    19    
     19
    2020    public BufferLogger() {
    21         _baos = new ByteArrayOutputStream(512);
    22         _ignore = false;
     21        _baos = new ByteArrayOutputStream(512);
     22        _ignore = false;
    2323    }
    2424
    2525    private final static String EMPTY = "";
    26     public String getBuffer() {
    27         if (_ignore) return EMPTY;
    28         else return new String(_baos.toByteArray());
     26
     27    public String getBuffer() {
     28        if (_ignore)
     29            return EMPTY;
     30        else
     31            return new String(_baos.toByteArray());
    2932    }
    3033
     
    3740     */
    3841    public void ignoreFurtherActions() {
    39         _ignore = true;
    40         synchronized (_baos) {
    41             _baos.reset();
    42         }
    43         _baos = null;
     42        _ignore = true;
     43        synchronized (_baos) {
     44            _baos.reset();
     45        }
     46        _baos = null;
    4447    }
    45    
     48
    4649    /**
    4750     * Pass in some random data
     
    4952     */
    5053    public void log(String s) {
    51         if (_ignore) return;
    52         if (s != null) {
    53             _log.debug("logging [" + s + "]");
    54             try {
    55                 _baos.write(s.getBytes());
    56                 _baos.write('\n');
    57             } catch (IOException ioe) {
    58                 _log.error("Error logging [" + s + "]");
    59             }
    60         }
     54        if (_ignore) return;
     55        if (s != null) {
     56            _log.debug("logging [" + s + "]");
     57            try {
     58                _baos.write(s.getBytes());
     59                _baos.write('\n');
     60            } catch (IOException ioe) {
     61                _log.error("Error logging [" + s + "]");
     62            }
     63        }
    6164    }
    6265}
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java

    r8a8e681 r17a1b11  
    6363import net.i2p.util.Log;
    6464
    65 
    6665public class I2PTunnel implements Logging, EventDispatcher {
    6766    private final static Log _log = new Log(I2PTunnel.class);
    6867    private final EventDispatcherImpl _event = new EventDispatcherImpl();
    6968
    70     public static final int PACKET_DELAY=100;
     69    public static final int PACKET_DELAY = 100;
    7170
    7271    public static boolean ownDest = false;
    7372
    74     public static String port =
    75         System.getProperty(I2PClient.PROP_TCP_PORT, "7654");
    76     public static String host = System.getProperty
    77         (I2PClient.PROP_TCP_HOST,"127.0.0.1");
     73    public static String port = System.getProperty(I2PClient.PROP_TCP_PORT, "7654");
     74    public static String host = System.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1");
    7875    public static String listenHost = host;
    7976
    80     private static final String nocli_args[] = {"-nocli", "-die"};
    81 
    82     private List tasks=new ArrayList();
     77    private static final String nocli_args[] = { "-nocli", "-die"};
     78
     79    private List tasks = new ArrayList();
    8380    private int next_task_id = 1;
    84    
     81
    8582    private Set listeners = new HashSet();
    86    
     83
    8784    public static void main(String[] args) throws IOException {
    88         new I2PTunnel(args);
     85        new I2PTunnel(args);
    8986    }
    9087
     
    9491
    9592    public I2PTunnel(String[] args) {
    96         this(args, null);
    97     }
     93        this(args, null);
     94    }
     95
    9896    public I2PTunnel(String[] args, ConnectionEventListener lsnr) {
    99         addConnectionEventListener(lsnr);
    100         boolean gui=true;
    101         boolean checkRunByE = true;;
    102         boolean cli=true;
    103         boolean dontDie = true;
    104         for(int i=0;i<args.length;i++) {
    105             if (args[i].equals("-die")) {
    106                 dontDie = false;
    107                 gui=false;
    108                 cli=false;
    109                 checkRunByE=false;
    110             } else if (args[i].equals("-nogui")) {
    111                 gui=false;
    112                 _log.warn("The `-nogui' option of I2PTunnel is deprecated.\n"+
    113                           "Use `-cli', `-nocli' (aka `-wait') or `-die' instead.");
    114             } else if (args[i].equals("-cli")) {
    115                 gui=false;
    116                 cli=true;
    117                 checkRunByE=false;
    118             } else if (args[i].equals("-nocli") || args[i].equals("-wait")) {
    119                 gui=false;
    120                 cli=false;
    121                 checkRunByE=false;
    122             } else if (args[i].equals("-e")) {
    123                 runCommand(args[i+1], this);
    124                 i++;
    125                 if (checkRunByE) {
    126                     checkRunByE = false;
    127                     cli=false;
    128                 }
    129             } else if (new File(args[i]).exists()) {
    130                 runCommand("run "+args[i], this);
    131             } else {
    132                 System.out.println("Unknown parameter "+args[i]);
    133             }
    134         }
    135         if (gui) {
    136             new I2PTunnelGUI(this);
    137         } else if (cli) {
    138                 try {
    139                     System.out.println("Enter 'help' for help.");
    140                     BufferedReader r = new BufferedReader
    141                         (new InputStreamReader(System.in));
    142                     while(true) {
    143                         System.out.print("I2PTunnel>");
    144                         String cmd = r.readLine();
    145                         if (cmd == null) break;
    146                         runCommand(cmd, this);
    147                     }
    148                 } catch (IOException ex) {
    149                     ex.printStackTrace();
    150                 }
    151         }
    152        
    153         while (dontDie) {
    154             synchronized (this) {
    155                 try { wait(); } catch (InterruptedException ie) {}
    156             }
    157         }
    158     }
    159    
    160     private void addtask (I2PTunnelTask tsk)
    161     {
    162         tsk.setTunnel(this);
    163         if (tsk.isOpen()) {
    164             tsk.setId(next_task_id);
    165             next_task_id++;
    166             synchronized (tasks) {
    167                 tasks.add(tsk);
    168             }
    169         }
     97        addConnectionEventListener(lsnr);
     98        boolean gui = true;
     99        boolean checkRunByE = true;
     100        boolean cli = true;
     101        boolean dontDie = true;
     102        for (int i = 0; i < args.length; i++) {
     103            if (args[i].equals("-die")) {
     104                dontDie = false;
     105                gui = false;
     106                cli = false;
     107                checkRunByE = false;
     108            } else if (args[i].equals("-nogui")) {
     109                gui = false;
     110                _log.warn("The `-nogui' option of I2PTunnel is deprecated.\n"
     111                          + "Use `-cli', `-nocli' (aka `-wait') or `-die' instead.");
     112            } else if (args[i].equals("-cli")) {
     113                gui = false;
     114                cli = true;
     115                checkRunByE = false;
     116            } else if (args[i].equals("-nocli") || args[i].equals("-wait")) {
     117                gui = false;
     118                cli = false;
     119                checkRunByE = false;
     120            } else if (args[i].equals("-e")) {
     121                runCommand(args[i + 1], this);
     122                i++;
     123                if (checkRunByE) {
     124                    checkRunByE = false;
     125                    cli = false;
     126                }
     127            } else if (new File(args[i]).exists()) {
     128                runCommand("run " + args[i], this);
     129            } else {
     130                System.out.println("Unknown parameter " + args[i]);
     131            }
     132        }
     133        if (gui) {
     134            new I2PTunnelGUI(this);
     135        } else if (cli) {
     136            try {
     137                System.out.println("Enter 'help' for help.");
     138                BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
     139                while (true) {
     140                    System.out.print("I2PTunnel>");
     141                    String cmd = r.readLine();
     142                    if (cmd == null) break;
     143                    runCommand(cmd, this);
     144                }
     145            } catch (IOException ex) {
     146                ex.printStackTrace();
     147            }
     148        }
     149
     150        while (dontDie) {
     151            synchronized (this) {
     152                try {
     153                    wait();
     154                } catch (InterruptedException ie) {
     155                }
     156            }
     157        }
     158    }
     159
     160    private void addtask(I2PTunnelTask tsk) {
     161        tsk.setTunnel(this);
     162        if (tsk.isOpen()) {
     163            tsk.setId(next_task_id);
     164            next_task_id++;
     165            synchronized (tasks) {
     166                tasks.add(tsk);
     167            }
     168        }
    170169    }
    171170
     
    173172     */
    174173    private static String[] split(String src, String delim) {
    175         StringTokenizer tok = new StringTokenizer(src, delim);
    176         String vals[] = new String[tok.countTokens()];
    177         for (int i = 0; i < vals.length; i++)
    178             vals[i] = tok.nextToken();
    179         return vals;
    180     }
     174        StringTokenizer tok = new StringTokenizer(src, delim);
     175        String vals[] = new String[tok.countTokens()];
     176        for (int i = 0; i < vals.length; i++)
     177            vals[i] = tok.nextToken();
     178        return vals;
     179    }
     180
    181181    public void runCommand(String cmd, Logging l) {
    182         if (cmd.indexOf(" ")== -1) cmd+=" ";
    183         int iii=cmd.indexOf(" ");
    184         String cmdname= cmd.substring(0,iii).toLowerCase();
    185         String allargs = cmd.substring(iii+1);
    186         String[] args = split(allargs, " "); // .split(" "); // java 1.4
    187        
    188         if ("help".equals(cmdname)) {
    189             runHelp(l);
    190         } else if ("server".equals(cmdname)) {
    191             runServer(args, l);
    192         } else if ("textserver".equals(cmdname)) {
    193             runTextServer(args, l);
    194         } else if ("client".equals(cmdname)) {
    195             runClient(args, l);
    196         } else if ("httpclient".equals(cmdname)) {
    197             runHttpClient(args, l);
    198         } else if ("sockstunnel".equals(cmdname)) {
    199             runSOCKSTunnel(args, l);
    200         } else if ("config".equals(cmdname)) {
    201             runConfig(args, l);
    202         } else if ("listen_on".equals(cmdname)) {
    203             runListenOn(args, l);
    204         } else if ("genkeys".equals(cmdname)) {
    205             runGenKeys(args, l);
    206         } else if ("gentextkeys".equals(cmdname)) {
    207             runGenTextKeys(l);
    208         } else if (cmdname.equals("quit")) {
    209             runQuit(l);
    210         } else if (cmdname.equals("list")) {
    211             runList(l);
    212         } else if (cmdname.equals("close")) {
    213             runClose(args, l);
    214         } else if (cmdname.equals("run")) {
    215             runRun(args, l);
    216         } else if (cmdname.equals("lookup")) {
    217             runLookup(args, l);
    218         } else if (cmdname.equals("ping")) {
    219             runPing(allargs, l);
    220         } else if (cmdname.equals("owndest")) {
    221             runOwnDest(args, l);
    222         } else {
    223             l.log("Unknown command [" + cmdname + "]");
    224         }
    225     }
    226        
     182        if (cmd.indexOf(" ") == -1) cmd += " ";
     183        int iii = cmd.indexOf(" ");
     184        String cmdname = cmd.substring(0, iii).toLowerCase();
     185        String allargs = cmd.substring(iii + 1);
     186        String[] args = split(allargs, " "); // .split(" "); // java 1.4
     187
     188        if ("help".equals(cmdname)) {
     189            runHelp(l);
     190        } else if ("server".equals(cmdname)) {
     191            runServer(args, l);
     192        } else if ("textserver".equals(cmdname)) {
     193            runTextServer(args, l);
     194        } else if ("client".equals(cmdname)) {
     195            runClient(args, l);
     196        } else if ("httpclient".equals(cmdname)) {
     197            runHttpClient(args, l);
     198        } else if ("sockstunnel".equals(cmdname)) {
     199            runSOCKSTunnel(args, l);
     200        } else if ("config".equals(cmdname)) {
     201            runConfig(args, l);
     202        } else if ("listen_on".equals(cmdname)) {
     203            runListenOn(args, l);
     204        } else if ("genkeys".equals(cmdname)) {
     205            runGenKeys(args, l);
     206        } else if ("gentextkeys".equals(cmdname)) {
     207            runGenTextKeys(l);
     208        } else if (cmdname.equals("quit")) {
     209            runQuit(l);
     210        } else if (cmdname.equals("list")) {
     211            runList(l);
     212        } else if (cmdname.equals("close")) {
     213            runClose(args, l);
     214        } else if (cmdname.equals("run")) {
     215            runRun(args, l);
     216        } else if (cmdname.equals("lookup")) {
     217            runLookup(args, l);
     218        } else if (cmdname.equals("ping")) {
     219            runPing(allargs, l);
     220        } else if (cmdname.equals("owndest")) {
     221            runOwnDest(args, l);
     222        } else {
     223            l.log("Unknown command [" + cmdname + "]");
     224        }
     225    }
     226
    227227    /**
    228228     * Display help information through the given logger.
     
    233233     */
    234234    public void runHelp(Logging l) {
    235         l.log("Command list:");
    236         l.log("config <i2phost> <i2pport>");
    237         l.log("listen_on <ip>");
    238         l.log("owndest yes|no");
    239         l.log("ping <args>");
    240         l.log("server <host> <port> <privkeyfile>");
    241         l.log("textserver <host> <port> <privkey>");
    242         l.log("genkeys <privkeyfile> [<pubkeyfile>]");
    243         l.log("gentextkeys");
    244         l.log("client <port> <pubkey>|file:<pubkeyfile>");
    245         l.log("httpclient <port>");
    246         l.log("lookup <name>");
    247         l.log("quit");
    248         l.log("close [forced] <jobnumber>|all");
    249         l.log("list");
    250         l.log("run <commandfile>");
    251     }
    252    
     235        l.log("Command list:");
     236        l.log("config <i2phost> <i2pport>");
     237        l.log("listen_on <ip>");
     238        l.log("owndest yes|no");
     239        l.log("ping <args>");
     240        l.log("server <host> <port> <privkeyfile>");
     241        l.log("textserver <host> <port> <privkey>");
     242        l.log("genkeys <privkeyfile> [<pubkeyfile>]");
     243        l.log("gentextkeys");
     244        l.log("client <port> <pubkey>|file:<pubkeyfile>");
     245        l.log("httpclient <port>");
     246        l.log("lookup <name>");
     247        l.log("quit");
     248        l.log("close [forced] <jobnumber>|all");
     249        l.log("list");
     250        l.log("run <commandfile>");
     251    }
     252
    253253    /**
    254254     * Run the server pointing at the host and port specified using the private i2p
     
    263263     */
    264264    public void runServer(String args[], Logging l) {
    265         if (args.length==3) {
    266             InetAddress serverHost = null;
    267             int portNum = -1;
    268             File privKeyFile = null;
    269             try {
    270                 serverHost = InetAddress.getByName(args[0]);
    271             } catch (UnknownHostException uhe) {
    272                 l.log("unknown host");
    273                 _log.error("Error resolving " + args[0], uhe);
    274                 notifyEvent("serverTaskId", new Integer(-1));
    275                 return;
    276             }
    277            
    278             try {
    279                 portNum = Integer.parseInt(args[1]);
    280             } catch (NumberFormatException nfe) {
    281                 l.log("invalid port");
    282                 _log.error("Port specified is not valid: " + args[1], nfe);
    283                 notifyEvent("serverTaskId", new Integer(-1));
    284                 return;
    285             }
    286            
    287             privKeyFile = new File(args[2]);
    288             if (!privKeyFile.canRead()) {
    289                 l.log("private key file does not exist");
    290                 _log.error("Private key file does not exist or is not readable: " + args[2]);
    291                 notifyEvent("serverTaskId", new Integer(-1));
    292                 return;
    293             }
    294             I2PTunnelTask task;
    295             task = new I2PTunnelServer(serverHost, portNum, privKeyFile,
    296                                        args[2], l, (EventDispatcher)this);
    297             addtask(task);
    298             notifyEvent("serverTaskId", new Integer(task.getId()));
    299             return;
    300         } else {
    301             l.log("server <host> <port> <privkeyfile>");
    302             l.log("  creates a server that sends all incoming data\n"+
    303                   "  of its destination to host:port.");
    304             notifyEvent("serverTaskId", new Integer(-1));
    305         }
    306     }
    307    
     265        if (args.length == 3) {
     266            InetAddress serverHost = null;
     267            int portNum = -1;
     268            File privKeyFile = null;
     269            try {
     270                serverHost = InetAddress.getByName(args[0]);
     271            } catch (UnknownHostException uhe) {
     272                l.log("unknown host");
     273                _log.error("Error resolving " + args[0], uhe);
     274                notifyEvent("serverTaskId", new Integer(-1));
     275                return;
     276            }
     277
     278            try {
     279                portNum = Integer.parseInt(args[1]);
     280            } catch (NumberFormatException nfe) {
     281                l.log("invalid port");
     282                _log.error("Port specified is not valid: " + args[1], nfe);
     283                notifyEvent("serverTaskId", new Integer(-1));
     284                return;
     285            }
     286
     287            privKeyFile = new File(args[2]);
     288            if (!privKeyFile.canRead()) {
     289                l.log("private key file does not exist");
     290                _log.error("Private key file does not exist or is not readable: " + args[2]);
     291                notifyEvent("serverTaskId", new Integer(-1));
     292                return;
     293            }
     294            I2PTunnelTask task;
     295            task = new I2PTunnelServer(serverHost, portNum, privKeyFile, args[2], l, (EventDispatcher) this);
     296            addtask(task);
     297            notifyEvent("serverTaskId", new Integer(task.getId()));
     298            return;
     299        } else {
     300            l.log("server <host> <port> <privkeyfile>");
     301            l.log("  creates a server that sends all incoming data\n" + "  of its destination to host:port.");
     302            notifyEvent("serverTaskId", new Integer(-1));
     303        }
     304    }
     305
    308306    /**
    309307     * Run the server pointing at the host and port specified using the private i2p
     
    318316     */
    319317    public void runTextServer(String args[], Logging l) {
    320         if (args.length==3) {
    321             InetAddress serverHost = null;
    322             int portNum = -1;
    323             try {
    324                 serverHost = InetAddress.getByName(args[0]);
    325             } catch (UnknownHostException uhe) {
    326                 l.log("unknown host");
    327                 _log.error("Error resolving " + args[0], uhe);
    328                 notifyEvent("serverTaskId", new Integer(-1));
    329                 return;
    330             }
    331            
    332             try {
    333                 portNum = Integer.parseInt(args[1]);
    334             } catch (NumberFormatException nfe) {
    335                 l.log("invalid port");
    336                 _log.error("Port specified is not valid: " + args[1], nfe);
    337                 notifyEvent("serverTaskId", new Integer(-1));
    338                 return;
    339             }
    340            
    341             I2PTunnelTask task;
    342             task = new I2PTunnelServer(serverHost, portNum, args[2], l,
    343                                        (EventDispatcher)this);
    344             addtask(task);
    345             notifyEvent("serverTaskId", new Integer(task.getId()));
    346         } else {
    347             l.log("textserver <host> <port> <privkey>");
    348             l.log("  creates a server that sends all incoming data\n"+
    349                   "  of its destination to host:port.");
    350             notifyEvent("textserverTaskId", new Integer(-1));
    351         }
    352     }
    353    
     318        if (args.length == 3) {
     319            InetAddress serverHost = null;
     320            int portNum = -1;
     321            try {
     322                serverHost = InetAddress.getByName(args[0]);
     323            } catch (UnknownHostException uhe) {
     324                l.log("unknown host");
     325                _log.error("Error resolving " + args[0], uhe);
     326                notifyEvent("serverTaskId", new Integer(-1));
     327                return;
     328            }
     329
     330            try {
     331                portNum = Integer.parseInt(args[1]);
     332            } catch (NumberFormatException nfe) {
     333                l.log("invalid port");
     334                _log.error("Port specified is not valid: " + args[1], nfe);
     335                notifyEvent("serverTaskId", new Integer(-1));
     336                return;
     337            }
     338
     339            I2PTunnelTask task;
     340            task = new I2PTunnelServer(serverHost, portNum, args[2], l, (EventDispatcher) this);
     341            addtask(task);
     342            notifyEvent("serverTaskId", new Integer(task.getId()));
     343        } else {
     344            l.log("textserver <host> <port> <privkey>");
     345            l.log("  creates a server that sends all incoming data\n" + "  of its destination to host:port.");
     346            notifyEvent("textserverTaskId", new Integer(-1));
     347        }
     348    }
     349
    354350    /**
    355351     * Run the client on the given port number pointing at the specified destination
     
    365361     */
    366362    public void runClient(String args[], Logging l) {
    367         if (args.length==2) {
    368             int port = -1;
    369             try {
    370                 port = Integer.parseInt(args[0]);
    371             } catch (NumberFormatException nfe) {
    372                 l.log("invalid port");
    373                 _log.error("Port specified is not valid: " + args[0], nfe);
    374                 notifyEvent("clientTaskId", new Integer(-1));
    375                 return;
    376             }
    377             I2PTunnelTask task;
    378             task = new I2PTunnelClient(port, args[1], l, ownDest,
    379                                        (EventDispatcher)this);
    380             addtask(task);
    381             notifyEvent("clientTaskId", new Integer(task.getId()));
    382         } else {
    383             l.log("client <port> <pubkey>|file:<pubkeyfile>");
    384             l.log("  creates a client that forwards port to the pubkey.\n"+
    385           "  use 0 as port to get a free port assigned.");
    386             notifyEvent("clientTaskId", new Integer(-1));
    387         }
    388     }
    389    
     363        if (args.length == 2) {
     364            int port = -1;
     365            try {
     366                port = Integer.parseInt(args[0]);
     367            } catch (NumberFormatException nfe) {
     368                l.log("invalid port");
     369                _log.error("Port specified is not valid: " + args[0], nfe);
     370                notifyEvent("clientTaskId", new Integer(-1));
     371                return;
     372            }
     373            I2PTunnelTask task;
     374            task = new I2PTunnelClient(port, args[1], l, ownDest, (EventDispatcher) this);
     375            addtask(task);
     376            notifyEvent("clientTaskId", new Integer(task.getId()));
     377        } else {
     378            l.log("client <port> <pubkey>|file:<pubkeyfile>");
     379            l.log("  creates a client that forwards port to the pubkey.\n"
     380                  + "  use 0 as port to get a free port assigned.");
     381            notifyEvent("clientTaskId", new Integer(-1));
     382        }
     383    }
     384
    390385    /**
    391386     * Run an HTTP client on the given port number
     
    398393     */
    399394    public void runHttpClient(String args[], Logging l) {
    400         if (args.length >= 1 && args.length <= 2) {
    401             int port = -1;
    402             try {
    403                 port = Integer.parseInt(args[0]);
    404             } catch (NumberFormatException nfe) {
    405                 l.log("invalid port");
    406                 _log.error("Port specified is not valid: " + args[0], nfe);
    407                 notifyEvent("httpclientTaskId", new Integer(-1));
    408                 return;
    409             }
    410            
    411             String proxy = "squid.i2p";
    412             if (args.length == 2) {
    413                 proxy = args[1];
    414             }
    415             I2PTunnelTask task;
    416             task = new I2PTunnelHTTPClient(port, l, ownDest, proxy,
    417                                            (EventDispatcher)this);
    418             addtask(task);
    419             notifyEvent("httpclientTaskId", new Integer(task.getId()));
    420         } else {
    421             l.log("httpclient <port> [<proxy>]");
    422             l.log("  creates a client that distributes HTTP requests.");
    423             l.log("  <proxy> (optional) indicates a proxy server to be used");
    424             l.log("  when trying to access an address out of the .i2p domain");
    425             l.log("  (the default proxy is squid.i2p).");
    426             notifyEvent("httpclientTaskId", new Integer(-1));
    427         }
     395        if (args.length >= 1 && args.length <= 2) {
     396            int port = -1;
     397            try {
     398                port = Integer.parseInt(args[0]);
     399            } catch (NumberFormatException nfe) {
     400                l.log("invalid port");
     401                _log.error("Port specified is not valid: " + args[0], nfe);
     402                notifyEvent("httpclientTaskId", new Integer(-1));
     403                return;
     404            }
     405
     406            String proxy = "squid.i2p";
     407            if (args.length == 2) {
     408                proxy = args[1];
     409            }
     410            I2PTunnelTask task;
     411            task = new I2PTunnelHTTPClient(port, l, ownDest, proxy, (EventDispatcher) this);
     412            addtask(task);
     413            notifyEvent("httpclientTaskId", new Integer(task.getId()));
     414        } else {
     415            l.log("httpclient <port> [<proxy>]");
     416            l.log("  creates a client that distributes HTTP requests.");
     417            l.log("  <proxy> (optional) indicates a proxy server to be used");
     418            l.log("  when trying to access an address out of the .i2p domain");
     419            l.log("  (the default proxy is squid.i2p).");
     420            notifyEvent("httpclientTaskId", new Integer(-1));
     421        }
    428422    }
    429423
     
    440434     */
    441435    public void runSOCKSTunnel(String args[], Logging l) {
    442         if (args.length >= 1 && args.length <= 2) {
    443             int port = -1;
    444             try {
    445                 port = Integer.parseInt(args[0]);
    446             } catch (NumberFormatException nfe) {
    447                 l.log("invalid port");
    448                 _log.error("Port specified is not valid: " + args[0], nfe);
    449                 notifyEvent("sockstunnelTaskId", new Integer(-1));
    450                 return;
    451             }
    452            
    453             I2PTunnelTask task;
    454             task = new I2PSOCKSTunnel(port, l, ownDest, (EventDispatcher)this);
    455             addtask(task);
    456             notifyEvent("sockstunnelTaskId", new Integer(task.getId()));
    457         } else {
    458             l.log("sockstunnel <port>");
    459             l.log("  creates a tunnel that distributes SOCKS requests.");
    460             notifyEvent("sockstunnelTaskId", new Integer(-1));
    461         }
    462     }
    463    
     436        if (args.length >= 1 && args.length <= 2) {
     437            int port = -1;
     438            try {
     439                port = Integer.parseInt(args[0]);
     440            } catch (NumberFormatException nfe) {
     441                l.log("invalid port");
     442                _log.error("Port specified is not valid: " + args[0], nfe);
     443                notifyEvent("sockstunnelTaskId", new Integer(-1));
     444                return;
     445            }
     446
     447            I2PTunnelTask task;
     448            task = new I2PSOCKSTunnel(port, l, ownDest, (EventDispatcher) this);
     449            addtask(task);
     450            notifyEvent("sockstunnelTaskId", new Integer(task.getId()));
     451        } else {
     452            l.log("sockstunnel <port>");
     453            l.log("  creates a tunnel that distributes SOCKS requests.");
     454            notifyEvent("sockstunnelTaskId", new Integer(-1));
     455        }
     456    }
     457
    464458    /**
    465459     * Specify the i2cp host and port
     
    471465     */
    472466    public void runConfig(String args[], Logging l) {
    473         if (args.length==2) {
    474             host=args[0];
    475             listenHost=host;
    476             port=args[1];
    477             notifyEvent("configResult", "ok");
    478         } else {
    479             l.log("config <i2phost> <i2pport>");
    480             l.log("  sets the connection to the i2p router.");
    481             notifyEvent("configResult", "error");
    482         }
     467        if (args.length == 2) {
     468            host = args[0];
     469            listenHost = host;
     470            port = args[1];
     471            notifyEvent("configResult", "ok");
     472        } else {
     473            l.log("config <i2phost> <i2pport>");
     474            l.log("  sets the connection to the i2p router.");
     475            notifyEvent("configResult", "error");
     476        }
    483477    }
    484478
     
    492486     */
    493487    public void runOwnDest(String args[], Logging l) {
    494         if (args.length==1 &&
    495             (args[0].equalsIgnoreCase("yes")
    496              || args[0].equalsIgnoreCase("no"))) {
    497             ownDest = args[0].equalsIgnoreCase("yes");
    498             notifyEvent("owndestResult", "ok");
    499         } else {
    500             l.log("owndest yes|no");
    501             l.log("  Specifies whether to use its own destination \n"+
    502                   "  for each outgoing tunnel");
    503             notifyEvent("owndestResult", "error");
    504         }
     488        if (args.length == 1 && (args[0].equalsIgnoreCase("yes") || args[0].equalsIgnoreCase("no"))) {
     489            ownDest = args[0].equalsIgnoreCase("yes");
     490            notifyEvent("owndestResult", "ok");
     491        } else {
     492            l.log("owndest yes|no");
     493            l.log("  Specifies whether to use its own destination \n" + "  for each outgoing tunnel");
     494            notifyEvent("owndestResult", "error");
     495        }
    505496    }
    506497
     
    514505     */
    515506    public void runListenOn(String args[], Logging l) {
    516         if (args.length==1) {
    517             listenHost=args[0];
    518             notifyEvent("listen_onResult", "ok");
    519         } else {
    520             l.log("listen_on <ip>");
    521             l.log("  sets the interface to listen for the I2PClient.");
    522             notifyEvent("listen_onResult", "ok");
    523         }
    524     }
    525    
     507        if (args.length == 1) {
     508            listenHost = args[0];
     509            notifyEvent("listen_onResult", "ok");
     510        } else {
     511            l.log("listen_on <ip>");
     512            l.log("  sets the interface to listen for the I2PClient.");
     513            notifyEvent("listen_onResult", "ok");
     514        }
     515    }
     516
    526517    /**
    527518     * Generate a new keypair
     
    533524     */
    534525    public void runGenKeys(String args[], Logging l) {
    535         OutputStream pubdest=null;
    536         if (args.length == 2) {
    537             try {
    538                 pubdest=new FileOutputStream(args[1]);
    539             } catch (IOException ioe) {
    540                 l.log("Error opening output stream");
    541                 _log.error("Error generating keys to out", ioe);
    542                 notifyEvent("genkeysResult", "error");
    543                 return;
    544             }
    545         } else if (args.length != 1) {
    546             l.log("genkeys <privkeyfile> [<pubkeyfile>]");
    547             l.log("   creates a new keypair and prints the public key.\n"+
    548                   "   if pubkeyfile is given, saves the public key there."+
    549                   "\n"+
    550                   "   if the privkeyfile already exists, just print/save"+
    551                   "the pubkey.");
    552             notifyEvent("genkeysResult", "error");
    553         }
    554         try {
    555             File privKeyFile = new File(args[0]);
    556             if (privKeyFile.exists()) {
    557                 l.log("File already exists.");
    558                 showKey(new FileInputStream(privKeyFile), pubdest, l);
    559             } else {
    560                 makeKey(new FileOutputStream(privKeyFile), pubdest, l);
    561             }
    562             notifyEvent("genkeysResult", "ok");
    563         } catch (IOException ioe) {
    564             l.log("Error generating keys - " + ioe.getMessage());
    565             notifyEvent("genkeysResult", "error");
    566             _log.error("Error generating keys", ioe);
    567         }
    568     }
    569    
     526        OutputStream pubdest = null;
     527        if (args.length == 2) {
     528            try {
     529                pubdest = new FileOutputStream(args[1]);
     530            } catch (IOException ioe) {
     531                l.log("Error opening output stream");
     532                _log.error("Error generating keys to out", ioe);
     533                notifyEvent("genkeysResult", "error");
     534                return;
     535            }
     536        } else if (args.length != 1) {
     537            l.log("genkeys <privkeyfile> [<pubkeyfile>]");
     538            l.log("   creates a new keypair and prints the public key.\n"
     539                  + "   if pubkeyfile is given, saves the public key there." + "\n"
     540                  + "   if the privkeyfile already exists, just print/save" + "the pubkey.");
     541            notifyEvent("genkeysResult", "error");
     542        }
     543        try {
     544            File privKeyFile = new File(args[0]);
     545            if (privKeyFile.exists()) {
     546                l.log("File already exists.");
     547                showKey(new FileInputStream(privKeyFile), pubdest, l);
     548            } else {
     549                makeKey(new FileOutputStream(privKeyFile), pubdest, l);
     550            }
     551            notifyEvent("genkeysResult", "ok");
     552        } catch (IOException ioe) {
     553            l.log("Error generating keys - " + ioe.getMessage());
     554            notifyEvent("genkeysResult", "error");
     555            _log.error("Error generating keys", ioe);
     556        }
     557    }
     558
    570559    /**
    571560     * Generate a new keypair
     
    577566     */
    578567    public void runGenTextKeys(Logging l) {
    579         ByteArrayOutputStream privkey = new ByteArrayOutputStream(512);
    580         ByteArrayOutputStream pubkey = new ByteArrayOutputStream(512);
    581         makeKey(privkey, pubkey, l);
    582         l.log("Private key: "+Base64.encode(privkey.toByteArray()));
    583         notifyEvent("privateKey", Base64.encode(privkey.toByteArray()));
    584         notifyEvent("publicDestination", Base64.encode(pubkey.toByteArray()));
    585     }
    586    
     568        ByteArrayOutputStream privkey = new ByteArrayOutputStream(512);
     569        ByteArrayOutputStream pubkey = new ByteArrayOutputStream(512);
     570        makeKey(privkey, pubkey, l);
     571        l.log("Private key: " + Base64.encode(privkey.toByteArray()));
     572        notifyEvent("privateKey", Base64.encode(privkey.toByteArray()));
     573        notifyEvent("publicDestination", Base64.encode(pubkey.toByteArray()));
     574    }
     575
    587576    /**
    588577     * Exit the JVM if there are no more tasks left running.  If there are tunnels
     
    595584     */
    596585    public void runQuit(Logging l) {
    597         purgetasks(l);
    598         synchronized (tasks) {
    599             if (tasks.isEmpty()) {
    600                 System.exit(0);
    601             }
    602         }
    603         l.log("There are running tasks. Try 'list'.");
    604         notifyEvent("quitResult", "error");
    605     }
    606    
     586        purgetasks(l);
     587        synchronized (tasks) {
     588            if (tasks.isEmpty()) {
     589                System.exit(0);
     590            }
     591        }
     592        l.log("There are running tasks. Try 'list'.");
     593        notifyEvent("quitResult", "error");
     594    }
     595
    607596    /**
    608597     * Retrieve a list of currently running tasks
     
    614603     */
    615604    public void runList(Logging l) {
    616         purgetasks(l);
    617         synchronized (tasks) {
    618             for (int i=0;i<tasks.size();i++) {
    619                 I2PTunnelTask t = (I2PTunnelTask) tasks.get(i);
    620                 l.log("[" + t.getId() + "] " + t.toString());
    621             }
    622         }
    623         notifyEvent("listDone", "done");
    624     }
    625    
     605        purgetasks(l);
     606        synchronized (tasks) {
     607            for (int i = 0; i < tasks.size(); i++) {
     608                I2PTunnelTask t = (I2PTunnelTask) tasks.get(i);
     609                l.log("[" + t.getId() + "] " + t.toString());
     610            }
     611        }
     612        notifyEvent("listDone", "done");
     613    }
     614
    626615    /**
    627616     * Close the given task (or all tasks), optionally forcing them to die a hard
     
    634623     */
    635624    public void runClose(String args[], Logging l) {
    636         if (args.length == 0 || args.length > 2) {
    637             l.log("close [forced] <jobnumber>|all");
    638             l.log("   stop running tasks. either only one or all.\n"+
    639           "   use 'forced' to also stop tasks with active connections.\n"+
    640                   "   use the 'list' command to show the job numbers");
    641             notifyEvent("closeResult", "error");
    642         } else {
    643             int argindex=0;  // parse optional 'forced' keyword
    644             boolean forced=false;
    645             if (args[argindex].equalsIgnoreCase("forced")) {
    646                 forced=true;
    647                 argindex++;
    648             }
    649             if (args[argindex].equalsIgnoreCase("all")) {
    650                 List curTasks = null;
    651                 synchronized (tasks) {
    652                     curTasks = new LinkedList(tasks);
    653                 }
    654 
    655                 boolean error = false;
    656                 for (int i=0;i<curTasks.size();i++) {
    657                     I2PTunnelTask t = (I2PTunnelTask)curTasks.get(i);
    658                     if (!closetask(t, forced, l)) {
    659                         notifyEvent("closeResult", "error");
    660                         error = true;
    661                     } else if (!error) { // If there's an error, don't hide it
    662                         notifyEvent("closeResult", "ok");
    663                     }
    664                 }
    665             } else {
    666                 try {
    667                     if (!closetask(Integer.parseInt(args[argindex]),forced,l)){
    668                         notifyEvent("closeResult", "error");
    669                     } else {
    670                         notifyEvent("closeResult", "ok");
    671                     }
    672                 } catch (NumberFormatException ex) {
    673                     l.log("Incorrect job number: " + args[argindex]);
    674                     notifyEvent("closeResult", "error");
    675                 }
    676             }
    677         }
    678     }
    679    
     625        if (args.length == 0 || args.length > 2) {
     626            l.log("close [forced] <jobnumber>|all");
     627            l.log("   stop running tasks. either only one or all.\n"
     628                  + "   use 'forced' to also stop tasks with active connections.\n"
     629                  + "   use the 'list' command to show the job numbers");
     630            notifyEvent("closeResult", "error");
     631        } else {
     632            int argindex = 0; // parse optional 'forced' keyword
     633            boolean forced = false;
     634            if (args[argindex].equalsIgnoreCase("forced")) {
     635                forced = true;
     636                argindex++;
     637            }
     638            if (args[argindex].equalsIgnoreCase("all")) {
     639                List curTasks = null;
     640                synchronized (tasks) {
     641                    curTasks = new LinkedList(tasks);
     642                }
     643
     644                boolean error = false;
     645                for (int i = 0; i < curTasks.size(); i++) {
     646                    I2PTunnelTask t = (I2PTunnelTask) curTasks.get(i);
     647                    if (!closetask(t, forced, l)) {
     648                        notifyEvent("closeResult", "error");
     649                        error = true;
     650                    } else if (!error) { // If there's an error, don't hide it
     651                        notifyEvent("closeResult", "ok");
     652                    }
     653                }
     654            } else {
     655                try {
     656                    if (!closetask(Integer.parseInt(args[argindex]), forced, l)) {
     657                        notifyEvent("closeResult", "error");
     658                    } else {
     659                        notifyEvent("closeResult", "ok");
     660                    }
     661                } catch (NumberFormatException ex) {
     662                    l.log("Incorrect job number: " + args[argindex]);
     663                    notifyEvent("closeResult", "error");
     664                }
     665            }
     666        }
     667    }
     668
    680669    /**
    681670     * Run all of the commands in the given file (one command per line)
     
    687676     */
    688677    public void runRun(String args[], Logging l) {
    689         if(args.length==1) {
    690             try {
    691                 BufferedReader br =
    692                     new BufferedReader(new FileReader(args[0]));
    693                 String line;
    694                 while((line = br.readLine()) != null) {
    695                     runCommand(line,l);
    696                 }
    697                 br.close();
    698                 notifyEvent("runResult", "ok");
    699             } catch (IOException ioe) {
    700                 l.log("IO error running the file");
    701                 _log.error("Error running the file", ioe);
    702                 notifyEvent("runResult", "error");
    703             }
    704         } else {
    705             l.log("run <commandfile>");
    706             l.log("   loads commandfile and runs each line in it. \n"+
    707                   "   You can also give the filename on the commandline.");
    708                 notifyEvent("runResult", "error");
    709         }
    710     }
    711    
     678        if (args.length == 1) {
     679            try {
     680                BufferedReader br = new BufferedReader(new FileReader(args[0]));
     681                String line;
     682                while ((line = br.readLine()) != null) {
     683                    runCommand(line, l);
     684                }
     685                br.close();
     686                notifyEvent("runResult", "ok");
     687            } catch (IOException ioe) {
     688                l.log("IO error running the file");
     689                _log.error("Error running the file", ioe);
     690                notifyEvent("runResult", "error");
     691            }
     692        } else {
     693            l.log("run <commandfile>");
     694            l.log("   loads commandfile and runs each line in it. \n"
     695                  + "   You can also give the filename on the commandline.");
     696            notifyEvent("runResult", "error");
     697        }
     698    }
     699
    712700    /**
    713701     * Perform a lookup of the name specified
     
    719707     */
    720708    public void runLookup(String args[], Logging l) {
    721         if (args.length != 1) {
    722             l.log("lookup <name>");
    723             l.log("   try to resolve the name into a destination key");
    724             notifyEvent("lookupResult", "invalidUsage");
    725         } else {
    726             String target = args[0];
    727             try {
    728                 Destination dest = destFromName(args[0]);
    729                 if (dest == null) {
    730                     l.log("Unknown host");
    731                     notifyEvent("lookupResult", "unkown host");
    732                 } else {
    733                     l.log(dest.toBase64());
    734                     notifyEvent("lookupResult", dest.toBase64());
    735                 }
    736             } catch (DataFormatException dfe) {
    737                 l.log("Unknown or invalid host");
    738                 notifyEvent("lookupResult", "invalid host");
    739             }
    740         }
    741     }
    742    
     709        if (args.length != 1) {
     710            l.log("lookup <name>");
     711            l.log("   try to resolve the name into a destination key");
     712            notifyEvent("lookupResult", "invalidUsage");
     713        } else {
     714            String target = args[0];
     715            try {
     716                Destination dest = destFromName(args[0]);
     717                if (dest == null) {
     718                    l.log("Unknown host");
     719                    notifyEvent("lookupResult", "unkown host");
     720                } else {
     721                    l.log(dest.toBase64());
     722                    notifyEvent("lookupResult", dest.toBase64());
     723                }
     724            } catch (DataFormatException dfe) {
     725                l.log("Unknown or invalid host");
     726                notifyEvent("lookupResult", "invalid host");
     727            }
     728        }
     729    }
     730
    743731    /**
    744732     * Start up a ping task with the specified args (currently supporting -ns, -h, -l)
     
    750738     */
    751739    public void runPing(String allargs, Logging l) {
    752         if(allargs.length() != 0) {
    753             I2PTunnelTask task;
    754             // pings always use the main destination
    755             task = new I2Ping(allargs, l, false, (EventDispatcher)this);
    756             addtask(task);
    757             notifyEvent("pingTaskId", new Integer(task.getId()));
    758         } else {
    759             l.log("ping <opts> <dest>");
    760             l.log("ping <opts> -h");
    761             l.log("ping <opts> -l <destlistfile>");
    762             l.log("   Tests communication with peers.\n"+
    763                   "   opts can be -ns (nosync) or not.");
    764             notifyEvent("pingTaskId", new Integer(-1));
    765         }
     740        if (allargs.length() != 0) {
     741            I2PTunnelTask task;
     742            // pings always use the main destination
     743            task = new I2Ping(allargs, l, false, (EventDispatcher) this);
     744            addtask(task);
     745            notifyEvent("pingTaskId", new Integer(task.getId()));
     746        } else {
     747            l.log("ping <opts> <dest>");
     748            l.log("ping <opts> -h");
     749            l.log("ping <opts> -l <destlistfile>");
     750            l.log("   Tests communication with peers.\n" + "   opts can be -ns (nosync) or not.");
     751            notifyEvent("pingTaskId", new Integer(-1));
     752        }
    766753    }
    767754
     
    772759     */
    773760    private boolean closetask(int num, boolean forced, Logging l) {
    774         boolean closed = false;
    775 
    776         _log.debug("closetask(): looking for task " + num);
    777         synchronized (tasks) {
    778             for (Iterator it=tasks.iterator(); it.hasNext();) {
    779                 I2PTunnelTask t = (I2PTunnelTask) it.next();
    780                 int id = t.getId();
    781                 _log.debug("closetask(): parsing task " + id + " (" +
    782                               t.toString() + ")");
    783                 if (id == num) {
    784                     closed = closetask(t, forced, l);
    785                     break;
    786                 } else if (id > num) {
    787                     break;
    788                 }
    789             }
    790         }
    791         return closed;
     761        boolean closed = false;
     762
     763        _log.debug("closetask(): looking for task " + num);
     764        synchronized (tasks) {
     765            for (Iterator it = tasks.iterator(); it.hasNext();) {
     766                I2PTunnelTask t = (I2PTunnelTask) it.next();
     767                int id = t.getId();
     768                _log.debug("closetask(): parsing task " + id + " (" + t.toString() + ")");
     769                if (id == num) {
     770                    closed = closetask(t, forced, l);
     771                    break;
     772                } else if (id > num) {
     773                    break;
     774                }
     775            }
     776        }
     777        return closed;
    792778    }
    793779
     
    798784     */
    799785    private boolean closetask(I2PTunnelTask t, boolean forced, Logging l) {
    800         l.log("Closing task " + t.getId() + (forced ? " forced..." : "..."));
    801         if (t.close(forced)) {
    802             l.log("Task " + t.getId() + " closed.");
    803             return true;
    804         }
    805         return false;
     786        l.log("Closing task " + t.getId() + (forced ? " forced..." : "..."));
     787        if (t.close(forced)) {
     788            l.log("Task " + t.getId() + " closed.");
     789            return true;
     790        }
     791        return false;
    806792    }
    807793
     
    811797     */
    812798    private void purgetasks(Logging l) {
    813         synchronized (tasks) {
    814             for (Iterator it=tasks.iterator(); it.hasNext();) {
    815                 I2PTunnelTask t = (I2PTunnelTask) it.next();
    816                 if (!t.isOpen()) {
    817                     _log.debug("Purging inactive tunnel: ["
    818                                   + t.getId() + "] "
    819                           + t.toString());
    820                     it.remove();
    821                 }
    822             }
    823         }
     799        synchronized (tasks) {
     800            for (Iterator it = tasks.iterator(); it.hasNext();) {
     801                I2PTunnelTask t = (I2PTunnelTask) it.next();
     802                if (!t.isOpen()) {
     803                    _log.debug("Purging inactive tunnel: [" + t.getId() + "] " + t.toString());
     804                    it.remove();
     805                }
     806            }
     807        }
    824808    }
    825809
     
    829813     */
    830814    public void log(String s) {
    831         System.out.println(s);
    832         _log.info("Display: " + s);
    833     }
    834    
     815        System.out.println(s);
     816        _log.info("Display: " + s);
     817    }
     818
    835819    /**
    836820     * Create a new destination, storing the destination and its private keys where
     
    841825     * @param l logger to send messages to
    842826     */
    843     public static void makeKey(OutputStream writeTo, OutputStream pubDest,
    844                                Logging l) {
    845         try {
    846             l.log("Generating new keys...");
    847             ByteArrayOutputStream priv = new ByteArrayOutputStream(),
    848                 pub = new ByteArrayOutputStream();
    849             I2PClient client = I2PClientFactory.createClient();
    850             Destination d = client.createDestination(writeTo);
    851             l.log("Secret key saved.");
    852             l.log("Public key: "+d.toBase64());
    853             writeTo.flush();
    854             writeTo.close();
    855             writePubKey(d, pubDest, l);
    856         } catch (I2PException ex) {
    857             ex.printStackTrace();
    858         } catch (IOException ex) {
    859             ex.printStackTrace();
    860         }
     827    public static void makeKey(OutputStream writeTo, OutputStream pubDest, Logging l) {
     828        try {
     829            l.log("Generating new keys...");
     830            ByteArrayOutputStream priv = new ByteArrayOutputStream(), pub = new ByteArrayOutputStream();
     831            I2PClient client = I2PClientFactory.createClient();
     832            Destination d = client.createDestination(writeTo);
     833            l.log("Secret key saved.");
     834            l.log("Public key: " + d.toBase64());
     835            writeTo.flush();
     836            writeTo.close();
     837            writePubKey(d, pubDest, l);
     838        } catch (I2PException ex) {
     839            ex.printStackTrace();
     840        } catch (IOException ex) {
     841            ex.printStackTrace();
     842        }
    861843    }
    862844
     
    868850     * @param l logger to send messages to
    869851     */
    870     public static void showKey(InputStream readFrom, OutputStream pubDest,
    871                                Logging l) {
    872         try {
    873             I2PClient client = I2PClientFactory.createClient();
    874             Destination d = new Destination();
    875             d.readBytes(readFrom);
    876             l.log("Public key: "+d.toBase64());
    877             readFrom.close();
    878             writePubKey(d, pubDest, l);
    879         } catch (I2PException ex) {
    880             ex.printStackTrace();
    881         } catch (IOException ex) {
    882             ex.printStackTrace();
    883         }
     852    public static void showKey(InputStream readFrom, OutputStream pubDest, Logging l) {
     853        try {
     854            I2PClient client = I2PClientFactory.createClient();
     855            Destination d = new Destination();
     856            d.readBytes(readFrom);
     857            l.log("Public key: " + d.toBase64());
     858            readFrom.close();
     859            writePubKey(d, pubDest, l);
     860        } catch (I2PException ex) {
     861            ex.printStackTrace();
     862        } catch (IOException ex) {
     863            ex.printStackTrace();
     864        }
    884865    }
    885866
     
    891872     * @param l logger to send messages to
    892873     */
    893     private static void writePubKey(Destination d, OutputStream o, Logging l)
    894         throws I2PException, IOException {
    895         if (o==null) return;
    896         d.writeBytes(o);
    897         l.log("Public key saved.");
    898     }
    899    
     874    private static void writePubKey(Destination d, OutputStream o, Logging l) throws I2PException, IOException {
     875        if (o == null) return;
     876        d.writeBytes(o);
     877        l.log("Public key saved.");
     878    }
     879
    900880    /**
    901881     * Generates a Destination from a name. Now only supports base64
     
    905885     * structure.
    906886     */
    907     public static Destination destFromName(String name)
    908         throws DataFormatException {
    909        
    910         if ( (name == null) || (name.trim().length() <= 0) )
    911             throw new DataFormatException("Empty destination provided");
    912        
    913         if (name.startsWith("file:")) {
    914             Destination result=new Destination();
    915             byte content[] = null;
    916             FileInputStream in = null;
    917             try {
    918                 in = new FileInputStream(name.substring("file:".length()));
    919                 byte buf[] = new byte[1024];
    920                 int read = DataHelper.read(in, buf);
    921                 content = new byte[read];
    922                 System.arraycopy(buf, 0, content, 0, read);
    923             } catch (IOException ioe) {
    924                 System.out.println(ioe.getMessage());
    925                 return null;
    926             } finally {
    927                 if (in != null) try { in.close(); } catch (IOException io) {}
    928             }
    929             try {
    930                 result.fromByteArray(content);
    931                 return result;
    932             } catch (Exception ex) {
    933                 if (_log.shouldLog(Log.INFO))
    934                     _log.info("File is not a binary destination - trying base64");
    935                 try {
    936                     byte decoded[] = Base64.decode(new String(content));
    937                     result.fromByteArray(decoded);
    938                     return result;
    939                 } catch (DataFormatException dfe) {
    940                     if (_log.shouldLog(Log.WARN))
    941                         _log.warn("File is not a base64 destination either - failing!");
    942                     return null;
    943                 }
    944             }
    945         } else {
    946             // ask naming service
    947             NamingService inst = NamingService.getInstance();
    948             return inst.lookup(name);
    949         }
    950     }
    951    
     887    public static Destination destFromName(String name) throws DataFormatException {
     888
     889        if ((name == null) || (name.trim().length() <= 0)) throw new DataFormatException("Empty destination provided");
     890
     891        if (name.startsWith("file:")) {
     892            Destination result = new Destination();
     893            byte content[] = null;
     894            FileInputStream in = null;
     895            try {
     896                in = new FileInputStream(name.substring("file:".length()));
     897                byte buf[] = new byte[1024];
     898                int read = DataHelper.read(in, buf);
     899                content = new byte[read];
     900                System.arraycopy(buf, 0, content, 0, read);
     901            } catch (IOException ioe) {
     902                System.out.println(ioe.getMessage());
     903                return null;
     904            } finally {
     905                if (in != null) try {
     906                    in.close();
     907                } catch (IOException io) {
     908                }
     909            }
     910            try {
     911                result.fromByteArray(content);
     912                return result;
     913            } catch (Exception ex) {
     914                if (_log.shouldLog(Log.INFO)) _log.info("File is not a binary destination - trying base64");
     915                try {
     916                    byte decoded[] = Base64.decode(new String(content));
     917                    result.fromByteArray(decoded);
     918                    return result;
     919                } catch (DataFormatException dfe) {
     920                    if (_log.shouldLog(Log.WARN)) _log.warn("File is not a base64 destination either - failing!");
     921                    return null;
     922                }
     923            }
     924        } else {
     925            // ask naming service
     926            NamingService inst = NamingService.getInstance();
     927            return inst.lookup(name);
     928        }
     929    }
     930
    952931    public void addConnectionEventListener(ConnectionEventListener lsnr) {
    953         if (lsnr == null) return;
    954         synchronized (listeners) {
    955             listeners.add(lsnr);
    956         }
    957     }
     932        if (lsnr == null) return;
     933        synchronized (listeners) {
     934            listeners.add(lsnr);
     935        }
     936    }
     937
    958938    public void removeConnectionEventListener(ConnectionEventListener lsnr) {
    959         if (lsnr == null) return;
    960         synchronized (listeners) {
    961             listeners.remove(lsnr);
    962         }
    963     }
    964    
     939        if (lsnr == null) return;
     940        synchronized (listeners) {
     941            listeners.remove(lsnr);
     942        }
     943    }
     944
    965945    /**
    966946     * Call this whenever we lose touch with the router involuntarily (aka the router
     
    969949     */
    970950    void routerDisconnected() {
    971         _log.error("Router disconnected - firing notification events");
    972         synchronized (listeners) {
    973             for (Iterator iter = listeners.iterator(); iter.hasNext();) {
    974                 ConnectionEventListener lsnr = (ConnectionEventListener)iter.next();
    975                 if (lsnr != null)
    976                     lsnr.routerDisconnected();
    977             }
    978         }
    979     }
    980    
     951        _log.error("Router disconnected - firing notification events");
     952        synchronized (listeners) {
     953            for (Iterator iter = listeners.iterator(); iter.hasNext();) {
     954                ConnectionEventListener lsnr = (ConnectionEventListener) iter.next();
     955                if (lsnr != null) lsnr.routerDisconnected();
     956            }
     957        }
     958    }
     959
    981960    /**
    982961     * Callback routine to find out
    983962     */
    984963    public interface ConnectionEventListener {
    985         public void routerDisconnected();
     964        public void routerDisconnected();
    986965    }
    987966
    988967    /* Required by the EventDispatcher interface */
    989     public EventDispatcher getEventDispatcher() { return _event; }
    990     public void attachEventDispatcher(EventDispatcher e) { _event.attachEventDispatcher(e.getEventDispatcher()); }
    991     public void detachEventDispatcher(EventDispatcher e) { _event.detachEventDispatcher(e.getEventDispatcher()); }
    992     public void notifyEvent(String e, Object a) { _event.notifyEvent(e,a); }
    993     public Object getEventValue(String n) { return _event.getEventValue(n); }
    994     public Set getEvents() { return _event.getEvents(); }
    995     public void ignoreEvents() { _event.ignoreEvents(); }
    996     public void unIgnoreEvents() { _event.unIgnoreEvents(); }
    997     public Object waitEventValue(String n) { return _event.waitEventValue(n); }
     968    public EventDispatcher getEventDispatcher() {
     969        return _event;
     970    }
     971
     972    public void attachEventDispatcher(EventDispatcher e) {
     973        _event.attachEventDispatcher(e.getEventDispatcher());
     974    }
     975
     976    public void detachEventDispatcher(EventDispatcher e) {
     977        _event.detachEventDispatcher(e.getEventDispatcher());
     978    }
     979
     980    public void notifyEvent(String e, Object a) {
     981        _event.notifyEvent(e, a);
     982    }
     983
     984    public Object getEventValue(String n) {
     985        return _event.getEventValue(n);
     986    }
     987
     988    public Set getEvents() {
     989        return _event.getEvents();
     990    }
     991
     992    public void ignoreEvents() {
     993        _event.ignoreEvents();
     994    }
     995
     996    public void unIgnoreEvents() {
     997        _event.unIgnoreEvents();
     998    }
     999
     1000    public Object waitEventValue(String n) {
     1001        return _event.waitEventValue(n);
     1002    }
    9981003}
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java

    r8a8e681 r17a1b11  
    1919    protected Destination dest;
    2020
    21     public I2PTunnelClient(int localPort, String destination,
    22                            Logging l, boolean ownDest,
    23                            EventDispatcher notifyThis) {
    24         super(localPort, ownDest, l, notifyThis, "SynSender");
     21    public I2PTunnelClient(int localPort, String destination, Logging l, boolean ownDest, EventDispatcher notifyThis) {
     22        super(localPort, ownDest, l, notifyThis, "SynSender");
    2523
    26         if (waitEventValue("openBaseClientResult").equals("error")) {
    27             notifyEvent("openClientResult", "error");
    28             return;
    29         }
    30        
    31         try {
    32             dest=I2PTunnel.destFromName(destination);
    33             if (dest == null) {
    34                 l.log("Could not resolve " + destination + ".");
    35                 return;
    36             }
    37         } catch (DataFormatException e) {
    38             l.log("Bad format in destination \"" + destination + "\".");
    39             notifyEvent("openClientResult", "error");
    40             return;
    41         }
     24        if (waitEventValue("openBaseClientResult").equals("error")) {
     25            notifyEvent("openClientResult", "error");
     26            return;
     27        }
    4228
    43         setName(getLocalPort() + " -> " + destination);
     29        try {
     30            dest = I2PTunnel.destFromName(destination);
     31            if (dest == null) {
     32                l.log("Could not resolve " + destination + ".");
     33                return;
     34            }
     35        } catch (DataFormatException e) {
     36            l.log("Bad format in destination \"" + destination + "\".");
     37            notifyEvent("openClientResult", "error");
     38            return;
     39        }
    4440
    45         startRunning();
     41        setName(getLocalPort() + " -> " + destination);
    4642
    47         notifyEvent("openClientResult", "ok");
     43        startRunning();
     44
     45        notifyEvent("openClientResult", "ok");
    4846    }
    4947
    5048    protected void clientConnectionRun(Socket s) {
    51         try {
    52             I2PSocket i2ps = createI2PSocket(dest);
    53             new I2PTunnelRunner(s, i2ps, sockLock, null);
    54         } catch (I2PException ex) {
    55             _log.info("Error connecting", ex);
    56             l.log("Unable to reach peer");
    57             // s has been initialized before the try block...
    58             closeSocket(s);
    59         }
     49        try {
     50            I2PSocket i2ps = createI2PSocket(dest);
     51            new I2PTunnelRunner(s, i2ps, sockLock, null);
     52        } catch (I2PException ex) {
     53            _log.info("Error connecting", ex);
     54            l.log("Unable to reach peer");
     55            // s has been initialized before the try block...
     56            closeSocket(s);
     57        }
    6058    }
    6159}
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java

    r8a8e681 r17a1b11  
    2424import net.i2p.util.Log;
    2525
    26 public abstract class I2PTunnelClientBase extends I2PTunnelTask
    27     implements Runnable {
    28    
     26public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runnable {
     27
    2928    private static final Log _log = new Log(I2PTunnelClientBase.class);
    3029    protected Logging l;
    31    
    32     private static final long DEFAULT_CONNECT_TIMEOUT = 60*1000;
     30
     31    private static final long DEFAULT_CONNECT_TIMEOUT = 60 * 1000;
    3332
    3433    protected Object sockLock = new Object(); // Guards sockMgr and mySockets
     
    4241
    4342    private ServerSocket ss;
    44    
     43
    4544    private Object startLock = new Object();
    4645    private boolean startRunning = false;
    4746
    4847    private Object closeLock = new Object();
    49    
     48
    5049    private byte[] pubkey;
    5150
     
    5756    //}
    5857
    59     public I2PTunnelClientBase(int localPort, boolean ownDest,
    60                                Logging l, EventDispatcher notifyThis,
    61                                String handlerName) {
    62         super(localPort+" (uninitialized)", notifyThis);
    63         this.localPort=localPort;
    64         this.l = l;
    65         this.handlerName=handlerName;
    66 
    67         synchronized(sockLock) {
    68             if (ownDest) {
    69                 sockMgr=buildSocketManager();
    70             } else {
    71                 sockMgr=getSocketManager();
    72             }
    73         }
    74         if (sockMgr == null) throw new NullPointerException();
    75         l.log("I2P session created");
    76        
    77         Thread t = new I2PThread(this);
    78         t.setName("Client");
    79         listenerReady=false;
    80         t.start();
    81         open=true;
    82         synchronized (this) {
    83             while (!listenerReady) {
    84                 try {
    85                     wait();
    86                 }
    87                 catch (InterruptedException e) {
    88                     // ignore
    89                 }
    90             }
    91         }
    92        
    93         if (open && listenerReady) {
    94             l.log("Ready! Port " + getLocalPort());
    95             notifyEvent("openBaseClientResult", "ok");
    96         } else {
    97             l.log("Error!");
    98             notifyEvent("openBaseClientResult", "error");
    99         }
     58    public I2PTunnelClientBase(int localPort, boolean ownDest, Logging l, EventDispatcher notifyThis, String handlerName) {
     59        super(localPort + " (uninitialized)", notifyThis);
     60        this.localPort = localPort;
     61        this.l = l;
     62        this.handlerName = handlerName;
     63
     64        synchronized (sockLock) {
     65            if (ownDest) {
     66                sockMgr = buildSocketManager();
     67            } else {
     68                sockMgr = getSocketManager();
     69            }
     70        }
     71        if (sockMgr == null) throw new NullPointerException();
     72        l.log("I2P session created");
     73
     74        Thread t = new I2PThread(this);
     75        t.setName("Client");
     76        listenerReady = false;
     77        t.start();
     78        open = true;
     79        synchronized (this) {
     80            while (!listenerReady) {
     81                try {
     82                    wait();
     83                } catch (InterruptedException e) {
     84                    // ignore
     85                }
     86            }
     87        }
     88
     89        if (open && listenerReady) {
     90            l.log("Ready! Port " + getLocalPort());
     91            notifyEvent("openBaseClientResult", "ok");
     92        } else {
     93            l.log("Error!");
     94            notifyEvent("openBaseClientResult", "error");
     95        }
    10096    }
    10197
    10298    private static I2PSocketManager socketManager;
    103    
     99
    104100    protected static synchronized I2PSocketManager getSocketManager() {
    105         if (socketManager == null) {
    106             socketManager = buildSocketManager();
    107         }
    108         return socketManager;
    109     }
    110    
     101        if (socketManager == null) {
     102            socketManager = buildSocketManager();
     103        }
     104        return socketManager;
     105    }
     106
    111107    protected static I2PSocketManager buildSocketManager() {
    112         Properties props = new Properties();
    113         props.putAll(System.getProperties());
    114         return I2PSocketManagerFactory.createManager
    115             (I2PTunnel.host, Integer.parseInt(I2PTunnel.port), props);
    116     }
    117    
     108        Properties props = new Properties();
     109        props.putAll(System.getProperties());
     110        return I2PSocketManagerFactory.createManager(I2PTunnel.host, Integer.parseInt(I2PTunnel.port), props);
     111    }
     112
    118113    public final int getLocalPort() {
    119114        return localPort;
     
    121116
    122117    protected final InetAddress getListenHost(Logging l) {
    123         try {
    124             return InetAddress.getByName(I2PTunnel.listenHost);
    125         } catch (UnknownHostException uhe) {
    126             l.log("Could not find listen host to bind to [" +
    127                   I2PTunnel.host + "]");
    128             _log.error("Error finding host to bind", uhe);
    129             notifyEvent("openBaseClientResult", "error");
    130             return null;
    131         }
    132     }
    133    
     118        try {
     119            return InetAddress.getByName(I2PTunnel.listenHost);
     120        } catch (UnknownHostException uhe) {
     121            l.log("Could not find listen host to bind to [" + I2PTunnel.host + "]");
     122            _log.error("Error finding host to bind", uhe);
     123            notifyEvent("openBaseClientResult", "error");
     124            return null;
     125        }
     126    }
     127
    134128    /**
    135129     * Actually start working on incoming connections.  *Must* be
     
    138132     */
    139133    public final void startRunning() {
    140         synchronized (startLock) {
    141             startRunning = true;
    142             startLock.notify();
    143         }
    144     }
    145    
     134        synchronized (startLock) {
     135            startRunning = true;
     136            startLock.notify();
     137        }
     138    }
     139
    146140    /**
    147141     * create the default options (using the default timeout, etc)
     
    149143     */
    150144    private I2PSocketOptions getDefaultOptions() {
    151         I2PSocketOptions opts = new I2PSocketOptions();
    152         opts.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
    153         return opts;
     145        I2PSocketOptions opts = new I2PSocketOptions();
     146        opts.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
     147        return opts;
    154148    }
    155149
     
    163157     */
    164158    public I2PSocket createI2PSocket(Destination dest) throws I2PException {
    165         return createI2PSocket(dest, getDefaultOptions());
     159        return createI2PSocket(dest, getDefaultOptions());
    166160    }
    167161
     
    176170     */
    177171    public I2PSocket createI2PSocket(Destination dest, I2PSocketOptions opt) throws I2PException {
    178         I2PSocket i2ps;
    179 
    180         synchronized (sockLock) {
    181             i2ps = sockMgr.connect(dest, opt);
    182             mySockets.add(i2ps);
    183         }
    184 
    185         return i2ps;
     172        I2PSocket i2ps;
     173
     174        synchronized (sockLock) {
     175            i2ps = sockMgr.connect(dest, opt);
     176            mySockets.add(i2ps);
     177        }
     178
     179        return i2ps;
    186180    }
    187181
    188182    public final void run() {
    189         try {
    190             InetAddress addr = getListenHost(l);
    191             if (addr == null) return;
    192             ss = new ServerSocket(localPort, 0, addr);
    193        
    194             // If a free port was requested, find out what we got
    195             if (localPort == 0) {
    196                 localPort = ss.getLocalPort();
    197             }
    198             notifyEvent("clientLocalPort", new Integer(ss.getLocalPort()));
    199             l.log("Listening for clients on port " + localPort +
    200                   " of " + I2PTunnel.listenHost);
    201            
    202             // Notify constructor that port is ready
    203             synchronized(this) {
    204                 listenerReady = true;
    205                 notify();       
    206             }
    207 
    208             // Wait until we are authorized to process data
    209             synchronized (startLock) {
    210                 while (!startRunning) {
    211                     try {
    212                         startLock.wait();
    213                     } catch (InterruptedException ie) {}
    214                 }
    215             }
    216 
    217             while (true) {
    218                 Socket s = ss.accept();
    219                 manageConnection(s);
    220             }
    221         } catch (IOException ex) {
    222             _log.error("Error listening for connections", ex);
    223             notifyEvent("openBaseClientResult", "error");
    224         }
     183        try {
     184            InetAddress addr = getListenHost(l);
     185            if (addr == null) return;
     186            ss = new ServerSocket(localPort, 0, addr);
     187
     188            // If a free port was requested, find out what we got
     189            if (localPort == 0) {
     190                localPort = ss.getLocalPort();
     191            }
     192            notifyEvent("clientLocalPort", new Integer(ss.getLocalPort()));
     193            l.log("Listening for clients on port " + localPort + " of " + I2PTunnel.listenHost);
     194
     195            // Notify constructor that port is ready
     196            synchronized (this) {
     197                listenerReady = true;
     198                notify();
     199            }
     200
     201            // Wait until we are authorized to process data
     202            synchronized (startLock) {
     203                while (!startRunning) {
     204                    try {
     205                        startLock.wait();
     206                    } catch (InterruptedException ie) {
     207                    }
     208                }
     209            }
     210
     211            while (true) {
     212                Socket s = ss.accept();
     213                manageConnection(s);
     214            }
     215        } catch (IOException ex) {
     216            _log.error("Error listening for connections", ex);
     217            notifyEvent("openBaseClientResult", "error");
     218        }
    225219    }
    226220
     
    231225     */
    232226    protected void manageConnection(Socket s) {
    233         new ClientConnectionRunner(s, handlerName);
    234     }
    235 
    236    
     227        new ClientConnectionRunner(s, handlerName);
     228    }
     229
    237230    public boolean close(boolean forced) {
    238         if (!open) return true;
    239         // FIXME: here we might have to wait quite a long time if
    240         // there is a connection attempt atm. But without waiting we
    241         // might risk to create an orphan socket. Would be better
    242         // to return with an error in that situation quickly.
    243         synchronized(sockLock) {
    244             mySockets.retainAll(sockMgr.listSockets());
    245             if (!forced && mySockets.size() != 0) {
    246                 l.log("There are still active connections!");
    247                 _log.debug("can't close: there are still active connections!");
    248                 for (Iterator it = mySockets.iterator(); it.hasNext();) {
    249                     l.log("->"+it.next());
    250                 }
    251                 return false;
    252             }
    253             l.log("Closing client "+toString());
    254             try {
    255                 if (ss != null) ss.close();
    256             } catch (IOException ex) {
    257                 ex.printStackTrace();
    258                 return false;
    259             }
    260             l.log("Client closed.");
    261             open=false;
    262             return true;
    263         }
     231        if (!open) return true;
     232        // FIXME: here we might have to wait quite a long time if
     233        // there is a connection attempt atm. But without waiting we
     234        // might risk to create an orphan socket. Would be better
     235        // to return with an error in that situation quickly.
     236        synchronized (sockLock) {
     237            mySockets.retainAll(sockMgr.listSockets());
     238            if (!forced && mySockets.size() != 0) {
     239                l.log("There are still active connections!");
     240                _log.debug("can't close: there are still active connections!");
     241                for (Iterator it = mySockets.iterator(); it.hasNext();) {
     242                    l.log("->" + it.next());
     243                }
     244                return false;
     245            }
     246            l.log("Closing client " + toString());
     247            try {
     248                if (ss != null) ss.close();
     249            } catch (IOException ex) {
     250                ex.printStackTrace();
     251                return false;
     252            }
     253            l.log("Client closed.");
     254            open = false;
     255            return true;
     256        }
    264257    }
    265258
    266259    public static void closeSocket(Socket s) {
    267         try {
    268             s.close();
    269         } catch (IOException ex) {
    270             _log.error("Could not close socket", ex);
    271         }
     260        try {
     261            s.close();
     262        } catch (IOException ex) {
     263            _log.error("Could not close socket", ex);
     264        }
    272265    }
    273266
    274267    public class ClientConnectionRunner extends I2PThread {
    275         private Socket s;
    276        
    277         public ClientConnectionRunner(Socket s, String name) {
    278             this.s=s;
    279             setName(name);
    280             start();
    281         }
    282        
    283         public void run() {
    284             clientConnectionRun(s);
    285         }
     268        private Socket s;
     269
     270        public ClientConnectionRunner(Socket s, String name) {
     271            this.s = s;
     272            setName(name);
     273            start();
     274        }
     275
     276        public void run() {
     277            clientConnectionRun(s);
     278        }
    286279    }
    287280
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelGUI.java

    r8a8e681 r17a1b11  
    2020    TextArea log;
    2121    I2PTunnel t;
    22    
     22