Changeset 9452547


Ignore:
Timestamp:
Aug 20, 2012 12:22:00 PM (7 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
5bb90c6
Parents:
34c0958
Message:
  • SSU: Allow port change if firewalled
  • UPnP:
    • Prep for UPnP returning different external port
    • Better logging of errors
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • history.txt

    r34c0958 r9452547  
     12012-08-20 zzz
     2 * I2CP: MessageStatus cleanup
     3 * i2psnark: Add minimum tracker and DHT announce intervals
     4 * I2PTunnelRunner: Remove unnecessary lock (ticket #690)
     5 * SSU: Allow port change if firewalled
     6 * Streaming: Increase max connection timeout
     7 * UPnP:
     8   - Prep for UPnP returning different external port
     9   - Better logging of errors
     10
    1112012-08-18 kytv
    212 * Fix hang during uninstallation experienced by some users in Windows
     
    919   - Fix another DHT warning message
    1020 * SSU:
    11    - Use remote MTU when published (ticket #687)
     21   - Use remote MTU when published (ticket #682)
    1222   - Queue outbound msgs during inbound establish
    1323   - IntroManager cleanups
  • router/java/src/net/i2p/router/RouterVersion.java

    r34c0958 r9452547  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 12;
     21    public final static long BUILD = 13;
    2222
    2323    /** for example "-test" */
  • router/java/src/net/i2p/router/transport/Transport.java

    r34c0958 r9452547  
    4141    public static final String SOURCE_CONFIG = "config"; // unused
    4242    public void externalAddressReceived(String source, byte[] ip, int port);
    43     public void forwardPortStatus(int port, boolean success, String reason);
     43    public void forwardPortStatus(int port, int externalPort, boolean success, String reason);
    4444    public int getRequestedPort();
    4545    public void setListener(TransportEventListener listener);
  • router/java/src/net/i2p/router/transport/TransportImpl.java

    r34c0958 r9452547  
    478478
    479479    /**
    480      *  Notify a transport of the results of trying to forward a port
    481      */
    482     public void forwardPortStatus(int port, boolean success, String reason) {}
     480     *  Notify a transport of the results of trying to forward a port.
     481     *  @param port the internal port
     482     *  @param externalPort the external port, which for now should always be the same as
     483     *                      the internal port if the forwarding was successful.
     484     */
     485    public void forwardPortStatus(int port, int externalPort, boolean success, String reason) {}
    483486
    484487    /**
     
    584587    }
    585588
     589    /** @param addr non-null */
    586590    public static boolean isPubliclyRoutable(byte addr[]) {
    587591        if (addr.length == 4) {
    588             if ((addr[0]&0xFF) == 127) return false;
    589             if ((addr[0]&0xFF) == 10) return false;
    590             if ( ((addr[0]&0xFF) == 172) && ((addr[1]&0xFF) >= 16) && ((addr[1]&0xFF) <= 31) ) return false;
    591             if ( ((addr[0]&0xFF) == 192) && ((addr[1]&0xFF) == 168) ) return false;
    592             if ((addr[0]&0xFF) >= 224) return false; // no multicast
    593             if ((addr[0]&0xFF) == 0) return false;
    594             if ( ((addr[0]&0xFF) == 169) && ((addr[1]&0xFF) == 254) ) return false;
     592            int a0 = addr[0] & 0xFF;
     593            if (a0 == 127) return false;
     594            if (a0 == 10) return false;
     595            int a1 = addr[1] & 0xFF;
     596            if (a0 == 172 && a1 >= 16 && a1 <= 31) return false;
     597            if (a0 == 192 && a1 == 168) return false;
     598            if (a0 >= 224) return false; // no multicast
     599            if (a0 == 0) return false;
     600            if (a0 == 169 && a1 == 254) return false;
    595601            // 5/8 allocated to RIPE (30 November 2010)
    596602            //if ((addr[0]&0xFF) == 5) return false;  // Hamachi
  • router/java/src/net/i2p/router/transport/TransportManager.java

    r34c0958 r9452547  
    131131     *
    132132     */
    133     public void forwardPortStatus(String style, int port, boolean success, String reason) {
     133    public void forwardPortStatus(String style, int port, int externalPort, boolean success, String reason) {
    134134        Transport t = getTransport(style);
    135135        if (t != null)
    136             t.forwardPortStatus(port, success, reason);
     136            t.forwardPortStatus(port, externalPort, success, reason);
    137137    }
    138138
  • router/java/src/net/i2p/router/transport/UPnP.java

    r34c0958 r9452547  
    88import java.net.UnknownHostException;
    99import java.net.URL;
    10 import java.util.HashMap;
     10import java.util.Collections;
    1111import java.util.HashSet;
    1212import java.util.Iterator;
     13import java.util.Map;
    1314import java.util.Set;
    1415
     
    2627import org.cybergarage.upnp.Service;
    2728import org.cybergarage.upnp.ServiceList;
     29import org.cybergarage.upnp.UPnPStatus;
    2830import org.cybergarage.upnp.device.DeviceChangeListener;
    2931import org.cybergarage.upnp.event.EventListener;
     
    162164        }
    163165       
     166        /**
     167         *  DeviceChangeListener
     168         */
    164169        public void deviceAdded(Device dev) {
    165170                synchronized (lock) {
     
    280285        }
    281286       
     287        /**
     288         *  DeviceChangeListener
     289         */
    282290        public void deviceRemoved(Device dev ){
    283291                if (_log.shouldLog(Log.WARN))
     
    299307        }
    300308       
    301         /** event callback - unused for now - how many devices support events? */
     309        /**
     310         *  EventListener callback -
     311         *  unused for now - how many devices support events?
     312         */
    302313        public void eventNotifyReceived(String uuid, long seq, String varName, String value) {
    303314                if (_log.shouldLog(Log.WARN))
     
    536547        }
    537548       
    538         /** blocking */
     549        /**
     550         *  This always requests that the external port == the internal port, for now.
     551         *  Blocking!
     552         */
    539553        private boolean addMapping(String protocol, int port, String description, ForwardPort fp) {
    540554                if(isDisabled || !isNATPresent() || _router == null) {
     
    569583                add.setArgumentValue("NewLeaseDuration", 0);
    570584               
    571                 if(add.postControlAction()) {
     585                boolean rv = add.postControlAction();
     586                if(rv) {
    572587                        synchronized(lock) {
    573588                                portsForwarded.add(fp);
    574589                        }
    575                         return true;
    576                 } else return false;
     590                }
     591
     592                int level = rv ? Log.INFO : Log.WARN;
     593                if (_log.shouldLog(level)) {
     594                        StringBuilder buf = new StringBuilder();
     595                        buf.append("AddPortMapping result for ").append(protocol).append(" port ").append(port);
     596                        // Not sure which of these has the good info
     597                        UPnPStatus status = add.getStatus();
     598                        if (status != null)
     599                            buf.append(" Status: ").append(status.getCode()).append(' ').append(status.getDescription());
     600                        status = add.getControlStatus();
     601                        if (status != null)
     602                            buf.append(" ControlStatus: ").append(status.getCode()).append(' ').append(status.getDescription());
     603                        _log.log(level, buf.toString());
     604                }
     605
     606                // TODO if port is busy, retry with wildcard external port ??
     607                // from spec:
     608                // 402 Invalid Args See UPnP Device Architecture section on Control.
     609                // 501 Action Failed See UPnP Device Architecture section on Control.
     610                // 715 WildCardNotPermittedInSrcIP The source IP address cannot be wild-carded
     611                // 716 WildCardNotPermittedInExtPort The external port cannot be wild-carded
     612                // 718 ConflictInMappingEntry The port mapping entry specified conflicts with a mapping assigned previously to another client
     613                // 724 SamePortValuesRequired Internal and External port values must be the same
     614                // 725 OnlyPermanentLeasesSupported The NAT implementation only supports permanent lease times on port mappings
     615                // 726 RemoteHostOnlySupportsWildcard RemoteHost must be a wildcard and cannot be a specific IP address or DNS name
     616                // 727 ExternalPortOnlySupportsWildcard ExternalPort must be a wildcard and cannot be a specific port value
     617
     618                // TODO return error code and description for display
     619
     620                return rv;
    577621        }
    578622
     
    668712
    669713        /**
     714         *  Registers a callback when the given ports change.
    670715         *  non-blocking
    671716         *  @param ports non-null
     717         *  @param cb in UPnPManager
    672718         */
    673719        public void onChangePublicPorts(Set<ForwardPort> ports, ForwardPortCallback cb) {
     
    761807
    762808                public void run() {
    763                         HashMap<ForwardPort, ForwardPortStatus> map = new HashMap(1);
    764809                        for(ForwardPort port : portsToForwardNow) {
    765810                                String proto = protoToString(port.protocol);
    766                                 map.clear();
    767811                                ForwardPortStatus fps;
    768812                                if (proto.length() <= 1) {
     
    773817                                        fps = new ForwardPortStatus(ForwardPortStatus.PROBABLE_FAILURE, "UPnP port forwarding apparently failed", port.portNumber);
    774818                                }
    775                                 map.put(port, fps);
     819                                Map map = Collections.singletonMap(port, fps);
    776820                                forwardCallback.portForwardStatus(map);
    777821                        }
  • router/java/src/net/i2p/router/transport/UPnPManager.java

    r34c0958 r9452547  
    153153                    continue;
    154154                boolean success = fps.status >= ForwardPortStatus.MAYBE_SUCCESS;
    155                 _manager.forwardPortStatus(style, fp.portNumber, success, fps.reasonString);
     155                _manager.forwardPortStatus(style, fp.portNumber, fps.externalPort, success, fps.reasonString);
    156156            }
    157157        }
  • router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java

    r34c0958 r9452547  
    665665     */
    666666    @Override
    667     public void forwardPortStatus(int port, boolean success, String reason) {
     667    public void forwardPortStatus(int port, int externalPort, boolean success, String reason) {
    668668        if (_log.shouldLog(Log.WARN)) {
    669669            if (success)
  • router/java/src/net/i2p/router/transport/udp/UDPTransport.java

    r34c0958 r9452547  
    103103    public static final String STYLE = "SSU";
    104104    public static final String PROP_INTERNAL_PORT = "i2np.udp.internalPort";
    105     /** now unused, we pick a random port */
     105
     106    /** now unused, we pick a random port
     107     *  @deprecated unused
     108     */
    106109    public static final int DEFAULT_INTERNAL_PORT = 8887;
    107     /** since fixed port defaults to true, this doesnt do anything at the moment.
    108      *  We should have an exception if it matches the existing low port. */
     110
     111    /** Limits on port told to us by others,
     112     *  We should have an exception if it matches the existing low port.
     113     */
    109114    private static final int MIN_EXTERNAL_PORT = 1024;
     115    private static final int MAX_EXTERNAL_PORT = 65535;
    110116
    111117    /** define this to explicitly set an external IP address */
     
    126132    private static final String DEFAULT_PREFER_UDP = "false";
    127133   
    128     /** if true (default), we don't change our advertised port no matter what our peers tell us */
    129     public static final String PROP_FIXED_PORT = "i2np.udp.fixedPort";
    130     private static final String DEFAULT_FIXED_PORT = "true";
     134    /** Override whether we will change our advertised port no matter what our peers tell us
     135     *  See getIsPortFixed() for default behaviour.
     136     */
     137    private static final String PROP_FIXED_PORT = "i2np.udp.fixedPort";
    131138
    132139    /** allowed sources of address updates */
     
    481488     */
    482489    @Override
    483     public void forwardPortStatus(int port, boolean success, String reason) {
     490    public void forwardPortStatus(int port, int externalPort, boolean success, String reason) {
    484491        if (_log.shouldLog(Log.WARN)) {
    485492            if (success)
    486                 _log.warn("UPnP has opened the SSU port: " + port);
     493                _log.warn("UPnP has opened the SSU port: " + port + " via external port: " + externalPort);
    487494            else
    488495                _log.warn("UPnP has failed to open the SSU port: " + port + " reason: " + reason);
     
    510517    void externalAddressReceived(Hash from, byte ourIP[], int ourPort) {
    511518        boolean isValid = isValid(ourIP) &&
    512                           (ourPort >= MIN_EXTERNAL_PORT || ourPort == _externalListenPort || _externalListenPort <= 0);
     519                          ((ourPort >= MIN_EXTERNAL_PORT && ourPort <= MAX_EXTERNAL_PORT) ||
     520                           ourPort == _externalListenPort || _externalListenPort <= 0);
    513521        boolean explicitSpecified = explicitAddressSpecified();
    514522        boolean inboundRecent = _lastInboundReceivedOn + ALLOW_IP_CHANGE_INTERVAL > System.currentTimeMillis();
     
    562570     */
    563571    private boolean changeAddress(byte ourIP[], int ourPort) {
    564         /** this defaults to true, which means we never change our external port based on what somebody tells us */
     572        // this defaults to true when we are firewalled and false otherwise.
    565573        boolean fixedPort = getIsPortFixed();
    566574        boolean updated = false;
     
    584592                            _externalListenHost = InetAddress.getByAddress(ourIP);
    585593                            // fixed port defaults to true so we never do this
    586                             if (ourPort >= MIN_EXTERNAL_PORT && !fixedPort)
     594                            if (ourPort >= MIN_EXTERNAL_PORT && ourPort <= MAX_EXTERNAL_PORT && !fixedPort)
    587595                                _externalListenPort = ourPort;
    588596                            if (_log.shouldLog(Log.WARN))
     
    615623
    616624        if (fireTest) {
    617             _context.statManager().addRateData("udp.addressTestInsteadOfUpdate", 1, 0);
     625            _context.statManager().addRateData("udp.addressTestInsteadOfUpdate", 1);
    618626        } else if (updated) {
    619             _context.statManager().addRateData("udp.addressUpdated", 1, 0);
     627            _context.statManager().addRateData("udp.addressUpdated", 1);
    620628            Map<String, String> changes = new HashMap();
    621629            if (!fixedPort)
     
    670678    }
    671679   
     680    /** @param addr may be null */
    672681    public final boolean isValid(byte addr[]) {
    673682        if (addr == null) return false;
    674         if (addr.length < 4) return false;
    675683        if (isPubliclyRoutable(addr))
    676684            return true;
     
    678686    }
    679687   
     688    /**
     689     *  Was true before 0.9.2
     690     *  Now false if we need introducers (as perhaps that's why we need them,
     691     *  our firewall is changing our port), unless overridden by the property.
     692     */
    680693    private boolean getIsPortFixed() {
    681         return DEFAULT_FIXED_PORT.equals(_context.getProperty(PROP_FIXED_PORT, DEFAULT_FIXED_PORT));
     694        String prop = _context.getProperty(PROP_FIXED_PORT);
     695        if (prop != null)
     696            return Boolean.valueOf(prop).booleanValue();
     697        int status = getReachabilityStatus();
     698        return status != CommSystemFacade.STATUS_REJECT_UNSOLICITED;
    682699    }
    683700
     
    863880                    RemoteHostId remote = peer.getRemoteHostId();
    864881                    _dropList.add(remote);
    865                     _context.statManager().addRateData("udp.dropPeerDroplist", 1, 0);
     882                    _context.statManager().addRateData("udp.dropPeerDroplist", 1);
    866883                    _context.simpleScheduler().addEvent(new RemoveDropList(remote), DROPLIST_PERIOD);
    867884                }
     
    23612378        switch (status) {
    23622379            case CommSystemFacade.STATUS_OK:
    2363                 _context.statManager().addRateData("udp.statusOK", 1, 0);
     2380                // TODO if OK but internal port != external port, should we have
     2381                // a different status state? ...as we don't know if the TCP
     2382                // port will be mapped the same way or not...
     2383                // Right now, we assume it is and hope for the best for TCP.
     2384                _context.statManager().addRateData("udp.statusOK", 1);
    23642385                _reachabilityStatus = status;
    23652386                _reachabilityStatusLastUpdated = now;
    23662387                break;
    23672388            case CommSystemFacade.STATUS_DIFFERENT:
    2368                 _context.statManager().addRateData("udp.statusDifferent", 1, 0);
     2389                _context.statManager().addRateData("udp.statusDifferent", 1);
    23692390                _reachabilityStatus = status;
    23702391                _reachabilityStatusLastUpdated = now;
    23712392                break;
    23722393            case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
    2373                 _context.statManager().addRateData("udp.statusReject", 1, 0);
     2394                _context.statManager().addRateData("udp.statusReject", 1);
    23742395// if old != unsolicited && now - lastUpdated > STATUS_GRACE_PERIOD)
    23752396//
     
    23812402            case CommSystemFacade.STATUS_UNKNOWN:
    23822403            default:
    2383                 _context.statManager().addRateData("udp.statusUnknown", 1, 0);
     2404                _context.statManager().addRateData("udp.statusUnknown", 1);
    23842405                //if (now - _reachabilityStatusLastUpdated < STATUS_GRACE_PERIOD) {
    23852406                //    _testEvent.forceRun();
Note: See TracChangeset for help on using the changeset viewer.