Changeset 1868d2b


Ignore:
Timestamp:
Apr 30, 2015 8:33:46 PM (6 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
42cb89f5
Parents:
4588f1e
Message:

Transport: Ticket #1458 continued…
Implement methods to remove only a single IPv4 or IPv6 address,
so that IPv6 addresses will remain when SSU detects that IPv4 is firewalled
Summary bar status fixes
Fix getIsPortFixed() for more enum cases
log tweaks, cleanups

Files:
8 edited

Legend:

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

    r4588f1e r1868d2b  
    161161            case IPV4_OK_IPV6_FIREWALLED:
    162162            case IPV4_UNKNOWN_IPV6_OK:
    163             case IPV4_FIREWALLED_IPV6_OK:
    164163            case IPV4_DISABLED_IPV6_OK:
    165164            case IPV4_SNAT_IPV6_OK:
     
    180179
    181180            case REJECT_UNSOLICITED:
    182             case IPV4_FIREWALLED_IPV6_UNKNOWN:
    183181            case IPV4_DISABLED_IPV6_FIREWALLED:
    184182                if (routerInfo.getTargetAddress("NTCP") != null)
    185183                    return _("WARN-Firewalled with Inbound TCP Enabled");
     184                // fall through...
     185            case IPV4_FIREWALLED_IPV6_OK:
     186            case IPV4_FIREWALLED_IPV6_UNKNOWN:
    186187                if (((FloodfillNetworkDatabaseFacade)_context.netDb()).floodfillEnabled())
    187188                    return _("WARN-Firewalled and Floodfill");
  • router/java/src/net/i2p/router/CommSystemFacade.java

    r4588f1e r1868d2b  
    114114     * Tell other transports our address changed
    115115     */
    116     public void notifyReplaceAddress(RouterAddress UDPAddr) {}
     116    public void notifyReplaceAddress(RouterAddress address) {}
     117
     118    /**
     119     * Tell other transports our address changed
     120     * @since 0.9.20
     121     */
     122    public void notifyRemoveAddress(RouterAddress address) {}
     123
     124    /**
     125     * Tell other transports our address changed
     126     * @since 0.9.20
     127     */
     128    public void notifyRemoveAddress(boolean ipv6) {}
    117129
    118130    /**
  • router/java/src/net/i2p/router/transport/CommSystemFacadeImpl.java

    r4588f1e r1868d2b  
    239239                port = udp.getRequestedPort();
    240240        }
    241         _manager.externalAddressReceived(Transport.AddressSource.SOURCE_SSU, ip, port);
     241        if (ip != null || port > 0)
     242            _manager.externalAddressReceived(Transport.AddressSource.SOURCE_SSU, ip, port);
     243        else
     244            notifyRemoveAddress(false);
     245    }
     246
     247    /**
     248     *  Tell other transports our address changed
     249     *
     250     *  @param address non-null; but address's host/IP may be null
     251     *  @since 0.9.20
     252     */
     253    @Override
     254    public void notifyRemoveAddress(RouterAddress address) {
     255        // just keep this simple for now, multiple v4 or v6 addresses not yet supported
     256        notifyRemoveAddress(address != null &&
     257                            address.getIP() != null &&
     258                            address.getIP().length == 16);
     259    }
     260
     261    /**
     262     *  Tell other transports our address changed
     263     *
     264     *  @since 0.9.20
     265     */
     266    @Override
     267    public void notifyRemoveAddress(boolean ipv6) {
     268        _manager.externalAddressRemoved(Transport.AddressSource.SOURCE_SSU, ipv6);
    242269    }
    243270
  • router/java/src/net/i2p/router/transport/Transport.java

    r4588f1e r1868d2b  
    100100
    101101    /**
     102     *  Notify a transport of an external address change.
     103     *  This may be from a local interface, UPnP, a config change, etc.
     104     *  This should not be called if the ip didn't change
     105     *  (from that source's point of view), or is a local address.
     106     *  May be called multiple times for IPv4 or IPv6.
     107     *  The transport should also do its own checking on whether to accept
     108     *  notifications from this source.
     109     *
     110     *  This can be called after the transport is running.
     111     *
     112     *  TODO externalAddressRemoved(source, ip, port)
     113     *
     114     *  @param source defined in Transport.java
     115     *  @since 0.9.20
     116     */
     117    public void externalAddressRemoved(AddressSource source, boolean ipv6);
     118
     119    /**
    102120     *  Notify a transport of the results of trying to forward a port.
    103121     *
  • router/java/src/net/i2p/router/transport/TransportImpl.java

    r4588f1e r1868d2b  
    555555     *  TODO: Allow multiple addresses of the same length.
    556556     *  Calls listener.transportAddressChanged()
     557     *  To remove all IPv4 or IPv6 addresses, use removeAddress(boolean).
    557558     *
    558559     *  @param address null to remove all
     
    567568            for (RouterAddress ra : _currentAddresses) {
    568569                if (isIPv6 == TransportUtil.isIPv6(ra))
     570                    // COWAL
    569571                    _currentAddresses.remove(ra);
    570572            }
     
    575577        if (_listener != null)
    576578            _listener.transportAddressChanged();
     579    }
     580
     581    /**
     582     *  Remove only this address.
     583     *  Calls listener.transportAddressChanged().
     584     *  To remove all IPv4 or IPv6 addresses, use removeAddress(boolean).
     585     *  To remove all IPv4 and IPv6 addresses, use replaceAddress(null).
     586     *
     587     *  @param ipv6 true to remove all IPv6 addresses, false to remove all IPv4 addresses
     588     *  @since 0.9.20
     589     */
     590    protected void removeAddress(RouterAddress address) {
     591        if (_log.shouldWarn())
     592             _log.warn("Removing address " + address, new Exception());
     593        boolean changed = _currentAddresses.remove(address);
     594            changed = true;
     595        if (changed) {
     596            if (_log.shouldWarn())
     597                 _log.warn(getStyle() + " now has " + _currentAddresses.size() + " addresses");
     598            if (_listener != null)
     599                _listener.transportAddressChanged();
     600        } else {
     601            if (_log.shouldWarn())
     602                 _log.warn(getStyle() + " no addresses removed");
     603        }
     604    }
     605
     606    /**
     607     *  Remove all existing addresses with the specified IP length (4 or 16).
     608     *  Calls listener.transportAddressChanged().
     609     *  To remove all IPv4 and IPv6 addresses, use replaceAddress(null).
     610     *
     611     *  @param ipv6 true to remove all IPv6 addresses, false to remove all IPv4 addresses
     612     *  @since 0.9.20
     613     */
     614    protected void removeAddress(boolean ipv6) {
     615        if (_log.shouldWarn())
     616             _log.warn("Removing addresses, ipv6? " + ipv6, new Exception());
     617        boolean changed = false;
     618        for (RouterAddress ra : _currentAddresses) {
     619            if (ipv6 == TransportUtil.isIPv6(ra)) {
     620                // COWAL
     621                if (_currentAddresses.remove(ra))
     622                    changed = true;
     623            }
     624        }
     625        if (changed) {
     626            if (_log.shouldWarn())
     627                 _log.warn(getStyle() + " now has " + _currentAddresses.size() + " addresses");
     628            if (_listener != null)
     629                _listener.transportAddressChanged();
     630        } else {
     631            if (_log.shouldWarn())
     632                 _log.warn(getStyle() + " no addresses removed");
     633        }
    577634    }
    578635
     
    701758
    702759    /**
     760     *  Notify a transport of an external address change.
     761     *  This may be from a local interface, UPnP, a config change, etc.
     762     *  This should not be called if the ip didn't change
     763     *  (from that source's point of view), or is a local address.
     764     *  May be called multiple times for IPv4 or IPv6.
     765     *  The transport should also do its own checking on whether to accept
     766     *  notifications from this source.
     767     *
     768     *  This can be called after the transport is running.
     769     *
     770     *  TODO externalAddressRemoved(source, ip, port)
     771     *
     772     *  This implementation does nothing. Transports should override if they want notification.
     773     *
     774     *  @param source defined in Transport.java
     775     *  @since 0.9.20
     776     */
     777    public void externalAddressRemoved(AddressSource source, boolean ipv6) {}
     778
     779    /**
    703780     *  Notify a transport of the results of trying to forward a port.
    704781     *
  • router/java/src/net/i2p/router/transport/TransportManager.java

    r4588f1e r1868d2b  
    194194    /**
    195195     * Initialize from interfaces, and callback from UPnP or SSU.
    196      * Tell all transports... but don't loop
     196     * See CSFI.notifyReplaceAddress().
     197     * Tell all transports... but don't loop.
    197198     *
    198199     */
     
    202203            if (!(source == SOURCE_SSU && t.getStyle().equals(UDPTransport.STYLE)))
    203204                t.externalAddressReceived(source, ip, port);
     205        }
     206    }
     207
     208    /**
     209     *  Remove all ipv4 or ipv6 addresses.
     210     *  See CSFI.notifyRemoveAddress().
     211     *  Tell all transports... but don't loop.
     212     *
     213     *  @since 0.9.20
     214     */
     215    public void externalAddressRemoved(Transport.AddressSource source, boolean ipv6) {
     216        for (Transport t : _transports.values()) {
     217            // don't loop
     218            if (!(source == SOURCE_SSU && t.getStyle().equals(UDPTransport.STYLE)))
     219                t.externalAddressRemoved(source, ipv6);
    204220        }
    205221    }
  • router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java

    r4588f1e r1868d2b  
    603603        if (_pumper.isAlive())
    604604            return;
    605         if (_log.shouldLog(Log.WARN)) _log.warn("Starting ntcp transport listening");
     605        if (_log.shouldLog(Log.WARN)) _log.warn("Starting NTCP transport listening");
    606606
    607607        startIt();
     
    637637    /**
    638638     *  Only called by externalAddressReceived().
     639     *  Calls replaceAddress() or removeAddress().
     640     *  To remove all addresses, call replaceAddress(null) directly.
    639641     *
    640642     *  Doesn't actually restart unless addr is non-null and
    641643     *  the port is different from the current listen port.
    642      *  If addr is null, removes IPv4 addresses only.
     644     *  If addr is null, removes the addresses specified (v4 or v6)
    643645     *
    644646     *  If we had interface addresses before, we lost them.
    645647     *
    646      *  @param addr may be null to indicate remove the IPv4 address only
    647      */
    648     private synchronized void restartListening(RouterAddress addr) {
     648     *  @param addr may be null to indicate remove the address
     649     *  @param ipv6 ignored if addr is non-null
     650     */
     651    private synchronized void restartListening(RouterAddress addr, boolean ipv6) {
    649652        if (addr != null) {
    650653            RouterAddress myAddress = bindAddress(addr.getPort());
     
    655658            // UDPTransport.rebuildExternalAddress() calls router.rebuildRouterInfo()
    656659        } else {
    657             // can't do this, want to remove IPv4 only
    658             //replaceAddress(null);
    659             for (RouterAddress ra : _currentAddresses) {
    660                 byte[] ip = ra.getIP();
    661                 if (ip != null && ip.length == 4) {
    662                     // COWAL
    663                     _currentAddresses.remove(ra);
    664                 }
    665             }
    666             _lastInboundIPv4 = 0;
     660            removeAddress(ipv6);
     661            if (ipv6)
     662                _lastInboundIPv6 = 0;
     663            else
     664                _lastInboundIPv4 = 0;
    667665        }
    668666    }
     
    953951    public void externalAddressReceived(AddressSource source, byte[] ip, int port) {
    954952        if (_log.shouldLog(Log.WARN))
    955             _log.warn("Received address: " + Addresses.toString(ip, port) + " from: " + source);
     953            _log.warn("Received address: " + Addresses.toString(ip, port) + " from: " + source, new Exception());
    956954        if ((source == SOURCE_INTERFACE || source == SOURCE_SSU)
    957955             && ip != null && ip.length == 16) {
     
    979977        if (source != SOURCE_SSU)
    980978            return;
    981         externalAddressReceived(ip, port);
    982     }
     979        boolean isIPv6 = ip != null && ip.length == 16;
     980        externalAddressReceived(ip, isIPv6, port);
     981    }
     982
     983    /**
     984     *  Notify a transport of an external address change.
     985     *  This may be from a local interface, UPnP, a config change, etc.
     986     *  This should not be called if the ip didn't change
     987     *  (from that source's point of view), or is a local address.
     988     *  May be called multiple times for IPv4 or IPv6.
     989     *  The transport should also do its own checking on whether to accept
     990     *  notifications from this source.
     991     *
     992     *  This can be called after the transport is running.
     993     *
     994     *  TODO externalAddressRemoved(source, ip, port)
     995     *
     996     *  @param source defined in Transport.java
     997     *  @since 0.9.20
     998     */
     999    @Override
     1000    public void externalAddressRemoved(AddressSource source, boolean ipv6) {
     1001        if (_log.shouldWarn())
     1002            _log.warn("Removing address, ipv6? " + ipv6 + " from: " + source, new Exception());
     1003        // ignore UPnP for now, get everything from SSU
     1004        if (source != SOURCE_SSU)
     1005            return;
     1006        externalAddressReceived(null, ipv6, 0);
     1007    }   
    9831008   
    9841009    /**
     
    9891014     *  @since IPv6 moved from CSFI.notifyReplaceAddress()
    9901015     */
    991     private synchronized void externalAddressReceived(byte[] ip, int port) {
     1016    private synchronized void externalAddressReceived(byte[] ip, boolean isIPv6, int port) {
    9921017        // FIXME just take first address for now
    9931018        // FIXME if SSU set to hostname, NTCP will be set to IP
    994         boolean isIPv6 = ip != null && ip.length == 16;
    9951019        RouterAddress oldAddr = getCurrentAddress(isIPv6);
    9961020        if (_log.shouldLog(Log.INFO))
     
    11371161        //    try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
    11381162        //}
    1139         restartListening(newAddr);
     1163        restartListening(newAddr, isIPv6);
    11401164        if (_log.shouldLog(Log.WARN))
    1141             _log.warn("Updating NTCP Address with " + newAddr);
     1165            _log.warn("Updating NTCP Address (ipv6? " + isIPv6 + ") with " + newAddr);
    11421166        return;         
    11431167    }
    1144    
    1145 
    11461168
    11471169    /**
  • router/java/src/net/i2p/router/transport/udp/UDPTransport.java

    r4588f1e r1868d2b  
    9393     */
    9494    private boolean _haveIPv6Address;
     95    private long _lastInboundIPv6;
    9596   
    9697    /** do we need to rebuild our external router address asap? */
     
    465466        if (newPort > 0 && bindToAddrs.isEmpty()) {
    466467            for (InetAddress ia : getSavedLocalAddresses()) {
     468                // Discovered or configured addresses are presumed good at the start.
     469                // when externalAddressReceived() was called with SOURCE_INTERFACE,
     470                // isAlive() was false, so setReachabilityStatus() was not called
     471                // TODO should we set both to unknown and wait for an inbound v6 conn,
     472                // since there's no v6 testing?
     473                if (ia.getAddress().length == 16) {
     474                    // FIXME we need to check and time out after an hour of no inbound ipv6,
     475                    // change to firewalled maybe? but we don't have any test to restore
     476                    // a v6 address after it's removed.
     477                    _lastInboundIPv6 = _context.clock().now();
     478                    setReachabilityStatus(Status.IPV4_UNKNOWN_IPV6_OK);
     479                } else {
     480                    setReachabilityStatus(Status.IPV4_OK_IPV6_UNKNOWN);
     481                }
    467482                rebuildExternalAddress(ia.getHostAddress(), newPort, false);
    468483            }
     
    498513        UDPPacket.clearCache();
    499514        UDPAddress.clearCache();
     515        _lastInboundIPv6 = 0;
    500516    }
    501517
     
    665681    void inboundConnectionReceived(boolean isIPv6) {
    666682        if (isIPv6) {
     683            _lastInboundIPv6 = _context.clock().now();
    667684            if (_currentOurV6Address != null)
    668685                setReachabilityStatus(Status.IPV4_UNKNOWN_IPV6_OK);
     
    776793     */
    777794    void externalAddressReceived(Hash from, byte ourIP[], int ourPort) {
    778         if (ourIP.length != 4)
    779             return;
    780795        boolean isValid = isValid(ourIP) &&
    781796                          TransportUtil.isValidPort(ourPort);
     
    786801                      + from + ", isValid? " + isValid + ", explicitSpecified? " + explicitSpecified
    787802                      + ", receivedInboundRecent? " + inboundRecent + " status " + _reachabilityStatus);
     803        if (ourIP.length != 4) {
     804            return;
     805        }
    788806       
    789807        if (explicitSpecified)
     
    9941012            return Boolean.parseBoolean(prop);
    9951013        Status status = getReachabilityStatus();
    996         return status != Status.REJECT_UNSOLICITED;
     1014        return status != Status.REJECT_UNSOLICITED &&
     1015               status != Status.IPV4_FIREWALLED_IPV6_OK &&
     1016               status != Status.IPV4_FIREWALLED_IPV6_UNKNOWN;
    9971017    }
    9981018
     
    10361056     */
    10371057    void changePeerPort(PeerState peer, int newPort) {
     1058        // this happens a lot
    10381059        int oldPort;
    10391060        synchronized (_addDropLock) {
     
    10451066            }
    10461067        }
    1047         if (_log.shouldLog(Log.WARN) && oldPort != newPort)
    1048             _log.warn("Changed port from " + oldPort + " to " + newPort + " for " + peer);
     1068        if (_log.shouldInfo() && oldPort != newPort)
     1069            _log.info("Changed port from " + oldPort + " to " + newPort + " for " + peer);
    10491070    }
    10501071
     
    11321153            oldPeer = _peersByIdent.put(remotePeer, peer);
    11331154            if ( (oldPeer != null) && (oldPeer != peer) ) {
    1134                 if (_log.shouldLog(Log.WARN))
    1135                     _log.warn("Peer already connected (PBID): old=" + oldPeer + " new=" + peer);
     1155                // this happens a lot
     1156                if (_log.shouldInfo())
     1157                    _log.info("Peer already connected (PBID): old=" + oldPeer + " new=" + peer);
    11361158                // transfer over the old state/inbound message fragments/etc
    11371159                peer.loadFrom(oldPeer);
     
    11481170            if (!remoteId.equals(oldID)) {
    11491171                // leak fix, remove old address
    1150                 if (_log.shouldLog(Log.WARN))
    1151                     _log.warn(remotePeer + " changed address FROM " + oldID + " TO " + remoteId);
     1172                if (_log.shouldInfo())
     1173                    _log.info(remotePeer + " changed address FROM " + oldID + " TO " + remoteId);
    11521174                PeerState oldPeer2 = _peersByRemoteHost.remove(oldID);
    11531175                // different ones in the two maps? shouldn't happen
     
    15331555        int toSleep = Math.max(8, (1000 / burstps));
    15341556        int count = 0;
    1535         if (_log.shouldLog(Log.WARN))
    1536             _log.warn("Sending destroy to : " + howMany + " peers");
     1557        if (_log.shouldInfo())
     1558            _log.info("Sending destroy to : " + howMany + " peers");
    15371559        for (PeerState peer : _peersByIdent.values()) {
    15381560            sendDestroy(peer);
     
    18591881    /**
    18601882     *  Update our IPv4 or IPv6 address and optionally tell the router to rebuild and republish the router info.
     1883     *  FIXME no way to remove an IPv6 address
    18611884     *
    18621885     *  @param host new validated IPv4 or IPv6 or DNS hostname or null
     
    19731996            if (wantsRebuild) {
    19741997                if (_log.shouldLog(Log.INFO))
    1975                     _log.info("Address rebuilt: " + addr);
     1998                    _log.info("Address rebuilt: " + addr, new Exception());
    19761999                replaceAddress(addr);
    19772000                if (allowRebuildRouterInfo)
     
    20002023                // We must remove current address, otherwise the user will see
    20012024                // "firewalled with inbound NTCP enabled" warning in console.
    2002                 // Unfortunately this will remove any IPv6 also,
    2003                 // but we don't have a method to remove just the IPv4 address. FIXME
    2004                 replaceAddress(null);
     2025                // Remove the IPv4 address only
     2026                removeAddress(false);
    20052027                if (allowRebuildRouterInfo)
    20062028                    _context.router().rebuildRouterInfo();
     
    20482070        super.replaceAddress(address);
    20492071        _context.commSystem().notifyReplaceAddress(address);
     2072    }
     2073
     2074    /**
     2075     *  Remove then tell NTCP that we changed.
     2076     *
     2077     *  @since 0.9.20
     2078     */
     2079    @Override
     2080    protected void removeAddress(RouterAddress address) {
     2081        super.removeAddress(address);
     2082        _context.commSystem().notifyRemoveAddress(address);
     2083    }
     2084
     2085    /**
     2086     *  Remove then tell NTCP that we changed.
     2087     *
     2088     *  @since 0.9.20
     2089     */
     2090    @Override
     2091    protected void removeAddress(boolean ipv6) {
     2092        super.removeAddress(ipv6);
     2093        if (ipv6)
     2094            _lastInboundIPv6 = 0;
     2095        _context.commSystem().notifyRemoveAddress(ipv6);
    20502096    }
    20512097
     
    28592905    public Status getReachabilityStatus() {
    28602906        String override = _context.getProperty(PROP_REACHABILITY_STATUS_OVERRIDE);
    2861         if (override == null)
    2862             return _reachabilityStatus;
    2863            
    2864         if ("ok".equals(override))
    2865             return Status.OK;
    2866         else if ("err-reject".equals(override))
    2867             return Status.REJECT_UNSOLICITED;
    2868         else if ("err-different".equals(override))
    2869             return Status.DIFFERENT;
    2870        
     2907        if (override != null) {
     2908            if ("ok".equals(override))
     2909                return Status.OK;
     2910            else if ("err-reject".equals(override))
     2911                return Status.REJECT_UNSOLICITED;
     2912            else if ("err-different".equals(override))
     2913                return Status.DIFFERENT;
     2914        }
    28712915        return _reachabilityStatus;
    28722916    }
Note: See TracChangeset for help on using the changeset viewer.