Skip to content

Commit 5c0f30c

Browse files
committed
add netcheck
1 parent 09d9249 commit 5c0f30c

File tree

4 files changed

+60
-15
lines changed

4 files changed

+60
-15
lines changed

tailnet/conn.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ func (c *Conn) AwaitReachable(ctx context.Context, ip netip.Addr) bool {
521521
case <-completedCtx.Done():
522522
// TODO(ethanndickson): For now, I'm interpreting 'connected' as when the
523523
// agent is reachable.
524-
_ = c.connectedTelemetryEvent()
524+
// _ = c.connectedTelemetryEvent()
525525
return true
526526
case <-t.C:
527527
// Pings can take a while, so we can run multiple
@@ -735,16 +735,16 @@ func (c *Conn) newTelemetryEvent() (*proto.TelemetryEvent, error) {
735735
return nil, xerrors.Errorf("marshal uuid to bytes: %w", err)
736736
}
737737

738-
logs, ips, dm, ni := c.telemeteryStore.getStore()
738+
logs, ips, dm, nc := c.telemeteryStore.getStore()
739739
return &proto.TelemetryEvent{
740740
Id: id,
741741
Time: timestamppb.Now(),
742742
ClientType: c.clientType,
743743
NodeIdSelf: uint64(c.nodeID),
744744
Logs: logs,
745745
LogIpHashes: ips,
746-
DerpMap: DERPMapToProto(dm),
747-
LatestNetcheck: NetInfoToProto(ni),
746+
DerpMap: dm,
747+
LatestNetcheck: nc,
748748

749749
// TODO:
750750
Application: "",

tailnet/convert.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ package tailnet
22

33
import (
44
"net/netip"
5+
"strconv"
6+
"strings"
7+
"time"
58

69
"github.com/google/uuid"
710
"golang.org/x/xerrors"
11+
"google.golang.org/protobuf/types/known/durationpb"
812
"google.golang.org/protobuf/types/known/timestamppb"
13+
"google.golang.org/protobuf/types/known/wrapperspb"
914
"tailscale.com/tailcfg"
1015
"tailscale.com/types/key"
1116

@@ -275,8 +280,49 @@ func NetInfoToProto(netInfo *tailcfg.NetInfo) *proto.Netcheck {
275280
if netInfo == nil {
276281
return nil
277282
}
283+
rlv4 := make(map[int64]*durationpb.Duration)
284+
rlv6 := make(map[int64]*durationpb.Duration)
285+
for k, seconds := range netInfo.DERPLatency {
286+
res := strings.Split(k, "-")
287+
if len(res) != 2 {
288+
continue
289+
}
278290

291+
rid, err := strconv.ParseInt(res[0], 10, 64)
292+
if err != nil {
293+
continue
294+
}
295+
296+
dur := time.Duration(seconds * float64(time.Second))
297+
298+
switch res[1] {
299+
case "v4":
300+
rlv4[rid] = durationpb.New(dur)
301+
case "v6":
302+
rlv6[rid] = durationpb.New(dur)
303+
}
304+
}
279305
return &proto.Netcheck{
280-
// TODO:
306+
UDP: netInfo.WorkingUDP.EqualBool(true),
307+
IPv6CanSend: netInfo.WorkingIPv6.EqualBool(true),
308+
OSHasIPv6: netInfo.OSHasIPv6.EqualBool(true),
309+
ICMPv4: netInfo.WorkingICMPv4.EqualBool(true),
310+
MappingVariesByDestIP: wrapperspb.Bool(netInfo.MappingVariesByDestIP.EqualBool(true)),
311+
HairPinning: wrapperspb.Bool(netInfo.HairPinning.EqualBool(true)),
312+
UPnP: wrapperspb.Bool(netInfo.UPnP.EqualBool(true)),
313+
PMP: wrapperspb.Bool(netInfo.PMP.EqualBool(true)),
314+
PCP: wrapperspb.Bool(netInfo.PCP.EqualBool(true)),
315+
PreferredDERP: int64(netInfo.PreferredDERP),
316+
RegionV4Latency: rlv4,
317+
RegionV6Latency: rlv6,
318+
// TODO: what's the most useful value to have here?
319+
RegionLatency: make(map[int64]*durationpb.Duration),
320+
// TODO: None of these are exposed by tailscale
321+
IPv4CanSend: false,
322+
IPv4: false,
323+
IPv6: false,
324+
GlobalV4: &proto.Netcheck_NetcheckIP{},
325+
GlobalV6: &proto.Netcheck_NetcheckIP{},
326+
CaptivePortal: &wrapperspb.BoolValue{},
281327
}
282328
}

tailnet/logger_internal_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,12 @@ func TestTelemetryStore(t *testing.T) {
185185
require.Len(t, dm.Regions[999].Nodes, 1)
186186
node := dm.Regions[999].Nodes[0]
187187
require.NotContains(t, node.HostName, "coolderp.com")
188-
require.NotContains(t, node.IPv4, "1.2.3.4")
189-
require.NotContains(t, node.IPv6, "2001:db8::1")
190-
require.NotContains(t, node.STUNTestIP, "5.6.7.8")
188+
require.NotContains(t, node.Ipv4, "1.2.3.4")
189+
require.NotContains(t, node.Ipv6, "2001:db8::1")
190+
require.NotContains(t, node.StunTestIp, "5.6.7.8")
191191
require.Contains(t, logs[0], node.HostName)
192-
require.Contains(t, ips, node.STUNTestIP)
193-
require.Contains(t, ips, node.IPv6)
194-
require.Contains(t, ips, node.IPv4)
192+
require.Contains(t, ips, node.StunTestIp)
193+
require.Contains(t, ips, node.Ipv6)
194+
require.Contains(t, ips, node.Ipv4)
195195
})
196196
}

tailnet/telemetry.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ func newTelemetryStore() (*TelemetryStore, error) {
126126

127127
// getStore returns a deep copy of all current telemetry state.
128128
// TODO: Should this return a populated event instead?
129-
func (b *TelemetryStore) getStore() ([]string, map[string]*proto.IPFields, *tailcfg.DERPMap, *tailcfg.NetInfo) {
129+
func (b *TelemetryStore) getStore() ([]string, map[string]*proto.IPFields, *proto.DERPMap, *proto.Netcheck) {
130130
b.mu.Lock()
131131
defer b.mu.Unlock()
132-
return append([]string{}, b.logs...), b.hashedIPs, b.cleanDerpMap.Clone(), b.netInfo.Clone()
132+
return append([]string{}, b.logs...), b.hashedIPs, DERPMapToProto(b.cleanDerpMap), NetInfoToProto(b.netInfo)
133133
}
134134

135135
// Given a DERPMap, anonymise all IPs and hostnames.
@@ -167,8 +167,7 @@ func (b *TelemetryStore) updateDerpMap(cur *tailcfg.DERPMap) {
167167
func (b *TelemetryStore) setNetInfo(ni *tailcfg.NetInfo) {
168168
b.mu.Lock()
169169
defer b.mu.Unlock()
170-
// TODO: Scrub PII from NetInfo
171-
b.netInfo = ni
170+
b.netInfo = ni.Clone()
172171
}
173172

174173
// Write implements io.Writer.

0 commit comments

Comments
 (0)