mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-05 14:57:49 +00:00
cmd/derper: add a STUN server
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
0e128f8f22
commit
00ad93ec25
@ -13,9 +13,11 @@
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/tailscale/wireguard-go/wgcfg"
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
@ -23,6 +25,7 @@
|
||||
"tailscale.com/derp"
|
||||
"tailscale.com/derp/derphttp"
|
||||
"tailscale.com/logpolicy"
|
||||
"tailscale.com/stun"
|
||||
"tailscale.com/tsweb"
|
||||
"tailscale.com/types/key"
|
||||
)
|
||||
@ -35,6 +38,7 @@
|
||||
hostname = flag.String("hostname", "derp.tailscale.com", "LetsEncrypt host name, if addr's port is :443")
|
||||
mbps = flag.Int("mbps", 5, "Mbps (mebibit/s) per-client rate limit; 0 means unlimited")
|
||||
logCollection = flag.String("logcollection", "", "If non-empty, logtail collection to log to")
|
||||
runSTUN = flag.Bool("stun", false, "also run a STUN server")
|
||||
)
|
||||
|
||||
type config struct {
|
||||
@ -135,6 +139,10 @@ func main() {
|
||||
}
|
||||
}))
|
||||
|
||||
if *runSTUN {
|
||||
go serveSTUN()
|
||||
}
|
||||
|
||||
httpsrv := &http.Server{
|
||||
Addr: *addr,
|
||||
Handler: mux,
|
||||
@ -190,3 +198,58 @@ func debugHandler(s *derp.Server) http.Handler {
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
func serveSTUN() {
|
||||
pc, err := net.ListenPacket("udp", ":3478")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open STUN listener: %v", err)
|
||||
}
|
||||
log.Printf("running STUN server on %v", pc.LocalAddr())
|
||||
var (
|
||||
stunReadErrors = expvar.NewInt("stun-read-error")
|
||||
stunWriteErrors = expvar.NewInt("stun-write-error")
|
||||
stunReadNotSTUN = expvar.NewInt("stun-read-not-stun")
|
||||
stunReadNotSTUNValid = expvar.NewInt("stun-read-not-stun-valid")
|
||||
stunReadIPv4 = expvar.NewInt("stun-read-ipv4")
|
||||
stunReadIPv6 = expvar.NewInt("stun-read-ipv6")
|
||||
stunWrite = expvar.NewInt("stun-write")
|
||||
)
|
||||
var buf [64 << 10]byte
|
||||
for {
|
||||
n, addr, err := pc.ReadFrom(buf[:])
|
||||
if err != nil {
|
||||
log.Printf("STUN ReadFrom: %v", err)
|
||||
time.Sleep(time.Second)
|
||||
stunReadErrors.Add(1)
|
||||
continue
|
||||
}
|
||||
ua, ok := addr.(*net.UDPAddr)
|
||||
if !ok {
|
||||
log.Printf("STUN unexpected address %T %v", addr, addr)
|
||||
stunReadErrors.Add(1)
|
||||
continue
|
||||
}
|
||||
pkt := buf[:n]
|
||||
if !stun.Is(pkt) {
|
||||
stunReadNotSTUN.Add(1)
|
||||
continue
|
||||
}
|
||||
txid, err := stun.ParseBindingRequest(pkt)
|
||||
if err != nil {
|
||||
stunReadNotSTUNValid.Add(1)
|
||||
continue
|
||||
}
|
||||
if ua.IP.To4() != nil {
|
||||
stunReadIPv4.Add(1)
|
||||
} else {
|
||||
stunReadIPv6.Add(1)
|
||||
}
|
||||
res := stun.Response(txid, ua.IP, uint16(ua.Port))
|
||||
_, err = pc.WriteTo(res, addr)
|
||||
if err != nil {
|
||||
stunWriteErrors.Add(1)
|
||||
} else {
|
||||
stunWrite.Add(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user