Initial "hardcoded" version of mapping.
This commit is contained in:
		
							
								
								
									
										50
									
								
								ipgeo/ipdb.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								ipgeo/ipdb.go
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										31
									
								
								mapping/map.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								mapping/map.go
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user