Git Product home page Git Product logo

geoip's Introduction

GeoIP API for Go

This package wraps the libgeoip C library for access from Go (golang). Build Status

Install with go get github.com/abh/geoip and use godoc geoip to read the documentation.

There's a small example in the ex/ subdirectory.

You can download the free GeoLite Country database or you can subscribe to updates.

Examples

file := "/usr/share/GeoIP/GeoIP.dat"

gi, err := geoip.Open(file)
if err != nil {
	fmt.Printf("Could not open GeoIP database\n")
}

if gi != nil {
	country, netmask := gi.GetCountry("207.171.7.51")
}

// Setup gi6 by opening the optional IPv6 database and then...
country := gi6.GetCountry_v6("2607:f238:2::5")
fmt.Println(country)

Contact

Copyright 2012-2013 Ask Bjørn Hansen [email protected]. The package is MIT licensed, see the LICENSE file. Originally based on example code from [email protected].

geoip's People

Contributors

abh avatar araddon avatar dgryski avatar gmccue avatar miekg avatar muesli avatar oschwald avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geoip's Issues

Programs using this package won't build because of an error in geoip-demo.go

If a Go program uses this package and will be build using go install ./... it can't build because
of an type error in geoip-demo.go:

# github.com/abh/geoip/ex
src/github.com/abh/geoip/ex/geoip-demo.go:41:9: cannot use *gi (type geoip.GeoIP) as type *geoip.GeoIP in argument to test4
src/github.com/abh/geoip/ex/geoip-demo.go:42:9: cannot use *gi (type geoip.GeoIP) as type *geoip.GeoIP in argument to test4

This is caused by a wrong type in geoip-demo.go. geoip.Open returns a pointer to GeoIP structure and the function test4 in the geoip-demo.go file expects a pointer but the main function passes the structure instead of the pointer.

This patch will fix this issue:

--- ex/geoip-demo.go.original	2020-06-06 11:24:57.841432573 +0200
+++ ex/geoip-demo.go	2020-06-06 11:25:04.749461347 +0200
@@ -38,8 +38,8 @@
 	}
 
 	if gi != nil {
-		test4(*gi, "207.171.7.51")
-		test4(*gi, "127.0.0.1")
+		test4(gi, "207.171.7.51")
+		test4(gi, "127.0.0.1")
 	}
 	if gi6 != nil {
 		ip := "2607:f238:2::5"

Use thread-safe API in GeoIP 1.5.x

(copied from issue #6)

@dryski wrote:

libgeoip included a thread-safe API in its 1.5.0 release in October 2012. This would allow the removal of all mutexes from the Go API. The work required is not that large and I'm willing to do it. Most distributions are probably still on earlier versions, although Ubuntu Saucy will include 1.5.1. Should I begin this work?

Mutex protection is insufficient

The mutex protecting access to GeoIP_last_netmask() is only locked during calls to GetCountry(), but won't any access to the Get* methods potentially mutate GeoIP_last_netmask()? I wonder if this should be a RWMutex instead, and most of the calls (that don't need to get the netmask as a separate call) can use RLock()/RUnlock() and GetCountry() can use the normal writer Lock().

(This is based on a cursory examination of geoip-c-api code; I haven't run this code under the race detector which I'm not sure can peek inside C routines anyway..)

Maybe it's just better to remove the netmask call from the Go API altogether?

Can't go get the package

Using latest go 1.6.1 on Windows I cannot get the package to work. I downloaded and installed pkg-config but whenever i do go get github.com/abh/geoip I get the following:

pkg-config --cflags geoip

Package geoip was not found in the pkg-config search path.
Perhaps you should add the directory containing `geoip.pc'
to the PKG_CONFIG_PATH environment variable
No package 'geoip' found
pkg-config: exit status 1

No such file or directory

I'm trying to make use of the lib but for some reasons I get errors related to the C files. I tried go get github.com/abh/geoip Is there anything else that I should do to make it work ?
go run main.go \# github.com/abh/geoip ../go/src/github.com/abh/geoip/geoip.go:9:19: error: GeoIP.h: No such file or directory ../go/src/github.com/abh/geoip/geoip.go:10:23: error: GeoIPCity.h: No such file or directory

Message at install via go get

At install after go get I have :
1: error: 'GeoIP_country_code_by_addr_v6' undeclared (first use in th
is function)
1: note: each undeclared identifier is reported only once for each fu
nction it appears in

(And you should fix the readme, the real go get syntax with github is

go get github.com/... (no protocol) )

Crash trying to GetCountry

fatal error: unexpected signal during runtime execution
[signal 0xb code=0x1 addr=0x7f73ec663614 pc=0x7f73eb6bf010]

runtime stack:
runtime.throw(0x537da0, 0x2a)
    /usr/lib/go/src/runtime/panic.go:527 +0x90
runtime.sigpanic()
    /usr/lib/go/src/runtime/sigpanic_unix.go:12 +0x5a

goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x401b90, 0xc820053d20, 0x0)
    /usr/lib/go/src/runtime/cgocall.go:120 +0x11b fp=0xc820053cf0 sp=0xc820053cc0
github.com/abh/geoip._Cfunc_GeoIP_country_code_by_addr(0x13b13e0, 0x13b1010, 0x0)
    ??:0 +0x36 fp=0xc820053d20 sp=0xc820053cf0
github.com/abh/geoip.(*GeoIP).GetCountry(0xc820074000, 0x5136a0, 0xc, 0x0, 0x0, 0x0)
    /home/v/go/src/github.com/abh/geoip/geoip.go:311 +0x110 fp=0xc820053d48 sp=0xc820053d20
main.test4.func1(0x5136a0, 0xc, 0x0, 0x0, 0xc820074000)
    /home/v/go/src/github.com/vikstrous/tox-crawler/test.go:25 +0x40 fp=0xc820053d80 sp=0xc820053d48
main.test(0xc820053e78, 0x5136a0, 0xc)
    /home/v/go/src/github.com/vikstrous/tox-crawler/test.go:29 +0x45 fp=0xc820053e58 sp=0xc820053d80
main.test4(0x13b13e0, 0x0, 0x5136a0, 0xc)
    /home/v/go/src/github.com/vikstrous/tox-crawler/test.go:25 +0x81 fp=0xc820053e90 sp=0xc820053e58
main.main()
    /home/v/go/src/github.com/vikstrous/tox-crawler/test.go:19 +0x1dd fp=0xc820053f50 sp=0xc820053e90
runtime.main()
    /usr/lib/go/src/runtime/proc.go:111 +0x2b0 fp=0xc820053fa0 sp=0xc820053f50
runtime.goexit()
    /usr/lib/go/src/runtime/asm_amd64.s:1696 +0x1 fp=0xc820053fa8 sp=0xc820053fa0

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/lib/go/src/runtime/asm_amd64.s:1696 +0x1
exit status 2

To reproduce:

package main

import (
    "fmt"

    "github.com/abh/geoip"
)

func main() {

    file6 := "GeoIP.dat"

    gi, err := geoip.Open(file6)
    if err != nil {
        fmt.Printf("Could not open GeoIPv6 database: %s\n", err)
    }

    if gi != nil {
        test4(*gi, "207.171.7.51")
        test4(*gi, "127.0.0.1")
    }
}

func test4(g geoip.GeoIP, ip string) {
    test(func(s string) (string, int) { return g.GetCountry(s) }, ip)
}

func test(f func(string) (string, int), ip string) {
    country, netmask := f(ip)
    fmt.Printf("ip: %s is [%s] (netmask %d)\n", ip, country, netmask)

}

Database used: http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz from http://dev.maxmind.com/geoip/geoip2/geolite2/

compiling error

clang: error: argument unused during compilation: '-fno-eliminate-unused-debug-types'

Expose opened database type

It would be great to expose opened database type available via GeoIP.databaseType https://github.com/maxmind/geoip-api-c/blob/master/libGeoIP/GeoIP.h#L65.

Actual need lies in the fact that underline C library produces warning message to stdout in case API method is not supported on a given database type.

In my particular case I have a code which is intended to work with either country or city databases (yes, still legacy, there are reasons for that) and it tries to derive country code via all possible APIs. It is not quite straight forward to get the database type using the provided APIs.

Here is a snippet for country code

package main

import (
	"github.com/abh/geoip"
	"log"
	"path/filepath"
)

func main() {
	TestDb("GeoIPCity.dat")
	TestDb("GeoIP.dat")
}

func TestDb(path string) {
	ip := "109.106.142.207" // RU

	log.Printf("====")
	db, err := geoip.Open(path)
	if err != nil {
		log.Fatal(err.Error())
	}

	if db == nil {
		log.Fatal("nil pointer geo database")
	}

	// GeoIPCity.dat -> GetRecord
	// GeoIP.dat -> GetCountry

	log.Println("GetRecord before")
	record := db.GetRecord(ip)
	if record != nil {
		log.Printf("code = %s", record.CountryCode)
	}
	log.Println("GetRecord after")

	log.Println("GetCountry before")
	code, _ := db.GetCountry(ip)
	log.Printf("code = %s", code)
	log.Println("GetCountry after")
}

Possible workaround could be using reflection.

import (
  "reflect"
  "log"
)

func FindDatabaseType(db *geoip.GeoIP) {
	t := reflect.ValueOf(*db)
	val := t.FieldByName("db")
	dbType := val.Elem().FieldByName("databaseType")
	log.Printf("databaseType = %d", dbType.Int())
}

But making it explicit will be a more simple approach.

Pretty similar problem was addressed here syslog-ng/syslog-ng#1446

I am happy to submit PR for that.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.