-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
net.go
95 lines (86 loc) · 2.26 KB
/
net.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
89
90
91
92
93
94
95
package minequery
import (
"errors"
"fmt"
"net"
"strings"
"time"
)
func (p *Pinger) openTCPConn(host string, port int) (net.Conn, error) {
conn, err := p.Dialer.Dial("tcp", toAddrString(host, port))
if err != nil {
return nil, err
}
if p.Timeout != 0 {
if err = conn.SetDeadline(time.Now().Add(p.Timeout)); err != nil {
return nil, err
}
}
return conn, nil
}
func (p *Pinger) openUDPConn(host string, port int) (*net.UDPConn, error) {
addr, err := net.ResolveUDPAddr("udp", toAddrString(host, port))
if err != nil {
return nil, err
}
conn, err := net.DialUDP("udp", nil, addr)
if err != nil {
return nil, err
}
if p.Timeout != 0 {
if err = conn.SetDeadline(time.Now().Add(p.Timeout)); err != nil {
return nil, err
}
}
return conn, nil
}
func (p *Pinger) openUDPConnWithLocalAddr(host string, remotePort int, localAddr string) (*net.UDPConn, error) {
lAddrObj, err := net.ResolveUDPAddr("udp", localAddr)
if err != nil {
return nil, err
}
addr, err := net.ResolveUDPAddr("udp", toAddrString(host, remotePort))
if err != nil {
return nil, err
}
conn, err := net.DialUDP("udp", lAddrObj, addr)
if err != nil {
return nil, err
}
if p.Timeout != 0 {
if err = conn.SetDeadline(time.Now().Add(p.Timeout)); err != nil {
return nil, err
}
}
return conn, nil
}
// resolveSRV performs SRV lookup of a Minecraft server hostname.
//
// In case there are no records found, an empty string, a zero port and nil error are returned.
//
// In case when there is more than one record, the hostname and port of the first record with
// the least weight is returned.
func (p *Pinger) resolveSRV(host string) (string, uint16, error) {
_, records, err := net.LookupSRV("minecraft", "tcp", host)
if err != nil {
var dnsError *net.DNSError
if errors.As(err, &dnsError) && dnsError.IsNotFound {
return "", 0, nil
}
return "", 0, err
}
if len(records) == 0 {
return "", 0, nil
}
target := records[0]
return target.Target, target.Port, nil
}
func shouldWrapIPv6(host string) bool {
return len(host) >= 2 && !(host[0] == '[' && host[1] == ']') && strings.Count(host, ":") >= 2
}
func toAddrString(host string, port int) string {
if shouldWrapIPv6(host) {
return fmt.Sprintf(`[%s]:%d`, host, port)
}
return fmt.Sprintf(`%s:%d`, host, port)
}