Changeset 7e87208


Ignore:
Timestamp:
Dec 10, 2015 1:03:49 PM (4 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
9b2bbe0
Parents:
77a6db1
Message:

Router:

  • Change addCapabilities() to getCapabilities()
  • Add netdb family sign/verify utility (ticket #1510) (verify not yet used)

RouterInfo?:

  • Remove addCapability() and delCapability()

StatPublisher?:

  • Remove Service interface, not required
  • Consolidate getCapabilities() and network ID here
  • Add family signatures
  • Remove unused coreVersion and stat_uptime (as of 0.9.24)
Location:
router/java/src/net/i2p
Files:
1 added
8 edited

Legend:

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

    r77a6db1 r7e87208  
    433433        }
    434434        return (bwTier);
    435     }
    436 
    437     /**
    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             }
    473435    }
    474436
  • router/java/src/net/i2p/router/Router.java

    r77a6db1 r7e87208  
    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;
    9195   
    9296    public final static String PROP_CONFIG_FILE = "router.configLocation";
     
    831835     */
    832836    private void locked_rebuildRouterInfo(boolean blockingRebuild) {
    833         RouterInfo ri = null;
     837        RouterInfo ri;
    834838        if (_routerInfo != null)
    835839            ri = new RouterInfo(_routerInfo);
     
    840844            ri.setPublished(_context.clock().now());
    841845            Properties stats = _context.statPublisher().publishStatistics();
    842             stats.setProperty(RouterInfo.PROP_NETWORK_ID, NETWORK_ID+"");
    843846           
    844847            ri.setOptions(stats);
    845848            ri.setAddresses(_context.commSystem().createAddresses());
    846849
    847             addCapabilities(ri);
    848850            SigningPrivateKey key = _context.keyManager().getSigningPrivateKey();
    849851            if (key == null) {
     
    865867    }
    866868
     869    /**
     870     *  Family Key Crypto Signer / Verifier.
     871     *  Not for external use.
     872     *  If family key is set, first call Will take a while to generate keys.
     873     *  Warning - risk of deadlock - do not call while holding locks
     874     *  (other than routerInfoLock)
     875     *
     876     *  @return null on initialization failure
     877     *  @since 0.9.24
     878     */
     879    public FamilyKeyCrypto getFamilyKeyCrypto() {
     880        synchronized (_routerInfoLock) {
     881            if (_familyKeyCrypto == null) {
     882                if (!_familyKeyCryptoFail) {
     883                    try {
     884                        _familyKeyCrypto = new FamilyKeyCrypto(_context);
     885                    } catch (GeneralSecurityException gse) {
     886                        _log.error("Failed to initialize family key crypto", gse);
     887                        _familyKeyCryptoFail = true;
     888                    }
     889                }
     890            }
     891        }
     892        return _familyKeyCrypto;
     893    }
     894
    867895    // publicize our ballpark capacity
    868896    public static final char CAPABILITY_BW12 = 'K';
     
    888916    /**
    889917     *  For building our RI. Not for external use.
    890      *  This does not publish the ri.
    891      *  This does not use anything in the ri (i.e. it can be freshly constructed)
    892      *
    893      *  TODO just return a string instead of passing in the RI? See PublishLocalRouterInfoJob.
    894      *
    895      *  @param ri an unpublished ri we are generating.
    896      */
    897     public void addCapabilities(RouterInfo ri) {
     918     *
     919     *  @return a capabilities string to be added to the RI
     920     */
     921    String getCapabilities() {
     922        StringBuilder rv = new StringBuilder(4);
    898923        int bwLim = Math.min(_context.bandwidthLimiter().getInboundKBytesPerSecond(),
    899924                             _context.bandwidthLimiter().getOutboundKBytesPerSecond());
     
    904929        String force = _context.getProperty(PROP_FORCE_BWCLASS);
    905930        if (force != null && force.length() > 0) {
    906             ri.addCapability(force.charAt(0));
     931            rv.append(force.charAt(0));
    907932        } else if (bwLim < 12) {
    908             ri.addCapability(CAPABILITY_BW12);
     933            rv.append(CAPABILITY_BW12);
    909934        } else if (bwLim <= 48) {
    910             ri.addCapability(CAPABILITY_BW32);
     935            rv.append(CAPABILITY_BW32);
    911936        } else if (bwLim <= 64) {
    912             ri.addCapability(CAPABILITY_BW64);
     937            rv.append(CAPABILITY_BW64);
    913938        } else if (bwLim <= 128) {
    914             ri.addCapability(CAPABILITY_BW128);
     939            rv.append(CAPABILITY_BW128);
    915940        } else if (bwLim <= 256) {
    916             ri.addCapability(CAPABILITY_BW256);
     941            rv.append(CAPABILITY_BW256);
    917942        } else if (bwLim <= 2000) {    // TODO adjust threshold
    918943            // 512 supported as of 0.9.18;
    919944            // Add 256 as well for compatibility
    920             ri.addCapability(CAPABILITY_BW512);
    921             ri.addCapability(CAPABILITY_BW256);
     945            rv.append(CAPABILITY_BW512);
     946            rv.append(CAPABILITY_BW256);
    922947        } else {
    923948            // Unlimited supported as of 0.9.18;
    924949            // Add 256 as well for compatibility
    925             ri.addCapability(CAPABILITY_BW_UNLIMITED);
    926             ri.addCapability(CAPABILITY_BW256);
     950            rv.append(CAPABILITY_BW_UNLIMITED);
     951            rv.append(CAPABILITY_BW256);
    927952        }
    928953       
     
    930955        if (_context.netDb().floodfillEnabled() &&
    931956            !_context.getBooleanProperty("router.hideFloodfillParticipant"))
    932             ri.addCapability(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL);
     957            rv.append(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL);
    933958       
    934959        if(_context.getBooleanProperty(PROP_HIDDEN))
    935             ri.addCapability(RouterInfo.CAPABILITY_HIDDEN);
     960            rv.append(RouterInfo.CAPABILITY_HIDDEN);
    936961       
    937962        if (_context.getBooleanProperty(PROP_FORCE_UNREACHABLE)) {
    938             ri.addCapability(CAPABILITY_UNREACHABLE);
    939             return;
     963            rv.append(CAPABILITY_UNREACHABLE);
     964            return rv.toString();
    940965        }
    941966        switch (_context.commSystem().getStatus()) {
     
    947972            case IPV4_UNKNOWN_IPV6_OK:
    948973            case IPV4_SNAT_IPV6_OK:
    949                 ri.addCapability(CAPABILITY_REACHABLE);
     974                rv.append(CAPABILITY_REACHABLE);
    950975                break;
    951976
     
    953978            case REJECT_UNSOLICITED:
    954979            case IPV4_DISABLED_IPV6_FIREWALLED:
    955                 ri.addCapability(CAPABILITY_UNREACHABLE);
     980                rv.append(CAPABILITY_UNREACHABLE);
    956981                break;
    957982
     
    967992                break;
    968993        }
     994        return rv.toString();
    969995    }
    970996   
     
    11791205        try { _context.namingService().shutdown(); } catch (Throwable t) { _log.error("Error shutting down the naming service", t); }
    11801206        try { _context.jobQueue().shutdown(); } catch (Throwable t) { _log.error("Error shutting down the job queue", t); }
    1181         try { _context.statPublisher().shutdown(); } catch (Throwable t) { _log.error("Error shutting down the stats publisher", t); }
    11821207        try { _context.tunnelManager().shutdown(); } catch (Throwable t) { _log.error("Error shutting down the tunnel manager", t); }
    11831208        try { _context.tunnelDispatcher().shutdown(); } catch (Throwable t) { _log.error("Error shutting down the tunnel dispatcher", t); }
  • router/java/src/net/i2p/router/StatisticsManager.java

    r77a6db1 r7e87208  
    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;
     
    3236    public final static String PROP_PUBLISH_RANKINGS = "router.publishPeerRankings";
    3337    private static final String PROP_CONTACT_NAME = "netdb.contact";
    34     private static final String PROP_FAMILY_NAME = "netdb.family.name";
    35     private static final String PROP_FAMILY_KEY = "netdb.family.key";
    36     private static final String PROP_FAMILY_SIG = "netdb.family.sig";
    3738    /** enhance anonymity by only including build stats one out of this many times */
    3839    private static final int RANDOM_INCLUDE_STATS = 16;
     
    4849    }
    4950       
    50     /** noop */
    51     public void shutdown() {}
    52 
    53     /** noop */
    54     public void restart() {}
    55 
    56     /** noop */
    57     public void startup() {}
    58    
    59     /** 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     */
    6056    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 current router hash, non-null
     67     *  @since 0.9.24
     68     */
     69    public Properties publishStatistics(Hash h) {
    6170        Properties stats = new Properties();
    6271        stats.setProperty("router.version", RouterVersion.VERSION);
    63         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());
    6477
    6578        // No longer expose, to make build tracking more expensive
     
    153166        }
    154167
    155         // So that we will still get build requests
    156         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");
    157172        if (FloodfillNetworkDatabaseFacade.isFloodfill(_context.router().getRouterInfo())) {
    158173            int ri = _context.router().getUptime() > 30*60*1000 ?
     
    169184        if (contact != null)
    170185            stats.setProperty("contact", contact);
    171         String family = _context.getProperty(PROP_FAMILY_NAME);
     186
     187        String family = _context.getProperty(FamilyKeyCrypto.PROP_FAMILY_NAME);
    172188        if (family != null) {
    173             stats.setProperty("family", family);
    174             // TODO
    175             //String key = _context.getProperty(PROP_FAMILY_KEY);
    176             //if (key != null) {
    177                 // get privkey
    178                 // sign something
    179                 // add b64 sig
    180             //}
     189            stats.setProperty(FamilyKeyCrypto.OPT_NAME, family);
     190            String sig = null;
     191            RouterInfo oldRI = _context.router().getRouterInfo();
     192            if (oldRI != null) {
     193                // don't do it if family changed
     194                if (family.equals(oldRI.getOption(FamilyKeyCrypto.OPT_NAME))) {
     195                    // copy over the signature
     196                    sig = oldRI.getOption(FamilyKeyCrypto.OPT_SIG);
     197                    if (sig != null)
     198                        stats.setProperty(FamilyKeyCrypto.OPT_SIG, sig);
     199                }
     200            }
     201            if (sig == null) {
     202                FamilyKeyCrypto fkc = _context.router().getFamilyKeyCrypto();
     203                if (fkc != null) {
     204                    try {
     205                        sig = fkc.sign(family, h);
     206                        stats.setProperty(FamilyKeyCrypto.OPT_SIG, sig);
     207                    } catch (GeneralSecurityException gse) {
     208                        _log.error("Failed to sign router family", gse);
     209                    }
     210                }
     211            }
    181212        }
    182213
  • router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java

    r77a6db1 r7e87208  
    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/startup/CreateRouterInfoJob.java

    r77a6db1 r7e87208  
    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/LoadRouterInfoJob.java

    r77a6db1 r7e87208  
    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           
  • router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java

    r77a6db1 r7e87208  
    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

    r77a6db1 r7e87208  
    3737        if (!SystemVersion.isAndroid())
    3838            getContext().jobQueue().addJob(new LoadClientAppsJob(getContext()));
    39         getContext().statPublisher().startup();
    4039        getContext().jobQueue().addJob(new LoadRouterInfoJob(getContext()));
    4140    }
Note: See TracChangeset for help on using the changeset viewer.