xpra icon
Bug tracker and wiki

Opened 14 months ago

Closed 2 weeks ago

#2417 closed enhancement (fixed)

IGD / UPNP integration

Reported by: Antoine Martin Owned by: Antoine Martin
Priority: major Milestone: 4.1
Component: network Version: 3.0.x
Keywords: Cc:

Description

So servers can be made reachable over the internet more easily.
(and clients too, now with listen mode: #1022)

Python: Open a Listening Port Behind a Router (upnp?)

Change History (5)

comment:1 Changed 9 months ago by Antoine Martin

Milestone: 4.05.0

Tried using:

My router claims to have upnp enabled.

Last edited 9 months ago by Antoine Martin (previous) (diff)

comment:2 Changed 5 months ago by Antoine Martin

Milestone: 5.04.1

pupnp has package for mingw.

comment:3 Changed 3 weeks ago by Antoine Martin

Status: newassigned

UPnPy looks like a better option, recent releases, good documentation.
Sadly, no packages for Fedora..

It looked promising:

import upnpy
upnp = upnpy.UPnP()
devices = upnp.discover()
device = upnp.get_igd()
device.get_services()
[<Service (Dummy) id="dummy1">, <Service (WANCommonInterfaceConfig) id="WANCommonIFC1">, <Service (WANIPConnection) id="WANIPConn1">]
service = device.get_services()[2]
service.GetExternalIPAddress()
XXX.XXX.XXX.XXX
service.get_actions()
[<Action name="SetConnectionType">, <Action name="GetConnectionTypeInfo">, \
 <Action name="RequestConnection">, <Action name="ForceTermination">, \
 <Action name="GetStatusInfo">, <Action name="GetNATRSIPStatus">, \
 <Action name="GetGenericPortMappingEntry">, <Action name="GetSpecificPortMappingEntry">, \
 <Action name="AddPortMapping">, <Action name="DeletePortMapping">, \
 <Action name="GetExternalIPAddress">]
service.AddPortMapping(NewRemoteHost='', NewExternalPort=10000, NewProtocol="TCP", \
 NewInternalPort=10000, NewInternalClient="192.168.0.10", \
 NewEnabled=1, NewPortMappingDescription="xpra-10000", NewLeaseDuration=3600)

Looks like it's done something, but the port is not actually reachable from the outside.

tcptraceroute ends with a different status depending on where it is launched from - all going to the same targe port!:

  • USA:
    11  * * *
    12  * * *
    13  * * *
    14  * * ?????.dynamic.???? (IP) <rst,ack>  223.845 ms
    
  • Europe:
    13  * * *
    14  * * *
    15  * * *
    16  * * *
    17  ?????.dynamic.???? (IP) [closed]  210.457 ms  210.540 ms  210.047 ms
    

So maybe I will need to test with another / better router, openwrt supports it.
(and users are likely to hit issues too... because there is bound to be many other broken setups out there: buggy routers, firewalls, etc)

comment:4 Changed 3 weeks ago by Antoine Martin

Works with freshtomato on a WRT54GL.

Implemented in r27642.

Tested with:

python3 /usr/bin/xpra start :20 --bind-tcp=0.0.0.0:10000,upnp=on --start=xterm --no-daemon  -d upnp

Setup debug:

2020-10-09 23:57:14,793 upnp_add('tcp', ('0.0.0.0', 10000), {'upnp': 'on'})
2020-10-09 23:57:14,821 upnp=<upnpy.upnp.UPnP.UPnP object at 0x7fa8a69b9460>
2020-10-09 23:57:16,948 using igd device Device <AP3 Router>
2020-10-09 23:57:16,949 device: AP3 Router
2020-10-09 23:57:16,949 device address: ('192.168.3.1', 1900)
2020-10-09 23:57:16,952 identified interface 'eth0' for device address ('192.168.3.1', 1900)
2020-10-09 23:57:16,953 ifaddresses(eth0)={17: [{'addr': '00:0e:c6:c2:72:86', 'broadcast': 'ff:ff:ff:ff:ff:ff'}], 2: [{'addr': '192.168.3.119', 'netmask': '255.255.255.0', 'broadcast': '192.168.3.255'}], 10: [{'addr': 'fe80::6941:f5ff:7728:6a2b%eth0', 'netmask': 'ffff:ffff:ffff:ffff::/64'}]}
2020-10-09 23:57:16,953 addresses[INET]=[{'addr': '192.168.3.119', 'netmask': '255.255.255.0', 'broadcast': '192.168.3.255'}]
2020-10-09 23:57:16,954 services=<Service (Layer3Forwarding) id="L3Forwarding1">, <Service (WANCommonInterfaceConfig) id="WANCommonIFC1">, <Service (WANIPConnection) id="WANIPConn1">
2020-10-09 23:57:16,954 <Action name="AddPortMapping">{'NewRemoteHost': '', 'NewExternalPort': 10000, 'NewProtocol': 'TCP', 'NewInternalPort': 10000, 'NewInternalClient': '192.168.3.119', 'NewEnabled': True, 'NewPortMappingDescription': 'Xpra-tcp', 'NewLeaseDuration': 600}
2020-10-09 23:57:16,978 GetConnectionTypeInfo={'NewConnectionType': 'IP_Routed', 'NewPossibleConnectionTypes': 'IP_Routed'}
2020-10-09 23:57:16,986 GetStatusInfo={'NewConnectionStatus': 'Connected', 'NewLastConnectionError': 'ERROR_NONE', 'NewUptime': '27253'}
2020-10-09 23:57:16,993  UPnP port mapping added for 192.168.0.102:10000
2020-10-09 23:57:16,994 xpra is ready.

It adds 2 seconds to the startup time as it needs to identify the upnp devices on the network. (could be much more on bigger networks?)

And it gets removed when the server is shut down:

2020-10-09 23:57:25,758 Shutting down in response to client request
(..)
2020-10-09 23:57:26,427 <Action name="DeletePortMapping">{'NewRemoteHost': '', 'NewExternalPort': 10000, 'NewProtocol': 'TCP'}

TODO:

  • more testing, especially specifying the device and service by hand using the upnp-device and upnp-service, also: upnp-remote-host, upnp-external-port, upnp-duration
  • expose the external IP in the socket options, send it to the client so it can generate more useful QR codes (#2627)

comment:5 Changed 2 weeks ago by Antoine Martin

Resolution: fixed
Status: assignedclosed
Note: See TracTickets for help on using tickets.