Changeset 2d67d11 for router


Ignore:
Timestamp:
Feb 18, 2019 5:55:17 PM (17 months ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
ab7f61d
Parents:
d244d17
Message:

Transport: Fixes for NTCP when SSU disabled (ticket #1417)
Delay port forwarding until after UPnP rescan complete
WIP

Location:
router/java/src/net/i2p/router
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • router/java/src/net/i2p/router/Router.java

    rd244d17 r2d67d11  
    11801180            removeConfigSetting(UDPTransport.PROP_INTERNAL_PORT);
    11811181            removeConfigSetting(UDPTransport.PROP_EXTERNAL_PORT);
     1182            removeConfigSetting(NTCPTransport.PROP_I2NP_NTCP_PORT);
    11821183            removeConfigSetting(NTCPTransport.PROP_NTCP2_SP);
    11831184            removeConfigSetting(NTCPTransport.PROP_NTCP2_IV);
  • router/java/src/net/i2p/router/RouterVersion.java

    rd244d17 r2d67d11  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 7;
     21    public final static long BUILD = 8;
    2222
    2323    /** for example "-test" */
  • router/java/src/net/i2p/router/transport/TransportManager.java

    rd244d17 r2d67d11  
    4343import net.i2p.util.Addresses;
    4444import net.i2p.util.Log;
     45import net.i2p.util.SimpleTimer;
     46import net.i2p.util.SimpleTimer2;
    4547import net.i2p.util.SystemVersion;
    4648import net.i2p.util.Translate;
     
    7375    private final boolean _enableUDP;
    7476    private final boolean _enableNTCP1;
     77    private boolean _upnpUpdateQueued;
    7578
    7679    /** default true */
     
    197200                // so that NTCP may bind early
    198201                int port = udp.getRequestedPort();
     202                if (port > 0)
     203                    ntcp.externalAddressReceived(SOURCE_CONFIG, (byte[]) null, port);
     204            } else {
     205                // SSU disabled
     206                int port = ntcp.getRequestedPort();
    199207                if (port > 0)
    200208                    ntcp.externalAddressReceived(SOURCE_CONFIG, (byte[]) null, port);
     
    662670                Transport udp = getTransport(UDPTransport.STYLE);
    663671                if (udp != null)
    664                     port = t.getRequestedPort();
     672                    port = udp.getRequestedPort();
    665673            }
    666674            if (port > 0)
     
    807815    public void transportAddressChanged() {
    808816        if (_upnpManager != null) {
    809             _upnpManager.rescan();
    810             // should really delay the following by 5 seconds?
    811             _upnpManager.update(getPorts());
     817            synchronized (_upnpManager) {
     818                if (!_upnpUpdateQueued) {
     819                    boolean shouldWait = _upnpManager.rescan();
     820                    if (shouldWait) {
     821                        // Delay until the rescan finishes, MX time + 250
     822                        _upnpUpdateQueued = true;
     823                        _context.simpleTimer2().addEvent(new UpdatePorts(), 3250);
     824                    } else {
     825                        _upnpManager.update(getPorts());
     826                    }
     827                }
     828            }
     829        }
     830    }
     831
     832    /**
     833     * Delayed update of UPnP ports
     834     *
     835     * @since 0.9.39
     836     */
     837    private class UpdatePorts implements SimpleTimer.TimedEvent {
     838        public void timeReached() {
     839            synchronized (_upnpManager) {
     840                _upnpUpdateQueued = false;
     841                _upnpManager.update(getPorts());
     842            }
    812843        }
    813844    }
  • router/java/src/net/i2p/router/transport/TransportUtil.java

    rd244d17 r2d67d11  
    1212import java.net.UnknownHostException;
    1313import java.util.HashMap;
     14import java.util.Locale;
    1415import java.util.Map;
    1516
    1617import net.i2p.I2PAppContext;
    1718import net.i2p.data.router.RouterAddress;
     19import net.i2p.util.Log;
    1820import net.i2p.router.RouterContext;
    1921
     
    2830    /** @since 0.9.28 */
    2931    public static final String PROP_IPV6_FIREWALLED = "i2np.ipv6.firewalled";
     32    private static final String PROP_PORT_PFX = "i2np.";
     33    private static final String PROP_MIN_PORT_SFX = ".minPort";
     34    private static final String PROP_MAX_PORT_SFX = ".maxPort";
     35    /**
     36     * 8998 is monotone, and 31000 is the wrapper outbound, so let's stay between those
     37     * Was 9111, increase to skip Tor browser at 9050
     38     */
     39    private static final int MIN_RANDOM_PORT = 9151;
     40    private static final int MAX_RANDOM_PORT = 30777;
    3041
    3142    public enum IPv6Config {
     
    251262               port != 32000;   // Wrapper
    252263    }
     264
     265    /**
     266     *  log an error
     267     *  @since 0.9.39 pulled out of UDPEndpoint
     268     */
     269    public static void logInvalidPort(Log log, String transportStyle, int port) {
     270        log.error("Specified " + transportStyle + " port " + port + " is not valid, selecting a new port");
     271        log.error("Invalid ports are: 0-1023, 1900, 2049, 2827, 3659, 4045, 4444, 4445, 6000, 6665-6669, 6697, 7650-7668, 8998, 9001, 9030, 9050, 9100, 9150, 31000, 32000, 65536+");
     272    }
     273
     274    /**
     275     *  Pick a random port between the configured boundaries
     276     *  @since IPv6, moved from UDPEndpoint in 0.9.39 to support NTCP also
     277     */
     278    public static int selectRandomPort(RouterContext ctx, String transportStyle) {
     279        if (transportStyle.equals("SSU"))
     280            transportStyle = "udp";
     281        else
     282            transportStyle = transportStyle.toLowerCase(Locale.US);
     283        String minprop = PROP_PORT_PFX + transportStyle + PROP_MIN_PORT_SFX;
     284        String maxprop = PROP_PORT_PFX + transportStyle + PROP_MAX_PORT_SFX;
     285        int minPort = Math.min(65535, Math.max(1, ctx.getProperty(minprop, MIN_RANDOM_PORT)));
     286        int maxPort = Math.min(65535, Math.max(minPort, ctx.getProperty(maxprop, MAX_RANDOM_PORT)));
     287        return minPort + ctx.random().nextInt(1 + maxPort - minPort);
     288    }
    253289}
  • router/java/src/net/i2p/router/transport/UPnPManager.java

    rd244d17 r2d67d11  
    144144     *  will come in over the MX time (3 seconds).
    145145     *
     146     *  @return true if a rescan was actually fired off
    146147     *  @since 0.9.18
    147148     */
    148     public synchronized void rescan() {
     149    public synchronized boolean rescan() {
    149150        if (!_shouldBeRunning)
    150             return;
     151            return false;
    151152        if (_context.router().gracefulShutdownInProgress())
    152             return;
     153            return false;
    153154        long now = System.currentTimeMillis();
    154155        if (_lastRescan + RESCAN_MIN_DELAY > now)
    155             return;
     156            return false;
    156157        _lastRescan = now;
    157158        if (_isRunning) {
     
    166167            start();
    167168        }
     169        return true;
    168170    }
    169171
     
    196198    public void update(Set<TransportManager.Port> ports) {
    197199        if (_log.shouldLog(Log.DEBUG))
    198             _log.debug("UPnP Update with " + ports.size() + " ports");
     200            _log.debug("UPnP Update with " + ports.size() + " ports", new Exception("I did it"));
    199201
    200202        //synchronized(this) {
     
    241243        public void portForwardStatus(Map<ForwardPort,ForwardPortStatus> statuses) {
    242244            if (_log.shouldLog(Log.DEBUG))
    243                  _log.debug("UPnP Callback:");
     245                 _log.debug("UPnP Callback: with " + statuses.size() + " statuses");
    244246            // Let's not have two of these running at once.
    245247            // Deadlock reported in ticket #1699
     
    255257            byte[] ipaddr = null;
    256258            DetectedIP[] ips = _upnp.getAddress();
    257             if (ips != null) {
     259            if (ips != null && ips.length > 0) {
    258260                for (DetectedIP ip : ips) {
    259261                    // store the first public one and tell the transport manager if it changed
     
    269271                        ipaddr = ip.publicAddress.getAddress();
    270272                        break;
     273                    } else {
     274                        if (_log.shouldWarn())
     275                            _log.warn("Unusable external address: " + ip.publicAddress + " type: " + ip.natType);
    271276                    }
    272277                }
     
    276281            }
    277282
     283            if (statuses.isEmpty()) {
     284                if (_log.shouldWarn())
     285                    _log.warn("No statuses returned");
     286                return;
     287            }
     288
    278289            for (Map.Entry<ForwardPort, ForwardPortStatus> entry : statuses.entrySet()) {
    279290                ForwardPort fp = entry.getKey();
    280291                ForwardPortStatus fps = entry.getValue();
    281                 if (_log.shouldLog(Log.DEBUG))
    282                     _log.debug(fp.name + " " + fp.protocol + " " + fp.portNumber +
     292                if (_log.shouldDebug())
     293                    _log.debug("FPS: " + fp.name + ' ' + fp.protocol + ' ' + fp.portNumber +
    283294                               " status: " + fps.status + " reason: " + fps.reasonString + " ext port: " + fps.externalPort);
    284295                String style;
    285                 if (fp.protocol == ForwardPort.PROTOCOL_UDP_IPV4)
     296                if (fp.protocol == ForwardPort.PROTOCOL_UDP_IPV4) {
    286297                    style = "SSU";
    287                 else if (fp.protocol == ForwardPort.PROTOCOL_TCP_IPV4)
     298                } else if (fp.protocol == ForwardPort.PROTOCOL_TCP_IPV4) {
    288299                    style = "NTCP";
    289                 else
     300                } else {
     301                    if (_log.shouldWarn())
     302                        _log.debug("Unknown protocol " + fp.protocol);
    290303                    continue;
     304                }
    291305                boolean success = fps.status >= ForwardPortStatus.MAYBE_SUCCESS;
    292306                // deadlock path 2
  • router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java

    rd244d17 r2d67d11  
    4848import net.i2p.router.transport.TransportBid;
    4949import net.i2p.router.transport.TransportImpl;
     50import net.i2p.router.transport.TransportManager;
    5051import net.i2p.router.transport.TransportUtil;
    5152import static net.i2p.router.transport.TransportUtil.IPv6Config.*;
     
    241242        _transientFail = new SharedBid(TransportBid.TRANSIENT_FAIL);
    242243
     244        setupPort();
    243245        _enableNTCP1 = dh != null;
    244246        _enableNTCP2 = xdh != null;
     
    304306            _b64Ntcp2StaticPubkey = null;
    305307            _b64Ntcp2StaticIV = null;
     308        }
     309    }
     310   
     311    /**
     312     *  Pick a port if not previously configured.
     313     *  Only if UDP is disabled.
     314     *
     315     *  @since 0.9.39
     316     */
     317    private void setupPort() {
     318        if (_context.getBooleanPropertyDefaultTrue(TransportManager.PROP_ENABLE_UDP))
     319            return;
     320        int port = getRequestedPort();
     321        if (port > 0 && !TransportUtil.isValidPort(port)) {
     322            TransportUtil.logInvalidPort(_log, STYLE, port);
     323        }
     324        if (port <= 0) {
     325            port = TransportUtil.selectRandomPort(_context, STYLE);
     326            Map<String, String> changes = new HashMap<String, String>(2);
     327            changes.put(PROP_I2NP_NTCP_PORT, Integer.toString(port));
     328            _context.router().saveConfig(changes, null);
     329            _log.logAlways(Log.INFO, "NTCP selected random port " + port);
    306330        }
    307331    }
     
    10001024                ServerSocketChannel chan = ServerSocketChannel.open();
    10011025                chan.configureBlocking(false);
     1026                // TODO retry
    10021027                chan.socket().bind(addr);
    10031028                _endpoints.add(addr);
     
    14381463            return;
    14391464        }
    1440         // ignore UPnP for now, get everything from SSU
    1441         if (source != SOURCE_SSU)
     1465        // ignore UPnP for now, get everything from SSU if it's enabled
     1466        if (source != SOURCE_SSU &&
     1467            _context.getBooleanPropertyDefaultTrue(TransportManager.PROP_ENABLE_UDP))
    14421468            return;
    14431469        boolean isIPv6 = ip != null && ip.length == 16;
     
    14651491        if (_log.shouldWarn())
    14661492            _log.warn("Removing address, ipv6? " + ipv6 + " from: " + source, new Exception());
    1467         // ignore UPnP for now, get everything from SSU
    1468         if (source != SOURCE_SSU)
     1493        // ignore UPnP for now, get everything from SSU if it's enabled
     1494        if (source != SOURCE_SSU &&
     1495            _context.getBooleanPropertyDefaultTrue(TransportManager.PROP_ENABLE_UDP))
    14691496            return;
    14701497        externalAddressReceived(null, ipv6, 0);
     
    16601687                _log.warn("UPnP has failed to open the NTCP port: " + port + " reason: " + reason);
    16611688        }
     1689        // ignore UPnP for now, get everything from SSU if it's enabled
     1690        if (!_context.getBooleanPropertyDefaultTrue(TransportManager.PROP_ENABLE_UDP)) {
     1691            // TODO
     1692            //if (success && ip != null && getExternalIP() != null) {
     1693            //    if (!isIPv4Firewalled())
     1694            //        setReachabilityStatus(Status.IPV4_OK_IPV6_UNKNOWN);
     1695            //}
     1696        }
    16621697    }
    16631698
  • router/java/src/net/i2p/router/transport/udp/UDPEndpoint.java

    rd244d17 r2d67d11  
    9898********/
    9999   
    100     /** 8998 is monotone, and 31000 is the wrapper outbound, so let's stay between those */
    101     public static final String PROP_MIN_PORT = "i2np.udp.minPort";
    102     public static final String PROP_MAX_PORT = "i2np.udp.maxPort";
    103     /** Was 9111, increase to skip Tor browser at 9050 */
    104     private static final int MIN_RANDOM_PORT = 9151;
    105     private static final int MAX_RANDOM_PORT = 30777;
    106100    private static final int MAX_PORT_RETRIES = 20;
    107101
     
    116110        int port = _listenPort;
    117111        if (port > 0 && !TransportUtil.isValidPort(port)) {
    118             _log.error("Specified UDP port " + port + " is not valid, selecting a new port");
    119             // See isValidPort() for list
    120             _log.error("Invalid ports are: 0-1023, 1900, 2049, 2827, 3659, 4045, 4444, 4445, 6000, 6665-6669, 6697, 7650-7668, 8998, 9001, 9030, 9050, 9100, 9150, 31000, 32000, 65536+");
     112            TransportUtil.logInvalidPort(_log, "UDP", port);
    121113            port = -1;
    122114        }
     
    126118                 // try random ports rather than just do new DatagramSocket()
    127119                 // so we stay out of the way of other I2P stuff
    128                  port = selectRandomPort(_context);
     120                 port = TransportUtil.selectRandomPort(_context, UDPTransport.STYLE);
    129121             }
    130122             try {
     
    152144    }
    153145
    154     /**
    155      *  Pick a random port between the configured boundaries
    156      *  @since IPv6
    157      */
    158     public static int selectRandomPort(RouterContext ctx) {
    159         int minPort = Math.min(65535, Math.max(1, ctx.getProperty(PROP_MIN_PORT, MIN_RANDOM_PORT)));
    160         int maxPort = Math.min(65535, Math.max(minPort, ctx.getProperty(PROP_MAX_PORT, MAX_RANDOM_PORT)));
    161         return minPort + ctx.random().nextInt(1 + maxPort - minPort);
    162     }
    163 
    164146
    165147    /** call after startup() to get actual port or -1 on startup failure */
  • router/java/src/net/i2p/router/transport/udp/UDPTransport.java

    rd244d17 r2d67d11  
    309309    private void setupPort() {
    310310        int port = getRequestedPort();
    311         if (port < 0) {
    312             port = UDPEndpoint.selectRandomPort(_context);
     311        if (port <= 0) {
     312            port = TransportUtil.selectRandomPort(_context, STYLE);
    313313            Map<String, String> changes = new HashMap<String, String>(2);
    314314            changes.put(PROP_INTERNAL_PORT, Integer.toString(port));
Note: See TracChangeset for help on using the changeset viewer.