net/portmapper: add UPnP client metrics

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This commit is contained in:
Josh Bleecher Snyder 2021-11-30 11:41:43 -08:00 committed by Josh Bleecher Snyder
parent 40f11c50a1
commit 9787ec6f4a

View File

@ -737,6 +737,7 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
// See https://github.com/tailscale/tailscale/issues/3197 for // See https://github.com/tailscale/tailscale/issues/3197 for
// an example of a device that strictly implements UPnP, and // an example of a device that strictly implements UPnP, and
// only responds to multicast queries. // only responds to multicast queries.
metricUPnPSent.Add(1)
uc.WriteTo(uPnPPacket, upnpAddr) uc.WriteTo(uPnPPacket, upnpAddr)
uc.WriteTo(uPnPPacket, upnpMulticastAddr) uc.WriteTo(uPnPPacket, upnpMulticastAddr)
} }
@ -762,11 +763,14 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
port := uint16(addr.(*net.UDPAddr).Port) port := uint16(addr.(*net.UDPAddr).Port)
switch port { switch port {
case c.upnpPort(): case c.upnpPort():
metricUPnPResponse.Add(1)
if ip == gw && mem.Contains(mem.B(buf[:n]), mem.S(":InternetGatewayDevice:")) { if ip == gw && mem.Contains(mem.B(buf[:n]), mem.S(":InternetGatewayDevice:")) {
meta, err := parseUPnPDiscoResponse(buf[:n]) meta, err := parseUPnPDiscoResponse(buf[:n])
if err != nil { if err != nil {
metricUPnPParseErr.Add(1)
c.logf("unrecognized UPnP discovery response; ignoring") c.logf("unrecognized UPnP discovery response; ignoring")
} }
metricUPnPOK.Add(1)
c.logf("[v1] UPnP reply %+v, %q", meta, buf[:n]) c.logf("[v1] UPnP reply %+v, %q", meta, buf[:n])
res.UPnP = true res.UPnP = true
c.mu.Lock() c.mu.Lock()
@ -774,6 +778,7 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
if c.uPnPMeta != meta { if c.uPnPMeta != meta {
c.logf("UPnP meta changed: %+v", meta) c.logf("UPnP meta changed: %+v", meta)
c.uPnPMeta = meta c.uPnPMeta = meta
metricUPnPUpdatedMeta.Add(1)
} }
c.mu.Unlock() c.mu.Unlock()
} }
@ -858,6 +863,7 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
"MAN: \"ssdp:discover\"\r\n" + "MAN: \"ssdp:discover\"\r\n" +
"MX: 2\r\n\r\n") "MX: 2\r\n\r\n")
// PCP/PMP metrics
var ( var (
// metricPCPOK counts the number of times // metricPCPOK counts the number of times
// we received a successful PCP response. // we received a successful PCP response.
@ -899,3 +905,22 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
// we received a PCP not authorized result code. // we received a PCP not authorized result code.
metricPMPNotAuthorized = clientmetric.NewCounter("portmap_pmp_not_authorized") metricPMPNotAuthorized = clientmetric.NewCounter("portmap_pmp_not_authorized")
) )
// UPnP metrics
var (
// metricUPnPSent counts the number of times we sent a UPnP request.
metricUPnPSent = clientmetric.NewCounter("portmap_upnp_sent")
// metricUPnPResponse counts the number of times we received a UPnP response.
metricUPnPResponse = clientmetric.NewCounter("portmap_upnp_response")
// metricUPnPParseErr counts the number of times we failed to parse a UPnP response.
metricUPnPParseErr = clientmetric.NewCounter("portmap_upnp_parse_err")
// metricUPnPOK counts the number of times we received a usable UPnP response.
metricUPnPOK = clientmetric.NewCounter("portmap_upnp_ok")
// metricUPnPUpdatedMeta counts the number of times
// we received a UPnP response with a new meta.
metricUPnPUpdatedMeta = clientmetric.NewCounter("portmap_upnp_updated_meta")
)