You've already forked armbian-router
mirror of
https://github.com/armbian/armbian-router.git
synced 2026-01-06 10:37:03 -08:00
filter servers using ipv6
This commit is contained in:
47
check.go
47
check.go
@@ -232,6 +232,53 @@ func (t *TLSCheck) Check(server *Server, logFields log.Fields) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// IPv6Check verifies that a server has a valid IPv6 address by checking for AAAA records.
|
||||
type IPv6Check struct {
|
||||
config *Config
|
||||
}
|
||||
|
||||
// Check verifies IPv6 support for the server by checking for AAAA records
|
||||
func (i *IPv6Check) Check(server *Server, logFields log.Fields) (bool, error) {
|
||||
// Extract host from server (handle host:port format)
|
||||
host := server.Host
|
||||
if strings.Contains(host, ":") {
|
||||
var err error
|
||||
host, _, err = net.SplitHostPort(server.Host)
|
||||
if err != nil {
|
||||
host = server.Host
|
||||
}
|
||||
}
|
||||
|
||||
ips, err := net.LookupIP(host)
|
||||
if err != nil {
|
||||
logFields["error"] = err
|
||||
return true, nil // DNS lookup failure shouldn't fail the whole check
|
||||
}
|
||||
|
||||
// Check if any resolved IP is IPv6
|
||||
hasIPv6 := false
|
||||
for _, ip := range ips {
|
||||
if ip.To4() == nil && ip.To16() != nil {
|
||||
hasIPv6 = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
server.mu.Lock()
|
||||
server.IPv6 = hasIPv6
|
||||
server.mu.Unlock()
|
||||
|
||||
if hasIPv6 {
|
||||
log.WithField("host", server.Host).Debug("Server has IPv6 support")
|
||||
} else {
|
||||
logFields["cause"] = "No AAAA record found"
|
||||
log.WithField("host", server.Host).Debug("Server does not have IPv6 support")
|
||||
}
|
||||
|
||||
// This check doesn't fail servers, it just updates their IPv6 status
|
||||
return true, nil
|
||||
}
|
||||
|
||||
type VersionCheck struct {
|
||||
config *Config
|
||||
VersionURL string
|
||||
|
||||
11
config.go
11
config.go
@@ -337,6 +337,17 @@ func (r *Redirector) addServer(server ServerConfig, u *url.URL) (*Server, error)
|
||||
}).Warning("Could not resolve address")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check for IPv6 support using resolved IPs
|
||||
hasIPv6 := false
|
||||
for _, ip := range ips {
|
||||
if ip.To4() == nil && ip.To16() != nil {
|
||||
hasIPv6 = true
|
||||
break
|
||||
}
|
||||
}
|
||||
s.IPv6 = hasIPv6
|
||||
|
||||
var city db.City
|
||||
err = r.db.Lookup(ips[0], &city)
|
||||
if err != nil {
|
||||
|
||||
5
http.go
5
http.go
@@ -96,9 +96,12 @@ func (r *Redirector) redirectHandler(w http.ResponseWriter, req *http.Request) {
|
||||
scheme = "http"
|
||||
}
|
||||
|
||||
// Detect if user is connecting via IPv6
|
||||
isIPv6 := ip.To4() == nil && ip.To16() != nil
|
||||
|
||||
// If none of the above exceptions are matched, we use the geographical distance based on IP
|
||||
if server == nil {
|
||||
server, distance, err = r.servers.Closest(r, scheme, ip)
|
||||
server, distance, err = r.servers.Closest(r, scheme, ip, isIPv6)
|
||||
|
||||
if err != nil {
|
||||
log.WithError(err).Warning("Unable to find closest server")
|
||||
|
||||
@@ -77,6 +77,9 @@ func New(config *Config) *Redirector {
|
||||
&TLSCheck{
|
||||
config: config,
|
||||
},
|
||||
&IPv6Check{
|
||||
config: config,
|
||||
},
|
||||
}
|
||||
|
||||
if config.CheckURL != "" {
|
||||
|
||||
13
servers.go
13
servers.go
@@ -31,6 +31,7 @@ type Server struct {
|
||||
Continent string `json:"continent"`
|
||||
Country string `json:"country"`
|
||||
Protocols []string `json:"protocols"`
|
||||
IPv6 bool `json:"ipv6"`
|
||||
Rules []Rule `json:"rules,omitempty"`
|
||||
Redirects prometheus.Counter `json:"-"`
|
||||
LastChange time.Time `json:"lastChange"`
|
||||
@@ -201,8 +202,12 @@ type ComputedDistance struct {
|
||||
// it computes the distances. If the nearest server is within a threshold (e.g. 50km),
|
||||
// it is selected deterministically; otherwise, a weighted selection is used.
|
||||
// If no local servers exist, it falls back to a weighted selection among all valid servers.
|
||||
func (s ServerList) Closest(r *Redirector, scheme string, ip net.IP) (*Server, float64, error) {
|
||||
// If requireIPv6 is true, servers without IPv6 support are filtered out.
|
||||
func (s ServerList) Closest(r *Redirector, scheme string, ip net.IP, requireIPv6 bool) (*Server, float64, error) {
|
||||
cacheKey := scheme + "_" + ip.String()
|
||||
if requireIPv6 {
|
||||
cacheKey += "_v6"
|
||||
}
|
||||
|
||||
if cached, exists := r.serverCache.Get(cacheKey); exists {
|
||||
if comp, ok := cached.(ComputedDistance); ok {
|
||||
@@ -237,6 +242,12 @@ func (s ServerList) Closest(r *Redirector, scheme string, ip net.IP) (*Server, f
|
||||
if !server.Available || !lo.Contains(server.Protocols, scheme) {
|
||||
return false
|
||||
}
|
||||
|
||||
// If user is on IPv6, filter out servers that don't support IPv6
|
||||
if requireIPv6 && !server.IPv6 {
|
||||
log.WithField("host", server.Host).Debug("Skipping server due to no IPv6 support")
|
||||
return false
|
||||
}
|
||||
if len(server.Rules) > 0 && !server.checkRules(ruleInput) {
|
||||
log.WithField("host", server.Host).Debug("Skipping server due to rules")
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user