Просмотр исходного кода

cli/netcheck: fail with output if we time out fetching a derpmap (#12528)

Updates tailscale/corp#20969

Right now, when netcheck starts, it asks tailscaled for a copy of the DERPMap. If it doesn't have one, it makes a HTTPS request to controlplane.tailscale.com to fetch one.

This will always fail if you're on a network with a captive portal actively blocking HTTPS traffic. The code appears to hang entirely because the http.Client doesn't have a Timeout set. It just sits there waiting until the request succeeds or fails.

This adds a timeout of 10 seconds, and logs more details about the status of the HTTPS request.

Signed-off-by: Andrea Gottardo <[email protected]>
Andrea Gottardo 1 год назад
Родитель
Сommit
8eb15d3d2d
1 измененных файлов с 6 добавлено и 1 удалено
  1. 6 1
      cmd/tailscale/cli/netcheck.go

+ 6 - 1
cmd/tailscale/cli/netcheck.go

@@ -78,9 +78,13 @@ func runNetcheck(ctx context.Context, args []string) error {
 		log.Printf("No DERP map from tailscaled; using default.")
 	}
 	if err != nil || noRegions {
-		hc := &http.Client{Transport: tlsdial.NewTransport()}
+		hc := &http.Client{
+			Transport: tlsdial.NewTransport(),
+			Timeout:   10 * time.Second,
+		}
 		dm, err = prodDERPMap(ctx, hc)
 		if err != nil {
+			log.Println("Failed to fetch a DERP map, so netcheck cannot continue. Check your Internet connection.")
 			return err
 		}
 	}
@@ -209,6 +213,7 @@ func portMapping(r *netcheck.Report) string {
 }
 
 func prodDERPMap(ctx context.Context, httpc *http.Client) (*tailcfg.DERPMap, error) {
+	log.Printf("attempting to fetch a DERPMap from %s", ipn.DefaultControlURL)
 	req, err := http.NewRequestWithContext(ctx, "GET", ipn.DefaultControlURL+"/derpmap/default", nil)
 	if err != nil {
 		return nil, fmt.Errorf("create prodDERPMap request: %w", err)