mirror of
https://github.com/PeernetOfficial/Abstraction.git
synced 2026-07-19 11:57:50 +01:00
added example package
This commit is contained in:
1
vendor/github.com/IncSW/geoip2/.gitignore
generated
vendored
Normal file
1
vendor/github.com/IncSW/geoip2/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
testdata
|
||||
21
vendor/github.com/IncSW/geoip2/LICENSE
generated
vendored
Normal file
21
vendor/github.com/IncSW/geoip2/LICENSE
generated
vendored
Normal 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
94
vendor/github.com/IncSW/geoip2/README.md
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
[](LICENSE)
|
||||
[](https://goreportcard.com/report/github.com/IncSW/geoip2)
|
||||
[](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
49
vendor/github.com/IncSW/geoip2/anonymous_ip.go
generated
vendored
Normal 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
29
vendor/github.com/IncSW/geoip2/asn.go
generated
vendored
Normal 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
67
vendor/github.com/IncSW/geoip2/city.go
generated
vendored
Normal 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
370
vendor/github.com/IncSW/geoip2/common.go
generated
vendored
Normal 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
24
vendor/github.com/IncSW/geoip2/connection_type.go
generated
vendored
Normal 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
67
vendor/github.com/IncSW/geoip2/continent.go
generated
vendored
Normal 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
82
vendor/github.com/IncSW/geoip2/country.go
generated
vendored
Normal 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
24
vendor/github.com/IncSW/geoip2/domain.go
generated
vendored
Normal 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
49
vendor/github.com/IncSW/geoip2/isp.go
generated
vendored
Normal 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
77
vendor/github.com/IncSW/geoip2/location.go
generated
vendored
Normal 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
108
vendor/github.com/IncSW/geoip2/metadata.go
generated
vendored
Normal 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 database’s binary format.
|
||||
BinaryFormatMinorVersion uint16 // binary_format_minor_version This is an unsigned 16-bit integer indicating the minor version number for the database’s 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
62
vendor/github.com/IncSW/geoip2/postal.go
generated
vendored
Normal 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
124
vendor/github.com/IncSW/geoip2/reader.go
generated
vendored
Normal 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
71
vendor/github.com/IncSW/geoip2/reader_anonymous_ip.go
generated
vendored
Normal 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
73
vendor/github.com/IncSW/geoip2/reader_asn.go
generated
vendored
Normal 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
116
vendor/github.com/IncSW/geoip2/reader_city.go
generated
vendored
Normal 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)
|
||||
}
|
||||
71
vendor/github.com/IncSW/geoip2/reader_connection_type.go
generated
vendored
Normal file
71
vendor/github.com/IncSW/geoip2/reader_connection_type.go
generated
vendored
Normal 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
88
vendor/github.com/IncSW/geoip2/reader_country.go
generated
vendored
Normal 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
71
vendor/github.com/IncSW/geoip2/reader_domain.go
generated
vendored
Normal 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
71
vendor/github.com/IncSW/geoip2/reader_isp.go
generated
vendored
Normal 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
114
vendor/github.com/IncSW/geoip2/subdivision.go
generated
vendored
Normal 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
117
vendor/github.com/IncSW/geoip2/traits.go
generated
vendored
Normal 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
130
vendor/github.com/IncSW/geoip2/types.go
generated
vendored
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user