go resolve tcp address

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
import (
"encoding/binary"
"fmt"
"net"
"strconv"
"unsafe"
)

func htons(w uint16) uint16 {
return w>>8 | w<<8
}

func resolveaddr(address string) (af int, sa interface{}, size uintptr, err error) {
var addr *net.TCPAddr
addr, err = net.ResolveTCPAddr("tcp", address)
if err != nil {
return
}
ip := addr.IP
if len(ip) == 0 {
ip = net.IPv4zero
}
if len(ip) == net.IPv4len {
af = AF_INET
sa = &sockaddr_in{
sin_family: AF_INET,
sin_port: htons(uint16(addr.Port)),
sin_addr: binary.BigEndian.Uint32(ip),
}
size = unsafe.Sizeof(sockaddr_in{})
} else if len(ip) == net.IPv6len {
af = AF_INET6
scopeid := uint32(0)
nif, err := net.InterfaceByName(addr.Zone)
if err == nil {
scopeid = uint32(nif.Index)
} else {
n, _ := strconv.Atoi(addr.Zone)
scopeid = uint32(n)
}
sin6 := &sockaddr_in6{
sin6_family: AF_INET6,
sin6_port: htons(uint16(addr.Port)),
sin6_scope_id: scopeid,
}
copy(sin6.sin6_addr[:], ip)
sa = sin6
size = unsafe.Sizeof(sockaddr_in6{})
} else {
err = fmt.Errorf("unrecognized address: %s", address)
}
return
}