diff --git a/app/app.go b/app/app.go index 45a8ad1..9e07e87 100644 --- a/app/app.go +++ b/app/app.go @@ -33,7 +33,7 @@ func NewApp(config *Config) (*App, error) { return &App{ ProviderManager: providerMgr, - iplookup: ip.NewCache(resolver.LookupWrapper(l)).Get, + iplookup: ip.NewCache(ip.LookupWrapper(l)).Get, }, nil } diff --git a/ip/helpers.go b/ip/interface.go similarity index 71% rename from ip/helpers.go rename to ip/interface.go index 6e53e4a..dd32b17 100644 --- a/ip/helpers.go +++ b/ip/interface.go @@ -5,9 +5,6 @@ import ( "net" ) -// Resolver is a function that gets the ip from a interface name -type NetInterfaceIPResolver func(iface string) (net.IP, error) - func GetInterfaceIP(iface_name string) (net.IP, error) { ip := net.IP{} iface, err := net.InterfaceByName(iface_name) @@ -47,15 +44,3 @@ func AddrToIP(addr net.Addr) (net.IP, error) { } return nil, errors.New("could not find ip") } - -func ParseIP(s string) (net.IP, error) { - var err error = nil - ip := net.ParseIP(s) - if ip == nil { - err = &net.ParseError{ - Type: "IP address", - Text: s, - } - } - return ip, err -} diff --git a/ip/helpers_test.go b/ip/interface_test.go similarity index 69% rename from ip/helpers_test.go rename to ip/interface_test.go index 9d45778..436eb96 100644 --- a/ip/helpers_test.go +++ b/ip/interface_test.go @@ -67,31 +67,3 @@ func TestAddrToIP(t *testing.T) { }) } } - -func TestParseIP(t *testing.T) { - tests := []struct { - name string - input string - want net.IP - wantErr bool - }{ - {"localhost", "127.0.0.1", net.IPv4(127, 0, 0, 1), false}, - {"Private#1", "10.4.0.11", net.IPv4(10, 4, 0, 11), false}, - {"Private#2", "192.168.1.12", net.IPv4(192, 168, 1, 12), false}, - {"Public#1", "82.249.10.254", net.IPv4(82, 249, 10, 254), false}, - {"Public#2", "57.167.50.222", net.IPv4(57, 167, 50, 222), false}, - {"Invalid", "xx", nil, true}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ParseIP(tt.input) - if (err != nil) != tt.wantErr { - t.Errorf("ParseIP() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ParseIP() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/ip/internal/ip.go b/ip/internal/ip.go new file mode 100644 index 0000000..45ab9be --- /dev/null +++ b/ip/internal/ip.go @@ -0,0 +1,15 @@ +package internal + +import "net" + +func ParseIP(s string) (net.IP, error) { + var err error = nil + ip := net.ParseIP(s) + if ip == nil { + err = &net.ParseError{ + Type: "IP address", + Text: s, + } + } + return ip, err +} diff --git a/ip/internal/ip_test.go b/ip/internal/ip_test.go new file mode 100644 index 0000000..29d0c2e --- /dev/null +++ b/ip/internal/ip_test.go @@ -0,0 +1,35 @@ +package internal + +import ( + "net" + "reflect" + "testing" +) + +func TestParseIP(t *testing.T) { + tests := []struct { + name string + input string + want net.IP + wantErr bool + }{ + {"localhost", "127.0.0.1", net.IPv4(127, 0, 0, 1), false}, + {"Private#1", "10.4.0.11", net.IPv4(10, 4, 0, 11), false}, + {"Private#2", "192.168.1.12", net.IPv4(192, 168, 1, 12), false}, + {"Public#1", "82.249.10.254", net.IPv4(82, 249, 10, 254), false}, + {"Public#2", "57.167.50.222", net.IPv4(57, 167, 50, 222), false}, + {"Invalid", "xx", nil, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ParseIP(tt.input) + if (err != nil) != tt.wantErr { + t.Errorf("ParseIP() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ParseIP() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/ip/lookup.go b/ip/lookup.go new file mode 100644 index 0000000..cad1d68 --- /dev/null +++ b/ip/lookup.go @@ -0,0 +1,23 @@ +package ip + +import ( + "context" + "net" + "time" + + "dnsupdater/ip/resolver" +) + +// Resolver is a function that gets the ip from a interface name +type NetInterfaceIPResolver func(iface string) (net.IP, error) + +func LookupWrapper(service resolver.Service) NetInterfaceIPResolver { + return func(iface_name string) (net.IP, error) { + if iface_name == resolver.WAN_IFACE { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + return service.Lookup(ctx) + } + return GetInterfaceIP(iface_name) + } +} diff --git a/ip/resolver/basic_http/service.go b/ip/resolver/basic_http/service.go index eece2da..c5407a3 100644 --- a/ip/resolver/basic_http/service.go +++ b/ip/resolver/basic_http/service.go @@ -8,7 +8,7 @@ import ( "strings" httputils "dnsupdater/http" - "dnsupdater/ip" + "dnsupdater/ip/internal" ) type Service struct { @@ -35,5 +35,5 @@ func (s Service) Lookup(ctx context.Context) (net.IP, error) { // Trim spaces and stuff. ip_str := strings.TrimSpace(string(body)) - return ip.ParseIP(ip_str) + return internal.ParseIP(ip_str) } diff --git a/ip/resolver/jsonip/service.go b/ip/resolver/jsonip/service.go index 0b6824b..c2b3846 100644 --- a/ip/resolver/jsonip/service.go +++ b/ip/resolver/jsonip/service.go @@ -6,7 +6,7 @@ import ( "net" "dnsupdater/http" - "dnsupdater/ip" + "dnsupdater/ip/internal" ) type Service struct { @@ -38,5 +38,5 @@ func (s Service) Lookup(ctx context.Context) (net.IP, error) { return nil, err } - return ip.ParseIP(v.Ip) + return internal.ParseIP(v.Ip) } diff --git a/ip/resolver/resolver.go b/ip/resolver/resolver.go new file mode 100644 index 0000000..5e2c93a --- /dev/null +++ b/ip/resolver/resolver.go @@ -0,0 +1,18 @@ +package resolver + +import ( + "context" + "net" +) + +// Interface that IP Lookup Services must implement. +type Service interface { + // Get the name of the serivce + Name() string + + // Lookup the public ip. + Lookup(ctx context.Context) (net.IP, error) +} + +// Constant name for the virtual WAN interface +const WAN_IFACE = "wan" diff --git a/ip/resolver/service.go b/ip/resolver/service.go deleted file mode 100644 index 94d3676..0000000 --- a/ip/resolver/service.go +++ /dev/null @@ -1,32 +0,0 @@ -package resolver - -import ( - "context" - "net" - "time" - - "dnsupdater/ip" -) - -// Interface that IP Lookup Services must implement. -type Service interface { - // Get the name of the serivce - Name() string - - // Lookup the public ip. - Lookup(ctx context.Context) (net.IP, error) -} - -// Constant name for the virtual WAN interface -const WAN_IFACE = "wan" - -func LookupWrapper(service Service) ip.NetInterfaceIPResolver { - return func(iface_name string) (net.IP, error) { - if iface_name == WAN_IFACE { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) - defer cancel() - return service.Lookup(ctx) - } - return ip.GetInterfaceIP(iface_name) - } -} diff --git a/main b/main new file mode 100755 index 0000000..b7540d4 Binary files /dev/null and b/main differ