mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-21 12:28:39 +00:00
net/stunserver: reply from the address at which STUN was received
Updates #15014 Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
parent
7aef4fd44d
commit
ea5f78ceca
@ -15,6 +15,8 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/ipv4"
|
||||||
|
"golang.org/x/net/ipv6"
|
||||||
"tailscale.com/metrics"
|
"tailscale.com/metrics"
|
||||||
"tailscale.com/net/stun"
|
"tailscale.com/net/stun"
|
||||||
)
|
)
|
||||||
@ -70,13 +72,17 @@ func (s *STUNServer) Listen(listenAddr string) error {
|
|||||||
// Serve starts serving responses to STUN requests. Listen must be called before Serve.
|
// Serve starts serving responses to STUN requests. Listen must be called before Serve.
|
||||||
func (s *STUNServer) Serve() error {
|
func (s *STUNServer) Serve() error {
|
||||||
var buf [64 << 10]byte
|
var buf [64 << 10]byte
|
||||||
|
var oob [4096]byte
|
||||||
var (
|
var (
|
||||||
n int
|
n, oobn int
|
||||||
ua *net.UDPAddr
|
remote netip.AddrPort
|
||||||
err error
|
local net.IP
|
||||||
|
err error
|
||||||
|
cm4 ipv4.ControlMessage
|
||||||
|
cm6 ipv6.ControlMessage
|
||||||
)
|
)
|
||||||
for {
|
for {
|
||||||
n, ua, err = s.pc.ReadFromUDP(buf[:])
|
n, oobn, _, remote, err = s.pc.ReadMsgUDPAddrPort(buf[:], oob[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, io.EOF) || errors.Is(err, net.ErrClosed) {
|
if errors.Is(err, io.EOF) || errors.Is(err, net.ErrClosed) {
|
||||||
return nil
|
return nil
|
||||||
@ -86,6 +92,22 @@ func (s *STUNServer) Serve() error {
|
|||||||
stunReadError.Add(1)
|
stunReadError.Add(1)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if remote.Addr().Is4() {
|
||||||
|
err = cm4.Parse(oob[:oobn])
|
||||||
|
} else {
|
||||||
|
err = cm6.Parse(oob[:oobn])
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("parse control msg error: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if remote.Addr().Is4() {
|
||||||
|
local = cm4.Dst
|
||||||
|
} else {
|
||||||
|
local = cm6.Dst
|
||||||
|
}
|
||||||
|
|
||||||
pkt := buf[:n]
|
pkt := buf[:n]
|
||||||
if !stun.Is(pkt) {
|
if !stun.Is(pkt) {
|
||||||
stunNotSTUN.Add(1)
|
stunNotSTUN.Add(1)
|
||||||
@ -96,14 +118,27 @@ func (s *STUNServer) Serve() error {
|
|||||||
stunNotSTUN.Add(1)
|
stunNotSTUN.Add(1)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if ua.IP.To4() != nil {
|
if remote.Addr().Is4() {
|
||||||
stunIPv4.Add(1)
|
stunIPv4.Add(1)
|
||||||
} else {
|
} else {
|
||||||
stunIPv6.Add(1)
|
stunIPv6.Add(1)
|
||||||
}
|
}
|
||||||
addr, _ := netip.AddrFromSlice(ua.IP)
|
res := stun.Response(txid, remote)
|
||||||
res := stun.Response(txid, netip.AddrPortFrom(addr, uint16(ua.Port)))
|
|
||||||
_, err = s.pc.WriteTo(res, ua)
|
// TODO(raggi): send upstream patch to provide a way to serialize a
|
||||||
|
// control message into an existng buffer.
|
||||||
|
if remote.Addr().Is4() {
|
||||||
|
cm4 = ipv4.ControlMessage{
|
||||||
|
Src: local,
|
||||||
|
}
|
||||||
|
oobn = copy(oob[:], cm4.Marshal())
|
||||||
|
} else {
|
||||||
|
cm6 = ipv6.ControlMessage{
|
||||||
|
Src: local,
|
||||||
|
}
|
||||||
|
oobn = copy(oob[:], cm6.Marshal())
|
||||||
|
}
|
||||||
|
_, _, err = s.pc.WriteMsgUDPAddrPort(res, oob[:oobn], remote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stunWriteError.Add(1)
|
stunWriteError.Add(1)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user