-
Notifications
You must be signed in to change notification settings - Fork 1
/
alternate_server.go
88 lines (80 loc) · 1.56 KB
/
alternate_server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package stun
import (
"errors"
"fmt"
"net"
)
type AlternateServer struct {
Family byte
Port uint16
IP net.IP
}
func (a *AlternateServer) Type() uint16 {
return ATTR_TYPE_ALTERNATE_SERVER
}
func (a *AlternateServer) Length() uint16 {
if a.Family == 0x01 {
return 8
} else {
return 20
}
}
func (a *AlternateServer) Pack(b []byte) error {
b = b[4:]
if a.Family == 0x01 {
if len(b) < 8 {
return errors.New("Buffer too short for IPv4")
}
b[0] = 0
b[1] = 0x01 // Family
putUint16(b[2:4], a.Port)
i := copy(b[4:8], a.IP.To4())
if i != 4 {
return errors.New("Copy failed")
}
return nil
} else if a.Family == 0x02 {
if len(b) < 20 {
return errors.New("Buffer too short for IPv6")
}
b[1] = 0x02 // Family
putUint16(b[2:4], a.Port)
i := copy(b[4:20], a.IP)
if i != 16 {
return errors.New("Copy failed")
}
return nil
}
return errors.New("Undefined Family")
}
func (a *AlternateServer) UnPack(b []byte) error {
b = b[4:]
if len(b) < 8 {
return errors.New("Buffer too short")
}
a.Family = b[1]
if a.Family == 0x02 && len(b) < 20 {
return errors.New("Buffer is too short for IPv6")
}
a.Port = toUint16(b[2:4])
if a.Family == 0x01 {
a.IP = net.IPv4(b[4], b[5], b[6], b[7])
} else {
a.IP = make(net.IP, 16)
i := copy(a.IP, b[4:20])
if i != 16 {
return errors.New("Copy failed")
}
}
return nil
}
func (a *AlternateServer) String() string {
var family string
switch a.Family {
case 1:
family = "IPv4"
case 2:
family = "IPv6"
}
return fmt.Sprintf("Alternate Server: %s %s:%d", family, a.IP, a.Port)
}