added example package

This commit is contained in:
2022-12-11 06:18:00 +00:00
parent fc9ed17ecd
commit 73b8a7c2a3
811 changed files with 276135 additions and 1 deletions

1
vendor/github.com/IncSW/geoip2/.gitignore generated vendored Normal file
View File

@@ -0,0 +1 @@
testdata

21
vendor/github.com/IncSW/geoip2/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017 Aleksey Lin <aleksey@incsw.in> (https://incsw.in)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

94
vendor/github.com/IncSW/geoip2/README.md generated vendored Normal file
View File

@@ -0,0 +1,94 @@
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
[![Go Report Card](https://goreportcard.com/badge/github.com/IncSW/geoip2?style=flat-square)](https://goreportcard.com/report/github.com/IncSW/geoip2)
[![Go Doc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/IncSW/geoip2?tab=doc)
# GeoIP2 Reader for Go
This library reads MaxMind GeoIP2 databases.
Inspired by [oschwald/geoip2-golang](https://github.com/oschwald/geoip2-golang).
## Installation
`go get github.com/IncSW/geoip2`
## Quick Start
```go
import "github.com/IncSW/geoip2"
reader, err := geoip2.NewCityReaderFromFile("path/to/GeoIP2-City.mmdb")
if err != nil {
panic(err)
}
record, err := reader.Lookup(net.ParseIP("81.2.69.142"))
if err != nil {
panic(err)
}
println(record.Continent.Names["zh-CN"]) // 欧洲
println(record.City.Names["pt-BR"]) // Wimbledon
if len(record.Subdivisions) != 0 {
println(record.Subdivisions[0].Names["en"]) // England
}
println(record.Country.Names["ru"]) // Великобритания
println(record.Country.ISOCode) // GB
println(record.Location.TimeZone) // Europe/London
println(record.Country.GeoNameID) // 2635167, https://www.geonames.org/2635167
```
## Performance
### [IncSW/geoip2](https://github.com/IncSW/geoip2)
```
city-24 342847 2981 ns/op 2032 B/op 12 allocs/op
city_parallel-24 4477626 269 ns/op 2032 B/op 12 allocs/op
isp-24 3539738 336 ns/op 64 B/op 1 allocs/op
isp_parallel-24 46938070 25.7 ns/op 64 B/op 1 allocs/op
connection_type-24 8759110 133 ns/op 0 B/op 0 allocs/op
connection_type_parallel-24 142261742 8.34 ns/op 0 B/op 0 allocs/op
```
### [oschwald/geoip2-golang](https://github.com/oschwald/geoip2-golang)
```
city-24 109092 10717 ns/op 2848 B/op 103 allocs/op
city_parallel-24 662510 1718 ns/op 2848 B/op 103 allocs/op
isp-24 1688287 705 ns/op 112 B/op 4 allocs/op
isp_parallel-24 14285560 84.4 ns/op 112 B/op 4 allocs/op
connection_type-24 3883234 305 ns/op 32 B/op 2 allocs/op
connection_type_parallel-24 34284831 32.1 ns/op 32 B/op 2 allocs/op
```
## Supported databases types
### Country
- GeoIP2-Country
- GeoLite2-Country
- DBIP-Country
- DBIP-Country-Lite
### City
- GeoIP2-City
- GeoLite2-City
- GeoIP2-Enterprise
- DBIP-City-Lite
### ISP
- GeoIP2-ISP
### ASN
- GeoLite2-ASN
- DBIP-ASN-Lite
- DBIP-ASN-Lite (compat=GeoLite2-ASN)
### Connection Type
- GeoIP2-Connection-Type
### Anonymous IP
- GeoIP2-Anonymous-IP
### Domain
- GeoIP2-Domain
## License
[MIT License](LICENSE).

49
vendor/github.com/IncSW/geoip2/anonymous_ip.go generated vendored Normal file
View File

@@ -0,0 +1,49 @@
package geoip2
import "errors"
func readAnonymousIPMap(result *AnonymousIP, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "is_anonymous":
result.IsAnonymous, offset, err = readBool(buffer, offset)
if err != nil {
return 0, err
}
case "is_anonymous_vpn":
result.IsAnonymousVPN, offset, err = readBool(buffer, offset)
if err != nil {
return 0, err
}
case "is_hosting_provider":
result.IsHostingProvider, offset, err = readBool(buffer, offset)
if err != nil {
return 0, err
}
case "is_public_proxy":
result.IsPublicProxy, offset, err = readBool(buffer, offset)
if err != nil {
return 0, err
}
case "is_tor_exit_node":
result.IsTorExitNode, offset, err = readBool(buffer, offset)
if err != nil {
return 0, err
}
case "is_residential_proxy":
result.IsResidentialProxy, offset, err = readBool(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown anonymous ip key: " + string(key))
}
}
return offset, nil
}

29
vendor/github.com/IncSW/geoip2/asn.go generated vendored Normal file
View File

@@ -0,0 +1,29 @@
package geoip2
import "errors"
func readASNMap(result *ASN, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "autonomous_system_number":
result.AutonomousSystemNumber, offset, err = readUInt32(buffer, offset)
if err != nil {
return 0, err
}
case "autonomous_system_organization":
result.AutonomousSystemOrganization, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown asn key: " + string(key))
}
}
return offset, nil
}

67
vendor/github.com/IncSW/geoip2/city.go generated vendored Normal file
View File

@@ -0,0 +1,67 @@
package geoip2
import (
"errors"
"strconv"
)
func readCity(city *City, buffer []byte, offset uint) (uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return 0, err
}
switch dataType {
case dataTypeMap:
return readCityMap(city, buffer, size, offset)
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return 0, err
}
if dataType != dataTypeMap {
return 0, errors.New("invalid city pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readCityMap(city, buffer, size, offset)
if err != nil {
return 0, err
}
return newOffset, nil
default:
return 0, errors.New("invalid city type: " + strconv.Itoa(int(dataType)))
}
}
func readCityMap(city *City, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "geoname_id":
city.GeoNameID, offset, err = readUInt32(buffer, offset)
if err != nil {
return 0, err
}
case "names":
city.Names, offset, err = readStringMap(buffer, offset)
if err != nil {
return 0, err
}
case "confidence":
city.Confidence, offset, err = readUInt16(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown city key: " + string(key))
}
}
return offset, nil
}

370
vendor/github.com/IncSW/geoip2/common.go generated vendored Normal file
View File

@@ -0,0 +1,370 @@
package geoip2
import (
"encoding/binary"
"errors"
"math"
"strconv"
"unsafe"
)
func readControl(buffer []byte, offset uint) (byte, uint, uint, error) {
controlByte := buffer[offset]
offset++
dataType := controlByte >> 5
if dataType == dataTypeExtended {
dataType = buffer[offset] + 7
offset++
}
size := uint(controlByte & 0x1f)
if dataType == dataTypeExtended || size < 29 {
return dataType, size, offset, nil
}
bytesToRead := size - 28
newOffset := offset + bytesToRead
if newOffset > uint(len(buffer)) {
return 0, 0, 0, errors.New("invalid offset")
}
size = uint(bytesToUInt64(buffer[offset:newOffset]))
switch bytesToRead {
case 1:
size += 29
case 2:
size += 285
default:
size += 65821
}
return dataType, size, newOffset, nil
}
func readPointer(buffer []byte, size uint, offset uint) (uint, uint, error) {
pointerSize := ((size >> 3) & 0x3) + 1
newOffset := offset + pointerSize
if newOffset > uint(len(buffer)) {
return 0, 0, errors.New("invalid offset")
}
prefix := uint64(0)
if pointerSize != 4 {
prefix = uint64(size) & 0x7
}
unpacked := uint(bytesToUInt64WithPrefix(prefix, buffer[offset:newOffset]))
pointerValueOffset := uint(0)
switch pointerSize {
case 2:
pointerValueOffset = 2048
case 3:
pointerValueOffset = 526336
case 4:
pointerValueOffset = 0
}
return unpacked + pointerValueOffset, newOffset, nil
}
func readFloat64(buffer []byte, offset uint) (float64, uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return 0, 0, err
}
switch dataType {
case dataTypeFloat64:
newOffset := offset + size
return bytesToFloat64(buffer[offset:newOffset]), newOffset, nil
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return 0, 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return 0, 0, err
}
if dataType != dataTypeFloat64 {
return 0, 0, errors.New("invalid float64 pointer type: " + strconv.Itoa(int(dataType)))
}
return bytesToFloat64(buffer[offset : offset+size]), newOffset, nil
default:
return 0, 0, errors.New("invalid float64 type: " + strconv.Itoa(int(dataType)))
}
}
func readUInt16(buffer []byte, offset uint) (uint16, uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return 0, 0, err
}
switch dataType {
case dataTypeUint16:
newOffset := offset + size
return uint16(bytesToUInt64(buffer[offset:newOffset])), newOffset, nil
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return 0, 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return 0, 0, err
}
if dataType != dataTypeUint16 {
return 0, 0, errors.New("invalid uint16 pointer type: " + strconv.Itoa(int(dataType)))
}
return uint16(bytesToUInt64(buffer[offset : offset+size])), newOffset, nil
default:
return 0, 0, errors.New("invalid uint16 type: " + strconv.Itoa(int(dataType)))
}
}
func readUInt32(buffer []byte, offset uint) (uint32, uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return 0, 0, err
}
switch dataType {
case dataTypeUint32:
newOffset := offset + size
return uint32(bytesToUInt64(buffer[offset:newOffset])), newOffset, nil
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return 0, 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return 0, 0, err
}
if dataType != dataTypeUint32 {
return 0, 0, errors.New("invalid uint32 pointer type: " + strconv.Itoa(int(dataType)))
}
return uint32(bytesToUInt64(buffer[offset : offset+size])), newOffset, nil
default:
return 0, 0, errors.New("invalid uint32 type: " + strconv.Itoa(int(dataType)))
}
}
func readBool(buffer []byte, offset uint) (bool, uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return false, 0, err
}
switch dataType {
case dataTypeBool:
return size != 0, offset, nil
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return false, 0, err
}
dataType, size, _, err := readControl(buffer, pointer)
if err != nil {
return false, 0, err
}
if dataType != dataTypeBool {
return false, 0, errors.New("invalid bool pointer type: " + strconv.Itoa(int(dataType)))
}
return size != 0, newOffset, nil
default:
return false, 0, errors.New("invalid bool type: " + strconv.Itoa(int(dataType)))
}
}
func readString(buffer []byte, offset uint) (string, uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return "", 0, err
}
switch dataType {
case dataTypeString:
newOffset := offset + size
return b2s(buffer[offset:newOffset]), newOffset, nil
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return "", 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return "", 0, err
}
if dataType != dataTypeString {
return "", 0, errors.New("invalid string pointer type: " + strconv.Itoa(int(dataType)))
}
return b2s(buffer[offset : offset+size]), newOffset, nil
default:
return "", 0, errors.New("invalid string type: " + strconv.Itoa(int(dataType)))
}
}
func readStringMap(buffer []byte, offset uint) (map[string]string, uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return nil, 0, err
}
switch dataType {
case dataTypeMap:
return readStringMapMap(buffer, size, offset)
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return nil, 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return nil, 0, err
}
if dataType != dataTypeMap {
return nil, 0, errors.New("invalid stringMap pointer type: " + strconv.Itoa(int(dataType)))
}
value, _, err := readStringMapMap(buffer, size, offset)
if err != nil {
return nil, 0, err
}
return value, newOffset, nil
default:
return nil, 0, errors.New("invalid stringMap type: " + strconv.Itoa(int(dataType)))
}
}
func readStringMapMap(buffer []byte, mapSize uint, offset uint) (map[string]string, uint, error) {
var key []byte
var err error
var dataType byte
var size uint
result := map[string]string{}
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return nil, 0, err
}
dataType, size, offset, err = readControl(buffer, offset)
if err != nil {
return nil, 0, err
}
switch dataType {
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return nil, 0, err
}
dataType, size, valueOffset, err := readControl(buffer, pointer)
if err != nil {
return nil, 0, err
}
if dataType != dataTypeString {
return nil, 0, errors.New("map key must be a string, got: " + strconv.Itoa(int(dataType)))
}
offset = newOffset
result[b2s(key)] = b2s(buffer[valueOffset : valueOffset+size])
case dataTypeString:
newOffset := offset + size
value := b2s(buffer[offset:newOffset])
offset = newOffset
result[b2s(key)] = value
default:
return nil, 0, errors.New("invalid data type of key " + string(key) + ": " + strconv.Itoa(int(dataType)))
}
}
return result, offset, nil
}
func readMapKey(buffer []byte, offset uint) ([]byte, uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return nil, 0, err
}
if dataType == dataTypePointer {
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return nil, 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return nil, 0, err
}
if dataType != dataTypeString {
return nil, 0, errors.New("map key must be a string, got: " + strconv.Itoa(int(dataType)))
}
return buffer[offset : offset+size], newOffset, nil
}
if dataType != dataTypeString {
return nil, 0, errors.New("map key must be a string, got: " + strconv.Itoa(int(dataType)))
}
newOffset := offset + size
if newOffset > uint(len(buffer)) {
return nil, 0, errors.New("invalid offset")
}
return buffer[offset:newOffset], newOffset, nil
}
func readStringSlice(buffer []byte, sliceSize uint, offset uint) ([]string, uint, error) {
var err error
var value string
result := make([]string, sliceSize)
for i := uint(0); i < sliceSize; i++ {
value, offset, err = readString(buffer, offset)
if err != nil {
return nil, 0, err
}
result[i] = value
}
return result, offset, nil
}
func bytesToUInt64(buffer []byte) uint64 {
switch len(buffer) {
case 1:
return uint64(buffer[0])
case 2:
return uint64(buffer[0])<<8 | uint64(buffer[1])
case 3:
return (uint64(buffer[0])<<8|uint64(buffer[1]))<<8 | uint64(buffer[2])
case 4:
return ((uint64(buffer[0])<<8|uint64(buffer[1]))<<8|uint64(buffer[2]))<<8 | uint64(buffer[3])
case 5:
return (((uint64(buffer[0])<<8|uint64(buffer[1]))<<8|uint64(buffer[2]))<<8|uint64(buffer[3]))<<8 | uint64(buffer[4])
case 6:
return ((((uint64(buffer[0])<<8|uint64(buffer[1]))<<8|uint64(buffer[2]))<<8|uint64(buffer[3]))<<8|uint64(buffer[4]))<<8 | uint64(buffer[5])
case 7:
return (((((uint64(buffer[0])<<8|uint64(buffer[1]))<<8|uint64(buffer[2]))<<8|uint64(buffer[3]))<<8|uint64(buffer[4]))<<8|uint64(buffer[5]))<<8 | uint64(buffer[6])
case 8:
return ((((((uint64(buffer[0])<<8|uint64(buffer[1]))<<8|uint64(buffer[2]))<<8|uint64(buffer[3]))<<8|uint64(buffer[4]))<<8|uint64(buffer[5]))<<8|uint64(buffer[6]))<<8 | uint64(buffer[7])
}
return 0
}
func bytesToUInt64WithPrefix(prefix uint64, buffer []byte) uint64 {
switch len(buffer) {
case 0:
return prefix
case 1:
return prefix<<8 | uint64(buffer[0])
case 2:
return (prefix<<8|uint64(buffer[0]))<<8 | uint64(buffer[1])
case 3:
return ((prefix<<8|uint64(buffer[0]))<<8|uint64(buffer[1]))<<8 | uint64(buffer[2])
case 4:
return (((prefix<<8|uint64(buffer[0]))<<8|uint64(buffer[1]))<<8|uint64(buffer[2]))<<8 | uint64(buffer[3])
case 5:
return ((((prefix<<8|uint64(buffer[0]))<<8|uint64(buffer[1]))<<8|uint64(buffer[2]))<<8|uint64(buffer[3]))<<8 | uint64(buffer[4])
case 6:
return (((((prefix<<8|uint64(buffer[0]))<<8|uint64(buffer[1]))<<8|uint64(buffer[2]))<<8|uint64(buffer[3]))<<8|uint64(buffer[4]))<<8 | uint64(buffer[5])
case 7:
return ((((((prefix<<8|uint64(buffer[0]))<<8|uint64(buffer[1]))<<8|uint64(buffer[2]))<<8|uint64(buffer[3]))<<8|uint64(buffer[4]))<<8|uint64(buffer[5]))<<8 | uint64(buffer[6])
case 8:
return (((((((prefix<<8|uint64(buffer[0]))<<8|uint64(buffer[1]))<<8|uint64(buffer[2]))<<8|uint64(buffer[3]))<<8|uint64(buffer[4]))<<8|uint64(buffer[5]))<<8|uint64(buffer[6]))<<8 | uint64(buffer[7])
}
return 0
}
func bytesToFloat32(buffer []byte) float32 {
bits := binary.BigEndian.Uint32(buffer)
return math.Float32frombits(bits)
}
func bytesToFloat64(buffer []byte) float64 {
bits := binary.BigEndian.Uint64(buffer)
return math.Float64frombits(bits)
}
func b2s(value []byte) string {
return *(*string)(unsafe.Pointer(&value))
}

24
vendor/github.com/IncSW/geoip2/connection_type.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
package geoip2
import "errors"
func readConnectionTypeMap(result *ConnectionType, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "connection_type":
result.ConnectionType, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown connectionType key: " + string(key))
}
}
return offset, nil
}

67
vendor/github.com/IncSW/geoip2/continent.go generated vendored Normal file
View File

@@ -0,0 +1,67 @@
package geoip2
import (
"errors"
"strconv"
)
func readContinent(continent *Continent, buffer []byte, offset uint) (uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return 0, err
}
switch dataType {
case dataTypeMap:
return readContinentMap(continent, buffer, size, offset)
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return 0, err
}
if dataType != dataTypeMap {
return 0, errors.New("invalid continent pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readContinentMap(continent, buffer, size, offset)
if err != nil {
return 0, err
}
return newOffset, nil
default:
return 0, errors.New("invalid continent type: " + strconv.Itoa(int(dataType)))
}
}
func readContinentMap(continent *Continent, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "geoname_id":
continent.GeoNameID, offset, err = readUInt32(buffer, offset)
if err != nil {
return 0, err
}
case "code":
continent.Code, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "names":
continent.Names, offset, err = readStringMap(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown continent key: " + string(key))
}
}
return offset, nil
}

82
vendor/github.com/IncSW/geoip2/country.go generated vendored Normal file
View File

@@ -0,0 +1,82 @@
package geoip2
import (
"errors"
"strconv"
)
func readCountry(country *Country, buffer []byte, offset uint) (uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return 0, err
}
switch dataType {
case dataTypeMap:
return readCountryMap(country, buffer, size, offset)
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return 0, err
}
if dataType != dataTypeMap {
return 0, errors.New("invalid country pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readCountryMap(country, buffer, size, offset)
if err != nil {
return 0, err
}
return newOffset, nil
default:
return 0, errors.New("invalid country type: " + strconv.Itoa(int(dataType)))
}
}
func readCountryMap(country *Country, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "geoname_id":
country.GeoNameID, offset, err = readUInt32(buffer, offset)
if err != nil {
return 0, err
}
case "iso_code":
country.ISOCode, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "names":
country.Names, offset, err = readStringMap(buffer, offset)
if err != nil {
return 0, err
}
case "is_in_european_union":
country.IsInEuropeanUnion, offset, err = readBool(buffer, offset)
if err != nil {
return 0, err
}
case "type":
country.Type, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "confidence":
country.Confidence, offset, err = readUInt16(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown country key: " + string(key))
}
}
return offset, nil
}

24
vendor/github.com/IncSW/geoip2/domain.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
package geoip2
import "errors"
func readDomainMap(result *Domain, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "domain":
result.Domain, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown domain key: " + string(key))
}
}
return offset, nil
}

49
vendor/github.com/IncSW/geoip2/isp.go generated vendored Normal file
View File

@@ -0,0 +1,49 @@
package geoip2
import "errors"
func readISPMap(result *ISP, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "autonomous_system_number":
result.AutonomousSystemNumber, offset, err = readUInt32(buffer, offset)
if err != nil {
return 0, err
}
case "autonomous_system_organization":
result.AutonomousSystemOrganization, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "isp":
result.ISP, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "organization":
result.Organization, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "mobile_country_code":
result.MobileCountryCode, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "mobile_network_code":
result.MobileNetworkCode, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown isp key: " + string(key))
}
}
return offset, nil
}

77
vendor/github.com/IncSW/geoip2/location.go generated vendored Normal file
View File

@@ -0,0 +1,77 @@
package geoip2
import (
"errors"
"strconv"
)
func readLocation(location *Location, buffer []byte, offset uint) (uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return 0, err
}
switch dataType {
case dataTypeMap:
return readLocationMap(location, buffer, size, offset)
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return 0, err
}
if dataType != dataTypeMap {
return 0, errors.New("invalid location pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readLocationMap(location, buffer, size, offset)
if err != nil {
return 0, err
}
return newOffset, nil
default:
return 0, errors.New("invalid location type: " + strconv.Itoa(int(dataType)))
}
}
func readLocationMap(location *Location, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "latitude":
location.Latitude, offset, err = readFloat64(buffer, offset)
if err != nil {
return 0, err
}
case "longitude":
location.Longitude, offset, err = readFloat64(buffer, offset)
if err != nil {
return 0, err
}
case "accuracy_radius":
location.AccuracyRadius, offset, err = readUInt16(buffer, offset)
if err != nil {
return 0, err
}
case "time_zone":
location.TimeZone, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "metro_code":
location.MetroCode, offset, err = readUInt16(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown location key: " + string(key))
}
}
return offset, nil
}

108
vendor/github.com/IncSW/geoip2/metadata.go generated vendored Normal file
View File

@@ -0,0 +1,108 @@
package geoip2
import (
"errors"
"strconv"
)
type Metadata struct {
NodeCount uint32 // node_count This is an unsigned 32-bit integer indicating the number of nodes in the search tree.
RecordSize uint16 // record_size This is an unsigned 16-bit integer. It indicates the number of bits in a record in the search tree. Note that each node consists of two records.
IPVersion uint16 // ip_version This is an unsigned 16-bit integer which is always 4 or 6. It indicates whether the database contains IPv4 or IPv6 address data.
DatabaseType string // database_type This is a string that indicates the structure of each data record associated with an IP address. The actual definition of these structures is left up to the database creator. Names starting with “GeoIP” are reserved for use by MaxMind (and “GeoIP” is a trademark anyway).
Languages []string // languages An array of strings, each of which is a locale code. A given record may contain data items that have been localized to some or all of these locales. Records should not contain localized data for locales not included in this array. This is an optional key, as this may not be relevant for all types of data.
BinaryFormatMajorVersion uint16 // binary_format_major_version This is an unsigned 16-bit integer indicating the major version number for the databases binary format.
BinaryFormatMinorVersion uint16 // binary_format_minor_version This is an unsigned 16-bit integer indicating the minor version number for the databases binary format.
BuildEpoch uint64 // build_epoch This is an unsigned 64-bit integer that contains the database build timestamp as a Unix epoch value.
Description map[string]string // description This key will always point to a map. The keys of that map will be language codes, and the values will be a description in that language as a UTF-8 string. The codes may include additional information such as script or country identifiers, like “zh-TW” or “mn-Cyrl-MN”. The additional identifiers will be separated by a dash character (“-“).
}
var metadataStartMarker = []byte("\xAB\xCD\xEFMaxMind.com")
func readMetadata(buffer []byte) (*Metadata, error) {
dataType, metadataSize, offset, err := readControl(buffer, 0)
if err != nil {
return nil, err
}
if dataType != dataTypeMap {
return nil, errors.New("invalid metadata type: " + strconv.Itoa(int(dataType)))
}
var key []byte
metadata := &Metadata{}
for i := uint(0); i < metadataSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return nil, err
}
size := uint(0)
dataType, size, offset, err = readControl(buffer, offset)
if err != nil {
return nil, err
}
newOffset := uint(0)
switch b2s(key) {
case "binary_format_major_version":
if dataType != dataTypeUint16 {
return nil, errors.New("invalid binary_format_major_version type: " + strconv.Itoa(int(dataType)))
}
newOffset = offset + size
metadata.BinaryFormatMajorVersion = uint16(bytesToUInt64(buffer[offset:newOffset]))
case "binary_format_minor_version":
if dataType != dataTypeUint16 {
return nil, errors.New("invalid binary_format_minor_version type: " + strconv.Itoa(int(dataType)))
}
newOffset = offset + size
metadata.BinaryFormatMinorVersion = uint16(bytesToUInt64(buffer[offset:newOffset]))
case "build_epoch":
if dataType != dataTypeUint64 {
return nil, errors.New("invalid build_epoch type: " + strconv.Itoa(int(dataType)))
}
newOffset = offset + size
metadata.BuildEpoch = bytesToUInt64(buffer[offset:newOffset])
case "database_type":
if dataType != dataTypeString {
return nil, errors.New("invalid database_type type: " + strconv.Itoa(int(dataType)))
}
newOffset = offset + size
metadata.DatabaseType = b2s(buffer[offset:newOffset])
case "description":
if dataType != dataTypeMap {
return nil, errors.New("invalid description type: " + strconv.Itoa(int(dataType)))
}
metadata.Description, newOffset, err = readStringMapMap(buffer, size, offset)
if err != nil {
return nil, err
}
case "ip_version":
if dataType != dataTypeUint16 {
return nil, errors.New("invalid ip_version type: " + strconv.Itoa(int(dataType)))
}
newOffset = offset + size
metadata.IPVersion = uint16(bytesToUInt64(buffer[offset:newOffset]))
case "languages":
if dataType != dataTypeSlice {
return nil, errors.New("invalid languages type: " + strconv.Itoa(int(dataType)))
}
metadata.Languages, newOffset, err = readStringSlice(buffer, size, offset)
if err != nil {
return nil, err
}
case "node_count":
if dataType != dataTypeUint32 {
return nil, errors.New("invalid node_count type: " + strconv.Itoa(int(dataType)))
}
newOffset = offset + size
metadata.NodeCount = uint32(bytesToUInt64(buffer[offset:newOffset]))
case "record_size":
if dataType != dataTypeUint16 {
return nil, errors.New("invalid record_size type: " + strconv.Itoa(int(dataType)))
}
newOffset = offset + size
metadata.RecordSize = uint16(bytesToUInt64(buffer[offset:newOffset]))
default:
return nil, errors.New("unknown key: " + string(key) + ", type: " + strconv.Itoa(int(dataType)))
}
offset = newOffset
}
return metadata, nil
}

62
vendor/github.com/IncSW/geoip2/postal.go generated vendored Normal file
View File

@@ -0,0 +1,62 @@
package geoip2
import (
"errors"
"strconv"
)
func readPostal(postal *Postal, buffer []byte, offset uint) (uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return 0, err
}
switch dataType {
case dataTypeMap:
return readPostalMap(postal, buffer, size, offset)
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return 0, err
}
if dataType != dataTypeMap {
return 0, errors.New("invalid postal pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readPostalMap(postal, buffer, size, offset)
if err != nil {
return 0, err
}
return newOffset, nil
default:
return 0, errors.New("invalid postal type: " + strconv.Itoa(int(dataType)))
}
}
func readPostalMap(postal *Postal, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "code":
postal.Code, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "confidence":
postal.Confidence, offset, err = readUInt16(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown postal key: " + string(key))
}
}
return offset, nil
}

124
vendor/github.com/IncSW/geoip2/reader.go generated vendored Normal file
View File

@@ -0,0 +1,124 @@
package geoip2
import (
"bytes"
"errors"
"net"
"strconv"
)
var ErrNotFound = errors.New("not found")
type reader struct {
metadata *Metadata
buffer []byte
decoderBuffer []byte
nodeBuffer []byte
ipV4Start uint
ipV4StartBitDepth uint
nodeOffsetMult uint
}
func (r *reader) getOffset(ip net.IP) (uint, error) {
pointer, err := r.lookupPointer(ip)
if err != nil {
return 0, err
}
offset := pointer - uint(r.metadata.NodeCount) - uint(dataSectionSeparatorSize)
if offset >= uint(len(r.buffer)) {
return 0, errors.New("the MaxMind DB search tree is corrupt: " + strconv.Itoa(int(pointer)))
}
return offset, nil
}
func (r *reader) lookupPointer(ip net.IP) (uint, error) {
if ip == nil {
return 0, errors.New("IP cannot be nil")
}
ipV4 := ip.To4()
if ipV4 != nil {
ip = ipV4
}
if len(ip) == 16 && r.metadata.IPVersion == 4 {
return 0, errors.New("cannot look up an IPv6 address in an IPv4-only database")
}
bitCount := uint(len(ip)) * 8
node := uint(0)
if bitCount == 32 {
node = r.ipV4Start
}
nodeCount := uint(r.metadata.NodeCount)
i := uint(0)
for ; i < bitCount && node < nodeCount; i++ {
bit := 1 & (ip[i>>3] >> (7 - (i % 8)))
offset := node * r.nodeOffsetMult
if bit == 0 {
node = r.readLeft(offset)
} else {
node = r.readRight(offset)
}
}
if node == nodeCount {
return 0, ErrNotFound
} else if node > nodeCount {
return node, nil
}
return 0, errors.New("invalid node in search tree")
}
func (r *reader) readLeft(nodeNumber uint) uint {
switch r.metadata.RecordSize {
case 28:
return ((uint(r.nodeBuffer[nodeNumber+3]) & 0xF0) << 20) | (uint(r.nodeBuffer[nodeNumber]) << 16) | (uint(r.nodeBuffer[nodeNumber+1]) << 8) | uint(r.nodeBuffer[nodeNumber+2])
case 24:
return (uint(r.nodeBuffer[nodeNumber]) << 16) | (uint(r.nodeBuffer[nodeNumber+1]) << 8) | uint(r.nodeBuffer[nodeNumber+2])
default: // case 32:
return (uint(r.nodeBuffer[nodeNumber]) << 24) | (uint(r.nodeBuffer[nodeNumber+1]) << 16) | (uint(r.nodeBuffer[nodeNumber+2]) << 8) | uint(r.nodeBuffer[nodeNumber+3])
}
}
func (r *reader) readRight(nodeNumber uint) uint {
switch r.metadata.RecordSize {
case 28:
return ((uint(r.nodeBuffer[nodeNumber+3]) & 0x0F) << 24) | (uint(r.nodeBuffer[nodeNumber+4]) << 16) | (uint(r.nodeBuffer[nodeNumber+5]) << 8) | uint(r.nodeBuffer[nodeNumber+6])
case 24:
return (uint(r.nodeBuffer[nodeNumber+3]) << 16) | (uint(r.nodeBuffer[nodeNumber+4]) << 8) | uint(r.nodeBuffer[nodeNumber+5])
default: // case 32:
return (uint(r.nodeBuffer[nodeNumber+4]) << 24) | (uint(r.nodeBuffer[nodeNumber+5]) << 16) | (uint(r.nodeBuffer[nodeNumber+6]) << 8) | uint(r.nodeBuffer[nodeNumber+7])
}
}
func newReader(buffer []byte) (*reader, error) {
if len(buffer) == 0 {
return nil, errors.New("buffer is empty")
}
metadataStart := bytes.LastIndex(buffer, metadataStartMarker)
metadata, err := readMetadata(buffer[metadataStart+len(metadataStartMarker):])
if err != nil {
return nil, err
}
nodeOffsetMult := uint(metadata.RecordSize) / 4
searchTreeSize := uint(metadata.NodeCount) * nodeOffsetMult
dataSectionStart := searchTreeSize + dataSectionSeparatorSize
if dataSectionStart > uint(metadataStart) {
return nil, errors.New("the MaxMind DB contains invalid metadata")
}
reader := &reader{
metadata: metadata,
buffer: buffer,
decoderBuffer: buffer[searchTreeSize+dataSectionSeparatorSize : metadataStart],
nodeBuffer: buffer[:searchTreeSize],
nodeOffsetMult: nodeOffsetMult,
}
if metadata.IPVersion == 6 {
node := uint(0)
i := uint(0)
for ; i < 96 && node < uint(metadata.NodeCount); i++ {
node = reader.readLeft(node * nodeOffsetMult)
}
reader.ipV4Start = node
reader.ipV4StartBitDepth = i
}
return reader, nil
}

71
vendor/github.com/IncSW/geoip2/reader_anonymous_ip.go generated vendored Normal file
View File

@@ -0,0 +1,71 @@
package geoip2
import (
"errors"
"io/ioutil"
"net"
"strconv"
)
type AnonymousIPReader struct {
*reader
}
func (r *AnonymousIPReader) Lookup(ip net.IP) (*AnonymousIP, error) {
offset, err := r.getOffset(ip)
if err != nil {
return nil, err
}
dataType, size, offset, err := readControl(r.decoderBuffer, offset)
if err != nil {
return nil, err
}
result := &AnonymousIP{}
switch dataType {
case dataTypeMap:
_, err = readAnonymousIPMap(result, r.decoderBuffer, size, offset)
if err != nil {
return nil, err
}
case dataTypePointer:
pointer, _, err := readPointer(r.decoderBuffer, size, offset)
if err != nil {
return nil, err
}
dataType, size, offset, err := readControl(r.decoderBuffer, pointer)
if err != nil {
return nil, err
}
if dataType != dataTypeMap {
return nil, errors.New("invalid Anonymous-IP pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readAnonymousIPMap(result, r.decoderBuffer, size, offset)
if err != nil {
return nil, err
}
default:
return nil, errors.New("invalid Anonymous-IP type: " + strconv.Itoa(int(dataType)))
}
return result, nil
}
func NewAnonymousIPReader(buffer []byte) (*AnonymousIPReader, error) {
reader, err := newReader(buffer)
if err != nil {
return nil, err
}
if reader.metadata.DatabaseType != "GeoIP2-Anonymous-IP" {
return nil, errors.New("wrong MaxMind DB Anonymous-IP type: " + reader.metadata.DatabaseType)
}
return &AnonymousIPReader{
reader: reader,
}, nil
}
func NewAnonymousIPReaderFromFile(filename string) (*AnonymousIPReader, error) {
buffer, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return NewAnonymousIPReader(buffer)
}

73
vendor/github.com/IncSW/geoip2/reader_asn.go generated vendored Normal file
View File

@@ -0,0 +1,73 @@
package geoip2
import (
"errors"
"io/ioutil"
"net"
"strconv"
)
type ASNReader struct {
*reader
}
func (r *ASNReader) Lookup(ip net.IP) (*ASN, error) {
offset, err := r.getOffset(ip)
if err != nil {
return nil, err
}
dataType, size, offset, err := readControl(r.decoderBuffer, offset)
if err != nil {
return nil, err
}
result := &ASN{}
switch dataType {
case dataTypeMap:
_, err = readASNMap(result, r.decoderBuffer, size, offset)
if err != nil {
return nil, err
}
case dataTypePointer:
pointer, _, err := readPointer(r.decoderBuffer, size, offset)
if err != nil {
return nil, err
}
dataType, size, offset, err := readControl(r.decoderBuffer, pointer)
if err != nil {
return nil, err
}
if dataType != dataTypeMap {
return nil, errors.New("invalid ASN pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readASNMap(result, r.decoderBuffer, size, offset)
if err != nil {
return nil, err
}
default:
return nil, errors.New("invalid ASN type: " + strconv.Itoa(int(dataType)))
}
return result, nil
}
func NewASNReader(buffer []byte) (*ASNReader, error) {
reader, err := newReader(buffer)
if err != nil {
return nil, err
}
if reader.metadata.DatabaseType != "GeoLite2-ASN" &&
reader.metadata.DatabaseType != "DBIP-ASN-Lite" &&
reader.metadata.DatabaseType != "DBIP-ASN-Lite (compat=GeoLite2-ASN)" {
return nil, errors.New("wrong MaxMind DB ASN type: " + reader.metadata.DatabaseType)
}
return &ASNReader{
reader: reader,
}, nil
}
func NewASNReaderFromFile(filename string) (*ASNReader, error) {
buffer, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return NewASNReader(buffer)
}

116
vendor/github.com/IncSW/geoip2/reader_city.go generated vendored Normal file
View File

@@ -0,0 +1,116 @@
package geoip2
import (
"errors"
"io/ioutil"
"net"
"strconv"
)
type CityReader struct {
*reader
}
func (r *CityReader) Lookup(ip net.IP) (*CityResult, error) {
offset, err := r.getOffset(ip)
if err != nil {
return nil, err
}
dataType, size, offset, err := readControl(r.decoderBuffer, offset)
if err != nil {
return nil, err
}
if dataType != dataTypeMap {
return nil, errors.New("invalid City type: " + strconv.Itoa(int(dataType)))
}
var key []byte
result := &CityResult{}
for i := uint(0); i < size; i++ {
key, offset, err = readMapKey(r.decoderBuffer, offset)
if err != nil {
return nil, err
}
switch b2s(key) {
case "city":
offset, err = readCity(&result.City, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "continent":
offset, err = readContinent(&result.Continent, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "country":
offset, err = readCountry(&result.Country, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "location":
offset, err = readLocation(&result.Location, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "postal":
offset, err = readPostal(&result.Postal, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "registered_country":
offset, err = readCountry(&result.RegisteredCountry, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "represented_country":
offset, err = readCountry(&result.RepresentedCountry, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "subdivisions":
result.Subdivisions, offset, err = readSubdivisions(r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "traits":
offset, err = readTraits(&result.Traits, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
default:
return nil, errors.New("unknown City response key: " + string(key) + ", type: " + strconv.Itoa(int(dataType)))
}
}
return result, nil
}
func NewCityReader(buffer []byte) (*CityReader, error) {
reader, err := newReader(buffer)
if err != nil {
return nil, err
}
if reader.metadata.DatabaseType != "GeoIP2-City" &&
reader.metadata.DatabaseType != "GeoLite2-City" &&
reader.metadata.DatabaseType != "GeoIP2-Enterprise" &&
reader.metadata.DatabaseType != "DBIP-City-Lite" {
return nil, errors.New("wrong MaxMind DB City type: " + reader.metadata.DatabaseType)
}
return &CityReader{
reader: reader,
}, nil
}
func NewCityReaderFromFile(filename string) (*CityReader, error) {
buffer, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return NewCityReader(buffer)
}
func NewEnterpriseReader(buffer []byte) (*CityReader, error) {
return NewCityReader(buffer)
}
func NewEnterpriseReaderFromFile(filename string) (*CityReader, error) {
return NewCityReaderFromFile(filename)
}

View File

@@ -0,0 +1,71 @@
package geoip2
import (
"errors"
"io/ioutil"
"net"
"strconv"
)
type ConnectionTypeReader struct {
*reader
}
func (r *ConnectionTypeReader) Lookup(ip net.IP) (string, error) {
offset, err := r.getOffset(ip)
if err != nil {
return "", err
}
dataType, size, offset, err := readControl(r.decoderBuffer, offset)
if err != nil {
return "", err
}
result := &ConnectionType{}
switch dataType {
case dataTypeMap:
_, err = readConnectionTypeMap(result, r.decoderBuffer, size, offset)
if err != nil {
return "", err
}
case dataTypePointer:
pointer, _, err := readPointer(r.decoderBuffer, size, offset)
if err != nil {
return "", err
}
dataType, size, offset, err := readControl(r.decoderBuffer, pointer)
if err != nil {
return "", err
}
if dataType != dataTypeMap {
return "", errors.New("invalid Connection-Type pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readConnectionTypeMap(result, r.decoderBuffer, size, offset)
if err != nil {
return "", err
}
default:
return "", errors.New("invalid Connection-Type type: " + strconv.Itoa(int(dataType)))
}
return result.ConnectionType, nil
}
func NewConnectionTypeReader(buffer []byte) (*ConnectionTypeReader, error) {
reader, err := newReader(buffer)
if err != nil {
return nil, err
}
if reader.metadata.DatabaseType != "GeoIP2-Connection-Type" {
return nil, errors.New("wrong MaxMind DB Connection-Type type: " + reader.metadata.DatabaseType)
}
return &ConnectionTypeReader{
reader: reader,
}, nil
}
func NewConnectionTypeReaderFromFile(filename string) (*ConnectionTypeReader, error) {
buffer, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return NewConnectionTypeReader(buffer)
}

88
vendor/github.com/IncSW/geoip2/reader_country.go generated vendored Normal file
View File

@@ -0,0 +1,88 @@
package geoip2
import (
"errors"
"io/ioutil"
"net"
"strconv"
)
type CountryReader struct {
*reader
}
func (r *CountryReader) Lookup(ip net.IP) (*CountryResult, error) {
offset, err := r.getOffset(ip)
if err != nil {
return nil, err
}
dataType, size, offset, err := readControl(r.decoderBuffer, offset)
if err != nil {
return nil, err
}
if dataType != dataTypeMap {
return nil, errors.New("invalid Country type: " + strconv.Itoa(int(dataType)))
}
var key []byte
result := &CountryResult{}
for i := uint(0); i < size; i++ {
key, offset, err = readMapKey(r.decoderBuffer, offset)
if err != nil {
return nil, err
}
switch b2s(key) {
case "continent":
offset, err = readContinent(&result.Continent, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "country":
offset, err = readCountry(&result.Country, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "registered_country":
offset, err = readCountry(&result.RegisteredCountry, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "represented_country":
offset, err = readCountry(&result.RepresentedCountry, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
case "traits":
offset, err = readTraits(&result.Traits, r.decoderBuffer, offset)
if err != nil {
return nil, err
}
default:
return nil, errors.New("unknown Country response key: " + string(key) + ", type: " + strconv.Itoa(int(dataType)))
}
}
return result, nil
}
func NewCountryReader(buffer []byte) (*CountryReader, error) {
reader, err := newReader(buffer)
if err != nil {
return nil, err
}
if reader.metadata.DatabaseType != "GeoIP2-Country" &&
reader.metadata.DatabaseType != "GeoLite2-Country" &&
reader.metadata.DatabaseType != "DBIP-Country" &&
reader.metadata.DatabaseType != "DBIP-Country-Lite" {
return nil, errors.New("wrong MaxMind DB Country type: " + reader.metadata.DatabaseType)
}
return &CountryReader{
reader: reader,
}, nil
}
func NewCountryReaderFromFile(filename string) (*CountryReader, error) {
buffer, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return NewCountryReader(buffer)
}

71
vendor/github.com/IncSW/geoip2/reader_domain.go generated vendored Normal file
View File

@@ -0,0 +1,71 @@
package geoip2
import (
"errors"
"io/ioutil"
"net"
"strconv"
)
type DomainReader struct {
*reader
}
func (r *DomainReader) Lookup(ip net.IP) (string, error) {
offset, err := r.getOffset(ip)
if err != nil {
return "", err
}
dataType, size, offset, err := readControl(r.decoderBuffer, offset)
if err != nil {
return "", err
}
result := &Domain{}
switch dataType {
case dataTypeMap:
_, err = readDomainMap(result, r.decoderBuffer, size, offset)
if err != nil {
return "", err
}
case dataTypePointer:
pointer, _, err := readPointer(r.decoderBuffer, size, offset)
if err != nil {
return "", err
}
dataType, size, offset, err := readControl(r.decoderBuffer, pointer)
if err != nil {
return "", err
}
if dataType != dataTypeMap {
return "", errors.New("invalid Domain pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readDomainMap(result, r.decoderBuffer, size, offset)
if err != nil {
return "", err
}
default:
return "", errors.New("invalid Domain type: " + strconv.Itoa(int(dataType)))
}
return result.Domain, nil
}
func NewDomainReader(buffer []byte) (*DomainReader, error) {
reader, err := newReader(buffer)
if err != nil {
return nil, err
}
if reader.metadata.DatabaseType != "GeoIP2-Domain" {
return nil, errors.New("wrong MaxMind DB Domain type: " + reader.metadata.DatabaseType)
}
return &DomainReader{
reader: reader,
}, nil
}
func NewDomainReaderFromFile(filename string) (*DomainReader, error) {
buffer, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return NewDomainReader(buffer)
}

71
vendor/github.com/IncSW/geoip2/reader_isp.go generated vendored Normal file
View File

@@ -0,0 +1,71 @@
package geoip2
import (
"errors"
"io/ioutil"
"net"
"strconv"
)
type ISPReader struct {
*reader
}
func (r *ISPReader) Lookup(ip net.IP) (*ISP, error) {
offset, err := r.getOffset(ip)
if err != nil {
return nil, err
}
dataType, size, offset, err := readControl(r.decoderBuffer, offset)
if err != nil {
return nil, err
}
result := &ISP{}
switch dataType {
case dataTypeMap:
_, err = readISPMap(result, r.decoderBuffer, size, offset)
if err != nil {
return nil, err
}
case dataTypePointer:
pointer, _, err := readPointer(r.decoderBuffer, size, offset)
if err != nil {
return nil, err
}
dataType, size, offset, err := readControl(r.decoderBuffer, pointer)
if err != nil {
return nil, err
}
if dataType != dataTypeMap {
return nil, errors.New("invalid ISP pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readISPMap(result, r.decoderBuffer, size, offset)
if err != nil {
return nil, err
}
default:
return nil, errors.New("invalid ISP type: " + strconv.Itoa(int(dataType)))
}
return result, nil
}
func NewISPReader(buffer []byte) (*ISPReader, error) {
reader, err := newReader(buffer)
if err != nil {
return nil, err
}
if reader.metadata.DatabaseType != "GeoIP2-ISP" {
return nil, errors.New("wrong MaxMind DB ISP type: " + reader.metadata.DatabaseType)
}
return &ISPReader{
reader: reader,
}, nil
}
func NewISPReaderFromFile(filename string) (*ISPReader, error) {
buffer, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return NewISPReader(buffer)
}

114
vendor/github.com/IncSW/geoip2/subdivision.go generated vendored Normal file
View File

@@ -0,0 +1,114 @@
package geoip2
import (
"errors"
"strconv"
)
func readSubdivisions(buffer []byte, offset uint) ([]Subdivision, uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return nil, 0, err
}
switch dataType {
case dataTypeSlice:
return readSubdivisionsSlice(buffer, size, offset)
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return nil, 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return nil, 0, err
}
if dataType != dataTypeSlice {
return nil, 0, errors.New("invalid subdivisions pointer type: " + strconv.Itoa(int(dataType)))
}
subdivisions, _, err := readSubdivisionsSlice(buffer, size, offset)
if err != nil {
return nil, 0, err
}
return subdivisions, newOffset, nil
default:
return nil, 0, errors.New("invalid subdivisions type: " + strconv.Itoa(int(dataType)))
}
}
func readSubdivisionsSlice(buffer []byte, subdivisionsSize uint, offset uint) ([]Subdivision, uint, error) {
var err error
subdivisions := make([]Subdivision, subdivisionsSize)
for i := uint(0); i < subdivisionsSize; i++ {
offset, err = readSubdivision(&subdivisions[i], buffer, offset)
if err != nil {
return nil, 0, err
}
}
return subdivisions, offset, nil
}
func readSubdivision(subdivision *Subdivision, buffer []byte, offset uint) (uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return 0, err
}
switch dataType {
case dataTypeMap:
return readSubdivisionMap(subdivision, buffer, size, offset)
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return 0, err
}
if dataType != dataTypeMap {
return 0, errors.New("invalid subdivision pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readSubdivisionMap(subdivision, buffer, size, offset)
if err != nil {
return 0, err
}
return newOffset, nil
default:
return 0, errors.New("invalid subdivision type: " + strconv.Itoa(int(dataType)))
}
}
func readSubdivisionMap(subdivision *Subdivision, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "geoname_id":
subdivision.GeoNameID, offset, err = readUInt32(buffer, offset)
if err != nil {
return 0, err
}
case "iso_code":
subdivision.ISOCode, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "names":
subdivision.Names, offset, err = readStringMap(buffer, offset)
if err != nil {
return 0, err
}
case "confidence":
subdivision.Confidence, offset, err = readUInt16(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown subdivision key: " + string(key))
}
}
return offset, nil
}

117
vendor/github.com/IncSW/geoip2/traits.go generated vendored Normal file
View File

@@ -0,0 +1,117 @@
package geoip2
import (
"errors"
"strconv"
)
func readTraits(traits *Traits, buffer []byte, offset uint) (uint, error) {
dataType, size, offset, err := readControl(buffer, offset)
if err != nil {
return 0, err
}
switch dataType {
case dataTypeMap:
return readTraitsMap(traits, buffer, size, offset)
case dataTypePointer:
pointer, newOffset, err := readPointer(buffer, size, offset)
if err != nil {
return 0, err
}
dataType, size, offset, err := readControl(buffer, pointer)
if err != nil {
return 0, err
}
if dataType != dataTypeMap {
return 0, errors.New("invalid traits pointer type: " + strconv.Itoa(int(dataType)))
}
_, err = readTraitsMap(traits, buffer, size, offset)
if err != nil {
return 0, err
}
return newOffset, nil
default:
return 0, errors.New("invalid traits type: " + strconv.Itoa(int(dataType)))
}
}
func readTraitsMap(traits *Traits, buffer []byte, mapSize uint, offset uint) (uint, error) {
var key []byte
var err error
for i := uint(0); i < mapSize; i++ {
key, offset, err = readMapKey(buffer, offset)
if err != nil {
return 0, err
}
switch b2s(key) {
case "is_anonymous_proxy":
traits.IsAnonymousProxy, offset, err = readBool(buffer, offset)
if err != nil {
return 0, err
}
case "is_satellite_provider":
traits.IsSatelliteProvider, offset, err = readBool(buffer, offset)
if err != nil {
return 0, err
}
case "is_legitimate_proxy":
traits.IsLegitimateProxy, offset, err = readBool(buffer, offset)
if err != nil {
return 0, err
}
case "static_ip_score":
traits.StaticIPScore, offset, err = readFloat64(buffer, offset)
if err != nil {
return 0, err
}
case "autonomous_system_number":
traits.AutonomousSystemNumber, offset, err = readUInt32(buffer, offset)
if err != nil {
return 0, err
}
case "autonomous_system_organization":
traits.AutonomousSystemOrganization, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "isp":
traits.ISP, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "organization":
traits.Organization, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "connection_type":
traits.ConnectionType, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "domain":
traits.Domain, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "user_type":
traits.UserType, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "mobile_country_code":
traits.MobileCountryCode, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
case "mobile_network_code":
traits.MobileNetworkCode, offset, err = readString(buffer, offset)
if err != nil {
return 0, err
}
default:
return 0, errors.New("unknown traits key: " + string(key))
}
}
return offset, nil
}

130
vendor/github.com/IncSW/geoip2/types.go generated vendored Normal file
View File

@@ -0,0 +1,130 @@
package geoip2
const (
dataTypeExtended = 0
dataTypePointer = 1
dataTypeString = 2
dataTypeFloat64 = 3
dataTypeBytes = 4
dataTypeUint16 = 5
dataTypeUint32 = 6
dataTypeMap = 7
dataTypeInt32 = 8
dataTypeUint64 = 9
dataTypeUint128 = 10
dataTypeSlice = 11
dataTypeDataCacheContainer = 12
dataTypeEndMarker = 13
dataTypeBool = 14
dataTypeFloat32 = 15
dataSectionSeparatorSize = 16
)
type Continent struct {
GeoNameID uint32
Code string
Names map[string]string
}
type Country struct {
ISOCode string
Names map[string]string
Type string // [RepresentedCountry]
GeoNameID uint32
Confidence uint16 // Enterprise [Country, RegisteredCountry]
IsInEuropeanUnion bool
}
type Subdivision struct {
ISOCode string
Names map[string]string
GeoNameID uint32
Confidence uint16 // Enterprise
}
type City struct {
Names map[string]string
GeoNameID uint32
Confidence uint16 // Enterprise
}
type Location struct {
Latitude float64
Longitude float64
TimeZone string
AccuracyRadius uint16
MetroCode uint16
}
type Postal struct {
Code string
Confidence uint16 // Enterprise
}
type Traits struct {
StaticIPScore float64 // Enterprise
ISP string // Enterprise
Organization string // Enterprise
ConnectionType string // Enterprise
Domain string // Enterprise
UserType string // Enterprise
AutonomousSystemOrganization string // Enterprise
AutonomousSystemNumber uint32 // Enterprise
IsLegitimateProxy bool // Enterprise
MobileCountryCode string // Enterprise
MobileNetworkCode string // Enterprise
IsAnonymousProxy bool
IsSatelliteProvider bool
}
type CountryResult struct {
Continent Continent
Country Country
RegisteredCountry Country
RepresentedCountry Country
Traits Traits
}
type CityResult struct {
Continent Continent
Country Country
Subdivisions []Subdivision
City City
Location Location
Postal Postal
RegisteredCountry Country
RepresentedCountry Country
Traits Traits
}
type ISP struct {
AutonomousSystemNumber uint32
AutonomousSystemOrganization string
ISP string
Organization string
MobileCountryCode string
MobileNetworkCode string
}
type ConnectionType struct {
ConnectionType string
}
type AnonymousIP struct {
IsAnonymous bool
IsAnonymousVPN bool
IsHostingProvider bool
IsPublicProxy bool
IsTorExitNode bool
IsResidentialProxy bool
}
type ASN struct {
AutonomousSystemNumber uint32
AutonomousSystemOrganization string
}
type Domain struct {
Domain string
}