mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-03 02:21:58 +00:00
cmd/{derper,stund},net/stunserver: add standalone stun server
Add a standalone server for STUN that can be hosted independently of the derper, and factor that back into the derper. Fixes #8434 Closes #8435 Closes #10745 Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
committed by
James Tucker
parent
569b91417f
commit
953fa80c6f
88
net/stunserver/stunserver_test.go
Normal file
88
net/stunserver/stunserver_test.go
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package stunserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"tailscale.com/net/stun"
|
||||
"tailscale.com/util/must"
|
||||
)
|
||||
|
||||
func TestSTUNServer(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
s := New(ctx)
|
||||
must.Do(s.Listen("localhost:0"))
|
||||
var w sync.WaitGroup
|
||||
w.Add(1)
|
||||
var serveErr error
|
||||
go func() {
|
||||
defer w.Done()
|
||||
serveErr = s.Serve()
|
||||
}()
|
||||
|
||||
c := must.Get(net.DialUDP("udp", nil, s.LocalAddr().(*net.UDPAddr)))
|
||||
defer c.Close()
|
||||
c.SetDeadline(time.Now().Add(5 * time.Second))
|
||||
txid := stun.NewTxID()
|
||||
_, err := c.Write(stun.Request(txid))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to write STUN request: %v", err)
|
||||
}
|
||||
var buf [64 << 10]byte
|
||||
n, err := c.Read(buf[:])
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read STUN response: %v", err)
|
||||
}
|
||||
if !stun.Is(buf[:n]) {
|
||||
t.Fatalf("response is not STUN")
|
||||
}
|
||||
tid, _, err := stun.ParseResponse(buf[:n])
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse STUN response: %v", err)
|
||||
}
|
||||
if tid != txid {
|
||||
t.Fatalf("STUN response has wrong transaction ID; got %d, want %d", tid, txid)
|
||||
}
|
||||
|
||||
cancel()
|
||||
w.Wait()
|
||||
if serveErr != nil {
|
||||
t.Fatalf("failed to listen and serve: %v", serveErr)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkServerSTUN(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
s := New(ctx)
|
||||
s.Listen("localhost:0")
|
||||
go s.Serve()
|
||||
addr := s.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user