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
|
package bilibili
import (
"context"
"fmt"
"net"
)
type IpNetType string
var (
IPv6Net IpNetType = "ipv6"
IPv4Net IpNetType = "ipv4"
IP64 IpNetType = "any"
)
// GetDialNetString returns the string accepted by net.Dialer::DialContext
func (t IpNetType) GetDialNetString() string {
switch t {
case IPv4Net:
return "tcp4"
case IPv6Net:
return "tcp6"
case IP64:
return "tcp"
}
return ""
}
func (t IpNetType) String() string {
return fmt.Sprintf("%s(%s)", string(t), t.GetDialNetString())
}
type netContext = func(context.Context, string, string) (net.Conn, error)
type netProbe struct {
list []IpNetType
i int
}
func newNetProbe(protocols []IpNetType) netProbe {
var netList []IpNetType
netList = append(netList, protocols...)
return netProbe{
list: netList,
i: 0,
}
}
func (p *netProbe) NextNetworkType(dialer net.Dialer) (netContext, IpNetType) {
if p.i >= len(p.list) {
return nil, IP64
}
network := p.list[p.i]
p.i++
return func(ctx context.Context, _, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, network.GetDialNetString(), addr)
}, network
}
|