ipn: allow FQDN in exit node selection

To match the format of exit node suggestions and ensure that the result
is not ambiguous, relax exit node CLI selection to permit using a FQDN
including the trailing dot.

Updates #12618

Change-Id: I04b9b36d2743154aa42f2789149b2733f8555d3f
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
pull/12843/head
Adrian Dewhurst 4 months ago committed by Adrian Dewhurst
parent fec41e4904
commit 0834712c91

@ -156,8 +156,7 @@ func runExitNodeSuggest(ctx context.Context, args []string) error {
fmt.Println("No exit node suggestion is available.") fmt.Println("No exit node suggestion is available.")
return nil return nil
} }
hostname := strings.TrimSuffix(res.Name, ".") fmt.Printf("Suggested exit node: %v\nTo accept this suggestion, use `tailscale set --exit-node=%v`.\n", res.Name, shellquote.Join(res.Name))
fmt.Printf("Suggested exit node: %v\nTo accept this suggestion, use `tailscale set --exit-node=%v`.\n", hostname, shellquote.Join(hostname))
return nil return nil
} }

@ -810,7 +810,7 @@ func exitNodeIPOfArg(s string, st *ipnstate.Status) (ip netip.Addr, err error) {
match := 0 match := 0
for _, ps := range st.Peer { for _, ps := range st.Peer {
baseName := dnsname.TrimSuffix(ps.DNSName, st.MagicDNSSuffix) baseName := dnsname.TrimSuffix(ps.DNSName, st.MagicDNSSuffix)
if !strings.EqualFold(s, baseName) { if !strings.EqualFold(s, baseName) && !strings.EqualFold(s, ps.DNSName) {
continue continue
} }
match++ match++

@ -914,6 +914,21 @@ func TestExitNodeIPOfArg(t *testing.T) {
}, },
want: mustIP("1.0.0.2"), want: mustIP("1.0.0.2"),
}, },
{
name: "name_fqdn",
arg: "skippy.foo.",
st: &ipnstate.Status{
MagicDNSSuffix: ".foo",
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
key.NewNode().Public(): {
DNSName: "skippy.foo.",
TailscaleIPs: []netip.Addr{mustIP("1.0.0.2")},
ExitNodeOption: true,
},
},
},
want: mustIP("1.0.0.2"),
},
{ {
name: "name_not_exit", name: "name_not_exit",
arg: "skippy", arg: "skippy",
@ -928,6 +943,20 @@ func TestExitNodeIPOfArg(t *testing.T) {
}, },
wantErr: `node "skippy" is not advertising an exit node`, wantErr: `node "skippy" is not advertising an exit node`,
}, },
{
name: "name_wrong_fqdn",
arg: "skippy.bar.",
st: &ipnstate.Status{
MagicDNSSuffix: ".foo",
Peer: map[key.NodePublic]*ipnstate.PeerStatus{
key.NewNode().Public(): {
DNSName: "skippy.foo.",
TailscaleIPs: []netip.Addr{mustIP("1.0.0.2")},
},
},
},
wantErr: `invalid value "skippy.bar." for --exit-node; must be IP or unique node name`,
},
{ {
name: "ambiguous", name: "ambiguous",
arg: "skippy", arg: "skippy",

Loading…
Cancel
Save