Changeset 07e85e0 for router


Ignore:
Timestamp:
Jan 19, 2016 1:13:09 AM (6 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
9d5e8dd
Parents:
9bb1a00 (diff), f0dc769 (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' (head 45c85fec6458cd0d1a6a6fa2d34b10ee2b9f215c)

to branch 'i2p.i2p.zzz.test2' (head 3ee9968e19867bebb063a98da1184ff4426626cd)

Location:
router/java
Files:
1 added
72 edited
2 moved

Legend:

Unmodified
Added
Removed
  • router/java/src/net/i2p/data/i2np/BuildRequestRecord.java

    r9bb1a00 r07e85e0  
    11package net.i2p.data.i2np;
    22
     3import java.util.Date;
     4
    35import net.i2p.I2PAppContext;
     6import net.i2p.data.Base64;
    47import net.i2p.data.ByteArray;
    58import net.i2p.data.DataFormatException;
     
    6972    private static final int OFF_LAYER_KEY = OFF_SEND_IDENT + Hash.HASH_LENGTH;
    7073    private static final int OFF_IV_KEY = OFF_LAYER_KEY + SessionKey.KEYSIZE_BYTES;
    71     private static final int OFF_REPLY_KEY = OFF_IV_KEY + SessionKey.KEYSIZE_BYTES;
     74    public static final int OFF_REPLY_KEY = OFF_IV_KEY + SessionKey.KEYSIZE_BYTES;
    7275    private static final int OFF_REPLY_IV = OFF_REPLY_KEY + SessionKey.KEYSIZE_BYTES;
    7376    private static final int OFF_FLAG = OFF_REPLY_IV + IV_SIZE;
     
    157160
    158161    /**
    159      * Time that the request was sent (ms), truncated to the nearest hour
     162     * Time that the request was sent (ms), truncated to the nearest hour.
     163     * This ignores leap seconds.
    160164     */
    161165    public long readRequestTime() {
     
    264268        // prevent hop identification at top of the hour
    265269        truncatedHour -= ctx.random().nextInt(90*1000);
     270        // this ignores leap seconds
    266271        truncatedHour /= (60l*60l*1000l);
    267272        DataHelper.toLong(buf, OFF_REQ_TIME, 4, truncatedHour);
     
    273278            throw new RuntimeException("foo");
    274279    }
     280
     281    /**
     282     *  @since 0.9.24
     283     */
     284    @Override
     285    public String toString() {
     286        StringBuilder buf = new StringBuilder(256);
     287        buf.append("BRR ");
     288        boolean isIBGW = readIsInboundGateway();
     289        boolean isOBEP = readIsOutboundEndpoint();
     290        if (isIBGW) {
     291            buf.append("IBGW in: ").append(readReceiveTunnelId())
     292               .append(" out ").append(readNextTunnelId());
     293        } else if (isOBEP) {
     294            buf.append("OBEP in: ").append(readReceiveTunnelId());
     295        } else {
     296            buf.append("part. in: ").append(readReceiveTunnelId())
     297               .append(" out: ").append(readNextTunnelId());
     298        }
     299        buf.append(" to: ").append(readNextIdentity())
     300           .append(" layer key: ").append(readLayerKey())
     301           .append(" IV key: ").append(readIVKey())
     302           .append(" reply key: ").append(readReplyKey())
     303           .append(" reply IV: ").append(Base64.encode(readReplyIV()))
     304           .append(" hour: ").append(new Date(readRequestTime()))
     305           .append(" reply msg id: ").append(readReplyMessageId());
     306        // to chase i2pd bug
     307        //buf.append('\n').append(net.i2p.util.HexDump.dump(readReplyKey().getData()));
     308        return buf.toString();
     309    }
    275310}   
  • router/java/src/net/i2p/data/i2np/DeliveryInstructions.java

    r9bb1a00 r07e85e0  
    431431        //               + " =?= " + flagMode(flags));
    432432        byte additionalInfo[] = getAdditionalInfo();
    433         DataHelper.writeLong(out, 1, flags);
     433        out.write((byte) flags);
    434434        if (additionalInfo != null) {
    435435            out.write(additionalInfo);
  • router/java/src/net/i2p/data/router/RouterAddress.java

    r9bb1a00 r07e85e0  
    289289        if (_transportStyle == null)
    290290            throw new DataFormatException("uninitialized");
    291         DataHelper.writeLong(out, 1, _cost);
     291        out.write((byte) _cost);
    292292        DataHelper.writeLong(out, 8, _expiration);
    293293        DataHelper.writeString(out, _transportStyle);
  • router/java/src/net/i2p/data/router/RouterInfo.java

    r9bb1a00 r07e85e0  
    7979    /** should we cache the byte and string versions _byteified ? **/
    8080    private boolean _shouldCache;
    81     /** maybe we should check if we are floodfill? */
    82     private static final boolean CACHE_ALL = SystemVersion.getMaxMemory() > 128*1024*1024l;
     81    /**
     82     * Maybe we should check if we are floodfill?
     83     * If we do bring this back, don't do on ARM or Android
     84     */
     85    private static final boolean CACHE_ALL = false; // SystemVersion.getMaxMemory() > 128*1024*1024l;
    8386
    8487    public static final String PROP_NETWORK_ID = "netId";
     
    309312    protected byte[] getBytes() throws DataFormatException {
    310313        if (_byteified != null) return _byteified;
    311         if (_identity == null) throw new DataFormatException("Router identity isn't set?!");
    312 
    313         //long before = Clock.getInstance().now();
    314314        ByteArrayOutputStream out = new ByteArrayOutputStream(2*1024);
    315315        try {
     316            writeDataBytes(out);
     317        } catch (IOException ioe) {
     318            throw new DataFormatException("IO Error getting bytes", ioe);
     319        }
     320        byte data[] = out.toByteArray();
     321        if (CACHE_ALL || _shouldCache)
     322            _byteified = data;
     323        return data;
     324    }
     325
     326    /**
     327     * Write out the raw payload of the routerInfo, excluding the signature.  This
     328     * caches the data in memory if possible.
     329     *
     330     * @throws DataFormatException if the data is somehow b0rked (missing props, etc)
     331     * @throws IOException
     332     * @since 0.9.24
     333     */
     334    private void writeDataBytes(OutputStream out) throws DataFormatException, IOException {
     335        if (_identity == null) throw new DataFormatException("Missing identity");
     336        if (_published < 0) throw new DataFormatException("Invalid published date: " + _published);
     337
    316338            _identity.writeBytes(out);
    317339            // avoid thrashing objects
     
    321343            if (sz <= 0 || isHidden()) {
    322344                // Do not send IP address to peers in hidden mode
    323                 DataHelper.writeLong(out, 1, 0);
     345                out.write((byte) 0);
    324346            } else {
    325                 DataHelper.writeLong(out, 1, sz);
     347                out.write((byte) sz);
    326348                for (RouterAddress addr : _addresses) {
    327349                    addr.writeBytes(out);
     
    333355            //         at the moment, and may not be later.
    334356            int psz = _peers == null ? 0 : _peers.size();
    335             DataHelper.writeLong(out, 1, psz);
     357            out.write((byte) psz);
    336358            if (psz > 0) {
    337359                Collection<Hash> peers = _peers;
     
    346368            }
    347369            DataHelper.writeProperties(out, _options);
    348         } catch (IOException ioe) {
    349             throw new DataFormatException("IO Error getting bytes", ioe);
    350         }
    351         byte data[] = out.toByteArray();
    352         //if (_log.shouldLog(Log.DEBUG)) {
    353         //    long after = Clock.getInstance().now();
    354         //    _log.debug("getBytes()  took " + (after - before) + "ms");
    355         //}
    356         if (CACHE_ALL || _shouldCache)
    357             _byteified = data;
    358         return data;
    359370    }
    360371
     
    436447
    437448    /**
    438      * Warning, must be called AFTER setOptions().
    439      *
    440      * @throws IllegalStateException if RouterInfo is already signed
    441      */
    442     public void addCapability(char cap) {
    443         if (_signature != null)
    444             throw new IllegalStateException();
    445 
    446             String caps = _options.getProperty(PROP_CAPABILITIES);
    447             if (caps == null)
    448                 _options.setProperty(PROP_CAPABILITIES, String.valueOf(cap));
    449             else if (caps.indexOf(cap) == -1)
    450                 _options.setProperty(PROP_CAPABILITIES, caps + cap);
    451     }
    452 
    453     /**
    454      * @throws IllegalStateException if RouterInfo is already signed
    455      * @deprecated unused
    456      */
    457     public void delCapability(char cap) {
    458         if (_signature != null)
    459             throw new IllegalStateException();
    460 
    461             String caps = _options.getProperty(PROP_CAPABILITIES);
    462             int idx;
    463             if (caps == null) {
    464                 return;
    465             } else if ((idx = caps.indexOf(cap)) == -1) {
    466                 return;
    467             } else {
    468                 StringBuilder buf = new StringBuilder(caps);
    469                 while ( (idx = buf.indexOf(""+cap)) != -1)
    470                     buf.deleteCharAt(idx);
    471                 _options.setProperty(PROP_CAPABILITIES, buf.toString());
    472             }
    473     }
    474 
    475     /**
    476449     * Determine whether the router was published recently (within the given age milliseconds).
    477450     * The age should be large enough to take into consideration any clock fudge factor, so
     
    526499        if (!_isValid) {
    527500            Log log = I2PAppContext.getGlobalContext().logManager().getLog(RouterInfo.class);
    528             byte data[] = null;
    529             try {
    530                 data = getBytes();
    531             } catch (DataFormatException dfe) {
    532                 log.error("Error validating", dfe);
    533                 return;
    534             }
    535             log.error("Invalid [" + SHA256Generator.getInstance().calculateHash(data).toBase64()
    536                            + (log.shouldLog(Log.WARN) ? ("]\n" + toString()) : ""),
    537                            new Exception("Signature failed"));
     501            if (log.shouldWarn()) {
     502                log.warn("Sig verify fail: " + toString(), new Exception("from"));
     503            } else {
     504                log.error("RI Sig verify fail: " + _identity.getHash());
     505            }
    538506        }
    539507    }
     
    632600     */
    633601    public void writeBytes(OutputStream out) throws DataFormatException, IOException {
    634         if (_identity == null) throw new DataFormatException("Missing identity");
    635         if (_published < 0) throw new DataFormatException("Invalid published date: " + _published);
    636602        if (_signature == null) throw new DataFormatException("Signature is null");
    637         //if (!isValid())
    638         //    throw new DataFormatException("Data is not valid");
    639         ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
    640         baos.write(getBytes());
    641         _signature.writeBytes(baos);
    642 
    643         byte data[] = baos.toByteArray();
    644         //_log.debug("Writing routerInfo [len=" + data.length + "]: " + toString());
    645         out.write(data);
     603        writeDataBytes(out);
     604        _signature.writeBytes(out);
    646605    }
    647606   
  • router/java/src/net/i2p/router/CommSystemFacade.java

    r9bb1a00 r07e85e0  
    7171     * @deprecated use getStatus()
    7272     */
     73    @Deprecated
    7374    public short getReachabilityStatus() { return (short) getStatus().getCode(); }
    7475   
     
    8283     * @deprecated unused
    8384     */
     85    @Deprecated
    8486    public void recheckReachability() {}
    8587
    86     public boolean isBacklogged(Hash dest) { return false; }
    87     public boolean wasUnreachable(Hash dest) { return false; }
    88     public boolean isEstablished(Hash dest) { return false; }
     88    public boolean isBacklogged(Hash peer) { return false; }
     89    public boolean wasUnreachable(Hash peer) { return false; }
     90    public boolean isEstablished(Hash peer) { return false; }
    8991    public byte[] getIP(Hash dest) { return null; }
    9092    public void queueLookup(byte[] ip) {}
     93   
     94    /**
     95     * Tell the comm system that we may disconnect from this peer.
     96     * This is advisory only.
     97     *
     98     * @since 0.9.24
     99     */
     100    public void mayDisconnect(Hash peer) {}
    91101
    92102    /** @since 0.8.11 */
  • router/java/src/net/i2p/router/InNetMessagePool.java

    r9bb1a00 r07e85e0  
    9595     * @throws AIOOBE if i2npMessageType is greater than MAX_I2NP_MESSAGE_TYPE
    9696     */
    97     public HandlerJobBuilder registerHandlerJobBuilder(int i2npMessageType, HandlerJobBuilder builder) {
     97    public synchronized HandlerJobBuilder registerHandlerJobBuilder(int i2npMessageType, HandlerJobBuilder builder) {
    9898        HandlerJobBuilder old = _handlerJobBuilders[i2npMessageType];
    9999        _handlerJobBuilders[i2npMessageType] = builder;
     
    104104     * @return previous builder for this message type, or null
    105105     * @throws AIOOBE if i2npMessageType is greater than MAX_I2NP_MESSAGE_TYPE
     106     * @deprecated unused
    106107     */
    107     public HandlerJobBuilder unregisterHandlerJobBuilder(int i2npMessageType) {
     108    @Deprecated
     109    public synchronized HandlerJobBuilder unregisterHandlerJobBuilder(int i2npMessageType) {
    108110        HandlerJobBuilder old = _handlerJobBuilders[i2npMessageType];
    109111        _handlerJobBuilders[i2npMessageType] = null;
  • router/java/src/net/i2p/router/MessageHistory.java

    r9bb1a00 r07e85e0  
    1111import java.util.concurrent.LinkedBlockingQueue;
    1212
     13import net.i2p.data.DataHelper;
    1314import net.i2p.data.Hash;
    1415import net.i2p.data.TunnelId;
     
    4142    private volatile boolean _firstPass;
    4243   
    43     private final static byte[] NL = System.getProperty("line.separator").getBytes();
     44    private final static byte[] NL = DataHelper.getUTF8(System.getProperty("line.separator"));
    4445    private final static int FLUSH_SIZE = 1000; // write out at least once every 1000 entries
    4546       
     
    637638            String entry;
    638639            while ((entry = _unwrittenEntries.poll()) != null) {
    639                 fos.write(entry.getBytes());
     640                fos.write(DataHelper.getUTF8(entry));
    640641                fos.write(NL);
    641642            }
  • router/java/src/net/i2p/router/Router.java

    r9bb1a00 r07e85e0  
    1111import java.io.File;
    1212import java.io.IOException;
     13import java.security.GeneralSecurityException;
    1314import java.util.Collection;
    1415import java.util.Collections;
     
    3637import net.i2p.data.router.RouterInfo;
    3738import net.i2p.router.CommSystemFacade.Status;
     39import net.i2p.router.crypto.FamilyKeyCrypto;
    3840import net.i2p.router.message.GarlicMessageHandler;
    3941import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
     
    8991    private final Object _stateLock = new Object();
    9092    private State _state = State.UNINITIALIZED;
     93    private FamilyKeyCrypto _familyKeyCrypto;
     94    private boolean _familyKeyCryptoFail;
     95    public final Object _familyKeyLock = new Object();
    9196   
    9297    public final static String PROP_CONFIG_FILE = "router.configLocation";
     
    489494     *  Our current router info.
    490495     *  Warning, may be null if called very early.
     496     *
     497     *  Warning - risk of deadlock - do not call while holding locks
     498     *
    491499     */
    492500    public RouterInfo getRouterInfo() {
     
    499507     *  Caller must ensure info is valid - no validation done here.
    500508     *  Not for external use.
     509     *
     510     *  Warning - risk of deadlock - do not call while holding locks
     511     *
    501512     */
    502513    public void setRouterInfo(RouterInfo info) {
     
    512523    /**
    513524     *  Used only by routerconsole.. to be deprecated?
     525     *  @return System time, NOT context time
    514526     */
    515527    public long getWhenStarted() { return _started; }
    516528
    517     /** wall clock uptime */
     529    /**
     530     * Wall clock uptime.
     531     * This uses System time, NOT context time, so context clock shifts will
     532     * not affect it. This is important if NTP fails and the
     533     * clock then shifts from a SSU peer source just after startup.
     534     */
    518535    public long getUptime() {
    519         if ( (_context == null) || (_context.clock() == null) ) return 1; // racing on startup
    520         return Math.max(1, _context.clock().now() - _context.clock().getOffset() - _started);
     536        if (_started <= 0) return 1000; // racing on startup
     537        return Math.max(1000, System.currentTimeMillis() - _started);
    521538    }
    522539   
     
    556573        startupStuff();
    557574        changeState(State.STARTING_2);
    558         _started = _context.clock().now();
     575        _started = System.currentTimeMillis();
    559576        try {
    560577            Runtime.getRuntime().addShutdownHook(_shutdownHook);
     
    807824     * has changed.
    808825     * Not for external use.
     826     *
     827     *  Warning - risk of deadlock - do not call while holding locks
     828     *
    809829     */
    810830    public void rebuildRouterInfo(boolean blockingRebuild) {
     
    822842     */
    823843    private void locked_rebuildRouterInfo(boolean blockingRebuild) {
    824         RouterInfo ri = null;
     844        RouterInfo ri;
    825845        if (_routerInfo != null)
    826846            ri = new RouterInfo(_routerInfo);
     
    831851            ri.setPublished(_context.clock().now());
    832852            Properties stats = _context.statPublisher().publishStatistics();
    833             stats.setProperty(RouterInfo.PROP_NETWORK_ID, NETWORK_ID+"");
    834853           
    835854            ri.setOptions(stats);
     855            // deadlock thru createAddresses() thru SSU REA... move outside lock?
    836856            ri.setAddresses(_context.commSystem().createAddresses());
    837857
    838             addCapabilities(ri);
    839858            SigningPrivateKey key = _context.keyManager().getSigningPrivateKey();
    840859            if (key == null) {
     
    856875    }
    857876
     877    /**
     878     *  Family Key Crypto Signer / Verifier.
     879     *  Not for external use.
     880     *  If family key is set, first call Will take a while to generate keys.
     881     *  Warning - risk of deadlock - do not call while holding locks
     882     *  (other than routerInfoLock)
     883     *
     884     *  @return null on initialization failure
     885     *  @since 0.9.24
     886     */
     887    public FamilyKeyCrypto getFamilyKeyCrypto() {
     888        synchronized (_familyKeyLock) {
     889            if (_familyKeyCrypto == null) {
     890                if (!_familyKeyCryptoFail) {
     891                    try {
     892                        _familyKeyCrypto = new FamilyKeyCrypto(_context);
     893                    } catch (GeneralSecurityException gse) {
     894                        _log.error("Failed to initialize family key crypto", gse);
     895                        _familyKeyCryptoFail = true;
     896                    }
     897                }
     898            }
     899        }
     900        return _familyKeyCrypto;
     901    }
     902
    858903    // publicize our ballpark capacity
    859904    public static final char CAPABILITY_BW12 = 'K';
     
    879924    /**
    880925     *  For building our RI. Not for external use.
    881      *  This does not publish the ri.
    882      *  This does not use anything in the ri (i.e. it can be freshly constructed)
    883      *
    884      *  TODO just return a string instead of passing in the RI? See PublishLocalRouterInfoJob.
    885      *
    886      *  @param ri an unpublished ri we are generating.
    887      */
    888     public void addCapabilities(RouterInfo ri) {
     926     *
     927     *  @return a capabilities string to be added to the RI
     928     */
     929    public String getCapabilities() {
     930        StringBuilder rv = new StringBuilder(4);
    889931        int bwLim = Math.min(_context.bandwidthLimiter().getInboundKBytesPerSecond(),
    890932                             _context.bandwidthLimiter().getOutboundKBytesPerSecond());
     
    895937        String force = _context.getProperty(PROP_FORCE_BWCLASS);
    896938        if (force != null && force.length() > 0) {
    897             ri.addCapability(force.charAt(0));
     939            rv.append(force.charAt(0));
    898940        } else if (bwLim < 12) {
    899             ri.addCapability(CAPABILITY_BW12);
     941            rv.append(CAPABILITY_BW12);
    900942        } else if (bwLim <= 48) {
    901             ri.addCapability(CAPABILITY_BW32);
     943            rv.append(CAPABILITY_BW32);
    902944        } else if (bwLim <= 64) {
    903             ri.addCapability(CAPABILITY_BW64);
     945            rv.append(CAPABILITY_BW64);
    904946        } else if (bwLim <= 128) {
    905             ri.addCapability(CAPABILITY_BW128);
     947            rv.append(CAPABILITY_BW128);
    906948        } else if (bwLim <= 256) {
    907             ri.addCapability(CAPABILITY_BW256);
     949            rv.append(CAPABILITY_BW256);
    908950        } else if (bwLim <= 2000) {    // TODO adjust threshold
    909951            // 512 supported as of 0.9.18;
    910952            // Add 256 as well for compatibility
    911             ri.addCapability(CAPABILITY_BW512);
    912             ri.addCapability(CAPABILITY_BW256);
     953            rv.append(CAPABILITY_BW512);
     954            rv.append(CAPABILITY_BW256);
    913955        } else {
    914956            // Unlimited supported as of 0.9.18;
    915957            // Add 256 as well for compatibility
    916             ri.addCapability(CAPABILITY_BW_UNLIMITED);
    917             ri.addCapability(CAPABILITY_BW256);
     958            rv.append(CAPABILITY_BW_UNLIMITED);
     959            rv.append(CAPABILITY_BW256);
    918960        }
    919961       
     
    921963        if (_context.netDb().floodfillEnabled() &&
    922964            !_context.getBooleanProperty("router.hideFloodfillParticipant"))
    923             ri.addCapability(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL);
     965            rv.append(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL);
    924966       
    925967        if(_context.getBooleanProperty(PROP_HIDDEN))
    926             ri.addCapability(RouterInfo.CAPABILITY_HIDDEN);
     968            rv.append(RouterInfo.CAPABILITY_HIDDEN);
    927969       
    928970        if (_context.getBooleanProperty(PROP_FORCE_UNREACHABLE)) {
    929             ri.addCapability(CAPABILITY_UNREACHABLE);
    930             return;
     971            rv.append(CAPABILITY_UNREACHABLE);
     972            return rv.toString();
    931973        }
    932974        switch (_context.commSystem().getStatus()) {
     
    938980            case IPV4_UNKNOWN_IPV6_OK:
    939981            case IPV4_SNAT_IPV6_OK:
    940                 ri.addCapability(CAPABILITY_REACHABLE);
     982                rv.append(CAPABILITY_REACHABLE);
    941983                break;
    942984
     
    944986            case REJECT_UNSOLICITED:
    945987            case IPV4_DISABLED_IPV6_FIREWALLED:
    946                 ri.addCapability(CAPABILITY_UNREACHABLE);
     988                rv.append(CAPABILITY_UNREACHABLE);
    947989                break;
    948990
     
    9581000                break;
    9591001        }
    960     }
    961    
     1002        return rv.toString();
     1003    }
     1004   
     1005    /*
     1006     *  This checks the config only. We don't check the current RI
     1007     *  due to deadlocks.
     1008     *
     1009     */
    9621010    public boolean isHidden() {
    963         RouterInfo ri;
    964         synchronized (_routerInfoLock) {
    965             ri = _routerInfo;
    966         }
    967         if ( (ri != null) && (ri.isHidden()) )
     1011        //RouterInfo ri;
     1012        //synchronized (_routerInfoLock) {
     1013        //    ri = _routerInfo;
     1014        //}
     1015        //if ( (ri != null) && (ri.isHidden()) )
     1016        //    return true;
     1017        if (_context.getBooleanProperty(PROP_HIDDEN))
    9681018            return true;
    9691019        String h = _context.getProperty(PROP_HIDDEN_HIDDEN);
     
    11651215        try { _context.namingService().shutdown(); } catch (Throwable t) { _log.error("Error shutting down the naming service", t); }
    11661216        try { _context.jobQueue().shutdown(); } catch (Throwable t) { _log.error("Error shutting down the job queue", t); }
    1167         try { _context.statPublisher().shutdown(); } catch (Throwable t) { _log.error("Error shutting down the stats publisher", t); }
    11681217        try { _context.tunnelManager().shutdown(); } catch (Throwable t) { _log.error("Error shutting down the tunnel manager", t); }
    11691218        try { _context.tunnelDispatcher().shutdown(); } catch (Throwable t) { _log.error("Error shutting down the tunnel dispatcher", t); }
  • router/java/src/net/i2p/router/RouterContext.java

    r9bb1a00 r07e85e0  
    262262     *  Convenience method for getting the router hash.
    263263     *  Equivalent to context.router().getRouterInfo().getIdentity().getHash()
     264     *
     265     *  Warning - risk of deadlock - do not call while holding locks
     266     *
    264267     *  @return may be null if called very early
    265268     */
  • router/java/src/net/i2p/router/RouterThrottleImpl.java

    r9bb1a00 r07e85e0  
    1515 *
    1616 */
    17 class RouterThrottleImpl implements RouterThrottle {
     17public class RouterThrottleImpl implements RouterThrottle {
    1818    protected final RouterContext _context;
    1919    private final Log _log;
     
    2929    // TODO reduce
    3030    private static final long JOB_LAG_LIMIT_TUNNEL = 500;
    31     private static final String PROP_MAX_TUNNELS = "router.maxParticipatingTunnels";
    32     private static final int DEFAULT_MAX_TUNNELS = 10*1000;
     31    public static final String PROP_MAX_TUNNELS = "router.maxParticipatingTunnels";
     32    public static final int DEFAULT_MAX_TUNNELS = 10*1000;
    3333    private static final String PROP_MAX_PROCESSINGTIME = "router.defaultProcessingTimeThrottle";
    3434    private static final long DEFAULT_REJECT_STARTUP_TIME = 10*60*1000;
     
    277277        // ok, we're not hosed, but can we handle the bandwidth requirements
    278278        // of another tunnel?
    279         rs = _context.statManager().getRate("tunnel.participatingMessageCount");
     279        rs = _context.statManager().getRate("tunnel.participatingMessageCountAvgPerTunnel");
    280280        r = null;
    281281        double messagesPerTunnel = DEFAULT_MESSAGES_PER_TUNNEL_ESTIMATE;
  • router/java/src/net/i2p/router/RouterVersion.java

    r9bb1a00 r07e85e0  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 24;
     21    public final static long BUILD = 25;
    2222
    2323    /** for example "-test" */
  • router/java/src/net/i2p/router/StatisticsManager.java

    r9bb1a00 r07e85e0  
    1010
    1111import java.io.Writer;
     12import java.security.GeneralSecurityException;
    1213import java.text.DecimalFormat;
    1314import java.text.DecimalFormatSymbols;
     
    1718import net.i2p.CoreVersion;
    1819import net.i2p.data.DataHelper;
     20import net.i2p.data.Hash;
     21import net.i2p.data.router.RouterInfo;
     22import net.i2p.router.crypto.FamilyKeyCrypto;
    1923import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
    2024import net.i2p.stat.Rate;
     
    2630 *
    2731 */
    28 public class StatisticsManager implements Service {
     32public class StatisticsManager {
    2933    private final Log _log;
    3034    private final RouterContext _context;
    3135   
    3236    public final static String PROP_PUBLISH_RANKINGS = "router.publishPeerRankings";
     37    private static final String PROP_CONTACT_NAME = "netdb.contact";
    3338    /** enhance anonymity by only including build stats one out of this many times */
    3439    private static final int RANDOM_INCLUDE_STATS = 16;
     
    4449    }
    4550       
    46     /** noop */
    47     public void shutdown() {}
    48 
    49     /** noop */
    50     public void restart() {}
    51 
    52     /** noop */
    53     public void startup() {}
    54    
    55     /** Retrieve a snapshot of the statistics that should be published */
     51    /**
     52     *  Retrieve a snapshot of the statistics that should be published.
     53     *
     54     *  This includes all standard options (as of 0.9.24, network ID and caps)
     55     */
    5656    public Properties publishStatistics() {
     57        // if hash is null, will be caught in fkc.sign()
     58        return publishStatistics(_context.routerHash());
     59    }
     60   
     61    /**
     62     *  Retrieve a snapshot of the statistics that should be published.
     63     *
     64     *  This includes all standard options (as of 0.9.24, network ID and caps)
     65     *
     66     *  @param h current router hash, non-null
     67     *  @since 0.9.24
     68     */
     69    public Properties publishStatistics(Hash h) {
    5770        Properties stats = new Properties();
    5871        stats.setProperty("router.version", RouterVersion.VERSION);
    59         stats.setProperty("coreVersion", CoreVersion.VERSION);
     72        // scheduled for removal, never used
     73        if (CoreVersion.VERSION.equals("0.9.23"))
     74            stats.setProperty("coreVersion", CoreVersion.VERSION);
     75        stats.setProperty(RouterInfo.PROP_NETWORK_ID, Integer.toString(Router.NETWORK_ID));
     76        stats.setProperty(RouterInfo.PROP_CAPABILITIES, _context.router().getCapabilities());
    6077
    6178        // No longer expose, to make build tracking more expensive
     
    149166        }
    150167
    151         // So that we will still get build requests
    152         stats.setProperty("stat_uptime", "90m");
     168        // So that we will still get build requests - not required since 0.7.9 2010-01-12
     169        // scheduled for removal
     170        if (CoreVersion.VERSION.equals("0.9.23"))
     171            stats.setProperty("stat_uptime", "90m");
    153172        if (FloodfillNetworkDatabaseFacade.isFloodfill(_context.router().getRouterInfo())) {
    154173            int ri = _context.router().getUptime() > 30*60*1000 ?
     
    160179                     30 + _context.random().nextInt(40);   // so it isn't obvious we restarted
    161180            stats.setProperty("netdb.knownLeaseSets", String.valueOf(ls));
     181        }
     182
     183        String contact = _context.getProperty(PROP_CONTACT_NAME);
     184        if (contact != null)
     185            stats.setProperty("contact", contact);
     186
     187        String family = _context.getProperty(FamilyKeyCrypto.PROP_FAMILY_NAME);
     188        if (family != null) {
     189            stats.setProperty(FamilyKeyCrypto.OPT_NAME, family);
     190            String sig = null;
     191            String key = null;
     192            RouterInfo oldRI = _context.router().getRouterInfo();
     193            if (oldRI != null) {
     194                // don't do it if family changed
     195                if (family.equals(oldRI.getOption(FamilyKeyCrypto.OPT_NAME))) {
     196                    // copy over the pubkey and signature
     197                    key = oldRI.getOption(FamilyKeyCrypto.OPT_KEY);
     198                    if (key != null) {
     199                        if (key.contains(";")) {
     200                            // we changed the separator from ';' to ':'
     201                            key = null;
     202                        } else {
     203                            stats.setProperty(FamilyKeyCrypto.OPT_KEY, key);
     204                            sig = oldRI.getOption(FamilyKeyCrypto.OPT_SIG);
     205                            if (sig != null)
     206                                stats.setProperty(FamilyKeyCrypto.OPT_SIG, sig);
     207                        }
     208                    }
     209                }
     210            }
     211            if (sig == null || key == null) {
     212                FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto();
     213                if (fkc != null) {
     214                    try {
     215                        stats.putAll(fkc.sign(family, h));
     216                    } catch (GeneralSecurityException gse) {
     217                        _log.error("Failed to sign router family", gse);
     218                        stats.remove(FamilyKeyCrypto.OPT_KEY);
     219                        stats.remove(FamilyKeyCrypto.OPT_SIG);
     220                    }
     221                }
     222            }
    162223        }
    163224
  • router/java/src/net/i2p/router/message/GarlicMessageBuilder.java

    r9bb1a00 r07e85e0  
    244244                byte clove[] = buildClove(ctx, (PayloadGarlicConfig)config);
    245245                baos = new ByteArrayOutputStream(clove.length + 16);
    246                 DataHelper.writeLong(baos, 1, 1);
     246                baos.write((byte) 1);
    247247                baos.write(clove);
    248248            } else {
     
    264264                    len += cloves[i].length;
    265265                baos = new ByteArrayOutputStream(len + 16);
    266                 DataHelper.writeLong(baos, 1, cloves.length);
     266                baos.write((byte) cloves.length);
    267267                for (int i = 0; i < cloves.length; i++)
    268268                    baos.write(cloves[i]);
  • router/java/src/net/i2p/router/message/OutboundClientMessageOneShotJob.java

    r9bb1a00 r07e85e0  
    3939
    4040/**
    41  * Send a client message out a random outbound tunnel and into a random inbound
     41 * Send a client message out an outbound tunnel and into an inbound
    4242 * tunnel on the target leaseSet.  This also (sometimes) bundles the sender's leaseSet and
    4343 * a DeliveryStatusMessage (for ACKing any sessionTags used in the garlic).
     44 *
     45 * <p>
     46 * This class is where we make several important decisions about
     47 * what to send and what path to send it over. These decisions
     48 * will dramatically affect:
     49 * <ul>
     50 * <li>Local performance and outbound bandwidth usage
     51 * <li>Streaming performance and reliability
     52 * <li>Overall network performace and connection congestion
     53 * </ul>
     54 *
     55 * <p>
     56 * For the outbound message, we build and encrypt a garlic message,
     57 * after making the following decisions:
     58 * <ul>
     59 * <li>Whether to bundle our leaseset
     60 * <li>Whether to bundle session tags, and if so, how many
     61 * <li>Whether to bundle an encrypted DeliveryStatusMessage to be returned
     62 *     to us as an acknowledgement
     63 * </ul>
     64 *
     65 * <p>
     66 * Also, we make the following path selection decisions:
     67 * <ul>
     68 * <li>What outbound client tunnel of ours to use send the message out
     69 * <li>What inbound client tunnel of his (i.e. lease, chosen from his leaseset)
     70 *     to use to send the message in
     71 * <li>If a DeliveryStatusMessage is bundled, What inbound client tunnel of ours
     72 *     do we specify to receive it
     73 * </ul>
     74 *
     75 * <p>
     76 * Note that the 4th tunnel in the DeliveryStatusMessage's round trip (his outbound tunnel)
     77 * is not selected by us, it is chosen by the recipient.
     78 *
     79 * <p>
     80 * If a DeliveryStatusMessage is sent, a listener is registered to wait for its reply.
     81 * When a reply is received, or the timeout is reached, this is noted
     82 * and will influence subsequent bundling and path selection decisions.
     83 *
     84 * <p>
     85 * Path selection decisions are cached and reused if still valid and if
     86 * previous deliveries were apparently successful. This significantly
     87 * reduces out-of-order delivery and network connection congestion.
     88 * Caching is based on the local/remote destination pair.
     89 *
     90 * <p>
     91 * Bundling decisions, and both messaging and reply expiration times, are generally
     92 * set here but may be overridden by the client on a per-message basis.
     93 * Within clients, there may be overall settings or per-message settings.
     94 * The streaming lib also overrides defaults for some messages.
     95 * A datagram-based DHT application may need significantly different
     96 * settings than a streaming application. For an application such as
     97 * a bittorrent client that sends both types of traffic on the same tunnels,
     98 * it is important to tune the settings for efficiency and performance.
     99 * The per-session and per-message overrides are set via I2CP.
     100 *
    44101 *
    45102 */
  • router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java

    r9bb1a00 r07e85e0  
    8383            int count = _runCount.incrementAndGet();
    8484            RouterInfo ri = new RouterInfo(oldRI);
    85             // this will get overwritten by setOptions() below, must restore it below
    86             getContext().router().addCapabilities(ri);
    87             String caps = ri.getCapabilities();
    8885            if (_notFirstTime && (count % 4) != 0 && oldAddrs.size() == newAddrs.size()) {
    8986                // 3 times out of 4, we don't republish if everything is the same...
     
    117114            ri.setPublished(getContext().clock().now());
    118115            Properties stats = getContext().statPublisher().publishStatistics();
    119             stats.setProperty(RouterInfo.PROP_NETWORK_ID, String.valueOf(Router.NETWORK_ID));
    120             // restore caps generated above
    121             stats.setProperty(RouterInfo.PROP_CAPABILITIES, caps);
    122116            ri.setOptions(stats);
    123117            ri.setAddresses(newAddrs);
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodOnlySearchJob.java

    r9bb1a00 r07e85e0  
    221221        }
    222222        _facade.complete(_key);
    223         getContext().statManager().addRateData("netDb.failedTime", time, 0);
     223        getContext().statManager().addRateData("netDb.failedTime", time);
    224224        for (Job j : _onFailed) {
    225225            getContext().jobQueue().addJob(j);
     
    252252        }
    253253        _facade.complete(_key);
    254         getContext().statManager().addRateData("netDb.successTime", time, 0);
     254        getContext().statManager().addRateData("netDb.successTime", time);
    255255        for (Job j : _onFind) {
    256256            getContext().jobQueue().addJob(j);
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodfillDatabaseLookupMessageHandler.java

    r9bb1a00 r07e85e0  
    4444
    4545    public Job createJob(I2NPMessage receivedMessage, RouterIdentity from, Hash fromHash) {
    46         _context.statManager().addRateData("netDb.lookupsReceived", 1, 0);
     46        _context.statManager().addRateData("netDb.lookupsReceived", 1);
    4747
    4848        DatabaseLookupMessage dlm = (DatabaseLookupMessage)receivedMessage;
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodfillVerifyStoreJob.java

    r9bb1a00 r07e85e0  
    258258                    if (_sentTo != null)
    259259                        getContext().profileManager().dbStoreSuccessful(_sentTo);
    260                     getContext().statManager().addRateData("netDb.floodfillVerifyOK", delay, 0);
     260                    getContext().statManager().addRateData("netDb.floodfillVerifyOK", delay);
    261261                    if (_log.shouldLog(Log.INFO))
    262262                        _log.info("Verify success for " + _key);
     
    291291            if (_target != null && !_target.equals(_sentTo))
    292292                getContext().profileManager().dbLookupFailed(_target);
    293             getContext().statManager().addRateData("netDb.floodfillVerifyFail", delay, 0);
     293            getContext().statManager().addRateData("netDb.floodfillVerifyFail", delay);
    294294            resend();
    295295        }       
     
    329329            //if (_sentTo != null)
    330330            //    getContext().profileManager().dbStoreFailed(_sentTo);
    331             getContext().statManager().addRateData("netDb.floodfillVerifyTimeout", getContext().clock().now() - _sendTime, 0);
     331            getContext().statManager().addRateData("netDb.floodfillVerifyTimeout", getContext().clock().now() - _sendTime);
    332332            if (_log.shouldLog(Log.WARN))
    333333                _log.warn("Verify timed out for: " + _key);
  • router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java

    r9bb1a00 r07e85e0  
    1111import java.util.concurrent.ConcurrentHashMap;
    1212
     13import net.i2p.crypto.SigType;
    1314import net.i2p.data.Base64;
    1415import net.i2p.data.DataHelper;
     
    3132import net.i2p.util.NativeBigInteger;
    3233import net.i2p.util.SystemVersion;
     34import net.i2p.util.VersionComparator;
    3335
    3436/**
     
    7577    private static final int MAX_NON_FF = 3;
    7678    /** Max number of peers to query */
    77     private static final int TOTAL_SEARCH_LIMIT = 6;
     79    private static final int TOTAL_SEARCH_LIMIT = 5;
    7880    /** Max number of peers to query if we are ff */
    7981    private static final int TOTAL_SEARCH_LIMIT_WHEN_FF = 3;
     
    200202        }
    201203        final boolean empty;
     204        // outside sync to avoid deadlock
     205        final Hash us = getContext().routerHash();
    202206        synchronized(this) {
    203207            _toTry.addAll(floodfillPeers);
    204208            // don't ask ourselves or the target
    205             _toTry.remove(getContext().routerHash());
     209            _toTry.remove(us);
    206210            _toTry.remove(_key);
    207211            empty = _toTry.isEmpty();
     
    287291            TunnelManagerFacade tm = getContext().tunnelManager();
    288292            RouterInfo ri = getContext().netDb().lookupRouterInfoLocally(peer);
     293            if (ri != null) {
     294                // Now that most of the netdb is Ed RIs and EC LSs, don't even bother
     295                // querying old floodfills that don't know about those sig types.
     296                // This is also more recent than the version that supports encrypted replies,
     297                // so we won't request unencrypted replies anymore either.
     298                String v = ri.getVersion();
     299                String since = SigType.EdDSA_SHA512_Ed25519.getSupportedSince();
     300                if (VersionComparator.comp(v, since) < 0) {
     301                    failed(peer, false);
     302                    if (_log.shouldLog(Log.WARN))
     303                        _log.warn(getJobId() + ": not sending query to old version " + v + ": " + peer);
     304                    return;
     305                }
     306            }
    289307            TunnelInfo outTunnel;
    290308            TunnelInfo replyTunnel;
     
    380398                if (ri != null) {
    381399                    // request encrypted reply
    382                     if (DatabaseLookupMessage.supportsEncryptedReplies(ri)) {
     400                    // now covered by version check above, which is more recent
     401                    //if (DatabaseLookupMessage.supportsEncryptedReplies(ri)) {
     402                    if (true) {
    383403                        MessageWrapper.OneTimeSession sess;
    384404                        if (isClientReplyTunnel)
     
    538558        }
    539559        // blame the unheard-from (others already blamed in failed() above)
    540         for (Hash h : unheard)
     560        for (Hash h : unheard) {
    541561            getContext().profileManager().dbLookupFailed(h);
     562        }
    542563        long time = System.currentTimeMillis() - _created;
    543564        if (_log.shouldLog(Log.INFO)) {
     
    546567                      ", peers queried: " + tries);
    547568        }
    548         getContext().statManager().addRateData("netDb.failedTime", time);
    549         getContext().statManager().addRateData("netDb.failedRetries", Math.max(0, tries - 1));
     569        if (tries > 0) {
     570            // don't bias the stats with immediate fails
     571            getContext().statManager().addRateData("netDb.failedTime", time);
     572            getContext().statManager().addRateData("netDb.failedRetries", tries - 1);
     573        }
    550574        for (Job j : _onFailed) {
    551575            getContext().jobQueue().addJob(j);
  • router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java

    r9bb1a00 r07e85e0  
    4141import net.i2p.router.Router;
    4242import net.i2p.router.RouterContext;
     43import net.i2p.router.crypto.FamilyKeyCrypto;
    4344import net.i2p.router.networkdb.PublishLocalRouterInfoJob;
    4445import net.i2p.router.networkdb.reseed.ReseedChecker;
     
    212213        if (!_initialized) return;
    213214        _exploreKeys.removeAll(toRemove);
    214         _context.statManager().addRateData("netDb.exploreKeySet", _exploreKeys.size(), 0);
     215        _context.statManager().addRateData("netDb.exploreKeySet", _exploreKeys.size());
    215216    }
    216217
     
    220221            _exploreKeys.add(iter.next());
    221222        }
    222         _context.statManager().addRateData("netDb.exploreKeySet", _exploreKeys.size(), 0);
     223        _context.statManager().addRateData("netDb.exploreKeySet", _exploreKeys.size());
    223224    }
    224225   
     
    894895                _log.warn("Bad network: " + routerInfo);
    895896            return "Not in our network";
     897        }
     898        FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto();
     899        if (fkc != null) {
     900            boolean validFamily = fkc.verify(routerInfo);
     901            if (!validFamily) {
     902                if (_log.shouldWarn())
     903                    _log.warn("Bad family sig: " + routerInfo.getHash());
     904            }
     905            // todo store in RI
    896906        }
    897907        return validate(routerInfo);
  • router/java/src/net/i2p/router/networkdb/kademlia/LookupThrottler.java

    r9bb1a00 r07e85e0  
    4646    /** yes, we could have a two-level lookup, or just do h.tostring() + id.tostring() */
    4747    private static class ReplyTunnel {
    48         public Hash h;
    49         public TunnelId id;
     48        public final Hash h;
     49        public final TunnelId id;
    5050
    5151        ReplyTunnel(Hash h, TunnelId id) {
  • router/java/src/net/i2p/router/networkdb/kademlia/PeerSelector.java

    r9bb1a00 r07e85e0  
    113113    /** UNUSED */
    114114    private class MatchSelectionCollector implements SelectionCollector<Hash> {
    115         private TreeMap<BigInteger, Hash> _sorted;
    116         private Hash _key;
    117         private Set<Hash> _toIgnore;
     115        private final TreeMap<BigInteger, Hash> _sorted;
     116        private final Hash _key;
     117        private final Set<Hash> _toIgnore;
    118118        private int _matches;
    119119        public MatchSelectionCollector(Hash key, Set<Hash> toIgnore) {
     
    121121            _sorted = new TreeMap<BigInteger, Hash>();
    122122            _toIgnore = toIgnore;
    123             _matches = 0;
    124123        }
    125124        public void add(Hash entry) {
  • router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java

    r9bb1a00 r07e85e0  
    166166   
    167167    private class RemoveJob extends JobImpl {
    168         private Hash _key;
     168        private final Hash _key;
    169169        public RemoveJob(Hash key) {
    170170            super(PersistentDataStore.this._context);
  • router/java/src/net/i2p/router/networkdb/kademlia/RepublishLeaseSetJob.java

    r9bb1a00 r07e85e0  
    5454                        if (_log.shouldLog(Log.INFO))
    5555                            _log.info("Publishing " + ls);
    56                         getContext().statManager().addRateData("netDb.republishLeaseSetCount", 1, 0);
     56                        getContext().statManager().addRateData("netDb.republishLeaseSetCount", 1);
    5757                        _facade.sendStore(_dest, ls, null, new OnRepublishFailure(getContext(), this), REPUBLISH_LEASESET_TIMEOUT, null);
    5858                        _lastPublished = getContext().clock().now();
     
    106106    /** requeue */
    107107    private static class OnRepublishFailure extends JobImpl {
    108         private RepublishLeaseSetJob _job;
     108        private final RepublishLeaseSetJob _job;
    109109        public OnRepublishFailure(RouterContext ctx, RepublishLeaseSetJob job) {
    110110            super(ctx);
  • router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java

    r9bb1a00 r07e85e0  
    782782   
    783783    private static class Search {
    784         private Job _onFind;
    785         private Job _onFail;
    786         private long _expiration;
    787         private boolean _isLease;
     784        private final Job _onFind;
     785        private final Job _onFail;
     786        private final long _expiration;
     787        private final boolean _isLease;
    788788       
    789789        public Search(Job onFind, Job onFail, long expiration, boolean isLease) {
  • router/java/src/net/i2p/router/networkdb/kademlia/SearchReplyJob.java

    r9bb1a00 r07e85e0  
    101101                    if (_log.shouldLog(Log.INFO))
    102102                        _log.info("Peer " + _peer.toBase64() + " sends us bad replies, so not verifying " + peer.toBase64());
    103                     getContext().statManager().addRateData("netDb.searchReplyValidationSkipped", 1, 0);
     103                    getContext().statManager().addRateData("netDb.searchReplyValidationSkipped", 1);
    104104                }
    105105            }
     
    126126            _log.info("Peer reply from " + _peer.toBase64());
    127127        _repliesPendingVerification--;
    128         getContext().statManager().addRateData("netDb.searchReplyValidated", 1, 0);
     128        getContext().statManager().addRateData("netDb.searchReplyValidated", 1);
    129129    }
    130130    void replyNotVerified() {
     
    133133        _repliesPendingVerification--;
    134134        _invalidPeers++;
    135         getContext().statManager().addRateData("netDb.searchReplyNotValidated", 1, 0);
     135        getContext().statManager().addRateData("netDb.searchReplyNotValidated", 1);
    136136    }
    137137}
  • router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java

    r9bb1a00 r07e85e0  
    294294        }
    295295        msg.setEntry(_state.getData());
    296         msg.setMessageExpiration(getContext().clock().now() + _timeoutMs);
     296        long now = getContext().clock().now();
     297        msg.setMessageExpiration(now + _timeoutMs);
    297298
    298299        if (router.getIdentity().equals(getContext().router().getRouterInfo().getIdentity())) {
     
    306307            _log.debug(getJobId() + ": Send store timeout is " + responseTime);
    307308
    308         sendStore(msg, router, getContext().clock().now() + responseTime);
     309        sendStore(msg, router, now + responseTime);
    309310    }
    310311   
     
    316317    private void sendStore(DatabaseStoreMessage msg, RouterInfo peer, long expiration) {
    317318        if (msg.getEntry().getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
    318             getContext().statManager().addRateData("netDb.storeLeaseSetSent", 1, 0);
     319            getContext().statManager().addRateData("netDb.storeLeaseSetSent", 1);
    319320            // if it is an encrypted leaseset...
    320321            if (getContext().keyRing().get(msg.getKey()) != null)
     
    323324                sendStoreThroughClient(msg, peer, expiration);
    324325        } else {
    325             getContext().statManager().addRateData("netDb.storeRouterInfoSent", 1, 0);
     326            getContext().statManager().addRateData("netDb.storeRouterInfoSent", 1);
    326327            sendDirect(msg, peer, expiration);
    327328        }
     
    558559     */
    559560    private class SendSuccessJob extends JobImpl implements ReplyJob {
    560         private RouterInfo _peer;
    561         private TunnelInfo _sendThrough;
    562         private int _msgSize;
     561        private final RouterInfo _peer;
     562        private final TunnelInfo _sendThrough;
     563        private final int _msgSize;
    563564       
    564565        public SendSuccessJob(RouterContext enclosingContext, RouterInfo peer) {
     
    616617     */
    617618    private class FailedJob extends JobImpl {
    618         private RouterInfo _peer;
    619         private long _sendOn;
     619        private final RouterInfo _peer;
     620        private final long _sendOn;
    620621
    621622        public FailedJob(RouterContext enclosingContext, RouterInfo peer, long sendOn) {
     
    636637
    637638            getContext().profileManager().dbStoreFailed(hash);
    638             getContext().statManager().addRateData("netDb.replyTimeout", getContext().clock().now() - _sendOn, 0);
     639            getContext().statManager().addRateData("netDb.replyTimeout", getContext().clock().now() - _sendOn);
    639640           
    640641            sendNext();
  • router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java

    r9bb1a00 r07e85e0  
    8787    public static final String DEFAULT_SSL_SEED_URL =
    8888              "https://reseed.i2p-projekt.de/" + "," + // Only HTTPS
    89               //"https://netdb.rows.io:444/" + "," + // Only HTTPS and SU3 (v3) support
    90               "https://i2pseed.zarrenspry.info/" + "," + // Only HTTPS and SU3 (v3) support
     89              //"https://i2pseed.zarrenspry.info/" + "," + // Only HTTPS and SU3 (v3) support
    9190              "https://i2p.mooo.com/netDb/" + "," +
    9291              "https://netdb.i2p2.no/" + "," + // Only SU3 (v3) support, SNI required
  • router/java/src/net/i2p/router/peermanager/CapacityCalculator.java

    r9bb1a00 r07e85e0  
    3030    // we make this a bonus for non-ff, not a penalty for ff, so we
    3131    // don't drive the ffs below the default
    32     private static final double BONUS_NON_FLOODFILL = 0.5;
     32    private static final double BONUS_NON_FLOODFILL = 1.0;
    3333   
    3434    public static double calc(PeerProfile profile) {
  • router/java/src/net/i2p/router/peermanager/DBHistory.java

    r9bb1a00 r07e85e0  
    1717    private final Log _log;
    1818    private final RouterContext _context;
    19     private long _successfulLookups;
    20     private long _failedLookups;
     19    //private long _successfulLookups;
     20    //private long _failedLookups;
    2121    private RateStat _failedLookupRate;
    2222    private RateStat _invalidReplyRate;
    23     private long _lookupReplyNew;
    24     private long _lookupReplyOld;
    25     private long _lookupReplyDuplicate;
    26     private long _lookupReplyInvalid;
    27     private long _lookupsReceived;
    28     private long _avgDelayBetweenLookupsReceived;
    29     private long _lastLookupReceived;
     23    //private long _lookupReplyNew;
     24    //private long _lookupReplyOld;
     25    //private long _lookupReplyDuplicate;
     26    //private long _lookupReplyInvalid;
     27    //private long _lookupsReceived;
     28    //private long _avgDelayBetweenLookupsReceived;
     29    //private long _lastLookupReceived;
    3030    private long _lastLookupSuccessful;
    3131    private long _lastLookupFailed;
     
    4040        _log = context.logManager().getLog(DBHistory.class);
    4141        _statGroup = statGroup;
    42         _lastLookupReceived = -1;
     42        //_lastLookupReceived = -1;
    4343        createRates(statGroup);
    4444    }
    4545   
    4646    /** how many times we have sent them a db lookup and received the value back from them
    47      *  @deprecated unused
    48      */
    49     public long getSuccessfulLookups() { return _successfulLookups; }
     47     */
     48    //public long getSuccessfulLookups() { return _successfulLookups; }
     49
    5050    /** how many times we have sent them a db lookup and not received the value or a lookup reply
    51      *  @deprecated unused
    52      */
    53     public long getFailedLookups() { return _failedLookups; }
     51     */
     52    //public long getFailedLookups() { return _failedLookups; }
     53
    5454    /** how many peers that we have never seen before did lookups provide us with?
    55      *  @deprecated unused
    56      */
    57     public long getLookupReplyNew() { return _lookupReplyNew; }
     55     */
     56    //public long getLookupReplyNew() { return _lookupReplyNew; }
     57
    5858    /** how many peers that we have already seen did lookups provide us with?
    59      *  @deprecated unused
    60      */
    61     public long getLookupReplyOld() { return _lookupReplyOld; }
     59     */
     60    //public long getLookupReplyOld() { return _lookupReplyOld; }
     61
    6262    /** how many peers that we explicitly asked the peer not to send us did they reply with?
    63      *  @deprecated unused
    64      */
    65     public long getLookupReplyDuplicate() { return _lookupReplyDuplicate; }
     63     */
     64    //public long getLookupReplyDuplicate() { return _lookupReplyDuplicate; }
     65
    6666    /** how many peers that were incorrectly formatted / expired / otherwise illegal did lookups provide us with?
    67      *  @deprecated unused
    68      */
    69     public long getLookupReplyInvalid() { return _lookupReplyInvalid; }
     67     */
     68    //public long getLookupReplyInvalid() { return _lookupReplyInvalid; }
     69
    7070    /** how many lookups this peer has sent us?
    71      *  @deprecated unused
    72      */
    73     public long getLookupsReceived() { return _lookupsReceived; }
     71     */
     72    //public long getLookupsReceived() { return _lookupsReceived; }
     73
    7474    /** how frequently do they send us lookup requests?
    75      *  @deprecated unused
    76      */
    77     public long getAvgDelayBetweenLookupsReceived() { return _avgDelayBetweenLookupsReceived; }
     75     */
     76    //public long getAvgDelayBetweenLookupsReceived() { return _avgDelayBetweenLookupsReceived; }
     77
    7878    /** when did they last send us a request?
    79      *  @deprecated unused
    80      */
    81     public long getLastLookupReceived() { return _lastLookupReceived; }
     79     */
     80   // public long getLastLookupReceived() { return _lastLookupReceived; }
     81
     82    /**
     83     *  Not persisted until 0.9.24
     84     *  @since 0.7.8
     85     */
    8286    public long getLastLookupSuccessful() { return _lastLookupSuccessful; }
     87
     88    /**
     89     *  Not persisted until 0.9.24
     90     *  @since 0.7.8
     91     */
    8392    public long getLastLookupFailed() { return _lastLookupFailed; }
     93
     94    /**
     95     *  Not persisted until 0.9.24
     96     *  @since 0.7.8
     97     */
    8498    public long getLastStoreSuccessful() { return _lastStoreSuccessful; }
     99
     100    /**
     101     *  Not persisted until 0.9.24
     102     *  @since 0.7.8
     103     */
    85104    public long getLastStoreFailed() { return _lastStoreFailed; }
    86105
     
    104123     */
    105124    public void lookupSuccessful() {
    106         _successfulLookups++;
    107         _failedLookupRate.addData(0, 0);
     125        //_successfulLookups++;
     126        _failedLookupRate.addData(0);
    108127        _context.statManager().addRateData("peer.failedLookupRate", 0);
    109128        _lastLookupSuccessful = _context.clock().now();
     
    114133     */
    115134    public void lookupFailed() {
    116         _failedLookups++;
    117         _failedLookupRate.addData(1, 0);
     135        //_failedLookups++;
     136        _failedLookupRate.addData(1);
    118137        _context.statManager().addRateData("peer.failedLookupRate", 1);
    119138        _lastLookupFailed = _context.clock().now();
     
    124143     * by asking another floodfill peer
    125144     *
     145     *  @since 0.7.8
    126146     */
    127147    public void storeSuccessful() {
    128148        // Fixme, redefined this to include both lookup and store fails,
    129149        // need to fix the javadocs
    130         _failedLookupRate.addData(0, 0);
     150        _failedLookupRate.addData(0);
    131151        _context.statManager().addRateData("peer.failedLookupRate", 0);
    132152        _lastStoreSuccessful = _context.clock().now();
     
    135155    /**
    136156     * Note that floodfill verify failed
     157     *
     158     *  @since 0.7.8
    137159     */
    138160    public void storeFailed() {
    139161        // Fixme, redefined this to include both lookup and store fails,
    140162        // need to fix the javadocs
    141         _failedLookupRate.addData(1, 0);
     163        _failedLookupRate.addData(1);
    142164        _lastStoreFailed = _context.clock().now();
    143165    }
     
    153175     */
    154176    public void lookupReply(int newPeers, int oldPeers, int invalid, int duplicate) {
    155         _lookupReplyNew += newPeers;
    156         _lookupReplyOld += oldPeers;
    157         _lookupReplyInvalid += invalid;
    158         _lookupReplyDuplicate += duplicate;
     177        //_lookupReplyNew += newPeers;
     178        //_lookupReplyOld += oldPeers;
     179        //_lookupReplyInvalid += invalid;
     180        //_lookupReplyDuplicate += duplicate;
    159181       
    160182        if (invalid > 0) {
    161             _invalidReplyRate.addData(invalid, 0);
     183            _invalidReplyRate.addData(invalid);
    162184        }
    163185    }
     186
    164187    /**
    165188     * Note that the peer sent us a lookup
    166189     *
    167190     */
     191/****
    168192    public void lookupReceived() {
    169193        long now = _context.clock().now();
     
    180204        }
    181205    }
     206****/
     207
    182208    /**
    183209     * Note that the peer sent us a data point without us asking for it
     
    191217    }
    192218   
    193     public void setSuccessfulLookups(long num) { _successfulLookups = num; }
    194     public void setFailedLookups(long num) { _failedLookups = num; }
    195     public void setLookupReplyNew(long num) { _lookupReplyNew = num; }
    196     public void setLookupReplyOld(long num) { _lookupReplyOld = num; }
    197     public void setLookupReplyInvalid(long num) { _lookupReplyInvalid = num; }
    198     public void setLookupReplyDuplicate(long num) { _lookupReplyDuplicate = num; }
    199     public void setLookupsReceived(long num) { _lookupsReceived = num; }
    200     public void setAvgDelayBetweenLookupsReceived(long ms) { _avgDelayBetweenLookupsReceived = ms; }
    201     public void setLastLookupReceived(long when) { _lastLookupReceived = when; }
     219    //public void setSuccessfulLookups(long num) { _successfulLookups = num; }
     220    //public void setFailedLookups(long num) { _failedLookups = num; }
     221    //public void setLookupReplyNew(long num) { _lookupReplyNew = num; }
     222    //public void setLookupReplyOld(long num) { _lookupReplyOld = num; }
     223    //public void setLookupReplyInvalid(long num) { _lookupReplyInvalid = num; }
     224    //public void setLookupReplyDuplicate(long num) { _lookupReplyDuplicate = num; }
     225    //public void setLookupsReceived(long num) { _lookupsReceived = num; }
     226    //public void setAvgDelayBetweenLookupsReceived(long ms) { _avgDelayBetweenLookupsReceived = ms; }
     227    //public void setLastLookupReceived(long when) { _lastLookupReceived = when; }
    202228    public void setUnpromptedDbStoreNew(long num) { _unpromptedDbStoreNew = num; }
    203229    public void setUnpromptedDbStoreOld(long num) { _unpromptedDbStoreOld = num; }
     
    218244        buf.append("# DB history").append(NL);
    219245        buf.append("###").append(NL);
    220         add(buf, "successfulLookups", _successfulLookups, "How many times have they successfully given us what we wanted when looking for it?");
    221         add(buf, "failedLookups", _failedLookups, "How many times have we sent them a db lookup and they didn't reply?");
    222         add(buf, "lookupsReceived", _lookupsReceived, "How many lookups have they sent us?");
    223         add(buf, "lookupReplyDuplicate", _lookupReplyDuplicate, "How many of their reply values to our lookups were something we asked them not to send us?");
    224         add(buf, "lookupReplyInvalid", _lookupReplyInvalid, "How many of their reply values to our lookups were invalid (expired, forged, corrupted)?");
    225         add(buf, "lookupReplyNew", _lookupReplyNew, "How many of their reply values to our lookups were brand new to us?");
    226         add(buf, "lookupReplyOld", _lookupReplyOld, "How many of their reply values to our lookups were something we had seen before?");
     246        //add(buf, "successfulLookups", _successfulLookups, "How many times have they successfully given us what we wanted when looking for it?");
     247        //add(buf, "failedLookups", _failedLookups, "How many times have we sent them a db lookup and they didn't reply?");
     248        //add(buf, "lookupsReceived", _lookupsReceived, "How many lookups have they sent us?");
     249        //add(buf, "lookupReplyDuplicate", _lookupReplyDuplicate, "How many of their reply values to our lookups were something we asked them not to send us?");
     250        //add(buf, "lookupReplyInvalid", _lookupReplyInvalid, "How many of their reply values to our lookups were invalid (expired, forged, corrupted)?");
     251        //add(buf, "lookupReplyNew", _lookupReplyNew, "How many of their reply values to our lookups were brand new to us?");
     252        //add(buf, "lookupReplyOld", _lookupReplyOld, "How many of their reply values to our lookups were something we had seen before?");
    227253        add(buf, "unpromptedDbStoreNew", _unpromptedDbStoreNew, "How times have they sent us something we didn't ask for and hadn't seen before?");
    228254        add(buf, "unpromptedDbStoreOld", _unpromptedDbStoreOld, "How times have they sent us something we didn't ask for but have seen before?");
    229         add(buf, "lastLookupReceived", _lastLookupReceived, "When was the last time they send us a lookup?  (milliseconds since the epoch)");
    230         add(buf, "avgDelayBetweenLookupsReceived", _avgDelayBetweenLookupsReceived, "How long is it typically between each db lookup they send us?  (in milliseconds)");
     255        //add(buf, "lastLookupReceived", _lastLookupReceived, "When was the last time they send us a lookup?  (milliseconds since the epoch)");
     256        //add(buf, "avgDelayBetweenLookupsReceived", _avgDelayBetweenLookupsReceived, "How long is it typically between each db lookup they send us?  (in milliseconds)");
     257        // following 4 weren't persisted until 0.9.24
     258        add(buf, "lastLookupSuccessful", _lastLookupSuccessful, "When was the last time a lookup from them succeeded?  (milliseconds since the epoch)");
     259        add(buf, "lastLookupFailed", _lastLookupFailed, "When was the last time a lookup from them failed?  (milliseconds since the epoch)");
     260        add(buf, "lastStoreSuccessful", _lastStoreSuccessful, "When was the last time a store to them succeeded?  (milliseconds since the epoch)");
     261        add(buf, "lastStoreFailed", _lastStoreFailed, "When was the last time a store to them failed?  (milliseconds since the epoch)");
    231262        out.write(buf.toString().getBytes("UTF-8"));
    232263        _failedLookupRate.store(out, "dbHistory.failedLookupRate");
     
    241272   
    242273    public void load(Properties props) {
    243         _successfulLookups = getLong(props, "dbHistory.successfulLookups");
    244         _failedLookups = getLong(props, "dbHistory.failedLookups");
    245         _lookupsReceived = getLong(props, "dbHistory.lookupsReceived");
    246         _lookupReplyDuplicate = getLong(props, "dbHistory.lookupReplyDuplicate");
    247         _lookupReplyInvalid = getLong(props, "dbHistory.lookupReplyInvalid");
    248         _lookupReplyNew = getLong(props, "dbHistory.lookupReplyNew");
    249         _lookupReplyOld = getLong(props, "dbHistory.lookupReplyOld");
     274        //_successfulLookups = getLong(props, "dbHistory.successfulLookups");
     275        //_failedLookups = getLong(props, "dbHistory.failedLookups");
     276        //_lookupsReceived = getLong(props, "dbHistory.lookupsReceived");
     277        //_lookupReplyDuplicate = getLong(props, "dbHistory.lookupReplyDuplicate");
     278        //_lookupReplyInvalid = getLong(props, "dbHistory.lookupReplyInvalid");
     279        //_lookupReplyNew = getLong(props, "dbHistory.lookupReplyNew");
     280        //_lookupReplyOld = getLong(props, "dbHistory.lookupReplyOld");
    250281        _unpromptedDbStoreNew = getLong(props, "dbHistory.unpromptedDbStoreNew");
    251282        _unpromptedDbStoreOld = getLong(props, "dbHistory.unpromptedDbStoreOld");
    252         _lastLookupReceived = getLong(props, "dbHistory.lastLookupReceived");
    253         _avgDelayBetweenLookupsReceived = getLong(props, "dbHistory.avgDelayBetweenLookupsReceived");
     283        //_lastLookupReceived = getLong(props, "dbHistory.lastLookupReceived");
     284        //_avgDelayBetweenLookupsReceived = getLong(props, "dbHistory.avgDelayBetweenLookupsReceived");
     285        // following 4 weren't persisted until 0.9.24
     286        _lastLookupSuccessful = getLong(props, "dbHistory.lastLookupSuccessful");
     287        _lastLookupFailed = getLong(props, "dbHistory.lastLookupFailed");
     288        _lastStoreSuccessful = getLong(props, "dbHistory.lastStoreSuccessful");
     289        _lastStoreFailed = getLong(props, "dbHistory.lastStoreFailed");
    254290        try {
    255291            _failedLookupRate.load(props, "dbHistory.failedLookupRate", true);
     
    267303    }
    268304   
    269     private void createRates(String statGroup) {
     305    private synchronized void createRates(String statGroup) {
    270306        if (_failedLookupRate == null)
    271307            _failedLookupRate = new RateStat("dbHistory.failedLookupRate", "How often does this peer to respond to a lookup?", statGroup, new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
     
    277313   
    278314    private final static long getLong(Properties props, String key) {
    279         String val = props.getProperty(key);
    280         if (val != null) {
    281             try {
    282                 return Long.parseLong(val);
    283             } catch (NumberFormatException nfe) {
    284                 return 0;
    285             }
    286         }
    287         return 0;
     315        return ProfilePersistenceHelper.getLong(props, key);
    288316    }
    289317}
  • router/java/src/net/i2p/router/peermanager/PeerProfile.java

    r9bb1a00 r07e85e0  
    2525 * (keeping only the most basic data) and maintain hundreds of thousands of profiles
    2626 * in memory. Beyond that size, we can simply eject the peers (e.g. keeping the best 100,000).
     27 *
     28 * TODO most of the methods should be synchronized.
     29 *
    2730 */
    2831
     
    3841    private long _lastFailedSend;
    3942    private long _lastHeardFrom;
    40     private double _tunnelTestResponseTimeAvg;
     43    private float _tunnelTestResponseTimeAvg;
    4144    // periodic rates
    4245    //private RateStat _sendSuccessSize = null;
     
    4750    private RateStat _dbIntroduction;
    4851    // calculation bonuses
    49     private long _speedBonus;
    50     private long _capacityBonus;
    51     private long _integrationBonus;
     52    // ints to save some space
     53    private int _speedBonus;
     54    private int _capacityBonus;
     55    private int _integrationBonus;
    5256    // calculation values
    53     private double _speedValue;
    54     private double _capacityValue;
    55     private double _integrationValue;
     57    // floats to save some space
     58    private float _speedValue;
     59    private float _capacityValue;
     60    private float _integrationValue;
    5661    private boolean _isFailing;
    5762    // new calculation values, to be updated
    58     private double _speedValueNew;
    59     private double _capacityValueNew;
     63    // floats to save some space
     64    private float _speedValueNew;
     65    private float _capacityValueNew;
    6066    // are we in coalescing state?
    6167    private boolean _coalescing;
     
    6874    //private int _consecutiveBanlists;
    6975    private final int _distance;
     76
     77    /** keep track of the fastest 3 throughputs */
     78    private static final int THROUGHPUT_COUNT = 3;
     79    /**
     80     * fastest 1 minute throughput, in bytes per minute, ordered with fastest
     81     * first.  this is not synchronized, as we don't *need* perfection, and we only
     82     * reorder/insert values on coallesce
     83     */
     84    private final float _peakThroughput[] = new float[THROUGHPUT_COUNT];
     85    private volatile long _peakThroughputCurrentTotal;
     86    private final float _peakTunnelThroughput[] = new float[THROUGHPUT_COUNT];
     87    /** total number of bytes pushed through a single tunnel in a 1 minute period */
     88    private final float _peakTunnel1mThroughput[] = new float[THROUGHPUT_COUNT];
     89    /** once a day, on average, cut the measured throughtput values in half */
     90    /** let's try once an hour times 3/4 */
     91    private static final int DROP_PERIOD_MINUTES = 60;
     92    private static final float DEGRADE_FACTOR = 0.75f;
     93    private long _lastCoalesceDate = System.currentTimeMillis();
    7094   
    7195    /**
     
    82106
    83107    /**
     108     *  Caller should call setLastHeardAbout() and setFirstHeardAbout()
     109     *
    84110     *  @param peer non-null
    85111     */
     
    89115
    90116    /**
     117     *  Caller should call setLastHeardAbout() and setFirstHeardAbout()
     118     *
    91119     *  @param peer non-null
    92120     *  @param expand must be true (see below)
    93121     */
    94122    private PeerProfile(RouterContext context, Hash peer, boolean expand) {
     123        if (peer == null)
     124            throw new NullPointerException();
    95125        _context = context;
    96126        _log = context.logManager().getLog(PeerProfile.class);
    97         if (peer == null)
    98             throw new NullPointerException();
    99127        _peer = peer;
     128        _firstHeardAbout = _context.clock().now();
    100129        // this is always true, and there are several places in the router that will NPE
    101130        // if it is false, so all need to be fixed before we can have non-expanded profiles
     
    192221    /**
    193222     *  When did we first hear about this peer?
    194      *  Currently unused, candidate for removal.
    195      */
    196     public long getFirstHeardAbout() { return _firstHeardAbout; }
    197     public void setFirstHeardAbout(long when) { _firstHeardAbout = when; }
    198    
    199     /** when did we last hear about this peer? */
    200     public long getLastHeardAbout() { return _lastHeardAbout; }
    201     public void setLastHeardAbout(long when) { _lastHeardAbout = when; }
     223     *  @return greater than zero, set to now in consturctor
     224     */
     225    public synchronized long getFirstHeardAbout() { return _firstHeardAbout; }
     226
     227    /**
     228     *  Set when did we first heard about this peer, only if older.
     229     *  Package private, only set by profile management subsystem.
     230     */
     231    synchronized void setFirstHeardAbout(long when) {
     232        if (when < _firstHeardAbout)
     233            _firstHeardAbout = when;
     234    }
     235   
     236    /**
     237     *  when did we last hear about this peer?
     238     *  @return 0 if unset
     239     */
     240    public synchronized long getLastHeardAbout() { return _lastHeardAbout; }
     241
     242    /**
     243     *  Set when did we last hear about this peer, only if unset or newer
     244     *  Also sets FirstHeardAbout if earlier
     245     */
     246    public synchronized void setLastHeardAbout(long when) {
     247        if (_lastHeardAbout <= 0 || when > _lastHeardAbout)
     248            _lastHeardAbout = when;
     249        // this is called by netdb PersistentDataStore, so fixup first heard
     250        if (when < _firstHeardAbout)
     251            _firstHeardAbout = when;
     252    }
    202253   
    203254    /** when did we last send to this peer successfully? */
     
    245296     * penalties
    246297     */
    247     public long getSpeedBonus() { return _speedBonus; }
    248     public void setSpeedBonus(long bonus) { _speedBonus = bonus; }
     298    public int getSpeedBonus() { return _speedBonus; }
     299    public void setSpeedBonus(int bonus) { _speedBonus = bonus; }
    249300   
    250301    /**
     
    253304     * penalties
    254305     */
    255     public long getCapacityBonus() { return _capacityBonus; }
    256     public void setCapacityBonus(long bonus) { _capacityBonus = bonus; }
     306    public int getCapacityBonus() { return _capacityBonus; }
     307    public void setCapacityBonus(int bonus) { _capacityBonus = bonus; }
    257308   
    258309    /**
     
    261312     * penalties
    262313     */
    263     public long getIntegrationBonus() { return _integrationBonus; }
    264     public void setIntegrationBonus(long bonus) { _integrationBonus = bonus; }
     314    public int getIntegrationBonus() { return _integrationBonus; }
     315    public void setIntegrationBonus(int bonus) { _integrationBonus = bonus; }
    265316   
    266317    /**
     
    270321     *
    271322     */
    272     public double getSpeedValue() { return _speedValue; }
     323    public float getSpeedValue() { return _speedValue; }
    273324    /**
    274325     * How many tunnels do we think this peer can handle over the next hour?
    275326     *
    276327     */
    277     public double getCapacityValue() { return _capacityValue; }
     328    public float getCapacityValue() { return _capacityValue; }
    278329    /**
    279330     * How well integrated into the network is this peer (as measured by how much they've
     
    281332     *
    282333     */
    283     public double getIntegrationValue() { return _integrationValue; }
     334    public float getIntegrationValue() { return _integrationValue; }
    284335    /**
    285336     * is this peer actively failing (aka not worth touching)?
     
    288339    public boolean getIsFailing() { return _isFailing; }
    289340
    290     public double getTunnelTestTimeAverage() { return _tunnelTestResponseTimeAvg; }
    291     void setTunnelTestTimeAverage(double avg) { _tunnelTestResponseTimeAvg = avg; }
     341    public float getTunnelTestTimeAverage() { return _tunnelTestResponseTimeAvg; }
     342    void setTunnelTestTimeAverage(float avg) { _tunnelTestResponseTimeAvg = avg; }
    292343   
    293344    void updateTunnelTestTimeAverage(long ms) {
     
    297348        // weighted since we want to let the average grow quickly and shrink slowly
    298349        if (ms < _tunnelTestResponseTimeAvg)
    299             _tunnelTestResponseTimeAvg = 0.95*_tunnelTestResponseTimeAvg + .05*ms;
     350            _tunnelTestResponseTimeAvg = 0.95f * _tunnelTestResponseTimeAvg + .05f * ms;
    300351        else
    301             _tunnelTestResponseTimeAvg = 0.75*_tunnelTestResponseTimeAvg + .25*ms;
     352            _tunnelTestResponseTimeAvg = 0.75f * _tunnelTestResponseTimeAvg + .25f * ms;
    302353       
    303354        if (_log.shouldLog(Log.INFO))
     
    306357    }
    307358
    308     /** keep track of the fastest 3 throughputs */
    309     private static final int THROUGHPUT_COUNT = 3;
    310     /**
    311      * fastest 1 minute throughput, in bytes per minute, ordered with fastest
    312      * first.  this is not synchronized, as we don't *need* perfection, and we only
    313      * reorder/insert values on coallesce
    314      */
    315     private final double _peakThroughput[] = new double[THROUGHPUT_COUNT];
    316     private volatile long _peakThroughputCurrentTotal;
    317     public double getPeakThroughputKBps() {
    318         double rv = 0;
     359    public float getPeakThroughputKBps() {
     360        float rv = 0;
    319361        for (int i = 0; i < THROUGHPUT_COUNT; i++)
    320362            rv += _peakThroughput[i];
    321         rv /= (60d*1024d*THROUGHPUT_COUNT);
     363        rv /= (60 * 1024 * THROUGHPUT_COUNT);
    322364        return rv;
    323365    }
    324     public void setPeakThroughputKBps(double kBps) {
     366    public void setPeakThroughputKBps(float kBps) {
    325367        _peakThroughput[0] = kBps*60*1024;
    326368        //for (int i = 0; i < THROUGHPUT_COUNT; i++)
     
    329371    void dataPushed(int size) { _peakThroughputCurrentTotal += size; }
    330372   
    331     private final double _peakTunnelThroughput[] = new double[THROUGHPUT_COUNT];
    332373    /** the tunnel pushed that much data in its lifetime */
    333374    void tunnelDataTransferred(long tunnelByteLifetime) {
    334         double lowPeak = _peakTunnelThroughput[THROUGHPUT_COUNT-1];
     375        float lowPeak = _peakTunnelThroughput[THROUGHPUT_COUNT-1];
    335376        if (tunnelByteLifetime > lowPeak) {
    336377            synchronized (_peakTunnelThroughput) {
     
    346387        }
    347388    }
    348     public double getPeakTunnelThroughputKBps() {
    349         double rv = 0;
     389    public float getPeakTunnelThroughputKBps() {
     390        float rv = 0;
    350391        for (int i = 0; i < THROUGHPUT_COUNT; i++)
    351392            rv += _peakTunnelThroughput[i];
    352         rv /= (10d*60d*1024d*THROUGHPUT_COUNT);
     393        rv /= (10 * 60 * 1024 * THROUGHPUT_COUNT);
    353394        return rv;
    354395    }
    355     public void setPeakTunnelThroughputKBps(double kBps) {
    356         _peakTunnelThroughput[0] = kBps*60d*10d*1024d;
    357     }
    358    
    359     /** total number of bytes pushed through a single tunnel in a 1 minute period */
    360     private final double _peakTunnel1mThroughput[] = new double[THROUGHPUT_COUNT];
     396    public void setPeakTunnelThroughputKBps(float kBps) {
     397        _peakTunnelThroughput[0] = kBps * (60 * 10 * 1024);
     398    }
     399   
    361400    /** the tunnel pushed that much data in a 1 minute period */
    362401    void dataPushed1m(int size) {
    363         double lowPeak = _peakTunnel1mThroughput[THROUGHPUT_COUNT-1];
     402        float lowPeak = _peakTunnel1mThroughput[THROUGHPUT_COUNT-1];
    364403        if (size > lowPeak) {
    365404            synchronized (_peakTunnel1mThroughput) {
     
    389428     *         once a day by coalesceThroughput(). This seems way too seldom.
    390429     */
    391     public double getPeakTunnel1mThroughputKBps() {
    392         double rv = 0;
     430    public float getPeakTunnel1mThroughputKBps() {
     431        float rv = 0;
    393432        for (int i = 0; i < THROUGHPUT_COUNT; i++)
    394433            rv += _peakTunnel1mThroughput[i];
    395         rv /= (60d*1024d*THROUGHPUT_COUNT);
     434        rv /= (60 * 1024 * THROUGHPUT_COUNT);
    396435        return rv;
    397436    }
    398     public void setPeakTunnel1mThroughputKBps(double kBps) {
     437    public void setPeakTunnel1mThroughputKBps(float kBps) {
    399438        _peakTunnel1mThroughput[0] = kBps*60*1024;
    400439    }
     
    430469     *
    431470     */
    432     public void expandProfile() {
     471    public synchronized void expandProfile() {
    433472        String group = (null == _peer ? "profileUnknown" : _peer.toBase64().substring(0,6));
    434473        //if (_sendSuccessSize == null)
     
    469508    }
    470509
    471     /** once a day, on average, cut the measured throughtput values in half */
    472     /** let's try once an hour times 3/4 */
    473     private static final int DROP_PERIOD_MINUTES = 60;
    474     private static final double DEGRADE_FACTOR = 0.75;
    475     private long _lastCoalesceDate = System.currentTimeMillis();
    476510    private void coalesceThroughput() {
    477511        long now = System.currentTimeMillis();
     
    479513        if (measuredPeriod >= 60*1000) {
    480514            long tot = _peakThroughputCurrentTotal;
    481             double lowPeak = _peakThroughput[THROUGHPUT_COUNT-1];
     515            float lowPeak = _peakThroughput[THROUGHPUT_COUNT-1];
    482516            if (tot > lowPeak) {
    483517                for (int i = 0; i < THROUGHPUT_COUNT; i++) {
     
    563597    }
    564598   
    565     private double calculateSpeed() { return SpeedCalculator.calc(this); }
    566     private double calculateCapacity() { return CapacityCalculator.calc(this); }
    567     private double calculateIntegration() { return IntegrationCalculator.calc(this); }
     599    private float calculateSpeed() { return (float) SpeedCalculator.calc(this); }
     600    private float calculateCapacity() { return (float) CapacityCalculator.calc(this); }
     601    private float calculateIntegration() { return (float) IntegrationCalculator.calc(this); }
    568602    /** deprecated - unused - always false */
    569603    private boolean calculateIsFailing() { return false; }
  • router/java/src/net/i2p/router/peermanager/ProfileManagerImpl.java

    r9bb1a00 r07e85e0  
    223223        if (!data.getIsExpandedDB())
    224224            return;
    225         DBHistory hist = data.getDBHistory();
    226         hist.lookupReceived();
     225        //DBHistory hist = data.getDBHistory();
     226        //hist.lookupReceived();
    227227    }
    228228   
     
    314314        PeerProfile data = getProfile(peer);
    315315        //if (data == null) return;
    316         if (when > data.getLastHeardAbout())
    317             data.setLastHeardAbout(when);
     316        data.setLastHeardAbout(when);
    318317    }
    319318   
     
    341340        if (prof == null) {
    342341            prof = new PeerProfile(_context, peer);
    343             prof.setFirstHeardAbout(_context.clock().now());
    344342            _context.profileOrganizer().addProfile(prof);
    345343        }
  • router/java/src/net/i2p/router/peermanager/ProfileOrganizer.java

    r9bb1a00 r07e85e0  
    1818import java.util.concurrent.locks.ReentrantReadWriteLock;
    1919
    20 import net.i2p.crypto.SHA256Generator;
     20import net.i2p.data.DataHelper;
    2121import net.i2p.data.Hash;
    2222import net.i2p.data.router.RouterAddress;
     
    12351235
    12361236    /**
     1237      *
     1238      * As of 0.9.24, checks for a netdb family match as well, unless mask == 0.
     1239      *
    12371240     * @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
    12381241     *             not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
     
    12401243    private void locked_selectPeers(Map<Hash, PeerProfile> peers, int howMany, Set<Hash> toExclude, Set<Hash> matches, int mask) {
    12411244        List<Hash> all = new ArrayList<Hash>(peers.keySet());
    1242         Set<Integer> IPSet = new HashSet<Integer>(8);
     1245        Set<String> IPSet = new HashSet<String>(8);
    12431246        // use RandomIterator to avoid shuffling the whole thing
    12441247        for (Iterator<Hash> iter = new RandomIterator<Hash>(all); (matches.size() < howMany) && iter.hasNext(); ) {
     
    12661269     * Does the peer's IP address NOT match the IP address of any peer already in the set,
    12671270     * on any transport, within a given mask?
     1271     *
     1272     * As of 0.9.24, checks for a netdb family match as well.
     1273     *
    12681274     * @param mask is 1-4 (number of bytes to match)
    12691275     * @param IPMatches all IPs so far, modified by this routine
    12701276     */
    1271     private boolean notRestricted(Hash peer, Set<Integer> IPSet, int mask) {
    1272         Set<Integer> peerIPs = maskedIPSet(peer, mask);
     1277    private boolean notRestricted(Hash peer, Set<String> IPSet, int mask) {
     1278        Set<String> peerIPs = maskedIPSet(peer, mask);
    12731279        if (containsAny(IPSet, peerIPs))
    12741280            return false;
     
    12811287      * Includes the comm system's record of the IP, and all netDb addresses.
    12821288      *
     1289      * As of 0.9.24, returned set will include netdb family as well.
     1290      *
    12831291      * @return an opaque set of masked IPs for this peer
    12841292      */
    1285     private Set<Integer> maskedIPSet(Hash peer, int mask) {
    1286         Set<Integer> rv = new HashSet<Integer>(4);
     1293    private Set<String> maskedIPSet(Hash peer, int mask) {
     1294        Set<String> rv = new HashSet<String>(4);
    12871295        byte[] commIP = _context.commSystem().getIP(peer);
    12881296        if (commIP != null)
     
    12971305            rv.add(maskedIP(pib, mask));
    12981306        }
     1307        String family = pinfo.getOption("family");
     1308        if (family != null) {
     1309            // TODO should KNDF put a family-verified indicator in the RI,
     1310            // after checking the sig, or does it matter?
     1311            // What's the threat here of not avoid ding a router
     1312            // falsely claiming to be in the family?
     1313            // Prefix with something so an IP can't be spoofed
     1314            rv.add('x' + family);
     1315        }
    12991316        return rv;
    13001317    }
     
    13021319    /**
    13031320     * generate an arbitrary unique value for this ip/mask (mask = 1-4)
    1304      * If IPv6, force mask = 8.
    1305      */
    1306     private static Integer maskedIP(byte[] ip, int mask) {
    1307         int rv = ip[0];
     1321     * If IPv6, force mask = 6.
     1322     */
     1323    private static String maskedIP(byte[] ip, int mask) {
     1324        final StringBuilder buf = new StringBuilder(1 + (mask*2));
     1325        final char delim;
    13081326        if (ip.length == 16) {
    1309             for (int i = 1; i < 8; i++) {
    1310                 rv <<= i * 4;
    1311                 rv ^= ip[i];
    1312             }
     1327            mask = 6;
     1328            delim = ':';
    13131329        } else {
    1314             for (int i = 1; i < mask; i++) {
    1315                 rv <<= 8;
    1316                 rv ^= ip[i];
    1317             }
    1318         }
    1319         return Integer.valueOf(rv);
     1330            delim = '.';
     1331        }
     1332        buf.append(delim);
     1333        buf.append(Long.toHexString(DataHelper.fromLong(ip, 0, mask)));
     1334        return buf.toString();
    13201335    }
    13211336
    13221337    /** does a contain any of the elements in b? */
    13231338    private static <T> boolean  containsAny(Set<T> a, Set<T> b) {
     1339        if (a.isEmpty() || b.isEmpty())
     1340            return false;
    13241341        for (T o : b) {
    13251342            if (a.contains(o))
  • router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java

    r9bb1a00 r07e85e0  
    4949   
    5050    /**
    51      * If we haven't been able to get a message through to the peer in 3 days,
     51     * If we haven't been able to get a message through to the peer in this much time,
    5252     * drop the profile.  They may reappear, but if they do, their config may
    5353     * have changed (etc).
    5454     *
    5555     */
    56     private static final long EXPIRE_AGE = 3*24*60*60*1000;
     56    private static final long EXPIRE_AGE = 15*24*60*60*1000;
    5757   
    5858    private final File _profileDir;
     
    171171   
    172172    /** @since 0.8.5 */
    173     private static void add(StringBuilder buf, String name, double val, String description) {
     173    private static void add(StringBuilder buf, String name, float val, String description) {
    174174        buf.append("# ").append(name).append(NL).append("# ").append(description).append(NL);
    175175        buf.append(name).append('=').append(val).append(NL).append(NL);
     
    264264            }
    265265           
    266             profile.setCapacityBonus(getLong(props, "capacityBonus"));
    267             profile.setIntegrationBonus(getLong(props, "integrationBonus"));
    268             profile.setSpeedBonus(getLong(props, "speedBonus"));
     266            profile.setCapacityBonus((int) getLong(props, "capacityBonus"));
     267            profile.setIntegrationBonus((int) getLong(props, "integrationBonus"));
     268            profile.setSpeedBonus((int) getLong(props, "speedBonus"));
    269269           
    270270            profile.setLastHeardAbout(getLong(props, "lastHeardAbout"));
     
    273273            profile.setLastSendFailed(getLong(props, "lastFailedSend"));
    274274            profile.setLastHeardFrom(getLong(props, "lastHeardFrom"));
    275             profile.setTunnelTestTimeAverage(getDouble(props, "tunnelTestTimeAverage"));
    276             profile.setPeakThroughputKBps(getDouble(props, "tunnelPeakThroughput"));
    277             profile.setPeakTunnelThroughputKBps(getDouble(props, "tunnelPeakTunnelThroughput"));
    278             profile.setPeakTunnel1mThroughputKBps(getDouble(props, "tunnelPeakTunnel1mThroughput"));
     275            profile.setTunnelTestTimeAverage(getFloat(props, "tunnelTestTimeAverage"));
     276            profile.setPeakThroughputKBps(getFloat(props, "tunnelPeakThroughput"));
     277            profile.setPeakTunnelThroughputKBps(getFloat(props, "tunnelPeakTunnelThroughput"));
     278            profile.setPeakTunnel1mThroughputKBps(getFloat(props, "tunnelPeakTunnel1mThroughput"));
    279279           
    280280            profile.getTunnelHistory().load(props);
     
    283283            // don't load the DB info at all unless there is something interesting there
    284284            // (i.e. floodfills)
    285             // It seems like we do one or two lookups as a part of handshaking?
    286             // Not sure, to be researched.
    287             if (getLong(props, "dbHistory.successfulLookups") > 1 ||
    288                 getLong(props, "dbHistory.failedlLokups") > 1) {
     285            if (getLong(props, "dbHistory.lastLookupSuccessful") > 0 ||
     286                getLong(props, "dbHistory.lastLookupFailed") > 0 ||
     287                getLong(props, "dbHistory.lastStoreSuccessful") > 0 ||
     288                getLong(props, "dbHistory.lastStoreFailed") > 0) {
    289289                profile.expandDBProfile();
    290290                profile.getDBHistory().load(props);
     
    301301                _log.debug("Loaded the profile for " + peer.toBase64() + " from " + file.getName());
    302302           
     303            fixupFirstHeardAbout(profile);
    303304            return profile;
    304305        } catch (IOException e) {
     
    309310        }
    310311    }
    311    
    312     private final static long getLong(Properties props, String key) {
     312
     313    /**
     314     *  First heard about wasn't always set correctly before,
     315     *  set it to the minimum of all recorded timestamps.
     316     *
     317     *  @since 0.9.24
     318     */
     319    private void fixupFirstHeardAbout(PeerProfile p) {
     320        long min = Long.MAX_VALUE;
     321        long t = p.getLastHeardAbout();
     322        if (t > 0 && t < min) min = t;
     323        t = p.getLastSendSuccessful();
     324        if (t > 0 && t < min) min = t;
     325        t = p.getLastSendFailed();
     326        if (t > 0 && t < min) min = t;
     327        t = p.getLastHeardFrom();
     328        if (t > 0 && t < min) min = t;
     329        // the first was never used and the last 4 were never persisted
     330        //DBHistory dh = p.getDBHistory();
     331        //if (dh != null) {
     332        //    t = dh.getLastLookupReceived();
     333        //    if (t > 0 && t < min) min = t;
     334        //    t = dh.getLastLookupSuccessful();
     335        //    if (t > 0 && t < min) min = t;
     336        //    t = dh.getLastLookupFailed();
     337        //    if (t > 0 && t < min) min = t;
     338        //    t = dh.getLastStoreSuccessful();
     339        //    if (t > 0 && t < min) min = t;
     340        //    t = dh.getLastStoreFailed();
     341        //    if (t > 0 && t < min) min = t;
     342        //}
     343        TunnelHistory th = p.getTunnelHistory();
     344        if (th != null) {
     345            t = th.getLastAgreedTo();
     346            if (t > 0 && t < min) min = t;
     347            t = th.getLastRejectedCritical();
     348            if (t > 0 && t < min) min = t;
     349            t = th.getLastRejectedBandwidth();
     350            if (t > 0 && t < min) min = t;
     351            t = th.getLastRejectedTransient();
     352            if (t > 0 && t < min) min = t;
     353            t = th.getLastRejectedProbabalistic();
     354            if (t > 0 && t < min) min = t;
     355            t = th.getLastFailed();
     356            if (t > 0 && t < min) min = t;
     357        }
     358        long fha = p.getFirstHeardAbout();
     359        if (min > 0 && min < Long.MAX_VALUE && (fha <= 0 || min < fha)) {
     360            p.setFirstHeardAbout(min);
     361            if (_log.shouldDebug())
     362                _log.debug("Fixed up the FHA time for " + p.getPeer().toBase64() + " to " + (new Date(min)));
     363        }
     364    }
     365   
     366    static long getLong(Properties props, String key) {
    313367        String val = props.getProperty(key);
    314368        if (val != null) {
    315369            try {
    316370                return Long.parseLong(val);
    317             } catch (NumberFormatException nfe) {
    318                 return 0;
    319             }
     371            } catch (NumberFormatException nfe) {}
    320372        }
    321373        return 0;
    322374    }
    323375
    324     private final static double getDouble(Properties props, String key) {
     376    private final static float getFloat(Properties props, String key) {
    325377        String val = props.getProperty(key);
    326378        if (val != null) {
    327379            try {
    328                 return Double.parseDouble(val);
    329             } catch (NumberFormatException nfe) {
    330                 return 0.0;
    331             }
    332         }
    333         return 0.0;
     380                return Float.parseFloat(val);
     381            } catch (NumberFormatException nfe) {}
     382        }
     383        return 0.0f;
    334384    }
    335385   
  • router/java/src/net/i2p/router/peermanager/TunnelHistory.java

    r9bb1a00 r07e85e0  
    9090        if (severity >= TUNNEL_REJECT_CRIT) {
    9191            _lastRejectedCritical = _context.clock().now();
    92             _rejectRate.addData(1, 1);
     92            _rejectRate.addData(1);
    9393        } else if (severity >= TUNNEL_REJECT_BANDWIDTH) {
    9494            _lastRejectedBandwidth = _context.clock().now();
    95             _rejectRate.addData(1, 1);
     95            _rejectRate.addData(1);
    9696        } else if (severity >= TUNNEL_REJECT_TRANSIENT_OVERLOAD) {
    9797            _lastRejectedTransient = _context.clock().now();
     
    109109    public void incrementFailed(int pct) {
    110110        _lifetimeFailed.incrementAndGet();
    111         _failRate.addData(pct, 1);
     111        _failRate.addData(pct);
    112112        _lastFailed = _context.clock().now();
    113113    }
     
    191191   
    192192    private final static long getLong(Properties props, String key) {
    193         String val = props.getProperty(key);
    194         if (val != null) {
    195             try {
    196                 return Long.parseLong(val);
    197             } catch (NumberFormatException nfe) {
    198                 return 0;
    199             }
    200         }
    201         return 0;
     193        return ProfilePersistenceHelper.getLong(props, key);
    202194    }
    203195}
  • router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java

    r9bb1a00 r07e85e0  
    9999        try {
    100100            info.setAddresses(getContext().commSystem().createAddresses());
    101             Properties stats = getContext().statPublisher().publishStatistics();
    102             stats.setProperty(RouterInfo.PROP_NETWORK_ID, Router.NETWORK_ID+"");
    103             getContext().router().addCapabilities(info);
    104             info.setOptions(stats);
    105101            // not necessary, in constructor
    106102            //info.setPeers(new HashSet());
     
    127123            }
    128124            info.setIdentity(ident);
     125            Properties stats = getContext().statPublisher().publishStatistics(ident.getHash());
     126            info.setOptions(stats);
    129127           
    130128            info.sign(signingPrivKey);
  • router/java/src/net/i2p/router/startup/LoadClientAppsJob.java

    r9bb1a00 r07e85e0  
    124124                switch (data[i]) {
    125125                    case '\'':
    126                     case '\"':
     126                    case '"':
    127127                        if (isQuoted) {
    128128                            String str = buf.toString().trim();
  • router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java

    r9bb1a00 r07e85e0  
    3232import net.i2p.router.Router;
    3333import net.i2p.router.RouterContext;
     34import net.i2p.router.crypto.FamilyKeyCrypto;
    3435import net.i2p.router.networkdb.kademlia.PersistentDataStore;
    3536import net.i2p.util.Log;
     
    99100                if (_log.shouldLog(Log.DEBUG))
    100101                    _log.debug("Reading in routerInfo from " + rif.getAbsolutePath() + " and it has " + info.getAddresses().size() + " addresses");
    101                 _us = info;
     102                // don't reuse if family name changed
     103                if (DataHelper.eq(info.getOption(FamilyKeyCrypto.OPT_NAME),
     104                                  getContext().getProperty(FamilyKeyCrypto.PROP_FAMILY_NAME))) {
     105                    _us = info;
     106                } else {
     107                    _log.logAlways(Log.WARN, "NetDb family name changed");
     108                }
    102109            }
    103110           
     
    115122                if (sigTypeChanged && getContext().getProperty(CreateRouterInfoJob.PROP_ROUTER_SIGTYPE) == null) {
    116123                    // Not explicitly configured, and default has changed
    117                     // Give a 15% chance of rekeying for each restart
     124                    // Give a 25% chance of rekeying for each restart
    118125                    // TODO reduce to ~3 (i.e. increase probability) in future release
    119                     if (getContext().random().nextInt(7) > 0) {
     126                    if (getContext().random().nextInt(4) > 0) {
    120127                        sigTypeChanged = false;
    121128                        if (_log.shouldWarn())
  • router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java

    r9bb1a00 r07e85e0  
    119119            try {
    120120                info.setAddresses(getContext().commSystem().createAddresses());
    121                 Properties stats = getContext().statPublisher().publishStatistics();
    122                 stats.setProperty(RouterInfo.PROP_NETWORK_ID, ""+Router.NETWORK_ID);
     121                Properties stats = getContext().statPublisher().publishStatistics(info.getHash());
    123122                info.setOptions(stats);
    124                 getContext().router().addCapabilities(info);
    125123                // info.setPeers(new HashSet()); // this would have the trusted peers
    126124                info.setPublished(CreateRouterInfoJob.getCurrentPublishDate(getContext()));
  • router/java/src/net/i2p/router/startup/StartupJob.java

    r9bb1a00 r07e85e0  
    3737        if (!SystemVersion.isAndroid())
    3838            getContext().jobQueue().addJob(new LoadClientAppsJob(getContext()));
    39         getContext().statPublisher().startup();
    4039        getContext().jobQueue().addJob(new LoadRouterInfoJob(getContext()));
    4140    }
  • router/java/src/net/i2p/router/time/RouterTimestamper.java

    r9bb1a00 r07e85e0  
    4646    private static final int DEFAULT_TIMEOUT = 10*1000;
    4747    private static final int SHORT_TIMEOUT = 5*1000;
     48    private static final long MAX_WAIT_INITIALIZATION = 45*1000;
    4849   
    4950    public static final String PROP_QUERY_FREQUENCY = "time.queryFrequencyMs";
     
    142143            synchronized (this) {
    143144                if (!_initialized)
    144                     wait();
     145                    wait(MAX_WAIT_INITIALIZATION);
    145146            }
    146147        } catch (InterruptedException ie) {}
  • router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java

    r9bb1a00 r07e85e0  
    156156   
    157157    @Override
    158     public boolean isBacklogged(Hash dest) {
    159         return _manager.isBacklogged(dest);
    160     }
    161    
    162     @Override
    163     public boolean isEstablished(Hash dest) {
    164         return _manager.isEstablished(dest);
    165     }
    166    
    167     @Override
    168     public boolean wasUnreachable(Hash dest) {
    169         return _manager.wasUnreachable(dest);
    170     }
    171    
    172     @Override
    173     public byte[] getIP(Hash dest) {
    174         return _manager.getIP(dest);
     158    public boolean isBacklogged(Hash peer) {
     159        return _manager.isBacklogged(peer);
     160    }
     161   
     162    @Override
     163    public boolean isEstablished(Hash peer) {
     164        return _manager.isEstablished(peer);
     165    }
     166   
     167    @Override
     168    public boolean wasUnreachable(Hash peer) {
     169        return _manager.wasUnreachable(peer);
     170    }
     171   
     172    @Override
     173    public byte[] getIP(Hash peer) {
     174        return _manager.getIP(peer);
     175    }
     176   
     177    /**
     178     * Tell the comm system that we may disconnect from this peer.
     179     * This is advisory only.
     180     *
     181     * @since 0.9.24
     182     */
     183    @Override
     184    public void mayDisconnect(Hash peer) {
     185        _manager.mayDisconnect(peer);
    175186    }
    176187   
     
    197208     */
    198209    @Override
     210    @Deprecated
    199211    public void recheckReachability() { _manager.recheckReachability(); }
    200212
  • router/java/src/net/i2p/router/transport/OutboundMessageRegistry.java

    r9bb1a00 r07e85e0  
    259259   
    260260    private class CleanupTask extends SimpleTimer2.TimedEvent {
     261        /** LOCKING: _selectors */
    261262        private long _nextExpire;
    262263
     
    326327            if (log) {
    327328                int e = removing.size();
    328                 int r = _selectors.size();
     329                int r;
     330                synchronized(_selectors) {
     331                    r = _selectors.size();
     332                }
    329333                int a = _activeMessages.size();
    330334                if (r > 0 || e > 0 || a > 0)
    331335                    _log.debug("Expired: " + e + " remaining: " + r + " active: " + a);
    332336            }
    333             synchronized(this) {
     337            synchronized(_selectors) {
    334338                if (_nextExpire <= now)
    335339                    _nextExpire = now + 10*1000;
     
    338342        }
    339343
    340         public synchronized void scheduleExpiration(MessageSelector sel) {
     344        public void scheduleExpiration(MessageSelector sel) {
    341345            long now = _context.clock().now();
    342             if ( (_nextExpire <= now) || (sel.getExpiration() < _nextExpire) ) {
    343                 _nextExpire = sel.getExpiration();
    344                 reschedule(_nextExpire - now);
     346            synchronized(_selectors) {
     347                if ( (_nextExpire <= now) || (sel.getExpiration() < _nextExpire) ) {
     348                    _nextExpire = sel.getExpiration();
     349                    reschedule(_nextExpire - now);
     350                }
    345351            }
    346352        }
  • router/java/src/net/i2p/router/transport/Transport.java

    r9bb1a00 r07e85e0  
    172172    public boolean isUnreachable(Hash peer);
    173173    public boolean isEstablished(Hash peer);
     174
     175    /**
     176     * Tell the transport that we may disconnect from this peer.
     177     * This is advisory only.
     178     *
     179     * @since 0.9.24
     180     */
     181    public void mayDisconnect(Hash peer);
    174182}
  • router/java/src/net/i2p/router/transport/TransportImpl.java

    r9bb1a00 r07e85e0  
    142142            maxProp = "i2np." + style.toLowerCase(Locale.US) + ".maxConnections";
    143143        int def = MAX_CONNECTION_FACTOR;
    144         RouterInfo ri = _context.router().getRouterInfo();
    145         if (ri != null) {
    146             char bw = ri.getBandwidthTier().charAt(0);
     144        // get it from here, not the RI, to avoid deadlock
     145        String caps = _context.router().getCapabilities();
     146
     147            char bw = caps.charAt(0);
    147148            switch (bw) {
    148149                case Router.CAPABILITY_BW12:
     
    169170                    break;
    170171            }
    171         }
     172
    172173        if (_context.netDb().floodfillEnabled()) {
    173174            // && !SystemVersion.isWindows()) {
     
    748749     *  or after the transport is running.
    749750     *
    750      *  This implementation does nothing. Transports should override if they want notification.
    751      *
    752751     *  @param source defined in Transport.java
    753752     *  @param ip typ. IPv4 or IPv6 non-local; may be null to indicate IPv4 failure or port info only
    754753     *  @param port 0 for unknown or unchanged
    755754     */
    756     public void externalAddressReceived(AddressSource source, byte[] ip, int port) {}
     755    public abstract void externalAddressReceived(AddressSource source, byte[] ip, int port);
    757756
    758757    /**
     
    811810     * @deprecated unused
    812811     */
     812    @Deprecated
    813813    public void recheckReachability() {}
    814814
     
    820820    }
    821821
    822     public boolean isBacklogged(Hash dest) { return false; }
    823     public boolean isEstablished(Hash dest) { return false; }
     822    public boolean isBacklogged(Hash peer) { return false; }
     823    public boolean isEstablished(Hash peer) { return false; }
     824
     825    /**
     826     * Tell the transport that we may disconnect from this peer.
     827     * This is advisory only.
     828     *
     829     * @since 0.9.24
     830     */
     831    public void mayDisconnect(Hash peer) {}
    824832
    825833    public boolean isUnreachable(Hash peer) {
  • router/java/src/net/i2p/router/transport/TransportManager.java

    r9bb1a00 r07e85e0  
    408408     * @deprecated unused
    409409     */
     410    @Deprecated
    410411    public void recheckReachability() {
    411412        for (Transport t : _transports.values())
     
    413414    }
    414415
    415     public boolean isBacklogged(Hash dest) {
    416         for (Transport t : _transports.values()) {
    417             if (t.isBacklogged(dest))
     416    public boolean isBacklogged(Hash peer) {
     417        for (Transport t : _transports.values()) {
     418            if (t.isBacklogged(peer))
    418419                return true;
    419420        }
     
    421422    }   
    422423   
    423     public boolean isEstablished(Hash dest) {
    424         for (Transport t : _transports.values()) {
    425             if (t.isEstablished(dest))
     424    public boolean isEstablished(Hash peer) {
     425        for (Transport t : _transports.values()) {
     426            if (t.isEstablished(peer))
    426427                return true;
    427428        }
    428429        return false;
    429430    }   
     431   
     432    /**
     433     * Tell the transports that we may disconnect from this peer.
     434     * This is advisory only.
     435     *
     436     * @since 0.9.24
     437     */
     438    public void mayDisconnect(Hash peer) {
     439        for (Transport t : _transports.values()) {
     440             t.mayDisconnect(peer);
     441        }
     442    }
    430443   
    431444    /**
     
    434447     * This is NOT reset if the peer contacts us.
    435448     */
    436     public boolean wasUnreachable(Hash dest) {
    437         for (Transport t : _transports.values()) {
    438             if (!t.wasUnreachable(dest))
     449    public boolean wasUnreachable(Hash peer) {
     450        for (Transport t : _transports.values()) {
     451            if (!t.wasUnreachable(peer))
    439452                return false;
    440453        }
     
    453466     * @return IPv4 or IPv6 or null
    454467     */
    455     public byte[] getIP(Hash dest) {
    456         return TransportImpl.getIP(dest);
     468    public byte[] getIP(Hash peer) {
     469        return TransportImpl.getIP(peer);
    457470    }   
    458471   
     
    746759                   "<b id=\"def.rto\">RTO</b>: ").append(_t("The retransmit timeout in milliseconds")).append("<br>\n" +
    747760                   "<b id=\"def.mtu\">MTU</b>: ").append(_t("Current maximum send packet size / estimated maximum receive packet size (bytes)")).append("<br>\n" +
    748                    "<b id=\"def.send\">").append(_t("TX")).append("</b>: ").append(_t("The total number of packets sent to the peer")).append("<br>\n" +
    749                    "<b id=\"def.recv\">").append(_t("RX")).append("</b>: ").append(_t("The total number of packets received from the peer")).append("<br>\n" +
     761                   "<b id=\"def.send\">").append(_t("TX")).append("</b>: ").append(_t("The total number of messages sent to the peer")).append("<br>\n" +
     762                   "<b id=\"def.recv\">").append(_t("RX")).append("</b>: ").append(_t("The total number of messages received from the peer")).append("<br>\n" +
    750763                   "<b id=\"def.resent\">").append(_t("Dup TX")).append("</b>: ").append(_t("The total number of packets retransmitted to the peer")).append("<br>\n" +
    751764                   "<b id=\"def.dupRecv\">").append(_t("Dup RX")).append("</b>: ").append(_t("The total number of duplicate packets received from the peer")).append("</p>" +
  • router/java/src/net/i2p/router/transport/TransportUtil.java

    r9bb1a00 r07e85e0  
    9999    public static boolean isIPv6(RouterAddress addr) {
    100100        // do this the fast way, without calling getIP() to parse the host string
    101         String host = addr.getOption(RouterAddress.PROP_HOST);
     101        String host = addr.getHost();
    102102        return host != null && host.contains(":");
    103103    }
  • router/java/src/net/i2p/router/transport/crypto/DHSessionKeyBuilder.java

    r9bb1a00 r07e85e0  
    506506                        long curCalc = System.currentTimeMillis() - curStart;
    507507                        // for some relief...
    508                         try {
    509                             Thread.sleep(Math.min(200, Math.max(10, _calcDelay + (curCalc * 3))));
    510                         } catch (InterruptedException ie) { // nop
     508                        if (!interrupted()) {
     509                            try {
     510                                Thread.sleep(Math.min(200, Math.max(10, _calcDelay + (curCalc * 3))));
     511                            } catch (InterruptedException ie) {}
    511512                        }
    512513                    }
     
    542543                _context.statManager().addRateData("crypto.DHEmpty", 1);
    543544                builder = precalc();
     545                // stop sleeping, wake up, make some more
     546                this.interrupt();
    544547            }
    545548            return builder;
  • router/java/src/net/i2p/router/transport/ntcp/EventPumper.java

    r9bb1a00 r07e85e0  
    8686    private static final long MIN_EXPIRE_IDLE_TIME = 120*1000l;
    8787    private static final long MAX_EXPIRE_IDLE_TIME = 11*60*1000l;
     88    private static final long MAY_DISCON_TIMEOUT = 10*1000;
    8889
    8990    /**
     
    222223
    223224                        // Increase allowed idle time if we are well under allowed connections, otherwise decrease
    224                         if (_transport.haveCapacity(33))
     225                        boolean haveCap = _transport.haveCapacity(33);
     226                        if (haveCap)
    225227                            _expireIdleWriteTime = Math.min(_expireIdleWriteTime + 1000, MAX_EXPIRE_IDLE_TIME);
    226228                        else
     
    271273                                }
    272274                               
    273                                 if ( con.getTimeSinceSend() > _expireIdleWriteTime &&
    274                                      con.getTimeSinceReceive() > _expireIdleWriteTime) {
     275                                final long expire;
     276                                if (!haveCap && con.getMayDisconnect() &&
     277                                    con.getMessagesReceived() <= 2 && con.getMessagesSent() <= 1) {
     278                                    expire = MAY_DISCON_TIMEOUT;
     279                                } else {
     280                                    expire = _expireIdleWriteTime;
     281                                }
     282
     283                                if ( con.getTimeSinceSend() > expire &&
     284                                     con.getTimeSinceReceive() > expire) {
    275285                                    // we haven't sent or received anything in a really long time, so lets just close 'er up
    276286                                    con.close();
  • router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java

    r9bb1a00 r07e85e0  
    1414import java.util.concurrent.LinkedBlockingQueue;
    1515import java.util.concurrent.atomic.AtomicBoolean;
     16import java.util.concurrent.atomic.AtomicInteger;
    1617import java.util.concurrent.atomic.AtomicLong;
    1718import java.util.zip.Adler32;
     
    116117    /** current partially read I2NP message */
    117118    private final ReadState _curReadState;
    118     private final AtomicLong _messagesRead = new AtomicLong();
    119     private final AtomicLong _messagesWritten = new AtomicLong();
     119    private final AtomicInteger _messagesRead = new AtomicInteger();
     120    private final AtomicInteger _messagesWritten = new AtomicInteger();
    120121    private long _lastSendTime;
    121122    private long _lastReceiveTime;
     
    135136    //private int _consecutiveBacklog;
    136137    private long _nextInfoTime;
     138    private boolean _mayDisconnect;
    137139   
    138140    /*
     
    326328    }
    327329
    328     public long getMessagesSent() { return _messagesWritten.get(); }
    329 
    330     public long getMessagesReceived() { return _messagesRead.get(); }
    331 
    332     public long getOutboundQueueSize() {
     330    public int getMessagesSent() { return _messagesWritten.get(); }
     331
     332    public int getMessagesReceived() { return _messagesRead.get(); }
     333
     334    public int getOutboundQueueSize() {
    333335            int queued;
    334336            synchronized(_outbound) {
     
    360362     */
    361363    public long getCreated() { return _created; }
     364
     365    /**
     366     * Sets to true.
     367     * @since 0.9.24
     368     */
     369    public void setMayDisconnect() { _mayDisconnect = true; }
     370
     371    /**
     372     * @since 0.9.24
     373     */
     374    public boolean getMayDisconnect() { return _mayDisconnect; }
    362375
    363376    /**
  • router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java

    r9bb1a00 r07e85e0  
    488488
    489489    /**
     490     * Tell the transport that we may disconnect from this peer.
     491     * This is advisory only.
     492     *
     493     * @since 0.9.24
     494     */
     495    @Override
     496    public void mayDisconnect(final Hash peer) {
     497        final NTCPConnection con = _conByIdent.get(peer);
     498        if (con != null && con.isEstablished() && con.isInbound() &&
     499            con.getMessagesReceived() <= 2 && con.getMessagesSent() <= 1) {
     500            con.setMayDisconnect();
     501        }
     502    }
     503
     504    /**
    490505     * @return usually the con passed in, but possibly a second connection with the same peer...
    491506     */
  • router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java

    r9bb1a00 r07e85e0  
    771771        dsm.setMessageExpiration(_context.clock().now() + DATA_MESSAGE_TIMEOUT);
    772772        dsm.setMessageId(_context.random().nextLong(I2NPMessage.MAX_ID_VALUE));
    773         _transport.send(dsm, peer);
     773        // sent below
    774774
    775775        // just do this inline
     
    781781                //if (_log.shouldLog(Log.INFO))
    782782                //    _log.info("Publishing to the peer after confirm plus delay (without banlist): " + peer);
    783                 sendOurInfo(peer, true);
     783                // bundle the two messages together for efficiency
     784                DatabaseStoreMessage dbsm = getOurInfo();
     785                List<I2NPMessage> msgs = new ArrayList<I2NPMessage>(2);
     786                msgs.add(dsm);
     787                msgs.add(dbsm);
     788                _transport.send(msgs, peer);
    784789            } else {
     790                _transport.send(dsm, peer);
    785791                // nuh uh.
    786792                if (_log.shouldLog(Log.WARN))
     
    829835       
    830836        _context.statManager().addRateData("udp.outboundEstablishTime", state.getLifetime(), 0);
     837        DatabaseStoreMessage dbsm = null;
    831838        if (!state.isFirstMessageOurDSM()) {
    832             sendOurInfo(peer, false);
     839            dbsm = getOurInfo();
    833840        } else if (_log.shouldLog(Log.INFO)) {
    834841            _log.info("Skipping publish: " + state);
    835842        }
    836843       
     844        List<OutNetMessage> msgs = new ArrayList<OutNetMessage>(8);
    837845        OutNetMessage msg;
    838846        while ((msg = state.getNextQueuedMessage()) != null) {
     
    842850            } else {
    843851                msg.timestamp("session fully established and sent");
    844                 _transport.send(msg);
    845             }
    846         }
     852                msgs.add(msg);
     853            }
     854        }
     855        _transport.send(dbsm, msgs, peer);
    847856        return peer;
    848857    }
    849858   
     859/****
    850860    private void sendOurInfo(PeerState peer, boolean isInbound) {
    851861        if (_log.shouldLog(Log.INFO))
    852862            _log.info("Publishing to the peer after confirm: " +
    853863                      (isInbound ? " inbound con from " + peer : "outbound con to " + peer));
    854        
     864        DatabaseStoreMessage m = getOurInfo();
     865        _transport.send(m, peer);
     866    }
     867****/
     868   
     869    /**
     870     *  A database store message with our router info
     871     *  @return non-null
     872     *  @since 0.9.24 split from sendOurInfo()
     873     */
     874    private DatabaseStoreMessage getOurInfo() {
    855875        DatabaseStoreMessage m = new DatabaseStoreMessage(_context);
    856876        m.setEntry(_context.router().getRouterInfo());
    857877        m.setMessageExpiration(_context.clock().now() + DATA_MESSAGE_TIMEOUT);
    858         _transport.send(m, peer);
     878        return m;
    859879    }
    860880   
  • router/java/src/net/i2p/router/transport/udp/IntroductionManager.java

    r9bb1a00 r07e85e0  
    44import java.net.UnknownHostException;
    55import java.util.ArrayList;
     6import java.util.Arrays;
    67import java.util.Collections;
    78import java.util.HashSet;
     
    165166     * to keep the connection up, since the netDb can have quite stale information,
    166167     * and we want to keep our introducers valid.
     168     *
     169     * @param ssuOptions out parameter, options are added
     170     * @return number of introducers added
    167171     */
    168172    public int pickInbound(Properties ssuOptions, int howMany) {
     
    441445        // FIXME implement for getting Alice's IPv4 in RelayRequest sent over IPv6?
    442446        // or is that just too easy to spoof?
    443         if (!isValid(alice.getIP(), alice.getPort()) || ipSize != 0 || port != 0) {
    444             if (_log.shouldLog(Log.WARN)) {
    445                 byte ip[] = new byte[ipSize];
    446                 rrReader.readIP(ip, 0);
    447                 _log.warn("Bad relay req from " + alice + " for " + Addresses.toString(ip, port));
    448             }
     447        byte[] aliceIP = alice.getIP();
     448        int alicePort = alice.getPort();
     449        if (!isValid(alice.getIP(), alice.getPort())) {
     450            if (_log.shouldWarn())
     451                _log.warn("Bad relay req from " + alice + " for " + Addresses.toString(aliceIP, alicePort));
     452            _context.statManager().addRateData("udp.relayBadIP", 1);
     453            return;
     454        }
     455        // prior to 0.9.24 we rejected any non-zero-length ip
     456        // here we reject anything different
     457        // TODO relay request over IPv6
     458        if (ipSize != 0) {
     459            byte ip[] = new byte[ipSize];
     460            rrReader.readIP(ip, 0);
     461            if (!Arrays.equals(aliceIP, ip)) {
     462                if (_log.shouldWarn())
     463                    _log.warn("Bad relay req from " + alice + " for " + Addresses.toString(ip, port));
     464                _context.statManager().addRateData("udp.relayBadIP", 1);
     465                return;
     466            }
     467        }
     468        // prior to 0.9.24 we rejected any nonzero port
     469        // here we reject anything different
     470        // TODO relay request over IPv6
     471        if (port != 0 && port != alicePort) {
     472            if (_log.shouldWarn())
     473                _log.warn("Bad relay req from " + alice + " for " + Addresses.toString(aliceIP, port));
    449474            _context.statManager().addRateData("udp.relayBadIP", 1);
    450475            return;
  • router/java/src/net/i2p/router/transport/udp/MTU.java

    r9bb1a00 r07e85e0  
    4040            ifcs = NetworkInterface.getNetworkInterfaces();
    4141        } catch (SocketException se) {
     42            return 0;
     43        } catch (java.lang.Error e) {
     44            // Windows, possibly when IPv6 only...
     45            // https://bugs.openjdk.java.net/browse/JDK-8046500
     46            // java.lang.Error: IP Helper Library GetIfTable function failed
     47            //   at java.net.NetworkInterface.getAll(Native Method)
     48            //   at java.net.NetworkInterface.getNetworkInterfaces(Unknown Source)
     49            //   at net.i2p.util.Addresses.getAddresses ...
    4250            return 0;
    4351        }
  • router/java/src/net/i2p/router/transport/udp/OutboundEstablishState.java

    r9bb1a00 r07e85e0  
    110110     *  @param remoteHostId non-null, == claimedAddress if direct, or a hash-based one if indirect
    111111     *  @param remotePeer must have supported sig type
    112      *  @param allowExtenededOptions are we allowed to send extended options to Bob?
     112     *  @param allowExtendedOptions are we allowed to send extended options to Bob?
    113113     *  @param needIntroduction should we ask Bob to be an introducer for us?
    114114               ignored unless allowExtendedOptions is true
  • router/java/src/net/i2p/router/transport/udp/OutboundMessageFragments.java

    r9bb1a00 r07e85e0  
    173173
    174174    /**
    175      * short circuit the OutNetMessage, letting us send the establish
    176      * complete message reliably
    177      */
    178     public void add(OutboundMessageState state) {
    179         PeerState peer = state.getPeer();
     175     *  Short circuit the OutNetMessage, letting us send the establish
     176     *  complete message reliably.
     177     *  If you have multiple messages, use the list variant,
     178     *  so the messages may be bundled efficiently.
     179     */
     180    public void add(OutboundMessageState state, PeerState peer) {
    180181        if (peer == null)
    181182            throw new RuntimeException("null peer for " + state);
    182183        peer.add(state);
     184        add(peer);
     185        //_context.statManager().addRateData("udp.outboundActiveCount", active, 0);
     186    }
     187
     188    /**
     189     *  Short circuit the OutNetMessage, letting us send multiple messages
     190     *  reliably and efficiently.
     191     *  @since 0.9.24
     192     */
     193    public void add(List<OutboundMessageState> states, PeerState peer) {
     194        if (peer == null)
     195            throw new RuntimeException("null peer");
     196        int sz = states.size();
     197        for (int i = 0; i < sz; i++) {
     198            peer.add(states.get(i));
     199        }
    183200        add(peer);
    184201        //_context.statManager().addRateData("udp.outboundActiveCount", active, 0);
     
    401418        // sort by size, biggest first
    402419        // don't bother unless more than one state (fragments are already sorted within a state)
    403         if (fragmentsToSend > 1 && states.size() > 1)
    404             Collections.sort(toSend, new FragmentComparator());
     420        // This puts the DeliveryStatusMessage after the DatabaseStoreMessage, don't do it for now.
     421        // It also undoes the ordering of the priority queue in PeerState.
     422        //if (fragmentsToSend > 1 && states.size() > 1)
     423        //    Collections.sort(toSend, new FragmentComparator());
    405424
    406425        List<Fragment> sendNext = new ArrayList<Fragment>(Math.min(toSend.size(), 4));
     
    491510     *  @since 0.9.16
    492511     */
     512/****
    493513    private static class FragmentComparator implements Comparator<Fragment>, Serializable {
    494514
     
    498518        }
    499519    }
    500 
     520****/
     521
     522    /** throttle */
    501523    public interface ActiveThrottle {
    502524        public void choke(Hash peer);
  • router/java/src/net/i2p/router/transport/udp/OutboundMessageState.java

    r9bb1a00 r07e85e0  
    178178     * Note that we have pushed the message fragments.
    179179     * Increments push count (and max sends... why?)
    180      */
    181     public synchronized void push() {
     180     * @return true if this is the first push
     181     */
     182    public synchronized boolean push() {
     183        boolean rv = _pushCount == 0;
    182184        // these will never be different...
    183185        _pushCount++;
    184186        _maxSends = _pushCount;
     187        return rv;
    185188    }
    186189
     
    291294        StringBuilder buf = new StringBuilder(256);
    292295        buf.append("OB Message ").append(_i2npMessage.getUniqueId());
     296        buf.append(" type ").append(_i2npMessage.getType());
    293297        buf.append(" with ").append(_numFragments).append(" fragments");
    294298        buf.append(" of size ").append(_messageBuf.length);
     
    302306            }
    303307        }
     308        //buf.append(" to: ").append(_peer.toString());
    304309        return buf.toString();
    305310    }
  • router/java/src/net/i2p/router/transport/udp/PeerState.java

    r9bb1a00 r07e85e0  
    1818import net.i2p.router.OutNetMessage;
    1919import net.i2p.router.RouterContext;
     20import net.i2p.router.util.CachedIteratorArrayList;
    2021import net.i2p.router.util.CoDelPriorityBlockingQueue;
    2122import net.i2p.router.util.PriBlockingQueue;
    22 import net.i2p.util.CachedIteratorArrayList;
    2323import net.i2p.util.Log;
    2424import net.i2p.util.ConcurrentHashSet;
     
    199199    private int _packetsReceivedDuplicate;
    200200    private int _packetsReceived;
     201    private boolean _mayDisconnect;
    201202   
    202203    /** list of InboundMessageState for active message */
     
    448449     *  @deprecated unused, ECNs are never sent, always returns false
    449450     */
     451    @Deprecated
    450452    public boolean getCurrentSecondECNReceived() { return _currentSecondECNReceived; }
    451453
     
    543545     * @deprecated unused
    544546     */
     547    @Deprecated
    545548    public void setNextMACKey(SessionKey key) { _nextMACKey = key; }
    546549
     
    551554     * @deprecated unused
    552555     */
     556    @Deprecated
    553557    public void setNextCipherKey(SessionKey key) { _nextCipherKey = key; }
    554558
     
    570574     * @deprecated unused
    571575     */
     576    @Deprecated
    572577    public void setKeyEstablishedTime(long when) { _keyEstablishedTime = when; }
    573578
     
    772777    public void setIntroducerTime() { _lastIntroducerTime = _context.clock().now(); }
    773778   
    774     /** we received the message specified completely */
     779    /**
     780     *  We received the message specified completely.
     781     *  @param bytes if less than or equal to zero, message is a duplicate.
     782     */
    775783    public void messageFullyReceived(Long messageId, int bytes) { messageFullyReceived(messageId, bytes, false); }
    776784
    777     public synchronized void messageFullyReceived(Long messageId, int bytes, boolean isForACK) {
     785    /**
     786     *  We received the message specified completely.
     787     *  @param isForACK unused
     788     *  @param bytes if less than or equal to zero, message is a duplicate.
     789     */
     790    private synchronized void messageFullyReceived(Long messageId, int bytes, boolean isForACK) {
    778791        if (bytes > 0) {
    779792            _receiveBytes += bytes;
    780793            //if (isForACK)
    781794            //    _receiveACKBytes += bytes;
     795            _messagesReceived++;
    782796        } else {
    783797            //if (true || _retransmissionPeriodStart + 1000 < _context.clock().now()) {
     
    804818            _wantACKSendSince = now;
    805819        _currentACKs.add(messageId);
    806         _messagesReceived++;
    807820    }
    808821   
     
    959972     * @deprecated unused
    960973     */
     974    @Deprecated
    961975    public List<ACKBitfield> retrieveACKBitfields() { return retrieveACKBitfields(true); }
    962976
     
    10281042            }
    10291043
    1030 
    1031 
    1032 
    1033 
    10341044        int partialIncluded = 0;
    10351045        if (bytesRemaining > 4) {
     
    11711181        //}
    11721182       
    1173         _messagesSent++;
    11741183        if (numSends < 2) {
    11751184            // caller synchs
     
    12751284    public synchronized int getRTTDeviation() { return _rttDeviation; }
    12761285   
    1277     public synchronized int getMessagesSent() { return _messagesSent; }
     1286    /**
     1287     *  I2NP messages sent.
     1288     *  Does not include duplicates.
     1289     *  As of 0.9.24, incremented when bandwidth is allocated just before sending, not when acked.
     1290     */
     1291    public int getMessagesSent() {
     1292        synchronized (_outboundMessages) {
     1293            return _messagesSent;
     1294        }
     1295    }
     1296   
     1297    /**
     1298     *  I2NP messages received.
     1299     *  As of 0.9.24, does not include duplicates.
     1300     */
    12781301    public synchronized int getMessagesReceived() { return _messagesReceived; }
     1302
    12791303    public synchronized int getPacketsTransmitted() { return _packetsTransmitted; }
    12801304    public synchronized int getPacketsRetransmitted() { return _packetsRetransmitted; }
     
    13401364
    13411365    /** @deprecated unused */
     1366    @Deprecated
    13421367    public void setLastACKSend(long when) { _lastACKSend = when; }
    13431368
     
    14991524        return _outboundMessages.size() + _outboundQueue.size();
    15001525    }
     1526
     1527    /**
     1528     * Sets to true.
     1529     * @since 0.9.24
     1530     */
     1531    public void setMayDisconnect() { _mayDisconnect = true; }
     1532
     1533    /**
     1534     * @since 0.9.24
     1535     */
     1536    public boolean getMayDisconnect() { return _mayDisconnect; }
     1537
    15011538   
    15021539    /**
     
    17721809                    _retransmitter = state;
    17731810
    1774                 state.push();
     1811                if (state.push())
     1812                    _messagesSent++;
    17751813           
    17761814                int rto = getRTO();
     
    20632101        buf.append(" acwin: ").append(_sendWindowBytesRemaining);
    20642102        buf.append(" consecFail: ").append(_consecutiveFailedSends);
    2065         buf.append(" recv OK/Dup: ").append(_packetsReceived).append('/').append(_packetsReceivedDuplicate);
    2066         buf.append(" send OK/Dup: ").append(_packetsTransmitted).append('/').append(_packetsRetransmitted);
     2103        buf.append(" msgs rcvd: ").append(_messagesReceived);
     2104        buf.append(" msgs sent: ").append(_messagesSent);
     2105        buf.append(" pkts rcvd OK/Dup: ").append(_packetsReceived).append('/').append(_packetsReceivedDuplicate);
     2106        buf.append(" pkts sent OK/Dup: ").append(_packetsTransmitted).append('/').append(_packetsRetransmitted);
    20672107        buf.append(" IBM: ").append(_inboundMessages.size());
    20682108        buf.append(" OBQ: ").append(_outboundQueue.size());
  • router/java/src/net/i2p/router/transport/udp/UDPAddress.java

    r9bb1a00 r07e85e0  
    6969            return;
    7070        }
    71         _host = addr.getOption(PROP_HOST);
     71        _host = addr.getHost();
    7272        _port = addr.getPort();
    7373        try {
  • router/java/src/net/i2p/router/transport/udp/UDPTransport.java

    r9bb1a00 r07e85e0  
    332332            if (fixedHost != null && fixedHost.length() > 0) {
    333333                try {
     334                    // TODO getAllByName(), bind to each
    334335                    String testAddr = InetAddress.getByName(fixedHost).getHostAddress();
    335336                    if (Addresses.getAddresses().contains(testAddr))
     
    734735        if (ip == null)
    735736            return;
     737        // this is essentially isValid(ip), but we can't use that because
     738        // _haveIPv6Address is not set yet
     739        if (!(isPubliclyRoutable(ip) || allowLocal())) {
     740            if (_log.shouldLog(Log.WARN))
     741                _log.warn("Invalid address: " + Addresses.toString(ip, port) + " from: " + source);
     742            return;
     743        }
    736744        if (source == SOURCE_INTERFACE && ip.length == 16) {
    737             // must be set before isValid() call
     745            // NOW we can set it, it's a valid v6 address
     746            // (we don't want to set this for Teredo, 6to4, ...)
    738747            _haveIPv6Address = true;
    739748        }
     
    743752        if (!sources.contains(source.toConfigString()))
    744753            return;
    745         if (!isValid(ip)) {
    746             if (_log.shouldLog(Log.WARN))
    747                 _log.warn("Invalid address: " + Addresses.toString(ip, port) + " from: " + source);
    748             return;
    749         }
    750754        if (!isAlive()) {
    751755            if (source == SOURCE_INTERFACE || source == SOURCE_UPNP) {
     
    18251829
    18261830    /**
    1827      *  "injected" message from the EstablishmentManager
     1831     *  "injected" message from the EstablishmentManager.
     1832     *  If you have multiple messages, use the list variant,
     1833     *  so the messages may be bundled efficiently.
     1834     *
     1835     *  @param peer all messages MUST be going to this peer
    18281836     */
    18291837    void send(I2NPMessage msg, PeerState peer) {
     
    18321840            if (_log.shouldLog(Log.DEBUG))
    18331841                _log.debug("Injecting a data message to a new peer: " + peer);
    1834             _fragments.add(state);
     1842            _fragments.add(state, peer);
     1843        } catch (IllegalArgumentException iae) {
     1844            if (_log.shouldLog(Log.WARN))
     1845                _log.warn("Shouldnt happen", new Exception("I did it"));
     1846        }
     1847    }
     1848
     1849    /**
     1850     *  "injected" message from the EstablishmentManager,
     1851     *  plus pending messages to send,
     1852     *  so the messages may be bundled efficiently.
     1853     *  Called at end of outbound establishment.
     1854     *
     1855     *  @param msg may be null if nothing to inject
     1856     *  @param msgs non-null, may be empty
     1857     *  @param peer all messages MUST be going to this peer
     1858     *  @since 0.9.24
     1859     */
     1860    void send(I2NPMessage msg, List<OutNetMessage> msgs, PeerState peer) {
     1861        try {
     1862            int sz = msgs.size();
     1863            List<OutboundMessageState> states = new ArrayList<OutboundMessageState>(sz + 1);
     1864            if (msg != null) {
     1865                OutboundMessageState state = new OutboundMessageState(_context, msg, peer);
     1866                states.add(state);
     1867            }
     1868            for (int i = 0; i < sz; i++) {
     1869                OutboundMessageState state = new OutboundMessageState(_context, msgs.get(i), peer);
     1870                states.add(state);
     1871            }
     1872            if (_log.shouldLog(Log.DEBUG))
     1873                _log.debug("Injecting " + states.size() + " data messages to a new peer: " + peer);
     1874            _fragments.add(states, peer);
     1875        } catch (IllegalArgumentException iae) {
     1876            if (_log.shouldLog(Log.WARN))
     1877                _log.warn("Shouldnt happen", new Exception("I did it"));
     1878        }
     1879    }
     1880
     1881    /**
     1882     *  "injected" messages from the EstablishmentManager.
     1883     *  Called at end of inbound establishment.
     1884     *
     1885     *  @param peer all messages MUST be going to this peer
     1886     *  @since 0.9.24
     1887     */
     1888    void send(List<I2NPMessage> msgs, PeerState peer) {
     1889        try {
     1890            int sz = msgs.size();
     1891            List<OutboundMessageState> states = new ArrayList<OutboundMessageState>(sz);
     1892            for (int i = 0; i < sz; i++) {
     1893                OutboundMessageState state = new OutboundMessageState(_context, msgs.get(i), peer);
     1894                states.add(state);
     1895            }
     1896            if (_log.shouldLog(Log.DEBUG))
     1897                _log.debug("Injecting " + sz + " data messages to a new peer: " + peer);
     1898            _fragments.add(states, peer);
    18351899        } catch (IllegalArgumentException iae) {
    18361900            if (_log.shouldLog(Log.WARN))
     
    24272491        PeerState peer =  _peersByIdent.get(dest);
    24282492        return peer != null && peer.isBacklogged();
     2493    }
     2494
     2495    /**
     2496     * Tell the transport that we may disconnect from this peer.
     2497     * This is advisory only.
     2498     *
     2499     * @since 0.9.24
     2500     */
     2501    @Override
     2502    public void mayDisconnect(final Hash peer) {
     2503        final PeerState ps =  _peersByIdent.get(peer);
     2504        if (ps != null && ps.isInbound() &&
     2505            ps.getWeRelayToThemAs() <= 0 &&
     2506            ps.getMessagesReceived() <= 2 && ps.getMessagesSent() <= 2) {
     2507            ps.setMayDisconnect();
     2508        }
    24292509    }
    24302510
     
    26752755            buf.append("</td>");
    26762756       
    2677             long sent = peer.getPacketsTransmitted();
    2678             long recv = peer.getPacketsReceived();
     2757            long sent = peer.getMessagesSent();
     2758            long recv = peer.getMessagesReceived();
    26792759           
    26802760            buf.append("<td class=\"cells\" align=\"right\">");
     
    28172897        private static final long EXPIRE_INCREMENT = 15*1000;
    28182898        private static final long EXPIRE_DECREMENT = 45*1000;
     2899        private static final long MAY_DISCON_TIMEOUT = 10*1000;
    28192900
    28202901        public ExpirePeerEvent() {
     
    28262907        public void timeReached() {
    28272908            // Increase allowed idle time if we are well under allowed connections, otherwise decrease
    2828             if (haveCapacity(33)) {
     2909            boolean haveCap = haveCapacity(33);
     2910            if (haveCap) {
    28292911                long inc;
    28302912                // don't adjust too quickly if we are looping fast
     
    28452927            long shortInactivityCutoff = now - _expireTimeout;
    28462928            long longInactivityCutoff = now - EXPIRE_TIMEOUT;
     2929            final long mayDisconCutoff = now - MAY_DISCON_TIMEOUT;
    28472930            long pingCutoff = now - (2 * 60*60*1000);
    28482931            long pingFirewallCutoff = now - PING_FIREWALL_CUTOFF;
     
    28592942                    long inactivityCutoff;
    28602943                    // if we offered to introduce them, or we used them as introducer in last 2 hours
    2861                     if (peer.getWeRelayToThemAs() > 0 || peer.getIntroducerTime() > pingCutoff)
     2944                    if (peer.getWeRelayToThemAs() > 0 || peer.getIntroducerTime() > pingCutoff) {
    28622945                        inactivityCutoff = longInactivityCutoff;
    2863                     else
     2946                    } else if (!haveCap && peer.getMayDisconnect() &&
     2947                               peer.getMessagesReceived() <= 2 && peer.getMessagesSent() <= 2) {
     2948                        inactivityCutoff = mayDisconCutoff;
     2949                    } else {
    28642950                        inactivityCutoff = shortInactivityCutoff;
     2951                    }
    28652952                    if ( (peer.getLastReceiveTime() < inactivityCutoff) && (peer.getLastSendTime() < inactivityCutoff) ) {
    28662953                        _expireBuffer.add(peer);
  • router/java/src/net/i2p/router/tunnel/BuildMessageGenerator.java

    r9bb1a00 r07e85e0  
    5555     *
    5656     * @param msg out parameter
     57     * @param peerKey Encrypt using this key.
     58     *                If null, replyRouter and replyTunnel are ignored,
     59     *                and the entire record is filled with random data
    5760     * @throws IllegalArgumentException if hop bigger than config
    5861     */
  • router/java/src/net/i2p/router/tunnel/BuildMessageProcessor.java

    r9bb1a00 r07e85e0  
    1111import net.i2p.data.i2np.EncryptedBuildRecord;
    1212import net.i2p.data.i2np.TunnelBuildMessage;
     13import net.i2p.router.RouterThrottleImpl;
    1314import net.i2p.router.util.DecayingBloomFilter;
    1415import net.i2p.router.util.DecayingHashSet;
    1516import net.i2p.util.Log;
     17import net.i2p.util.SystemVersion;
    1618
    1719/**
     
    1921 * read the enclosed tunnel request, decide how to reply, write the reply,
    2022 * encrypt the reply record, and return a TunnelBuildMessage to forward on to
    21  * the next hop
     23 * the next hop.
     24 *
     25 * There is only one of these.
     26 * Instantiated by BuildHandler.
     27 *
    2228 */
    2329public class BuildMessageProcessor {
     30    private final I2PAppContext ctx;
     31    private final Log log;
    2432    private final DecayingBloomFilter _filter;
    2533   
    2634    public BuildMessageProcessor(I2PAppContext ctx) {
    27         _filter = new DecayingHashSet(ctx, 60*1000, 32, "TunnelBMP");
     35        this.ctx = ctx;
     36        log = ctx.logManager().getLog(getClass());
     37        _filter = selectFilter();
    2838        // all createRateStat in TunnelDispatcher
    2939    }
     40
     41    /**
     42     *  For N typical part tunnels and rejecting 50%, that's 12N requests per hour.
     43     *  This is the equivalent of (12N/600) KBps through the IVValidator filter.
     44     *
     45     *  Target false positive rate is 1E-5 or lower
     46     *
     47     *  @since 0.9.24
     48     */
     49    private DecayingBloomFilter selectFilter() {
     50        long maxMemory = SystemVersion.getMaxMemory();
     51        int m;
     52        if (SystemVersion.isAndroid() || SystemVersion.isARM() || maxMemory < 96*1024*1024L) {
     53            // 32 KB
     54            // appx 500 part. tunnels or 6K req/hr
     55            m = 17;
     56        } else if (ctx.getProperty(RouterThrottleImpl.PROP_MAX_TUNNELS, RouterThrottleImpl.DEFAULT_MAX_TUNNELS) >
     57                   RouterThrottleImpl.DEFAULT_MAX_TUNNELS && maxMemory > 256*1024*1024L) {
     58            // 2 MB
     59            // appx 20K part. tunnels or 240K req/hr
     60            m = 23;
     61        } else if (maxMemory > 256*1024*1024L) {
     62            // 1 MB
     63            // appx 10K part. tunnels or 120K req/hr
     64            m = 22;
     65        } else if (maxMemory > 128*1024*1024L) {
     66            // 512 KB
     67            // appx 5K part. tunnels or 60K req/hr
     68            m = 21;
     69        } else {
     70            // 128 KB
     71            // appx 2K part. tunnels or 24K req/hr
     72            m = 19;
     73        }
     74        if (log.shouldInfo())
     75            log.info("Selected Bloom filter m = " + m);
     76        return new DecayingBloomFilter(ctx, 60*60*1000, 32, "TunnelBMP", m);
     77    }
     78
    3079    /**
    3180     * Decrypt the record targetting us, encrypting all of the other records with the included
     
    3988     * @return the current hop's decrypted record or null on failure
    4089     */
    41     public BuildRequestRecord decrypt(I2PAppContext ctx, TunnelBuildMessage msg, Hash ourHash, PrivateKey privKey) {
    42         Log log = ctx.logManager().getLog(getClass());
     90    public BuildRequestRecord decrypt(TunnelBuildMessage msg, Hash ourHash, PrivateKey privKey) {
    4391        BuildRequestRecord rv = null;
    4492        int ourHop = -1;
    4593        long beforeActualDecrypt = 0;
    4694        long afterActualDecrypt = 0;
    47         long totalEq = 0;
    48         long totalDup = 0;
     95        byte[] ourHashData = ourHash.getData();
    4996        long beforeLoop = System.currentTimeMillis();
    5097        for (int i = 0; i < msg.getRecordCount(); i++) {
    5198            EncryptedBuildRecord rec = msg.getRecord(i);
    5299            int len = BuildRequestRecord.PEER_SIZE;
    53             long beforeEq = System.currentTimeMillis();
    54             boolean eq = DataHelper.eq(ourHash.getData(), 0, rec.getData(), 0, len);
    55             totalEq += System.currentTimeMillis()-beforeEq;
     100            boolean eq = DataHelper.eq(ourHashData, 0, rec.getData(), 0, len);
    56101            if (eq) {
    57                 long beforeIsDup = System.currentTimeMillis();
    58                 boolean isDup = _filter.add(rec.getData(), len, 32);
    59                 totalDup += System.currentTimeMillis()-beforeIsDup;
    60                 if (isDup) {
    61                     if (log.shouldLog(Log.WARN))
    62                         log.debug(msg.getUniqueId() + ": A record matching our hash was found, but it seems to be a duplicate");
    63                     ctx.statManager().addRateData("tunnel.buildRequestDup", 1);
    64                     return null;
    65                 }
    66102                beforeActualDecrypt = System.currentTimeMillis();
    67103                try {
    68                     BuildRequestRecord req = new BuildRequestRecord(ctx, privKey, rec);
     104                    rv = new BuildRequestRecord(ctx, privKey, rec);
     105                    afterActualDecrypt = System.currentTimeMillis();
     106
     107                    // i2pd bug
     108                    boolean isBad = SessionKey.INVALID_KEY.equals(rv.readReplyKey());
     109                    if (isBad) {
     110                        if (log.shouldLog(Log.WARN))
     111                            log.warn(msg.getUniqueId() + ": Bad reply key: " + rv);
     112                        ctx.statManager().addRateData("tunnel.buildRequestBadReplyKey", 1);
     113                        return null;
     114                    }
     115
     116                    // The spec says to feed the 32-byte AES-256 reply key into the Bloom filter.
     117                    // But we were using the first 32 bytes of the encrypted reply.
     118                    // Fixed in 0.9.24
     119                    boolean isDup = _filter.add(rv.getData(), BuildRequestRecord.OFF_REPLY_KEY, 32);
     120                    if (isDup) {
     121                        if (log.shouldLog(Log.WARN))
     122                            log.warn(msg.getUniqueId() + ": Dup record: " + rv);
     123                        ctx.statManager().addRateData("tunnel.buildRequestDup", 1);
     124                        return null;
     125                    }
     126
    69127                    if (log.shouldLog(Log.DEBUG))
    70                         log.debug(msg.getUniqueId() + ": A record matching our hash was found and decrypted");
    71                     rv = req;
     128                        log.debug(msg.getUniqueId() + ": Matching record: " + rv);
     129                    ourHop = i;
     130                    // TODO should we keep looking for a second match and fail if found?
     131                    break;
    72132                } catch (DataFormatException dfe) {
    73                     if (log.shouldLog(Log.DEBUG))
    74                         log.debug(msg.getUniqueId() + ": A record matching our hash was found, but could not be decrypted");
    75                     return null; // our hop is invalid?  b0rkage
     133                    if (log.shouldLog(Log.WARN))
     134                        log.warn(msg.getUniqueId() + ": Matching record decrypt failure", dfe);
     135                    // on the microscopic chance that there's another router
     136                    // out there with the same first 16 bytes, go around again
     137                    continue;
    76138                }
    77                 afterActualDecrypt = System.currentTimeMillis();
    78                 ourHop = i;
    79139            }
    80140        }
    81141        if (rv == null) {
    82142            // none of the records matched, b0rk
    83             if (log.shouldLog(Log.DEBUG))
    84                 log.debug(msg.getUniqueId() + ": No records matching our hash was found");
     143            if (log.shouldLog(Log.WARN))
     144                log.warn(msg.getUniqueId() + ": No matching record");
    85145            return null;
    86146        }
     
    89149        SessionKey replyKey = rv.readReplyKey();
    90150        byte iv[] = rv.readReplyIV();
    91         int ivOff = 0;
    92151        for (int i = 0; i < msg.getRecordCount(); i++) {
    93152            if (i != ourHop) {
    94153                EncryptedBuildRecord data = msg.getRecord(i);
    95                 if (log.shouldLog(Log.DEBUG))
    96                     log.debug("Encrypting record " + i + "/? with replyKey " + replyKey.toBase64() + "/" + Base64.encode(iv, ivOff, 16));
    97                 // corrupts SDS
    98                 ctx.aes().encrypt(data.getData(), 0, data.getData(), 0, replyKey,
    99                                   iv, ivOff, data.length());
     154                //if (log.shouldLog(Log.DEBUG))
     155                //    log.debug("Encrypting record " + i + "/? with replyKey " + replyKey.toBase64() + "/" + Base64.encode(iv));
     156                // encrypt in-place, corrupts SDS
     157                byte[] bytes = data.getData();
     158                ctx.aes().encrypt(bytes, 0, bytes, 0, replyKey, iv, 0, EncryptedBuildRecord.LENGTH);
    100159            }
    101160        }
     
    107166                         + " looping=" + (beforeEncrypt-beforeLoop)
    108167                         + " decrypt=" + (afterActualDecrypt-beforeActualDecrypt)
    109                          + " eq=" + totalEq
    110                          + " dup=" + totalDup
    111168                         + " encrypt=" + (afterEncrypt-beforeEncrypt));
    112169        }
  • router/java/src/net/i2p/router/tunnel/HopConfig.java

    r9bb1a00 r07e85e0  
    2727    // these 4 were longs, let's save some space
    2828    // 2 billion * 1KB / 10 minutes = 3 GBps in a single tunnel
     29    // we use synchronization instead of an AtomicInteger here to save space
    2930    private int _messagesProcessed;
    3031    private int _oldMessagesProcessed;
     
    128129     *  Take note of a message being pumped through this tunnel.
    129130     *  "processed" is for incoming and "sent" is for outgoing (could be dropped in between)
     131     *  We use synchronization instead of an AtomicInteger here to save space.
    130132     */
    131     public void incrementProcessedMessages() { _messagesProcessed++; }
     133    public synchronized void incrementProcessedMessages() { _messagesProcessed++; }
    132134
    133     public int getProcessedMessagesCount() { return _messagesProcessed; }
     135    public synchronized int getProcessedMessagesCount() { return _messagesProcessed; }
    134136
    135     public int getRecentMessagesCount() {
     137    /**
     138     *  This returns the number of processed messages since
     139     *  the last time getAndResetRecentMessagesCount() was called.
     140     *  As of 0.9.23, does NOT reset the count, see getAndResetRecentMessagesCount().
     141     */
     142    public synchronized int getRecentMessagesCount() {
     143        return _messagesProcessed - _oldMessagesProcessed;
     144    }
     145
     146    /**
     147     *  This returns the number of processed messages since the last time this was called,
     148     *  and resets the count. It should only be called by code that updates the router stats.
     149     *  See TunnelDispatcher.updateParticipatingStats().
     150     *
     151     *  @since 0.9.23
     152     */
     153    synchronized int getAndResetRecentMessagesCount() {
    136154        int rv = _messagesProcessed - _oldMessagesProcessed;
    137155        _oldMessagesProcessed = _messagesProcessed;
     
    172190       
    173191        buf.append(" exp. ").append(TunnelCreatorConfig.format(_expiration));
    174         if (_messagesProcessed > 0)
    175             buf.append(" used ").append(_messagesProcessed).append("KB");
     192        int messagesProcessed = getProcessedMessagesCount();
     193        if (messagesProcessed > 0)
     194            buf.append(" used ").append(messagesProcessed).append("KB");
    176195        return buf.toString();
    177196    }
  • router/java/src/net/i2p/router/tunnel/HopProcessor.java

    r9bb1a00 r07e85e0  
    3232    static final int IV_LENGTH = 16;
    3333   
    34     /** @deprecated unused */
    35     public HopProcessor(I2PAppContext ctx, HopConfig config) {
    36         this(ctx, config, createValidator());
    37     }
    3834
    3935    public HopProcessor(I2PAppContext ctx, HopConfig config, IVValidator validator) {
     
    4238        _config = config;
    4339        _validator = validator;
    44     }
    45    
    46     /** @deprecated unused */
    47     protected static IVValidator createValidator() {
    48         // yeah, we'll use an O(1) validator later (e.g. bloom filter)
    49         return new HashSetIVValidator();
    5040    }
    5141   
  • router/java/src/net/i2p/router/tunnel/TunnelCreatorConfig.java

    r9bb1a00 r07e85e0  
    153153    /**
    154154     *  This calls profile manager tunnelDataPushed1m() for each peer
    155      *  @return null for exploratory
    156155     */
    157156    public synchronized void incrementVerifiedBytesTransferred(int bytes) {
  • router/java/src/net/i2p/router/tunnel/TunnelDispatcher.java

    r9bb1a00 r07e85e0  
    164164                                         "Dropped for exceeding share limit", "Tunnels",
    165165                                         new long[] { 60*1000l, 60*10*1000l });
     166        // count for console
    166167        ctx.statManager().createRequiredRateStat("tunnel.participatingMessageCount",
    167168                                         "Number of 1KB participating messages", "Tunnels",
    168169                                         new long[] { 60*1000l, 60*10*1000l, 60*60*1000l });
     170        // estimate for RouterThrottleImpl
     171        ctx.statManager().createRequiredRateStat("tunnel.participatingMessageCountAvgPerTunnel",
     172                                         "Estimate of participating messages per tunnel lifetime", "Tunnels",
     173                                         new long[] { 60*1000l });
    169174        ctx.statManager().createRateStat("tunnel.ownedMessageCount",
    170175                                         "How many messages are sent through a tunnel we created (period == failures)?", "Tunnels",
     
    200205        // following is for BuildMessageProcessor
    201206        ctx.statManager().createRateStat("tunnel.buildRequestDup", "How frequently we get dup build request messages", "Tunnels", new long[] { 60*60*1000 });
     207        ctx.statManager().createRateStat("tunnel.buildRequestBadReplyKey", "Build requests with bad reply keys", "Tunnels", new long[] { 60*60*1000 });
    202208        // following are for FragmentHandler
    203209        ctx.statManager().createRateStat("tunnel.smallFragments", "How many pad bytes are in small fragments?",
     
    446452        if (cfg.isInbound()) {
    447453            TunnelId recvId = cfg.getConfig(cfg.getLength()-1).getReceiveTunnel();
    448             if (_log.shouldLog(Log.DEBUG))
    449                 _log.debug("removing our own inbound " + cfg);
     454            if (_log.shouldLog(Log.INFO))
     455                _log.info("removing our own inbound " + cfg);
    450456            TunnelParticipant participant = _participants.remove(recvId);
    451457            if (participant == null) {
     
    465471            }
    466472        } else {
    467             if (_log.shouldLog(Log.DEBUG))
    468                 _log.debug("removing our own outbound " + cfg);
     473            if (_log.shouldLog(Log.INFO))
     474                _log.info("removing our own outbound " + cfg);
    469475            TunnelId outId = cfg.getConfig(0).getSendTunnel();
    470476            TunnelGateway gw = _outboundGateways.remove(outId);
     
    493499        boolean removed = (null != _participatingConfig.remove(recvId));
    494500        if (removed) {
    495             if (_log.shouldLog(Log.DEBUG))
    496                 _log.debug("removing " + cfg /* , new Exception() */ );
     501            if (_log.shouldLog(Log.INFO))
     502                _log.info("removing " + cfg /* , new Exception() */ );
    497503        } else {
    498504            // this is normal, this can get called twice
     
    599605                           + "/" + msg.getMessage().getUniqueId()
    600606                           + " messageType: " + msg.getMessage().getClass().getSimpleName()
    601                            + " existing = " + _inboundGateways.size(), new Exception("source"));
     607                           + " existing = " + _inboundGateways.size());
    602608        }
    603609       
     
    713719        long tooOld = tooYoung - 9*60*1000;
    714720        for (HopConfig cfg : _participatingConfig.values()) {
    715             long c = cfg.getRecentMessagesCount();
     721            long c = cfg.getAndResetRecentMessagesCount();
    716722            bw += c;
    717723            //bwOut += cfg.getRecentSentMessagesCount();
     
    722728            count += c;
    723729        }
     730        // This is an estimate of the average number of participating messages per tunnel
     731        // in a tunnel lifetime, used only by RouterThrottleImpl
     732        // 10 minutes / 50 seconds = 12
    724733        if (tcount > 0)
    725             count = count * 30 / tcount;
    726         _context.statManager().addRateData("tunnel.participatingMessageCount", count, ms);
     734            count = count * (10*60*1000 / ms) / tcount;
     735        _context.statManager().addRateData("tunnel.participatingMessageCountAvgPerTunnel", count, ms);
     736        // This is a straight count of the total participating messages, used in the router console
     737        _context.statManager().addRateData("tunnel.participatingMessageCount", bw, ms);
     738        // Bandwidth in bits per second
    727739        _context.statManager().addRateData("tunnel.participatingBandwidth", bw*1024/(ms/1000), ms);
    728740        // moved to FIFOBandwidthRefiller
  • router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java

    r9bb1a00 r07e85e0  
    4848 *
    4949 * Note that 10 minute tunnel expiration is hardcoded in here.
     50 *
     51 * There is only one of these objects but there may be multiple
     52 * threads running it. Instantiated and started by TunnelPoolManager.
     53 *
    5054 */
    5155class BuildHandler implements Runnable {
     
    123127        _context.statManager().createRequiredRateStat("tunnel.dropReqThrottle", "Drop per-hop limit", "Tunnels", new long[] { 60*60*1000 });
    124128        _context.statManager().createRequiredRateStat("tunnel.dropLookupThrottle", "Drop next hop lookup", "Tunnels", new long[] { 60*60*1000 });
     129        _context.statManager().createRateStat("tunnel.dropDecryptFail", "Can't find our slot", "Tunnels", new long[] { 60*60*1000 });
    125130
    126131        _context.statManager().createRequiredRateStat("tunnel.rejectOverloaded", "Delay to process rejected request (ms)", "Tunnels", new long[] { 60*1000, 10*60*1000 });
     
    444449    private long handleRequest(BuildMessageState state) {
    445450        long timeSinceReceived = _context.clock().now()-state.recvTime;
    446         if (_log.shouldLog(Log.DEBUG))
    447             _log.debug(state.msg.getUniqueId() + ": handling request after " + timeSinceReceived);
     451        //if (_log.shouldLog(Log.DEBUG))
     452        //    _log.debug(state.msg.getUniqueId() + ": handling request after " + timeSinceReceived);
    448453       
     454        Hash from = state.fromHash;
     455        if (from == null && state.from != null)
     456            from = state.from.calculateHash();
     457
    449458        if (timeSinceReceived > (BuildRequestor.REQUEST_TIMEOUT*3)) {
    450459            // don't even bother, since we are so overloaded locally
     
    454463                           + ", since we received it a long time ago: " + timeSinceReceived);
    455464            _context.statManager().addRateData("tunnel.dropLoadDelay", timeSinceReceived);
     465            if (from != null)
     466                _context.commSystem().mayDisconnect(from);
    456467            return -1;
    457468        }
     
    460471        // with the enclosed reply key
    461472        long beforeDecrypt = System.currentTimeMillis();
    462         BuildRequestRecord req = _processor.decrypt(_context, state.msg, _context.routerHash(), _context.keyManager().getPrivateKey());
     473        BuildRequestRecord req = _processor.decrypt(state.msg, _context.routerHash(), _context.keyManager().getPrivateKey());
    463474        long decryptTime = System.currentTimeMillis() - beforeDecrypt;
    464475        _context.statManager().addRateData("tunnel.decryptRequestTime", decryptTime);
     
    467478        if (req == null) {
    468479            // no records matched, or the decryption failed.  bah
    469             if (_log.shouldLog(Log.WARN))
    470                 _log.warn("The request " + state.msg.getUniqueId() + " could not be decrypted");
     480            if (_log.shouldLog(Log.WARN)) {
     481                _log.warn("The request " + state.msg.getUniqueId() + " could not be decrypted from: " + from);
     482            }
     483            _context.statManager().addRateData("tunnel.dropDecryptFail", 1);
     484            if (from != null)
     485                _context.commSystem().mayDisconnect(from);
    471486            return -1;
    472487        }
     
    478493        long lookupTime = System.currentTimeMillis()-beforeLookup;
    479494        if (lookupTime > 500 && _log.shouldLog(Log.WARN))
    480             _log.warn("Took too long to lookup the request: " + lookupTime + "/" + readPeerTime + " for message " + state.msg.getUniqueId() + " received " + (timeSinceReceived+decryptTime) + " ago");
     495            _log.warn("Took too long to lookup the request: " + lookupTime + "/" + readPeerTime + " for " + req);
    481496        if (nextPeerInfo == null) {
    482497            // limit concurrent next-hop lookups to prevent job queue overload attacks
     
    486501            if (current <= limit) {
    487502                if (_log.shouldLog(Log.DEBUG))
    488                     _log.debug("Request " + state.msg.getUniqueId() + '/' + req.readReceiveTunnelId() + '/' + req.readNextTunnelId()
     503                    _log.debug("Request " + req
    489504                               + " handled, lookup next peer " + nextPeer
    490505                               + " lookups: " + current + '/' + limit);
     
    494509                _currentLookups.decrementAndGet();
    495510                if (_log.shouldLog(Log.WARN))
    496                     _log.warn("Drop next hop lookup, limit " + limit);
     511                    _log.warn("Drop next hop lookup, limit " + limit + ": " + req);
    497512                _context.statManager().addRateData("tunnel.dropLookupThrottle", 1);
    498513            }
     514            if (from != null)
     515                _context.commSystem().mayDisconnect(from);
    499516            return -1;
    500517        } else {
     
    503520            long handleTime = System.currentTimeMillis() - beforeHandle;
    504521            if (_log.shouldLog(Log.DEBUG))
    505                 _log.debug("Request " + state.msg.getUniqueId() + " handled and we know the next peer "
     522                _log.debug("Request " + req + " handled and we know the next peer "
    506523                           + nextPeer + " after " + handleTime
    507524                           + "/" + decryptTime + "/" + lookupTime + "/" + timeSinceReceived);
     
    544561            _currentLookups.decrementAndGet();
    545562            if (_log.shouldLog(Log.DEBUG))
    546                 _log.debug("Request " + _state.msg.getUniqueId() + " handled with a successful deferred lookup for the next peer " + _nextPeer);
     563                _log.debug("Request " + _state.msg.getUniqueId() + " handled with a successful deferred lookup: " + _req);
    547564
    548565            RouterInfo ri = getContext().netDb().lookupRouterInfoLocally(_nextPeer);
     
    552569            } else {
    553570                if (_log.shouldLog(Log.WARN))
    554                     _log.warn("Deferred successfully, but we couldnt find " + _nextPeer);
     571                    _log.warn("Deferred successfully, but we couldnt find " + _nextPeer + "? " + _req);
    555572                getContext().statManager().addRateData("tunnel.buildLookupSuccess", 0);
    556573            }
     
    577594            getContext().statManager().addRateData("tunnel.rejectTimeout", 1);
    578595            getContext().statManager().addRateData("tunnel.buildLookupSuccess", 0);
    579             // logging commented out so class can be static
    580             //if (_log.shouldLog(Log.WARN))
    581             //    _log.warn("Request " + _state.msg.getUniqueId()
    582             //              + " could no be satisfied, as the next peer could not be found: " + _nextPeer.toBase64());
     596            if (_log.shouldLog(Log.WARN))
     597                _log.warn("Next hop lookup failure: " + _req);
    583598
    584599            // ???  should we blame the peer here?   getContext().profileManager().tunnelTimedOut(_nextPeer);
    585600            getContext().messageHistory().tunnelRejected(_state.fromHash, new TunnelId(_req.readReceiveTunnelId()), _nextPeer,
    586                                                          "rejected because we couldn't find " + _nextPeer + ": " +
    587                                                          _state.msg.getUniqueId() + "/" + _req.readNextTunnelId());
     601                                                         // this is all disabled anyway
     602                                                         //"rejected because we couldn't find " + _nextPeer + ": " +
     603                                                         //_state.msg.getUniqueId() + "/" + _req.readNextTunnelId());
     604                                                         "lookup fail");
    588605        }
    589606    }
     
    630647        boolean isOutEnd = req.readIsOutboundEndpoint();
    631648
     649        Hash from = state.fromHash;
     650        if (from == null && state.from != null)
     651            from = state.from.calculateHash();
     652        // warning, from could be null, but it should only
     653        // happen if we will be a IBGW and it came from us as a OBEP
     654
    632655        if (isInGW && isOutEnd) {
    633656            _context.statManager().addRateData("tunnel.rejectHostile", 1);
    634             _log.error("Dropping build request, IBGW+OBEP");
     657            _log.error("Dropping build request, IBGW+OBEP: " + req);
     658            if (from != null)
     659                _context.commSystem().mayDisconnect(from);
    635660            return;
    636661        }
     
    643668            // old i2pd
    644669            if (_log.shouldWarn())
    645                 _log.warn("Dropping build request, we are the next hop");
     670                _log.warn("Dropping build request, we are the next hop: " + req);
     671            if (from != null)
     672                _context.commSystem().mayDisconnect(from);
    646673            return;
    647674        }
    648         // previous test should be sufficient to keep it from getting here but maybe not?
    649675        if (!isInGW) {
    650             Hash from = state.fromHash;
    651             if (from == null)
    652                 from = state.from.calculateHash();
    653             if (_context.routerHash().equals(from)) {
     676            // if from is null, it came via OutboundMessageDistributor.distribute(),
     677            // i.e. we were the OBEP, which is fine if we're going to be an IBGW
     678            // but if not, something is seriously wrong here.
     679            if (from == null || _context.routerHash().equals(from)) {
    654680                _context.statManager().addRateData("tunnel.rejectHostile", 1);
    655                 _log.error("Dropping build request, we are the previous hop");
     681                _log.error("Dropping build request, we are the previous hop: " + req);
    656682                return;
    657683            }
    658684        }
    659685        if ((!isOutEnd) && (!isInGW)) {
    660             Hash from = state.fromHash;
    661             if (from == null)
    662                 from = state.from.calculateHash();
    663686            // Previous and next hop the same? Don't help somebody be evil. Drop it without a reply.
    664687            // A-B-C-A is not preventable
     
    667690                _context.statManager().addRateData("tunnel.rejectHostile", 1);
    668691                if (_log.shouldLog(Log.WARN))
    669                     _log.warn("Dropping build request with the same previous and next hop");
     692                    _log.warn("Dropping build request with the same previous and next hop: " + req);
     693                _context.commSystem().mayDisconnect(from);
    670694                return;
    671695            }
     
    681705            _context.statManager().addRateData("tunnel.rejectTooOld", 1);
    682706            if (_log.shouldLog(Log.WARN))
    683                 _log.warn("Dropping build request too old... replay attack? " + DataHelper.formatDuration(timeDiff));
     707                _log.warn("Dropping build request too old... replay attack? " + DataHelper.formatDuration(timeDiff) + ": " + req);
     708            if (from != null)
     709                _context.commSystem().mayDisconnect(from);
    684710            return;
    685711        }
     
    687713            _context.statManager().addRateData("tunnel.rejectFuture", 1);
    688714            if (_log.shouldLog(Log.WARN))
    689                 _log.warn("Dropping build request too far in future " + DataHelper.formatDuration(0 - timeDiff));
     715                _log.warn("Dropping build request too far in future " + DataHelper.formatDuration(0 - timeDiff) + ": " + req);
     716            if (from != null)
     717                _context.commSystem().mayDisconnect(from);
    690718            return;
    691719        }
     
    762790        // We may need another counter above for requests.
    763791        if (response == 0 && !isInGW) {
    764             Hash from = state.fromHash;
    765             if (from == null)
    766                 from = state.from.calculateHash();
    767792            if (from != null && _throttler.shouldThrottle(from)) {
    768793                if (_log.shouldLog(Log.WARN))
    769                     _log.warn("Rejecting tunnel (hop throttle), previous hop: " + from);
     794                    _log.warn("Rejecting tunnel (hop throttle), previous hop: " + from + ": " + req);
    770795                // no setTunnelStatus() indication
    771796                _context.statManager().addRateData("tunnel.rejectHopThrottle", 1);
     
    776801            _throttler.shouldThrottle(nextPeer)) {
    777802            if (_log.shouldLog(Log.WARN))
    778                 _log.warn("Rejecting tunnel (hop throttle), next hop: " + nextPeer);
     803                _log.warn("Rejecting tunnel (hop throttle), next hop: " + req);
    779804            _context.statManager().addRateData("tunnel.rejectHopThrottle", 1);
    780805            // no setTunnelStatus() indication
    781806            response = TunnelHistory.TUNNEL_REJECT_BANDWIDTH;
    782807        }
    783 
    784         if (_log.shouldLog(Log.DEBUG))
    785             _log.debug("Responding to " + state.msg.getUniqueId() + "/" + ourId
    786                        + " after " + recvDelay + " with " + response
    787                        + " from " + (state.fromHash != null ? state.fromHash :
    788                                      state.from != null ? state.from.calculateHash() : "tunnel"));
    789808
    790809        HopConfig cfg = null;
     
    799818                //cfg.setReceiveFrom(null);
    800819            } else {
    801                 if (state.fromHash != null) {
    802                     cfg.setReceiveFrom(state.fromHash);
    803                 } else if (state.from != null) {
    804                     cfg.setReceiveFrom(state.from.calculateHash());
     820                if (from != null) {
     821                    cfg.setReceiveFrom(from);
    805822                } else {
    806823                    // b0rk
     
    828845            if (success) {
    829846                if (_log.shouldLog(Log.DEBUG))
    830                     _log.debug("Joining " + state.msg.getUniqueId() + "/" + cfg.getReceiveTunnel() + "/" + recvDelay + " as " + (isOutEnd ? "outbound endpoint" : isInGW ? "inbound gw" : "participant"));
     847                    _log.debug("Joining: " + req);
    831848            } else {
    832849                // Dup Tunnel ID. This can definitely happen (birthday paradox).
     
    836853                _context.statManager().addRateData("tunnel.rejectDupID", 1);
    837854                if (_log.shouldLog(Log.WARN))
    838                     _log.warn("DUP ID failure " + state.msg.getUniqueId() + "/" + cfg.getReceiveTunnel() + " as " + (isOutEnd ? "outbound endpoint" : isInGW ? "inbound gw" : "participant"));
    839             }
    840         }
     855                    _log.warn("DUP ID failure: " + req);
     856            }
     857        }
     858
     859        // determination of response is now complete
     860
    841861        if (response != 0) {
    842862            _context.statManager().addRateData("tunnel.reject." + response, 1);
    843             _context.messageHistory().tunnelRejected(state.fromHash, new TunnelId(ourId), nextPeer,
    844                                                      "rejecting for " + response + ": " +
    845                                                      state.msg.getUniqueId() + "/" + ourId + "/" + req.readNextTunnelId() + " delay " +
    846                                                      recvDelay + " as " +
    847                                                      (isOutEnd ? "outbound endpoint" : isInGW ? "inbound gw" : "participant"));
    848         }
    849 
    850         // Connection congestion control:
    851         // If we rejected the request, are near our conn limits, and aren't connected to the next hop,
    852         // just drop it.
    853         // 81% = between 75% control measures in Transports and 87% rejection above
    854         if (response != 0 &&
    855             (! _context.routerHash().equals(nextPeer)) &&
    856             (! _context.commSystem().haveOutboundCapacity(81)) &&
    857             (! _context.commSystem().isEstablished(nextPeer))) {
    858             _context.statManager().addRateData("tunnel.dropConnLimits", 1);
    859             if (_log.shouldLog(Log.WARN))
    860                 _log.warn("Not sending rejection due to conn limits");
    861             return;
    862         }
     863            _context.messageHistory().tunnelRejected(from, new TunnelId(ourId), nextPeer,
     864                                                     // this is all disabled anyway
     865                                                     //"rejecting for " + response + ": " +
     866                                                     //state.msg.getUniqueId() + "/" + ourId + "/" + req.readNextTunnelId() + " delay " +
     867                                                     //recvDelay + " as " +
     868                                                     //(isOutEnd ? "outbound endpoint" : isInGW ? "inbound gw" : "participant"));
     869                                                     Integer.toString(response));
     870            if (from != null)
     871                _context.commSystem().mayDisconnect(from);
     872            // Connection congestion control:
     873            // If we rejected the request, are near our conn limits, and aren't connected to the next hop,
     874            // just drop it.
     875            // 81% = between 75% control measures in Transports and 87% rejection above
     876            if ((! _context.routerHash().equals(nextPeer)) &&
     877                (! _context.commSystem().haveOutboundCapacity(81)) &&
     878                (! _context.commSystem().isEstablished(nextPeer))) {
     879                _context.statManager().addRateData("tunnel.dropConnLimits", 1);
     880                if (_log.shouldLog(Log.WARN))
     881                    _log.warn("Not sending rejection due to conn limits: " + req);
     882                return;
     883            }
     884        } else if (isInGW && from != null) {
     885            // we're the start of the tunnel, no use staying connected
     886            _context.commSystem().mayDisconnect(from);
     887        }
     888
     889        if (_log.shouldLog(Log.DEBUG))
     890            _log.debug("Responding to " + state.msg.getUniqueId()
     891                       + " after " + recvDelay + " with " + response
     892                       + " from " + (from != null ? from : "tunnel") + ": " + req);
    863893
    864894        EncryptedBuildRecord reply = BuildResponseRecord.create(_context, response, req.readReplyKey(), req.readReplyIV(), state.msg.getUniqueId());
     
    877907
    878908        if (_log.shouldLog(Log.DEBUG))
    879             _log.debug("Read slot " + ourSlot + " containing our hop @ " + _context.routerHash()
    880                       + " accepted? " + response + " receiving on " + ourId
    881                       + " sending to " + nextId
    882                       + " on " + nextPeer
    883                       + " inGW? " + isInGW + " outEnd? " + isOutEnd
    884                       + " recvDelay " + recvDelay + " replyMessage " + req.readReplyMessageId()
    885                       + " replyKey " + req.readReplyKey() + " replyIV " + Base64.encode(req.readReplyIV()));
     909            _log.debug("Read slot " + ourSlot + " containing: " + req
     910                      + " accepted? " + response
     911                      + " recvDelay " + recvDelay + " replyMessage " + req.readReplyMessageId());
    886912
    887913        // now actually send the response
     914        long expires = _context.clock().now() + NEXT_HOP_SEND_TIMEOUT;
    888915        if (!isOutEnd) {
    889916            state.msg.setUniqueId(req.readReplyMessageId());
    890             state.msg.setMessageExpiration(_context.clock().now() + NEXT_HOP_SEND_TIMEOUT);
    891             OutNetMessage msg = new OutNetMessage(_context, state.msg, state.msg.getMessageExpiration(), PRIORITY, nextPeerInfo);
     917            state.msg.setMessageExpiration(expires);
     918            OutNetMessage msg = new OutNetMessage(_context, state.msg, expires, PRIORITY, nextPeerInfo);
    892919            if (response == 0)
    893920                msg.setOnFailedSendJob(new TunnelBuildNextHopFailJob(_context, cfg));
     
    905932                replyMsg.setRecord(i, state.msg.getRecord(i));
    906933            replyMsg.setUniqueId(req.readReplyMessageId());
    907             replyMsg.setMessageExpiration(_context.clock().now() + NEXT_HOP_SEND_TIMEOUT);
     934            replyMsg.setMessageExpiration(expires);
    908935            TunnelGatewayMessage m = new TunnelGatewayMessage(_context);
    909936            m.setMessage(replyMsg);
    910             m.setMessageExpiration(replyMsg.getMessageExpiration());
     937            m.setMessageExpiration(expires);
    911938            m.setTunnelId(new TunnelId(nextId));
    912939            if (_context.routerHash().equals(nextPeer)) {
     
    914941                if (_log.shouldLog(Log.DEBUG))
    915942                    _log.debug("We are the reply gateway for " + nextId
    916                               + " when replying to replyMessage " + req.readReplyMessageId());
     943                              + " when replying to replyMessage " + req);
    917944                _context.tunnelDispatcher().dispatch(m);
    918945            } else {
    919946                // ok, the gateway is some other peer, shove 'er across
    920                 OutNetMessage outMsg = new OutNetMessage(_context, m, m.getMessageExpiration(), PRIORITY, nextPeerInfo);
     947                OutNetMessage outMsg = new OutNetMessage(_context, m, expires, PRIORITY, nextPeerInfo);
    921948                if (response == 0)
    922949                    outMsg.setOnFailedSendJob(new TunnelBuildNextHopFailJob(_context, cfg));
     
    935962     */
    936963    private class TunnelBuildMessageHandlerJobBuilder implements HandlerJobBuilder {
     964
     965        /**
     966         *  Either from or fromHash may be null, but both should be null only if
     967         *  we're to be a IBGW and it came from us as a OBEP.
     968         */
    937969        public Job createJob(I2NPMessage receivedMessage, RouterIdentity from, Hash fromHash) {
    938970            // need to figure out if this is a reply to an inbound tunnel request (where we are the
     
    940972            long reqId = receivedMessage.getUniqueId();
    941973            PooledTunnelCreatorConfig cfg = _exec.removeFromBuilding(reqId);
    942             if (_log.shouldLog(Log.DEBUG))
    943                 _log.debug("Receive tunnel build message " + reqId + " from "
    944                            + (from != null ? from.calculateHash() : fromHash != null ? fromHash : "tunnels")
    945                            + ", found matching tunnel? " + (cfg != null));
     974            //if (_log.shouldLog(Log.DEBUG))
     975            //    _log.debug("Receive tunnel build message " + reqId + " from "
     976            //               + (from != null ? from.calculateHash() : fromHash != null ? fromHash : "tunnels")
     977            //               + ", found matching tunnel? " + (cfg != null));
    946978            if (cfg != null) {
    947979                if (!cfg.isInbound()) {
     
    9781010                        if (fh != null && _requestThrottler.shouldThrottle(fh)) {
    9791011                            if (_log.shouldLog(Log.WARN))
    980                                 _log.warn("Dropping tunnel request (from throttle), previous hop: " + from);
     1012                                _log.warn("Dropping tunnel request (from throttle), previous hop: " + fh);
    9811013                            _context.statManager().addRateData("tunnel.dropReqThrottle", 1);
    9821014                            accept = false;
     
    10611093        final long recvTime;
    10621094
     1095        /**
     1096         *  Either f or h may be null, but both should be null only if
     1097         *  we're to be a IBGW and it came from us as a OBEP.
     1098         */
    10631099        public BuildMessageState(RouterContext ctx, I2NPMessage m, RouterIdentity f, Hash h) {
    10641100            _ctx = ctx;
     
    11351171
    11361172        public void runJob() {
    1137             getContext().tunnelDispatcher().remove(_cfg);
     1173            //  TODO
     1174            //  This doesn't seem to be a reliable indication of actual failure,
     1175            //  as we sometimes get subsequent tunnel messages.
     1176            //  Until this is investigated and fixed, don't remove the tunnel.
     1177            //getContext().tunnelDispatcher().remove(_cfg);
    11381178            getContext().statManager().addRateData("tunnel.rejectTimeout2", 1);
    11391179            Log log = getContext().logManager().getLog(BuildHandler.class);
  • router/java/src/net/i2p/router/util/CachedIteratorArrayList.java

    r9bb1a00 r07e85e0  
    1 package net.i2p.util;
     1package net.i2p.router.util;
    22
    33import java.io.Serializable;
     
    1212 * while keeping the conveniences of an iterator.
    1313 *
    14  * @since 0.9.4
     14 * @since 0.9.4 moved from net.i2p.util in 0.9.24
    1515 *
    1616 * @author zab
  • router/java/src/net/i2p/router/util/DecayingBloomFilter.java

    r9bb1a00 r07e85e0  
    6262        _longToEntryMask = 0;
    6363        context.addShutdownTask(new Shutdown());
    64         _decayEvent = new DecayEvent();
    6564        _keepDecaying = true;
    66         _decayEvent.schedule(_durationMs);
     65        if (_durationMs == 60*60*1000) {
     66            // special mode for BuildMessageProcessor
     67            _decayEvent = new DecayHourlyEvent();
     68        } else {
     69            _decayEvent = new DecayEvent();
     70            _decayEvent.schedule(_durationMs);
     71        }
    6772    }
    6873
    6974    /**
    7075     * Create a bloom filter that will decay its entries over time. 
     76     * Uses default m of 23, memory usage is 2 MB.
    7177     *
    7278     * @param durationMs entries last for at least this long, but no more than twice this long
     
    7985    }
    8086
    81     /** @param name just for logging / debugging / stats */
     87    /**
     88     * Uses default m of 23, memory usage is 2 MB.
     89     * @param name just for logging / debugging / stats
     90     */
    8291    public DecayingBloomFilter(I2PAppContext context, int durationMs, int entryBytes, String name) {
    8392        // this is instantiated in four different places, they may have different
     
    8897
    8998    /**
     99     * Memory usage is 2 * (2**m) bits or 2**(m-2) bytes.
     100     *
    90101     * @param m filter size exponent, max is 29
    91102     */
     
    124135            _longToEntryMask = 0;
    125136        }
    126         _decayEvent = new DecayEvent();
    127137        _keepDecaying = true;
    128         _decayEvent.schedule(_durationMs);
     138        if (_durationMs == 60*60*1000) {
     139            // special mode for BuildMessageProcessor
     140            _decayEvent = new DecayHourlyEvent();
     141        } else {
     142            _decayEvent = new DecayEvent();
     143            _decayEvent.schedule(_durationMs);
     144        }
    129145        if (_log.shouldLog(Log.WARN))
    130146           _log.warn("New DBF " + name + " m = " + m + " k = " + k + " entryBytes = " + entryBytes +
     
    319335   
    320336    private class DecayEvent extends SimpleTimer2.TimedEvent {
     337        /**
     338         *  Caller MUST schedule.
     339         */
    321340        DecayEvent() {
    322341            super(_context.simpleTimer2());
    323342        }
    324        
     343
    325344        public void timeReached() {
    326345            if (_keepDecaying) {
     
    328347                schedule(_durationMs);
    329348            }
     349        }
     350    }
     351   
     352    /**
     353     *  Decays at 5 minutes after the top of the hour.
     354     *  This ignores leap seconds.
     355     *  @since 0.9.24
     356     */
     357    private class DecayHourlyEvent extends SimpleTimer2.TimedEvent {
     358        private static final long HOUR = 60 * 60 * 1000L;
     359        private static final long LAG = 5 * 60 * 1000L;
     360        private volatile long _currentHour;
     361
     362        /**
     363         *  Schedules itself. Caller MUST NOT schedule.
     364         */
     365        DecayHourlyEvent() {
     366            super(_context.simpleTimer2());
     367            schedule(getTimeTillNextHour());
     368        }
     369
     370        public void timeReached() {
     371            if (_keepDecaying) {
     372                long now = _context.clock().now();
     373                long currentHour = now / HOUR;
     374                // handle possible clock adjustments
     375                if (_currentHour != currentHour) {
     376                    decay();
     377                    _currentHour = currentHour;
     378                }
     379                long next = ((1 + currentHour) * HOUR) + LAG;
     380                schedule(Math.max(5000, next - now));
     381            }
     382        }
     383
     384        /** side effect: sets _currentHour */
     385        private long getTimeTillNextHour() {
     386            long now = _context.clock().now();
     387            long currentHour = now / HOUR;
     388            _currentHour = currentHour;
     389            long next = ((1 + currentHour) * HOUR) + LAG;
     390            return Math.max(5000, next - now);
    330391        }
    331392    }
  • router/java/src/net/i2p/router/util/EventLog.java

    r9bb1a00 r07e85e0  
    1616import net.i2p.data.DataHelper;
    1717import net.i2p.util.SecureFileOutputStream;
     18import net.i2p.util.SystemVersion;
    1819
    1920/**
     
    9596            if (info != null && info.length() > 0)
    9697                buf.append(' ').append(info);
     98            if (SystemVersion.isWindows())
     99                buf.append('\r');
    97100            buf.append('\n');
    98101            out.write(buf.toString().getBytes("UTF-8"));
     
    127130            while ( (line = br.readLine()) != null) {
    128131                try {
    129                     String[] s = DataHelper.split(line, " ", 3);
     132                    String[] s = DataHelper.split(line.trim(), " ", 3);
    130133                    if (!s[1].equals(event))
    131134                        continue;
     
    169172            while ( (line = br.readLine()) != null) {
    170173                try {
    171                     String[] s = DataHelper.split(line, " ", 2);
     174                    String[] s = DataHelper.split(line.trim(), " ", 2);
    172175                    if (s.length < 2)
    173176                        continue;
  • router/java/src/net/i2p/router/util/RouterPasswordManager.java

    r9bb1a00 r07e85e0  
    159159        if (user != null && user.length() > 0)
    160160            pfx += '.' + user;
    161         byte[] salt = new byte[SALT_LENGTH];
    162         _context.random().nextBytes(salt);
    163         byte[] pwHash = _context.keyGenerator().generateSessionKey(salt, DataHelper.getUTF8(pw)).getData();
    164         byte[] shashBytes = new byte[SHASH_LENGTH];
    165         System.arraycopy(salt, 0, shashBytes, 0, SALT_LENGTH);
    166         System.arraycopy(pwHash, 0, shashBytes, SALT_LENGTH, SessionKey.KEYSIZE_BYTES);
    167         String shash = Base64.encode(shashBytes);
     161        String shash = createHash(pw);
    168162        Map<String, String> toAdd = Collections.singletonMap(pfx + PROP_SHASH, shash);
    169163        List<String> toDel = new ArrayList<String>(4);
  • router/java/test/junit/net/i2p/router/crypto/SessionEncryptionTest.java

    r9bb1a00 r07e85e0  
    4747        SessionKey curKey = skm.createSession(pubKey);
    4848       
    49         byte[] msg = "msg 1".getBytes();
     49        byte[] msg = DataHelper.getASCII("msg 1");
    5050       
    5151        byte emsg[] = _context.elGamalAESEngine().encrypt(msg, pubKey, curKey, 64);
     
    6161        SessionKey curKey = skm.createSession(pubKey);
    6262       
    63         byte[] msg = "msg 2".getBytes();
     63        byte[] msg = DataHelper.getASCII("msg 2");
    6464       
    6565        byte emsg[] = _context.elGamalAESEngine().encrypt(msg, pubKey, curKey, 64);
     
    9696        secondTags.add(tag4);
    9797       
    98         byte[] msg1 = "msg 1".getBytes();
    99         byte[] msg2 = "msg 2".getBytes();
    100         byte[] msg3 = "msg 3".getBytes();
    101         byte[] msg4 = "msg 4".getBytes();
    102         byte[] msg5 = "msg 5".getBytes();
     98        byte[] msg1 = DataHelper.getASCII("msg 1");
     99        byte[] msg2 = DataHelper.getASCII("msg 2");
     100        byte[] msg3 = DataHelper.getASCII("msg 3");
     101        byte[] msg4 = DataHelper.getASCII("msg 4");
     102        byte[] msg5 = DataHelper.getASCII("msg 5");
    103103       
    104104        byte emsg1[] = _context.elGamalAESEngine().encrypt(msg1, pubKey, curKey, firstTags, 64);
     
    196196        secondTags.add(tag4);
    197197       
    198         byte[] msg1 = "msg 1".getBytes();
    199         byte[] msg2 = "msg 2".getBytes();
    200         byte[] msg3 = "msg 3".getBytes();
    201         byte[] msg4 = "msg 4".getBytes();
    202         byte[] msg5 = "msg 5".getBytes();
     198        byte[] msg1 = DataHelper.getASCII("msg 1");
     199        byte[] msg2 = DataHelper.getASCII("msg 2");
     200        byte[] msg3 = DataHelper.getASCII("msg 3");
     201        byte[] msg4 = DataHelper.getASCII("msg 4");
     202        byte[] msg5 = DataHelper.getASCII("msg 5");
    203203       
    204204        byte emsg1[] = _context.elGamalAESEngine().encrypt(msg1, pubKey, curKey, firstTags, 64);
     
    292292                nextKey = KeyGenerator.getInstance().generateSessionKey();
    293293           
    294             byte[] msg = ("msg " + i).getBytes();
     294            byte[] msg = DataHelper.getASCII("msg " + i);
    295295           
    296296            byte emsg[] = _context.elGamalAESEngine().encrypt(msg, pubKey, curKey, tags, curTag, nextKey, 64);
  • router/java/test/junit/net/i2p/router/transport/crypto/DHSessionKeyBuilderTest.java

    r9bb1a00 r07e85e0  
    1414import junit.framework.TestCase;
    1515import net.i2p.I2PAppContext;
     16import net.i2p.data.DataHelper;
    1617import net.i2p.data.SessionKey;
    1718import net.i2p.util.RandomSource;
     
    4142            byte enc[] = new byte[16];
    4243            byte dec[] = new byte[16];
    43             ctx.aes().encrypt(origVal.getBytes(), 0, enc, 0, key1, iv, 16);
     44            ctx.aes().encrypt(DataHelper.getASCII(origVal), 0, enc, 0, key1, iv, 16);
    4445            ctx.aes().decrypt(enc, 0, dec, 0, key2, iv, 16);
    4546            String tranVal = new String(dec);
  • router/java/test/junit/net/i2p/router/util/CachedIteratorArrayListTest.java

    r9bb1a00 r07e85e0  
    1 package net.i2p.util;
     1package net.i2p.router.util;
    22
    33import static org.junit.Assert.*;
Note: See TracChangeset for help on using the changeset viewer.