96 lines
2.2 KiB
Go
96 lines
2.2 KiB
Go
// Package that will query for IP
|
|
package checker
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"log/slog"
|
|
"net"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/maximotejeda/ddns/config"
|
|
)
|
|
|
|
type client struct {
|
|
urls []string
|
|
method string
|
|
headers map[string][]string
|
|
reqs []*http.Request
|
|
log *slog.Logger
|
|
}
|
|
|
|
type Response struct {
|
|
IP *net.IP `json:"ip,omitempty" yaml:"ip,omitempty"`
|
|
IPSTR string `json:"ip_str,omitempty" yaml:"ip_str,omitempty"`
|
|
Version string `json:"version" yaml:"version,omitempty"`
|
|
Type string `json:"type,omitempty" yaml:"type,omitempty"`
|
|
Identifyer string `json:"identifyer" yaml:"identifyer"`
|
|
}
|
|
|
|
func NewClient(log *slog.Logger, provider string) *client {
|
|
c := &client{}
|
|
c.urls = strings.Split(config.GetServiceVerifyURL("IP_VERIFY_PROVIDER_URL"), ",")
|
|
c.method = http.MethodGet
|
|
for _, url := range c.urls {
|
|
req, _ := http.NewRequest(c.method, url, nil)
|
|
c.reqs = append(c.reqs, req)
|
|
}
|
|
log = log.With("location", "Checker")
|
|
c.log = log
|
|
return c
|
|
}
|
|
|
|
// Do
|
|
// Make a request to retrieve the ip of the machine
|
|
func (c *client) Do() (res *Response, err error) {
|
|
r := &Response{}
|
|
client := http.DefaultClient
|
|
if len(c.reqs) <= 0 {
|
|
c.log.Error("no request on struct")
|
|
return nil, errors.New("no request on client struct")
|
|
}
|
|
resp, err := client.Do(c.reqs[0])
|
|
r.Identifyer = c.urls[0]
|
|
if err != nil {
|
|
c.log.Error("doing request for ip", "err", err, "identidyer", c.reqs[0])
|
|
c.log.Info("retrying on other provider")
|
|
resp, err = client.Do(c.reqs[1])
|
|
r.Identifyer = c.urls[1]
|
|
if err != nil {
|
|
c.log.Error("doing request for ip", "err", err, "identidyer", c.reqs[1])
|
|
return nil, err
|
|
}
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
ipSTR, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
c.log.Error("reading body", err)
|
|
}
|
|
|
|
ipi := net.ParseIP(string(ipSTR))
|
|
r.IP = &ipi
|
|
|
|
//check ip is not nil
|
|
if r.IP == nil {
|
|
return nil, errors.New("ip not found")
|
|
}
|
|
// check if ip is private
|
|
if r.IP.IsPrivate() {
|
|
return nil, errors.New("ip is a private ip")
|
|
}
|
|
// check if is loop back ip
|
|
if r.IP.IsLoopback() {
|
|
return nil, errors.New("ip is a loopback ip")
|
|
}
|
|
if r.IP.To4() != nil {
|
|
r.Version = "V4"
|
|
r.Type = "A"
|
|
}else {
|
|
r.Version = "V6"
|
|
r.Type = "AAAA"
|
|
}
|
|
return r, err
|
|
}
|