Changeset f7c3195


Ignore:
Timestamp:
Aug 16, 2011 4:20:51 PM (10 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
336e50e9
Parents:
dc02f9c
Message:

UPnP: Fix bug causing failure when the PC has multiple interfaces

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • history.txt

    rdc02f9c rf7c3195  
     12011-08-16 zzz
     2  * UPnP: Fix bug causing failure when the PC has multiple interfaces
     3
    142011-08-06 kytv
    25 * Fix #473 (wrapper.logfile set to the wrong path in Windows).
  • router/java/src/net/i2p/router/RouterVersion.java

    rdc02f9c rf7c3195  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 19;
     21    public final static long BUILD = 20;
    2222
    2323    /** for example "-test" */
  • router/java/src/net/i2p/router/transport/UPnP.java

    rdc02f9c rf7c3195  
    55
    66import java.net.InetAddress;
     7import java.net.MalformedURLException;
    78import java.net.UnknownHostException;
     9import java.net.URL;
    810import java.util.HashMap;
    911import java.util.HashSet;
     
    1315import net.i2p.I2PAppContext;
    1416import net.i2p.data.DataHelper;
     17import net.i2p.util.Addresses;
    1518import net.i2p.util.Log;
    1619import net.i2p.util.Translate;
     
    528531                // Just in case...
    529532                // this confuses my linksys? - zzz
    530                 removeMapping(protocol, port, fp, true);
     533                //removeMapping(protocol, port, fp, true);
    531534               
    532535                Action add = _service.getAction("AddPortMapping");
     
    539542                add.setArgumentValue("NewRemoteHost", "");
    540543                add.setArgumentValue("NewExternalPort", port);
    541                 add.setArgumentValue("NewInternalClient", _router.getInterfaceAddress());
     544                // bugfix, see below for details
     545                String intf = _router.getInterfaceAddress();
     546                String us = getOurAddress(intf);
     547                if (_log.shouldLog(Log.WARN) && !us.equals(intf))
     548                        _log.warn("Requesting port forward to " + us + ':' + port +
     549                                  " when cybergarage wanted " + intf);
     550                add.setArgumentValue("NewInternalClient", us);
    542551                add.setArgumentValue("NewInternalPort", port);
    543552                add.setArgumentValue("NewProtocol", protocol);
     
    553562                } else return false;
    554563        }
    555        
     564
     565        /**
     566         * Bug fix:
     567         * If the SSDP notify or search response sockets listen on more than one interface,
     568         * cybergarage can get our IP address wrong, and then we send the wrong one
     569         * to the UPnP device, which will reject it if it enforces strict addressing.
     570         *
     571         * For example, if we have interfaces 192.168.1.1 and 192.168.2.1, we could
     572         * get a response from 192.168.1.99 on the 192.168.2.1 interface, but when
     573         * we send something to 192.168.1.99 it will go out the 192.168.1.1 interface
     574         * with a request to forward to 192.168.2.1.
     575         *
     576         * So return the address of ours that is closest to his.
     577         *
     578         * @since 0.8.8
     579         */
     580        private String getOurAddress(String deflt) {
     581                String rv = deflt;
     582                String hisIP = null;
     583                // see ControlRequest.setRequestHost()
     584                String him = _router.getURLBase();
     585                if (him != null && him.length() > 0) {
     586                        try {
     587                                URL url = new URL(him);
     588                                hisIP = url.getHost();
     589                        } catch (MalformedURLException mue) {}
     590                }
     591                if (hisIP == null) {
     592                        him = _router.getLocation();
     593                        if (him != null && him.length() > 0) {
     594                                try {
     595                                        URL url = new URL(him);
     596                                        hisIP = url.getHost();
     597                                } catch (MalformedURLException mue) {}
     598                        }
     599                }
     600                if (hisIP == null)
     601                        return rv;
     602                try {
     603                        byte[] hisBytes = InetAddress.getByName(hisIP).getAddress();
     604                        if (hisBytes.length != 4)
     605                                return deflt;
     606                        long hisLong = DataHelper.fromLong(hisBytes, 0, 4);
     607                        long distance = Long.MAX_VALUE;
     608
     609                        // loop through all our IP addresses, including the default, and
     610                        // return the one closest to the router's IP
     611                        Set<String> myAddresses = Addresses.getAddresses(true, false);  // yes local, no IPv6
     612                        myAddresses.add(deflt);
     613                        for (String me : myAddresses) {
     614                                if (me.startsWith("127.") || me.equals("0.0.0.0"))
     615                                        continue;
     616                                try {
     617                                        byte[] myBytes = InetAddress.getByName(me).getAddress();
     618                                        long myLong = DataHelper.fromLong(myBytes, 0, 4);
     619                                        long newDistance = myLong ^ hisLong;
     620                                        if (newDistance < distance) {
     621                                                rv = me;
     622                                                distance = newDistance;
     623                                        }
     624                                } catch (UnknownHostException uhe) {}
     625                        }
     626                } catch (UnknownHostException uhe) {}
     627                return rv;
     628        }
     629
    556630        /** blocking */
    557631        private boolean removeMapping(String protocol, int port, ForwardPort fp, boolean noLog) {
  • router/java/src/org/cybergarage/upnp/ControlPoint.java

    rdc02f9c rf7c3195  
    231231                                return;
    232232                        rootDev.setSSDPPacket(ssdpPacket);
     233                        Debug.warning("Add root device", new Exception("received on " + ssdpPacket.getLocalAddress()));
    233234                        addDevice(rootNode);
    234235
  • router/java/src/org/cybergarage/upnp/ssdp/HTTPMUSocket.java

    rdc02f9c rf7c3195  
    192192                        ssdpMultiSock.receive(recvPacket.getDatagramPacket());
    193193                        recvPacket.setTimeStamp(System.currentTimeMillis());
     194                        Debug.warning("Received SSDP multicast packet on " + getLocalAddress() + " from " + recvPacket.getRemoteAddress());
    194195                }
    195196                catch (Exception e) {
  • router/java/src/org/cybergarage/upnp/ssdp/HTTPUSocket.java

    rdc02f9c rf7c3195  
    196196                        ssdpUniSock.receive(recvPacket.getDatagramPacket());
    197197                        recvPacket.setTimeStamp(System.currentTimeMillis());
     198                        Debug.warning("Received SSDP unicast packet on " + getLocalAddress() + " from " + recvPacket.getRemoteAddress());
    198199                }
    199200                catch (Exception e) {
  • router/java/src/org/cybergarage/upnp/ssdp/SSDPNotifySocket.java

    rdc02f9c rf7c3195  
    3030import org.cybergarage.http.*;
    3131import org.cybergarage.upnp.*;
     32import org.cybergarage.util.Debug;
    3233
    3334public class SSDPNotifySocket extends HTTPMUSocket implements Runnable
     
    4849                }
    4950                open(addr, SSDP.PORT, bindAddr);
     51                Debug.warning("Opened SSDP notify socket at " + bindAddr + ':' + SSDP.PORT);
    5052                setControlPoint(null);
    5153        }
  • router/java/src/org/cybergarage/upnp/ssdp/SSDPSearchResponseSocketList.java

    rdc02f9c rf7c3195  
    2323
    2424import org.cybergarage.upnp.*;
     25import org.cybergarage.util.Debug;
    2526
    2627public class SSDPSearchResponseSocketList extends Vector
     
    6970                                String bindAddr = HostInterface.getHostAddress(n);
    7071                                SSDPSearchResponseSocket socket = new SSDPSearchResponseSocket(bindAddr, port);
     72                                Debug.warning("Opened SSDP search response socket at " + bindAddr + ':' + port);
    7173                                add(socket);
    7274                        }
  • router/java/src/org/cybergarage/upnp/ssdp/SSDPSearchSocket.java

    rdc02f9c rf7c3195  
    3838        {
    3939                open(bindAddr);
     40                Debug.warning("Opened SSDP search socket at " + bindAddr + ':' + SSDP.PORT);
    4041        }
    4142
Note: See TracChangeset for help on using the changeset viewer.