diff --git a/ipgeo/ipdb.go b/ipgeo/ipdb.go new file mode 100644 index 0000000..cd57b6a --- /dev/null +++ b/ipgeo/ipdb.go @@ -0,0 +1,50 @@ +package ipgeo + +import ( + "flag" + "github.com/ipipdotnet/ipdb-go" + "log" +) + +var ( + requiredFields = []string{ + "country_name", + "region_name", + "city_name", + "isp_domain", + "country_code", + "continent_code", + } + ipipdb = flag.String("ipdb-database", "ipip.db", "path to ipip database") + db *ipdb.City +) + +func Init() { + var err error + db, err = ipdb.NewCity(*ipipdb) + if err != nil { + log.Fatalln("Unable to open ipdb:", err.Error()) + } + if !db.IsIPv4() { + log.Fatalln("This IPIP.net database has no IPv4 information!") + } + { + fields := db.Fields() + for _, requiredField := range requiredFields { + ok := false + for _, field := range fields { + if field == requiredField { + ok = true + break + } + } + if !ok { + log.Fatalln("This IPIP.net database has no required field", requiredField) + } + } + } +} + +func Get() *ipdb.City { + return db +} diff --git a/main.go b/main.go index d2462be..b85afdd 100644 --- a/main.go +++ b/main.go @@ -4,27 +4,17 @@ import ( "encoding/json" "flag" "fmt" - "log" "net" "net/http" _ "net/http/pprof" "strconv" "strings" + "git.eve.moe/jackyyf/navigator/ipgeo" + "git.eve.moe/jackyyf/navigator/mapping" "github.com/ipipdotnet/ipdb-go" ) -var ( - requiredFields = []string{ - "country_name", - "region_name", - "city_name", - "isp_domain", - "country_code", - "continent_code", - } -) - const ( errIPv4Only = "Navigator works for IPv4 only :)" ) @@ -68,32 +58,8 @@ func buildLocation(info *ipdb.CityInfo) string { } func main() { - ipipdb := flag.String("ipdb-database", "ipip.db", "path to ipip database") flag.Parse() - db, err := ipdb.NewCity(*ipipdb) - if err != nil { - log.Fatalln("Unable to open ipdb:", err.Error()) - } - if !db.IsIPv4() { - log.Fatalln("This IPIP.net database has no IPv4 information!") - } - { - fields := db.Fields() - for _, requiredField := range requiredFields { - ok := false - for _, field := range fields { - if field == requiredField { - ok = true - break - } - } - if !ok { - log.Fatalln("This IPIP.net database has no required field", requiredField) - } - } - } - http.HandleFunc("/healthz", func(resp http.ResponseWriter, req *http.Request) { resp.WriteHeader(200) resp.Write([]byte("ok")) @@ -109,6 +75,7 @@ func main() { responseWithError(resp, http.StatusPreconditionFailed, errIPv4Only) return } + db := ipgeo.Get() info_cn, err := db.FindInfo(host, "CN") if err != nil { @@ -122,20 +89,24 @@ func main() { } resp.Header().Set("Content-Type", "text/plain") resp.WriteHeader(http.StatusOK) + server := mapping.Get(host) fmt.Fprintln(resp, "您的IP:", host) fmt.Fprintln(resp, "数据库中IP所属位置:", buildLocation(info_cn)) if info_cn.IspDomain != "" { fmt.Fprintln(resp, "数据库中IP所属运营商:", info_cn.IspDomain) } - // TODO(jackyyf): add mapping info here + fmt.Fprintln(resp, "您被分配的CDN节点为:", server) + fmt.Fprintln(resp) + fmt.Fprintln(resp, strings.Repeat("=", 72)) fmt.Fprintln(resp, "Your IP:", host) fmt.Fprintln(resp, "Location for your IP according our database:", buildLocation(info_en)) if info_en.IspDomain != "" { fmt.Fprintln(resp, "ISP for your IP according our database:", info_en.IspDomain) } - // TODO(jackyyf): add mapping info here - + fmt.Fprintln(resp, "Allocated CDN node for you:", server) + fmt.Fprintln(resp) }) + ipgeo.Init() http.ListenAndServe("0.0.0.0:8086", nil) } diff --git a/mapping/map.go b/mapping/map.go new file mode 100644 index 0000000..6ae9f4e --- /dev/null +++ b/mapping/map.go @@ -0,0 +1,31 @@ +package mapping + +import ( + "git.eve.moe/jackyyf/navigator/ipgeo" +) + +const ( + // Server IDs + WHOLESALE_INTERNET_10GE = "xe-mci1-us" + HETZNER_FSN_1GE = "ge-fsn1-de" + HETZNER_HEL_1GE = "ge-hel1-fi" + default_server = WHOLESALE_INTERNET_10GE + + // Served domain suffix + CHINA_MAINLAND_SUFFIX = ".eveedge.link" + GLOBAL_SUFFIX = ".edge.eve.network" + default_suffix = GLOBAL_SUFFIX +) + +// Get returns the edge node that should be used for client. +func Get(ip string) string { + db := ipgeo.Get() + info_en, err := db.FindInfo(ip, "EN") + if err != nil { + return default_server + default_suffix + } + if info_en.CountryCode == "CN" { + return default_server + CHINA_MAINLAND_SUFFIX + } + return default_server + GLOBAL_SUFFIX +}