mirror of
https://github.com/wweir/sower.git
synced 2026-10-19 16:14:33 +00:00
- Add DialSmart (rule+detect+fallback) and DialProxyOnly (forced proxy) as explicit routing entry points; keep Dial as compatibility alias. - NewRouter now returns (*Router, error); non-empty invalid MMDB path is a startup error instead of a silent warning. - AddCountryCIDRs now returns error; invalid CIDR entries fail fast. - Add Router.Close() to release geoip2.Reader on shutdown. - Add country RWMutex so Close() does not race with concurrent reads. - localSite checks all resolved IPs instead of only the first. - Move accessCache from package-level global to Router instance field; inject accessProbeFunc for testability. - Disable redirect following in pingClient to avoid misleading probe results on redirect responses.
59 lines
1.1 KiB
Go
59 lines
1.1 KiB
Go
package router
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"net"
|
|
"time"
|
|
)
|
|
|
|
func (r *Router) localSite(ctx context.Context, domain string) bool {
|
|
if ctx == nil {
|
|
ctx = context.Background()
|
|
}
|
|
|
|
if ip := net.ParseIP(domain); ip != nil {
|
|
return r.localIP(domain, ip)
|
|
}
|
|
|
|
resolveCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
|
|
defer cancel()
|
|
|
|
ips, err := net.DefaultResolver.LookupIP(resolveCtx, "ip", domain)
|
|
if err != nil || len(ips) == 0 {
|
|
slog.Warn("resolve domain", "error", err, "domain", domain, "ips", len(ips))
|
|
return false
|
|
}
|
|
|
|
for _, ip := range ips {
|
|
if r.localIP(domain, ip) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (r *Router) localIP(domain string, ip net.IP) bool {
|
|
// CIDR match
|
|
for _, cidr := range r.country.cidrs {
|
|
if cidr.Contains(ip) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
r.country.RLock()
|
|
reader := r.country.Reader
|
|
if reader == nil {
|
|
r.country.RUnlock()
|
|
return false
|
|
}
|
|
city, err := reader.City(ip)
|
|
r.country.RUnlock()
|
|
if err != nil {
|
|
slog.Warn("mmdb search", "error", err, "domain", domain, "ip", ip)
|
|
return false
|
|
}
|
|
|
|
return city.Country.IsoCode == "CN"
|
|
}
|