chore(all): replace net.IP with netip.Addr
This commit is contained in:
@@ -3,8 +3,8 @@ package cli
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -28,11 +28,11 @@ type Unzipper interface {
|
||||
|
||||
type ParallelResolver interface {
|
||||
Resolve(ctx context.Context, settings resolver.ParallelSettings) (
|
||||
hostToIPs map[string][]net.IP, warnings []string, err error)
|
||||
hostToIPs map[string][]netip.Addr, warnings []string, err error)
|
||||
}
|
||||
|
||||
type IPFetcher interface {
|
||||
FetchMultiInfo(ctx context.Context, ips []net.IP) (data []ipinfo.Response, err error)
|
||||
FetchMultiInfo(ctx context.Context, ips []netip.Addr) (data []ipinfo.Response, err error)
|
||||
}
|
||||
|
||||
type IPv6Checker interface {
|
||||
|
||||
@@ -2,7 +2,7 @@ package settings
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings/helpers"
|
||||
"github.com/qdm12/gotree"
|
||||
@@ -13,9 +13,9 @@ type DNS struct {
|
||||
// ServerAddress is the DNS server to use inside
|
||||
// the Go program and for the system.
|
||||
// It defaults to '127.0.0.1' to be used with the
|
||||
// DoT server. It cannot be nil in the internal
|
||||
// DoT server. It cannot be the zero value in the internal
|
||||
// state.
|
||||
ServerAddress net.IP
|
||||
ServerAddress netip.Addr
|
||||
// KeepNameserver is true if the Docker DNS server
|
||||
// found in /etc/resolv.conf should be kept.
|
||||
// Note settings this to true will go around the
|
||||
@@ -39,7 +39,7 @@ func (d DNS) validate() (err error) {
|
||||
|
||||
func (d *DNS) Copy() (copied DNS) {
|
||||
return DNS{
|
||||
ServerAddress: helpers.CopyIP(d.ServerAddress),
|
||||
ServerAddress: d.ServerAddress,
|
||||
KeepNameserver: helpers.CopyBoolPtr(d.KeepNameserver),
|
||||
DoT: d.DoT.copy(),
|
||||
}
|
||||
@@ -63,7 +63,7 @@ func (d *DNS) overrideWith(other DNS) {
|
||||
}
|
||||
|
||||
func (d *DNS) setDefaults() {
|
||||
localhost := net.IPv4(127, 0, 0, 1) //nolint:gomnd
|
||||
localhost := netip.AddrFrom4([4]byte{127, 0, 0, 1})
|
||||
d.ServerAddress = helpers.DefaultIP(d.ServerAddress, localhost)
|
||||
d.KeepNameserver = helpers.DefaultBool(d.KeepNameserver, false)
|
||||
d.DoT.setDefaults()
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
@@ -81,25 +79,6 @@ func CopyLogLevelPtr(original *log.Level) (copied *log.Level) {
|
||||
return copied
|
||||
}
|
||||
|
||||
func CopyIP(original net.IP) (copied net.IP) {
|
||||
if original == nil {
|
||||
return nil
|
||||
}
|
||||
copied = make(net.IP, len(original))
|
||||
copy(copied, original)
|
||||
return copied
|
||||
}
|
||||
|
||||
func CopyNetipAddress(original netip.Addr) (copied netip.Addr) {
|
||||
// AsSlice creates a new byte slice so no need to copy the bytes.
|
||||
bytes := original.AsSlice()
|
||||
copied, ok := netip.AddrFromSlice(bytes)
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("cannot deep copy address with bytes %#v", bytes))
|
||||
}
|
||||
return copied
|
||||
}
|
||||
|
||||
func CopyStringSlice(original []string) (copied []string) {
|
||||
if original == nil {
|
||||
return nil
|
||||
@@ -136,9 +115,6 @@ func CopyNetipAddressesSlice(original []netip.Addr) (copied []netip.Addr) {
|
||||
}
|
||||
|
||||
copied = make([]netip.Addr, len(original))
|
||||
for i := range original {
|
||||
copied[i] = CopyNetipAddress(original[i])
|
||||
}
|
||||
|
||||
copy(copied, original)
|
||||
return copied
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/log"
|
||||
@@ -101,9 +101,9 @@ func DefaultLogLevel(existing *log.Level,
|
||||
return result
|
||||
}
|
||||
|
||||
func DefaultIP(existing net.IP, defaultValue net.IP) (
|
||||
result net.IP) {
|
||||
if existing != nil {
|
||||
func DefaultIP(existing netip.Addr, defaultValue netip.Addr) (
|
||||
result netip.Addr) {
|
||||
if existing.IsValid() {
|
||||
return existing
|
||||
}
|
||||
return defaultValue
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"net"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"time"
|
||||
@@ -96,14 +96,17 @@ func MergeWithUint32(existing, other *uint32) (result *uint32) {
|
||||
return result
|
||||
}
|
||||
|
||||
func MergeWithIP(existing, other net.IP) (result net.IP) {
|
||||
if existing != nil {
|
||||
func MergeWithIP(existing, other netip.Addr) (result netip.Addr) {
|
||||
if existing.IsValid() {
|
||||
return existing
|
||||
} else if !other.IsValid() {
|
||||
return existing
|
||||
} else if other == nil {
|
||||
return nil
|
||||
}
|
||||
result = make(net.IP, len(other))
|
||||
copy(result, other)
|
||||
|
||||
result, ok := netip.AddrFromSlice(other.AsSlice())
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("failed copying other address: %s", other))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"net"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"time"
|
||||
@@ -84,12 +84,14 @@ func OverrideWithUint32(existing, other *uint32) (result *uint32) {
|
||||
return result
|
||||
}
|
||||
|
||||
func OverrideWithIP(existing, other net.IP) (result net.IP) {
|
||||
if other == nil {
|
||||
func OverrideWithIP(existing, other netip.Addr) (result netip.Addr) {
|
||||
if !other.IsValid() {
|
||||
return existing
|
||||
}
|
||||
result = make(net.IP, len(other))
|
||||
copy(result, other)
|
||||
result, ok := netip.AddrFromSlice(other.AsSlice())
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("failed copying other address: %s", other))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package settings
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings/helpers"
|
||||
@@ -21,10 +21,10 @@ type ServerSelection struct { //nolint:maligned
|
||||
VPN string
|
||||
// TargetIP is the server endpoint IP address to use.
|
||||
// It will override any IP address from the picked
|
||||
// built-in server. It cannot be nil in the internal
|
||||
// state, and can be set to an empty net.IP{} to indicate
|
||||
// built-in server. It cannot be the empty value in the internal
|
||||
// state, and can be set to the unspecified address to indicate
|
||||
// there is not target IP address to use.
|
||||
TargetIP net.IP
|
||||
TargetIP netip.Addr
|
||||
// Counties is the list of countries to filter VPN servers with.
|
||||
Countries []string
|
||||
// Regions is the list of regions to filter VPN servers with.
|
||||
@@ -202,7 +202,7 @@ func validateServerFilters(settings ServerSelection, filterChoices models.Filter
|
||||
func (ss *ServerSelection) copy() (copied ServerSelection) {
|
||||
return ServerSelection{
|
||||
VPN: ss.VPN,
|
||||
TargetIP: helpers.CopyIP(ss.TargetIP),
|
||||
TargetIP: ss.TargetIP,
|
||||
Countries: helpers.CopyStringSlice(ss.Countries),
|
||||
Regions: helpers.CopyStringSlice(ss.Regions),
|
||||
Cities: helpers.CopyStringSlice(ss.Cities),
|
||||
@@ -261,7 +261,7 @@ func (ss *ServerSelection) overrideWith(other ServerSelection) {
|
||||
|
||||
func (ss *ServerSelection) setDefaults(vpnProvider string) {
|
||||
ss.VPN = helpers.DefaultString(ss.VPN, vpn.OpenVPN)
|
||||
ss.TargetIP = helpers.DefaultIP(ss.TargetIP, net.IP{})
|
||||
ss.TargetIP = helpers.DefaultIP(ss.TargetIP, netip.IPv4Unspecified())
|
||||
ss.OwnedOnly = helpers.DefaultBool(ss.OwnedOnly, false)
|
||||
ss.FreeOnly = helpers.DefaultBool(ss.FreeOnly, false)
|
||||
ss.PremiumOnly = helpers.DefaultBool(ss.PremiumOnly, false)
|
||||
@@ -278,7 +278,7 @@ func (ss ServerSelection) String() string {
|
||||
func (ss ServerSelection) toLinesNode() (node *gotree.Node) {
|
||||
node = gotree.New("Server selection settings:")
|
||||
node.Appendf("VPN type: %s", ss.VPN)
|
||||
if len(ss.TargetIP) > 0 {
|
||||
if !ss.TargetIP.IsUnspecified() {
|
||||
node.Appendf("Target IP address: %s", ss.TargetIP)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package settings
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/dns/pkg/provider"
|
||||
@@ -155,14 +154,24 @@ func (u Unbound) ToUnboundFormat() (settings unbound.Settings, err error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (u Unbound) GetFirstPlaintextIPv4() (ipv4 net.IP, err error) {
|
||||
var (
|
||||
ErrConvertingNetip = errors.New("converting net.IP to netip.Addr failed")
|
||||
)
|
||||
|
||||
func (u Unbound) GetFirstPlaintextIPv4() (ipv4 netip.Addr, err error) {
|
||||
s := u.Providers[0]
|
||||
provider, err := provider.Parse(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ipv4, err
|
||||
}
|
||||
|
||||
return provider.DNS().IPv4[0], nil
|
||||
ip := provider.DNS().IPv4[0]
|
||||
ipv4, ok := netip.AddrFromSlice(ip)
|
||||
if !ok {
|
||||
return ipv4, fmt.Errorf("%w: for ip %s (%#v)",
|
||||
ErrConvertingNetip, ip, ip)
|
||||
}
|
||||
return ipv4.Unmap(), nil
|
||||
}
|
||||
|
||||
func (u Unbound) String() string {
|
||||
|
||||
@@ -2,7 +2,7 @@ package settings
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings/helpers"
|
||||
"github.com/qdm12/gluetun/internal/constants/providers"
|
||||
@@ -15,9 +15,9 @@ type WireguardSelection struct {
|
||||
// It is only used with VPN providers generating Wireguard
|
||||
// configurations specific to each server and user.
|
||||
// To indicate it should not be used, it should be set
|
||||
// to the empty net.IP{} slice. It can never be nil
|
||||
// to netaddr.IPv4Unspecified(). It can never be the zero value
|
||||
// in the internal state.
|
||||
EndpointIP net.IP
|
||||
EndpointIP netip.Addr
|
||||
// EndpointPort is a the server port to use for the VPN server.
|
||||
// It is optional for VPN providers IVPN, Mullvad, Surfshark
|
||||
// and Windscribe, and compulsory for the others.
|
||||
@@ -40,7 +40,7 @@ func (w WireguardSelection) validate(vpnProvider string) (err error) {
|
||||
providers.Surfshark, providers.Windscribe:
|
||||
// endpoint IP addresses are baked in
|
||||
case providers.Custom:
|
||||
if len(w.EndpointIP) == 0 {
|
||||
if !w.EndpointIP.IsValid() || w.EndpointIP.IsUnspecified() {
|
||||
return fmt.Errorf("%w", ErrWireguardEndpointIPNotSet)
|
||||
}
|
||||
default: // Providers not supporting Wireguard
|
||||
@@ -109,7 +109,7 @@ func (w WireguardSelection) validate(vpnProvider string) (err error) {
|
||||
|
||||
func (w *WireguardSelection) copy() (copied WireguardSelection) {
|
||||
return WireguardSelection{
|
||||
EndpointIP: helpers.CopyIP(w.EndpointIP),
|
||||
EndpointIP: w.EndpointIP,
|
||||
EndpointPort: helpers.CopyUint16Ptr(w.EndpointPort),
|
||||
PublicKey: w.PublicKey,
|
||||
}
|
||||
@@ -128,7 +128,7 @@ func (w *WireguardSelection) overrideWith(other WireguardSelection) {
|
||||
}
|
||||
|
||||
func (w *WireguardSelection) setDefaults() {
|
||||
w.EndpointIP = helpers.DefaultIP(w.EndpointIP, net.IP{})
|
||||
w.EndpointIP = helpers.DefaultIP(w.EndpointIP, netip.IPv4Unspecified())
|
||||
w.EndpointPort = helpers.DefaultUint16(w.EndpointPort, 0)
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ func (w WireguardSelection) String() string {
|
||||
func (w WireguardSelection) toLinesNode() (node *gotree.Node) {
|
||||
node = gotree.New("Wireguard selection settings:")
|
||||
|
||||
if len(w.EndpointIP) > 0 {
|
||||
if !w.EndpointIP.IsUnspecified() {
|
||||
node.Appendf("Endpoint IP address: %s", w.EndpointIP)
|
||||
}
|
||||
|
||||
|
||||
14
internal/configuration/sources/env/dns.go
vendored
14
internal/configuration/sources/env/dns.go
vendored
@@ -2,7 +2,7 @@ package env
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||
)
|
||||
@@ -26,19 +26,19 @@ func (s *Source) readDNS() (dns settings.DNS, err error) {
|
||||
return dns, nil
|
||||
}
|
||||
|
||||
func (s *Source) readDNSServerAddress() (address net.IP, err error) {
|
||||
func (s *Source) readDNSServerAddress() (address netip.Addr, err error) {
|
||||
key, value := s.getEnvWithRetro("DNS_ADDRESS", "DNS_PLAINTEXT_ADDRESS")
|
||||
if value == "" {
|
||||
return nil, nil
|
||||
return address, nil
|
||||
}
|
||||
|
||||
address = net.ParseIP(value)
|
||||
if address == nil {
|
||||
return nil, fmt.Errorf("environment variable %s: %w: %s", key, ErrIPAddressParse, value)
|
||||
address, err = netip.ParseAddr(value)
|
||||
if err != nil {
|
||||
return address, fmt.Errorf("environment variable %s: %w", key, err)
|
||||
}
|
||||
|
||||
// TODO remove in v4
|
||||
if !address.Equal(net.IPv4(127, 0, 0, 1)) { //nolint:gomnd
|
||||
if address.Unmap().Compare(netip.AddrFrom4([4]byte{127, 0, 0, 1})) != 0 {
|
||||
s.warner.Warn(key + " is set to " + value +
|
||||
" so the DNS over TLS (DoT) server will not be used." +
|
||||
" The default value changed to 127.0.0.1 so it uses the internal DoT serves." +
|
||||
|
||||
@@ -3,7 +3,7 @@ package env
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -113,16 +113,15 @@ var (
|
||||
ErrInvalidIP = errors.New("invalid IP address")
|
||||
)
|
||||
|
||||
func (s *Source) readOpenVPNTargetIP() (ip net.IP, err error) {
|
||||
func (s *Source) readOpenVPNTargetIP() (ip netip.Addr, err error) {
|
||||
envKey, value := s.getEnvWithRetro("VPN_ENDPOINT_IP", "OPENVPN_TARGET_IP")
|
||||
if value == "" {
|
||||
return nil, nil
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
ip = net.ParseIP(value)
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("environment variable %s: %w: %s",
|
||||
envKey, ErrInvalidIP, value)
|
||||
ip, err = netip.ParseAddr(value)
|
||||
if err != nil {
|
||||
return ip, fmt.Errorf("environment variable %s: %w", envKey, err)
|
||||
}
|
||||
|
||||
return ip, nil
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||
"github.com/qdm12/govalid/port"
|
||||
@@ -26,18 +25,15 @@ func (s *Source) readWireguardSelection() (
|
||||
return selection, nil
|
||||
}
|
||||
|
||||
var ErrIPAddressParse = errors.New("cannot parse IP address")
|
||||
|
||||
func (s *Source) readWireguardEndpointIP() (endpointIP net.IP, err error) {
|
||||
func (s *Source) readWireguardEndpointIP() (endpointIP netip.Addr, err error) {
|
||||
key, value := s.getEnvWithRetro("VPN_ENDPOINT_IP", "WIREGUARD_ENDPOINT_IP")
|
||||
if value == "" {
|
||||
return nil, nil
|
||||
return endpointIP, nil
|
||||
}
|
||||
|
||||
endpointIP = net.ParseIP(value)
|
||||
if endpointIP == nil {
|
||||
return nil, fmt.Errorf("environment variable %s: %w: %s",
|
||||
key, ErrIPAddressParse, value)
|
||||
endpointIP, err = netip.ParseAddr(value)
|
||||
if err != nil {
|
||||
return endpointIP, fmt.Errorf("environment variable %s: %w", key, err)
|
||||
}
|
||||
|
||||
return endpointIP, nil
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/dns/pkg/nameserver"
|
||||
)
|
||||
@@ -12,14 +12,14 @@ func (l *Loop) useUnencryptedDNS(fallback bool) {
|
||||
// Try with user provided plaintext ip address
|
||||
// if it's not 127.0.0.1 (default for DoT)
|
||||
targetIP := settings.ServerAddress
|
||||
if targetIP != nil && !targetIP.Equal(net.IPv4(127, 0, 0, 1)) { //nolint:gomnd
|
||||
if targetIP.Compare(netip.AddrFrom4([4]byte{127, 0, 0, 1})) != 0 {
|
||||
if fallback {
|
||||
l.logger.Info("falling back on plaintext DNS at address " + targetIP.String())
|
||||
} else {
|
||||
l.logger.Info("using plaintext DNS at address " + targetIP.String())
|
||||
}
|
||||
nameserver.UseDNSInternally(targetIP)
|
||||
err := nameserver.UseDNSSystemWide(l.resolvConf, targetIP, *settings.KeepNameserver)
|
||||
nameserver.UseDNSInternally(targetIP.AsSlice())
|
||||
err := nameserver.UseDNSSystemWide(l.resolvConf, targetIP.AsSlice(), *settings.KeepNameserver)
|
||||
if err != nil {
|
||||
l.logger.Error(err.Error())
|
||||
}
|
||||
@@ -38,8 +38,8 @@ func (l *Loop) useUnencryptedDNS(fallback bool) {
|
||||
} else {
|
||||
l.logger.Info("using plaintext DNS at address " + targetIP.String())
|
||||
}
|
||||
nameserver.UseDNSInternally(targetIP)
|
||||
err = nameserver.UseDNSSystemWide(l.resolvConf, targetIP, *settings.KeepNameserver)
|
||||
nameserver.UseDNSInternally(targetIP.AsSlice())
|
||||
err = nameserver.UseDNSSystemWide(l.resolvConf, targetIP.AsSlice(), *settings.KeepNameserver)
|
||||
if err != nil {
|
||||
l.logger.Error(err.Error())
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ func (l *Loop) setupUnbound(ctx context.Context) (
|
||||
}
|
||||
|
||||
// use Unbound
|
||||
nameserver.UseDNSInternally(settings.ServerAddress)
|
||||
err = nameserver.UseDNSSystemWide(l.resolvConf, settings.ServerAddress,
|
||||
nameserver.UseDNSInternally(settings.ServerAddress.AsSlice())
|
||||
err = nameserver.UseDNSSystemWide(l.resolvConf, settings.ServerAddress.AsSlice(),
|
||||
*settings.KeepNameserver)
|
||||
if err != nil {
|
||||
l.logger.Error(err.Error())
|
||||
|
||||
@@ -130,7 +130,7 @@ func (c *Config) enable(ctx context.Context) (err error) {
|
||||
}
|
||||
|
||||
func (c *Config) allowVPNIP(ctx context.Context) (err error) {
|
||||
if c.vpnConnection.IP == nil {
|
||||
if !c.vpnConnection.IP.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -146,8 +145,7 @@ func (c *Config) acceptOutputTrafficToVPN(ctx context.Context,
|
||||
instruction := fmt.Sprintf("%s OUTPUT -d %s -o %s -p %s -m %s --dport %d -j ACCEPT",
|
||||
appendOrDelete(remove), connection.IP, defaultInterface, connection.Protocol,
|
||||
connection.Protocol, connection.Port)
|
||||
isIPv4 := connection.IP.To4() != nil
|
||||
if isIPv4 {
|
||||
if connection.IP.Is4() {
|
||||
return c.runIptablesInstruction(ctx, instruction)
|
||||
} else if c.ip6Tables == "" {
|
||||
return fmt.Errorf("accept output to VPN server: %w", ErrNeedIP6Tables)
|
||||
@@ -157,8 +155,8 @@ func (c *Config) acceptOutputTrafficToVPN(ctx context.Context,
|
||||
|
||||
// Thanks to @npawelek.
|
||||
func (c *Config) acceptOutputFromIPToSubnet(ctx context.Context,
|
||||
intf string, sourceIP net.IP, destinationSubnet netip.Prefix, remove bool) error {
|
||||
doIPv4 := sourceIP.To4() != nil && destinationSubnet.Addr().Is4()
|
||||
intf string, sourceIP netip.Addr, destinationSubnet netip.Prefix, remove bool) error {
|
||||
doIPv4 := sourceIP.Is4() && destinationSubnet.Addr().Is4()
|
||||
|
||||
interfaceFlag := "-o " + intf
|
||||
if intf == "*" { // all interfaces
|
||||
|
||||
@@ -25,7 +25,7 @@ func (c *Config) SetVPNConnection(ctx context.Context,
|
||||
}
|
||||
|
||||
remove := true
|
||||
if c.vpnConnection.IP != nil {
|
||||
if c.vpnConnection.IP.IsValid() {
|
||||
for _, defaultRoute := range c.defaultRoutes {
|
||||
if err := c.acceptOutputTrafficToVPN(ctx, defaultRoute.NetInterface, c.vpnConnection, remove); err != nil {
|
||||
c.logger.Error("cannot remove outdated VPN connection rule: " + err.Error())
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
type Connection struct {
|
||||
// Type is the connection type and can be "openvpn" or "wireguard"
|
||||
Type string `json:"type"`
|
||||
// IP is the VPN server IP address.
|
||||
IP net.IP `json:"ip"`
|
||||
IP netip.Addr `json:"ip"`
|
||||
// Port is the VPN server port.
|
||||
Port uint16 `json:"port"`
|
||||
// Protocol can be "tcp" or "udp".
|
||||
@@ -24,15 +24,15 @@ type Connection struct {
|
||||
}
|
||||
|
||||
func (c *Connection) Equal(other Connection) bool {
|
||||
return c.IP.Equal(other.IP) && c.Port == other.Port &&
|
||||
return c.IP.Compare(other.IP) == 0 && c.Port == other.Port &&
|
||||
c.Protocol == other.Protocol && c.Hostname == other.Hostname &&
|
||||
c.ServerName == other.ServerName && c.PubKey == other.PubKey
|
||||
}
|
||||
|
||||
// UpdateEmptyWith updates each field of the connection where the
|
||||
// value is not set using the value given as arguments.
|
||||
func (c *Connection) UpdateEmptyWith(ip net.IP, port uint16, protocol string) {
|
||||
if c.IP == nil {
|
||||
func (c *Connection) UpdateEmptyWith(ip netip.Addr, port uint16, protocol string) {
|
||||
if !c.IP.IsValid() {
|
||||
c.IP = ip
|
||||
}
|
||||
if c.Port == 0 {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package models
|
||||
|
||||
import "net"
|
||||
import (
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
type PublicIP struct {
|
||||
IP net.IP `json:"public_ip,omitempty"`
|
||||
IP netip.Addr `json:"public_ip,omitempty"`
|
||||
Region string `json:"region,omitempty"`
|
||||
Country string `json:"country,omitempty"`
|
||||
City string `json:"city,omitempty"`
|
||||
@@ -16,7 +18,7 @@ type PublicIP struct {
|
||||
|
||||
func (p *PublicIP) Copy() (publicIPCopy PublicIP) {
|
||||
publicIPCopy = PublicIP{
|
||||
IP: make(net.IP, len(p.IP)),
|
||||
IP: p.IP,
|
||||
Region: p.Region,
|
||||
Country: p.Country,
|
||||
City: p.City,
|
||||
@@ -26,6 +28,5 @@ func (p *PublicIP) Copy() (publicIPCopy PublicIP) {
|
||||
PostalCode: p.PostalCode,
|
||||
Timezone: p.Timezone,
|
||||
}
|
||||
copy(publicIPCopy.IP, p.IP)
|
||||
return publicIPCopy
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package models
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
@@ -32,7 +32,7 @@ type Server struct {
|
||||
Premium bool `json:"premium,omitempty"`
|
||||
PortForward bool `json:"port_forward,omitempty"`
|
||||
Keep bool `json:"keep,omitempty"`
|
||||
IPs []net.IP `json:"ips,omitempty"`
|
||||
IPs []netip.Addr `json:"ips,omitempty"`
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -72,13 +72,13 @@ func (s *Server) Equal(other Server) (equal bool) {
|
||||
return reflect.DeepEqual(serverCopy, other)
|
||||
}
|
||||
|
||||
func ipsAreEqual(a, b []net.IP) (equal bool) {
|
||||
func ipsAreEqual(a, b []netip.Addr) (equal bool) {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range a {
|
||||
if !a[i].Equal(b[i]) {
|
||||
if a[i].Compare(b[i]) != 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -17,28 +17,28 @@ func Test_Server_Equal(t *testing.T) {
|
||||
}{
|
||||
"same IPs": {
|
||||
a: &Server{
|
||||
IPs: []net.IP{net.IPv4(1, 2, 3, 4)},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
},
|
||||
b: Server{
|
||||
IPs: []net.IP{net.IPv4(1, 2, 3, 4)},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
},
|
||||
equal: true,
|
||||
},
|
||||
"same IP strings": {
|
||||
a: &Server{
|
||||
IPs: []net.IP{net.IPv4(1, 2, 3, 4)},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
},
|
||||
b: Server{
|
||||
IPs: []net.IP{{1, 2, 3, 4}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
},
|
||||
equal: true,
|
||||
},
|
||||
"different IPs": {
|
||||
a: &Server{
|
||||
IPs: []net.IP{{1, 2, 3, 4}, {2, 3, 4, 5}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4}), netip.AddrFrom4([4]byte{2, 3, 4, 5})},
|
||||
},
|
||||
b: Server{
|
||||
IPs: []net.IP{{1, 2, 3, 4}, {1, 2, 3, 4}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4}), netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
},
|
||||
},
|
||||
"all fields equal": {
|
||||
@@ -61,7 +61,7 @@ func Test_Server_Equal(t *testing.T) {
|
||||
Free: true,
|
||||
Stream: true,
|
||||
PortForward: true,
|
||||
IPs: []net.IP{net.IPv4(1, 2, 3, 4)},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
Keep: true,
|
||||
},
|
||||
b: Server{
|
||||
@@ -83,7 +83,7 @@ func Test_Server_Equal(t *testing.T) {
|
||||
Free: true,
|
||||
Stream: true,
|
||||
PortForward: true,
|
||||
IPs: []net.IP{net.IPv4(1, 2, 3, 4)},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
Keep: true,
|
||||
},
|
||||
equal: true,
|
||||
|
||||
@@ -3,7 +3,7 @@ package extract
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -25,12 +25,12 @@ func extractDataFromLines(lines []string) (
|
||||
|
||||
connection.UpdateEmptyWith(ip, port, protocol)
|
||||
|
||||
if connection.Protocol != "" && connection.IP != nil {
|
||||
if connection.Protocol != "" && connection.IP.IsValid() {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if connection.IP == nil {
|
||||
if !connection.IP.IsValid() {
|
||||
return connection, errRemoteLineNotFound
|
||||
}
|
||||
|
||||
@@ -49,24 +49,24 @@ func extractDataFromLines(lines []string) (
|
||||
}
|
||||
|
||||
func extractDataFromLine(line string) (
|
||||
ip net.IP, port uint16, protocol string, err error) {
|
||||
ip netip.Addr, port uint16, protocol string, err error) {
|
||||
switch {
|
||||
case strings.HasPrefix(line, "proto "):
|
||||
protocol, err = extractProto(line)
|
||||
if err != nil {
|
||||
return nil, 0, "", fmt.Errorf("extracting protocol from proto line: %w", err)
|
||||
return ip, 0, "", fmt.Errorf("extracting protocol from proto line: %w", err)
|
||||
}
|
||||
return nil, 0, protocol, nil
|
||||
return ip, 0, protocol, nil
|
||||
|
||||
case strings.HasPrefix(line, "remote "):
|
||||
ip, port, protocol, err = extractRemote(line)
|
||||
if err != nil {
|
||||
return nil, 0, "", fmt.Errorf("extracting from remote line: %w", err)
|
||||
return ip, 0, "", fmt.Errorf("extracting from remote line: %w", err)
|
||||
}
|
||||
return ip, port, protocol, nil
|
||||
}
|
||||
|
||||
return nil, 0, "", nil
|
||||
return ip, 0, "", nil
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -95,19 +95,19 @@ var (
|
||||
errPortNotValid = errors.New("port is not valid")
|
||||
)
|
||||
|
||||
func extractRemote(line string) (ip net.IP, port uint16,
|
||||
func extractRemote(line string) (ip netip.Addr, port uint16,
|
||||
protocol string, err error) {
|
||||
fields := strings.Fields(line)
|
||||
n := len(fields)
|
||||
|
||||
if n < 2 || n > 4 {
|
||||
return nil, 0, "", fmt.Errorf("%w: %s", errRemoteLineFieldsCount, line)
|
||||
return netip.Addr{}, 0, "", fmt.Errorf("%w: %s", errRemoteLineFieldsCount, line)
|
||||
}
|
||||
|
||||
host := fields[1]
|
||||
ip = net.ParseIP(host)
|
||||
if ip == nil {
|
||||
return nil, 0, "", fmt.Errorf("%w: %s", errHostNotIP, host)
|
||||
ip, err = netip.ParseAddr(host)
|
||||
if err != nil {
|
||||
return netip.Addr{}, 0, "", fmt.Errorf("%w: %s", errHostNotIP, host)
|
||||
// TODO resolve hostname once there is an option to allow it through
|
||||
// the firewall before the VPN is up.
|
||||
}
|
||||
@@ -115,9 +115,9 @@ func extractRemote(line string) (ip net.IP, port uint16,
|
||||
if n > 2 { //nolint:gomnd
|
||||
portInt, err := strconv.Atoi(fields[2])
|
||||
if err != nil {
|
||||
return nil, 0, "", fmt.Errorf("%w: %s", errPortNotValid, line)
|
||||
return netip.Addr{}, 0, "", fmt.Errorf("%w: %s", errPortNotValid, line)
|
||||
} else if portInt < 1 || portInt > 65535 {
|
||||
return nil, 0, "", fmt.Errorf("%w: %d must be between 1 and 65535", errPortNotValid, portInt)
|
||||
return netip.Addr{}, 0, "", fmt.Errorf("%w: %d must be between 1 and 65535", errPortNotValid, portInt)
|
||||
}
|
||||
port = uint16(portInt)
|
||||
}
|
||||
@@ -127,7 +127,7 @@ func extractRemote(line string) (ip net.IP, port uint16,
|
||||
case "tcp", "udp":
|
||||
protocol = fields[3]
|
||||
default:
|
||||
return nil, 0, "", fmt.Errorf("%w: %s", errProtocolNotSupported, fields[3])
|
||||
return netip.Addr{}, 0, "", fmt.Errorf("%w: %s", errProtocolNotSupported, fields[3])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package extract
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
@@ -22,7 +22,7 @@ func Test_extractDataFromLines(t *testing.T) {
|
||||
"success": {
|
||||
lines: []string{"bla bla", "proto tcp", "remote 1.2.3.4 1194 tcp", "dev tun6"},
|
||||
connection: models.Connection{
|
||||
IP: net.IPv4(1, 2, 3, 4),
|
||||
IP: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||
Port: 1194,
|
||||
Protocol: constants.TCP,
|
||||
},
|
||||
@@ -34,7 +34,7 @@ func Test_extractDataFromLines(t *testing.T) {
|
||||
"only use first values found": {
|
||||
lines: []string{"proto udp", "proto tcp", "remote 1.2.3.4 443 tcp", "remote 5.2.3.4 1194 udp"},
|
||||
connection: models.Connection{
|
||||
IP: net.IPv4(1, 2, 3, 4),
|
||||
IP: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||
Port: 443,
|
||||
Protocol: constants.UDP,
|
||||
},
|
||||
@@ -49,7 +49,7 @@ func Test_extractDataFromLines(t *testing.T) {
|
||||
"default TCP port": {
|
||||
lines: []string{"remote 1.2.3.4", "proto tcp"},
|
||||
connection: models.Connection{
|
||||
IP: net.IPv4(1, 2, 3, 4),
|
||||
IP: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||
Port: 443,
|
||||
Protocol: constants.TCP,
|
||||
},
|
||||
@@ -57,7 +57,7 @@ func Test_extractDataFromLines(t *testing.T) {
|
||||
"default UDP port": {
|
||||
lines: []string{"remote 1.2.3.4", "proto udp"},
|
||||
connection: models.Connection{
|
||||
IP: net.IPv4(1, 2, 3, 4),
|
||||
IP: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||
Port: 1194,
|
||||
Protocol: constants.UDP,
|
||||
},
|
||||
@@ -88,7 +88,7 @@ func Test_extractDataFromLine(t *testing.T) {
|
||||
|
||||
testCases := map[string]struct {
|
||||
line string
|
||||
ip net.IP
|
||||
ip netip.Addr
|
||||
port uint16
|
||||
protocol string
|
||||
isErr error
|
||||
@@ -110,7 +110,7 @@ func Test_extractDataFromLine(t *testing.T) {
|
||||
},
|
||||
"extract remote success": {
|
||||
line: "remote 1.2.3.4 1194 udp",
|
||||
ip: net.IPv4(1, 2, 3, 4),
|
||||
ip: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||
port: 1194,
|
||||
protocol: constants.UDP,
|
||||
},
|
||||
@@ -186,7 +186,7 @@ func Test_extractRemote(t *testing.T) {
|
||||
|
||||
testCases := map[string]struct {
|
||||
line string
|
||||
ip net.IP
|
||||
ip netip.Addr
|
||||
port uint16
|
||||
protocol string
|
||||
err error
|
||||
@@ -205,7 +205,7 @@ func Test_extractRemote(t *testing.T) {
|
||||
},
|
||||
"only IP host": {
|
||||
line: "remote 1.2.3.4",
|
||||
ip: net.IPv4(1, 2, 3, 4),
|
||||
ip: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||
},
|
||||
"port not an integer": {
|
||||
line: "remote 1.2.3.4 bad",
|
||||
@@ -225,7 +225,7 @@ func Test_extractRemote(t *testing.T) {
|
||||
},
|
||||
"IP host and port": {
|
||||
line: "remote 1.2.3.4 8000",
|
||||
ip: net.IPv4(1, 2, 3, 4),
|
||||
ip: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||
port: 8000,
|
||||
},
|
||||
"invalid protocol": {
|
||||
@@ -234,7 +234,7 @@ func Test_extractRemote(t *testing.T) {
|
||||
},
|
||||
"IP host and port and protocol": {
|
||||
line: "remote 1.2.3.4 8000 udp",
|
||||
ip: net.IPv4(1, 2, 3, 4),
|
||||
ip: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||
port: 8000,
|
||||
protocol: constants.UDP,
|
||||
},
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/provider"
|
||||
)
|
||||
|
||||
type StartData struct {
|
||||
PortForwarder provider.PortForwarder
|
||||
Gateway net.IP // needed for PIA
|
||||
Gateway netip.Addr // needed for PIA
|
||||
ServerName string // needed for PIA
|
||||
Interface string // tun0 for example
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/provider/common"
|
||||
)
|
||||
@@ -20,14 +20,14 @@ type apiServer struct {
|
||||
CountryCode string `json:"country_code"`
|
||||
Location string `json:"location"`
|
||||
Continent string `json:"continent"`
|
||||
IPv4In1 net.IP `json:"ip_v4_in1"`
|
||||
IPv4In2 net.IP `json:"ip_v4_in2"`
|
||||
IPv4In3 net.IP `json:"ip_v4_in3"`
|
||||
IPv4In4 net.IP `json:"ip_v4_in4"`
|
||||
IPv6In1 net.IP `json:"ip_v6_in1"`
|
||||
IPv6In2 net.IP `json:"ip_v6_in2"`
|
||||
IPv6In3 net.IP `json:"ip_v6_in3"`
|
||||
IPv6In4 net.IP `json:"ip_v6_in4"`
|
||||
IPv4In1 netip.Addr `json:"ip_v4_in1"`
|
||||
IPv4In2 netip.Addr `json:"ip_v4_in2"`
|
||||
IPv4In3 netip.Addr `json:"ip_v4_in3"`
|
||||
IPv4In4 netip.Addr `json:"ip_v4_in4"`
|
||||
IPv6In1 netip.Addr `json:"ip_v6_in1"`
|
||||
IPv6In2 netip.Addr `json:"ip_v6_in2"`
|
||||
IPv6In3 netip.Addr `json:"ip_v6_in3"`
|
||||
IPv6In4 netip.Addr `json:"ip_v6_in4"`
|
||||
Health string `json:"health"`
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package updater
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -57,12 +57,12 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
||||
baseWireguardServer.WgPubKey = "PyLCXAQT8KkM4T+dUsOQfn+Ub3pGxfGlxkIApuig+hk="
|
||||
|
||||
ipv4WireguadServer := baseWireguardServer
|
||||
ipv4WireguadServer.IPs = []net.IP{apiServer.IPv4In1}
|
||||
ipv4WireguadServer.IPs = []netip.Addr{apiServer.IPv4In1}
|
||||
ipv4WireguadServer.Hostname = apiServer.CountryCode + ".vpn.airdns.org"
|
||||
servers = append(servers, ipv4WireguadServer)
|
||||
|
||||
ipv6WireguadServer := baseWireguardServer
|
||||
ipv6WireguadServer.IPs = []net.IP{apiServer.IPv6In1}
|
||||
ipv6WireguadServer.IPs = []netip.Addr{apiServer.IPv6In1}
|
||||
ipv6WireguadServer.Hostname = apiServer.CountryCode + ".ipv6.vpn.airdns.org"
|
||||
servers = append(servers, ipv6WireguadServer)
|
||||
|
||||
@@ -74,22 +74,22 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
||||
// Ignore IPs 1 and 2 since tls-crypt is superior to tls-auth really.
|
||||
|
||||
ipv4In3OpenVPNServer := baseOpenVPNServer
|
||||
ipv4In3OpenVPNServer.IPs = []net.IP{apiServer.IPv4In3}
|
||||
ipv4In3OpenVPNServer.IPs = []netip.Addr{apiServer.IPv4In3}
|
||||
ipv4In3OpenVPNServer.Hostname = apiServer.CountryCode + "3.vpn.airdns.org"
|
||||
servers = append(servers, ipv4In3OpenVPNServer)
|
||||
|
||||
ipv6In3OpenVPNServer := baseOpenVPNServer
|
||||
ipv6In3OpenVPNServer.IPs = []net.IP{apiServer.IPv6In3}
|
||||
ipv6In3OpenVPNServer.IPs = []netip.Addr{apiServer.IPv6In3}
|
||||
ipv6In3OpenVPNServer.Hostname = apiServer.CountryCode + "3.ipv6.vpn.airdns.org"
|
||||
servers = append(servers, ipv6In3OpenVPNServer)
|
||||
|
||||
ipv4In4OpenVPNServer := baseOpenVPNServer
|
||||
ipv4In4OpenVPNServer.IPs = []net.IP{apiServer.IPv4In4}
|
||||
ipv4In4OpenVPNServer.IPs = []netip.Addr{apiServer.IPv4In4}
|
||||
ipv4In4OpenVPNServer.Hostname = apiServer.CountryCode + "4.vpn.airdns.org"
|
||||
servers = append(servers, ipv4In4OpenVPNServer)
|
||||
|
||||
ipv6In4OpenVPNServer := baseOpenVPNServer
|
||||
ipv6In4OpenVPNServer.IPs = []net.IP{apiServer.IPv6In4}
|
||||
ipv6In4OpenVPNServer.IPs = []netip.Addr{apiServer.IPv6In4}
|
||||
ipv6In4OpenVPNServer.Hostname = apiServer.CountryCode + "4.ipv6.vpn.airdns.org"
|
||||
servers = append(servers, ipv6In4OpenVPNServer)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ package common
|
||||
|
||||
import (
|
||||
context "context"
|
||||
net "net"
|
||||
netip "net/netip"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
@@ -39,10 +39,10 @@ func (m *MockParallelResolver) EXPECT() *MockParallelResolverMockRecorder {
|
||||
}
|
||||
|
||||
// Resolve mocks base method.
|
||||
func (m *MockParallelResolver) Resolve(arg0 context.Context, arg1 resolver.ParallelSettings) (map[string][]net.IP, []string, error) {
|
||||
func (m *MockParallelResolver) Resolve(arg0 context.Context, arg1 resolver.ParallelSettings) (map[string][]netip.Addr, []string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Resolve", arg0, arg1)
|
||||
ret0, _ := ret[0].(map[string][]net.IP)
|
||||
ret0, _ := ret[0].(map[string][]netip.Addr)
|
||||
ret1, _ := ret[1].([]string)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
|
||||
@@ -2,4 +2,5 @@ package common
|
||||
|
||||
// Exceptionally, these mocks are exported since they are used by all
|
||||
// provider subpackages tests, and it reduces test code duplication a lot.
|
||||
// Note mocks.go might need to be removed before re-generating it.
|
||||
//go:generate mockgen -destination=mocks.go -package $GOPACKAGE . ParallelResolver,Storage,Unzipper,Warner
|
||||
|
||||
@@ -3,7 +3,7 @@ package common
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/publicip/ipinfo"
|
||||
@@ -21,7 +21,7 @@ type Fetcher interface {
|
||||
|
||||
type ParallelResolver interface {
|
||||
Resolve(ctx context.Context, settings resolver.ParallelSettings) (
|
||||
hostToIPs map[string][]net.IP, warnings []string, err error)
|
||||
hostToIPs map[string][]netip.Addr, warnings []string, err error)
|
||||
}
|
||||
|
||||
type Unzipper interface {
|
||||
@@ -34,5 +34,5 @@ type Warner interface {
|
||||
}
|
||||
|
||||
type IPFetcher interface {
|
||||
FetchMultiInfo(ctx context.Context, ips []net.IP) (data []ipinfo.Response, err error)
|
||||
FetchMultiInfo(ctx context.Context, ips []netip.Addr) (data []ipinfo.Response, err error)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package custom
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||
@@ -46,7 +46,7 @@ func Test_modifyConfig(t *testing.T) {
|
||||
Verbosity: intPtr(0),
|
||||
}.WithDefaults(providers.Custom),
|
||||
connection: models.Connection{
|
||||
IP: net.IPv4(1, 2, 3, 4),
|
||||
IP: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||
Port: 1194,
|
||||
Protocol: constants.UDP,
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
@@ -47,7 +47,7 @@ func (hts hostToServer) hostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
|
||||
@@ -3,7 +3,7 @@ package expressvpn
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
@@ -41,7 +41,7 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
},
|
||||
"default OpenVPN TCP port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
OpenVPN: settings.OpenVPNSelection{
|
||||
@@ -52,7 +52,7 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
},
|
||||
"default OpenVPN UDP port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
OpenVPN: settings.OpenVPNSelection{
|
||||
@@ -61,14 +61,14 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 1195,
|
||||
Protocol: constants.UDP,
|
||||
},
|
||||
},
|
||||
"default Wireguard port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
VPN: vpn.Wireguard,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -33,7 +33,7 @@ func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"sort"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
@@ -38,7 +38,7 @@ func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
@@ -134,17 +134,17 @@ func Test_hostToServer_adaptWithIPs(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
initialHTS hostToServer
|
||||
hostToIPs map[string][]net.IP
|
||||
hostToIPs map[string][]netip.Addr
|
||||
expectedHTS hostToServer
|
||||
}{
|
||||
"create server": {
|
||||
initialHTS: hostToServer{},
|
||||
hostToIPs: map[string][]net.IP{
|
||||
"A": {{1, 2, 3, 4}},
|
||||
hostToIPs: map[string][]netip.Addr{
|
||||
"A": {netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
},
|
||||
expectedHTS: hostToServer{
|
||||
"A": models.Server{
|
||||
IPs: []net.IP{{1, 2, 3, 4}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -154,13 +154,13 @@ func Test_hostToServer_adaptWithIPs(t *testing.T) {
|
||||
Country: "country",
|
||||
},
|
||||
},
|
||||
hostToIPs: map[string][]net.IP{
|
||||
"A": {{1, 2, 3, 4}},
|
||||
hostToIPs: map[string][]netip.Addr{
|
||||
"A": {netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
},
|
||||
expectedHTS: hostToServer{
|
||||
"A": models.Server{
|
||||
Country: "country",
|
||||
IPs: []net.IP{{1, 2, 3, 4}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -170,7 +170,7 @@ func Test_hostToServer_adaptWithIPs(t *testing.T) {
|
||||
Country: "country",
|
||||
},
|
||||
},
|
||||
hostToIPs: map[string][]net.IP{},
|
||||
hostToIPs: map[string][]netip.Addr{},
|
||||
expectedHTS: hostToServer{},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package updater
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -32,7 +32,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
||||
// Resolution
|
||||
expectResolve bool
|
||||
resolverSettings resolver.ParallelSettings
|
||||
hostToIPs map[string][]net.IP
|
||||
hostToIPs map[string][]netip.Addr
|
||||
resolveWarnings []string
|
||||
resolveErr error
|
||||
|
||||
@@ -161,9 +161,9 @@ func Test_Updater_GetServers(t *testing.T) {
|
||||
SortIPs: true,
|
||||
},
|
||||
},
|
||||
hostToIPs: map[string][]net.IP{
|
||||
"hosta": {{1, 1, 1, 1}, {2, 2, 2, 2}},
|
||||
"hostb": {{3, 3, 3, 3}, {4, 4, 4, 4}},
|
||||
hostToIPs: map[string][]netip.Addr{
|
||||
"hosta": {netip.AddrFrom4([4]byte{1, 1, 1, 1}), netip.AddrFrom4([4]byte{2, 2, 2, 2})},
|
||||
"hostb": {netip.AddrFrom4([4]byte{3, 3, 3, 3}), netip.AddrFrom4([4]byte{4, 4, 4, 4})},
|
||||
},
|
||||
resolveWarnings: []string{"resolve warning"},
|
||||
servers: []models.Server{
|
||||
@@ -173,7 +173,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
||||
City: "City A",
|
||||
Hostname: "hosta",
|
||||
UDP: true,
|
||||
IPs: []net.IP{{1, 1, 1, 1}, {2, 2, 2, 2}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1}), netip.AddrFrom4([4]byte{2, 2, 2, 2})},
|
||||
},
|
||||
{
|
||||
VPN: vpn.OpenVPN,
|
||||
@@ -181,7 +181,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
||||
City: "City B",
|
||||
Hostname: "hostb",
|
||||
UDP: true,
|
||||
IPs: []net.IP{{3, 3, 3, 3}, {4, 4, 4, 4}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{3, 3, 3, 3}), netip.AddrFrom4([4]byte{4, 4, 4, 4})},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -3,8 +3,8 @@ package ivpn
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
@@ -41,7 +41,7 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
},
|
||||
"default OpenVPN TCP port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
OpenVPN: settings.OpenVPNSelection{
|
||||
@@ -50,14 +50,14 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 443,
|
||||
Protocol: constants.TCP,
|
||||
},
|
||||
},
|
||||
"default OpenVPN UDP port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
OpenVPN: settings.OpenVPNSelection{
|
||||
@@ -66,21 +66,21 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 1194,
|
||||
Protocol: constants.UDP,
|
||||
},
|
||||
},
|
||||
"default Wireguard port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}, WgPubKey: "x"},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}, WgPubKey: "x"},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
VPN: vpn.Wireguard,
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.Wireguard,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 58237,
|
||||
Protocol: constants.UDP,
|
||||
PubKey: "x",
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -36,7 +36,7 @@ func Test_Updater_GetServers(t *testing.T) {
|
||||
// Resolution
|
||||
expectResolve bool
|
||||
resolveSettings resolver.ParallelSettings
|
||||
hostToIPs map[string][]net.IP
|
||||
hostToIPs map[string][]netip.Addr
|
||||
resolveWarnings []string
|
||||
resolveErr error
|
||||
|
||||
@@ -109,24 +109,24 @@ func Test_Updater_GetServers(t *testing.T) {
|
||||
SortIPs: true,
|
||||
},
|
||||
},
|
||||
hostToIPs: map[string][]net.IP{
|
||||
"hosta": {{1, 1, 1, 1}, {2, 2, 2, 2}},
|
||||
"hostb": {{3, 3, 3, 3}, {4, 4, 4, 4}},
|
||||
"hostc": {{5, 5, 5, 5}, {6, 6, 6, 6}},
|
||||
hostToIPs: map[string][]netip.Addr{
|
||||
"hosta": {netip.AddrFrom4([4]byte{1, 1, 1, 1}), netip.AddrFrom4([4]byte{2, 2, 2, 2})},
|
||||
"hostb": {netip.AddrFrom4([4]byte{3, 3, 3, 3}), netip.AddrFrom4([4]byte{4, 4, 4, 4})},
|
||||
"hostc": {netip.AddrFrom4([4]byte{5, 5, 5, 5}), netip.AddrFrom4([4]byte{6, 6, 6, 6})},
|
||||
},
|
||||
resolveWarnings: []string{"resolve warning"},
|
||||
servers: []models.Server{
|
||||
{VPN: vpn.OpenVPN, Country: "Country1",
|
||||
City: "City A", Hostname: "hosta", TCP: true, UDP: true,
|
||||
IPs: []net.IP{{1, 1, 1, 1}, {2, 2, 2, 2}}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1}), netip.AddrFrom4([4]byte{2, 2, 2, 2})}},
|
||||
{VPN: vpn.OpenVPN, Country: "Country2",
|
||||
City: "City B", Hostname: "hostb", TCP: true, UDP: true,
|
||||
IPs: []net.IP{{3, 3, 3, 3}, {4, 4, 4, 4}}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{3, 3, 3, 3}), netip.AddrFrom4([4]byte{4, 4, 4, 4})}},
|
||||
{VPN: vpn.Wireguard,
|
||||
Country: "Country3", City: "City C",
|
||||
Hostname: "hostc",
|
||||
WgPubKey: "xyz",
|
||||
IPs: []net.IP{{5, 5, 5, 5}, {6, 6, 6, 6}}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{5, 5, 5, 5}), netip.AddrFrom4([4]byte{6, 6, 6, 6})}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package mullvad
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
@@ -41,7 +41,7 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
},
|
||||
"default OpenVPN TCP port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
OpenVPN: settings.OpenVPNSelection{
|
||||
@@ -50,14 +50,14 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 443,
|
||||
Protocol: constants.TCP,
|
||||
},
|
||||
},
|
||||
"default OpenVPN UDP port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
OpenVPN: settings.OpenVPNSelection{
|
||||
@@ -66,21 +66,21 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 1194,
|
||||
Protocol: constants.UDP,
|
||||
},
|
||||
},
|
||||
"default Wireguard port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}, WgPubKey: "x"},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}, WgPubKey: "x"},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
VPN: vpn.Wireguard,
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.Wireguard,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 51820,
|
||||
Protocol: constants.UDP,
|
||||
PubKey: "x",
|
||||
|
||||
@@ -3,7 +3,7 @@ package updater
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
@@ -14,8 +14,8 @@ type hostToServer map[string]models.Server
|
||||
|
||||
var (
|
||||
ErrNoIP = errors.New("no IP address for VPN server")
|
||||
ErrParseIPv4 = errors.New("cannot parse IPv4 address")
|
||||
ErrParseIPv6 = errors.New("cannot parse IPv6 address")
|
||||
ErrIPIsNotV4 = errors.New("IP address is not IPv4")
|
||||
ErrIPIsNotV6 = errors.New("IP address is not IPv6")
|
||||
ErrVPNTypeNotSupported = errors.New("VPN type not supported")
|
||||
)
|
||||
|
||||
@@ -48,17 +48,21 @@ func (hts hostToServer) add(data serverData) (err error) {
|
||||
}
|
||||
|
||||
if data.IPv4 != "" {
|
||||
ipv4 := net.ParseIP(data.IPv4)
|
||||
if ipv4 == nil || ipv4.To4() == nil {
|
||||
return fmt.Errorf("%w: %s", ErrParseIPv4, data.IPv4)
|
||||
ipv4, err := netip.ParseAddr(data.IPv4)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing IPv4 address: %w", err)
|
||||
} else if !ipv4.Is4() {
|
||||
return fmt.Errorf("%w: %s", ErrIPIsNotV4, data.IPv4)
|
||||
}
|
||||
server.IPs = append(server.IPs, ipv4)
|
||||
}
|
||||
|
||||
if data.IPv6 != "" {
|
||||
ipv6 := net.ParseIP(data.IPv6)
|
||||
if ipv6 == nil || ipv6.To4() != nil {
|
||||
return fmt.Errorf("%w: %s", ErrParseIPv6, data.IPv6)
|
||||
ipv6, err := netip.ParseAddr(data.IPv6)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing IPv6 address: %w", err)
|
||||
} else if !ipv6.Is6() {
|
||||
return fmt.Errorf("%w: %s", ErrIPIsNotV6, data.IPv6)
|
||||
}
|
||||
server.IPs = append(server.IPs, ipv6)
|
||||
}
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sort"
|
||||
)
|
||||
|
||||
func uniqueSortedIPs(ips []net.IP) []net.IP {
|
||||
func uniqueSortedIPs(ips []netip.Addr) []netip.Addr {
|
||||
uniqueIPs := make(map[string]struct{}, len(ips))
|
||||
for _, ip := range ips {
|
||||
key := ip.String()
|
||||
uniqueIPs[key] = struct{}{}
|
||||
}
|
||||
|
||||
ips = make([]net.IP, 0, len(uniqueIPs))
|
||||
ips = make([]netip.Addr, 0, len(uniqueIPs))
|
||||
for key := range uniqueIPs {
|
||||
ip := net.ParseIP(key)
|
||||
if ipv4 := ip.To4(); ipv4 != nil {
|
||||
ip = ipv4
|
||||
ip, err := netip.ParseAddr(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if ip.Is4In6() {
|
||||
ip = netip.AddrFrom4(ip.As4())
|
||||
}
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
|
||||
sort.Slice(ips, func(i, j int) bool {
|
||||
return bytes.Compare(ips[i], ips[j]) < 0
|
||||
return ips[i].Compare(ips[j]) < 0
|
||||
})
|
||||
|
||||
return ips
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -10,24 +10,24 @@ import (
|
||||
func Test_uniqueSortedIPs(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
inputIPs []net.IP
|
||||
outputIPs []net.IP
|
||||
inputIPs []netip.Addr
|
||||
outputIPs []netip.Addr
|
||||
}{
|
||||
"nil": {
|
||||
inputIPs: nil,
|
||||
outputIPs: []net.IP{},
|
||||
outputIPs: []netip.Addr{},
|
||||
},
|
||||
"empty": {
|
||||
inputIPs: []net.IP{},
|
||||
outputIPs: []net.IP{},
|
||||
inputIPs: []netip.Addr{},
|
||||
outputIPs: []netip.Addr{},
|
||||
},
|
||||
"single IPv4": {
|
||||
inputIPs: []net.IP{{1, 1, 1, 1}},
|
||||
outputIPs: []net.IP{{1, 1, 1, 1}},
|
||||
inputIPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})},
|
||||
outputIPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})},
|
||||
},
|
||||
"two IPv4s": {
|
||||
inputIPs: []net.IP{{1, 1, 2, 1}, {1, 1, 1, 1}},
|
||||
outputIPs: []net.IP{{1, 1, 1, 1}, {1, 1, 2, 1}},
|
||||
inputIPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 2, 1}), netip.AddrFrom4([4]byte{1, 1, 1, 1})},
|
||||
outputIPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1}), netip.AddrFrom4([4]byte{1, 1, 2, 1})},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
|
||||
@@ -2,15 +2,16 @@ package updater
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
func parseIPv4(s string) (ipv4 net.IP, err error) {
|
||||
ip := net.ParseIP(s)
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("%w: %q", ErrParseIP, s)
|
||||
} else if ip.To4() == nil {
|
||||
return nil, fmt.Errorf("%w: %s", ErrNotIPv4, ip)
|
||||
func parseIPv4(s string) (ipv4 netip.Addr, err error) {
|
||||
ipv4, err = netip.ParseAddr(s)
|
||||
if err != nil {
|
||||
return ipv4, err
|
||||
}
|
||||
return ip, nil
|
||||
if !ipv4.Is4() {
|
||||
return ipv4, fmt.Errorf("%w: %s", ErrNotIPv4, ipv4)
|
||||
}
|
||||
return ipv4, nil
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sort"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrParseIP = errors.New("cannot parse IP address")
|
||||
ErrNotIPv4 = errors.New("IP address is not IPv4")
|
||||
)
|
||||
|
||||
@@ -47,7 +46,7 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
||||
Region: jsonServer.Country,
|
||||
Hostname: jsonServer.Domain,
|
||||
Number: number,
|
||||
IPs: []net.IP{ip},
|
||||
IPs: []netip.Addr{ip},
|
||||
TCP: jsonServer.Features.TCP,
|
||||
UDP: jsonServer.Features.UDP,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
type cityToServer map[string]models.Server
|
||||
|
||||
func (cts cityToServer) add(city string, ips []net.IP) {
|
||||
func (cts cityToServer) add(city string, ips []netip.Addr) {
|
||||
server, ok := cts[city]
|
||||
if !ok {
|
||||
server.VPN = vpn.OpenVPN
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -28,7 +28,7 @@ func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
|
||||
@@ -2,7 +2,7 @@ package updater
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/provider/common"
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
func setLocationInfo(ctx context.Context, fetcher common.IPFetcher, servers []models.Server) (err error) {
|
||||
// Get public IP address information
|
||||
ipsToGetInfo := make([]net.IP, 0, len(servers))
|
||||
ipsToGetInfo := make([]netip.Addr, 0, len(servers))
|
||||
for _, server := range servers {
|
||||
ipsToGetInfo = append(ipsToGetInfo, server.IPs...)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
@@ -22,13 +23,13 @@ import (
|
||||
|
||||
var (
|
||||
ErrServerNameNotFound = errors.New("server name not found in servers")
|
||||
ErrGatewayIPIsNil = errors.New("gateway IP address is nil")
|
||||
ErrGatewayIPIsNotValid = errors.New("gateway IP address is not valid")
|
||||
ErrServerNameEmpty = errors.New("server name is empty")
|
||||
)
|
||||
|
||||
// PortForward obtains a VPN server side port forwarded from PIA.
|
||||
func (p *Provider) PortForward(ctx context.Context, client *http.Client,
|
||||
logger utils.Logger, gateway net.IP, serverName string) (
|
||||
logger utils.Logger, gateway netip.Addr, serverName string) (
|
||||
port uint16, err error) {
|
||||
server, ok := p.storage.GetServerByName(providers.PrivateInternetAccess, serverName)
|
||||
if !ok {
|
||||
@@ -40,8 +41,8 @@ func (p *Provider) PortForward(ctx context.Context, client *http.Client,
|
||||
" (region " + server.Region + ") does not support port forwarding")
|
||||
return 0, nil
|
||||
}
|
||||
if gateway == nil {
|
||||
return 0, ErrGatewayIPIsNil
|
||||
if !gateway.IsValid() {
|
||||
return 0, fmt.Errorf("%w: %s", ErrGatewayIPIsNotValid, gateway)
|
||||
} else if serverName == "" {
|
||||
return 0, ErrServerNameEmpty
|
||||
}
|
||||
@@ -91,7 +92,7 @@ var (
|
||||
)
|
||||
|
||||
func (p *Provider) KeepPortForward(ctx context.Context,
|
||||
gateway net.IP, serverName string) (err error) {
|
||||
gateway netip.Addr, serverName string) (err error) {
|
||||
privateIPClient, err := newHTTPClient(serverName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating custom HTTP client: %w", err)
|
||||
@@ -132,7 +133,7 @@ func (p *Provider) KeepPortForward(ctx context.Context,
|
||||
}
|
||||
|
||||
func refreshPIAPortForwardData(ctx context.Context, client, privateIPClient *http.Client,
|
||||
gateway net.IP, portForwardPath, authFilePath string) (data piaPortForwardData, err error) {
|
||||
gateway netip.Addr, portForwardPath, authFilePath string) (data piaPortForwardData, err error) {
|
||||
data.Token, err = fetchToken(ctx, client, authFilePath)
|
||||
if err != nil {
|
||||
return data, fmt.Errorf("fetching token: %w", err)
|
||||
@@ -314,7 +315,7 @@ func getOpenvpnCredentials(authFilePath string) (
|
||||
return username, password, nil
|
||||
}
|
||||
|
||||
func fetchPortForwardData(ctx context.Context, client *http.Client, gateway net.IP, token string) (
|
||||
func fetchPortForwardData(ctx context.Context, client *http.Client, gateway netip.Addr, token string) (
|
||||
port uint16, signature string, expiration time.Time, err error) {
|
||||
errSubstitutions := map[string]string{url.QueryEscape(token): "<token>"}
|
||||
|
||||
@@ -368,7 +369,7 @@ var (
|
||||
ErrBadResponse = errors.New("bad response received")
|
||||
)
|
||||
|
||||
func bindPort(ctx context.Context, client *http.Client, gateway net.IP, data piaPortForwardData) (err error) {
|
||||
func bindPort(ctx context.Context, client *http.Client, gateway netip.Addr, data piaPortForwardData) (err error) {
|
||||
payload, err := packPayload(data.Port, data.Token, data.Expiration)
|
||||
if err != nil {
|
||||
return fmt.Errorf("serializing payload: %w", err)
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -31,7 +31,7 @@ type regionData struct {
|
||||
}
|
||||
|
||||
type serverData struct {
|
||||
IP net.IP `json:"ip"`
|
||||
IP netip.Addr `json:"ip"`
|
||||
CN string `json:"cn"`
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
type nameToServer map[string]models.Server
|
||||
|
||||
func (nts nameToServer) add(name, hostname, region string,
|
||||
tcp, udp, portForward bool, ip net.IP) (change bool) {
|
||||
tcp, udp, portForward bool, ip netip.Addr) (change bool) {
|
||||
server, ok := nts[name]
|
||||
if !ok {
|
||||
change = true
|
||||
@@ -32,7 +32,7 @@ func (nts nameToServer) add(name, hostname, region string,
|
||||
|
||||
ipFound := false
|
||||
for _, existingIP := range server.IPs {
|
||||
if ip.Equal(existingIP) {
|
||||
if ip == existingIP {
|
||||
ipFound = true
|
||||
break
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -32,7 +32,7 @@ func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -26,8 +26,8 @@ type logicalServer struct {
|
||||
}
|
||||
|
||||
type physicalServer struct {
|
||||
EntryIP net.IP
|
||||
ExitIP net.IP
|
||||
EntryIP netip.Addr
|
||||
ExitIP netip.Addr
|
||||
Domain string
|
||||
Status uint8
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
type ipToServer map[string]models.Server
|
||||
|
||||
func (its ipToServer) add(country, region, city, name, hostname string,
|
||||
free bool, entryIP net.IP) {
|
||||
free bool, entryIP netip.Addr) {
|
||||
key := entryIP.String()
|
||||
|
||||
server, ok := its[key]
|
||||
@@ -27,7 +27,7 @@ func (its ipToServer) add(country, region, city, name, hostname string,
|
||||
server.Free = free
|
||||
server.UDP = true
|
||||
server.TCP = true
|
||||
server.IPs = []net.IP{entryIP}
|
||||
server.IPs = []netip.Addr{entryIP}
|
||||
its[key] = server
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -22,8 +22,8 @@ type Provider interface {
|
||||
|
||||
type PortForwarder interface {
|
||||
PortForward(ctx context.Context, client *http.Client,
|
||||
logger utils.Logger, gateway net.IP, serverName string) (
|
||||
logger utils.Logger, gateway netip.Addr, serverName string) (
|
||||
port uint16, err error)
|
||||
KeepPortForward(ctx context.Context, gateway net.IP,
|
||||
KeepPortForward(ctx context.Context, gateway netip.Addr,
|
||||
serverName string) (err error)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -32,7 +32,7 @@ func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
|
||||
@@ -3,7 +3,7 @@ package updater
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -76,7 +76,7 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
||||
servers = hts.toServersSlice()
|
||||
|
||||
// Get public IP address information
|
||||
ipsToGetInfo := make([]net.IP, len(servers))
|
||||
ipsToGetInfo := make([]netip.Addr, len(servers))
|
||||
for i := range servers {
|
||||
ipsToGetInfo[i] = servers[i].IPs[0]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -75,7 +75,7 @@ func (hts hostToServers) toHostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServers) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServers) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
servers := hts[host]
|
||||
for i := range servers {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
type hostToServer map[string]models.Server
|
||||
|
||||
func (hts hostToServer) add(host, country, city string,
|
||||
tcp, udp bool, ips []net.IP) {
|
||||
tcp, udp bool, ips []netip.Addr) {
|
||||
server, ok := hts[host]
|
||||
if !ok {
|
||||
server.VPN = vpn.OpenVPN
|
||||
@@ -39,7 +39,7 @@ func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
|
||||
@@ -48,7 +48,7 @@ func GetConnection(provider string,
|
||||
connections := make([]models.Connection, 0, len(servers))
|
||||
for _, server := range servers {
|
||||
for _, ip := range server.IPs {
|
||||
if !ipv6Supported && ip.To4() == nil {
|
||||
if !ipv6Supported && ip.Is6() {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package utils
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
@@ -58,7 +58,7 @@ func Test_GetConnection(t *testing.T) {
|
||||
{
|
||||
VPN: vpn.OpenVPN,
|
||||
UDP: true,
|
||||
IPs: []net.IP{net.IPv4(1, 1, 1, 1)},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})},
|
||||
Hostname: "name",
|
||||
},
|
||||
},
|
||||
@@ -68,7 +68,7 @@ func Test_GetConnection(t *testing.T) {
|
||||
randSource: rand.NewSource(0),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Protocol: constants.UDP,
|
||||
Port: 1194,
|
||||
Hostname: "name",
|
||||
@@ -79,7 +79,7 @@ func Test_GetConnection(t *testing.T) {
|
||||
{
|
||||
VPN: vpn.OpenVPN,
|
||||
UDP: true,
|
||||
IPs: []net.IP{net.IPv4(1, 1, 1, 1)},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})},
|
||||
Hostname: "hostname",
|
||||
OvpnX509: "x509",
|
||||
},
|
||||
@@ -90,7 +90,7 @@ func Test_GetConnection(t *testing.T) {
|
||||
randSource: rand.NewSource(0),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Protocol: constants.UDP,
|
||||
Port: 1194,
|
||||
Hostname: "x509",
|
||||
@@ -101,14 +101,14 @@ func Test_GetConnection(t *testing.T) {
|
||||
{
|
||||
VPN: vpn.OpenVPN,
|
||||
UDP: true,
|
||||
IPs: []net.IP{
|
||||
net.IPv4(1, 1, 1, 1),
|
||||
IPs: []netip.Addr{
|
||||
netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
// All IPv6 is ignored
|
||||
net.IPv6zero,
|
||||
net.IPv6zero,
|
||||
net.IPv6zero,
|
||||
net.IPv6zero,
|
||||
net.IPv6zero,
|
||||
netip.IPv6Unspecified(),
|
||||
netip.IPv6Unspecified(),
|
||||
netip.IPv6Unspecified(),
|
||||
netip.IPv6Unspecified(),
|
||||
netip.IPv6Unspecified(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -118,7 +118,7 @@ func Test_GetConnection(t *testing.T) {
|
||||
randSource: rand.NewSource(0),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Protocol: constants.UDP,
|
||||
Port: 1194,
|
||||
},
|
||||
@@ -128,9 +128,9 @@ func Test_GetConnection(t *testing.T) {
|
||||
{
|
||||
VPN: vpn.OpenVPN,
|
||||
UDP: true,
|
||||
IPs: []net.IP{
|
||||
net.IPv6zero,
|
||||
net.IPv4(1, 1, 1, 1),
|
||||
IPs: []netip.Addr{
|
||||
netip.IPv6Unspecified(),
|
||||
netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -141,7 +141,7 @@ func Test_GetConnection(t *testing.T) {
|
||||
randSource: rand.NewSource(0),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv6zero,
|
||||
IP: netip.IPv6Unspecified(),
|
||||
Protocol: constants.UDP,
|
||||
Port: 1194,
|
||||
},
|
||||
@@ -151,21 +151,21 @@ func Test_GetConnection(t *testing.T) {
|
||||
{
|
||||
VPN: vpn.OpenVPN,
|
||||
UDP: true,
|
||||
IPs: []net.IP{net.IPv4(1, 1, 1, 1)},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})},
|
||||
OvpnX509: "ovpnx509",
|
||||
},
|
||||
{
|
||||
VPN: vpn.Wireguard,
|
||||
UDP: true,
|
||||
IPs: []net.IP{net.IPv4(2, 2, 2, 2)},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{2, 2, 2, 2})},
|
||||
OvpnX509: "ovpnx509",
|
||||
},
|
||||
{
|
||||
VPN: vpn.OpenVPN,
|
||||
UDP: true,
|
||||
IPs: []net.IP{
|
||||
net.IPv4(3, 3, 3, 3),
|
||||
{1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, // ipv6 ignored
|
||||
IPs: []netip.Addr{
|
||||
netip.AddrFrom4([4]byte{3, 3, 3, 3}),
|
||||
netip.AddrFrom16([16]byte{1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}), // ipv6 ignored
|
||||
},
|
||||
Hostname: "hostname",
|
||||
},
|
||||
@@ -176,7 +176,7 @@ func Test_GetConnection(t *testing.T) {
|
||||
randSource: rand.NewSource(0),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Protocol: constants.UDP,
|
||||
Port: 1194,
|
||||
Hostname: "ovpnx509",
|
||||
|
||||
@@ -4,15 +4,15 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
type NoPortForwarder interface {
|
||||
PortForward(ctx context.Context, client *http.Client,
|
||||
logger Logger, gateway net.IP, serverName string) (
|
||||
logger Logger, gateway netip.Addr, serverName string) (
|
||||
port uint16, err error)
|
||||
KeepPortForward(ctx context.Context, gateway net.IP,
|
||||
KeepPortForward(ctx context.Context, gateway netip.Addr,
|
||||
serverName string) (err error)
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ func NewNoPortForwarding(providerName string) *NoPortForwarding {
|
||||
var ErrPortForwardingNotSupported = errors.New("custom port forwarding obtention is not supported")
|
||||
|
||||
func (n *NoPortForwarding) PortForward(context.Context, *http.Client,
|
||||
Logger, net.IP, string) (port uint16, err error) {
|
||||
Logger, netip.Addr, string) (port uint16, err error) {
|
||||
return 0, fmt.Errorf("%w: for %s", ErrPortForwardingNotSupported, n.providerName)
|
||||
}
|
||||
|
||||
func (n *NoPortForwarding) KeepPortForward(context.Context, net.IP, string) (err error) {
|
||||
func (n *NoPortForwarding) KeepPortForward(context.Context, netip.Addr, string) (err error) {
|
||||
return fmt.Errorf("%w: for %s", ErrPortForwardingNotSupported, n.providerName)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
@@ -25,13 +25,15 @@ func pickConnection(connections []models.Connection,
|
||||
return connection, ErrNoConnectionToPickFrom
|
||||
}
|
||||
|
||||
if len(selection.TargetIP) > 0 && selection.VPN == vpn.Wireguard {
|
||||
targetIPSet := selection.TargetIP.IsValid() && !selection.TargetIP.IsUnspecified()
|
||||
|
||||
if targetIPSet && selection.VPN == vpn.Wireguard {
|
||||
// we need the right public key
|
||||
return getTargetIPConnection(connections, selection.TargetIP)
|
||||
}
|
||||
|
||||
connection = pickRandomConnection(connections, randSource)
|
||||
if len(selection.TargetIP) > 0 {
|
||||
if targetIPSet {
|
||||
connection.IP = selection.TargetIP
|
||||
}
|
||||
|
||||
@@ -46,9 +48,9 @@ func pickRandomConnection(connections []models.Connection,
|
||||
var errTargetIPNotFound = errors.New("target IP address not found")
|
||||
|
||||
func getTargetIPConnection(connections []models.Connection,
|
||||
targetIP net.IP) (connection models.Connection, err error) {
|
||||
targetIP netip.Addr) (connection models.Connection, err error) {
|
||||
for _, connection := range connections {
|
||||
if targetIP.Equal(connection.IP) {
|
||||
if targetIP == connection.IP {
|
||||
return connection, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,7 @@ func BuildWireguardSettings(connection models.Connection,
|
||||
settings.RulePriority = rulePriority
|
||||
|
||||
settings.Endpoint = new(net.UDPAddr)
|
||||
settings.Endpoint.IP = make(net.IP, len(connection.IP))
|
||||
copy(settings.Endpoint.IP, connection.IP)
|
||||
settings.Endpoint.IP = connection.IP.AsSlice()
|
||||
settings.Endpoint.Port = int(connection.Port)
|
||||
|
||||
settings.Addresses = make([]netip.Prefix, 0, len(userSettings.Addresses))
|
||||
|
||||
@@ -24,7 +24,7 @@ func Test_BuildWireguardSettings(t *testing.T) {
|
||||
}{
|
||||
"some settings": {
|
||||
connection: models.Connection{
|
||||
IP: net.IPv4(1, 2, 3, 4),
|
||||
IP: netip.AddrFrom4([4]byte{1, 2, 3, 4}),
|
||||
Port: 51821,
|
||||
PubKey: "public",
|
||||
},
|
||||
@@ -44,7 +44,7 @@ func Test_BuildWireguardSettings(t *testing.T) {
|
||||
PublicKey: "public",
|
||||
PreSharedKey: "pre-shared",
|
||||
Endpoint: &net.UDPAddr{
|
||||
IP: net.IPv4(1, 2, 3, 4),
|
||||
IP: net.IP{1, 2, 3, 4},
|
||||
Port: 51821,
|
||||
},
|
||||
Addresses: []netip.Prefix{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
@@ -16,7 +16,7 @@ func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
@@ -16,7 +16,7 @@ func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -33,7 +33,7 @@ func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]netip.Addr) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
|
||||
@@ -3,7 +3,7 @@ package wevpn
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
@@ -41,7 +41,7 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
},
|
||||
"default OpenVPN TCP port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
OpenVPN: settings.OpenVPNSelection{
|
||||
@@ -50,14 +50,14 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 1195,
|
||||
Protocol: constants.TCP,
|
||||
},
|
||||
},
|
||||
"default OpenVPN UDP port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
OpenVPN: settings.OpenVPNSelection{
|
||||
@@ -66,14 +66,14 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 1194,
|
||||
Protocol: constants.UDP,
|
||||
},
|
||||
},
|
||||
"default Wireguard port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}, WgPubKey: "x"},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}, WgPubKey: "x"},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
VPN: vpn.Wireguard,
|
||||
|
||||
@@ -3,8 +3,8 @@ package windscribe
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
@@ -42,7 +42,7 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
},
|
||||
"default OpenVPN TCP port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
OpenVPN: settings.OpenVPNSelection{
|
||||
@@ -51,14 +51,14 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 443,
|
||||
Protocol: constants.TCP,
|
||||
},
|
||||
},
|
||||
"default OpenVPN UDP port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
OpenVPN: settings.OpenVPNSelection{
|
||||
@@ -67,21 +67,21 @@ func Test_Provider_GetConnection(t *testing.T) {
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.OpenVPN,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 1194,
|
||||
Protocol: constants.UDP,
|
||||
},
|
||||
},
|
||||
"default Wireguard port": {
|
||||
filteredServers: []models.Server{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}, WgPubKey: "x"},
|
||||
{IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})}, WgPubKey: "x"},
|
||||
},
|
||||
selection: settings.ServerSelection{
|
||||
VPN: vpn.Wireguard,
|
||||
}.WithDefaults(provider),
|
||||
connection: models.Connection{
|
||||
Type: vpn.Wireguard,
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
IP: netip.AddrFrom4([4]byte{1, 1, 1, 1}),
|
||||
Port: 1194,
|
||||
Protocol: constants.UDP,
|
||||
PubKey: "x",
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
@@ -33,9 +33,9 @@ type groupData struct {
|
||||
|
||||
type serverData struct {
|
||||
Hostname string `json:"hostname"`
|
||||
IP net.IP `json:"ip"`
|
||||
IP2 net.IP `json:"ip2"`
|
||||
IP3 net.IP `json:"ip3"`
|
||||
IP netip.Addr `json:"ip"`
|
||||
IP2 netip.Addr `json:"ip2"`
|
||||
IP3 netip.Addr `json:"ip3"`
|
||||
}
|
||||
|
||||
func fetchAPI(ctx context.Context, client *http.Client) (
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sort"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants/vpn"
|
||||
@@ -30,11 +30,11 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
||||
x5090Name := group.OvpnX509
|
||||
wgPubKey := group.WgPubKey
|
||||
for _, node := range group.Nodes {
|
||||
ips := make([]net.IP, 0, 2) //nolint:gomnd
|
||||
if node.IP != nil {
|
||||
ips := make([]netip.Addr, 0, 2) //nolint:gomnd
|
||||
if node.IP.IsValid() {
|
||||
ips = append(ips, node.IP)
|
||||
}
|
||||
if node.IP2 != nil {
|
||||
if node.IP2.IsValid() {
|
||||
ips = append(ips, node.IP2)
|
||||
}
|
||||
server := models.Server{
|
||||
@@ -49,7 +49,7 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
||||
}
|
||||
servers = append(servers, server)
|
||||
|
||||
if node.IP3 == nil { // Wireguard + Stealth
|
||||
if !node.IP3.IsValid() { // Wireguard + Stealth
|
||||
continue
|
||||
} else if wgPubKey == "" {
|
||||
return nil, fmt.Errorf("%w: for node %s", ErrNoWireguardKey, node.Hostname)
|
||||
@@ -60,7 +60,7 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
|
||||
server.TCP = false
|
||||
server.OvpnX509 = ""
|
||||
server.WgPubKey = wgPubKey
|
||||
server.IPs = []net.IP{node.IP3}
|
||||
server.IPs = []netip.Addr{node.IP3}
|
||||
servers = append(servers, server)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,12 @@ package publicip
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/publicip/ipinfo"
|
||||
)
|
||||
|
||||
type Fetcher interface {
|
||||
FetchInfo(ctx context.Context, ip net.IP) (
|
||||
FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
result ipinfo.Response, err error)
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
@@ -28,13 +28,13 @@ var (
|
||||
)
|
||||
|
||||
// FetchInfo obtains information on the ip address provided
|
||||
// using the ipinfo.io API. If the ip is nil, the public IP address
|
||||
// using the ipinfo.io API. If the ip is the zero value, the public IP address
|
||||
// of the machine is used as the IP.
|
||||
func (f *Fetch) FetchInfo(ctx context.Context, ip net.IP) (
|
||||
func (f *Fetch) FetchInfo(ctx context.Context, ip netip.Addr) (
|
||||
result Response, err error) {
|
||||
const baseURL = "https://ipinfo.io/"
|
||||
url := baseURL
|
||||
if ip != nil {
|
||||
if ip.IsValid() {
|
||||
url += ip.String()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package ipinfo
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
IP net.IP `json:"ip,omitempty"`
|
||||
IP netip.Addr `json:"ip,omitempty"`
|
||||
Region string `json:"region,omitempty"`
|
||||
Country string `json:"country,omitempty"`
|
||||
City string `json:"city,omitempty"`
|
||||
@@ -19,8 +19,8 @@ type Response struct {
|
||||
}
|
||||
|
||||
func (r *Response) ToPublicIPModel() (model models.PublicIP) {
|
||||
model = models.PublicIP{
|
||||
IP: make(net.IP, len(r.IP)),
|
||||
return models.PublicIP{
|
||||
IP: r.IP,
|
||||
Region: r.Region,
|
||||
Country: r.Country,
|
||||
City: r.City,
|
||||
@@ -30,6 +30,4 @@ func (r *Response) ToPublicIPModel() (model models.PublicIP) {
|
||||
PostalCode: r.Postal,
|
||||
Timezone: r.Timezone,
|
||||
}
|
||||
copy(model.IP, r.IP)
|
||||
return model
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package ipinfo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
// FetchMultiInfo obtains the public IP address information for every IP
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
// If an error is encountered, all the operations are canceled and
|
||||
// an error is returned, so the results returned should be considered
|
||||
// incomplete in this case.
|
||||
func (f *Fetch) FetchMultiInfo(ctx context.Context, ips []net.IP) (
|
||||
func (f *Fetch) FetchMultiInfo(ctx context.Context, ips []netip.Addr) (
|
||||
results []Response, err error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
||||
@@ -23,7 +23,7 @@ func (f *Fetch) FetchMultiInfo(ctx context.Context, ips []net.IP) (
|
||||
resultsCh := make(chan asyncResult)
|
||||
|
||||
for i, ip := range ips {
|
||||
go func(index int, ip net.IP) {
|
||||
go func(index int, ip netip.Addr) {
|
||||
aResult := asyncResult{
|
||||
index: index,
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package publicip
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/netip"
|
||||
"os"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
@@ -26,7 +27,7 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
||||
resultCh := make(chan models.PublicIP)
|
||||
errorCh := make(chan error)
|
||||
go func() {
|
||||
result, err := l.fetcher.FetchInfo(getCtx, nil)
|
||||
result, err := l.fetcher.FetchInfo(getCtx, netip.Addr{})
|
||||
if err != nil {
|
||||
if getCtx.Err() == nil {
|
||||
errorCh <- err
|
||||
|
||||
@@ -3,7 +3,7 @@ package routing
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/netlink"
|
||||
)
|
||||
@@ -14,8 +14,8 @@ var (
|
||||
|
||||
type DefaultRoute struct {
|
||||
NetInterface string
|
||||
Gateway net.IP
|
||||
AssignedIP net.IP
|
||||
Gateway netip.Addr
|
||||
AssignedIP netip.Addr
|
||||
Family int
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ func (r *Routing) DefaultRoutes() (defaultRoutes []DefaultRoute, err error) {
|
||||
continue
|
||||
}
|
||||
defaultRoute := DefaultRoute{
|
||||
Gateway: route.Gw,
|
||||
Gateway: netIPToNetipAddress(route.Gw),
|
||||
Family: route.Family,
|
||||
}
|
||||
linkIndex := route.LinkIndex
|
||||
|
||||
@@ -62,7 +62,7 @@ func (r *Routing) unrouteInboundFromDefault(defaultRoutes []DefaultRoute) (err e
|
||||
|
||||
func (r *Routing) addRuleInboundFromDefault(table int, defaultRoutes []DefaultRoute) (err error) {
|
||||
for _, defaultRoute := range defaultRoutes {
|
||||
assignedIP := netIPToNetipAddress(defaultRoute.AssignedIP)
|
||||
assignedIP := defaultRoute.AssignedIP
|
||||
bits := 32
|
||||
if assignedIP.Is6() {
|
||||
bits = 128
|
||||
@@ -82,7 +82,7 @@ func (r *Routing) addRuleInboundFromDefault(table int, defaultRoutes []DefaultRo
|
||||
|
||||
func (r *Routing) delRuleInboundFromDefault(table int, defaultRoutes []DefaultRoute) (err error) {
|
||||
for _, defaultRoute := range defaultRoutes {
|
||||
assignedIP := netIPToNetipAddress(defaultRoute.AssignedIP)
|
||||
assignedIP := defaultRoute.AssignedIP
|
||||
bits := 32
|
||||
if assignedIP.Is6() {
|
||||
bits = 128
|
||||
|
||||
@@ -4,11 +4,12 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/netlink"
|
||||
)
|
||||
|
||||
func IPIsPrivate(ip net.IP) bool {
|
||||
func IPIsPrivate(ip netip.Addr) bool {
|
||||
return ip.IsPrivate() || ip.IsLoopback() ||
|
||||
ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast()
|
||||
}
|
||||
@@ -17,38 +18,26 @@ var (
|
||||
errInterfaceIPNotFound = errors.New("IP address not found for interface")
|
||||
)
|
||||
|
||||
func ipMatchesFamily(ip net.IP, family int) bool {
|
||||
return (family == netlink.FAMILY_V6 && ip.To4() == nil) ||
|
||||
(family == netlink.FAMILY_V4 && ip.To4() != nil)
|
||||
func ipMatchesFamily(ip netip.Addr, family int) bool {
|
||||
return (family == netlink.FAMILY_V6 && ip.Is6()) ||
|
||||
(family == netlink.FAMILY_V4 && (ip.Is4() || ip.Is4In6()))
|
||||
}
|
||||
|
||||
func ensureNoIPv6WrappedIPv4(candidateIP net.IP) (resultIP net.IP) {
|
||||
const ipv4Size = 4
|
||||
if candidateIP.To4() == nil || len(candidateIP) == ipv4Size { // ipv6 or ipv4
|
||||
return candidateIP
|
||||
}
|
||||
|
||||
// ipv6-wrapped ipv4
|
||||
resultIP = make(net.IP, ipv4Size)
|
||||
copy(resultIP, candidateIP[12:16])
|
||||
return resultIP
|
||||
}
|
||||
|
||||
func (r *Routing) assignedIP(interfaceName string, family int) (ip net.IP, err error) {
|
||||
func (r *Routing) assignedIP(interfaceName string, family int) (ip netip.Addr, err error) {
|
||||
iface, err := net.InterfaceByName(interfaceName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("network interface %s not found: %w", interfaceName, err)
|
||||
return ip, fmt.Errorf("network interface %s not found: %w", interfaceName, err)
|
||||
}
|
||||
addresses, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listing interface %s addresses: %w", interfaceName, err)
|
||||
return ip, fmt.Errorf("listing interface %s addresses: %w", interfaceName, err)
|
||||
}
|
||||
for _, address := range addresses {
|
||||
switch value := address.(type) {
|
||||
case *net.IPAddr:
|
||||
ip = value.IP
|
||||
ip = netIPToNetipAddress(value.IP)
|
||||
case *net.IPNet:
|
||||
ip = value.IP
|
||||
ip = netIPToNetipAddress(value.IP)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
@@ -60,9 +49,8 @@ func (r *Routing) assignedIP(interfaceName string, family int) (ip net.IP, err e
|
||||
// Ensure we don't return an IPv6-wrapped IPv4 address
|
||||
// since netip.Address String method works differently than
|
||||
// net.IP String method for this kind of addresses.
|
||||
ip = ensureNoIPv6WrappedIPv4(ip)
|
||||
return ip, nil
|
||||
return ip.Unmap(), nil
|
||||
}
|
||||
return nil, fmt.Errorf("%w: interface %s in %d addresses",
|
||||
return ip, fmt.Errorf("%w: interface %s in %d addresses",
|
||||
errInterfaceIPNotFound, interfaceName, len(addresses))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -87,8 +87,8 @@ func Test_IPIsPrivate(t *testing.T) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ip := net.ParseIP(testCase.ipString)
|
||||
require.NotNil(t, ip)
|
||||
ip, err := netip.ParseAddr(testCase.ipString)
|
||||
require.NoError(t, err)
|
||||
|
||||
isPrivate := IPIsPrivate(ip)
|
||||
|
||||
@@ -96,35 +96,3 @@ func Test_IPIsPrivate(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_ensureNoIPv6WrappedIPv4(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
candidateIP net.IP
|
||||
resultIP net.IP
|
||||
}{
|
||||
"nil": {},
|
||||
"ipv6": {
|
||||
candidateIP: net.IPv6loopback,
|
||||
resultIP: net.IPv6loopback,
|
||||
},
|
||||
"ipv4": {
|
||||
candidateIP: net.IP{1, 2, 3, 4},
|
||||
resultIP: net.IP{1, 2, 3, 4},
|
||||
},
|
||||
"ipv6_wrapped_ipv4": {
|
||||
candidateIP: net.IPv4(1, 2, 3, 4),
|
||||
resultIP: net.IP{1, 2, 3, 4},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
resultIP := ensureNoIPv6WrappedIPv4(testCase.candidateIP)
|
||||
assert.Equal(t, testCase.resultIP, resultIP)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package routing
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/netlink"
|
||||
@@ -18,7 +17,7 @@ var (
|
||||
type LocalNetwork struct {
|
||||
IPNet netip.Prefix
|
||||
InterfaceName string
|
||||
IP net.IP
|
||||
IP netip.Addr
|
||||
}
|
||||
|
||||
func (r *Routing) LocalNetworks() (localNetworks []LocalNetwork, err error) {
|
||||
|
||||
@@ -2,14 +2,13 @@ package routing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strconv"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/netlink"
|
||||
)
|
||||
|
||||
func (r *Routing) addRouteVia(destination netip.Prefix, gateway net.IP,
|
||||
func (r *Routing) addRouteVia(destination netip.Prefix, gateway netip.Addr,
|
||||
iface string, table int) error {
|
||||
destinationStr := destination.String()
|
||||
r.logger.Info("adding route for " + destinationStr)
|
||||
@@ -25,7 +24,7 @@ func (r *Routing) addRouteVia(destination netip.Prefix, gateway net.IP,
|
||||
|
||||
route := netlink.Route{
|
||||
Dst: NetipPrefixToIPNet(&destination),
|
||||
Gw: gateway,
|
||||
Gw: gateway.AsSlice(),
|
||||
LinkIndex: link.Attrs().Index,
|
||||
Table: table,
|
||||
}
|
||||
@@ -37,7 +36,7 @@ func (r *Routing) addRouteVia(destination netip.Prefix, gateway net.IP,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Routing) deleteRouteVia(destination netip.Prefix, gateway net.IP,
|
||||
func (r *Routing) deleteRouteVia(destination netip.Prefix, gateway netip.Addr,
|
||||
iface string, table int) (err error) {
|
||||
destinationStr := destination.String()
|
||||
r.logger.Info("deleting route for " + destinationStr)
|
||||
@@ -53,7 +52,7 @@ func (r *Routing) deleteRouteVia(destination netip.Prefix, gateway net.IP,
|
||||
|
||||
route := netlink.Route{
|
||||
Dst: NetipPrefixToIPNet(&destination),
|
||||
Gw: gateway,
|
||||
Gw: gateway.AsSlice(),
|
||||
LinkIndex: link.Attrs().Index,
|
||||
Table: table,
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/netlink"
|
||||
)
|
||||
@@ -14,10 +15,10 @@ var (
|
||||
ErrVPNLocalGatewayIPNotFound = errors.New("VPN local gateway IP address not found")
|
||||
)
|
||||
|
||||
func (r *Routing) VPNDestinationIP() (ip net.IP, err error) {
|
||||
func (r *Routing) VPNDestinationIP() (ip netip.Addr, err error) {
|
||||
routes, err := r.netLinker.RouteList(nil, netlink.FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listing routes: %w", err)
|
||||
return ip, fmt.Errorf("listing routes: %w", err)
|
||||
}
|
||||
|
||||
defaultLinkIndex := -1
|
||||
@@ -28,36 +29,36 @@ func (r *Routing) VPNDestinationIP() (ip net.IP, err error) {
|
||||
}
|
||||
}
|
||||
if defaultLinkIndex == -1 {
|
||||
return nil, fmt.Errorf("%w: in %d route(s)", ErrLinkDefaultNotFound, len(routes))
|
||||
return ip, fmt.Errorf("%w: in %d route(s)", ErrLinkDefaultNotFound, len(routes))
|
||||
}
|
||||
|
||||
for _, route := range routes {
|
||||
if route.LinkIndex == defaultLinkIndex &&
|
||||
route.Dst != nil &&
|
||||
!IPIsPrivate(route.Dst.IP) &&
|
||||
!IPIsPrivate(netIPToNetipAddress(route.Dst.IP)) &&
|
||||
bytes.Equal(route.Dst.Mask, net.IPMask{255, 255, 255, 255}) {
|
||||
return route.Dst.IP, nil
|
||||
return netIPToNetipAddress(route.Dst.IP), nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("%w: in %d routes", ErrVPNDestinationIPNotFound, len(routes))
|
||||
return ip, fmt.Errorf("%w: in %d routes", ErrVPNDestinationIPNotFound, len(routes))
|
||||
}
|
||||
|
||||
func (r *Routing) VPNLocalGatewayIP(vpnIntf string) (ip net.IP, err error) {
|
||||
func (r *Routing) VPNLocalGatewayIP(vpnIntf string) (ip netip.Addr, err error) {
|
||||
routes, err := r.netLinker.RouteList(nil, netlink.FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listing routes: %w", err)
|
||||
return ip, fmt.Errorf("listing routes: %w", err)
|
||||
}
|
||||
for _, route := range routes {
|
||||
link, err := r.netLinker.LinkByIndex(route.LinkIndex)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("finding link at index %d: %w", route.LinkIndex, err)
|
||||
return ip, fmt.Errorf("finding link at index %d: %w", route.LinkIndex, err)
|
||||
}
|
||||
interfaceName := link.Attrs().Name
|
||||
if interfaceName == vpnIntf &&
|
||||
route.Dst != nil &&
|
||||
route.Dst.IP.Equal(net.IP{0, 0, 0, 0}) {
|
||||
return route.Gw, nil
|
||||
return netIPToNetipAddress(route.Gw), nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("%w: in %d routes", ErrVPNLocalGatewayIPNotFound, len(routes))
|
||||
return ip, fmt.Errorf("%w: in %d routes", ErrVPNLocalGatewayIPNotFound, len(routes))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
@@ -12,21 +12,12 @@ func copyServer(server models.Server) (serverCopy models.Server) {
|
||||
return serverCopy
|
||||
}
|
||||
|
||||
func copyIPs(toCopy []net.IP) (copied []net.IP) {
|
||||
func copyIPs(toCopy []netip.Addr) (copied []netip.Addr) {
|
||||
if toCopy == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
copied = make([]net.IP, len(toCopy))
|
||||
for i := range toCopy {
|
||||
copied[i] = copyIP(toCopy[i])
|
||||
}
|
||||
|
||||
return copied
|
||||
}
|
||||
|
||||
func copyIP(toCopy net.IP) (copied net.IP) {
|
||||
copied = make(net.IP, len(toCopy))
|
||||
copied = make([]netip.Addr, len(toCopy))
|
||||
copy(copied, toCopy)
|
||||
return copied
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_copyServer(t *testing.T) {
|
||||
@@ -14,14 +13,14 @@ func Test_copyServer(t *testing.T) {
|
||||
|
||||
server := models.Server{
|
||||
Country: "a",
|
||||
IPs: []net.IP{{1, 2, 3, 4}},
|
||||
IPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 2, 3, 4})},
|
||||
}
|
||||
|
||||
serverCopy := copyServer(server)
|
||||
|
||||
assert.Equal(t, server, serverCopy)
|
||||
// Check for mutation
|
||||
serverCopy.IPs[0][0] = 9
|
||||
serverCopy.IPs[0] = netip.AddrFrom4([4]byte{9, 9, 9, 9})
|
||||
assert.NotEqual(t, server, serverCopy)
|
||||
}
|
||||
|
||||
@@ -29,21 +28,21 @@ func Test_copyIPs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
toCopy []net.IP
|
||||
copied []net.IP
|
||||
toCopy []netip.Addr
|
||||
copied []netip.Addr
|
||||
}{
|
||||
"nil": {},
|
||||
"empty": {
|
||||
toCopy: []net.IP{},
|
||||
copied: []net.IP{},
|
||||
toCopy: []netip.Addr{},
|
||||
copied: []netip.Addr{},
|
||||
},
|
||||
"single IP": {
|
||||
toCopy: []net.IP{{1, 1, 1, 1}},
|
||||
copied: []net.IP{{1, 1, 1, 1}},
|
||||
toCopy: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})},
|
||||
copied: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})},
|
||||
},
|
||||
"two IPs": {
|
||||
toCopy: []net.IP{{1, 1, 1, 1}, {2, 2, 2, 2}},
|
||||
copied: []net.IP{{1, 1, 1, 1}, {2, 2, 2, 2}},
|
||||
toCopy: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1}), netip.AddrFrom4([4]byte{2, 2, 2, 2})},
|
||||
copied: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1}), netip.AddrFrom4([4]byte{2, 2, 2, 2})},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -52,23 +51,13 @@ func Test_copyIPs(t *testing.T) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// Reserver leading 9 for copy modifications below
|
||||
for _, ipToCopy := range testCase.toCopy {
|
||||
require.NotEqual(t, 9, ipToCopy[0])
|
||||
}
|
||||
|
||||
copied := copyIPs(testCase.toCopy)
|
||||
|
||||
assert.Equal(t, testCase.copied, copied)
|
||||
|
||||
if len(copied) > 0 {
|
||||
original := testCase.toCopy[0][0]
|
||||
testCase.toCopy[0][0] = 9
|
||||
assert.NotEqual(t, 9, copied[0][0])
|
||||
testCase.toCopy[0][0] = original
|
||||
|
||||
copied[0][0] = 9
|
||||
assert.NotEqual(t, 9, testCase.toCopy[0][0])
|
||||
testCase.toCopy[0] = netip.AddrFrom4([4]byte{9, 9, 9, 9})
|
||||
assert.NotEqual(t, testCase.toCopy[0], testCase.copied[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package openvpn
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
@@ -54,7 +54,7 @@ func ExtractHost(b []byte) (host, warning string, err error) {
|
||||
return hosts[0], warning, nil
|
||||
}
|
||||
|
||||
func ExtractIPs(b []byte) (ips []net.IP, err error) {
|
||||
func ExtractIPs(b []byte) (ips []netip.Addr, err error) {
|
||||
const rejectIP, rejectDomain = false, true
|
||||
ipStrings := extractRemoteHosts(b, rejectIP, rejectDomain)
|
||||
if len(ipStrings) == 0 {
|
||||
@@ -65,9 +65,12 @@ func ExtractIPs(b []byte) (ips []net.IP, err error) {
|
||||
return ipStrings[i] < ipStrings[j]
|
||||
})
|
||||
|
||||
ips = make([]net.IP, len(ipStrings))
|
||||
ips = make([]netip.Addr, len(ipStrings))
|
||||
for i := range ipStrings {
|
||||
ips[i] = net.ParseIP(ipStrings[i])
|
||||
ips[i], err = netip.ParseAddr(ipStrings[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing IP address: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return ips, nil
|
||||
@@ -85,9 +88,9 @@ func extractRemoteHosts(content []byte, rejectIP, rejectDomain bool) (hosts []st
|
||||
continue
|
||||
}
|
||||
host := fields[1]
|
||||
parsedIP := net.ParseIP(host)
|
||||
if (rejectIP && parsedIP != nil) ||
|
||||
(rejectDomain && parsedIP == nil) {
|
||||
_, err := netip.ParseAddr(host)
|
||||
if (rejectIP && err == nil) ||
|
||||
(rejectDomain && err != nil) {
|
||||
continue
|
||||
}
|
||||
hosts = append(hosts, host)
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
package resolver
|
||||
|
||||
import "net"
|
||||
import (
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
func uniqueIPsToSlice(uniqueIPs map[string]struct{}) (ips []net.IP) {
|
||||
ips = make([]net.IP, 0, len(uniqueIPs))
|
||||
func uniqueIPsToSlice(uniqueIPs map[string]struct{}) (ips []netip.Addr) {
|
||||
ips = make([]netip.Addr, 0, len(uniqueIPs))
|
||||
for key := range uniqueIPs {
|
||||
IP := net.ParseIP(key)
|
||||
if IPv4 := IP.To4(); IPv4 != nil {
|
||||
IP = IPv4
|
||||
ip, err := netip.ParseAddr(key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ips = append(ips, IP)
|
||||
if ip.Is4In6() {
|
||||
ip = netip.AddrFrom4(ip.As4())
|
||||
}
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
return ips
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -11,23 +11,23 @@ func Test_uniqueIPsToSlice(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
inputIPs map[string]struct{}
|
||||
outputIPs []net.IP
|
||||
outputIPs []netip.Addr
|
||||
}{
|
||||
"nil": {
|
||||
inputIPs: nil,
|
||||
outputIPs: []net.IP{},
|
||||
outputIPs: []netip.Addr{},
|
||||
},
|
||||
"empty": {
|
||||
inputIPs: map[string]struct{}{},
|
||||
outputIPs: []net.IP{},
|
||||
outputIPs: []netip.Addr{},
|
||||
},
|
||||
"single IPv4": {
|
||||
inputIPs: map[string]struct{}{"1.1.1.1": {}},
|
||||
outputIPs: []net.IP{{1, 1, 1, 1}},
|
||||
outputIPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})},
|
||||
},
|
||||
"two IPv4s": {
|
||||
inputIPs: map[string]struct{}{"1.1.1.1": {}, "1.1.2.1": {}},
|
||||
outputIPs: []net.IP{{1, 1, 1, 1}, {1, 1, 2, 1}},
|
||||
outputIPs: []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1}), netip.AddrFrom4([4]byte{1, 1, 2, 1})},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
)
|
||||
|
||||
type Parallel struct {
|
||||
@@ -31,7 +31,7 @@ type ParallelSettings struct {
|
||||
|
||||
type parallelResult struct {
|
||||
host string
|
||||
IPs []net.IP
|
||||
IPs []netip.Addr
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -40,7 +40,7 @@ var (
|
||||
)
|
||||
|
||||
func (pr *Parallel) Resolve(ctx context.Context, settings ParallelSettings) (
|
||||
hostToIPs map[string][]net.IP, warnings []string, err error) {
|
||||
hostToIPs map[string][]netip.Addr, warnings []string, err error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
@@ -53,7 +53,7 @@ func (pr *Parallel) Resolve(ctx context.Context, settings ParallelSettings) (
|
||||
go pr.resolveAsync(ctx, host, settings.Repeat, results, errors)
|
||||
}
|
||||
|
||||
hostToIPs = make(map[string][]net.IP, len(settings.Hosts))
|
||||
hostToIPs = make(map[string][]netip.Addr, len(settings.Hosts))
|
||||
maxFails := int(settings.MaxFailRatio * float64(len(settings.Hosts)))
|
||||
|
||||
for range settings.Hosts {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package resolver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
@@ -31,7 +31,7 @@ type RepeatSettings struct {
|
||||
}
|
||||
|
||||
func (r *Repeat) Resolve(ctx context.Context, host string, settings RepeatSettings) (
|
||||
ips []net.IP, err error) {
|
||||
ips []netip.Addr, err error) {
|
||||
timedCtx, cancel := context.WithTimeout(ctx, settings.MaxDuration)
|
||||
defer cancel()
|
||||
|
||||
@@ -54,7 +54,7 @@ func (r *Repeat) Resolve(ctx context.Context, host string, settings RepeatSettin
|
||||
|
||||
if settings.SortIPs {
|
||||
sort.Slice(ips, func(i, j int) bool {
|
||||
return bytes.Compare(ips[i], ips[j]) < 1
|
||||
return ips[i].Compare(ips[j]) < 1
|
||||
})
|
||||
}
|
||||
|
||||
@@ -121,15 +121,15 @@ func (r *Repeat) resolveOnce(ctx, timedCtx context.Context, host string,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Repeat) lookupIPs(ctx context.Context, host string) (ips []net.IP, err error) {
|
||||
func (r *Repeat) lookupIPs(ctx context.Context, host string) (ips []netip.Addr, err error) {
|
||||
addresses, err := r.resolver.LookupIPAddr(ctx, host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ips = make([]net.IP, 0, len(addresses))
|
||||
ips = make([]netip.Addr, 0, len(addresses))
|
||||
for i := range addresses {
|
||||
ip := addresses[i].IP
|
||||
if ip == nil {
|
||||
ip, ok := netip.AddrFromSlice(addresses[i].IP)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
ips = append(ips, ip)
|
||||
|
||||
@@ -2,7 +2,7 @@ package vpn
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration/settings"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -18,7 +18,7 @@ type Firewall interface {
|
||||
}
|
||||
|
||||
type Routing interface {
|
||||
VPNLocalGatewayIP(vpnInterface string) (gateway net.IP, err error)
|
||||
VPNLocalGatewayIP(vpnInterface string) (gateway netip.Addr, err error)
|
||||
}
|
||||
|
||||
type PortForward interface {
|
||||
|
||||
Reference in New Issue
Block a user