Changeset 9089fdd


Ignore:
Timestamp:
Nov 26, 2005 9:16:11 AM (15 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
70c4560
Parents:
ef82cc4
git-author:
jrandom <jrandom> (11/26/05 09:16:11)
git-committer:
zzz <zzz@…> (11/26/05 09:16:11)
Message:

2005-11-26 Raccoon23

  • Added support for 'dynamic keys' mode, where the router creates a new router identity whenever it detects a substantial change in its public address (read: SSU IP or port). This only offers minimal additional protection against trivial attackers, but should provide functional improvement for people who have periodic IP changes, since their new router address would not be shitlisted while their old one would be.
  • Added further infrastructure for restricted route operation, but its use is not recommended.
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHandler.java

    ref82cc4 r9089fdd  
    1818import net.i2p.time.Timestamper;
    1919import net.i2p.router.transport.udp.UDPTransport;
     20import net.i2p.router.Router;
     21import net.i2p.data.RouterInfo;
     22import net.i2p.router.web.ConfigServiceHandler.UpdateWrapperManagerTask;
     23import net.i2p.router.web.ConfigServiceHandler.UpdateWrapperManagerAndRekeyTask;
    2024
    2125/**
     
    3236    private boolean _timeSyncEnabled;
    3337    private boolean _requireIntroductions;
     38    private boolean _hiddenMode;
     39    private boolean _dynamicKeys;
    3440    private String _tcpPort;
    3541    private String _udpPort;
     
    6369    public void setRecheckReachability(String moo) { _recheckReachabilityRequested = true; }
    6470    public void setRequireIntroductions(String moo) { _requireIntroductions = true; }
     71    public void setHiddenMode(String moo) { _hiddenMode = true; }
     72    public void setDynamicKeys(String moo) { _dynamicKeys = true; }
    6573   
    6674    public void setHostname(String hostname) {
     
    264272            }
    265273        }
     274
     275        // If hidden mode value changes, restart is required
     276        if (_hiddenMode && "false".equalsIgnoreCase(_context.getProperty(Router.PROP_HIDDEN, "false"))) {
     277            _context.router().setConfigSetting(Router.PROP_HIDDEN, "true");
     278            _context.router().getRouterInfo().addCapability(RouterInfo.CAPABILITY_HIDDEN);
     279            addFormNotice("Gracefully restarting into Hidden Router Mode. Make sure you have no 0-1 length "
     280                          + "<a href=\"configtunnels.jsp\">tunnels!</a>");
     281            hiddenSwitch();
     282        }
     283
     284        if (!_hiddenMode && "true".equalsIgnoreCase(_context.getProperty(Router.PROP_HIDDEN, "false"))) {
     285            _context.router().removeConfigSetting(Router.PROP_HIDDEN);
     286            _context.router().getRouterInfo().delCapability(RouterInfo.CAPABILITY_HIDDEN);
     287            addFormNotice("Gracefully restarting to exit Hidden Router Mode");
     288            hiddenSwitch();
     289        }
     290
     291        if (_dynamicKeys) {
     292            _context.router().setConfigSetting(Router.PROP_DYNAMIC_KEYS, "true");
     293        } else {
     294            _context.router().removeConfigSetting(Router.PROP_DYNAMIC_KEYS);
     295        }
    266296       
    267297        if (_requireIntroductions) {
     
    290320            addFormNotice("Soft restart complete");
    291321        }
     322    }
     323
     324    private void hiddenSwitch() {
     325        // Full restart required to generate new keys
     326        _context.router().addShutdownTask(new UpdateWrapperManagerAndRekeyTask(Router.EXIT_GRACEFUL_RESTART));
     327        _context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
    292328    }
    293329   
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigNetHelper.java

    ref82cc4 r9089fdd  
    77import net.i2p.router.transport.udp.UDPAddress;
    88import net.i2p.router.transport.udp.UDPTransport;
     9import net.i2p.router.Router;
    910
    1011public class ConfigNetHelper {
     
    6465    }
    6566   
     67    public String getHiddenModeChecked() {
     68        String enabled = _context.getProperty(Router.PROP_HIDDEN, "false");
     69        if ( (enabled != null) && ("true".equalsIgnoreCase(enabled)) )
     70            return " checked ";
     71        else
     72            return "";
     73    }
     74
     75    public String getDynamicKeysChecked() {
     76        String enabled = _context.getProperty(Router.PROP_DYNAMIC_KEYS, "false");
     77        if ( (enabled != null) && ("true".equalsIgnoreCase(enabled)) )
     78            return " checked ";
     79        else
     80            return "";
     81    }
     82
    6683    public String getRequireIntroductionsChecked() {
    6784        short status = _context.commSystem().getReachabilityStatus();
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java

    ref82cc4 r9089fdd  
    2828        public void run() {
    2929            try {
     30                WrapperManager.signalStopped(_exitCode);
     31            } catch (Throwable t) {
     32                t.printStackTrace();
     33            }
     34        }
     35    }
     36
     37    public static class UpdateWrapperManagerAndRekeyTask implements Runnable {
     38        private int _exitCode;
     39        public UpdateWrapperManagerAndRekeyTask(int exitCode) {
     40            _exitCode = exitCode;
     41        }
     42        public void run() {
     43            try {
     44                Router.killKeys();
    3045                WrapperManager.signalStopped(_exitCode);
    3146            } catch (Throwable t) {
     
    5772            _context.router().shutdown(Router.EXIT_HARD_RESTART);
    5873            addFormNotice("Hard restart requested");
     74        } else if ("Rekey and Restart".equals(_action)) {
     75            addFormNotice("Rekeying after graceful restart");
     76            _context.router().addShutdownTask(new UpdateWrapperManagerAndRekeyTask(Router.EXIT_GRACEFUL_RESTART));
     77            _context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
     78        } else if ("Rekey and Shutdown".equals(_action)) {
     79            addFormNotice("Rekeying after graceful shutdown");
     80            _context.router().addShutdownTask(new UpdateWrapperManagerAndRekeyTask(Router.EXIT_GRACEFUL));
     81            _context.router().shutdownGracefully(Router.EXIT_GRACEFUL);
    5982        } else if ("Run I2P on startup".equals(_action)) {
    6083            installService();
  • apps/routerconsole/jsp/config.jsp

    ref82cc4 r9089fdd  
    5959 Sharing a higher percentage will improve your anonymity and help the network
    6060 <hr />
     61 <b>Dynamic Router Keys: </b>
     62 <input type="checkbox" name="dynamicKeys" value="true" <jsp:getProperty name="nethelper" property="dynamicKeysChecked" /> /><br />
     63 <p>
     64 This setting causes your router identity to be regenerated every time your IP address
     65 changes. If you have a dynamic IP this option can speed up your reintegration into
     66 the network (since people will have shitlisted your old router identity), and, for
     67 very weak adversaries, help frustrate trivial
     68 <a href="http://www.i2p.net/how_threatmodel#intersection">intersection
     69 attacks</a> against the NetDB.  Your different router identities would only be
     70 'hidden' among other I2P users at your ISP, and further analysis would link
     71 the router identities further.</p>
     72 <p>Note that when I2P detects an IP address change, it will automatically
     73 initiate a restart in order to rekey and to disconnect from peers before they
     74 update their profiles - any long lasting client connections will be disconnected,
     75 though such would likely already be the case anyway, since the IP address changed.
     76 </p>
     77 <hr />
    6178 <input type="submit" name="save" value="Save changes" /> <input type="reset" value="Cancel" /><br />
    6279 </form>
  • core/java/src/net/i2p/data/RouterInfo.java

    ref82cc4 r9089fdd  
    5252    public static final String PROP_NETWORK_ID = "netId";
    5353    public static final String PROP_CAPABILITIES = "caps";
     54    public static final char CAPABILITY_HIDDEN = 'H';
     55
    5456   
    5557    public RouterInfo() {
     
    251253            _identity.writeBytes(out);
    252254            DataHelper.writeDate(out, new Date(_published));
    253             DataHelper.writeLong(out, 1, _addresses.size());
    254             List addresses = DataHelper.sortStructures(_addresses);
    255             for (Iterator iter = addresses.iterator(); iter.hasNext();) {
    256                 RouterAddress addr = (RouterAddress) iter.next();
    257                 addr.writeBytes(out);
     255            if (isHidden()) {
     256                // Do not send IP address to peers in hidden mode
     257                DataHelper.writeLong(out, 1, 0);
     258            } else {
     259                DataHelper.writeLong(out, 1, _addresses.size());
     260                List addresses = DataHelper.sortStructures(_addresses);
     261                for (Iterator iter = addresses.iterator(); iter.hasNext();) {
     262                    RouterAddress addr = (RouterAddress) iter.next();
     263                    addr.writeBytes(out);
     264                }
    258265            }
     266            // XXX: what about peers?
     267            // answer: they're always empty... they're a placeholder for one particular
     268            //         method of trusted links, which isn't implemented in the router
     269            //         at the moment, and may not be later.
    259270            DataHelper.writeLong(out, 1, _peers.size());
    260271            List peers = DataHelper.sortStructures(_peers);
     
    316327            return "";
    317328    }
    318    
     329
     330    /**
     331     * Is this a hidden node?
     332     */
     333    public boolean isHidden() {
     334        return (getCapabilities().indexOf(CAPABILITY_HIDDEN) != -1);
     335    }
     336
    319337    public void addCapability(char cap) {
    320338        if (_options == null) _options = new OrderedProperties();
     
    327345        }
    328346    }
     347
     348    public void delCapability(char cap) {
     349        if (_options == null) return;
     350        synchronized (_options) {
     351            String caps = _options.getProperty(PROP_CAPABILITIES);
     352            int idx;
     353            if (caps == null) {
     354                return;
     355            } else if ((idx = caps.indexOf(cap)) == -1) {
     356                return;
     357            } else {
     358                StringBuffer buf = new StringBuffer(caps);
     359                while ( (idx = buf.indexOf(""+cap)) != -1)
     360                    buf.deleteCharAt(idx);
     361                _options.setProperty(PROP_CAPABILITIES, buf.toString());
     362            }
     363        }
     364    }
     365
    329366       
    330367    /**
  • history.txt

    ref82cc4 r9089fdd  
    1 $Id: history.txt,v 1.329 2005/11/25 06:06:03 jrandom Exp $
     1$Id: history.txt,v 1.330 2005/11/26 00:05:54 jrandom Exp $
     2
     32005-11-26  Raccoon23
     4    * Added support for 'dynamic keys' mode, where the router creates a new
     5      router identity whenever it detects a substantial change in its public
     6      address (read: SSU IP or port).  This only offers minimal additional
     7      protection against trivial attackers, but should provide functional
     8      improvement for people who have periodic IP changes, since their new
     9      router address would not be shitlisted while their old one would be.
     10    * Added further infrastructure for restricted route operation, but its use
     11      is not recommended.
    212
    3132005-11-25  jrandom
  • router/java/src/net/i2p/router/Router.java

    ref82cc4 r9089fdd  
    1616import java.text.DecimalFormat;
    1717import java.util.Calendar;
     18import java.util.Collection;
    1819import java.util.Date;
    1920import java.util.GregorianCalendar;
     
    3031import net.i2p.data.DataFormatException;
    3132import net.i2p.data.DataHelper;
     33import net.i2p.data.RouterAddress;
    3234import net.i2p.data.RouterInfo;
    3335import net.i2p.data.SigningPrivateKey;
     
    3739//import net.i2p.router.message.TunnelMessageHandler;
    3840import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
     41import net.i2p.router.transport.udp.UDPTransport;
     42import net.i2p.router.transport.udp.UDPAddress;
    3943import net.i2p.router.startup.StartupJob;
    4044import net.i2p.stat.Rate;
     
    7478    public static final int NETWORK_ID = 1;
    7579   
     80    public final static String PROP_HIDDEN = "router.hiddenMode";
     81    public final static String PROP_DYNAMIC_KEYS = "router.dynamicKeys";
    7682    public final static String PROP_INFO_FILENAME = "router.info.location";
    7783    public final static String PROP_INFO_FILENAME_DEFAULT = "router.info";
     
    212218            _context.jobQueue().addJob(new PersistRouterInfoJob());
    213219    }
     220
     221    /**
     222     * Called when our RouterInfo is loaded by LoadRouterInfoJob
     223     * to store our most recently known address to determine if
     224     * it has changed while we were down.
     225     */
     226    public boolean updateExternalAddress(Collection addrs, boolean reboot) {
     227        if ("false".equalsIgnoreCase(_context.getProperty(Router.PROP_DYNAMIC_KEYS, "false")))
     228            return false; // no one cares. pretend it didn't change
     229        boolean ret = false;
     230        for (Iterator i = addrs.iterator(); i.hasNext(); ) {
     231            RouterAddress addr = (RouterAddress)i.next();
     232            if (UDPTransport.STYLE.equalsIgnoreCase(addr.getTransportStyle()))
     233                ret = updateExternalAddress(addr, reboot);
     234        }
     235        return ret;
     236    }
     237
     238    /**
     239     * Called by TransportImpl.replaceAddress to notify the router of an
     240     * address change.  It is the caller's responsibility to make sure this
     241     * really is a substantial change.
     242     *
     243     */
     244    public boolean updateExternalAddress(RouterAddress addr, boolean rebootRouter) {
     245        String newExternal = null;
     246        // TCP is often incorrectly initialized to 83.246.74.28 for some
     247        // reason. Numerous hosts in the netdb report this address for TCP.
     248        // It is also easier to lie over the TCP transport. So only trust UDP.
     249        if (!UDPTransport.STYLE.equalsIgnoreCase(addr.getTransportStyle()))
     250            return false;
     251
     252        if ("false".equalsIgnoreCase(_context.getProperty(Router.PROP_DYNAMIC_KEYS, "false")))
     253            return false; // no one cares. pretend it didn't change
     254
     255        if (_log.shouldLog(Log.WARN))
     256            _log.warn("Rekeying and restarting due to " + addr.getTransportStyle()
     257                      + " address update. new address: " + addr);
     258        if (rebootRouter) {
     259            _context.router().rebuildNewIdentity();
     260        } else {
     261            _context.router().killKeys();
     262        }
     263        return true;
     264    }
    214265   
    215266    /**
     
    238289       
    239290        setupHandlers();
     291        if ("true".equalsIgnoreCase(_context.getProperty(Router.PROP_HIDDEN, "false")))
     292            killKeys();
     293
    240294        _context.messageValidator().startup();
    241295        _context.tunnelDispatcher().startup();
     
    320374            if (FloodfillNetworkDatabaseFacade.floodfillEnabled(_context))
    321375                ri.addCapability(FloodfillNetworkDatabaseFacade.CAPACITY_FLOODFILL);
     376            if("true".equalsIgnoreCase(_context.getProperty(Router.PROP_HIDDEN, "false"))) {
     377                ri.addCapability(RouterInfo.CAPABILITY_HIDDEN);
     378            }
     379
    322380            addReachabilityCapability(ri);
    323381            SigningPrivateKey key = _context.keyManager().getSigningPrivateKey();
     
    375433    private static final String _rebuildFiles[] = new String[] { "router.info",
    376434                                                                 "router.keys",
     435                                                                 "netDb/my.info",
    377436                                                                 "connectionTag.keys",
    378437                                                                 "keyBackup/privateEncryption.key",
     
    381440                                                                 "keyBackup/publicSigning.key",
    382441                                                                 "sessionKeys.dat" };
    383     /**
    384      * Rebuild a new identity the hard way - delete all of our old identity
    385      * files, then reboot the router.
    386      *
    387      */
    388     public void rebuildNewIdentity() {
     442
     443    public static void killKeys() {
    389444        for (int i = 0; i < _rebuildFiles.length; i++) {
    390445            File f = new File(_rebuildFiles[i]);
     
    397452            }
    398453        }
    399         System.out.println("INFO:  Restarting the router after removing any old identity files");
     454    }
     455    /**
     456     * Rebuild a new identity the hard way - delete all of our old identity
     457     * files, then reboot the router.
     458     *
     459     */
     460    public void rebuildNewIdentity() {
     461        killKeys();
    400462        // hard and ugly
    401         System.exit(EXIT_HARD_RESTART);
     463        finalShutdown(EXIT_HARD_RESTART);
    402464    }
    403465   
     
    803865            _log.log(Log.CRIT, "Error running shutdown task", t);
    804866        }
     867        finalShutdown(exitCode);
     868    }
     869
     870    public void finalShutdown(int exitCode) {
    805871        _log.log(Log.CRIT, "Shutdown(" + exitCode + ") complete", new Exception("Shutdown"));
    806872        try { _context.logManager().shutdown(); } catch (Throwable t) { }
  • router/java/src/net/i2p/router/RouterVersion.java

    ref82cc4 r9089fdd  
    1616 */
    1717public class RouterVersion {
    18     public final static String ID = "$Revision: 1.297 $ $Date: 2005/11/25 06:06:02 $";
     18    public final static String ID = "$Revision: 1.298 $ $Date: 2005/11/26 00:05:53 $";
    1919    public final static String VERSION = "0.6.1.5";
    20     public final static long BUILD = 8;
     20    public final static long BUILD = 9;
    2121    public static void main(String args[]) {
    2222        System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
  • router/java/src/net/i2p/router/Shitlist.java

    ref82cc4 r9089fdd  
    6262        boolean wasAlready = false;
    6363        if (_log.shouldLog(Log.INFO))
    64             _log.info("Shitlisting router " + peer.toBase64(), new Exception("Shitlist cause"));
     64            _log.info("Shitlisting router " + peer.toBase64(), new Exception("Shitlist cause: " + reason));
    6565       
    6666        long period = SHITLIST_DURATION_MS + _context.random().nextLong(SHITLIST_DURATION_MS);
  • router/java/src/net/i2p/router/networkdb/HandleDatabaseLookupMessageJob.java

    ref82cc4 r9089fdd  
    8181                _log.debug("dbLookup received with replies going to " + fromKey
    8282                          + " (tunnel " + _message.getReplyTunnel() + ")");
     83        }
     84
     85        // If we are hidden we should not get queries, log and return
     86        if (getContext().router().getRouterInfo().isHidden()) {
     87            if (_log.shouldLog(Log.ERROR)) {
     88                _log.error("Uninvited dbLookup received with replies going to " + fromKey
     89                           + " (tunnel " + _message.getReplyTunnel() + ")");
     90            }
     91            return;
    8392        }
    8493
     
    118127                    us.add(getContext().router().getRouterInfo());
    119128                    sendClosest(_message.getSearchKey(), us, fromKey, _message.getReplyTunnel());
     129                //} else if (info.isHidden()) {
     130                //    // Don't return hidden nodes
     131                //    ERR: we don't want to explicitly reject lookups for hidden nodes, since they
     132                //         may have just sent the hidden mode to only us and bundled a lookup with
     133                //         a payload targetting some hidden destination (and if we refused to answer,
     134                //         yet answered the bundled data message [e.g. HTTP GET], they'd know that
     135                //         *we* were hosting that destination).  To operate safely,
     136                //         perhaps we should refuse to honor lookups bundled down client tunnels?
    120137                } else {
    121138                    // send that routerInfo to the _message.getFromHash peer
     
    130147                                                                        MAX_ROUTERS_RETURNED,
    131148                                                                        _message.getDontIncludePeers());
     149
     150                // ERR: see above
     151                // // Remove hidden nodes from set..
     152                // for (Iterator iter = routerInfoSet.iterator(); iter.hasNext();) {
     153                //     RouterInfo peer = (RouterInfo)iter.next();
     154                //     if (peer.isHidden()) {
     155                //         iter.remove();
     156                //     }
     157                // }
     158
    132159                if (_log.shouldLog(Log.DEBUG))
    133160                    _log.debug("We do not have key " + _message.getSearchKey().toBase64() +
  • router/java/src/net/i2p/router/networkdb/HandleDatabaseStoreMessageJob.java

    ref82cc4 r9089fdd  
    4747        if (_log.shouldLog(Log.DEBUG))
    4848            _log.debug("Handling database store message");
     49
     50        // ERR: see comments regarding hidden mode in HandleDatabaseLookupMessageJob. 
     51        // // If we are a hidden peer, log and return
     52        // if (getContext().router().getRouterInfo().isHidden()) {
     53        //     if (_log.shouldLog(Log.ERROR)) {
     54        //         _log.error("Uninvited dbStore received (tunnel " + _message.getReplyTunnel() + ")");
     55        //     }
     56        //     return;
     57        // }
    4958
    5059        String invalidMessage = null;
  • router/java/src/net/i2p/router/networkdb/PublishLocalRouterInfoJob.java

    ref82cc4 r9089fdd  
    4848            if (FloodfillNetworkDatabaseFacade.floodfillEnabled(getContext()))
    4949                ri.addCapability(FloodfillNetworkDatabaseFacade.CAPACITY_FLOODFILL);
     50
     51            if ("true".equalsIgnoreCase(getContext().getProperty(Router.PROP_HIDDEN, "false")))
     52                ri.addCapability(RouterInfo.CAPABILITY_HIDDEN);
     53
    5054            getContext().router().addReachabilityCapability(ri);
    5155            SigningPrivateKey key = getContext().keyManager().getSigningPrivateKey();
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java

    ref82cc4 r9089fdd  
    3232    public void publish(RouterInfo localRouterInfo) throws IllegalArgumentException {
    3333        if (localRouterInfo == null) throw new IllegalArgumentException("wtf, null localRouterInfo?");
     34        if (localRouterInfo.isHidden()) return; // DE-nied!
    3435        super.publish(localRouterInfo);
    3536        sendStore(localRouterInfo.getIdentity().calculateHash(), localRouterInfo, null, null, PUBLISH_TIMEOUT, null);
  • router/java/src/net/i2p/router/networkdb/kademlia/HandleFloodfillDatabaseStoreMessageJob.java

    ref82cc4 r9089fdd  
    9696                    if (_message.getValueType() == DatabaseStoreMessage.KEY_TYPE_LEASESET)
    9797                        _facade.flood(_message.getLeaseSet());
     98                    // ERR: see comment in HandleDatabaseLookupMessageJob regarding hidden mode
     99                    //else if (!_message.getRouterInfo().isHidden())
    98100                    else
    99101                        _facade.flood(_message.getRouterInfo());
  • router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java

    ref82cc4 r9089fdd  
    505505    public void publish(RouterInfo localRouterInfo) throws IllegalArgumentException {
    506506        if (!_initialized) return;
     507        writeMyInfo(localRouterInfo);
     508        if (localRouterInfo.isHidden()) return; // DE-nied!
    507509        Hash h = localRouterInfo.getIdentity().getHash();
    508510        store(h, localRouterInfo);
     
    510512            _explicitSendKeys.add(h);
    511513        }
    512         writeMyInfo(localRouterInfo);
    513514    }
    514515
  • router/java/src/net/i2p/router/networkdb/kademlia/SearchJob.java

    ref82cc4 r9089fdd  
    244244                        _state.replyTimeout(peer);
    245245                    } else {
    246                         if (getContext().shitlist().isShitlisted(peer)) {
     246                        if (((RouterInfo)ds).isHidden() ||
     247                            getContext().shitlist().isShitlisted(peer)) {
    247248                            // dont bother
    248249                        } else {
  • router/java/src/net/i2p/router/networkdb/kademlia/StoreJob.java

    ref82cc4 r9089fdd  
    177177                    //    _state.addSkipped(peer);
    178178                    //} else {
     179                    //
     180                    // ERR: see hidden mode comments in HandleDatabaseLookupMessageJob
     181                    // // Do not store to hidden nodes
     182                    // if (!((RouterInfo)ds).isHidden()) {
    179183                        _state.addPending(peer);
    180184                        sendStore((RouterInfo)ds, peerTimeout);
  • router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java

    ref82cc4 r9089fdd  
    5555            Properties stats = getContext().statPublisher().publishStatistics();
    5656            stats.setProperty(RouterInfo.PROP_NETWORK_ID, Router.NETWORK_ID+"");
     57            getContext().router().addReachabilityCapability(info);
     58            info.setOptions(stats);
    5759            if (FloodfillNetworkDatabaseFacade.floodfillEnabled(getContext()))
    5860                info.addCapability(FloodfillNetworkDatabaseFacade.CAPACITY_FLOODFILL);
    59             getContext().router().addReachabilityCapability(info);
    60             info.setOptions(stats);
     61            if ("true".equalsIgnoreCase(getContext().getProperty(Router.PROP_HIDDEN, "false")))
     62                info.addCapability(RouterInfo.CAPABILITY_HIDDEN);
    6163            info.setPeers(new HashSet());
    6264            info.setPublished(getCurrentPublishDate(getContext()));
  • router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java

    ref82cc4 r9089fdd  
    1212import java.io.FileInputStream;
    1313import java.io.IOException;
     14import java.util.Collection;
     15import java.util.Set;
    1416
    1517import net.i2p.data.DataFormatException;
     
    7779                info = new RouterInfo();
    7880                info.readBytes(fis1);
     81                getContext().router().updateExternalAddress(info.getAddresses(), false);
    7982                _log.debug("Reading in routerInfo from " + rif.getAbsolutePath() + " and it has " + info.getAddresses().size() + " addresses");
    8083            }
  • router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java

    ref82cc4 r9089fdd  
    130130                if (FloodfillNetworkDatabaseFacade.floodfillEnabled(getContext()))
    131131                    info.addCapability(FloodfillNetworkDatabaseFacade.CAPACITY_FLOODFILL);
     132
     133                // Set caps=H for hidden mode routers
     134                if ("true".equalsIgnoreCase(getContext().getProperty(Router.PROP_HIDDEN, "false")))
     135                    info.addCapability(RouterInfo.CAPABILITY_HIDDEN);
     136
    132137                getContext().router().addReachabilityCapability(info);
    133138                // info.setPeers(new HashSet()); // this would have the trusted peers
  • router/java/src/net/i2p/router/transport/udp/UDPTransport.java

    ref82cc4 r9089fdd  
    816816        if ( (_externalAddress == null) || !(_externalAddress.equals(addr)) )
    817817            wantsRebuild = true;
     818        RouterAddress oldAddress = _externalAddress;
    818819        _externalAddress = addr;
    819820        if (_log.shouldLog(Log.INFO))
    820821            _log.info("Address rebuilt: " + addr);
    821         replaceAddress(addr);
     822        replaceAddress(addr, oldAddress);
    822823        if (allowRebuildRouterInfo)
    823824            _context.router().rebuildRouterInfo();
     825    }
     826
     827    protected void replaceAddress(RouterAddress address, RouterAddress oldAddress) {
     828        replaceAddress(address);
     829        if (oldAddress != null) {
     830            // fire a router.updateExternalAddress only if the address /really/ changed.
     831            // updating the introducers doesn't require a real change, only updating the
     832            // IP or port does.
     833            UDPAddress old = new UDPAddress(oldAddress);
     834            InetAddress oldHost = old.getHostAddress();
     835            UDPAddress newAddr = new UDPAddress(address);
     836            InetAddress newHost = newAddr.getHostAddress();
     837            if ( (old.getPort() != newAddr.getPort()) || (!oldHost.equals(newHost)) )
     838                _context.router().updateExternalAddress(address, true);
     839        }
    824840    }
    825841   
  • router/java/src/net/i2p/router/tunnel/pool/HandleTunnelCreateMessageJob.java

    ref82cc4 r9089fdd  
    1717import net.i2p.router.JobImpl;
    1818import net.i2p.router.RouterContext;
     19import net.i2p.router.Router;
    1920import net.i2p.router.message.GarlicMessageBuilder;
    2021import net.i2p.router.message.PayloadGarlicConfig;
     
    7778   
    7879    private int shouldAccept() {
     80        // Should not see any initiation requests in hidden mode
     81        if ("true".equalsIgnoreCase(getContext().getProperty(Router.PROP_HIDDEN, "false"))) {
     82            return TunnelHistory.TUNNEL_REJECT_CRIT;
     83        }
     84
    7985        if (_request.getDurationSeconds() >= MAX_DURATION_SECONDS)
    8086            return TunnelHistory.TUNNEL_REJECT_CRIT;
  • router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java

    ref82cc4 r9089fdd  
    117117     */
    118118    public Set getExclude(RouterContext ctx, boolean isInbound, boolean isExploratory) {
    119         if (filterUnreachable(ctx, isInbound, isExploratory)) {
     119        // we may want to update this to skip 'hidden' or 'unreachable' peers, but that
     120        // isn't safe, since they may publish one set of routerInfo to us and another to
     121        // other peers.  the defaults for filterUnreachable has always been to return false,
     122        // but might as well make it explicit with a "false &&"
     123       
     124        if (false && filterUnreachable(ctx, isInbound, isExploratory)) {
    120125            List caps = ctx.peerManager().getPeersByCapability(Router.CAPABILITY_UNREACHABLE);
    121126            if (caps == null) return new HashSet(0);
Note: See TracChangeset for help on using the changeset viewer.