Changeset e721ddd


Ignore:
Timestamp:
Jan 31, 2011 1:42:36 PM (9 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
97f93c64
Parents:
07b2e3e (diff), 6981db4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

propagate from branch 'i2p.i2p.zzz.test4' (head 592b7d2b980e8cba19167fa064f25251296ed8bb)

to branch 'i2p.i2p' (head 0ba672eaca7076092389d2277dba231fdd34423b)

Files:
5 added
1 deleted
158 edited

Legend:

Unmodified
Added
Removed
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java

    r07b2e3e re721ddd  
    4444import java.net.UnknownHostException;
    4545import java.util.ArrayList;
    46 import java.util.HashSet;
    4746import java.util.Iterator;
    4847import java.util.LinkedList;
     
    5150import java.util.Set;
    5251import java.util.StringTokenizer;
     52import java.util.concurrent.CopyOnWriteArraySet;
    5353
    5454import net.i2p.I2PAppContext;
     
    100100    private int next_task_id = 1;
    101101
    102     private final Set listeners = new HashSet();
     102    private final Set listeners = new CopyOnWriteArraySet();
    103103
    104104    public static void main(String[] args) throws IOException {
     
    119119        _log = _context.logManager().getLog(I2PTunnel.class);
    120120        _event = new EventDispatcherImpl();
    121         Properties p = new Properties();
    122         p.putAll(System.getProperties());
     121        // as of 0.8.4, include context properties
     122        Properties p = _context.getProperties();
    123123        _clientOptions = p;
    124124        _sessions = new ArrayList(1);
     
    16271627    public void addConnectionEventListener(ConnectionEventListener lsnr) {
    16281628        if (lsnr == null) return;
    1629         synchronized (listeners) {
    1630             listeners.add(lsnr);
    1631         }
     1629        listeners.add(lsnr);
    16321630    }
    16331631
    16341632    public void removeConnectionEventListener(ConnectionEventListener lsnr) {
    16351633        if (lsnr == null) return;
    1636         synchronized (listeners) {
    1637             listeners.remove(lsnr);
    1638         }
     1634        listeners.remove(lsnr);
    16391635    }
    16401636   
     
    16501646    void routerDisconnected() {
    16511647        _log.error(getPrefix() + "Router disconnected - firing notification events");
    1652         synchronized (listeners) {
    16531648            for (Iterator iter = listeners.iterator(); iter.hasNext();) {
    16541649                ConnectionEventListener lsnr = (ConnectionEventListener) iter.next();
    16551650                if (lsnr != null) lsnr.routerDisconnected();
    16561651            }
    1657         }
    16581652    }
    16591653
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelControllerGroup.java

    r07b2e3e re721ddd  
    311311            Set<TunnelController> owners = _sessions.get(session);
    312312            if (owners == null) {
    313                 owners = new HashSet(1);
     313                owners = new HashSet(2);
    314314                _sessions.put(session, owners);
    315315            }
  • apps/ministreaming/java/src/net/i2p/client/streaming/ByteCollector.java

    r07b2e3e re721ddd  
    55 * so care should be taken when using in a multithreaded environment.
    66 *
     7 * @deprecated Only used by deprecated I2PSocketImpl
    78 */
    89class ByteCollector {
  • apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManager.java

    r07b2e3e re721ddd  
    55package net.i2p.client.streaming;
    66
     7import java.io.IOException;
    78import java.io.InterruptedIOException;
    89import java.net.ConnectException;
    910import java.net.NoRouteToHostException;
     11import java.net.ServerSocket;
     12import java.net.Socket;
    1013import java.util.Properties;
    1114import java.util.Set;
     
    8588     * @return a set of currently connected I2PSockets
    8689     */
    87     public Set listSockets();
     90    public Set<I2PSocket> listSockets();
    8891
    8992    /**
     
    108111        public void sessionDisconnected();
    109112    }
     113
     114    /**
     115     *  Like getServerSocket but returns a real ServerSocket for easier porting of apps.
     116     *  @since 0.8.4
     117     */
     118    public ServerSocket getStandardServerSocket() throws IOException;
     119
     120    /**
     121     *  Like connect() but returns a real Socket, and throws only IOE,
     122     *  for easier porting of apps.
     123     *  @since 0.8.4
     124     */
     125    public Socket connectToSocket(Destination peer) throws IOException;
     126
     127    /**
     128     *  Like connect() but returns a real Socket, and throws only IOE,
     129     *  for easier porting of apps.
     130     *  @param timeout ms if > 0, forces blocking (disables connectDelay)
     131     *  @since 0.8.4
     132     */
     133    public Socket connectToSocket(Destination peer, int timeout) throws IOException;
    110134}
  • apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerImpl.java

    r07b2e3e re721ddd  
    1111import java.net.ConnectException;
    1212import java.net.NoRouteToHostException;
     13import java.net.ServerSocket;
     14import java.net.Socket;
    1315import java.util.ArrayList;
    1416import java.util.HashMap;
     
    463465
    464466    /**
     467     *  @throws UnsupportedOperationException
     468     *  @since 0.8.4
     469     */
     470    public ServerSocket getStandardServerSocket() {
     471        throw new UnsupportedOperationException();
     472    }
     473
     474    /**
    465475     * Create a new connected socket (block until the socket is created)
    466476     *
     
    603613
    604614    /**
     615     *  @throws UnsupportedOperationException
     616     *  @since 0.8.4
     617     */
     618    public Socket connectToSocket(Destination peer) {
     619        throw new UnsupportedOperationException();
     620    }
     621
     622    /**
     623     *  @throws UnsupportedOperationException
     624     *  @since 0.8.4
     625     */
     626    public Socket connectToSocket(Destination peer, int timeout) {
     627        throw new UnsupportedOperationException();
     628    }
     629
     630    /**
    605631     * Destroy the socket manager, freeing all the associated resources.  This
    606632     * method will block untill all the managed sockets are closed.
     
    661687     *
    662688     */
    663     public Set listSockets() {
     689    public Set<I2PSocket> listSockets() {
    664690        Set<I2PSocket> sockets = new HashSet<I2PSocket>(8);
    665691        synchronized (lock) {
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java

    r07b2e3e re721ddd  
    101101
    102102    public String getTcpAutoIPChecked(int mode) {
    103         boolean enabled = TransportManager.enableNTCP(_context);
     103        boolean enabled = TransportManager.isNTCPEnabled(_context);
    104104        String hostname = _context.getProperty(PROP_I2NP_NTCP_HOSTNAME);
    105105        boolean specified = hostname != null && hostname.length() > 0;
  • apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java

    r07b2e3e re721ddd  
    2626import org.mortbay.http.NCSARequestLog;
    2727import org.mortbay.http.SecurityConstraint;
     28import org.mortbay.http.SocketListener;
    2829import org.mortbay.http.SslListener;
    2930import org.mortbay.http.handler.SecurityHandler;
     
    186187                    String host = tok.nextToken().trim();
    187188                    try {
    188                         if (host.indexOf(":") >= 0) // IPV6 - requires patched Jetty 5
    189                             _server.addListener('[' + host + "]:" + _listenPort);
    190                         else
    191                             _server.addListener(host + ':' + _listenPort);
     189                        //if (host.indexOf(":") >= 0) // IPV6 - requires patched Jetty 5
     190                        //    _server.addListener('[' + host + "]:" + _listenPort);
     191                        //else
     192                        //    _server.addListener(host + ':' + _listenPort);
     193                        Integer lport = Integer.parseInt(_listenPort);
     194                        InetAddrPort iap = new InetAddrPort(host, lport);
     195                        SocketListener lsnr = new SocketListener(iap);
     196                        lsnr.setMinThreads(1);           // default 2
     197                        lsnr.setMaxThreads(24);          // default 256
     198                        lsnr.setMaxIdleTimeMs(90*1000);  // default 10 sec
     199                        lsnr.setName("ConsoleSocket");   // all with same name will use the same thread pool
     200                        _server.addListener(lsnr);
    192201                        boundAddresses++;
     202                    } catch (NumberFormatException nfe) {
     203                        System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ' ' + nfe);
    193204                    } catch (IOException ioe) { // this doesn't seem to work, exceptions don't happen until start() below
    194205                        System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ' ' + ioe);
     
    222233                            // the X.509 cert password (if not present, verifyKeyStore() returned false)
    223234                            ssll.setKeyPassword(ctx.getProperty(PROP_KEY_PASSWORD, "thisWontWork"));
     235                            ssll.setMinThreads(1);           // default 2
     236                            ssll.setMaxThreads(24);          // default 256
     237                            ssll.setMaxIdleTimeMs(90*1000);  // default 10 sec
     238                            ssll.setName("ConsoleSocket");   // all with same name will use the same thread pool
    224239                            _server.addListener(ssll);
    225240                            boundAddresses++;
  • apps/streaming/java/src/net/i2p/client/streaming/ConnectionManager.java

    r07b2e3e re721ddd  
    4141    private ConnectionOptions _defaultOptions;
    4242    private volatile int _numWaiting;
    43     private long SoTimeout;
     43    private long _soTimeout;
    4444    private ConnThrottler _minuteThrottler;
    4545    private ConnThrottler _hourThrottler;
     
    6565        _numWaiting = 0;
    6666        /** Socket timeout for accept() */
    67         SoTimeout = -1;
     67        _soTimeout = -1;
    6868
    6969        _context.statManager().createRateStat("stream.con.lifetimeMessagesSent", "How many messages do we send on a stream?", "Stream", new long[] { 60*60*1000, 24*60*60*1000 });
     
    9898     * @param x
    9999     */
    100     public void MsetSoTimeout(long x) {
    101         SoTimeout = x;
     100    public void setSoTimeout(long x) {
     101        _soTimeout = x;
    102102    }
    103103
     
    106106     * @return accept timeout in ms.
    107107     */
    108     public long MgetSoTimeout() {
    109         return SoTimeout;
     108    public long getSoTimeout() {
     109        return _soTimeout;
    110110    }
    111111
  • apps/streaming/java/src/net/i2p/client/streaming/I2PServerSocketFull.java

    r07b2e3e re721ddd  
    2727   
    2828    public long getSoTimeout() {
    29         return _socketManager.getConnectionManager().MgetSoTimeout();
     29        return _socketManager.getConnectionManager().getSoTimeout();
    3030    }
    3131   
    3232    public void setSoTimeout(long x) {
    33         _socketManager.getConnectionManager().MsetSoTimeout(x);
     33        _socketManager.getConnectionManager().setSoTimeout(x);
    3434    }
    3535    /**
  • apps/streaming/java/src/net/i2p/client/streaming/I2PSocketFull.java

    r07b2e3e re721ddd  
    4747    Connection getConnection() { return _connection; }
    4848   
     49    /**
     50     *  Warning, may return null instead of throwing IOE,
     51     *  which is not what the interface says.
     52     */
    4953    public InputStream getInputStream() {
    5054        Connection c = _connection;
     
    6367    }
    6468   
     69    /**
     70     *  Warning, may return null instead of throwing IOE,
     71     *  which is not what the interface says.
     72     */
    6573    public OutputStream getOutputStream() throws IOException {
    6674        Connection c = _connection;
  • apps/streaming/java/src/net/i2p/client/streaming/I2PSocketManagerFull.java

    r07b2e3e re721ddd  
    11package net.i2p.client.streaming;
    22
     3import java.io.IOException;
    34import java.net.NoRouteToHostException;
     5import java.net.ServerSocket;
     6import java.net.Socket;
    47import java.net.SocketTimeoutException;
    58import java.util.HashSet;
     
    3134    private I2PSession _session;
    3235    private I2PServerSocketFull _serverSocket;
     36    private StandardServerSocket _realServerSocket;
    3337    private ConnectionOptions _defaultOptions;
    3438    private long _acceptTimeout;
     
    4549   
    4650    public I2PSocketManagerFull() {
    47         _context = null;
    48         _session = null;
    4951    }
    5052
     
    121123    public I2PSocket receiveSocket() throws I2PException, SocketTimeoutException {
    122124        verifySession();
    123         Connection con = _connectionManager.getConnectionHandler().accept(_connectionManager.MgetSoTimeout());
     125        Connection con = _connectionManager.getConnectionHandler().accept(_connectionManager.getSoTimeout());
    124126        if(_log.shouldLog(Log.DEBUG)) {
    125127            _log.debug("receiveSocket() called: " + con);
     
    130132            return sock;
    131133        } else {
    132             if(_connectionManager.MgetSoTimeout() == -1) {
     134            if(_connectionManager.getSoTimeout() == -1) {
    133135                return null;
    134136            }
     
    170172        _connectionManager.setAllowIncomingConnections(true);
    171173        return _serverSocket;
     174    }
     175
     176    /**
     177     *  Like getServerSocket but returns a real ServerSocket for easier porting of apps.
     178     *  @since 0.8.4
     179     */
     180    public synchronized ServerSocket getStandardServerSocket() throws IOException {
     181        if (_realServerSocket == null)
     182            _realServerSocket = new StandardServerSocket(_serverSocket);
     183        _connectionManager.setAllowIncomingConnections(true);
     184        return _realServerSocket;
    172185    }
    173186
     
    186199     *
    187200     * @param peer Destination to connect to
    188      * @param options I2P socket options to be used for connecting
     201     * @param options I2P socket options to be used for connecting, may be null
    189202     *
    190203     * @return I2PSocket if successful
     
    237250
    238251    /**
     252     *  Like connect() but returns a real Socket, and throws only IOE,
     253     *  for easier porting of apps.
     254     *  @since 0.8.4
     255     */
     256    public Socket connectToSocket(Destination peer) throws IOException {
     257        return connectToSocket(peer, _defaultOptions);
     258    }
     259
     260    /**
     261     *  Like connect() but returns a real Socket, and throws only IOE,
     262     *  for easier porting of apps.
     263     *  @param timeout ms if > 0, forces blocking (disables connectDelay)
     264     *  @since 0.8.4
     265     */
     266    public Socket connectToSocket(Destination peer, int timeout) throws IOException {
     267        ConnectionOptions opts = new ConnectionOptions(_defaultOptions);
     268        opts.setConnectTimeout(timeout);
     269        if (timeout > 0)
     270            opts.setConnectDelay(-1);
     271        return connectToSocket(peer, opts);
     272    }
     273
     274    /**
     275     *  Like connect() but returns a real Socket, and throws only IOE,
     276     *  for easier porting of apps.
     277     *  @param options may be null
     278     *  @since 0.8.4
     279     */
     280    private Socket connectToSocket(Destination peer, I2PSocketOptions options) throws IOException {
     281        try {
     282            I2PSocket sock = connect(peer, options);
     283            return new StandardSocket(sock);
     284        } catch (I2PException i2pe) {
     285            // fixme in 1.6 change to cause
     286            throw new IOException(i2pe.toString());
     287        }
     288    }
     289
     290    /**
    239291     * Destroy the socket manager, freeing all the associated resources.  This
    240292     * method will block untill all the managed sockets are closed.
     
    260312     * @return set of currently connected I2PSockets
    261313     */
    262     public Set listSockets() {
    263         Set connections = _connectionManager.listConnections();
    264         Set rv = new HashSet(connections.size());
    265         for (Iterator iter = connections.iterator(); iter.hasNext(); ) {
    266             Connection con = (Connection)iter.next();
     314    public Set<I2PSocket> listSockets() {
     315        Set<Connection> connections = _connectionManager.listConnections();
     316        Set<I2PSocket> rv = new HashSet(connections.size());
     317        for (Connection con : connections) {
    267318            if (con.getSocket() != null)
    268319                rv.add(con.getSocket());
  • apps/streaming/java/src/net/i2p/client/streaming/MessageHandler.java

    r07b2e3e re721ddd  
    33import java.util.Iterator;
    44import java.util.Set;
     5import java.util.concurrent.CopyOnWriteArraySet;
    56
    67import net.i2p.I2PAppContext;
     
    910import net.i2p.client.I2PSessionListener;
    1011import net.i2p.util.Log;
    11 import net.i2p.util.ConcurrentHashSet;
    1212
    1313/**
     
    2525        _manager = mgr;
    2626        _context = ctx;
    27         _listeners = new ConcurrentHashSet(1);
     27        _listeners = new CopyOnWriteArraySet();
    2828        _log = ctx.logManager().getLog(MessageHandler.class);
    2929        _context.statManager().createRateStat("stream.packetReceiveFailure", "When do we fail to decrypt or otherwise receive a packet sent to us?", "Stream", new long[] { 60*60*1000, 24*60*60*1000 });
  • core/java/src/net/i2p/I2PAppContext.java

    r07b2e3e re721ddd  
    6666public class I2PAppContext {
    6767    /** the context that components without explicit root are bound */
    68     protected static I2PAppContext _globalAppContext;
     68    protected static volatile I2PAppContext _globalAppContext;
    6969   
    7070    protected I2PProperties _overrideProps;
     
    120120     */
    121121    public static I2PAppContext getGlobalContext() {
    122         // skip the global lock
     122        // skip the global lock - _gAC must be volatile
     123        // http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
    123124        I2PAppContext rv = _globalAppContext;
    124125        if (rv != null)
     
    477478     * System.getProperties.
    478479     *
     480     * WARNING - not overridden in RouterContext, doesn't contain router config settings,
     481     * use getProperties() instead.
     482     *
    479483     * @return set of Strings containing the names of defined system properties
    480484     */
     
    484488            names.addAll(_overrideProps.keySet());
    485489        return names;
     490    }
     491   
     492    /**
     493     * Access the configuration attributes of this context, listing the properties
     494     * provided during the context construction, as well as the ones included in
     495     * System.getProperties.
     496     *
     497     * @return new Properties with system and context properties
     498     * @since 0.8.4
     499     */
     500    public Properties getProperties() {
     501        Properties rv = new Properties();
     502        rv.putAll(System.getProperties());
     503        rv.putAll(_overrideProps);
     504        return rv;
    486505    }
    487506   
     
    768787     *
    769788     */
    770     public Clock clock() { // overridden in RouterContext
     789    public Clock clock() {
    771790        if (!_clockInitialized)
    772791            initializeClock();
  • core/java/src/net/i2p/client/I2CPMessageProducer.java

    r07b2e3e re721ddd  
    1313import java.util.Properties;
    1414import java.util.Set;
     15import java.util.concurrent.TimeUnit;
     16import java.util.concurrent.locks.ReentrantLock;
    1517
    1618import net.i2p.I2PAppContext;
     
    4244 */
    4345class I2CPMessageProducer {
    44     private final static Log _log = new Log(I2CPMessageProducer.class);
     46    private final Log _log;
    4547    private final I2PAppContext _context;
    46     private int _sendBps;
    47     private long _sendPeriodBytes;
    48     private long _sendPeriodBeginTime;
     48    private int _maxBytesPerSecond;
     49    private volatile int _sendPeriodBytes;
     50    private volatile long _sendPeriodBeginTime;
     51    private final ReentrantLock _lock;
     52    private static final String PROP_MAX_BW = "i2cp.outboundBytesPerSecond";
     53    /** see ConnectionOptions in streaming  - MTU + streaming overhead + gzip overhead */
     54    private static final int TYP_SIZE = 1730 + 28 + 23;
     55    private static final int MIN_RATE = 2 * TYP_SIZE;
    4956
    5057    public I2CPMessageProducer(I2PAppContext context) {
    5158        _context = context;
    52         context.statManager().createRateStat("client.sendBpsRaw", "How fast we pump out I2CP data messages", "ClientMessages", new long[] { 60*1000, 5*60*1000, 10*60*1000, 60*60*1000 });
     59        _log = context.logManager().getLog(I2CPMessageProducer.class);
     60        _lock = new ReentrantLock(true);
     61        context.statManager().createRateStat("client.sendThrottled", "Times waited for bandwidth", "ClientMessages", new long[] { 60*1000 });
     62        context.statManager().createRateStat("client.sendDropped", "Length of msg dropped waiting for bandwidth", "ClientMessages", new long[] { 60*1000 });
    5363    }
    5464   
     65    /**
     66     * Update the bandwidth setting
     67     * @since 0.8.4
     68     */
     69    public void updateBandwidth(I2PSessionImpl session) {
     70        String max = session.getOptions().getProperty(PROP_MAX_BW);
     71        if (max != null) {
     72            try {
     73                int iMax = Integer.parseInt(max);
     74                if (iMax > 0)
     75                    // round up to next higher TYP_SIZE for efficiency, then add some fudge for small messages
     76                    _maxBytesPerSecond = 256 + Math.max(MIN_RATE, TYP_SIZE * ((iMax + TYP_SIZE - 1) / TYP_SIZE));
     77                else
     78                    _maxBytesPerSecond = 0;
     79            } catch (NumberFormatException nfe) {}
     80        }
     81        if (_log.shouldLog(Log.DEBUG))
     82            _log.debug("Setting " + _maxBytesPerSecond + " BPS max");
     83    }
     84
    5585    /**
    5686     * Send all the messages that a client needs to send to a router to establish
     
    5888     */
    5989    public void connect(I2PSessionImpl session) throws I2PSessionException {
     90        updateBandwidth(session);
    6091        CreateSessionMessage msg = new CreateSessionMessage();
    6192        SessionConfig cfg = new SessionConfig(session.getMyDestination());
     
    100131    public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SessionTag tag,
    101132                            SessionKey key, Set tags, SessionKey newKey, long expires) throws I2PSessionException {
     133        sendMessage(session, dest, nonce, payload, expires, 0);
     134    }
     135
     136    /**
     137     * Package up and send the payload to the router for delivery
     138     * @since 0.8.4
     139     */
     140    public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload,
     141                            long expires, int flags) throws I2PSessionException {
     142
     143        if (!updateBps(payload.length, expires))
     144            // drop the message... send fail notification?
     145            return;
    102146        SendMessageMessage msg;
    103         if (expires > 0) {
    104             msg = new SendMessageExpiresMessage();
    105             ((SendMessageExpiresMessage)msg).setExpiration(new Date(expires));
     147        if (expires > 0 || flags > 0) {
     148            SendMessageExpiresMessage smsg = new SendMessageExpiresMessage();
     149            smsg.setExpiration(expires);
     150            smsg.setFlags(flags);
     151            msg = smsg;
    106152        } else
    107153            msg = new SendMessageMessage();
     
    109155        msg.setSessionId(session.getSessionId());
    110156        msg.setNonce(nonce);
    111         Payload data = createPayload(dest, payload, tag, key, tags, newKey);
     157        Payload data = createPayload(dest, payload, null, null, null, null);
    112158        msg.setPayload(data);
    113159        session.sendMessage(msg);
    114         updateBps(payload.length);
    115     }
    116 
    117     private void updateBps(int len) {
    118         long now = _context.clock().now();
    119         float period = ((float)now-_sendPeriodBeginTime)/1000f;
    120         if (period >= 1f) {
    121             // first term decays on slow transmission
    122             _sendBps = (int)(((float)0.9f * (float)_sendBps) + ((float)0.1f*((float)_sendPeriodBytes)/period));
    123             _sendPeriodBytes = len;
    124             _sendPeriodBeginTime = now;
    125             _context.statManager().addRateData("client.sendBpsRaw", _sendBps, 0);
    126         } else {
    127             _sendPeriodBytes += len;
     160    }
     161
     162    /**
     163     *  Super-simple bandwidth throttler.
     164     *  We only calculate on a one-second basis, so large messages
     165     *  (compared to the one-second limit) may exceed the limits.
     166     *  Tuned for streaming, may not work well for large datagrams.
     167     *
     168     *  This does poorly with low rate limits since it doesn't credit
     169     *  bandwidth across two periods. So the limit is rounded up,
     170     *  and the min limit is set to 2x the typ size, above.
     171     *
     172     *  Blocking so this could be very bad for retransmissions,
     173     *  as it could clog StreamingTimer.
     174     *  Waits are somewhat "fair" using ReentrantLock.
     175     *  While out-of-order transmission is acceptable, fairness
     176     *  reduces the chance of starvation. ReentrantLock does not
     177     *  guarantee in-order execution due to thread priority issues,
     178     *  so out-of-order may still occur. But shouldn't happen within
     179     *  the same thread anyway... Also note that small messages may
     180     *  go ahead of large ones that are waiting for the next window.
     181     *  Also, threads waiting a second time go to the back of the line.
     182     *
     183     *  Since this is at the I2CP layer, it includes streaming overhead,
     184     *  streaming acks and retransmissions,
     185     *  gzip overhead (or "underhead" for compression),
     186     *  repliable datagram overhead, etc.
     187     *  However, it does not, of course, include the substantial overhead
     188     *  imposed by the router for the leaseset, tags, encryption,
     189     *  and fixed-size tunnel messages.
     190     *
     191     *  @param expires if > 0, an expiration date
     192     *  @return true if we should send the message, false to drop it
     193     */
     194    private boolean updateBps(int len, long expires) {
     195        if (_maxBytesPerSecond <= 0)
     196            return true;
     197        //synchronized(this) {
     198        _lock.lock();
     199        try {
     200            int waitCount = 0;
     201            while (true) {
     202                long now = _context.clock().now();
     203                if (waitCount > 0 && expires > 0 && expires < now) {
     204                    // just say no to bufferbloat... drop the message right here
     205                    _context.statManager().addRateData("client.sendDropped", len, 0);
     206                    if (_log.shouldLog(Log.WARN))
     207                        _log.warn("Dropping " + len + " byte msg expired in queue");
     208                    return false;
     209                }
     210
     211                long period = now - _sendPeriodBeginTime;
     212                if (period >= 2000) {
     213                    // start new period, always let it through no matter how big
     214                    _sendPeriodBytes = len;
     215                    _sendPeriodBeginTime = now;
     216                    if (_log.shouldLog(Log.DEBUG))
     217                        _log.debug("New period after idle, " + len + " bytes");
     218                    return true;
     219                }
     220
     221                if (period >= 1000) {
     222                    // start new period
     223                    // Allow burst within 2 sec, only advance window by 1 sec, and
     224                    // every other second give credit for unused bytes in previous period
     225                    if (_sendPeriodBytes > 0 && ((_sendPeriodBeginTime / 1000) & 0x01) == 0)
     226                        _sendPeriodBytes += len - _maxBytesPerSecond;
     227                    else
     228                        _sendPeriodBytes = len;
     229                    _sendPeriodBeginTime += 1000;
     230                    if (_log.shouldLog(Log.DEBUG))
     231                        _log.debug("New period, " + len + " bytes");
     232                    return true;
     233                }
     234
     235                if (_sendPeriodBytes + len <= _maxBytesPerSecond) {
     236                    // still bytes available in this period
     237                    _sendPeriodBytes += len;
     238                    if (_log.shouldLog(Log.DEBUG))
     239                        _log.debug("Sending " + len + ", Elapsed " + period + "ms, total " + _sendPeriodBytes + " bytes");
     240                    return true;
     241                }
     242
     243                if (waitCount >= 2) {
     244                    // just say no to bufferbloat... drop the message right here
     245                    _context.statManager().addRateData("client.sendDropped", len, 0);
     246                    if (_log.shouldLog(Log.WARN))
     247                        _log.warn("Dropping " + len + " byte msg after waiting " + waitCount + " times");
     248                    return false;
     249                }
     250
     251                // wait until next period
     252                _context.statManager().addRateData("client.sendThrottled", ++waitCount, 0);
     253                if (_log.shouldLog(Log.DEBUG))
     254                    _log.debug("Throttled " + len + " bytes, wait #" + waitCount + ' ' + (1000 - period) + "ms" /*, new Exception()*/);
     255                try {
     256                    //this.wait(1000 - period);
     257                    _lock.newCondition().await(1000 - period, TimeUnit.MILLISECONDS);
     258                } catch (InterruptedException ie) {}
     259            }
     260        } finally {
     261            _lock.unlock();
    128262        }
    129263    }
  • core/java/src/net/i2p/client/I2PSession.java

    r07b2e3e re721ddd  
    1010 */
    1111
     12import java.util.Properties;
    1213import java.util.Set;
    1314
     
    2122 * <p>Define the standard means of sending and receiving messages on the
    2223 * I2P network by using the I2CP (the client protocol).  This is done over a
    23  * bidirectional TCP socket and never sends any private keys - all end to end
    24  * encryption is done transparently within the client's I2PSession
    25  * itself.  Periodically the router will ask the client to authorize a new set of
     24 * bidirectional TCP socket and never sends any private keys.
     25 *
     26 * End to end encryption in I2PSession was disabled in release 0.6.
     27 *
     28 * Periodically the router will ask the client to authorize a new set of
    2629 * tunnels to be allocated to the client, which the client can accept by sending a
    2730 * {@link net.i2p.data.LeaseSet} signed by the {@link net.i2p.data.Destination}. 
    28  * In addition, the router may on occation provide the client with an updated
     31 * In addition, the router may on occasion provide the client with an updated
    2932 * clock offset so that the client can stay in sync with the network (even if
    3033 * the host computer's clock is off).</p>
     
    3235 */
    3336public interface I2PSession {
     37
    3438    /** Send a new message to the given destination, containing the specified
    3539     * payload, returning true if the router feels confident that the message
     
    4044     */
    4145    public boolean sendMessage(Destination dest, byte[] payload) throws I2PSessionException;
     46
    4247    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size) throws I2PSessionException;
    43     /** See I2PSessionMuxedImpl for details */
     48
     49    /**
     50     * See I2PSessionMuxedImpl for proto/port details.
     51     * @since 0.7.1
     52     */
    4453    public boolean sendMessage(Destination dest, byte[] payload, int proto, int fromport, int toport) throws I2PSessionException;
    4554
    4655    /**
     56     * End-to-End Crypto is disabled, tags and keys are ignored!
     57     *
    4758     * Like sendMessage above, except the key used and the tags sent are exposed to the
    4859     * application.  <p />
     
    6273     * @param dest location to send the message
    6374     * @param payload body of the message to be sent (unencrypted)
    64      * @param keyUsed session key delivered to the destination for association with the tags sent.  This is essentially
     75     * @param keyUsed UNUSED, IGNORED. Session key delivered to the destination for association with the tags sent.  This is essentially
    6576     *                an output parameter - keyUsed.getData() is ignored during this call, but after the call completes,
    6677     *                it will be filled with the bytes of the session key delivered.  Typically the key delivered is the
    6778     *                same one as the key encrypted with, but not always.  If this is null then the key data will not be
    6879     *                exposed.
    69      * @param tagsSent set of tags delivered to the peer and associated with the keyUsed.  This is also an output parameter -
     80     * @param tagsSent UNUSED, IGNORED. Set of tags delivered to the peer and associated with the keyUsed.  This is also an output parameter -
    7081     *                 the contents of the set is ignored during the call, but afterwards it contains a set of SessionTag
    7182     *                 objects that were sent along side the given keyUsed.
    7283     */
    7384    public boolean sendMessage(Destination dest, byte[] payload, SessionKey keyUsed, Set tagsSent) throws I2PSessionException;
     85
     86    /**
     87     * End-to-End Crypto is disabled, tags and keys are ignored.
     88     * @param keyUsed UNUSED, IGNORED.
     89     * @param tagsSent UNUSED, IGNORED.
     90     */
    7491    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set tagsSent) throws I2PSessionException;
     92
     93    /**
     94     * End-to-End Crypto is disabled, tags and keys are ignored.
     95     * @param keyUsed UNUSED, IGNORED.
     96     * @param tagsSent UNUSED, IGNORED.
     97     * @since 0.7.1
     98     */
    7599    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set tagsSent, long expire) throws I2PSessionException;
    76     /** See I2PSessionMuxedImpl for details */
     100
     101    /**
     102     * See I2PSessionMuxedImpl for proto/port details.
     103     * End-to-End Crypto is disabled, tags and keys are ignored.
     104     * @param keyUsed UNUSED, IGNORED.
     105     * @param tagsSent UNUSED, IGNORED.
     106     * @since 0.7.1
     107     */
    77108    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set tagsSent,
    78109                               int proto, int fromport, int toport) throws I2PSessionException;
    79     /** See I2PSessionMuxedImpl for details */
     110
     111    /**
     112     * See I2PSessionMuxedImpl for proto/port details.
     113     * End-to-End Crypto is disabled, tags and keys are ignored.
     114     * @param keyUsed UNUSED, IGNORED.
     115     * @param tagsSent UNUSED, IGNORED.
     116     * @since 0.7.1
     117     */
    80118    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set tagsSent, long expire,
    81119                               int proto, int fromport, int toport) throws I2PSessionException;
     120
     121    /**
     122     * See I2PSessionMuxedImpl for proto/port details.
     123     * End-to-End Crypto is disabled, tags and keys are ignored.
     124     * @param keyUsed UNUSED, IGNORED.
     125     * @param tagsSent UNUSED, IGNORED.
     126     * @since 0.8.4
     127     */
     128    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set tagsSent, long expire,
     129                               int proto, int fromport, int toport, int flags) throws I2PSessionException;
    82130
    83131    /** Receive a message that the router has notified the client about, returning
     
    153201
    154202    /**
     203     *  Does not remove properties previously present but missing from this options parameter.
     204     *  @param options non-null
     205     *  @since 0.8.4
     206     */
     207    public void updateOptions(Properties options);
     208
     209    /**
    155210     * Get the current bandwidth limits. Blocking.
     211     * @since 0.8.3
    156212     */
    157213    public int[] bandwidthLimits() throws I2PSessionException;
  • core/java/src/net/i2p/client/I2PSessionImpl.java

    r07b2e3e re721ddd  
    222222    }
    223223
     224    /** save some memory, don't pass along the pointless properties */
    224225    private Properties filter(Properties options) {
    225226        Properties rv = new Properties();
    226227        for (Iterator iter = options.keySet().iterator(); iter.hasNext();) {
    227228            String key = (String) iter.next();
     229            if (key.startsWith("java.") ||
     230                key.startsWith("user.") ||
     231                key.startsWith("os.") ||
     232                key.startsWith("sun.") ||
     233                key.startsWith("file.") ||
     234                key.equals("line.separator") ||
     235                key.equals("path.separator") ||
     236                key.equals("prng.buffers") ||
     237                key.equals("router.trustedUpdateKeys") ||
     238                key.startsWith("router.update") ||
     239                key.startsWith("routerconsole.") ||
     240                key.startsWith("time.") ||
     241                key.startsWith("stat.") ||
     242                key.startsWith("gnu.") ||  // gnu JVM
     243                key.startsWith("net.i2p.router.web.") ||  // console nonces
     244                key.startsWith("wrapper.")) {
     245                if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping property: " + key);
     246                continue;
     247            }
    228248            String val = options.getProperty(key);
    229             if (key.startsWith("java") ||
    230                 key.startsWith("user") ||
    231                 key.startsWith("os") ||
    232                 key.startsWith("sun") ||
    233                 key.startsWith("file") ||
    234                 key.startsWith("line") ||
    235                 key.startsWith("wrapper")) {
    236                 if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping property: " + key);
    237             } else if ((key.length() > 255) || (val.length() > 255)) {
     249            if ((key.length() > 255) || (val.length() > 255)) {
    238250                if (_log.shouldLog(Log.WARN))
    239251                    _log.warn(getPrefix() + "Not passing on property ["
     
    246258        }
    247259        return rv;
     260    }
     261
     262    /**
     263     * Update the tunnel and bandwidth settings
     264     * @since 0.8.4
     265     */
     266    public void updateOptions(Properties options) {
     267        _options.putAll(filter(options));
     268        _producer.updateBandwidth(this);
     269        try {
     270            _producer.updateTunnels(this, 0);
     271        } catch (I2PSessionException ise) {}
    248272    }
    249273
     
    398422     */
    399423    public byte[] receiveMessage(int msgId) throws I2PSessionException {
    400         MessagePayloadMessage msg = _availableMessages.remove(new Long(msgId));
     424        MessagePayloadMessage msg = _availableMessages.remove(Long.valueOf(msgId));
    401425        if (msg == null) {
    402426            _log.error("Receive message " + msgId + " had no matches");
     
    414438        _producer.reportAbuse(this, msgId, severity);
    415439    }
    416 
    417     /**
    418      * Send the data to the destination. 
    419      * TODO: this currently always returns true, regardless of whether the message was
    420      * delivered successfully.  make this wait for at least ACCEPTED
    421      *
    422      */
    423     public abstract boolean sendMessage(Destination dest, byte[] payload) throws I2PSessionException;
    424    
    425     /**
    426      * @param keyUsed unused - no end-to-end crypto
    427      * @param tagsSent unused - no end-to-end crypto
    428      */
    429     public abstract boolean sendMessage(Destination dest, byte[] payload, SessionKey keyUsed,
    430                                         Set tagsSent) throws I2PSessionException;
    431440
    432441    public abstract void receiveStatus(int msgId, long nonce, int status);
     
    445454     */
    446455    public void addNewMessage(MessagePayloadMessage msg) {
    447         Long mid = new Long(msg.getMessageId());
     456        Long mid = Long.valueOf(msg.getMessageId());
    448457        _availableMessages.put(mid, msg);
    449458        long id = msg.getMessageId();
     
    495504        public void available(long msgId, int size) {
    496505            synchronized (AvailabilityNotifier.this) {
    497                 _pendingIds.add(new Long(msgId));
     506                _pendingIds.add(Long.valueOf(msgId));
    498507                _pendingSizes.add(Integer.valueOf(size));
    499508                AvailabilityNotifier.this.notifyAll();
  • core/java/src/net/i2p/client/I2PSessionImpl2.java

    r07b2e3e re721ddd  
    131131        throw new IllegalArgumentException("Use MuxedImpl");
    132132    }
     133    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set tagsSent, long expire,
     134                               int proto, int fromport, int toport, int flags) throws I2PSessionException {
     135        throw new IllegalArgumentException("Use MuxedImpl");
     136    }
    133137
    134138    @Override
     
    223227
    224228    /**
     229     * @param keyUsed unused - no end-to-end crypto
     230     * @param tagsSent unused - no end-to-end crypto
     231     */
     232    protected boolean sendBestEffort(Destination dest, byte payload[], SessionKey keyUsed, Set tagsSent, long expires)
     233                    throws I2PSessionException {
     234        return sendBestEffort(dest, payload, expires, 0);
     235    }
     236
     237    /**
    225238     * TODO - Don't need to save MessageState since actuallyWait is false...
    226239     * But for now just use sendNoEffort() instead.
    227240     *
    228      * @param keyUsed unused - no end-to-end crypto
    229      * @param tagsSent unused - no end-to-end crypto
    230      */
    231     protected boolean sendBestEffort(Destination dest, byte payload[], SessionKey keyUsed, Set tagsSent, long expires)
     241     * @param flags to be passed to the router
     242     * @since 0.8.4
     243     */
     244    protected boolean sendBestEffort(Destination dest, byte payload[], long expires, int flags)
    232245                    throws I2PSessionException {
    233246        //SessionKey key = null;
     
    325338                       + " add took " + (afterSendingSync-inSendingSync));
    326339        //_producer.sendMessage(this, dest, nonce, payload, tag, key, sentTags, newKey, expires);
    327         _producer.sendMessage(this, dest, nonce, payload, null, null, null, null, expires);
     340        _producer.sendMessage(this, dest, nonce, payload, expires, flags);
    328341       
    329342        // since this is 'best effort', all we're waiting for is a status update
  • core/java/src/net/i2p/client/I2PSessionMuxedImpl.java

    r07b2e3e re721ddd  
    163163     *  @param fromPort 1-65535 or 0 for unset
    164164     *  @param toPort 1-65535 or 0 for unset
     165     *  @since 0.7.1
    165166     */
    166167    @Override
     
    168169                               SessionKey keyUsed, Set tagsSent, long expires,
    169170                               int proto, int fromPort, int toPort)
     171                   throws I2PSessionException {
     172        return sendMessage(dest, payload, offset, size, keyUsed, tagsSent, 0, proto, fromPort, toPort, 0);
     173    }
     174
     175    /**
     176     *  @param keyUsed unused - no end-to-end crypto
     177     *  @param tagsSent unused - no end-to-end crypto
     178     *  @param proto 1-254 or 0 for unset; recommended:
     179     *         I2PSession.PROTO_UNSPECIFIED
     180     *         I2PSession.PROTO_STREAMING
     181     *         I2PSession.PROTO_DATAGRAM
     182     *         255 disallowed
     183     *  @param fromPort 1-65535 or 0 for unset
     184     *  @param toPort 1-65535 or 0 for unset
     185     *  @param flags to be passed to the router
     186     *  @since 0.8.4
     187     */
     188    @Override
     189    public boolean sendMessage(Destination dest, byte[] payload, int offset, int size,
     190                               SessionKey keyUsed, Set tagsSent, long expires,
     191                               int proto, int fromPort, int toPort, int flags)
    170192                   throws I2PSessionException {
    171193        if (isClosed()) throw new I2PSessionException("Already closed");
     
    184206        _context.statManager().addRateData("i2cp.tx.msgCompressed", payload.length, 0);
    185207        _context.statManager().addRateData("i2cp.tx.msgExpanded", size, 0);
    186         return sendBestEffort(dest, payload, keyUsed, tagsSent, expires);
     208        return sendBestEffort(dest, payload, expires, flags);
    187209    }
    188210
     
    192214    @Override
    193215    public void addNewMessage(MessagePayloadMessage msg) {
    194         Long mid = new Long(msg.getMessageId());
     216        Long mid = Long.valueOf(msg.getMessageId());
    195217        _availableMessages.put(mid, msg);
    196218        long id = msg.getMessageId();
  • core/java/src/net/i2p/client/I2PSimpleSession.java

    r07b2e3e re721ddd  
    100100
    101101    /**
     102     * Ignore, does nothing
     103     * @since 0.8.4
     104     */
     105    @Override
     106    public void updateOptions(Properties options) {}
     107
     108    /**
    102109     * Only map message handlers that we will use
    103110     */
    104     class SimpleMessageHandlerMap extends I2PClientMessageHandlerMap {
     111    private static class SimpleMessageHandlerMap extends I2PClientMessageHandlerMap {
    105112        public SimpleMessageHandlerMap(I2PAppContext context) {
    106113            int highest = Math.max(DestReplyMessage.MESSAGE_TYPE, BandwidthLimitsMessage.MESSAGE_TYPE);
  • core/java/src/net/i2p/crypto/CryptixAESEngine.java

    r07b2e3e re721ddd  
    150150    public final void decryptBlock(byte payload[], int inIndex, SessionKey sessionKey, byte rv[], int outIndex) {
    151151        if ( (payload == null) || (rv == null) )
    152             throw new IllegalArgumentException("null block args [payload=" + payload + " rv="+rv);
     152            throw new IllegalArgumentException("null block args");
    153153        if (payload.length - inIndex > rv.length - outIndex)
    154154            throw new IllegalArgumentException("bad block args [payload.len=" + payload.length
  • core/java/src/net/i2p/crypto/ElGamalAESEngine.java

    r07b2e3e re721ddd  
    1111
    1212import java.util.ArrayList;
     13import java.util.Collections;
    1314import java.util.HashSet;
    1415import java.util.Iterator;
     
    528529    }
    529530
    530     private final static Set EMPTY_SET = new HashSet();
    531 
    532531    /**
    533532     * For both scenarios, this method encrypts the AES area using the given key, iv
     
    553552        //_log.debug("iv for encryption: " + DataHelper.toString(iv, 16));
    554553        //_log.debug("Encrypting AES");
    555         if (tagsForDelivery == null) tagsForDelivery = EMPTY_SET;
     554        if (tagsForDelivery == null) tagsForDelivery = Collections.EMPTY_SET;
    556555        int size = 2 // sizeof(tags)
    557556                 + tagsForDelivery.size()
  • core/java/src/net/i2p/data/Base32.java

    r07b2e3e re721ddd  
    7373
    7474    private static void runApp(String args[]) {
     75        if ("encodestring".equalsIgnoreCase(args[0])) {
     76            System.out.println(encode(args[1].getBytes()));
     77            return;
     78        }
     79        InputStream in = System.in;
     80        OutputStream out = System.out;
    7581        try {
    76             if ("encodestring".equalsIgnoreCase(args[0])) {
    77                 System.out.println(encode(args[1].getBytes()));
    78                 return;
    79             }
    80             InputStream in = System.in;
    81             OutputStream out = System.out;
    8282            if (args.length >= 3) {
    8383                out = new FileOutputStream(args[2]);
     
    9696        } catch (IOException ioe) {
    9797            ioe.printStackTrace(System.err);
     98        } finally {
     99            try { in.close(); } catch (IOException e) {}
     100            try { out.close(); } catch (IOException e) {}
    98101        }
    99102    }
  • core/java/src/net/i2p/data/Base64.java

    r07b2e3e re721ddd  
    179179
    180180    private static void runApp(String args[]) {
     181        if ("encodestring".equalsIgnoreCase(args[0])) {
     182            System.out.println(encode(args[1].getBytes()));
     183            return;
     184        }
     185        InputStream in = System.in;
     186        OutputStream out = System.out;
    181187        try {
    182             if ("encodestring".equalsIgnoreCase(args[0])) {
    183                 System.out.println(encode(args[1].getBytes()));
    184                 return;
    185             }
    186             InputStream in = System.in;
    187             OutputStream out = System.out;
    188188            if (args.length >= 3) {
    189189                out = new FileOutputStream(args[2]);
     
    202202        } catch (IOException ioe) {
    203203            ioe.printStackTrace(System.err);
     204        } finally {
     205            try { in.close(); } catch (IOException e) {}
     206            try { out.close(); } catch (IOException e) {}
    204207        }
    205208    }
  • core/java/src/net/i2p/data/DataHelper.java

    r07b2e3e re721ddd  
    846846    public final static void xor(byte lhs[], int startLeft, byte rhs[], int startRight, byte out[], int startOut, int len) {
    847847        if ( (lhs == null) || (rhs == null) || (out == null) )
    848             throw new NullPointerException("Invalid params to xor (" + lhs + ", " + rhs + ", " + out + ")");
     848            throw new NullPointerException("Null params to xor");
    849849        if (lhs.length < startLeft + len)
    850850            throw new IllegalArgumentException("Left hand side is too short");
  • core/java/src/net/i2p/data/PrivateKeyFile.java

    r07b2e3e re721ddd  
    134134    public Destination createIfAbsent() throws I2PException, IOException, DataFormatException {
    135135        if(!this.file.exists()) {
    136             FileOutputStream out = new FileOutputStream(this.file);
    137             this.client.createDestination(out);
    138             out.close();
     136            FileOutputStream out = null;
     137            try {
     138                out = new FileOutputStream(this.file);
     139                this.client.createDestination(out);
     140            } finally {
     141                if (out != null) {
     142                    try { out.close(); } catch (IOException ioe) {}
     143                }
     144            }
    139145        }
    140146        return getDestination();
     
    244250        return this.open(new Properties());
    245251    }
     252
    246253    public I2PSession open(Properties opts) throws I2PSessionException, IOException {
    247         // open input file
    248         FileInputStream in = new FileInputStream(this.file);
    249        
    250         // create sesssion
    251         I2PSession s = this.client.createSession(in, opts);
    252        
    253         // close file
    254         in.close();
    255        
    256         return s;
     254        FileInputStream in = null;
     255        try {
     256            in = new FileInputStream(this.file);
     257            I2PSession s = this.client.createSession(in, opts);
     258            return s;
     259        } finally {
     260            if (in != null) {
     261                try { in.close(); } catch (IOException ioe) {}
     262            }
     263        }
    257264    }
    258265   
     
    261268     */
    262269    public void write() throws IOException, DataFormatException {
    263         FileOutputStream out = new FileOutputStream(this.file);
    264         this.dest.writeBytes(out);
    265         this.privKey.writeBytes(out);
    266         this.signingPrivKey.writeBytes(out);
    267         out.flush();
    268         out.close();
     270        FileOutputStream out = null;
     271        try {
     272            out = new FileOutputStream(this.file);
     273            this.dest.writeBytes(out);
     274            this.privKey.writeBytes(out);
     275            this.signingPrivKey.writeBytes(out);
     276            out.flush();
     277        } finally {
     278            if (out != null) {
     279                try { out.close(); } catch (IOException ioe) {}
     280            }
     281        }
    269282    }
    270283
     
    378391                    }
    379392                }
    380             } catch (Exception ioe) {
     393            } catch (DataFormatException dfe) {
     394            } catch (IOException ioe) {
    381395            }
    382396            // not found, continue to the next file
  • core/java/src/net/i2p/data/TunnelId.java

    r07b2e3e re721ddd  
    5151    }
    5252
     53    /**
     54     * Overridden for efficiency.
     55     */
     56    @Override
     57    public byte[] toByteArray() {
     58        return DataHelper.toLong(4, _tunnelId);
     59    }
     60
     61    /**
     62     * Overridden for efficiency.
     63     * @param data non-null
     64     * @throws DataFormatException if null or wrong length
     65     */
     66    @Override
     67    public void fromByteArray(byte data[]) throws DataFormatException {
     68        if (data == null) throw new DataFormatException("Null data passed in");
     69        if (data.length != 4) throw new DataFormatException("Bad data length");
     70        _tunnelId = (int) DataHelper.fromLong(data, 0, 4);
     71    }
     72
    5373    @Override
    5474    public boolean equals(Object obj) {
  • core/java/src/net/i2p/data/i2cp/DestReplyMessage.java

    r07b2e3e re721ddd  
    7575
    7676    protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
    77         if (_dest == null && _hash == null)
    78             return new byte[0];  // null response allowed
    79         if (_dest == null && _hash != null)
     77        if (_dest == null) {
     78            if (_hash == null)
     79                return new byte[0];  // null response allowed
    8080            return _hash.getData();
     81        }
    8182        ByteArrayOutputStream os = new ByteArrayOutputStream(_dest.size());
    8283        try {
  • core/java/src/net/i2p/data/i2cp/SendMessageExpiresMessage.java

    r07b2e3e re721ddd  
    1717import net.i2p.data.DataFormatException;
    1818import net.i2p.data.DataHelper;
     19import net.i2p.data.DateAndFlags;
    1920import net.i2p.data.Destination;
    2021import net.i2p.data.Payload;
     
    2324 * Same as SendMessageMessage, but with an expiration to be passed to the router
    2425 *
     26 * As of 0.8.4, retrofitted to use DateAndFlags. Backwards compatible.
     27 *
    2528 * @author zzz
    2629 */
     
    2831    /* FIXME hides another field FIXME */
    2932    public final static int MESSAGE_TYPE = 36;
    30     private SessionId _sessionId;
    31     private Destination _destination;
    32     private Payload _payload;
    33     private Date _expiration;
     33    private final DateAndFlags _daf;
    3434
    3535    public SendMessageExpiresMessage() {
    3636        super();
     37        _daf = new DateAndFlags();
    3738    }
    3839
     40    /**
     41     *  The Date object is created here, it is not cached.
     42     *  Use getExpirationTime() if you only need the long value.
     43     */
    3944    public Date getExpiration() {
    40         return _expiration;
     45        return _daf.getDate();
     46    }
     47
     48    /**
     49     *  Use this instead of getExpiration().getTime()
     50     *  @since 0.8.4
     51     */
     52    public long getExpirationTime() {
     53        return _daf.getTime();
    4154    }
    4255
    4356    public void setExpiration(Date d) {
    44         _expiration = d;
     57        _daf.setDate(d);
     58    }
     59
     60    /**
     61     *  @since 0.8.4
     62     */
     63    public void setExpiration(long d) {
     64        _daf.setDate(d);
     65    }
     66
     67    /**
     68     *  @since 0.8.4
     69     */
     70    public int getFlags() {
     71        return _daf.getFlags();
     72    }
     73
     74    /**
     75     *  @since 0.8.4
     76     */
     77    public void setFlags(int f) {
     78        _daf.setFlags(f);
    4579    }
    4680
     
    5589
    5690        try {
    57             _expiration = DataHelper.readDate(in);
     91            _daf.readBytes(in);
    5892        } catch (DataFormatException dfe) {
    5993            throw new I2CPMessageException("Unable to load the message data", dfe);
     
    69103    @Override
    70104    public void writeMessage(OutputStream out) throws I2CPMessageException, IOException {
    71         if ((getSessionId() == null) || (getDestination() == null) || (getPayload() == null) || (getNonce() <= 0) || (_expiration == null))
     105        if ((getSessionId() == null) || (getDestination() == null) || (getPayload() == null) || (getNonce() <= 0))
    72106            throw new I2CPMessageException("Unable to write out the message as there is not enough data");
    73107        int len = 2 + getDestination().size() + getPayload().getSize() + 4 + 4 + DataHelper.DATE_LENGTH;
     
    80114            getPayload().writeBytes(out);
    81115            DataHelper.writeLong(out, 4, getNonce());
    82             DataHelper.writeDate(out, _expiration);
     116            _daf.writeBytes(out);
    83117        } catch (DataFormatException dfe) {
    84118            throw new I2CPMessageException("Error writing the msg", dfe);
     
    97131            SendMessageExpiresMessage msg = (SendMessageExpiresMessage) object;
    98132            return super.equals(object)
    99                    && DataHelper.eq(getExpiration(), msg.getExpiration());
     133                   && _daf.equals(msg._daf);
    100134        }
    101135         
  • core/java/src/net/i2p/stat/FrequencyStat.java

    r07b2e3e re721ddd  
    9090    @Override
    9191    public boolean equals(Object obj) {
    92         if ((obj == null) || (obj.getClass() != FrequencyStat.class)) return false;
     92        if ((obj == null) || !(obj instanceof FrequencyStat)) return false;
    9393        return _statName.equals(((FrequencyStat)obj)._statName);
    9494    }
  • core/java/src/net/i2p/stat/Rate.java

    r07b2e3e re721ddd  
    474474    @Override
    475475    public boolean equals(Object obj) {
    476         if ((obj == null) || (obj.getClass() != Rate.class)) return false;
     476        if ((obj == null) || !(obj instanceof Rate)) return false;
    477477        if (obj == this) return true;
    478478        Rate r = (Rate) obj;
  • core/java/src/net/i2p/stat/RateStat.java

    r07b2e3e re721ddd  
    109109    @Override
    110110    public boolean equals(Object obj) {
    111         if ((obj == null) || (obj.getClass() != RateStat.class)) return false;
     111        if ((obj == null) || !(obj instanceof RateStat)) return false;
    112112        RateStat rs = (RateStat) obj;
    113113        if (DataHelper.eq(getGroupName(), rs.getGroupName()) && DataHelper.eq(getDescription(), rs.getDescription())
  • core/java/src/net/i2p/util/Clock.java

    r07b2e3e re721ddd  
    11package net.i2p.util;
    22
    3 import java.util.HashSet;
    43import java.util.Iterator;
    54import java.util.Set;
     5import java.util.concurrent.CopyOnWriteArraySet;
    66
    77import net.i2p.I2PAppContext;
     
    2020 */
    2121public class Clock implements Timestamper.UpdateListener {
    22     protected I2PAppContext _context;
    23     private Timestamper _timestamper;
    24     protected long _startedOn;
     22    protected final I2PAppContext _context;
     23    private final Timestamper _timestamper;
     24    protected final long _startedOn;
    2525    protected boolean _statCreated;
     26    protected volatile long _offset;
     27    protected boolean _alreadyChanged;
     28    private final Set _listeners;
    2629   
    2730    public Clock(I2PAppContext context) {
    2831        _context = context;
    29         _offset = 0;
    30         _alreadyChanged = false;
    31         _listeners = new HashSet(1);
     32        _listeners = new CopyOnWriteArraySet();
    3233        _timestamper = new Timestamper(context, this);
    3334        _startedOn = System.currentTimeMillis();
    34         _statCreated = false;
    3535    }
    3636    public static Clock getInstance() {
     
    4242    /** we fetch it on demand to avoid circular dependencies (logging uses the clock) */
    4343    protected Log getLog() { return _context.logManager().getLog(Clock.class); }
    44    
    45     protected volatile long _offset;
    46     protected boolean _alreadyChanged;
    47     private final Set _listeners;
    4844
    4945    /** if the clock is skewed by 3+ days, fuck 'em */
     
    137133
    138134    public void addUpdateListener(ClockUpdateListener lsnr) {
    139         synchronized (_listeners) {
    140135            _listeners.add(lsnr);
    141         }
    142136    }
    143137
    144138    public void removeUpdateListener(ClockUpdateListener lsnr) {
    145         synchronized (_listeners) {
    146139            _listeners.remove(lsnr);
    147         }
    148140    }
    149141
    150142    protected void fireOffsetChanged(long delta) {
    151         synchronized (_listeners) {
    152143            for (Iterator iter = _listeners.iterator(); iter.hasNext();) {
    153144                ClockUpdateListener lsnr = (ClockUpdateListener) iter.next();
    154145                lsnr.offsetChanged(delta);
    155146            }
    156         }
    157147    }
    158148
  • core/java/src/net/i2p/util/ConcurrentHashSet.java

    r07b2e3e re721ddd  
    1515public class ConcurrentHashSet<E> extends AbstractSet<E> implements Set<E> {
    1616    private static final Object DUMMY = new Object();
    17     private Map<E, Object> _map;
     17    private final Map<E, Object> _map;
    1818
    1919    public ConcurrentHashSet() {
  • core/java/src/net/i2p/util/DecayingBloomFilter.java

    r07b2e3e re721ddd  
    2121 */
    2222public class DecayingBloomFilter {
    23     private I2PAppContext _context;
    24     private Log _log;
     23    protected final I2PAppContext _context;
     24    protected final Log _log;
    2525    private BloomSHA1 _current;
    2626    private BloomSHA1 _previous;
    27     private int _durationMs;
    28     private int _entryBytes;
     27    protected final int _durationMs;
     28    protected final int _entryBytes;
    2929    private byte _extenders[][];
    3030    private byte _extended[];
     
    3232    private long _longToEntryMask;
    3333    protected long _currentDuplicates;
    34     private boolean _keepDecaying;
    35     private DecayEvent _decayEvent;
     34    protected volatile boolean _keepDecaying;
     35    protected SimpleTimer.TimedEvent _decayEvent;
    3636    /** just for logging */
    37     private String _name;
     37    protected final String _name;
    3838   
    3939    private static final int DEFAULT_M = 23;
     
    4141    private static final boolean ALWAYS_MISS = false;
    4242   
    43     /** noop for DHS */
    44     public DecayingBloomFilter() {}
     43    /** only for extension by DHS */
     44    protected DecayingBloomFilter(int durationMs, int entryBytes, String name, I2PAppContext context) {
     45        _context = context;
     46        _log = context.logManager().getLog(getClass());
     47        _entryBytes = entryBytes;
     48        _name = name;
     49        _durationMs = durationMs;
     50    }
    4551
    4652    /**
     
    8894            _longToEntryMask = (1l << (_entryBytes * 8l)) -1;
    8995        }
    90         _currentDuplicates = 0;
    9196        _decayEvent = new DecayEvent();
    9297        _keepDecaying = true;
     
    106111   
    107112    public long getCurrentDuplicateCount() { return _currentDuplicates; }
     113
    108114    public int getInsertedCount() {
    109115        synchronized (this) {
     
    111117        }
    112118    }
     119
    113120    public double getFalsePositiveRate() {
    114121        synchronized (this) {
     
    118125   
    119126    /**
    120      * return true if the entry added is a duplicate
    121      *
     127     * @return true if the entry added is a duplicate
    122128     */
    123129    public boolean add(byte entry[]) {
    124130        return add(entry, 0, entry.length);
    125131    }
     132
     133    /**
     134     * @return true if the entry added is a duplicate
     135     */
    126136    public boolean add(byte entry[], int off, int len) {
    127137        if (ALWAYS_MISS) return false;
     
    132142                                               + _entryBytes + "]");
    133143        synchronized (this) {
    134             return locked_add(entry, off, len);
     144            return locked_add(entry, off, len, true);
    135145        }
    136146    }
    137147   
    138148    /**
    139      * return true if the entry added is a duplicate.  the number of low order
     149     * @return true if the entry added is a duplicate.  the number of low order
    140150     * bits used is determined by the entryBytes parameter used on creation of the
    141151     * filter.
     
    144154    public boolean add(long entry) {
    145155        if (ALWAYS_MISS) return false;
    146         synchronized (this) {
    147             if (_entryBytes <= 7)
    148                 entry = ((entry ^ _longToEntryMask) & ((1 << 31)-1)) | (entry ^ _longToEntryMask);
    149                 //entry &= _longToEntryMask;
    150             if (entry < 0) {
    151                 DataHelper.toLong(_longToEntry, 0, _entryBytes, 0-entry);
    152                 _longToEntry[0] |= (1 << 7);
    153             } else {
    154                 DataHelper.toLong(_longToEntry, 0, _entryBytes, entry);
    155             }
    156             return locked_add(_longToEntry, 0, _longToEntry.length);
     156        if (_entryBytes <= 7)
     157            entry = ((entry ^ _longToEntryMask) & ((1 << 31)-1)) | (entry ^ _longToEntryMask);
     158            //entry &= _longToEntryMask;
     159        if (entry < 0) {
     160            DataHelper.toLong(_longToEntry, 0, _entryBytes, 0-entry);
     161            _longToEntry[0] |= (1 << 7);
     162        } else {
     163            DataHelper.toLong(_longToEntry, 0, _entryBytes, entry);
     164        }
     165        synchronized (this) {
     166            return locked_add(_longToEntry, 0, _longToEntry.length, true);
    157167        }
    158168    }
    159169   
    160170    /**
    161      * return true if the entry is already known.  this does NOT add the
     171     * @return true if the entry is already known.  this does NOT add the
    162172     * entry however.
    163173     *
     
    165175    public boolean isKnown(long entry) {
    166176        if (ALWAYS_MISS) return false;
    167         synchronized (this) {
    168             if (_entryBytes <= 7)
    169                 entry = ((entry ^ _longToEntryMask) & ((1 << 31)-1)) | (entry ^ _longToEntryMask);
    170             if (entry < 0) {
    171                 DataHelper.toLong(_longToEntry, 0, _entryBytes, 0-entry);
    172                 _longToEntry[0] |= (1 << 7);
    173             } else {
    174                 DataHelper.toLong(_longToEntry, 0, _entryBytes, entry);
    175             }
     177        if (_entryBytes <= 7)
     178            entry = ((entry ^ _longToEntryMask) & ((1 << 31)-1)) | (entry ^ _longToEntryMask);
     179        if (entry < 0) {
     180            DataHelper.toLong(_longToEntry, 0, _entryBytes, 0-entry);
     181            _longToEntry[0] |= (1 << 7);
     182        } else {
     183            DataHelper.toLong(_longToEntry, 0, _entryBytes, entry);
     184        }
     185        synchronized (this) {
    176186            return locked_add(_longToEntry, 0, _longToEntry.length, false);
    177187        }
    178188    }
    179189   
    180     private boolean locked_add(byte entry[], int offset, int len) {
    181         return locked_add(entry, offset, len, true);
    182     }
    183190    private boolean locked_add(byte entry[], int offset, int len, boolean addIfNew) {
    184191        if (_extended != null) {
     
    196203                if (addIfNew) {
    197204                    _current.locked_insert(_extended);
    198                     _previous.locked_insert(_extended);
    199205                }
    200206                return false;
     
    209215                if (addIfNew) {
    210216                    _current.locked_insert(entry, offset, len);
    211                     _previous.locked_insert(entry, offset, len);
    212217                }
    213218                return false;
  • core/java/src/net/i2p/util/DecayingHashSet.java

    r07b2e3e re721ddd  
    1818 *      ./router/java/src/net/i2p/router/tunnel/BuildMessageProcessor.java:
    1919 *           32 bytes, peak 10 entries in 1m
     20 *           (320 peak entries seen on fast router)
    2021 *
    2122 *      ./router/java/src/net/i2p/router/transport/udp/InboundMessageFragments.java:
    2223 *           4 bytes, peak 150 entries in 10s
     24 *           (1600 peak entries seen on fast router)
    2325 *
    2426 *      ./router/java/src/net/i2p/router/MessageValidator.java:
    2527 *           8 bytes, peak 1K entries in 2m
     28 *           (36K peak entries seen on fast router)
    2629 *
    2730 *      ./router/java/src/net/i2p/router/tunnel/BloomFilterIVValidator.java:
     
    5861 */
    5962public class DecayingHashSet extends DecayingBloomFilter {
    60     private final I2PAppContext _context;
    61     private final Log _log;
    6263    private ConcurrentHashSet<ArrayWrapper> _current;
    6364    private ConcurrentHashSet<ArrayWrapper> _previous;
    64     private int _durationMs;
    65     private int _entryBytes;
    66     private volatile boolean _keepDecaying;
    67     private final DecayEvent _decayEvent;
    68     /** just for logging */
    69     private final String _name;
    7065    /** synchronize against this lock when switching double buffers */
    7166    private final ReentrantReadWriteLock _reorganizeLock = new ReentrantReadWriteLock(true);
    72    
    7367   
    7468    /**
     
    8478    /** @param name just for logging / debugging / stats */
    8579    public DecayingHashSet(I2PAppContext context, int durationMs, int entryBytes, String name) {
     80        super(durationMs, entryBytes, name, context);
    8681        if (entryBytes <= 0 || entryBytes > 32)
    8782            throw new IllegalArgumentException("Bad size");
    88         _context = context;
    89         _log = context.logManager().getLog(DecayingHashSet.class);
    90         _entryBytes = entryBytes;
    91         _name = name;
    9283        _current = new ConcurrentHashSet(128);
    9384        _previous = new ConcurrentHashSet(128);
    94         _durationMs = durationMs;
    95         _currentDuplicates = 0;
    9685        _decayEvent = new DecayEvent();
    9786        _keepDecaying = true;
     
    112101        return _current.size() + _previous.size();
    113102    }
     103
    114104    /** pointless, only used for logging elsewhere */
    115105    @Override
     
    122112    /**
    123113     * @return true if the entry added is a duplicate
    124      *
    125114     */
    126115    @Override
     
    131120            throw new IllegalArgumentException("Bad entry [" + len + ", expected "
    132121                                               + _entryBytes + "]");
     122        ArrayWrapper w = new ArrayWrapper(entry, off, len);
    133123        getReadLock();
    134124        try {
    135             return locked_add(entry, off, len, true);
     125            return locked_add(w, true);
    136126        } finally { releaseReadLock(); }
    137127    }
     
    159149
    160150    private boolean add(long entry, boolean addIfNew) {
    161         int len = Math.min(8, _entryBytes);
    162         byte[] b = toLong(len, entry);
     151        ArrayWrapper w = new ArrayWrapper(entry);
    163152        getReadLock();
    164153        try {
    165             return locked_add(b, 0, len, addIfNew);
     154            return locked_add(w, addIfNew);
    166155        } finally { releaseReadLock(); }
    167156    }
    168157   
    169     /** from DataHelper, except negative values ok */
    170     private static byte[] toLong(int numBytes, long value) {
    171         byte target[] = new byte[numBytes];
    172         for (int i = 0; i < numBytes; i++)
    173             target[numBytes-i-1] = (byte)(value >>> (i*8));
    174         return target;
    175     }
    176    
    177     /** so many questions... */
    178     private boolean locked_add(byte entry[], int offset, int len, boolean addIfNew) {
    179         ArrayWrapper w = new ArrayWrapper(entry, offset, len);
    180         boolean seen = _current.contains(w);
    181         seen = seen || _previous.contains(w);
     158    /**
     159     *  @param addIfNew if true, add the element to current if it is not already there;
     160     *                  if false, only check
     161     *  @return if the element is in either the current or previous set
     162     */
     163    private boolean locked_add(ArrayWrapper w, boolean addIfNew) {
     164        boolean seen;
     165        // only access _current once. This adds to _current even if seen in _previous.
     166        if (addIfNew)
     167            seen = !_current.add(w);
     168        else
     169            seen = _current.contains(w);
     170        if (!seen)
     171            seen = _previous.contains(w);
    182172        if (seen) {
    183             // why increment if addIfNew == false?
    184             // why not add to current if only in previous?
     173            // why increment if addIfNew == false? Only used for stats...
    185174            _currentDuplicates++;
    186         } else if (addIfNew) {
    187             _current.add(w);
    188             // why add to previous?
    189             _previous.add(w);
    190175        }
    191176        return seen;
     
    271256     */
    272257    private static class ArrayWrapper {
    273         private long _longhashcode;
     258        private final long _longhashcode;
     259
    274260        public ArrayWrapper(byte[] b, int offset, int len) {
    275261            int idx = offset;
    276262            int shift = Math.min(8, 64 / len);
     263            long lhc = 0;
    277264            for (int i = 0; i < len; i++) {
    278265                // xor better than + in tests
    279                 _longhashcode ^= (((long) b[idx++]) << (i * shift));
     266                lhc ^= (((long) b[idx++]) << (i * shift));
    280267            }
     268            _longhashcode = lhc;
     269        }
     270
     271        /** faster version for when storing <= 8 bytes */
     272        public ArrayWrapper(long b) {
     273            _longhashcode = b;
    281274        }
    282275
  • core/java/src/net/i2p/util/EepGet.java

    r07b2e3e re721ddd  
    431431        while (_keepFetching) {
    432432            SocketTimeout timeout = null;
    433             if (_fetchHeaderTimeout > 0)
     433            if (_fetchHeaderTimeout > 0) {
    434434                timeout = new SocketTimeout(_fetchHeaderTimeout);
    435             final SocketTimeout stimeout = timeout; // ugly - why not use sotimeout?
    436             timeout.setTimeoutCommand(new Runnable() {
    437                 public void run() {
    438                     if (_log.shouldLog(Log.DEBUG))
    439                         _log.debug("timeout reached on " + _url + ": " + stimeout);
    440                     _aborted = true;
    441                 }
    442             });
    443             timeout.setTotalTimeoutPeriod(_fetchEndTime);
     435                final SocketTimeout stimeout = timeout; // ugly - why not use sotimeout?
     436                timeout.setTimeoutCommand(new Runnable() {
     437                    public void run() {
     438                        if (_log.shouldLog(Log.DEBUG))
     439                            _log.debug("timeout reached on " + _url + ": " + stimeout);
     440                        _aborted = true;
     441                    }
     442                });
     443                timeout.setTotalTimeoutPeriod(_fetchEndTime);
     444            }
    444445            try {
    445446                for (int i = 0; i < _listeners.size(); i++)
    446447                    _listeners.get(i).attempting(_url);
    447448                sendRequest(timeout);
    448                 timeout.resetTimer();
     449                if (timeout != null)
     450                    timeout.resetTimer();
    449451                doFetch(timeout);
    450                 timeout.cancel();
     452                if (timeout != null)
     453                    timeout.cancel();
    451454                if (!_transferFailed)
    452455                    return true;
    453456                break;
    454457            } catch (IOException ioe) {
    455                 timeout.cancel();
     458                if (timeout != null)
     459                    timeout.cancel();
    456460                for (int i = 0; i < _listeners.size(); i++)
    457461                    _listeners.get(i).attemptFailed(_url, _bytesTransferred, _bytesRemaining, _currentAttempt, _numRetries, ioe);
     
    493497    }
    494498
    495     /** single fetch */
     499    /**
     500     *  single fetch
     501     *  @param timeout may be null
     502     */
    496503    protected void doFetch(SocketTimeout timeout) throws IOException {
    497504        _headersRead = false;
     
    505512            throw new IOException("Timed out reading the HTTP headers");
    506513       
    507         timeout.resetTimer();
    508         if (_fetchInactivityTimeout > 0)
    509             timeout.setInactivityTimeout(_fetchInactivityTimeout);
    510         else
    511             timeout.setInactivityTimeout(INACTIVITY_TIMEOUT);
     514        if (timeout != null) {
     515            timeout.resetTimer();
     516            if (_fetchInactivityTimeout > 0)
     517                timeout.setInactivityTimeout(_fetchInactivityTimeout);
     518            else
     519                timeout.setInactivityTimeout(INACTIVITY_TIMEOUT);
     520        }
    512521       
    513522        if (_redirectLocation != null) {
     
    572581            if (read == -1)
    573582                break;
    574             timeout.resetTimer();
     583            if (timeout != null)
     584                timeout.resetTimer();
    575585            _out.write(buf, 0, read);
    576586            _bytesTransferred += read;
     
    598608                }
    599609            }
    600             timeout.resetTimer();
     610            if (timeout != null)
     611                timeout.resetTimer();
    601612            if (_bytesRemaining >= read) // else chunked?
    602613                _bytesRemaining -= read;
     
    623634            throw new IOException("Timed out reading the HTTP data");
    624635       
    625         timeout.cancel();
     636        if (timeout != null)
     637            timeout.cancel();
    626638       
    627639        if (_log.shouldLog(Log.DEBUG))
     
    868880    private static boolean isNL(byte b) { return (b == NL); }
    869881
     882    /**
     883     *  @param timeout may be null
     884     */
    870885    protected void sendRequest(SocketTimeout timeout) throws IOException {
    871886        if (_outputStream != null) {
     
    908923        _proxyOut = _proxy.getOutputStream();
    909924       
    910         timeout.setSocket(_proxy);
     925        if (timeout != null)
     926            timeout.setSocket(_proxy);
    911927       
    912928        _proxyOut.write(DataHelper.getUTF8(req));
  • core/java/src/net/i2p/util/EepPost.java

    r07b2e3e re721ddd  
    3232    }
    3333   
     34/*****
    3435    public static void main(String args[]) {
    3536        EepPost e = new EepPost();
     
    4849        //e.postFiles("http://localhost:2001/import.jsp", null, -1, fields, null);
    4950    }
     51*****/
     52
    5053    /**
    5154     * Submit an HTTP POST to the given URL (using the proxy if specified),
     
    118121                }
    119122                out.close();
    120             } catch (Exception e) {
     123            } catch (IOException e) {
    121124                e.printStackTrace();
    122125            } finally {
  • core/java/src/net/i2p/util/FileUtil.java

    r07b2e3e re721ddd  
    123123                    }
    124124                } else {
     125                    InputStream in = null;
     126                    FileOutputStream fos = null;
     127                    JarOutputStream jos = null;
    125128                    try {
    126                         InputStream in = zip.getInputStream(entry);
     129                        in = zip.getInputStream(entry);
    127130                        if (entry.getName().endsWith(".jar.pack") || entry.getName().endsWith(".war.pack")) {
    128131                            target = new File(targetDir, entry.getName().substring(0, entry.getName().length() - ".pack".length()));
    129                             JarOutputStream fos = new JarOutputStream(new FileOutputStream(target));
    130                             unpack(in, fos);
    131                             fos.close();
     132                            jos = new JarOutputStream(new FileOutputStream(target));
     133                            unpack(in, jos);
    132134                            System.err.println("INFO: File [" + entry.getName() + "] extracted and unpacked");
    133135                        } else {
    134                             FileOutputStream fos = new FileOutputStream(target);
     136                            fos = new FileOutputStream(target);
    135137                            int read = 0;
    136138                            while ( (read = in.read(buf)) != -1) {
    137139                                fos.write(buf, 0, read);
    138140                            }
    139                             fos.close();
    140141                            System.err.println("INFO: File [" + entry.getName() + "] extracted");
    141142                        }
    142                         in.close();
    143143                    } catch (IOException ioe) {
    144144                        System.err.println("ERROR: Error extracting the zip entry (" + entry.getName() + ')');
     
    152152                                           "), your JVM does not support unpack200");
    153153                        return false;
     154                    } finally {
     155                        try { if (in != null) in.close(); } catch (IOException ioe) {}
     156                        try { if (fos != null) fos.close(); } catch (IOException ioe) {}
     157                        try { if (jos != null) jos.close(); } catch (IOException ioe) {}
    154158                    }
    155159                }
     
    402406       
    403407        byte buf[] = new byte[4096];
    404         try {
    405             FileInputStream in = new FileInputStream(src);
    406             FileOutputStream out = new FileOutputStream(dst);
     408        InputStream in = null;
     409        OutputStream out = null;
     410        try {
     411            in = new FileInputStream(src);
     412            out = new FileOutputStream(dst);
    407413           
    408414            int read = 0;
     
    410416                out.write(buf, 0, read);
    411417           
    412             in.close();
    413             out.close();
    414418            return true;
    415419        } catch (IOException ioe) {
     
    417421                ioe.printStackTrace();
    418422            return false;
     423        } finally {
     424            try { if (in != null) in.close(); } catch (IOException ioe) {}
     425            try { if (out != null) out.close(); } catch (IOException ioe) {}
    419426        }
    420427    }
  • core/java/src/net/i2p/util/I2PAppThread.java

    r07b2e3e re721ddd  
    1111
    1212
    13 import java.util.HashSet;
    1413import java.util.Iterator;
    1514import java.util.Set;
     15import java.util.concurrent.CopyOnWriteArraySet;
    1616
    1717/**
     
    2323public class I2PAppThread extends I2PThread {
    2424
    25     private Set _threadListeners = new HashSet(0);
     25    private final Set _threadListeners = new CopyOnWriteArraySet();
    2626
    2727    public I2PAppThread() {
  • core/java/src/net/i2p/util/I2PThread.java

    r07b2e3e re721ddd  
    1111
    1212
    13 import java.util.HashSet;
    1413import java.util.Iterator;
    1514import java.util.Set;
     15import java.util.concurrent.CopyOnWriteArraySet;
    1616
    1717/**
     
    2222public class I2PThread extends Thread {
    2323    private static volatile Log _log;
    24     private static Set _listeners = new HashSet(4);
     24    private static final Set _listeners = new CopyOnWriteArraySet();
    2525    private String _name;
    2626    private Exception _createdBy;
  • core/java/src/net/i2p/util/Log.java

    r07b2e3e re721ddd  
    206206        @Override
    207207        public boolean equals(Object obj) {
    208             if (obj == null) throw new NullPointerException("Null object scope?");
     208            if (obj == null)
     209                return false;
    209210            if (obj instanceof LogScope) {
    210211                LogScope s = (LogScope)obj;
  • core/java/src/net/i2p/util/LogManager.java

    r07b2e3e re721ddd  
    167167        if (rv == null) {
    168168            rv = new Log(this, cls, name);
    169             _logs.putIfAbsent(scope, rv);
    170             isNew = true;
     169            Log old = _logs.putIfAbsent(scope, rv);
     170            isNew = old == null;
     171            if (!isNew)
     172                rv = old;
    171173        }
    172174        if (isNew)
     
    181183
    182184    void addLog(Log log) {
    183         _logs.putIfAbsent(log.getScope(), log);
    184         updateLimit(log);
     185        Log old = _logs.putIfAbsent(log.getScope(), log);
     186        if (old == null)
     187            updateLimit(log);
    185188    }
    186189   
     
    637640    }
    638641
     642/*****
    639643    public static void main(String args[]) {
    640644        I2PAppContext ctx = new I2PAppContext();
     
    657661        System.exit(0);
    658662    }
     663*****/
    659664
    660665    public void shutdown() {
  • core/java/src/net/i2p/util/LogRecordFormatter.java

    r07b2e3e re721ddd  
    9393
    9494    /** don't translate */
     95/****
    9596    private static String getPriority(LogRecord rec) {
    9697        return toString(Log.toLevelString(rec.getPriority()), MAX_PRIORITY_LENGTH);
    9798    }
     99****/
    98100
     101    /** */
    99102    private static final String BUNDLE_NAME = "net.i2p.router.web.messages";
    100103
  • core/java/src/net/i2p/util/LookaheadInputStream.java

    r07b2e3e re721ddd  
    7979    public byte[] getFooter() { return _footerLookahead; }
    8080   
     81/*******
    8182    public static void main(String args[]) {
    8283        byte buf[] = new byte[32];
     
    129130        }
    130131    }
     132******/
    131133}
  • core/java/src/net/i2p/util/SSLEepGet.java

    r07b2e3e re721ddd  
    483483            throw new IOException("Timed out reading the HTTP headers");
    484484       
    485         timeout.resetTimer();
    486         if (_fetchInactivityTimeout > 0)
    487             timeout.setInactivityTimeout(_fetchInactivityTimeout);
    488         else
    489             timeout.setInactivityTimeout(60*1000);
    490        
     485        if (timeout != null) {
     486            timeout.resetTimer();
     487            if (_fetchInactivityTimeout > 0)
     488                timeout.setInactivityTimeout(_fetchInactivityTimeout);
     489            else
     490                timeout.setInactivityTimeout(60*1000);
     491        }       
     492
    491493        if (_redirectLocation != null) {
    492494            throw new IOException("Server redirect to " + _redirectLocation + " not allowed");
     
    507509            if (read == -1)
    508510                break;
    509             timeout.resetTimer();
     511            if (timeout != null)
     512                timeout.resetTimer();
    510513            _out.write(buf, 0, read);
    511514            _bytesTransferred += read;
     
    532535                }
    533536            }
    534             timeout.resetTimer();
     537            if (timeout != null)
     538                timeout.resetTimer();
    535539            if (_bytesRemaining >= read) // else chunked?
    536540                _bytesRemaining -= read;
     
    557561            throw new IOException("Timed out reading the HTTP data");
    558562       
    559         timeout.cancel();
     563        if (timeout != null)
     564            timeout.cancel();
    560565       
    561566        if (_transferFailed) {
  • core/java/src/net/i2p/util/ShellCommand.java

    r07b2e3e re721ddd  
    9090     * @author hypercubus
    9191     */
    92     private class StreamConsumer extends Thread {
     92    private static class StreamConsumer extends Thread {
    9393
    9494        private BufferedReader    bufferedReader;
     
    124124     * @author hypercubus
    125125     */
    126     private class StreamReader extends Thread {
     126    private static class StreamReader extends Thread {
    127127
    128128        private BufferedReader    bufferedReader;
     
    160160     * @author hypercubus
    161161     */
    162     private class StreamWriter extends Thread {
     162    private static class StreamWriter extends Thread {
    163163
    164164        private BufferedWriter     bufferedWriter;
     
    184184                    bufferedWriter.flush();
    185185                }
    186             } catch (Exception e) {
     186            } catch (IOException e) {
    187187                try {
    188188                    bufferedWriter.flush();
  • core/java/src/net/i2p/util/SimpleTimer.java

    r07b2e3e re721ddd  
    9191        long now = System.currentTimeMillis();
    9292        long eventTime = now + timeoutMs;
    93         Long time = new Long(eventTime);
     93        Long time = Long.valueOf(eventTime);
    9494        synchronized (_events) {
    9595            // remove the old scheduled position, then reinsert it
  • core/java/src/net/i2p/util/SimpleTimer2.java

    r07b2e3e re721ddd  
    5656    }
    5757
    58     private class CustomScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
     58    private static class CustomScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
    5959        public CustomScheduledThreadPoolExecutor(int threads, ThreadFactory factory) {
    6060             super(threads, factory);
  • installer/resources/jetty.xml

    r07b2e3e re721ddd  
    1313<!--           enclosed in brackets e.g. [::1]                                 -->
    1414<!--   * port: Default 7658 in the addListener section                         -->
    15 <!--   * threads: Raise MaxThreads in the addListener section                  -->
     15<!--   * docroot: Change the ResourceBase in the addContext section            -->
     16<!--           to serve files from a different location.                       -->
     17<!--   * threads: Raise MinThreads and/or MaxThreads in the addListener section -->
    1618<!--           if you have a high-traffic site and get a lot of warnings.      -->
    1719<!--   * Uncomment the addWebApplications section to use to enable             -->
     
    2426<!-- or run any other web server such as Apache. If you do run another         -->
    2527<!-- web server instead, be sure and disable the Jetty 5 server for your       -->
    26 <!-- eepsite on http://127.0.0.1/configclients.jsp .                           -->
     28<!-- eepsite on http://127.0.0.1:7657/configclients.jsp .                      -->
    2729<!--                                                                           -->
    2830<!-- Jetty errors and warnings will appear in wrapper.log, check there         -->
     
    5860          </New>
    5961        </Arg>
    60         <Set name="MinThreads">3</Set>
    61         <Set name="MaxThreads">10</Set>
     62        <Set name="MinThreads">1</Set>
     63        <Set name="MaxThreads">16</Set>
    6264        <Set name="MaxIdleTimeMs">60000</Set>
    6365        <Set name="LowResourcePersistTimeMs">1000</Set>
    6466        <Set name="ConfidentialPort">8443</Set>
    6567        <Set name="IntegralPort">8443</Set>
    66         <Set name="PoolName">main</Set>
    6768      </New>
    6869    </Arg>
  • router/java/src/net/i2p/data/i2np/DatabaseStoreMessage.java

    r07b2e3e re721ddd  
    1313
    1414import net.i2p.I2PAppContext;
     15import net.i2p.data.DatabaseEntry;
    1516import net.i2p.data.DataFormatException;
    1617import net.i2p.data.DataHelper;
     
    2930    public final static int MESSAGE_TYPE = 1;
    3031    private Hash _key;
    31     private int _type;
    32     private LeaseSet _leaseSet;
    33     private RouterInfo _info;
    34     private byte[] _leaseSetCache;
    35     private byte[] _routerInfoCache;
     32    private DatabaseEntry _dbEntry;
     33    private byte[] _byteCache;
    3634    private long _replyToken;
    3735    private TunnelId _replyTunnel;
    3836    private Hash _replyGateway;
    3937   
    40     public final static int KEY_TYPE_ROUTERINFO = 0;
    41     public final static int KEY_TYPE_LEASESET = 1;
    42    
    4338    public DatabaseStoreMessage(I2PAppContext context) {
    4439        super(context);
    45         setValueType(-1);
    4640    }
    4741   
     
    5044     *
    5145     */
    52     public Hash getKey() { return _key; }
    53     public void setKey(Hash key) { _key = key; }
    54    
    55     /**
    56      * Defines the router info value in the network database being stored
    57      *
    58      */
    59     public RouterInfo getRouterInfo() { return _info; }
    60     public void setRouterInfo(RouterInfo routerInfo) {
    61         _info = routerInfo;
    62         if (_info != null)
    63             setValueType(KEY_TYPE_ROUTERINFO);
    64     }
    65    
    66     /**
    67      * Defines the lease set value in the network database being stored
    68      *
    69      */
    70     public LeaseSet getLeaseSet() { return _leaseSet; }
    71     public void setLeaseSet(LeaseSet leaseSet) {
    72         _leaseSet = leaseSet;
    73         if (_leaseSet != null)
    74             setValueType(KEY_TYPE_LEASESET);
    75     }
    76    
    77     /**
    78      * Defines type of key being stored in the network database -
    79      * either KEY_TYPE_ROUTERINFO or KEY_TYPE_LEASESET
    80      *
    81      */
    82     public int getValueType() { return _type; }
    83     public void setValueType(int type) { _type = type; }
     46    public Hash getKey() {
     47        if (_key != null)
     48            return _key;   // receive
     49        if (_dbEntry != null)
     50            return _dbEntry.getHash();   // create
     51        return null;
     52    }
     53   
     54    /**
     55     * Defines the entry in the network database being stored
     56     */
     57    public DatabaseEntry getEntry() { return _dbEntry; }
     58
     59    /**
     60     * This also sets the key
     61     */
     62    public void setEntry(DatabaseEntry entry) {
     63        _dbEntry = entry;
     64    }
    8465   
    8566    /**
     
    9172     */
    9273    public long getReplyToken() { return _replyToken; }
     74
    9375    /**
    9476     * Update the reply token.
     
    11496        int curIndex = offset;
    11597       
    116         //byte keyData[] = new byte[Hash.HASH_LENGTH];
    117         //System.arraycopy(data, curIndex, keyData, 0, Hash.HASH_LENGTH);
    11898        _key = Hash.create(data, curIndex);
    11999        curIndex += Hash.HASH_LENGTH;
    120         //_key = new Hash(keyData);
    121        
    122         _type = (int)DataHelper.fromLong(data, curIndex, 1);
     100       
     101        type = (int)DataHelper.fromLong(data, curIndex, 1);
    123102        curIndex++;
    124103       
     
    132111            curIndex += 4;
    133112           
    134             //byte gw[] = new byte[Hash.HASH_LENGTH];
    135             //System.arraycopy(data, curIndex, gw, 0, Hash.HASH_LENGTH);
    136113            _replyGateway = Hash.create(data, curIndex);
    137114            curIndex += Hash.HASH_LENGTH;
    138             //_replyGateway = new Hash(gw);
    139115        } else {
    140116            _replyTunnel = null;
     
    142118        }
    143119       
    144         if (_type == KEY_TYPE_LEASESET) {
    145             _leaseSet = new LeaseSet();
     120        if (type == DatabaseEntry.KEY_TYPE_LEASESET) {
     121            _dbEntry = new LeaseSet();
    146122            try {
    147                 _leaseSet.readBytes(new ByteArrayInputStream(data, curIndex, data.length-curIndex));
     123                _dbEntry.readBytes(new ByteArrayInputStream(data, curIndex, data.length-curIndex));
    148124            } catch (DataFormatException dfe) {
    149125                throw new I2NPMessageException("Error reading the leaseSet", dfe);
    150126            }
    151         } else if (_type == KEY_TYPE_ROUTERINFO) {
    152             _info = new RouterInfo();
     127        } else if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
     128            _dbEntry = new RouterInfo();
    153129            int compressedSize = (int)DataHelper.fromLong(data, curIndex, 2);
    154130            curIndex += 2;
     
    156132            try {
    157133                byte decompressed[] = DataHelper.decompress(data, curIndex, compressedSize);
    158                 _info.readBytes(new ByteArrayInputStream(decompressed));
     134                _dbEntry.readBytes(new ByteArrayInputStream(decompressed));
    159135            } catch (DataFormatException dfe) {
    160136                throw new I2NPMessageException("Error reading the routerInfo", dfe);
     
    163139            }
    164140        } else {
    165             throw new I2NPMessageException("Invalid type of key read from the structure - " + _type);
    166         }
     141            throw new I2NPMessageException("Invalid type of key read from the structure - " + type);
     142        }
     143        //if (!key.equals(_dbEntry.getHash()))
     144        //    throw new I2NPMessageException("Hash mismatch in DSM");
    167145    }
    168146   
     
    173151        if (_replyToken > 0)
    174152            len += 4 + Hash.HASH_LENGTH; // replyTunnel+replyGateway
    175         if (_type == KEY_TYPE_LEASESET) {
    176             _leaseSetCache = _leaseSet.toByteArray();
    177             len += _leaseSetCache.length;
    178         } else if (_type == KEY_TYPE_ROUTERINFO) {
    179             byte uncompressed[] = _info.toByteArray();
    180             byte compressed[] = DataHelper.compress(uncompressed);
    181             _routerInfoCache = compressed;
    182             len += compressed.length + 2;
    183         }
     153        if (_dbEntry.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
     154            _byteCache = _dbEntry.toByteArray();
     155        } else if (_dbEntry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
     156            byte uncompressed[] = _dbEntry.toByteArray();
     157            _byteCache = DataHelper.compress(uncompressed);
     158            len += 2;
     159        }
     160        len += _byteCache.length;
    184161        return len;
    185162    }
     163
    186164    /** write the message body to the output array, starting at the given index */
    187165    protected int writeMessageBody(byte out[], int curIndex) throws I2NPMessageException {
    188         if (_key == null) throw new I2NPMessageException("Invalid key");
    189         if ( (_type != KEY_TYPE_LEASESET) && (_type != KEY_TYPE_ROUTERINFO) ) throw new I2NPMessageException("Invalid key type");
    190         if ( (_type == KEY_TYPE_LEASESET) && (_leaseSet == null) ) throw new I2NPMessageException("Missing lease set");
    191         if ( (_type == KEY_TYPE_ROUTERINFO) && (_info == null) ) throw new I2NPMessageException("Missing router info");
    192        
    193         System.arraycopy(_key.getData(), 0, out, curIndex, Hash.HASH_LENGTH);
     166        if (_dbEntry == null) throw new I2NPMessageException("Missing entry");
     167        int type = _dbEntry.getType();
     168        if (type != DatabaseEntry.KEY_TYPE_LEASESET && type != DatabaseEntry.KEY_TYPE_ROUTERINFO)
     169            throw new I2NPMessageException("Invalid key type");
     170       
     171        // Use the hash of the DatabaseEntry
     172        System.arraycopy(getKey().getData(), 0, out, curIndex, Hash.HASH_LENGTH);
    194173        curIndex += Hash.HASH_LENGTH;
    195         byte type[] = DataHelper.toLong(1, _type);
    196         out[curIndex++] = type[0];
     174        out[curIndex++] = (byte) type;
    197175        byte tok[] = DataHelper.toLong(4, _replyToken);
    198176        System.arraycopy(tok, 0, out, curIndex, 4);
     
    210188        }
    211189       
    212         if (_type == KEY_TYPE_LEASESET) {
    213             // initialized in calculateWrittenLength
    214             System.arraycopy(_leaseSetCache, 0, out, curIndex, _leaseSetCache.length);
    215             curIndex += _leaseSetCache.length;
    216         } else if (_type == KEY_TYPE_ROUTERINFO) {
    217             byte len[] = DataHelper.toLong(2, _routerInfoCache.length);
     190        // _byteCache initialized in calculateWrittenLength
     191        if (type == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
     192            byte len[] = DataHelper.toLong(2, _byteCache.length);
    218193            out[curIndex++] = len[0];
    219194            out[curIndex++] = len[1];
    220             System.arraycopy(_routerInfoCache, 0, out, curIndex, _routerInfoCache.length);
    221             curIndex += _routerInfoCache.length;
    222         }
     195        }
     196        System.arraycopy(_byteCache, 0, out, curIndex, _byteCache.length);
     197        curIndex += _byteCache.length;
    223198        return curIndex;
    224199    }
     
    229204    public int hashCode() {
    230205        return DataHelper.hashCode(getKey()) +
    231                DataHelper.hashCode(getLeaseSet()) +
    232                DataHelper.hashCode(getRouterInfo()) +
    233                getValueType() +
     206               DataHelper.hashCode(_dbEntry) +
    234207               (int)getReplyToken() +
    235208               DataHelper.hashCode(getReplyTunnel()) +
     
    242215            DatabaseStoreMessage msg = (DatabaseStoreMessage)object;
    243216            return DataHelper.eq(getKey(),msg.getKey()) &&
    244                    DataHelper.eq(getLeaseSet(),msg.getLeaseSet()) &&
    245                    DataHelper.eq(getRouterInfo(),msg.getRouterInfo()) &&
    246                    _type == msg.getValueType() &&
     217                   DataHelper.eq(_dbEntry,msg.getEntry()) &&
    247218                   getReplyToken() == msg.getReplyToken() &&
    248219                   DataHelper.eq(getReplyTunnel(), msg.getReplyTunnel()) &&
     
    260231        buf.append("\n\tUnique ID: ").append(getUniqueId());
    261232        buf.append("\n\tKey: ").append(getKey());
    262         buf.append("\n\tValue Type: ").append(getValueType());
    263         buf.append("\n\tRouter Info: ").append(getRouterInfo());
    264         buf.append("\n\tLease Set: ").append(getLeaseSet());
     233        buf.append("\n\tEntry: ").append(_dbEntry);
    265234        buf.append("\n\tReply token: ").append(getReplyToken());
    266235        buf.append("\n\tReply tunnel: ").append(getReplyTunnel());
  • router/java/src/net/i2p/data/i2np/I2NPMessageImpl.java

    r07b2e3e re721ddd  
    123123                throw new I2NPMessageException("Hash does not match for " + getClass().getName());
    124124
    125             long start = _context.clock().now();
     125            //long start = _context.clock().now();
    126126            if (_log.shouldLog(Log.DEBUG))
    127127                _log.debug("Reading bytes: type = " + type + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
     
    185185            throw new I2NPMessageException("Hash does not match for " + getClass().getName());
    186186
    187         long start = _context.clock().now();
     187        //long start = _context.clock().now();
    188188        if (_log.shouldLog(Log.DEBUG))
    189189            _log.debug("Reading bytes: type = " + type + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
     
    241241   
    242242    public int toByteArray(byte buffer[]) {
    243         long start = _context.clock().now();
     243        //long start = _context.clock().now();
    244244
    245245        int prefixLen = 1 // type
  • router/java/src/net/i2p/data/i2np/TunnelDataMessage.java

    r07b2e3e re721ddd  
    161161    protected int writeMessageBody(byte out[], int curIndex) throws I2NPMessageException {
    162162        if ( (_tunnelId <= 0) || (_data == null) )
    163             throw new I2NPMessageException("Not enough data to write out (id=" + _tunnelId + " data=" + _data + ")");
     163            throw new I2NPMessageException("Not enough data to write out (id=" + _tunnelId + ")");
    164164        if (_data.length <= 0)
    165165            throw new I2NPMessageException("Not enough data to write out (data.length=" + _data.length + ")");
  • router/java/src/net/i2p/router/Blocklist.java

    r07b2e3e re721ddd  
    6060 */
    6161public class Blocklist {
    62     private Log _log;
     62    private final Log _log;
    6363    private RouterContext _context;
    6464    private long _blocklist[];
     
    7373        _context = context;
    7474        _log = context.logManager().getLog(Blocklist.class);
    75         _blocklist = null;
    76         _blocklistSize = 0;
    77         _wrapSave = null;
    7875    }
    7976   
     77    /** only for testing with main() */
    8078    public Blocklist() {
    8179        _log = new Log(Blocklist.class);
    82         _blocklist = null;
    83         _blocklistSize = 0;
    8480    }
    8581   
     
    684680        Job job = new ShitlistJob(peer);
    685681        if (number > 0)
    686             job.getTiming().setStartAfter(_context.clock().now() + (number * 30*1000));
     682            job.getTiming().setStartAfter(_context.clock().now() + (30*1000l * number));
    687683        _context.jobQueue().addJob(job);
    688684    }
  • router/java/src/net/i2p/router/ClientMessage.java

    r07b2e3e re721ddd  
    2929    private MessageId _messageId;
    3030    private long _expiration;
     31    /** only for outbound messages */
     32    private int _flags;
    3133   
    3234    public ClientMessage() {
    33         setPayload(null);
    34         setDestination(null);
    35         setFromDestination(null);
    36         setReceptionInfo(null);
    37         setSenderConfig(null);
    38         setDestinationHash(null);
    39         setMessageId(null);
    40         setExpiration(0);
    4135    }
    4236   
     
    10296    public long getExpiration() { return _expiration; }
    10397    public void setExpiration(long e) { _expiration = e; }
     98
     99    /**
     100     * Flags requested by the client that sent the message.  This will only be available
     101     * for locally originated messages.
     102     *
     103     * @since 0.8.4
     104     */
     105    public int getFlags() { return _flags; }
     106
     107    /**
     108     * @since 0.8.4
     109     */
     110    public void setFlags(int f) { _flags = f; }
    104111}
  • router/java/src/net/i2p/router/ClientMessagePool.java

    r07b2e3e re721ddd  
    2424 */
    2525public class ClientMessagePool {
    26     private Log _log;
    27     private RouterContext _context;
     26    private final Log _log;
     27    private final RouterContext _context;
    2828   
    2929    public ClientMessagePool(RouterContext context) {
    3030        _context = context;
    3131        _log = _context.logManager().getLog(ClientMessagePool.class);
     32        OutboundClientMessageOneShotJob.init(_context);
    3233    }
    3334 
     
    6667    }
    6768   
     69/******
    6870    private boolean isGuaranteed(ClientMessage msg) {
    6971        Properties opts = null;
     
    7779        }
    7880    }
     81******/
    7982}
  • router/java/src/net/i2p/router/DummyNetworkDatabaseFacade.java

    r07b2e3e re721ddd  
    1717import java.util.Set;
    1818
     19import net.i2p.data.DatabaseEntry;
    1920import net.i2p.data.Hash;
    2021import net.i2p.data.LeaseSet;
     
    3738    }
    3839   
     40    public DatabaseEntry lookupLocally(Hash key) { return null; }
    3941    public void lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs) {}
    4042    public LeaseSet lookupLeaseSetLocally(Hash key) { return null; }
  • router/java/src/net/i2p/router/InNetMessagePool.java

    r07b2e3e re721ddd  
    3131 */
    3232public class InNetMessagePool implements Service {
    33     private Log _log;
    34     private RouterContext _context;
    35     private HandlerJobBuilder _handlerJobBuilders[];
     33    private final Log _log;
     34    private final RouterContext _context;
     35    private final HandlerJobBuilder _handlerJobBuilders[];
     36
    3637    /** following 5 unused unless DISPATCH_DIRECT == false */
    3738    private final List _pendingDataMessages;
     
    4041    private SharedShortCircuitDataJob _shortCircuitDataJob;
    4142    private SharedShortCircuitGatewayJob _shortCircuitGatewayJob;
     43
    4244    private boolean _alive;
    4345    private boolean _dispatchThreaded;
  • router/java/src/net/i2p/router/JobQueue.java

    r07b2e3e re721ddd  
    3535 */
    3636public class JobQueue {
    37     private Log _log;
    38     private RouterContext _context;
     37    private final Log _log;
     38    private final RouterContext _context;
    3939   
    4040    /** Integer (runnerId) to JobQueueRunner for created runners */
     
    4343    private volatile static int _runnerId = 0;
    4444    /** list of jobs that are ready to run ASAP */
    45     private BlockingQueue<Job> _readyJobs;
     45    private final BlockingQueue<Job> _readyJobs;
    4646    /** list of jobs that are scheduled for running in the future */
    47     private List<Job> _timedJobs;
     47    private final List<Job> _timedJobs;
    4848    /** job name to JobStat for that job */
    4949    private final Map<String, JobStats> _jobStats;
    5050    /** how many job queue runners can go concurrently */
    5151    private int _maxRunners = 1;
    52     private QueuePumper _pumper;
     52    private final QueuePumper _pumper;
    5353    /** will we allow the # job runners to grow beyond 1? */
    5454    private boolean _allowParallelOperation;
     
    209209     */
    210210    public boolean isJobActive(Job job) {
    211         if (_readyJobs.contains(job) | _timedJobs.contains(job))
     211        if (_readyJobs.contains(job) || _timedJobs.contains(job))
    212212            return true;
    213213        for (JobQueueRunner runner: _queueRunners.values())
     
    690690        for (int i = 0; i < timedJobs.size(); i++) {
    691691            Job j = timedJobs.get(i);
    692             ordered.put(new Long(j.getTiming().getStartAfter()), j);
     692            ordered.put(Long.valueOf(j.getTiming().getStartAfter()), j);
    693693        }
    694694        for (Iterator<Job> iter = ordered.values().iterator(); iter.hasNext(); ) {
  • router/java/src/net/i2p/router/JobQueueRunner.java

    r07b2e3e re721ddd  
    55/** a do run run run a do run run */
    66class JobQueueRunner implements Runnable {
    7     private Log _log;
    8     private RouterContext _context;
     7    private final Log _log;
     8    private final RouterContext _context;
    99    private boolean _keepRunning;
    10     private int _id;
     10    private final int _id;
    1111    private long _numJobs;
    1212    private Job _currentJob;
     
    2020        _id = id;
    2121        _keepRunning = true;
    22         _numJobs = 0;
    23         _currentJob = null;
    24         _lastJob = null;
    2522        _log = _context.logManager().getLog(JobQueueRunner.class);
    2623        _context.statManager().createRateStat("jobQueue.jobRun", "How long jobs take", "JobQueue", new long[] { 60*60*1000l, 24*60*60*1000l });
  • router/java/src/net/i2p/router/JobStats.java

    r07b2e3e re721ddd  
    55/** glorified struct to contain basic job stats */
    66class JobStats {
    7     private String _job;
     7    private final String _job;
    88    private volatile long _numRuns;
    99    private volatile long _totalTime;
  • router/java/src/net/i2p/router/JobTiming.java

    r07b2e3e re721ddd  
    1919    private long _actualStart;
    2020    private long _actualEnd;
    21     private RouterContext _context;
     21    private final RouterContext _context;
    2222   
    2323    public JobTiming(RouterContext context) {
  • router/java/src/net/i2p/router/KeyManager.java

    r07b2e3e re721ddd  
    1313import java.io.FileOutputStream;
    1414import java.io.IOException;
    15 import java.util.HashSet;
    1615import java.util.Map;
    17 import java.util.Set;
    1816import java.util.concurrent.ConcurrentHashMap;
    1917
     
    3836 */
    3937public class KeyManager {
    40     private Log _log;
    41     private RouterContext _context;
     38    private final Log _log;
     39    private final RouterContext _context;
    4240    private PrivateKey _privateKey;
    4341    private PublicKey _publicKey;
     
    4543    private SigningPublicKey _signingPublicKey;
    4644    private final Map<Hash, LeaseSetKeys> _leaseSetKeys; // Destination --> LeaseSetKeys
    47     private SynchronizeKeysJob _synchronizeJob;
     45    private final SynchronizeKeysJob _synchronizeJob;
    4846   
    4947    public final static String PROP_KEYDIR = "router.keyBackupDir";
     
    6260        _log = _context.logManager().getLog(KeyManager.class); 
    6361        _synchronizeJob = new SynchronizeKeysJob();
    64         setPrivateKey(null);
    65         setPublicKey(null);
    66         setSigningPrivateKey(null);
    67         setSigningPublicKey(null);
    6862        _leaseSetKeys = new ConcurrentHashMap();
    6963    }
     
    131125    public LeaseSetKeys getKeys(Hash dest) {
    132126            return _leaseSetKeys.get(dest);
    133     }
    134    
    135     public Set<LeaseSetKeys> getAllKeys() {
    136         HashSet keys = new HashSet();
    137         keys.addAll(_leaseSetKeys.values());
    138         return keys;
    139127    }
    140128   
  • router/java/src/net/i2p/router/MessageValidator.java

    r07b2e3e re721ddd  
    1414 */
    1515public class MessageValidator {
    16     private Log _log;
    17     private RouterContext _context;
     16    private final Log _log;
     17    private final RouterContext _context;
    1818    private DecayingBloomFilter _filter;
    1919   
     
    2121    public MessageValidator(RouterContext context) {
    2222        _log = context.logManager().getLog(MessageValidator.class);
    23         _filter = null;
    2423        _context = context;
    2524        context.statManager().createRateStat("router.duplicateMessageId", "Note that a duplicate messageId was received", "Router",
  • router/java/src/net/i2p/router/MultiRouter.java

    r07b2e3e re721ddd  
    9191    private static Properties getEnv(String filename) {
    9292        Properties props = new Properties();
     93        FileInputStream in = null;
    9394        try {
    94             props.load(new FileInputStream(filename));
     95            in = new FileInputStream(filename);
     96            props.load(in);
    9597            props.setProperty("time.disabled", "true");
    9698            return props;
     
    98100            ioe.printStackTrace();
    99101            return null;
     102        } finally {
     103            if (in != null) try { in.close(); } catch (IOException ioe) {}
    100104        }
    101105    }
  • router/java/src/net/i2p/router/NetworkDatabaseFacade.java

    r07b2e3e re721ddd  
    1414import java.util.Set;
    1515
     16import net.i2p.data.DatabaseEntry;
    1617import net.i2p.data.Hash;
    1718import net.i2p.data.LeaseSet;
     
    3334    public abstract Set<Hash> findNearestRouters(Hash key, int maxNumRouters, Set<Hash> peersToIgnore);
    3435   
     36    /**
     37     *  @return RouterInfo, LeaseSet, or null
     38     *  @since 0.8.3
     39     */
     40    public abstract DatabaseEntry lookupLocally(Hash key);
    3541    public abstract void lookupLeaseSet(Hash key, Job onFindJob, Job onFailedLookupJob, long timeoutMs);
    3642    public abstract LeaseSet lookupLeaseSetLocally(Hash key);
  • router/java/src/net/i2p/router/OutNetMessage.java

    r07b2e3e re721ddd  
    9090            synchronized (this) {
    9191                locked_initTimestamps();
    92                 while (_timestamps.containsKey(eventName)) {
    93                     eventName = eventName + '.';
    94                 }
    95                 _timestamps.put(eventName, new Long(now));
     92                // ???
     93                //while (_timestamps.containsKey(eventName)) {
     94                //    eventName = eventName + '.';
     95                //}
     96                _timestamps.put(eventName, Long.valueOf(now));
    9697                _timestampOrder.add(eventName);
    9798            }
     
    99100        return now - _created;
    100101    }
     102
     103    /** @deprecated unused */
    101104    public Map<String, Long> getTimestamps() {
    102105        if (_log.shouldLog(Log.INFO)) {
     
    108111        return Collections.EMPTY_MAP;
    109112    }
     113
     114    /** @deprecated unused */
    110115    public Long getTimestamp(String eventName) {
    111116        if (_log.shouldLog(Log.INFO)) {
     
    221226    public void transportFailed(String transportStyle) {
    222227        if (_failedTransports == null)
    223             _failedTransports = new HashSet(1);
     228            _failedTransports = new HashSet(2);
    224229        _failedTransports.add(transportStyle);
    225230    }
     
    369374    public boolean equals(Object obj) {
    370375        if(obj == null) return false;
    371         if(obj.getClass() != OutNetMessage.class) return false;
     376        if(!(obj instanceof OutNetMessage)) return false;
    372377        return obj == this; // two OutNetMessages are different even if they contain the same message
    373378    }
  • router/java/src/net/i2p/router/RouterClock.java

    r07b2e3e re721ddd  
    3535    private int _lastStratum;
    3636
    37     RouterContext _contextRC; // LINT field hides another field
     37    private final RouterContext _contextRC;
    3838
    3939    public RouterClock(RouterContext context) {
  • router/java/src/net/i2p/router/RouterContext.java

    r07b2e3e re721ddd  
    1010import net.i2p.router.client.ClientManagerFacadeImpl;
    1111import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
    12 import net.i2p.router.peermanager.Calculator;
    13 import net.i2p.router.peermanager.CapacityCalculator;
    14 import net.i2p.router.peermanager.IntegrationCalculator;
    1512import net.i2p.router.peermanager.PeerManagerFacadeImpl;
    1613import net.i2p.router.peermanager.ProfileManagerImpl;
    1714import net.i2p.router.peermanager.ProfileOrganizer;
    18 import net.i2p.router.peermanager.SpeedCalculator;
    1915import net.i2p.router.transport.CommSystemFacadeImpl;
    2016import net.i2p.router.transport.FIFOBandwidthLimiter;
     
    5955    private MessageStateMonitor _messageStateMonitor;
    6056    private RouterThrottle _throttle;
    61     private RouterClock _clockX;  // LINT field hides another field, hope rename won't break anything.
    62     private Calculator _integrationCalc;
    63     private Calculator _speedCalc;
    64     private Calculator _capacityCalc;
    65 
    6657
    6758    private static List<RouterContext> _contexts = new ArrayList(1);
     
    167158        _throttle = new RouterThrottleImpl(this);
    168159        //_throttle = new RouterDoSThrottle(this);
    169         _integrationCalc = new IntegrationCalculator(this);
    170         _speedCalc = new SpeedCalculator(this);
    171         _capacityCalc = new CapacityCalculator(this);
    172160    }
    173161   
     
    290278     */
    291279    public RouterThrottle throttle() { return _throttle; }
    292    
    293     /** how do we rank the integration of profiles? */
    294     public Calculator integrationCalculator() { return _integrationCalc; }
    295     /** how do we rank the speed of profiles? */
    296     public Calculator speedCalculator() { return _speedCalc; }
    297     /** how do we rank the capacity of profiles? */
    298     public Calculator capacityCalculator() { return _capacityCalc; }
    299280   
    300281    @Override
     
    321302        buf.append(_shitlist).append('\n');
    322303        buf.append(_messageValidator).append('\n');
    323         buf.append(_integrationCalc).append('\n');
    324         buf.append(_speedCalc).append('\n');
    325304        return buf.toString();
    326305    }
     
    372351
    373352    /**
    374      * The context's synchronized clock, which is kept context specific only to
    375      * enable simulators to play with clock skew among different instances.
    376      *
    377      * It wouldn't be necessary to override clock(), except for the reason
    378      * that it triggers initializeClock() of which we definitely
    379      * need the local version to run.
    380      */
    381     @Override
    382     public Clock clock() {
    383         if (!_clockInitialized) initializeClock();
    384         return _clockX;
    385     }
     353     * @return new Properties with system and context properties
     354     * @since 0.8.4
     355     */
     356    @Override
     357    public Properties getProperties() {
     358        Properties rv = super.getProperties();
     359        if (_router != null)
     360            rv.putAll(_router.getConfigMap());
     361        return rv;
     362    }
     363   
    386364    @Override
    387365    protected void initializeClock() {
    388366        synchronized (this) {
    389             if (_clockX == null)
    390                 _clockX = new RouterClock(this);
     367            if (_clock == null)
     368                _clock = new RouterClock(this);
    391369            _clockInitialized = true;
    392370        }
  • router/java/src/net/i2p/router/RouterThrottleImpl.java

    r07b2e3e re721ddd  
    1313 */
    1414class RouterThrottleImpl implements RouterThrottle {
    15     private RouterContext _context;
    16     private Log _log;
     15    private final RouterContext _context;
     16    private final Log _log;
    1717    private String _tunnelStatus;
    1818   
    1919    /**
    20      * arbitrary hard limit of 10 seconds - if its taking this long to get
     20     * arbitrary hard limit - if it's taking this long to get
    2121     * to a job, we're congested.
    2222     *
     
    9999            return TunnelHistory.TUNNEL_REJECT_BANDWIDTH;
    100100
    101         long lag = _context.jobQueue().getMaxLag();
     101        //long lag = _context.jobQueue().getMaxLag();
    102102        // reject here if lag too high???
    103103       
  • router/java/src/net/i2p/router/RouterWatchdog.java

    r07b2e3e re721ddd  
    1313 */
    1414class RouterWatchdog implements Runnable {
    15     private Log _log;
    16     private RouterContext _context;
     15    private final Log _log;
     16    private final RouterContext _context;
    1717    private int _consecutiveErrors;
    1818   
  • router/java/src/net/i2p/router/Shitlist.java

    r07b2e3e re721ddd  
    1111import java.io.IOException;
    1212import java.io.Writer;
    13 import java.util.concurrent.ConcurrentHashMap;
    1413import java.util.ArrayList;
    1514import java.util.HashMap;
     
    1817import java.util.Map;
    1918import java.util.Set;
     19import java.util.concurrent.ConcurrentHashMap;
    2020
    2121import net.i2p.data.DataHelper;
     
    3232 */
    3333public class Shitlist {
    34     private Log _log;
    35     private RouterContext _context;
    36     private Map<Hash, Entry> _entries;
     34    private final Log _log;
     35    private final RouterContext _context;
     36    private final Map<Hash, Entry> _entries;
    3737   
    3838    public static class Entry {
     
    157157        e.transports = null;
    158158        if (transport != null) {
    159             e.transports = new ConcurrentHashSet(1);
     159            e.transports = new ConcurrentHashSet(2);
    160160            e.transports.add(transport);
    161161        }
  • router/java/src/net/i2p/router/StatisticsManager.java

    r07b2e3e re721ddd  
    158158    }
    159159   
     160/*****
    160161    private void includeRate(String rateName, Properties stats, long selectedPeriods[]) {
    161162        includeRate(rateName, stats, selectedPeriods, false);
    162163    }
     164*****/
     165
    163166    /**
    164167     * @param fudgeQuantity the data being published in this stat is too sensitive to, uh
     
    259262            buf.append("0;0;0;0;");
    260263        }
    261         long numPeriods = rate.getLifetimePeriods();
    262264        buf.append(num(fudgeQuantity)).append(';');
    263265        return buf.toString();
  • router/java/src/net/i2p/router/client/ClientConnectionRunner.java

    r07b2e3e re721ddd  
    281281        id.setMessageId(getNextMessageId());
    282282        long expiration = 0;
    283         if (message instanceof SendMessageExpiresMessage)
    284             expiration = ((SendMessageExpiresMessage) message).getExpiration().getTime();
     283        int flags = 0;
     284        if (message.getType() == SendMessageExpiresMessage.MESSAGE_TYPE) {
     285            SendMessageExpiresMessage msg = (SendMessageExpiresMessage) message;
     286            expiration = msg.getExpirationTime();
     287            flags = msg.getFlags();
     288        }
    285289        if (!_dontSendMSM)
    286290            _acceptedPending.add(id);
     
    290294                       + payload.getSize() + "]" + " for session [" + _sessionId.getSessionId()
    291295                       + "]");
    292         long beforeDistribute = _context.clock().now();
     296        //long beforeDistribute = _context.clock().now();
    293297        // the following blocks as described above
    294298        SessionConfig cfg = _config;
    295299        if (cfg != null)
    296             _manager.distributeMessage(cfg.getDestination(), dest, payload, id, expiration);
    297         long timeToDistribute = _context.clock().now() - beforeDistribute;
    298         if (_log.shouldLog(Log.DEBUG))
    299             _log.warn("Time to distribute in the manager to "
    300                       + dest.calculateHash().toBase64() + ": "
    301                       + timeToDistribute);
     300            _manager.distributeMessage(cfg.getDestination(), dest, payload, id, expiration, flags);
     301        // else log error?
     302        //long timeToDistribute = _context.clock().now() - beforeDistribute;
     303        //if (_log.shouldLog(Log.DEBUG))
     304        //    _log.warn("Time to distribute in the manager to "
     305        //              + dest.calculateHash().toBase64() + ": "
     306        //              + timeToDistribute);
    302307        return id;
    303308    }
  • router/java/src/net/i2p/router/client/ClientManager.java

    r07b2e3e re721ddd  
    194194    }
    195195   
    196     void distributeMessage(Destination fromDest, Destination toDest, Payload payload, MessageId msgId, long expiration) {
     196    /**
     197     * Distribute message to a local or remote destination.
     198     * @param flags ignored for local
     199     */
     200    void distributeMessage(Destination fromDest, Destination toDest, Payload payload, MessageId msgId, long expiration, int flags) {
    197201        // check if there is a runner for it
    198202        ClientConnectionRunner runner = getRunner(toDest);
     
    205209                return;
    206210            }
     211            // TODO can we just run this inline instead?
    207212            _ctx.jobQueue().addJob(new DistributeLocal(toDest, runner, sender, fromDest, payload, msgId));
    208213        } else {
     
    218223            msg.setDestination(toDest);
    219224            msg.setPayload(payload);
    220             msg.setReceptionInfo(null);
    221225            msg.setSenderConfig(runner.getConfig());
    222226            msg.setFromDestination(runner.getConfig().getDestination());
    223227            msg.setMessageId(msgId);
    224228            msg.setExpiration(expiration);
     229            msg.setFlags(flags);
    225230            _ctx.clientMessagePool().add(msg, true);
    226231        }
     
    228233   
    229234    private class DistributeLocal extends JobImpl {
    230         private Destination _toDest;
    231         private ClientConnectionRunner _to;
    232         private ClientConnectionRunner _from;
    233         private Destination _fromDest;
    234         private Payload _payload;
    235         private MessageId _msgId;
     235        private final Destination _toDest;
     236        private final ClientConnectionRunner _to;
     237        private final ClientConnectionRunner _from;
     238        private final Destination _fromDest;
     239        private final Payload _payload;
     240        private final MessageId _msgId;
    236241       
    237242        public DistributeLocal(Destination toDest, ClientConnectionRunner to, ClientConnectionRunner from, Destination fromDest, Payload payload, MessageId id) {
     
    434439    }
    435440   
     441    /** @deprecated unused */
    436442    public void renderStatusHTML(Writer out) throws IOException {
     443/******
    437444        StringBuilder buf = new StringBuilder(8*1024);
    438445        buf.append("<u><b>Local destinations</b></u><br>");
     
    480487        out.write(buf.toString());
    481488        out.flush();
     489******/
    482490    }
    483491   
  • router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java

    r07b2e3e re721ddd  
    208208    }
    209209   
     210    /** @deprecated unused */
    210211    @Override
    211212    public void renderStatusHTML(Writer out) throws IOException {
  • router/java/src/net/i2p/router/client/SSLClientListenerRunner.java

    r07b2e3e re721ddd  
    143143        File sdir = new SecureDirectory(_context.getConfigDir(), "certificates");
    144144        if (sdir.exists() || sdir.mkdir()) {
     145            InputStream fis = null;
    145146            try {
    146147                KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    147                 InputStream fis = new FileInputStream(ks);
     148                fis = new FileInputStream(ks);
    148149                String ksPass = _context.getProperty(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD);
    149150                keyStore.load(fis, ksPass.toCharArray());
    150                 fis.close();
    151151                Certificate cert = keyStore.getCertificate(KEY_ALIAS);
    152152                if (cert != null) {
     
    160160            } catch (IOException ioe) {
    161161                _log.error("Error saving ASCII SSL keys", ioe);
     162            } finally {
     163                if (fis != null) try { fis.close(); } catch (IOException ioe) {}
    162164            }
    163165        } else {
     
    209211            return false;
    210212        }
     213        InputStream fis = null;
    211214        try {
    212215            SSLContext sslc = SSLContext.getInstance("TLS");
    213216            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    214             InputStream fis = new FileInputStream(ks);
     217            fis = new FileInputStream(ks);
    215218            keyStore.load(fis, ksPass.toCharArray());
    216             fis.close();
    217219            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    218220            kmf.init(keyStore, keyPass.toCharArray());
     
    224226        } catch (IOException ioe) {
    225227            _log.error("Error loading SSL keys", ioe);
     228        } finally {
     229            if (fis != null) try { fis.close(); } catch (IOException ioe) {}
    226230        }
    227231        return false;
  • router/java/src/net/i2p/router/message/CloveSet.java

    r07b2e3e re721ddd  
    1919 *
    2020 */
    21 public class CloveSet {
    22     private List _cloves;
     21class CloveSet {
     22    private final List _cloves;
    2323    private Certificate _cert;
    2424    private long _msgId;
     
    2626   
    2727    public CloveSet() {
    28         _cloves = new ArrayList();
    29         _cert = null;
     28        _cloves = new ArrayList(4);
    3029        _msgId = -1;
    3130        _expiration = -1;
  • router/java/src/net/i2p/router/message/GarlicConfig.java

    r07b2e3e re721ddd  
    2222 *
    2323 */
    24 public class GarlicConfig {
     24class GarlicConfig {
    2525    private RouterInfo _recipient;
    2626    private PublicKey _recipientPublicKey;
     
    2828    private long _id;
    2929    private long _expiration;
    30     private List _cloveConfigs;
     30    private final List _cloveConfigs;
    3131    private DeliveryInstructions _instructions;
    3232    private boolean _requestAck;
     
    4040        _id = -1;
    4141        _expiration = -1;
    42         _cloveConfigs = new ArrayList();
     42        _cloveConfigs = new ArrayList(4);
    4343        _replyBlockMessageId = -1;
    4444        _replyBlockExpiration = -1;
  • router/java/src/net/i2p/router/message/GarlicMessageHandler.java

    r07b2e3e re721ddd  
    2222 */
    2323public class GarlicMessageHandler implements HandlerJobBuilder {
    24     private RouterContext _context;
     24    private final RouterContext _context;
    2525   
    2626    public GarlicMessageHandler(RouterContext context) {
  • router/java/src/net/i2p/router/message/GarlicMessageParser.java

    r07b2e3e re721ddd  
    2525 *
    2626 */
    27 public class GarlicMessageParser {
    28     private Log _log;
    29     private RouterContext _context;
     27class GarlicMessageParser {
     28    private final Log _log;
     29    private final RouterContext _context;
    3030   
    3131    public GarlicMessageParser(RouterContext context) {
     
    4848        if (decrData == null) {
    4949            if (_log.shouldLog(Log.WARN))
    50                 _log.warn("Decryption of garlic message failed (data = " + encData + ")", new Exception("Decrypt fail"));
     50                _log.warn("Decryption of garlic message failed", new Exception("Decrypt fail"));
    5151            return null;
    5252        } else {
  • router/java/src/net/i2p/router/message/GarlicMessageReceiver.java

    r07b2e3e re721ddd  
    2727 */
    2828public class GarlicMessageReceiver {
    29     private RouterContext _context;
    30     private Log _log;
    31     private CloveReceiver _receiver;
    32     private Hash _clientDestination;
    33     private GarlicMessageParser _parser;
     29    private final RouterContext _context;
     30    private final Log _log;
     31    private final CloveReceiver _receiver;
     32    private final Hash _clientDestination;
     33    private final GarlicMessageParser _parser;
    3434   
    3535    private final static int FORWARD_PRIORITY = 50;
  • router/java/src/net/i2p/router/message/HandleGarlicMessageJob.java

    r07b2e3e re721ddd  
    2929 *
    3030 */
    31 public class HandleGarlicMessageJob extends JobImpl implements GarlicMessageReceiver.CloveReceiver {
    32     private Log _log;
    33     private GarlicMessage _message;
     31class HandleGarlicMessageJob extends JobImpl implements GarlicMessageReceiver.CloveReceiver {
     32    private final Log _log;
     33    private final GarlicMessage _message;
    3434    //private RouterIdentity _from;
    3535    //private Hash _fromHash;
  • router/java/src/net/i2p/router/message/OutboundClientMessageJobHelper.java

    r07b2e3e re721ddd  
    228228        clove.setId(ctx.random().nextLong(I2NPMessage.MAX_ID_VALUE));
    229229        DatabaseStoreMessage msg = new DatabaseStoreMessage(ctx);
    230         msg.setLeaseSet(replyLeaseSet);
     230        msg.setEntry(replyLeaseSet);
    231231        msg.setMessageExpiration(expiration);
    232         msg.setKey(replyLeaseSet.getDestination().calculateHash());
    233232        clove.setPayload(msg);
    234233        clove.setRecipientPublicKey(null);
  • router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java

    r07b2e3e re721ddd  
    4848 */
    4949public class OutboundClientMessageOneShotJob extends JobImpl {
    50     private Log _log;
     50    private final Log _log;
    5151    private long _overallExpiration;
    5252    private ClientMessage _clientMessage;
    53     private MessageId _clientMessageId;
    54     private int _clientMessageSize;
    55     private Destination _from;
    56     private Destination _to;
    57     private String _toString;
     53    private final MessageId _clientMessageId;
     54    private final int _clientMessageSize;
     55    private final Destination _from;
     56    private final Destination _to;
     57    private final String _toString;
    5858    /** target destination's leaseSet, if known */
    5959    private LeaseSet _leaseSet;
     
    6262    private PayloadGarlicConfig _clove;
    6363    private long _cloveId;
    64     private long _start;
     64    private final long _start;
    6565    private boolean _finished;
    6666    private long _leaseSetLookupBegin;
     
    104104    private static final int BUNDLE_PROBABILITY_DEFAULT = 100;
    105105   
    106     private static final Object _initializeLock = new Object();
    107     private static boolean _initialized = false;
    108106    private static final int CLEAN_INTERVAL = 5*60*1000;
    109107    private static final int REPLY_REQUEST_INTERVAL = 60*1000;
     
    116114        _log = ctx.logManager().getLog(OutboundClientMessageOneShotJob.class);
    117115       
    118         synchronized (_initializeLock) {
    119             if (!_initialized) {
    120                 SimpleScheduler.getInstance().addPeriodicEvent(new OCMOSJCacheCleaner(ctx), CLEAN_INTERVAL, CLEAN_INTERVAL);
    121                 ctx.statManager().createFrequencyStat("client.sendMessageFailFrequency", "How often does a client fail to send a message?", "ClientMessages", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
    122                 ctx.statManager().createRateStat("client.sendMessageSize", "How large are messages sent by the client?", "ClientMessages", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
    123                 ctx.statManager().createRateStat("client.sendAckTime", "Message round trip time", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    124                 ctx.statManager().createRateStat("client.timeoutCongestionTunnel", "How lagged our tunnels are when a send times out?", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    125                 ctx.statManager().createRateStat("client.timeoutCongestionMessage", "How fast we process messages locally when a send times out?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    126                 ctx.statManager().createRateStat("client.timeoutCongestionInbound", "How much faster we are receiving data than our average bps when a send times out?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    127                 ctx.statManager().createRateStat("client.leaseSetFoundLocally", "How often we tried to look for a leaseSet and found it locally?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    128                 ctx.statManager().createRateStat("client.leaseSetFoundRemoteTime", "How long we tried to look for a remote leaseSet (when we succeeded)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    129                 ctx.statManager().createRateStat("client.leaseSetFailedRemoteTime", "How long we tried to look for a remote leaseSet (when we failed)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    130                 ctx.statManager().createRateStat("client.dispatchPrepareTime", "How long until we've queued up the dispatch job (since we started)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    131                 ctx.statManager().createRateStat("client.dispatchTime", "How long until we've dispatched the message (since we started)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    132                 ctx.statManager().createRateStat("client.dispatchSendTime", "How long the actual dispatching takes?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    133                 ctx.statManager().createRateStat("client.dispatchNoTunnels", "How long after start do we run out of tunnels to send/receive with?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
    134                 ctx.statManager().createRateStat("client.dispatchNoACK", "Repeated message sends to a peer (no ack required)", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l });
    135                 _initialized = true;
    136             }
    137         }
    138116        long timeoutMs = OVERALL_TIMEOUT_MS_DEFAULT;
    139117        _clientMessage = msg;
     
    150128        _overallExpiration = msg.getExpiration();
    151129        if (_overallExpiration > 0) {
    152            _overallExpiration = Math.max(_overallExpiration, _start + OVERALL_TIMEOUT_MS_MIN);
    153            _overallExpiration = Math.min(_overallExpiration, _start + OVERALL_TIMEOUT_MS_DEFAULT);
    154            if (_log.shouldLog(Log.INFO))
    155                _log.info(getJobId() + ": Message Expiration (ms): " + (_overallExpiration - _start));
     130            // Unless it's already expired, set a min and max expiration
     131            if (_overallExpiration <= _start) {
     132                _overallExpiration = Math.max(_overallExpiration, _start + OVERALL_TIMEOUT_MS_MIN);
     133                _overallExpiration = Math.min(_overallExpiration, _start + OVERALL_TIMEOUT_MS_DEFAULT);
     134                if (_log.shouldLog(Log.INFO))
     135                    _log.info(getJobId() + ": Message Expiration (ms): " + (_overallExpiration - _start));
     136            } else {
     137                if (_log.shouldLog(Log.WARN))
     138                    _log.warn(getJobId() + ": Expired before we got to it");
     139                // runJob() will call dieFatal()
     140            }
    156141        } else {
    157142            String param = msg.getSenderConfig().getOptions().getProperty(OVERALL_TIMEOUT_MS_PARAM);
     
    172157               _log.info(getJobId() + " Default Expiration (ms): " + timeoutMs);
    173158        }
    174         _finished = false;
    175     }
    176    
     159    }
     160   
     161    /** call once only */
     162    public static void init(RouterContext ctx) {
     163        SimpleScheduler.getInstance().addPeriodicEvent(new OCMOSJCacheCleaner(ctx), CLEAN_INTERVAL, CLEAN_INTERVAL);
     164        ctx.statManager().createFrequencyStat("client.sendMessageFailFrequency", "How often does a client fail to send a message?", "ClientMessages", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
     165        ctx.statManager().createRateStat("client.sendMessageSize", "How large are messages sent by the client?", "ClientMessages", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
     166        ctx.statManager().createRateStat("client.sendAckTime", "Message round trip time", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     167        ctx.statManager().createRateStat("client.timeoutCongestionTunnel", "How lagged our tunnels are when a send times out?", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     168        ctx.statManager().createRateStat("client.timeoutCongestionMessage", "How fast we process messages locally when a send times out?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     169        ctx.statManager().createRateStat("client.timeoutCongestionInbound", "How much faster we are receiving data than our average bps when a send times out?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     170        ctx.statManager().createRateStat("client.leaseSetFoundLocally", "How often we tried to look for a leaseSet and found it locally?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     171        ctx.statManager().createRateStat("client.leaseSetFoundRemoteTime", "How long we tried to look for a remote leaseSet (when we succeeded)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     172        ctx.statManager().createRateStat("client.leaseSetFailedRemoteTime", "How long we tried to look for a remote leaseSet (when we failed)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     173        ctx.statManager().createRateStat("client.dispatchPrepareTime", "How long until we've queued up the dispatch job (since we started)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     174        ctx.statManager().createRateStat("client.dispatchTime", "How long until we've dispatched the message (since we started)?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     175        ctx.statManager().createRateStat("client.dispatchSendTime", "How long the actual dispatching takes?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     176        ctx.statManager().createRateStat("client.dispatchNoTunnels", "How long after start do we run out of tunnels to send/receive with?", "ClientMessages", new long[] { 5*60*1000l, 60*60*1000l, 24*60*60*1000l });
     177        ctx.statManager().createRateStat("client.dispatchNoACK", "Repeated message sends to a peer (no ack required)", "ClientMessages", new long[] { 60*1000l, 5*60*1000l, 60*60*1000l });
     178    }
     179
    177180    public String getName() { return "Outbound client message"; }
    178181   
    179182    public void runJob() {
     183        long now = getContext().clock().now();
     184        if (now >= _overallExpiration) {
     185            dieFatal();
     186            return;
     187        }
    180188        if (_log.shouldLog(Log.DEBUG))
    181189            _log.debug(getJobId() + ": Send outbound client message job beginning");
    182         long timeoutMs = _overallExpiration - getContext().clock().now();
     190        long timeoutMs = _overallExpiration - now;
    183191        if (_log.shouldLog(Log.DEBUG))
    184192            _log.debug(getJobId() + ": preparing to search for the leaseSet for " + _toString);
     
    250258
    251259        // If the last leaseSet we sent him is still good, don't bother sending again
    252         long now = getContext().clock().now();
    253260        synchronized (_leaseSetCache) {
    254261            if (!force) {
     
    327334            return false;
    328335        }
    329         long now = getContext().clock().now();
    330336
    331337        // Use the same lease if it's still good
     
    374380        // randomize the ordering (so leases with equal # of failures per next
    375381        // sort are randomly ordered)
    376         Collections.shuffle(leases);
     382        Collections.shuffle(leases, getContext().random());
    377383       
    378384/****
     
    794800    private TunnelInfo selectOutboundTunnel(Destination to) {
    795801        TunnelInfo tunnel;
    796         long now = getContext().clock().now();
    797802        synchronized (_tunnelCache) {
    798803            /**
  • router/java/src/net/i2p/router/message/PayloadGarlicConfig.java

    r07b2e3e re721ddd  
    2020    public PayloadGarlicConfig() {
    2121        super();
    22         _payload = null;
    2322    }
    2423   
  • router/java/src/net/i2p/router/message/SendMessageDirectJob.java

    r07b2e3e re721ddd  
    2323
    2424public class SendMessageDirectJob extends JobImpl {
    25     private Log _log;
    26     private I2NPMessage _message;
    27     private Hash _targetHash;
     25    private final Log _log;
     26    private final I2NPMessage _message;
     27    private final Hash _targetHash;
    2828    private RouterInfo _router;
    29     private long _expiration;
    30     private int _priority;
    31     private Job _onSend;
    32     private ReplyJob _onSuccess;
    33     private Job _onFail;
    34     private MessageSelector _selector;
     29    private final long _expiration;
     30    private final int _priority;
     31    private final Job _onSend;
     32    private final ReplyJob _onSuccess;
     33    private final Job _onFail;
     34    private final MessageSelector _selector;
    3535    private boolean _alreadySearched;
    3636    private boolean _sent;
     
    4848        _message = message;
    4949        _targetHash = toPeer;
    50         _router = null;
    5150        if (timeoutMs < 10*1000) {
    5251            if (_log.shouldLog(Log.WARN))
     
    5756        }
    5857        _priority = priority;
    59         _searchOn = 0;
    60         _alreadySearched = false;
    6158        _onSend = onSend;
    6259        _onSuccess = onSuccess;
     
    6764        if (_targetHash == null)
    6865            throw new IllegalArgumentException("Attempt to send a message to a null peer");
    69         _sent = false;
    7066    }
    7167   
  • router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java

    r07b2e3e re721ddd  
    1313import java.util.Set;
    1414
    15 import net.i2p.data.DataStructure;
     15import net.i2p.data.DatabaseEntry;
    1616import net.i2p.data.Hash;
    1717import net.i2p.data.LeaseSet;
     
    228228    }
    229229   
    230     private void sendData(Hash key, DataStructure data, Hash toPeer, TunnelId replyTunnel) {
     230    private void sendData(Hash key, DatabaseEntry data, Hash toPeer, TunnelId replyTunnel) {
     231        if (!key.equals(data.getHash())) {
     232            _log.error("Hash mismatch HDLMJ");
     233            return;
     234        }
    231235        if (_log.shouldLog(Log.DEBUG))
    232236            _log.debug("Sending data matching key " + key.toBase64() + " to peer " + toPeer.toBase64()
    233237                       + " tunnel " + replyTunnel);
    234238        DatabaseStoreMessage msg = new DatabaseStoreMessage(getContext());
    235         msg.setKey(key);
    236         if (data instanceof LeaseSet) {
    237             msg.setLeaseSet((LeaseSet)data);
    238             msg.setValueType(DatabaseStoreMessage.KEY_TYPE_LEASESET);
     239        if (data.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
    239240            getContext().statManager().addRateData("netDb.lookupsMatchedLeaseSet", 1, 0);
    240         } else if (data instanceof RouterInfo) {
    241             msg.setRouterInfo((RouterInfo)data);
    242             msg.setValueType(DatabaseStoreMessage.KEY_TYPE_ROUTERINFO);
    243         }
     241        }
     242        msg.setEntry(data);
    244243        getContext().statManager().addRateData("netDb.lookupsMatched", 1, 0);
    245244        getContext().statManager().addRateData("netDb.lookupsHandled", 1, 0);
  • router/java/src/net/i2p/router/networkdb/HandleDatabaseStoreMessageJob.java

    r07b2e3e re721ddd  
    1111import java.util.Date;
    1212
     13import net.i2p.data.DatabaseEntry;
    1314import net.i2p.data.Hash;
    1415import net.i2p.data.LeaseSet;
    1516import net.i2p.data.RouterIdentity;
     17import net.i2p.data.RouterInfo;
    1618import net.i2p.data.i2np.DatabaseStoreMessage;
    1719import net.i2p.data.i2np.DeliveryStatusMessage;
     
    6062        String invalidMessage = null;
    6163        boolean wasNew = false;
    62         if (_message.getValueType() == DatabaseStoreMessage.KEY_TYPE_LEASESET) {
     64        DatabaseEntry entry = _message.getEntry();
     65        if (entry.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
    6366            getContext().statManager().addRateData("netDb.storeLeaseSetHandled", 1, 0);
    6467   
    6568            try {
    66                 LeaseSet ls = _message.getLeaseSet();
     69                LeaseSet ls = (LeaseSet) entry;
    6770                // mark it as something we received, so we'll answer queries
    6871                // for it.  this flag does NOT get set on entries that we
    6972                // receive in response to our own lookups.
    7073                ls.setReceivedAsPublished(true);
    71                 LeaseSet match = getContext().netDb().store(_message.getKey(), _message.getLeaseSet());
     74                LeaseSet match = getContext().netDb().store(_message.getKey(), ls);
    7275                if (match == null) {
    7376                    wasNew = true;
     
    7982                invalidMessage = iae.getMessage();
    8083            }
    81         } else if (_message.getValueType() == DatabaseStoreMessage.KEY_TYPE_ROUTERINFO) {
     84        } else if (entry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
     85            RouterInfo ri = (RouterInfo) entry;
    8286            getContext().statManager().addRateData("netDb.storeRouterInfoHandled", 1, 0);
    8387            if (_log.shouldLog(Log.INFO))
    8488                _log.info("Handling dbStore of router " + _message.getKey() + " with publishDate of "
    85                           + new Date(_message.getRouterInfo().getPublished()));
     89                          + new Date(ri.getPublished()));
    8690            try {
    87                 Object match = getContext().netDb().store(_message.getKey(), _message.getRouterInfo());
     91                Object match = getContext().netDb().store(_message.getKey(), ri);
    8892                wasNew = (null == match);
    8993                getContext().profileManager().heardAbout(_message.getKey());
     
    9397        } else {
    9498            if (_log.shouldLog(Log.ERROR))
    95                 _log.error("Invalid DatabaseStoreMessage data type - " + _message.getValueType()
     99                _log.error("Invalid DatabaseStoreMessage data type - " + entry.getType()
    96100                           + ": " + _message);
    97101        }
  • router/java/src/net/i2p/router/networkdb/kademlia/DataStore.java

    r07b2e3e re721ddd  
    99 */
    1010
     11import java.util.Collection;
     12import java.util.Map;
    1113import java.util.Set;
    1214
    13 import net.i2p.data.DataStructure;
     15import net.i2p.data.DatabaseEntry;
    1416import net.i2p.data.Hash;
    1517
     
    1719    public boolean isInitialized();
    1820    public boolean isKnown(Hash key);
    19     public DataStructure get(Hash key);
    20     public DataStructure get(Hash key, boolean persist);
    21     public boolean put(Hash key, DataStructure data);
    22     public boolean put(Hash key, DataStructure data, boolean persist);
    23     public DataStructure remove(Hash key);
    24     public DataStructure remove(Hash key, boolean persist);
     21    public DatabaseEntry get(Hash key);
     22    public DatabaseEntry get(Hash key, boolean persist);
     23    public boolean put(Hash key, DatabaseEntry data);
     24    public boolean put(Hash key, DatabaseEntry data, boolean persist);
     25    public DatabaseEntry remove(Hash key);
     26    public DatabaseEntry remove(Hash key, boolean persist);
    2527    public Set<Hash> getKeys();
     28    /** @since 0.8.3 */
     29    public Collection<DatabaseEntry> getEntries();
     30    /** @since 0.8.3 */
     31    public Set<Map.Entry<Hash, DatabaseEntry>> getMapEntries();
    2632    public void stop();
    2733    public void restart();
  • router/java/src/net/i2p/router/networkdb/kademlia/ExpireLeasesJob.java

    r07b2e3e re721ddd  
    1313import java.util.Set;
    1414
     15import net.i2p.data.DatabaseEntry;
    1516import net.i2p.data.Hash;
    1617import net.i2p.data.LeaseSet;
     
    6263        for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
    6364            Hash key = (Hash)iter.next();
    64             Object obj = _facade.getDataStore().get(key);
    65             if (obj instanceof LeaseSet) {
     65            DatabaseEntry obj = _facade.getDataStore().get(key);
     66            if (obj.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
    6667                LeaseSet ls = (LeaseSet)obj;
    6768                if (!ls.isCurrent(Router.CLOCK_FUDGE_FACTOR))
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodOnlyLookupMatchJob.java

    r07b2e3e re721ddd  
    11package net.i2p.router.networkdb.kademlia;
    22
     3import net.i2p.data.DatabaseEntry;
     4import net.i2p.data.LeaseSet;
     5import net.i2p.data.RouterInfo;
    36import net.i2p.data.i2np.DatabaseSearchReplyMessage;
    47import net.i2p.data.i2np.DatabaseStoreMessage;
     
    6265            // runJob() and search.success() is called???
    6366            // Should we just pass the DataStructure directly back to somebody?
    64             if (dsm.getValueType() == DatabaseStoreMessage.KEY_TYPE_LEASESET) {
     67            if (dsm.getEntry().getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
    6568                // Since HFDSMJ wants to setReceivedAsPublished(), we have to
    6669                // set a flag saying this was really the result of a query,
    6770                // so don't do that.
    68                 dsm.getLeaseSet().setReceivedAsReply();
    69                 getContext().netDb().store(dsm.getKey(), dsm.getLeaseSet());
     71                LeaseSet ls = (LeaseSet) dsm.getEntry();
     72                ls.setReceivedAsReply();
     73                getContext().netDb().store(dsm.getKey(), ls);
    7074            } else {
    71                 getContext().netDb().store(dsm.getKey(), dsm.getRouterInfo());
     75                getContext().netDb().store(dsm.getKey(), (RouterInfo) dsm.getEntry());
    7276            }
    7377        } catch (IllegalArgumentException iae) {
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodSearchJob.java

    r07b2e3e re721ddd  
    183183        }
    184184        public void runJob() {
    185             if ( (getContext().netDb().lookupLeaseSetLocally(_search.getKey()) != null) ||
    186                  (getContext().netDb().lookupRouterInfoLocally(_search.getKey()) != null) ) {
     185            if (getContext().netDb().lookupLocally(_search.getKey()) != null) {
    187186                _search.success();
    188187            } else {
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java

    r07b2e3e re721ddd  
    88import java.util.Set;
    99
     10import net.i2p.data.DatabaseEntry;
    1011import net.i2p.data.DataFormatException;
    11 import net.i2p.data.DataStructure;
    1212import net.i2p.data.Hash;
    1313import net.i2p.data.LeaseSet;
     
    9494   
    9595    @Override
    96     public void sendStore(Hash key, DataStructure ds, Job onSuccess, Job onFailure, long sendTimeout, Set toIgnore) {
     96    public void sendStore(Hash key, DatabaseEntry ds, Job onSuccess, Job onFailure, long sendTimeout, Set toIgnore) {
    9797        // if we are a part of the floodfill netDb, don't send out our own leaseSets as part
    9898        // of the flooding - instead, send them to a random floodfill peer so *they* can flood 'em out.
    9999        // perhaps statistically adjust this so we are the source every 1/N times... or something.
    100         if (floodfillEnabled() && (ds instanceof RouterInfo)) {
     100        if (floodfillEnabled() && (ds.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO)) {
    101101            flood(ds);
    102102            if (onSuccess != null)
     
    130130     *  we flood to those closest to the key.
    131131     */
    132     public void flood(DataStructure ds) {
    133         Hash key;
    134         if (ds instanceof LeaseSet)
    135             key = ((LeaseSet)ds).getDestination().calculateHash();
    136         else
    137             key = ((RouterInfo)ds).getIdentity().calculateHash();
     132    public void flood(DatabaseEntry ds) {
     133        Hash key = ds.getHash();
    138134        Hash rkey = _context.routingKeyGenerator().getRoutingKey(key);
    139135        FloodfillPeerSelector sel = (FloodfillPeerSelector)getPeerSelector();
     
    152148                continue;
    153149            DatabaseStoreMessage msg = new DatabaseStoreMessage(_context);
    154             if (ds instanceof LeaseSet) {
    155                 msg.setLeaseSet((LeaseSet)ds);
    156             } else {
    157                 msg.setRouterInfo((RouterInfo)ds);
    158             }
    159             msg.setKey(key);
     150            msg.setEntry(ds);
    160151            msg.setReplyGateway(null);
    161152            msg.setReplyToken(0);
     
    243234        DataStore ds = getDataStore();
    244235        if (ds != null) {
    245             Set keys = ds.getKeys();
    246             if (keys != null) {
    247                 for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
    248                     Object o = ds.get((Hash)iter.next());
    249                     if (o instanceof RouterInfo)
    250                         rv.add((RouterInfo)o);
    251                 }
     236            for (DatabaseEntry o : ds.getEntries()) {
     237                if (o.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO)
     238                    rv.add((RouterInfo)o);
    252239            }
    253240        }
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodfillPeerSelector.java

    r07b2e3e re721ddd  
    1212import java.util.Collections;
    1313import java.util.HashSet;
     14import java.util.Iterator;
    1415import java.util.List;
    1516import java.util.Set;
     
    2021import net.i2p.router.RouterContext;
    2122import net.i2p.router.peermanager.PeerProfile;
     23import net.i2p.router.util.RandomIterator;
    2224import net.i2p.stat.Rate;
    2325import net.i2p.util.Log;
     
    7375    List<Hash> selectNearestExplicitThin(Hash key, int maxNumRouters, Set<Hash> peersToIgnore, KBucketSet kbuckets, boolean preferConnected) {
    7476        if (peersToIgnore == null)
    75             peersToIgnore = new HashSet(1);
    76         peersToIgnore.add(_context.routerHash());
     77            peersToIgnore = Collections.singleton(_context.routerHash());
     78        else
     79            peersToIgnore.add(_context.routerHash());
     80        // TODO this is very slow
    7781        FloodfillSelectionCollector matches = new FloodfillSelectionCollector(key, peersToIgnore, maxNumRouters);
    7882        if (kbuckets == null) return new ArrayList();
     
    9296     */
    9397    List<Hash> selectFloodfillParticipants(KBucketSet kbuckets) {
    94         Set<Hash> ignore = new HashSet(1);
    95         ignore.add(_context.routerHash());
     98        Set<Hash> ignore = Collections.singleton(_context.routerHash());
    9699        return selectFloodfillParticipants(ignore, kbuckets);
    97100    }
     
    105108    private List<Hash> selectFloodfillParticipants(Set<Hash> toIgnore, KBucketSet kbuckets) {
    106109        if (kbuckets == null) return Collections.EMPTY_LIST;
     110        // TODO this is very slow - use profile getPeersByCapability('f') instead
     111        _context.statManager().addRateData("netDb.newFSC", 0, 0);
    107112        FloodfillSelectionCollector matches = new FloodfillSelectionCollector(null, toIgnore, 0);
    108113        kbuckets.getAll(matches);
     
    128133     */
    129134    List<Hash> selectFloodfillParticipants(Hash key, int maxNumRouters, KBucketSet kbuckets) {
    130         Set<Hash> ignore = new HashSet(1);
    131         ignore.add(_context.routerHash());
     135        Set<Hash> ignore = Collections.singleton(_context.routerHash());
    132136        return selectFloodfillParticipants(key, maxNumRouters, ignore, kbuckets);
    133137    }
     
    148152    List<Hash> selectFloodfillParticipants(Hash key, int howMany, Set<Hash> toIgnore, KBucketSet kbuckets) {
    149153        if (toIgnore == null) {
    150             toIgnore = new HashSet(1);
    151             toIgnore.add(_context.routerHash());
     154            toIgnore = Collections.singleton(_context.routerHash());
    152155        } else if (!toIgnore.contains(_context.routerHash())) {
    153156            // copy the Set so we don't confuse StoreJob
     
    321324         */
    322325        public List<Hash> get(int howMany, boolean preferConnected) {
    323             Collections.shuffle(_floodfillMatches, _context.random());
    324326            List<Hash> rv = new ArrayList(howMany);
    325327            List<Hash> badff = new ArrayList(howMany);
     
    330332            // Let's say published in last 3h and no failed sends in last 30m
    331333            // (Forever shitlisted ones are excluded in add() above)
    332             for (int i = 0; found < howMany && i < _floodfillMatches.size(); i++) {
    333                 Hash entry = (Hash) _floodfillMatches.get(i);
     334            for (Iterator<Hash> iter = new RandomIterator(_floodfillMatches); (found < howMany) && iter.hasNext(); ) {
     335                Hash entry = iter.next();
    334336                RouterInfo info = _context.netDb().lookupRouterInfoLocally(entry);
    335337                if (info != null && now - info.getPublished() > 3*60*60*1000) {
     
    392394            // return non-ff
    393395            peersToIgnore.addAll(selectFloodfillParticipants(peersToIgnore, kbuckets));
     396            // TODO this is very slow
    394397            FloodfillSelectionCollector matches = new FloodfillSelectionCollector(rkey, peersToIgnore, maxNumRouters);
    395398            kbuckets.getAll(matches);
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodfillStoreJob.java

    r07b2e3e re721ddd  
    1313import java.util.Set;
    1414
    15 import net.i2p.data.DataStructure;
     15import net.i2p.data.DatabaseEntry;
    1616import net.i2p.data.Hash;
    1717import net.i2p.data.LeaseSet;
     
    3131     *
    3232     */
    33     public FloodfillStoreJob(RouterContext context, FloodfillNetworkDatabaseFacade facade, Hash key, DataStructure data, Job onSuccess, Job onFailure, long timeoutMs) {
     33    public FloodfillStoreJob(RouterContext context, FloodfillNetworkDatabaseFacade facade, Hash key, DatabaseEntry data, Job onSuccess, Job onFailure, long timeoutMs) {
    3434        this(context, facade, key, data, onSuccess, onFailure, timeoutMs, null);
    3535    }
     
    3939     *               already know they have it).  This can be null.
    4040     */
    41     public FloodfillStoreJob(RouterContext context, FloodfillNetworkDatabaseFacade facade, Hash key, DataStructure data, Job onSuccess, Job onFailure, long timeoutMs, Set<Hash> toSkip) {
     41    public FloodfillStoreJob(RouterContext context, FloodfillNetworkDatabaseFacade facade, Hash key, DatabaseEntry data, Job onSuccess, Job onFailure, long timeoutMs, Set<Hash> toSkip) {
    4242        super(context, facade, key, data, onSuccess, onFailure, timeoutMs, toSkip);
    4343        _facade = facade;
     
    6464            // Get the time stamp from the data we sent, so the Verify job can meke sure that
    6565            // it finds something stamped with that time or newer.
    66             long published = 0;
    67             DataStructure data = _state.getData();
    68             boolean isRouterInfo = data instanceof RouterInfo;
     66            DatabaseEntry data = _state.getData();
     67            boolean isRouterInfo = data.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO;
     68            long published = data.getDate();
    6969            if (isRouterInfo) {
    70                 published = ((RouterInfo) data).getPublished();
    7170                // Temporarily disable
    7271                return;
    73             } else if (data instanceof LeaseSet) {
    74                 published = ((LeaseSet) data).getEarliestLeaseDate();
    7572            }
    7673            // we should always have exactly one successful entry
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java

    r07b2e3e re721ddd  
    55import java.util.Set;
    66
    7 import net.i2p.data.DataStructure;
     7import net.i2p.data.DatabaseEntry;
    88import net.i2p.data.Hash;
    99import net.i2p.data.RouterInfo;
     
    202202                boolean success = false;
    203203                DatabaseStoreMessage dsm = (DatabaseStoreMessage)_message;
    204                 if (_isRouterInfo && dsm.getValueType() == DatabaseStoreMessage.KEY_TYPE_ROUTERINFO)
    205                     success = dsm.getRouterInfo().getPublished() >= _published;
    206                 else if ((!_isRouterInfo) && dsm.getValueType() == DatabaseStoreMessage.KEY_TYPE_LEASESET)
    207                     success = dsm.getLeaseSet().getEarliestLeaseDate() >= _published;
     204                success = dsm.getEntry().getDate() >= _published;
    208205                if (success) {
    209206                    // store ok, w00t!
     
    219216                    _log.warn("Verify failed (older) for " + _key);
    220217                if (_log.shouldLog(Log.INFO))
    221                     _log.info("Rcvd older lease: " + dsm.getLeaseSet());
     218                    _log.info("Rcvd older lease: " + dsm.getEntry());
    222219            } else if (_message instanceof DatabaseSearchReplyMessage) {
    223220                // assume 0 old, all new, 0 invalid, 0 dup
     
    246243     */
    247244    private void resend() {
    248         DataStructure ds;
    249         if (_isRouterInfo)
    250             ds = _facade.lookupRouterInfoLocally(_key);
    251         else
    252             ds = _facade.lookupLeaseSetLocally(_key);
     245        DatabaseEntry ds = _facade.lookupLocally(_key);
    253246        if (ds != null) {
    254247            Set<Hash> toSkip = new HashSet(2);
  • router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseLookupMessageJob.java

    r07b2e3e re721ddd  
    5858            DatabaseStoreMessage msg = new DatabaseStoreMessage(getContext());
    5959            RouterInfo me = getContext().router().getRouterInfo();
    60             msg.setKey(me.getIdentity().getHash());
    61             msg.setRouterInfo(me);
    62             msg.setValueType(DatabaseStoreMessage.KEY_TYPE_ROUTERINFO);
     60            msg.setEntry(me);
    6361            sendMessage(msg, toPeer, replyTunnel);
    6462        }
  • router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java

    r07b2e3e re721ddd  
    1212import java.util.Set;
    1313
     14import net.i2p.data.DatabaseEntry;
    1415import net.i2p.data.Hash;
    1516import net.i2p.data.LeaseSet;
     
    5657        RouterInfo prevNetDb = null;
    5758        Hash key = _message.getKey();
    58         if (_message.getValueType() == DatabaseStoreMessage.KEY_TYPE_LEASESET) {
     59        DatabaseEntry entry = _message.getEntry();
     60        if (entry.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
    5961            getContext().statManager().addRateData("netDb.storeLeaseSetHandled", 1, 0);
    6062            if (_log.shouldLog(Log.INFO))
     
    7678                                                       key.toBase64().substring(0, 4));
    7779                }
    78                 LeaseSet ls = _message.getLeaseSet();
     80                LeaseSet ls = (LeaseSet) entry;
    7981                //boolean oldrar = ls.getReceivedAsReply();
    8082                //boolean oldrap = ls.getReceivedAsPublished();
     
    9294                //if (_log.shouldLog(Log.INFO))
    9395                //    _log.info("oldrap? " + oldrap + " oldrar? " + oldrar + " newrap? " + rap);
    94                 LeaseSet match = getContext().netDb().store(key, _message.getLeaseSet());
     96                LeaseSet match = getContext().netDb().store(key, ls);
    9597                if (match == null) {
    9698                    wasNew = true;
    97                 } else if (match.getEarliestLeaseDate() < _message.getLeaseSet().getEarliestLeaseDate()) {
     99                } else if (match.getEarliestLeaseDate() < ls.getEarliestLeaseDate()) {
    98100                    wasNew = true;
    99101                    // If it is in our keyspace and we are talking to it
     
    118120                invalidMessage = iae.getMessage();
    119121            }
    120         } else if (_message.getValueType() == DatabaseStoreMessage.KEY_TYPE_ROUTERINFO) {
     122        } else if (entry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
     123            RouterInfo ri = (RouterInfo) entry;
    121124            getContext().statManager().addRateData("netDb.storeRouterInfoHandled", 1, 0);
    122125            if (_log.shouldLog(Log.INFO))
    123126                _log.info("Handling dbStore of router " + key + " with publishDate of "
    124                           + new Date(_message.getRouterInfo().getPublished()));
     127                          + new Date(ri.getPublished()));
    125128            try {
    126129                // Never store our RouterInfo received from somebody else.
     
    133136                    throw new IllegalArgumentException("Peer attempted to store our RouterInfo");
    134137                }
    135                 prevNetDb = getContext().netDb().store(key, _message.getRouterInfo());
    136                 wasNew = ((null == prevNetDb) || (prevNetDb.getPublished() < _message.getRouterInfo().getPublished()));
     138                prevNetDb = getContext().netDb().store(key, ri);
     139                wasNew = ((null == prevNetDb) || (prevNetDb.getPublished() < ri.getPublished()));
    137140                // Check new routerinfo address against blocklist
    138141                if (wasNew) {
     
    144147                    } else {
    145148                        Set oldAddr = prevNetDb.getAddresses();
    146                         Set newAddr = _message.getRouterInfo().getAddresses();
     149                        Set newAddr = ri.getAddresses();
    147150                        if (newAddr != null && (!newAddr.equals(oldAddr)) &&
    148151                            (!getContext().shitlist().isShitlistedForever(key)) &&
     
    158161        } else {
    159162            if (_log.shouldLog(Log.ERROR))
    160                 _log.error("Invalid DatabaseStoreMessage data type - " + _message.getValueType()
     163                _log.error("Invalid DatabaseStoreMessage data type - " + entry.getType()
    161164                           + ": " + _message);
    162165        }
     
    199202                }
    200203                long floodBegin = System.currentTimeMillis();
    201                 if (_message.getValueType() == DatabaseStoreMessage.KEY_TYPE_LEASESET)
    202                     _facade.flood(_message.getLeaseSet());
     204                _facade.flood(_message.getEntry());
    203205                // ERR: see comment in HandleDatabaseLookupMessageJob regarding hidden mode
    204206                //else if (!_message.getRouterInfo().isHidden())
    205                 else
    206                     _facade.flood(_message.getRouterInfo());
    207207                long floodEnd = System.currentTimeMillis();
    208208                getContext().statManager().addRateData("netDb.storeFloodNew", floodEnd-floodBegin, 0);
  • router/java/src/net/i2p/router/networkdb/kademlia/HarvesterJob.java

    r07b2e3e re721ddd  
    8686                if (when + MIN_UPDATE_FREQUENCY > now)
    8787                    continue;
    88                 while (routersByAge.containsKey(new Long(when)))
     88                while (routersByAge.containsKey(Long.valueOf(when)))
    8989                    when++;
    90                routersByAge.put(new Long(when), info.getIdentity().getHash());
     90               routersByAge.put(Long.valueOf(when), info.getIdentity().getHash());
    9191            }
    9292        }
  • router/java/src/net/i2p/router/networkdb/kademlia/KBucketImpl.java

    r07b2e3e re721ddd  
    388388        KBucketImpl bucket = new KBucketImpl(I2PAppContext.getGlobalContext(), local);
    389389        bucket.setRange(low, high);
    390         Hash lowerBoundKey = bucket.getRangeBeginKey();
    391         Hash upperBoundKey = bucket.getRangeEndKey();
     390        //Hash lowerBoundKey = bucket.getRangeBeginKey();
     391        //Hash upperBoundKey = bucket.getRangeEndKey();
    392392        for (int i = 0; i < 100000; i++) {
    393393            Hash rnd = bucket.generateRandomKey();
     
    396396            if (!ok) {
    397397                byte diff[] = bucket.getLocal().cachedXor(rnd);
    398                 BigInteger dv = new BigInteger(1, diff);
     398                //BigInteger dv = new BigInteger(1, diff);
    399399                //log.error("WTF! bucket doesn't want: \n" + toString(rnd.getData())
    400400                //          + "\nDelta: \n" + toString(diff) + "\nDelta val: \n" + dv.toString(2)
     
    404404                           + "\nVal: " + DataHelper.toHexString(rnd.getData())
    405405                           + "\nHigh:" + DataHelper.toHexString(bucket.getRangeEndKey().getData()));
    406                 try { Thread.sleep(1000); } catch (Exception e) {}
     406                try { Thread.sleep(1000); } catch (InterruptedException e) {}
    407407                System.exit(0);
    408408            } else {
     
    416416    private static void testRand2() {
    417417        Log log = I2PAppContext.getGlobalContext().logManager().getLog(KBucketImpl.class);
    418         StringBuilder buf = new StringBuilder(1024*1024*16);
    419418        int low = 1;
    420419        int high = 200;
     
    425424        KBucketImpl bucket = new KBucketImpl(I2PAppContext.getGlobalContext(), local);
    426425        bucket.setRange(low, high);
    427         Hash lowerBoundKey = bucket.getRangeBeginKey();
    428         Hash upperBoundKey = bucket.getRangeEndKey();
     426        //Hash lowerBoundKey = bucket.getRangeBeginKey();
     427        //Hash upperBoundKey = bucket.getRangeEndKey();
    429428        for (int i = 0; i < 100000; i++) {
    430429            Hash rnd = bucket.generateRandomKey();
     
    433432            if (!ok) {
    434433                byte diff[] = bucket.getLocal().cachedXor(rnd);
    435                 BigInteger dv = new BigInteger(1, diff);
     434                //BigInteger dv = new BigInteger(1, diff);
    436435                //log.error("WTF! bucket doesn't want: \n" + toString(rnd.getData())
    437436                //          + "\nDelta: \n" + toString(diff) + "\nDelta val: \n" + dv.toString(2)
     
    441440                           + "\nVal: " + DataHelper.toHexString(rnd.getData())
    442441                           + "\nHigh:" + DataHelper.toHexString(bucket.getRangeEndKey().getData()));
    443                 try { Thread.sleep(1000); } catch (Exception e) {}
     442                try { Thread.sleep(1000); } catch (InterruptedException e) {}
    444443                System.exit(0);
    445444            } else {
     
    447446            }
    448447        }
    449         log.info("Passed 100,000 random key generations against a random hash\n" + buf.toString());
     448        log.info("Passed 100,000 random key generations against a random hash");
    450449    }
    451450   
  • router/java/src/net/i2p/router/networkdb/kademlia/KBucketSet.java

    r07b2e3e re721ddd  
    4343        _log = context.logManager().getLog(KBucketSet.class);
    4444        createBuckets();
     45        context.statManager().createRateStat("netDb.KBSGetAllTime", "Time to add all Hashes to the Collector", "NetworkDatabase", new long[] { 60*60*1000 });
    4546    }
    4647   
     
    100101   
    101102    public void getAll(SelectionCollector collector) {
     103        long start = _context.clock().now();
    102104        for (int i = 0; i < _buckets.length; i++)
    103105            _buckets[i].getEntries(collector);
     106        _context.statManager().addRateData("netDb.KBSGetAllTime", _context.clock().now() - start, 0);
    104107    }
    105108   
  • router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java

    r07b2e3e re721ddd  
    2525import java.util.TreeSet;
    2626
     27import net.i2p.data.DatabaseEntry;
    2728import net.i2p.data.DataHelper;
    28 import net.i2p.data.DataStructure;
    2929import net.i2p.data.Destination;
    3030import net.i2p.data.Hash;
     
    8989        if (_log.shouldLog(Log.DEBUG))
    9090            _log.debug("search Complete: " + key);
    91         SearchJob removed = null;
    9291        synchronized (_activeRequests) {
    93             removed = (SearchJob)_activeRequests.remove(key);
     92            _activeRequests.remove(key);
    9493        }
    9594    }
     
    236235        _log.info("Starting up the kademlia network database");
    237236        RouterInfo ri = _context.router().getRouterInfo();
    238         String dbDir = _context.router().getConfigSetting(PROP_DB_DIR);
    239         if (dbDir == null) {
    240             _log.info("No DB dir specified [" + PROP_DB_DIR + "], using [" + DEFAULT_DB_DIR + "]");
    241             dbDir = DEFAULT_DB_DIR;
    242         }
     237        String dbDir = _context.getProperty(PROP_DB_DIR, DEFAULT_DB_DIR);
    243238        String enforce = _context.getProperty(PROP_ENFORCE_NETID);
    244239        if (enforce != null)
     
    355350    public Set<Hash> getAllRouters() {
    356351        if (!_initialized) return Collections.EMPTY_SET;
    357         Set<Hash> keys = _ds.getKeys();
    358         Set<Hash> rv = new HashSet(keys.size());
    359         if (_log.shouldLog(Log.DEBUG))
    360             _log.debug("getAllRouters(): # keys in the datastore: " + keys.size());
    361         for (Hash key : keys) {
    362             DataStructure ds = _ds.get(key);
    363             if (ds == null) {
    364                 if (_log.shouldLog(Log.INFO))
    365                     _log.info("Selected hash " + key.toBase64() + " is not stored locally");
    366             } else if ( !(ds instanceof RouterInfo) ) {
    367                 // leaseSet
    368             } else {
    369                 if (_log.shouldLog(Log.DEBUG))
    370                     _log.debug("getAllRouters(): key is router: " + key.toBase64());
    371                 rv.add(key);
     352        Set<Map.Entry<Hash, DatabaseEntry>> entries = _ds.getMapEntries();
     353        Set<Hash> rv = new HashSet(entries.size());
     354        for (Map.Entry<Hash, DatabaseEntry> entry : entries) {
     355            if (entry.getValue().getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
     356                rv.add(entry.getKey());
    372357            }
    373358        }
     
    388373        public void add(Hash entry) {
    389374            if (_ds == null) return;
    390             Object o = _ds.get(entry);
    391             if (o instanceof RouterInfo)
     375            DatabaseEntry o = _ds.get(entry);
     376            if (o != null && o.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO)
    392377                _count++;
    393378        }
     
    405390        if (_ds == null) return 0;
    406391        //return _ds.countLeaseSets();
    407         Set<Hash> keys = _ds.getKeys();