mirror of
https://github.com/taigrr/godns
synced 2025-01-18 04:03:25 -08:00
support for getting an IP from an interface, and skip DNS record update if IP address is the same with last one
This commit is contained in:
parent
78f52ebe54
commit
851e2d7e46
@ -19,6 +19,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ip_url": "http://members.3322.org/dyndns/getip",
|
"ip_url": "http://members.3322.org/dyndns/getip",
|
||||||
|
"ip_interface": "eth0",
|
||||||
"socks5_proxy": "",
|
"socks5_proxy": "",
|
||||||
"notify": {
|
"notify": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
|
@ -74,6 +74,7 @@ func (handler *CloudflareHandler) DomainLoop(domain *godns.Domain, panicChan cha
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var lastIP string
|
||||||
for {
|
for {
|
||||||
currentIP, err := godns.GetCurrentIP(handler.Configuration)
|
currentIP, err := godns.GetCurrentIP(handler.Configuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -81,7 +82,11 @@ func (handler *CloudflareHandler) DomainLoop(domain *godns.Domain, panicChan cha
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Println("Current IP is:", currentIP)
|
log.Println("Current IP is:", currentIP)
|
||||||
// TODO: check against locally cached IP, if no change, skip update
|
//check against locally cached IP, if no change, skip update
|
||||||
|
if (currentIP == lastIP){
|
||||||
|
log.Printf("IP is the same as cached one. Skip update.\n")
|
||||||
|
} else {
|
||||||
|
lastIP = currentIP
|
||||||
|
|
||||||
log.Println("Checking IP for domain", domain.DomainName)
|
log.Println("Checking IP for domain", domain.DomainName)
|
||||||
zoneID := handler.getZone(domain.DomainName)
|
zoneID := handler.getZone(domain.DomainName)
|
||||||
@ -104,7 +109,7 @@ func (handler *CloudflareHandler) DomainLoop(domain *godns.Domain, panicChan cha
|
|||||||
} else {
|
} else {
|
||||||
log.Println("Failed to find zone for domain:", domain.DomainName)
|
log.Println("Failed to find zone for domain:", domain.DomainName)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Interval is 5 minutes
|
// Interval is 5 minutes
|
||||||
log.Printf("Going to sleep, will start next checking in %d minutes...\r\n", godns.INTERVAL)
|
log.Printf("Going to sleep, will start next checking in %d minutes...\r\n", godns.INTERVAL)
|
||||||
time.Sleep(time.Minute * godns.INTERVAL)
|
time.Sleep(time.Minute * godns.INTERVAL)
|
||||||
|
@ -36,6 +36,7 @@ func (handler *DNSPodHandler) DomainLoop(domain *godns.Domain, panicChan chan<-
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var lastIP string
|
||||||
for {
|
for {
|
||||||
log.Printf("Checking IP for domain %s \r\n", domain.DomainName)
|
log.Printf("Checking IP for domain %s \r\n", domain.DomainName)
|
||||||
domainID := handler.GetDomain(domain.DomainName)
|
domainID := handler.GetDomain(domain.DomainName)
|
||||||
@ -52,6 +53,12 @@ func (handler *DNSPodHandler) DomainLoop(domain *godns.Domain, panicChan chan<-
|
|||||||
}
|
}
|
||||||
log.Println("currentIP is:", currentIP)
|
log.Println("currentIP is:", currentIP)
|
||||||
|
|
||||||
|
//check against locally cached IP, if no change, skip update
|
||||||
|
if (currentIP == lastIP){
|
||||||
|
log.Printf("IP is the same as cached one. Skip update.\n")
|
||||||
|
}else{
|
||||||
|
lastIP = currentIP
|
||||||
|
|
||||||
for _, subDomain := range domain.SubDomains {
|
for _, subDomain := range domain.SubDomains {
|
||||||
|
|
||||||
subDomainID, ip := handler.GetSubDomain(domainID, subDomain)
|
subDomainID, ip := handler.GetSubDomain(domainID, subDomain)
|
||||||
@ -76,7 +83,7 @@ func (handler *DNSPodHandler) DomainLoop(domain *godns.Domain, panicChan chan<-
|
|||||||
log.Printf("%s.%s Current IP is same as domain IP, no need to update...\n", subDomain, domain.DomainName)
|
log.Printf("%s.%s Current IP is same as domain IP, no need to update...\n", subDomain, domain.DomainName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Interval is 5 minutes
|
// Interval is 5 minutes
|
||||||
log.Printf("Going to sleep, will start next checking in %d minutes...\r\n", godns.INTERVAL)
|
log.Printf("Going to sleep, will start next checking in %d minutes...\r\n", godns.INTERVAL)
|
||||||
time.Sleep(time.Minute * godns.INTERVAL)
|
time.Sleep(time.Minute * godns.INTERVAL)
|
||||||
|
@ -39,6 +39,7 @@ func (handler *HEHandler) DomainLoop(domain *godns.Domain, panicChan chan<- godn
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var lastIP string
|
||||||
for {
|
for {
|
||||||
currentIP, err := godns.GetCurrentIP(handler.Configuration)
|
currentIP, err := godns.GetCurrentIP(handler.Configuration)
|
||||||
|
|
||||||
@ -48,6 +49,12 @@ func (handler *HEHandler) DomainLoop(domain *godns.Domain, panicChan chan<- godn
|
|||||||
}
|
}
|
||||||
log.Println("currentIP is:", currentIP)
|
log.Println("currentIP is:", currentIP)
|
||||||
|
|
||||||
|
//check against locally cached IP, if no change, skip update
|
||||||
|
if (currentIP == lastIP){
|
||||||
|
log.Printf("IP is the same as cached one. Skip update.\n")
|
||||||
|
} else {
|
||||||
|
lastIP = currentIP
|
||||||
|
|
||||||
for _, subDomain := range domain.SubDomains {
|
for _, subDomain := range domain.SubDomains {
|
||||||
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
|
log.Printf("%s.%s Start to update record IP...\n", subDomain, domain.DomainName)
|
||||||
handler.UpdateIP(domain.DomainName, subDomain, currentIP)
|
handler.UpdateIP(domain.DomainName, subDomain, currentIP)
|
||||||
@ -58,11 +65,12 @@ func (handler *HEHandler) DomainLoop(domain *godns.Domain, panicChan chan<- godn
|
|||||||
godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP)
|
godns.SendNotify(handler.Configuration, fmt.Sprintf("%s.%s", subDomain, domain.DomainName), currentIP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Interval is 5 minutes
|
// Interval is 5 minutes
|
||||||
log.Printf("Going to sleep, will start next checking in %d minutes...\r\n", godns.INTERVAL)
|
log.Printf("Going to sleep, will start next checking in %d minutes...\r\n", godns.INTERVAL)
|
||||||
time.Sleep(time.Minute * godns.INTERVAL)
|
time.Sleep(time.Minute * godns.INTERVAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateIP update subdomain with current IP
|
// UpdateIP update subdomain with current IP
|
||||||
|
@ -33,6 +33,9 @@ type Settings struct {
|
|||||||
LogPath string `json:"log_path"`
|
LogPath string `json:"log_path"`
|
||||||
Socks5Proxy string `json:"socks5_proxy"`
|
Socks5Proxy string `json:"socks5_proxy"`
|
||||||
Notify Notify `json:"notify"`
|
Notify Notify `json:"notify"`
|
||||||
|
IPInterface string `json:"ip_interface"`
|
||||||
|
//the code is not ready to update AAAA record
|
||||||
|
//IPType string `json:"ip_type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadSettings -- Load settings from config file
|
// LoadSettings -- Load settings from config file
|
||||||
|
82
utils.go
82
utils.go
@ -8,6 +8,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"net"
|
||||||
|
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
"gopkg.in/gomail.v2"
|
"gopkg.in/gomail.v2"
|
||||||
@ -43,8 +44,87 @@ const (
|
|||||||
CLOUDFLARE = "Cloudflare"
|
CLOUDFLARE = "Cloudflare"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetCurrentIP gets public IP from internet
|
//GetIPFromInterface gets IP address from the specific interface
|
||||||
|
func GetIPFromInterface(configuration *Settings) (string,error) {
|
||||||
|
ifaces, err := net.InterfaceByName(configuration.IPInterface)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("can't get network device "+configuration.IPInterface+":", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
addrs, err :=ifaces.Addrs();
|
||||||
|
if err != nil {
|
||||||
|
log.Println("can't get address from "+configuration.IPInterface+":", err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var ip net.IP
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
ip = v.IP
|
||||||
|
case *net.IPAddr:
|
||||||
|
ip = v.IP
|
||||||
|
}
|
||||||
|
if (ip == nil){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ip.IsGlobalUnicast() &&!(ip.IsUnspecified()||ip.IsMulticast()||ip.IsLoopback()||ip.IsLinkLocalUnicast()||ip.IsLinkLocalMulticast()||ip.IsInterfaceLocalMulticast()))){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//the code is not ready for updating an AAAA record
|
||||||
|
/*
|
||||||
|
if (isIPv4(ip.String())){
|
||||||
|
if (configuration.IPType=="IPv6"){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if (configuration.IPType!="IPv6"){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
if (!isIPv4(ip.String())){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ip.String(),nil
|
||||||
|
|
||||||
|
}
|
||||||
|
return "", errors.New("can't get a vaild address from "+configuration.IPInterface)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isIPv4(ip string) bool{
|
||||||
|
return strings.Count(ip, ":") < 2
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetCurrentIP gets an IP from either internet or specific interface, depending on configuration
|
||||||
func GetCurrentIP(configuration *Settings) (string, error) {
|
func GetCurrentIP(configuration *Settings) (string, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if (configuration.IPUrl != ""){
|
||||||
|
ip, err := GetIPOnline(configuration)
|
||||||
|
if (err != nil){
|
||||||
|
log.Println("get ip online failed. Fallback to get ip from interface if possible.")
|
||||||
|
}else{
|
||||||
|
return ip,nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configuration.IPInterface != ""){
|
||||||
|
ip, err := GetIPFromInterface(configuration)
|
||||||
|
if (err != nil){
|
||||||
|
log.Println("get ip from interface failed. There is no more ways to try.")
|
||||||
|
}else{
|
||||||
|
return ip,nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// GetIPOnline gets public IP from internet
|
||||||
|
func GetIPOnline(configuration *Settings) (string, error) {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
|
||||||
if configuration.Socks5Proxy != "" {
|
if configuration.Socks5Proxy != "" {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user