From b9bd7dbc5dda17b7b8abb938092aa0a625c27056 Mon Sep 17 00:00:00 2001 From: julianknodt Date: Tue, 10 Aug 2021 14:50:33 -0700 Subject: [PATCH] net/portmapper: log upnp information This logs some basic statistics for UPnP, so that tailscale can better understand what routers are being used and how to connect to them. Signed-off-by: julianknodt --- net/portmapper/portmapper.go | 5 ++++- net/portmapper/upnp.go | 7 +++++++ net/portmapper/upnp_test.go | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/net/portmapper/portmapper.go b/net/portmapper/portmapper.go index e4ca98d83..1f955f67d 100644 --- a/net/portmapper/portmapper.go +++ b/net/portmapper/portmapper.go @@ -714,7 +714,10 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) { res.UPnP = true c.mu.Lock() c.uPnPSawTime = time.Now() - c.uPnPMeta = meta + if c.uPnPMeta != meta { + c.logf("UPnP meta changed: %+v", meta) + c.uPnPMeta = meta + } c.mu.Unlock() } case c.pxpPort(): // same value for PMP and PCP diff --git a/net/portmapper/upnp.go b/net/portmapper/upnp.go index d153dbe33..de6b32026 100644 --- a/net/portmapper/upnp.go +++ b/net/portmapper/upnp.go @@ -311,6 +311,11 @@ func (c *Client) getUPnPPortMapping( type uPnPDiscoResponse struct { Location string + // Server describes what version the UPnP is, such as MiniUPnPd/2.x.x + Server string + // USN is the serial number of the device, which also contains + // what kind of UPnP service is being offered, i.e. InternetGatewayDevice:2 + USN string } // parseUPnPDiscoResponse parses a UPnP HTTP-over-UDP discovery response. @@ -321,5 +326,7 @@ func parseUPnPDiscoResponse(body []byte) (uPnPDiscoResponse, error) { return r, err } r.Location = res.Header.Get("Location") + r.Server = res.Header.Get("Server") + r.USN = res.Header.Get("Usn") return r, nil } diff --git a/net/portmapper/upnp_test.go b/net/portmapper/upnp_test.go index 9bd25b192..347d00b6a 100644 --- a/net/portmapper/upnp_test.go +++ b/net/portmapper/upnp_test.go @@ -43,9 +43,13 @@ func TestParseUPnPDiscoResponse(t *testing.T) { }{ {"google", googleWifiUPnPDisco, uPnPDiscoResponse{ Location: "http://192.168.86.1:5000/rootDesc.xml", + Server: "Linux/5.4.0-1034-gcp UPnP/1.1 MiniUPnPd/1.9", + USN: "uuid:a9708184-a6c0-413a-bbac-11bcf7e30ece::urn:schemas-upnp-org:device:InternetGatewayDevice:2", }}, {"pfsense", pfSenseUPnPDisco, uPnPDiscoResponse{ Location: "http://192.168.1.1:2189/rootDesc.xml", + Server: "FreeBSD/12.2-STABLE UPnP/1.1 MiniUPnPd/2.2.1", + USN: "uuid:bee7052b-49e8-3597-b545-55a1e38ac11::urn:schemas-upnp-org:device:InternetGatewayDevice:1", }}, } for _, tt := range tests {