179 lines
4.8 KiB
Go
179 lines
4.8 KiB
Go
package ddnscore
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"regexp"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/gdy666/lucky/config"
|
|
"github.com/gdy666/lucky/thirdlib/gdylib/httputils"
|
|
"github.com/gdy666/lucky/thirdlib/gdylib/netinterfaces"
|
|
)
|
|
|
|
// Ipv4Reg IPv4正则
|
|
const Ipv4Reg = `((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])`
|
|
|
|
// Ipv6Reg IPv6正则
|
|
const Ipv6Reg = `((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))`
|
|
|
|
var ipUrlAddrMap sync.Map
|
|
|
|
type DDNSTaskInfo struct {
|
|
config.DDNSTask
|
|
TaskState DDNSTaskState `json:"TaskState"`
|
|
}
|
|
|
|
func (d *DDNSTaskInfo) getIpAddr() (result string) {
|
|
if d.TaskType == "IPv6" {
|
|
return d.getIpv6Addr()
|
|
}
|
|
return d.getIpv4Addr()
|
|
}
|
|
|
|
// CheckIPChange 检测公网IP是否改变
|
|
func (d *DDNSTaskInfo) CheckIPChange() (ipAddr string, change bool) {
|
|
ipAddr = d.getIpAddr()
|
|
|
|
checkIPChange := d.TaskState.IPChangeCheck(ipAddr)
|
|
|
|
if checkIPChange {
|
|
return ipAddr, true
|
|
}
|
|
|
|
//IP没变化
|
|
return ipAddr, false
|
|
}
|
|
|
|
// getIpv4Addr 获得IPv4地址
|
|
func (d *DDNSTaskInfo) getIpv4Addr() (result string) {
|
|
// 判断从哪里获取IP
|
|
if d.GetType == "netInterface" {
|
|
result = netinterfaces.GetIPFromNetInterface("IPv4", d.NetInterface, d.IPReg)
|
|
return
|
|
}
|
|
|
|
ddnsGlobalConf := config.GetDDNSConfigure()
|
|
|
|
client, err := httputils.CreateHttpClient(
|
|
"tcp4",
|
|
"",
|
|
ddnsGlobalConf.HttpClientSecureVerify,
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
time.Duration(d.HttpClientTimeout)*time.Second)
|
|
|
|
if err != nil {
|
|
log.Printf("%s", err.Error())
|
|
return
|
|
}
|
|
|
|
for _, url := range d.URL {
|
|
url = strings.TrimSpace(url)
|
|
|
|
mapIp, ok := ipUrlAddrMap.Load(url)
|
|
if ok {
|
|
//log.Printf("URL[%s]已缓存IP[%s]", url, mapIp)
|
|
result = mapIp.(string)
|
|
return
|
|
}
|
|
|
|
resp, err := client.Get(url)
|
|
if err != nil {
|
|
//log.Printf("连接失败!%s查看接口能否返回IPv4地址</a>,", url)
|
|
continue
|
|
}
|
|
defer resp.Body.Close()
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
log.Printf("读取IPv4结果失败! 接口:%s", url)
|
|
continue
|
|
}
|
|
comp := regexp.MustCompile(Ipv4Reg)
|
|
result = comp.FindString(string(body))
|
|
if result != "" {
|
|
ipUrlAddrMap.Store(url, result)
|
|
return
|
|
}
|
|
// else {
|
|
// log.Printf("获取IPv4结果失败! 接口: %s ,返回值: %s\n", url, result)
|
|
// }
|
|
}
|
|
|
|
log.Printf("所有查询公网IPv4的接口均获取IPv4结果失败,请检查接口或当前网络情况")
|
|
return
|
|
}
|
|
|
|
// getIpv6Addr 获得IPv6地址
|
|
func (d *DDNSTaskInfo) getIpv6Addr() (result string) {
|
|
// 判断从哪里获取IP
|
|
if d.GetType == "netInterface" {
|
|
result = netinterfaces.GetIPFromNetInterface("IPv6", d.NetInterface, d.IPReg)
|
|
return
|
|
}
|
|
|
|
ddnsGlobalConf := config.GetDDNSConfigure()
|
|
client, err := httputils.CreateHttpClient(
|
|
"tcp6",
|
|
"",
|
|
!ddnsGlobalConf.HttpClientSecureVerify,
|
|
"",
|
|
"",
|
|
"",
|
|
"",
|
|
time.Duration(d.HttpClientTimeout)*time.Second)
|
|
|
|
if err != nil {
|
|
log.Printf("%s", err.Error())
|
|
return
|
|
}
|
|
|
|
for _, url := range d.URL {
|
|
url = strings.TrimSpace(url)
|
|
|
|
mapIp, ok := ipUrlAddrMap.Load(url)
|
|
if ok {
|
|
//log.Printf("URL[%s]已缓存IP[%s]", url, mapIp)
|
|
result = mapIp.(string)
|
|
return
|
|
}
|
|
|
|
resp, err := client.Get(url)
|
|
if err != nil {
|
|
//log.Printf("连接失败! %s查看接口能否返回IPv6地址 ", url)
|
|
continue
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
body, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
log.Println("读取IPv6结果失败! 接口: ", url)
|
|
continue
|
|
}
|
|
comp := regexp.MustCompile(Ipv6Reg)
|
|
result = comp.FindString(string(body))
|
|
if result != "" {
|
|
ipUrlAddrMap.Store(url, result)
|
|
return
|
|
}
|
|
}
|
|
log.Printf("所有查询公网IPv6的接口均获取IPv6结果失败,请检查接口或当前网络情况")
|
|
|
|
return
|
|
}
|
|
|
|
func CleanIPUrlAddrMap() {
|
|
keys := []string{}
|
|
ipUrlAddrMap.Range(func(key, value any) bool {
|
|
keys = append(keys, key.(string))
|
|
return true
|
|
})
|
|
for _, k := range keys {
|
|
ipUrlAddrMap.Delete(k)
|
|
}
|
|
}
|