net/portmapper: add clientmetrics for PCP/PMP responses

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
pull/3455/head
Josh Bleecher Snyder 3 years ago committed by Josh Bleecher Snyder
parent 999814e9e1
commit 38d90fa330

@ -72,7 +72,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
tailscale.com/types/persist from tailscale.com/ipn tailscale.com/types/persist from tailscale.com/ipn
tailscale.com/types/preftype from tailscale.com/cmd/tailscale/cli+ tailscale.com/types/preftype from tailscale.com/cmd/tailscale/cli+
tailscale.com/types/structs from tailscale.com/ipn+ tailscale.com/types/structs from tailscale.com/ipn+
tailscale.com/util/clientmetric from tailscale.com/net/netcheck tailscale.com/util/clientmetric from tailscale.com/net/netcheck+
tailscale.com/util/dnsname from tailscale.com/cmd/tailscale/cli+ tailscale.com/util/dnsname from tailscale.com/cmd/tailscale/cli+
W tailscale.com/util/endian from tailscale.com/net/netns W tailscale.com/util/endian from tailscale.com/net/netns
tailscale.com/util/groupmember from tailscale.com/cmd/tailscale/cli tailscale.com/util/groupmember from tailscale.com/cmd/tailscale/cli

@ -22,6 +22,7 @@ import (
"tailscale.com/net/interfaces" "tailscale.com/net/interfaces"
"tailscale.com/net/netns" "tailscale.com/net/netns"
"tailscale.com/types/logger" "tailscale.com/types/logger"
"tailscale.com/util/clientmetric"
) )
// Debug knobs for "tailscaled debug --portmap". // Debug knobs for "tailscaled debug --portmap".
@ -785,29 +786,35 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
case pcpCodeOK: case pcpCodeOK:
c.logf("[v1] Got PCP response: epoch: %v", pres.Epoch) c.logf("[v1] Got PCP response: epoch: %v", pres.Epoch)
res.PCP = true res.PCP = true
metricPCPOK.Add(1)
continue continue
case pcpCodeNotAuthorized: case pcpCodeNotAuthorized:
// A PCP service is running, but refuses to // A PCP service is running, but refuses to
// provide port mapping services. // provide port mapping services.
res.PCP = false res.PCP = false
metricPCPNotAuthorized.Add(1)
continue continue
case pcpCodeAddressMismatch: case pcpCodeAddressMismatch:
// A PCP service is running, but it is behind a NAT, so it can't help us. // A PCP service is running, but it is behind a NAT, so it can't help us.
res.PCP = false res.PCP = false
metricPCPAddressMismatch.Add(1)
continue continue
default: default:
// Fall through to unexpected log line. // Fall through to unexpected log line.
} }
} }
metricPCPUnhandledResponseCode.Add(1)
c.logf("unexpected PCP probe response: %+v", pres) c.logf("unexpected PCP probe response: %+v", pres)
} }
if pres, ok := parsePMPResponse(buf[:n]); ok { if pres, ok := parsePMPResponse(buf[:n]); ok {
if pres.OpCode != pmpOpReply|pmpOpMapPublicAddr { if pres.OpCode != pmpOpReply|pmpOpMapPublicAddr {
c.logf("unexpected PMP probe response opcode: %+v", pres) c.logf("unexpected PMP probe response opcode: %+v", pres)
metricPMPUnhandledOpcode.Add(1)
continue continue
} }
switch pres.ResultCode { switch pres.ResultCode {
case pmpCodeOK: case pmpCodeOK:
metricPMPOK.Add(1)
c.logf("[v1] Got PMP response; IP: %v, epoch: %v", pres.PublicAddr, pres.SecondsSinceEpoch) c.logf("[v1] Got PMP response; IP: %v, epoch: %v", pres.PublicAddr, pres.SecondsSinceEpoch)
res.PMP = true res.PMP = true
c.mu.Lock() c.mu.Lock()
@ -816,11 +823,20 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
c.pmpLastEpoch = pres.SecondsSinceEpoch c.pmpLastEpoch = pres.SecondsSinceEpoch
c.mu.Unlock() c.mu.Unlock()
continue continue
case pmpCodeNotAuthorized, pmpCodeNetworkFailure, pmpCodeOutOfResources: case pmpCodeNotAuthorized:
// Normal failures. metricPMPNotAuthorized.Add(1)
c.logf("PMP probe failed due result code: %+v", pres)
continue
case pmpCodeNetworkFailure:
metricPMPNetworkFailure.Add(1)
c.logf("PMP probe failed due result code: %+v", pres)
continue
case pmpCodeOutOfResources:
metricPMPOutOfResources.Add(1)
c.logf("PMP probe failed due result code: %+v", pres) c.logf("PMP probe failed due result code: %+v", pres)
continue continue
} }
metricPMPUnhandledResponseCode.Add(1)
c.logf("unexpected PMP probe response: %+v", pres) c.logf("unexpected PMP probe response: %+v", pres)
} }
} }
@ -839,3 +855,45 @@ var uPnPPacket = []byte("M-SEARCH * HTTP/1.1\r\n" +
"ST: ssdp:all\r\n" + "ST: ssdp:all\r\n" +
"MAN: \"ssdp:discover\"\r\n" + "MAN: \"ssdp:discover\"\r\n" +
"MX: 2\r\n\r\n") "MX: 2\r\n\r\n")
var (
// metricPCPOK counts the number of times
// we received a successful PCP response.
metricPCPOK = clientmetric.NewCounter("portmap_pcp_ok")
// metricPCPAddressMismatch counts the number of times
// we received a PCP address mismatch result code.
metricPCPAddressMismatch = clientmetric.NewCounter("portmap_pcp_address_mismatch")
// metricPCPNotAuthorized counts the number of times
// we received a PCP not authorized result code.
metricPCPNotAuthorized = clientmetric.NewCounter("portmap_pcp_not_authorized")
// metricPCPUnhandledResponseCode counts the number of times
// we received an (as yet) unhandled PCP result code.
metricPCPUnhandledResponseCode = clientmetric.NewCounter("portmap_pcp_unhandled_response_code")
// metricPMPOK counts the number of times
// we received a succesful PMP response.
metricPMPOK = clientmetric.NewCounter("portmap_pmp_ok")
// metricPMPUnhandledOpcode counts the number of times
// we received an unhandled PMP opcode.
metricPMPUnhandledOpcode = clientmetric.NewCounter("portmap_pmp_unhandled_opcode")
// metricPMPUnhandledResponseCode counts the number of times
// we received an unhandled PMP result code.
metricPMPUnhandledResponseCode = clientmetric.NewCounter("portmap_pmp_unhandled_response_code")
// metricPMPOutOfResources counts the number of times
// we received a PCP out of resources result code.
metricPMPOutOfResources = clientmetric.NewCounter("portmap_pmp_out_of_resources")
// metricPMPNetworkFailure counts the number of times
// we received a PCP network failure result code.
metricPMPNetworkFailure = clientmetric.NewCounter("portmap_pmp_network_failure")
// metricPMPNotAuthorized counts the number of times
// we received a PCP not authorized result code.
metricPMPNotAuthorized = clientmetric.NewCounter("portmap_pmp_not_authorized")
)

Loading…
Cancel
Save