[gui-dev] Re: [codepatch] [core] UPnPManager.java

"Philippe Verdy" <[email protected]> Wed, 29 Dec 2004 00:44:22 +0100
Newsgroups gmane.network.gnutella.limewire.gui.devel
Message-ID <[email protected]>
----- Original Message ----- 
From: "Zlatin Balevsky" <[email protected]>
To: "Philippe Verdy" <[email protected]>
Cc: <[email protected]>
Sent: Tuesday, December 28, 2004 7:25 PM
Subject: Re: [codepatch] [core] UPnPManager.java


> Thanks a lot for the patch Phillipe.  Unfortunately the patch -p0 command 
> rejected it, so we applied the changes manually.

Most probably this did not work because of incoherent end-of-lines in the 
original source file, which was apparently created initially as a binary 
file on a Mac and restored later as a text file, but with the Mac still 
keeping its previous format.

That's why I had to filter CR+CRLF on my PC: this is not possible with 
NotePad which does not allow editing the sequences for end-of-lines, and 
preserves them unless they are deleted and recreated manually. This is not 
possible too with WordPad because it changes silently CR+CRLF into 
CRLF+CRLF, and there's no more indicator of which CR was substituted at 
end-of-lines. But it's possible with MSDOS Edit.com which displays isolated 
CR as a musical note symbol, which can be selected and replaced throughout 
the file.
Under Linux, this should be done by getting the source from CVS, and 
removing all CR characters that remain (CR+end-of-line in CVS text files 
become CR+LF on local files, and only LF is needed to recreate end-of-lines 
into CVS).

> Feel free to poke around the UPnP code more - its a very interesting 
> standard which allows the developers to do a lot of cool stuff with 
> routers.  The third-party we used was not exactly flawless so more review 
> and comments are always welcome.

UPnP is a protocol based on a XML syntax and XSD schemas, and HTTP as the 
transport protocol to perform requests, plus a complex discovery machanism 
using broadcasts on physical links to detect the IP addresses of UPNP 
devices which are directly accessible or that are acting as gateways for 
other UPnP devices.

The most common "bugs" or difficulties to resolve is that for now, LimeWire 
still has no support to handle multiple local IP interfaces with separate 
routing strategies. In fact, LimeWire now uses information from the local OS 
with network interfaces (using APIs that are not part of UPnP), which would 
allow it to handle several routing tables, each with their own firewalling 
rules, their own filters, their own bandwidth management, their own 
connection slots.

Unfortunately, Limewire makes various tricks in the code to handle all as if 
there was only 1 networking interface plus a single loopback address, and it 
fails when handling more complex cases like multicasting on a LAN. I do 
think that the OS network interfaces support in Java.net should be better 
used, so that Limewire would determine more precisely from which interface a 
message was received, and how it can be transfered to another interface, 
possibly after internal masquerading. This would allow LimeWire to act 
transparently as a gateway between all physical links on which it is 
connected, and through which there can be other nodes that are otherwise not 
mutually accessible (except through Internet). LimeWire would be less 
Internet-centric, and could be deployed within private LANs as well.

Today, we find many devices for home users that allow them to interconnect 
various systems through distinct LANs or WANs: DSL routers, cable routers, 
Ethernet hub, Wifi access points, BlueTooth, electrical wave adapters, 
infrared, Wi-Max accesses (I have it available since one month in my area: 
50 Megabits/second for a introduction price only 30% higher than 1Mb/s ADSL, 
and the same price as 8Mb/s accesses, but the small city where I live now 
cannot benefit of new ADSL2+ accesses at 8Mb/s to 15Mb/s offered only in 
large French cities!), private Wi-Max networks (802.11a, authorized recently 
within a 3km distance, and which is starting to expand across large cities 
as private alternative bandwidth providers).

So users have now plenty of connections available, including for the 
Internet access, and the only way to use these connections is to use 
external transparent routers or local routing services exploiting more than 
1 local interface. This is also a requirement for later access to IPv6 
networks that also require multiple logical local interfaces, each one 
managed by separate autodiscovery and autoconfiguration protocols, that 
LimeWire should be able to live with.

Unfortunately, LimeWire has removed the possibility to force the IP address 
for the local interface to listen, and it attempts to determine which local 
interface to use and it sometimes fails. Instead Limewire could listen on 
the 0.0.0.0 (any) pseudo-interface to listen for all local interfaces 
simultaneously, but this causes various problems because port numbers 
assigned on one interface are not necessarily the same through all 
interfaces, when they are managed externally by distinct NAT routers. 
Limewire should better use UPnP devices by allowing them to use PAT if 
possible, so that all local interfaces will be listened on the same local 
port, even if they are routed externally with distinct ports.

Also LimeWire does not work correctly for now in some enterprise networks, 
that use Multi-NAT routers: 1 internal address for the local host connected 
to the LAN, and several external IP interfaces to the Internet managed by 
the MultiNAT router. The MultiNAT router is seen on the network as if it was 
several (virtual) NAT routers each with their own local IP address on the 
same physical link. But it's impossible to determine by a host in the 
internal LAN, which of these virtual routers, Internet connections will be 
coming from, or which one will be actually used for outgoing connections. 
Here again, with UPnP, we could list of these external devices and get info 
about their respective routes.

Some users do complain today that LimeWire was working in previous versions 
from their Enterprise or University private LAN, but not today with the 
recent introduction of the preliminary UPnP support: it certainly comes the 
fact that this code failed to determine correctly which local IP interface 
to listen or advertize, and this causes connection attempts to fail.

Another problem with multihomed hosts: even if UPnP is not supported in 
external devices, there's a support for the local routing tables managed in 
Windows or Unix IP kernels and in java.net. But LimeWire attempts to 
determine the "public" IP address as if it was unique and the same for all 
remote clients. However, LimeWire forgets to determine at least from which 
local interface a message was received, and so makes false determination of 
the "echoed back" public IP addresses. This unique setting can even become 
unstable, always switching from one to another, and causing further 
transfers of QueryHit data or push requests to fail as they contain the 
wrong IP for the effectively used local interface.

If Limewire was separating each interface (including the loopback interface 
at 127.0.0.1), things would be simpler and more stable. The configuration 
panel could list each interface according to the addresse types they can 
route. An interface that can route loopback addresses would have limited 
configuration options and no need to specify IP addresses: it would be 
configured directly under the name "local host loopback interface", and the 
user could enable/disable its support separately (disabling the loopback 
would have the effect of closing the support for external Magnet handlers, 
so Magnet options should only be present in the configuration pane for the 
local host interface).

Many hosts would have an additional interface active only when the Internet 
connection is active: it can be detected by the fact that it routes the 
0.0.0.0 address via the address of a gateway which can connect to the 
Internet. Such interface routing 0.0.0.0 can be qualified of "Internet 
connection", and the interface specified in the routing table is clear about 
this.

See for exampel what my PC indicates in its routing table:

D:\CVSHOME\limewire\gui>netstat -rn

Table de routage
===========================================================================
Liste d'Interfaces
0x1 ........................... MS TCP Loopback interface
0x2 ...00 0e a6 c4 a7 5b ...... Broadcom NetXtreme Gigabit Ethernet - 
Miniport d'ordonnancement de paquets
===========================================================================
===========================================================================
Itinéraires actifs :
Destination réseau    Masque réseau  Adr. passerelle   Adr. interface 
Métrique
          0.0.0.0          0.0.0.0       10.0.0.138        10.0.0.3       20
         10.0.0.0    255.255.255.0         10.0.0.3        10.0.0.3       20
         10.0.0.3  255.255.255.255        127.0.0.1       127.0.0.1       20
   10.255.255.255  255.255.255.255         10.0.0.3        10.0.0.3       20
        127.0.0.0        255.0.0.0        127.0.0.1       127.0.0.1       1
        224.0.0.0        240.0.0.0         10.0.0.3        10.0.0.3       20
  255.255.255.255  255.255.255.255         10.0.0.3        10.0.0.3       1
Passerelle par défaut :        10.0.0.138
===========================================================================
Itinéraires persistants :
  Aucun


The interesting column in this result is "Adr. interface" which above can be 
either "10.0.0.3" (interface 0x2) or "127.0.0.1" (interface 0x1): this is 
the discriminating information for our routing management data, which then 
determines the LAN segment used by this interface (above, dest. 
reseau=10.0.0.0, netmask=255.255.255.0), and whever this segment is 
connected to the Internet by an intermediate router (this is the case here, 
as the interface 10.0.0.3 routes 0.0.0.0 via the 10.0.0.138 gateway).

All this is directly accessible in java.net without UPnP. Before using UPnP 
(which will be useful only to get similar routing tables for other remote 
hosts), one should first handle correctly the local routing table as seen by 
the "netstat -rn" command line or by the java.net.* classes (both use the 
SNMP protocol interface with the standard MIBv2 schema to get this 
information).

Now when the LAN interface is disconnected or disabled, the routing table 
becomes:


Table de routage
===========================================================================
Liste d'Interfaces
0x1 ........................... MS TCP Loopback interface
0x2 ...00 0e a6 c4 a7 5b ...... Broadcom NetXtreme Gigabit Ethernet - 
Miniport d'ordonnancement de paquets
===========================================================================
===========================================================================
Itinéraires actifs :
Destination réseau    Masque réseau  Adr. passerelle   Adr. interface 
Métrique
        127.0.0.0        255.0.0.0        127.0.0.1       127.0.0.1       1
  255.255.255.255  255.255.255.255  255.255.255.255               2       1
===========================================================================
Itinéraires persistants :
  Aucun

where the interface address 10.0.0.3 has disappeared and been replaced by 
the pseudo-interface address 2 (displayed simply as "2" or "0x2"): it does 
not route 0.0.0.0 and so it is not connected to the Internet. But the 
interface still routes 255.255.255.255 (ANY_ROUTER), and so is visible as a 
router which can be reenabled and even queried by UPnP, to detect if and 
when it will be able to connect to the Internet.

Using UPnP will display information about this interface 0x2: you can see 
its firewall routing rules, traffic policy, allowed/filtered ports, ICMP 
port/features opened, traffic counters, and allowed applications... Possibly 
more information if you use SNMP and specific MIB schemas, instead of just 
the XML schemas standardized for UPnP devices.


_______________________________________________
gui-dev mailing list
[email protected]
http://www.limewire.org/mailman/listinfo/gui-dev