y500 / libtorrent

Automatically exported from code.google.com/p/libtorrent
0 stars 0 forks source link

Portmap fails without a message #535

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I tried this with 0.16.10, 0.16.11 and 0.16.12.

I have connected to portmap_error_alert, portmap_log_alert, portmap_alert. I 
use both upnp and nat-pmp to add_mapping().

In the `portmap_alert` handler I output this kind of message to a 
log(pseudocode):
QString type;
if (p->map_type == 0)
   type = "NAT-PMP: ";
else if (p->map_type == 1)
   type = "UPnP: ";
addConsoleMessage(type + "Port mapping successful, message:" + p->message());

(p is of type portmap_alert*)

In the log I get messages as these:
03/11/2013 19:03:31 - UPnP: Port mapping successful, message: successfully 
mapped port using UPnP. external port: 30076
03/11/2013 19:03:31 - UPnP: Port mapping successful, message: successfully 
mapped port using UPnP. external port: 7619
03/11/2013 19:03:31 - UPnP: Port mapping successful, message: successfully 
mapped port using UPnP. external port: 0
03/11/2013 19:03:31 - UPnP: Port mapping successful, message: successfully 
mapped port using UPnP. external port: 30076
03/11/2013 19:03:31 - UPnP: Port mapping successful, message: successfully 
mapped port using UPnP. external port: 7619
03/11/2013 19:03:31 - UPnP: Port mapping successful, message: successfully 
mapped port using UPnP. external port: 7619
03/11/2013 19:03:31 - UPnP: Port mapping successful, message: successfully 
mapped port using UPnP. external port: 0
03/11/2013 19:03:31 - UPnP: Port mapping successful, message: successfully 
mapped port using UPnP. external port: 7619

As you can see I don't get a line starting with "NAT-PMP: " nor does a 
'portmap_error_alert' get fired(not even for nat-pmp).
Furthermore, although it reports that it has succeeded in actuality it has 
failed because:
1. I don't see a port entry in my router
2. Using this tool: http://sourceforge.net/projects/upnp-portmapper/ I can 
query my router and see what mappings it has. The above ports aren't in the 
list. Moreover, if I tell this tool to port map these ports it actually 
succeeds in doing so. I even get incoming connections in qbt.

I have saved all 'portmap_log_alert' alerts in a file so it may help you 
understand the problem.
Here is the log in pastebin: http://pastebin.com/MUCiLUt2

Each line was outputted in this way(pseudocode)
QTextStream str(&log);
QString type;
if (p->map_type == 0)
    type = "NAT-PMP: ";
else if (p->map_type == 1)
    type = "UPnP: ";
str << type << "Log, message: " << p->msg << endl;

(p is of type portmap_log_alert*)

Also do you notice the entry about external port 0? I have no idea why it tries 
to do map that. It only does that if I compile with mingw 4.8.0. Msvc2008 
doesn't have this problem. qbt code does try to map this.

Original issue reported on code.google.com by hammered...@gmail.com on 3 Nov 2013 at 5:19

GoogleCodeExporter commented 8 years ago
could you capture a wireshark dump of the UPnP router interaction?

mapping port 0 means the router gets to decide which external port to use. 
iirc, libtorrent tries various things if mappings fail. If it depends on the 
compiler (and possibly run-time) it could be a formatting issue of the 
requests. But I take it the actual mapping fails with both mingw and msvc?

Original comment by arvid.no...@gmail.com on 3 Nov 2013 at 6:38

GoogleCodeExporter commented 8 years ago
Yes, it fails with both.

I'll try to set up wireshark and capture the conversation. Usually wireshark is 
very verbose, any ideas on what filter to use to restrict the info to the 
interesting parts?

Original comment by hammered...@gmail.com on 3 Nov 2013 at 6:46

GoogleCodeExporter commented 8 years ago
"ip.addr == <IP of your router>" is probably the simplest one. you could tie it 
down to ports by adding " && tcp.port == <port used for soap messages>".

Original comment by arvid.no...@gmail.com on 3 Nov 2013 at 7:06

GoogleCodeExporter commented 8 years ago
I've send it to your email.

Original comment by hammered...@gmail.com on 3 Nov 2013 at 8:13

GoogleCodeExporter commented 8 years ago
So, this is what I've found so far:

The SSDP succeeds and we discover the internet gateway device description URL 
/igd.xml and request it. In it, there's a WANIPConnection service which appears 
well-formed:

...<service>
....<serviceType>urn:schemas-upnp-org:service:WANIPConnection:1</serviceType>
....<serviceId>urn:upnp-org:serviceId:WANIPConn1</serviceId>
....<SCPDURL>/igd_wic.xml</SCPDURL>
....<controlURL>/upnp/control?WANIPConnection</controlURL>
....<eventSubURL>/upnp/event?WANIPConnection</eventSubURL>
...</service>

libtorrent then attempts to forward a port:

POST /upnp/control?WANIPConnection HTTP/1.0
Host: 192.168.1.1:80
Content-Type: text/xml; charset="utf-8"
Content-Length: 612
Soapaction: "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" 
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:AddPortMa
pping 
xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewRemoteHost></NewRem
oteHost><NewExternalPort>0</NewExternalPort><NewProtocol>TCP</NewProtocol><NewIn
ternalPort>0</NewInternalPort><NewInternalClient>192.168.1.3</NewInternalClient>
<NewEnabled>1</NewEnabled><NewPortMappingDescription>qBittorrent v3.2.0alpha at 
192.168.1.3:0</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration><
/u:AddPortMapping></s:Body></s:Envelope>

and the router responds with 200 OK, but instead of a valid SOAP response, it 
returns a web page (which clearly it expects to be loaded in a browser, because 
it has javascript in it). libtorrent doesn't currently look for invalid 
responses, just valid error responses. I should probably fix that.

However, it doesn't explain why this router fails.

Original comment by arvid.no...@gmail.com on 4 Nov 2013 at 2:24

GoogleCodeExporter commented 8 years ago
looking for differences between the calls that succeed (from the upnp tool) and 
the libtorrent calls, the only real difference seems to be:

1. libtorrent uses HTTP/1.0 instead of HTTP/1.1 (this was changed to fix 
certain routers that didn't properly support 1.1)
2. libtorrent does not specify a user agent nor cache control headers in its 
request, which the tool does.

Original comment by arvid.no...@gmail.com on 4 Nov 2013 at 2:31

GoogleCodeExporter commented 8 years ago
Could you try this patch? It should fix the error reporting:

Index: src/upnp.cpp
===================================================================
--- src/upnp.cpp    (revision 9274)
+++ src/upnp.cpp    (working copy)
@@ -1260,6 +1260,17 @@
        return;
    }

+   std::string ct = p.header("content-type");
+   if (!ct.empty() && ct.find_first_of("text/xml") == std::string::npos)
+   {
+       char msg[300];
+       snprintf(msg, sizeof(msg), "error while adding port map: invalid 
content-type, %s. Expected text/xml"
+           , ct.c_str());
+       log(msg, l);
+       next(d, mapping, l);
+       return;
+   }
+
    // We don't want to ignore responses with return codes other than 200
    // since those might contain valid UPnP error codes

Original comment by arvid.no...@gmail.com on 4 Nov 2013 at 2:40

GoogleCodeExporter commented 8 years ago
have you had any chance to test this?

Original comment by arvid.no...@gmail.com on 6 Nov 2013 at 5:36

GoogleCodeExporter commented 8 years ago
Nope , sprry. I've been busy in RL. I'll try to test it today.

Original comment by hammered...@gmail.com on 6 Nov 2013 at 7:52

GoogleCodeExporter commented 8 years ago

Original comment by arvid.no...@gmail.com on 8 Nov 2013 at 9:56

GoogleCodeExporter commented 8 years ago
I suppose you closed this because I was inactive. I think you gave to reopen 
this. I tested today with r9305.

1. I still get portmap_alert and not portmap_error_alert. Also these indicate 
only Upnp stuff, not nat-pmp stuff. I don't get anything about nat-pmp.

2. I was hoping that you really extend the upnp capabilities of libtorrent to 
work with my router too, like that java tool does(open source)

Original comment by hammered...@gmail.com on 13 Nov 2013 at 10:44

GoogleCodeExporter commented 8 years ago
could you capture a successful portmap open with your router? (if at all 
possible, please keep the capture to just the device descriptions xml and the 
soap messages)

Original comment by arvid.no...@gmail.com on 15 Nov 2013 at 12:18

GoogleCodeExporter commented 8 years ago
I'll email it tomorrow. And I'll try to keep it as short as possible (wireshark 
is very verbose even with ip.addr set.)

Original comment by hammered...@gmail.com on 15 Nov 2013 at 12:43