tailscale/cmd/derper/derper_test.go
Andrew Dunham e85613aa2d net/netcheck: don't use a space in the captive portal challenge
The derpers don't allow whitespace in the challenge.

Change-Id: I93a8b073b846b87854fba127b5c1d80db205f658
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
2022-11-08 16:58:54 -05:00

132 lines
2.8 KiB
Go

// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"context"
"net"
"net/http"
"net/http/httptest"
"strings"
"testing"
"tailscale.com/net/stun"
)
func TestProdAutocertHostPolicy(t *testing.T) {
tests := []struct {
in string
wantOK bool
}{
{"derp.tailscale.com", true},
{"derp.tailscale.com.", true},
{"derp1.tailscale.com", true},
{"derp1b.tailscale.com", true},
{"derp2.tailscale.com", true},
{"derp02.tailscale.com", true},
{"derp-nyc.tailscale.com", true},
{"derpfoo.tailscale.com", true},
{"derp02.bar.tailscale.com", false},
{"example.net", false},
}
for _, tt := range tests {
got := prodAutocertHostPolicy(context.Background(), tt.in) == nil
if got != tt.wantOK {
t.Errorf("f(%q) = %v; want %v", tt.in, got, tt.wantOK)
}
}
}
func BenchmarkServerSTUN(b *testing.B) {
b.ReportAllocs()
pc, err := net.ListenPacket("udp", "127.0.0.1:0")
if err != nil {
b.Fatal(err)
}
defer pc.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go serverSTUNListener(ctx, pc.(*net.UDPConn))
addr := pc.LocalAddr().(*net.UDPAddr)
var resBuf [1500]byte
cc, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1")})
if err != nil {
b.Fatal(err)
}
tx := stun.NewTxID()
req := stun.Request(tx)
for i := 0; i < b.N; i++ {
if _, err := cc.WriteToUDP(req, addr); err != nil {
b.Fatal(err)
}
_, _, err := cc.ReadFromUDP(resBuf[:])
if err != nil {
b.Fatal(err)
}
}
}
func TestNoContent(t *testing.T) {
testCases := []struct {
name string
input string
want string
}{
{
name: "no challenge",
},
{
name: "valid challenge",
input: "input",
want: "response input",
},
{
name: "valid challenge hostname",
input: "ts_derp99b.tailscale.com",
want: "response ts_derp99b.tailscale.com",
},
{
name: "invalid challenge",
input: "foo\x00bar",
want: "",
},
{
name: "whitespace invalid challenge",
input: "foo bar",
want: "",
},
{
name: "long challenge",
input: strings.Repeat("x", 65),
want: "",
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
req, _ := http.NewRequest("GET", "https://localhost/generate_204", nil)
if tt.input != "" {
req.Header.Set(noContentChallengeHeader, tt.input)
}
w := httptest.NewRecorder()
serveNoContent(w, req)
resp := w.Result()
if tt.want == "" {
if h, found := resp.Header[noContentResponseHeader]; found {
t.Errorf("got %+v; expected no response header", h)
}
return
}
if got := resp.Header.Get(noContentResponseHeader); got != tt.want {
t.Errorf("got %q; want %q", got, tt.want)
}
})
}
}