geodb.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package geodb
  2. import (
  3. _ "embed"
  4. "net/http"
  5. "sync"
  6. "imuslab.com/zoraxy/mod/database"
  7. "imuslab.com/zoraxy/mod/netutils"
  8. )
  9. //go:embed geoipv4.csv
  10. var geoipv4 []byte //Geodb dataset for ipv4
  11. //go:embed geoipv6.csv
  12. var geoipv6 []byte //Geodb dataset for ipv6
  13. type Store struct {
  14. geodb [][]string //Parsed geodb list
  15. geodbIpv6 [][]string //Parsed geodb list for ipv6
  16. geotrie *trie
  17. geotrieIpv6 *trie
  18. geoipCache sync.Map
  19. sysdb *database.Database
  20. option *StoreOptions
  21. }
  22. type StoreOptions struct {
  23. AllowSlowIpv4LookUp bool
  24. AllowSloeIpv6Lookup bool
  25. }
  26. type CountryInfo struct {
  27. CountryIsoCode string
  28. ContinetCode string
  29. }
  30. func NewGeoDb(sysdb *database.Database, option *StoreOptions) (*Store, error) {
  31. parsedGeoData, err := parseCSV(geoipv4)
  32. if err != nil {
  33. return nil, err
  34. }
  35. parsedGeoDataIpv6, err := parseCSV(geoipv6)
  36. if err != nil {
  37. return nil, err
  38. }
  39. var ipv4Trie *trie
  40. if !option.AllowSlowIpv4LookUp {
  41. ipv4Trie = constrctTrieTree(parsedGeoData)
  42. }
  43. var ipv6Trie *trie
  44. if !option.AllowSloeIpv6Lookup {
  45. ipv6Trie = constrctTrieTree(parsedGeoDataIpv6)
  46. }
  47. return &Store{
  48. geodb: parsedGeoData,
  49. geotrie: ipv4Trie,
  50. geodbIpv6: parsedGeoDataIpv6,
  51. geotrieIpv6: ipv6Trie,
  52. sysdb: sysdb,
  53. option: option,
  54. }, nil
  55. }
  56. func (s *Store) ResolveCountryCodeFromIP(ipstring string) (*CountryInfo, error) {
  57. cc := s.search(ipstring)
  58. return &CountryInfo{
  59. CountryIsoCode: cc,
  60. ContinetCode: "",
  61. }, nil
  62. }
  63. func (s *Store) Close() {
  64. }
  65. func (s *Store) GetRequesterCountryISOCode(r *http.Request) string {
  66. ipAddr := netutils.GetRequesterIP(r)
  67. if ipAddr == "" {
  68. return ""
  69. }
  70. if netutils.IsPrivateIP(ipAddr) {
  71. return "LAN"
  72. }
  73. countryCode, err := s.ResolveCountryCodeFromIP(ipAddr)
  74. if err != nil {
  75. return ""
  76. }
  77. return countryCode.CountryIsoCode
  78. }