LWJGL Forum

Programming => General Java Game Development => Topic started by: broumbroum on November 28, 2009, 23:52:49

Title: what about UPNP™ for Java ?
Post by: broumbroum on November 28, 2009, 23:52:49
hi,

I'd like to use upnp for port mapping multi-player activity with the game. I found out upnplib and cyberlink for java.
the latter is quite a bit older, but is there any more recent stuff or do you know a better way to connect two players in a peer-to-peer fashion ?

I've got an implemented server-client interface, whose connection depends on a specific port, selected randomly, but which will not get opened unless set up by the players themselves when using a firewall/router beyond the local network. Then, I'd like to make players able to "announce" on a database located on any internet server, which will list matches (as hosts) available... quite a common sense.
e.g. "I host a game on 23.43.33.222:9090, would you like to join it ?" anyway the odd player wouldn't  establish the connection if he ain't up to access its router admin to open port 9090 for UDP/TCP. Hence, almost all routers run UPNP nowadays so that it can solve the technical issue for that average player.
UPNPLib documentation talks about  security issues with ACL  (http://www.sbbi.net/site/upnp/docs/security.html) which were not available at the time this project was developed, then it may not work with newer devices (???).
Title: Re: what about UPNP™ for Java ?
Post by: broumbroum on December 01, 2009, 01:18:27
I choosed UPNPLib.
Now here's another issue with the local IP address (in my LAN) :                     
localHostIP = InetAddress.getLocalHost().getHostAddress();

always return 127.0.0.2, but I'd like to read my LAN IP address.
from javadoc :
QuoteReturns the local host.

If there is a security manager, its checkConnect method is called with the local host name and -1 as its arguments to see if the operation is allowed. If the operation is not allowed, an InetAddress representing the loopback address is returned.
How to do it ?
Title: Re: what about UPNP™ for Java ?
Post by: bobjob on December 01, 2009, 17:34:25
Im just having a stab at it.

maybe send a network broadcast packet. then when you recieve the packet, check the origin of the IP.

edit: Multiple NIC cards may be a problem, as well as the network each card connects to. So it might be important to first know which network you want the program to run on.
ei. wireless/wired running on the same computer.
Title: Re: what about UPNP™ for Java ?
Post by: broumbroum on December 09, 2009, 22:40:39
Quote from: bobjob on December 01, 2009, 17:34:25
Im just having a stab at it.

maybe send a network broadcast packet. then when you recieve the packet, check the origin of the IP.
(...)
could you explain a bit further on that broadcast please ? It should'nt be casted to the WAN, but the LAN.
I'm connected to my router by wire, so I don't see at the moment where to define Java on the external-LAN address of my pc. it should return 168.192.1.3, not the loopback...

I'm using a Socket to establish connection. But I need first to set the UPNP port to my local address.
For that broadcast trick, is this MulticastSocket http://java.sun.com/docs/books/tutorial/networking/datagrams/definition.html the correct object ?
Title: Re: what about UPNP™ for Java ?
Post by: broumbroum on December 09, 2009, 23:02:12
found how to list NIC, thanks bobjob, http://java.sun.com/docs/books/tutorial/networking/nifs/definition.html.
Title: Re: what about UPNP™ for Java ?
Post by: broumbroum on December 19, 2009, 00:49:07
yet here's how to get it read from a java 1.5 sdk :
Enumeration<NetworkInterface> nic = NetworkInterface.getNetworkInterfaces();
                   while (nic.hasMoreElements()) {
                       NetworkInterface anic = nic.nextElement();
                       Enumeration<InetAddress> addrs = anic.getInetAddresses();
                       while (addrs.hasMoreElements()) {
                           InetAddress addr = addrs.nextElement();
                           if (!addr.isLoopbackAddress() && addr.isSiteLocalAddress()) {
                               localHostIP = addr.getHostAddress();
                               break;
                           }
                       }
                       if (localHostIP != null) {
                           break;
                       }
                   }
                   if (localHostIP == null) {
                       localHostIP = InetAddress.getLocalHost().getHostAddress();
                   }


I have now 192.168.1.5 which is my local area address I was looking for. :D
Now UPNPLib receives the NAT mapping address correctly :
if (gateway != null) {
                        // now let's open the port
                        // we assume that localHostIP is something else than 127.0.0.1
                        mapped = gateway.addPortMapping("Some mapping description", null, internalPort, externalPort, localHostIP, 0, protocol);
                        if (mapped) {
                            System.out.println(JXAenvUtils._JXAEnvOutput("UPNP Port " + externalPort + " mapped for " + protocol + " to " + localHostIP + " : " + internalPort, JXAenvUtils.APP_NOTICE));
                        } else {
                            throw new IOException("UPNP Port " + externalPort + " not mapped");
                        }
                    }