package stun
import (
"fmt"
"io"
"net"
"strconv"
)
type MappedAddress struct {
IP net .IP
Port int
}
type AlternateServer struct {
IP net .IP
Port int
}
type ResponseOrigin struct {
IP net .IP
Port int
}
type OtherAddress struct {
IP net .IP
Port int
}
func (s *AlternateServer ) AddTo (m *Message ) error {
a := (*MappedAddress )(s )
return a .AddToAs (m , AttrAlternateServer )
}
func (s *AlternateServer ) GetFrom (m *Message ) error {
a := (*MappedAddress )(s )
return a .GetFromAs (m , AttrAlternateServer )
}
func (a MappedAddress ) String () string {
return net .JoinHostPort (a .IP .String (), strconv .Itoa (a .Port ))
}
func (a *MappedAddress ) GetFromAs (m *Message , t AttrType ) error {
v , err := m .Get (t )
if err != nil {
return err
}
if len (v ) <= 4 {
return io .ErrUnexpectedEOF
}
family := bin .Uint16 (v [0 :2 ])
if family != familyIPv6 && family != familyIPv4 {
return newDecodeErr ("xor-mapped address" , "family" ,
fmt .Sprintf ("bad value %d" , family ),
)
}
ipLen := net .IPv4len
if family == familyIPv6 {
ipLen = net .IPv6len
}
if len (a .IP ) < ipLen {
a .IP = a .IP [:cap (a .IP )]
for len (a .IP ) < ipLen {
a .IP = append (a .IP , 0 )
}
}
a .IP = a .IP [:ipLen ]
for i := range a .IP {
a .IP [i ] = 0
}
a .Port = int (bin .Uint16 (v [2 :4 ]))
copy (a .IP , v [4 :])
return nil
}
func (a *MappedAddress ) AddToAs (m *Message , t AttrType ) error {
var (
family = familyIPv4
ip = a .IP
)
if len (a .IP ) == net .IPv6len {
if isIPv4 (ip ) {
ip = ip [12 :16 ]
} else {
family = familyIPv6
}
} else if len (ip ) != net .IPv4len {
return ErrBadIPLength
}
value := make ([]byte , 128 )
value [0 ] = 0
bin .PutUint16 (value [0 :2 ], family )
bin .PutUint16 (value [2 :4 ], uint16 (a .Port ))
copy (value [4 :], ip )
m .Add (t , value [:4 +len (ip )])
return nil
}
func (a *MappedAddress ) AddTo (m *Message ) error {
return a .AddToAs (m , AttrMappedAddress )
}
func (a *MappedAddress ) GetFrom (m *Message ) error {
return a .GetFromAs (m , AttrMappedAddress )
}
func (o *OtherAddress ) AddTo (m *Message ) error {
a := (*MappedAddress )(o )
return a .AddToAs (m , AttrOtherAddress )
}
func (o *OtherAddress ) GetFrom (m *Message ) error {
a := (*MappedAddress )(o )
return a .GetFromAs (m , AttrOtherAddress )
}
func (o OtherAddress ) String () string {
return net .JoinHostPort (o .IP .String (), strconv .Itoa (o .Port ))
}
func (o *ResponseOrigin ) AddTo (m *Message ) error {
a := (*MappedAddress )(o )
return a .AddToAs (m , AttrResponseOrigin )
}
func (o *ResponseOrigin ) GetFrom (m *Message ) error {
a := (*MappedAddress )(o )
return a .GetFromAs (m , AttrResponseOrigin )
}
func (o ResponseOrigin ) String () string {
return net .JoinHostPort (o .IP .String (), strconv .Itoa (o .Port ))
}
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 .