package stun
import (
"errors"
"fmt"
"net"
"time"
"github.com/pion/stun/v3"
)
var (
errGetXorMappedAddrResponse = errors .New ("failed to get XOR-MAPPED-ADDRESS response" )
errMismatchUsername = errors .New ("username mismatch" )
)
func GetXORMappedAddr (conn net .PacketConn , serverAddr net .Addr , timeout time .Duration ) (*stun .XORMappedAddress , error ) {
if timeout > 0 {
if err := conn .SetReadDeadline (time .Now ().Add (timeout )); err != nil {
return nil , err
}
defer conn .SetReadDeadline (time .Time {})
}
req , err := stun .Build (stun .BindingRequest , stun .TransactionID )
if err != nil {
return nil , err
}
if _, err = conn .WriteTo (req .Raw , serverAddr ); err != nil {
return nil , err
}
const maxMessageSize = 1280
buf := make ([]byte , maxMessageSize )
n , _ , err := conn .ReadFrom (buf )
if err != nil {
return nil , err
}
res := &stun .Message {Raw : buf [:n ]}
if err = res .Decode (); err != nil {
return nil , err
}
var addr stun .XORMappedAddress
if err = addr .GetFrom (res ); err != nil {
return nil , fmt .Errorf ("%w: %v" , errGetXorMappedAddrResponse , err )
}
return &addr , nil
}
func AssertUsername (m *stun .Message , expectedUsername string ) error {
var username stun .Username
if err := username .GetFrom (m ); err != nil {
return err
} else if string (username ) != expectedUsername {
return fmt .Errorf ("%w expected(%x) actual(%x)" , errMismatchUsername , expectedUsername , string (username ))
}
return nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .