🚸 取 Agent IP 优化,直接分 IPv4/IPv6 访问

This commit is contained in:
naiba 2021-05-22 11:28:43 +08:00
parent 3e09c12dc7
commit 7d5ea7ab99
3 changed files with 99 additions and 15 deletions

View File

@ -1,11 +1,17 @@
package monitor
import (
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
"strings"
"time"
"github.com/miekg/dns"
)
type geoIP struct {
@ -13,22 +19,24 @@ type geoIP struct {
IP string `json:"ip,omitempty"`
}
var ipv4Servers = []string{
"https://api-ipv4.ip.sb/geoip",
"https://ip4.seeip.org/geoip",
}
var ipv6Servers = []string{
"https://ip6.seeip.org/geoip",
"https://api-ipv6.ip.sb/geoip",
}
var cachedIP, cachedCountry string
var (
ipv4Servers = []string{
"https://api-ipv4.ip.sb/geoip",
"https://ip4.seeip.org/geoip",
}
ipv6Servers = []string{
"https://ip6.seeip.org/geoip",
"https://api-ipv6.ip.sb/geoip",
}
cachedIP, cachedCountry string
httpClientV4 = newHTTPClient(time.Second*20, time.Second*5, time.Second*10, false)
httpClientV6 = newHTTPClient(time.Second*20, time.Second*5, time.Second*10, true)
)
func UpdateIP() {
for {
ipv4 := fetchGeoIP(ipv4Servers)
ipv6 := fetchGeoIP(ipv6Servers)
ipv4 := fetchGeoIP(ipv4Servers, false)
ipv6 := fetchGeoIP(ipv6Servers, true)
cachedIP = fmt.Sprintf("ip(v4:%s,v6:%s)", ipv4.IP, ipv6.IP)
if ipv4.CountryCode != "" {
cachedCountry = ipv4.CountryCode
@ -39,10 +47,16 @@ func UpdateIP() {
}
}
func fetchGeoIP(servers []string) geoIP {
func fetchGeoIP(servers []string, isV6 bool) geoIP {
var ip geoIP
var resp *http.Response
var err error
for i := 0; i < len(servers); i++ {
resp, err := http.Get(servers[i])
if isV6 {
resp, err = httpClientV6.Get(servers[i])
} else {
resp, err = httpClientV4.Get(servers[i])
}
if err == nil {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
@ -58,3 +72,70 @@ func fetchGeoIP(servers []string) geoIP {
}
return ip
}
func newHTTPClient(httpTimeout, dialTimeout, keepAliveTimeout time.Duration, ipv6 bool) *http.Client {
dialer := &net.Dialer{
Timeout: dialTimeout,
KeepAlive: keepAliveTimeout,
}
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
ForceAttemptHTTP2: false,
DialContext: func(ctx context.Context, network string, addr string) (net.Conn, error) {
ip, err := resolveIP(addr, ipv6)
if err != nil {
return nil, err
}
return dialer.DialContext(ctx, network, ip)
},
}
return &http.Client{
Transport: transport,
Timeout: httpTimeout,
}
}
func resolveIP(addr string, ipv6 bool) (string, error) {
url := strings.Split(addr, ":")
m := new(dns.Msg)
if ipv6 {
m.SetQuestion(dns.Fqdn(url[0]), dns.TypeAAAA)
} else {
m.SetQuestion(dns.Fqdn(url[0]), dns.TypeA)
}
m.RecursionDesired = true
c := new(dns.Client)
r, _, err := c.Exchange(m, net.JoinHostPort("1.1.1.1", "53"))
if err != nil {
return "", err
}
var ipv4Resolved, ipv6Resolved bool
for _, ans := range r.Answer {
if ipv6 {
if aaaa, ok := ans.(*dns.AAAA); ok {
url[0] = aaaa.AAAA.String()
ipv6Resolved = true
}
} else {
if a, ok := ans.(*dns.A); ok {
url[0] = a.A.String()
ipv4Resolved = true
}
}
}
if ipv6 && !ipv6Resolved {
return "", errors.New("the AAAA record not resolved")
}
if !ipv6 && !ipv4Resolved {
return "", errors.New("the A record not resolved")
}
return strings.Join(url, ":"), nil
}

1
go.mod
View File

@ -13,6 +13,7 @@ require (
github.com/golang/protobuf v1.4.2
github.com/google/go-github v17.0.0+incompatible
github.com/gorilla/websocket v1.4.2
github.com/miekg/dns v1.0.14
github.com/onsi/ginkgo v1.7.0 // indirect
github.com/onsi/gomega v1.4.3 // indirect
github.com/p14yground/go-github-selfupdate v0.0.0-20210520015421-eddf14461293

2
go.sum
View File

@ -228,6 +228,7 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ=
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@ -420,6 +421,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=