(ctx context.Context, args []string)
| 67 | } |
| 68 | |
| 69 | func runNetcheck(ctx context.Context, args []string) error { |
| 70 | logf := logger.WithPrefix(log.Printf, "portmap: ") |
| 71 | bus := eventbus.New() |
| 72 | defer bus.Close() |
| 73 | netMon, err := netmon.New(bus, logf) |
| 74 | if err != nil { |
| 75 | return err |
| 76 | } |
| 77 | |
| 78 | var pm portmappertype.Client |
| 79 | if buildfeatures.HasPortMapper { |
| 80 | // Ensure that we close the portmapper after running a netcheck; this |
| 81 | // will release any port mappings created. |
| 82 | pm = portmappertype.HookNewPortMapper.Get()(logf, bus, netMon, nil, nil) |
| 83 | defer pm.Close() |
| 84 | } |
| 85 | |
| 86 | flagsProvided := set.Set[string]{} |
| 87 | netcheckFlagSet.Visit(func(f *flag.Flag) { |
| 88 | flagsProvided.Add(f.Name) |
| 89 | }) |
| 90 | |
| 91 | c := &netcheck.Client{ |
| 92 | NetMon: netMon, |
| 93 | PortMapper: pm, |
| 94 | UseDNSCache: false, // always resolve, don't cache |
| 95 | } |
| 96 | if netcheckArgs.verbose { |
| 97 | c.Logf = logger.WithPrefix(log.Printf, "netcheck: ") |
| 98 | c.Verbose = true |
| 99 | } else { |
| 100 | c.Logf = logger.Discard |
| 101 | } |
| 102 | |
| 103 | if strings.HasPrefix(netcheckArgs.format, "json") { |
| 104 | fmt.Fprintln(Stderr, "# Warning: this JSON format is not yet considered a stable interface") |
| 105 | } |
| 106 | |
| 107 | bind, err := createNetcheckBindString( |
| 108 | netcheckArgs.bindAddress, |
| 109 | flagsProvided.Contains("bind-address"), |
| 110 | netcheckArgs.bindPort, |
| 111 | flagsProvided.Contains("bind-port"), |
| 112 | envknob.String("TS_DEBUG_NETCHECK_UDP_BIND")) |
| 113 | if err != nil { |
| 114 | return err |
| 115 | } |
| 116 | |
| 117 | if err := c.Standalone(ctx, bind); err != nil { |
| 118 | fmt.Fprintln(Stderr, "netcheck: UDP test failure:", err) |
| 119 | } |
| 120 | |
| 121 | dm, err := localClient.CurrentDERPMap(ctx) |
| 122 | noRegions := dm != nil && len(dm.Regions) == 0 |
| 123 | if noRegions { |
| 124 | log.Printf("No DERP map from tailscaled; using default.") |
| 125 | } |
| 126 | if err != nil || noRegions { |
nothing calls this directly
no test coverage detected
searching dependent graphs…