summaryrefslogtreecommitdiffabout
authorSergey Poznyakoff <gray@gnu.org.ua>2017-07-26 07:17:24 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2017-07-26 07:17:24 (GMT)
commit72f4a1452469501b945aee79b97bbe456858f44d (patch) (side-by-side diff)
tree007d7fe41b526e0323d3a30caaef54594839832a
parent02bc62f6f7bbffb26e3bb7dd4a9b053b98dc3dd6 (diff)
downloadvmod-geoip-72f4a1452469501b945aee79b97bbe456858f44d.tar.gz
vmod-geoip-72f4a1452469501b945aee79b97bbe456858f44d.tar.bz2
Change IP argument type
* src/vmod_geoip.vcc (get, country_code) (city_name): Pass IP argument, instead of STRING * src/vmod_geoip.c: Ditto. Use VSLb and WS_Printf instead of own functions.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--src/vmod_geoip.c126
-rw-r--r--src/vmod_geoip.vcc14
2 files changed, 67 insertions, 73 deletions
diff --git a/src/vmod_geoip.c b/src/vmod_geoip.c
index fd85030..b7e30ba 100644
--- a/src/vmod_geoip.c
+++ b/src/vmod_geoip.c
@@ -10,8 +10,10 @@
#include <inttypes.h>
#include "vcl.h"
#include "vrt.h"
+#include "vtcp.h"
+#include "vsa.h"
#include "vcc_if.h"
-#include "bin/varnishd/cache/cache.h"
+#include "cache/cache.h"
#include <maxminddb.h>
#include <assert.h>
@@ -23,6 +25,13 @@ struct geoip_config {
char *database;
};
+static void
+free_conf(void *data)
+{
+ struct geoip_config *cfg = data;
+ free(data);
+}
+
int
geoip_event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
{
@@ -30,6 +39,7 @@ geoip_event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
struct geoip_config *conf = calloc(1, sizeof(*conf));
AN(conf);
priv->priv = conf;
+ priv->free = free_conf;
}
return 0;
}
@@ -41,10 +51,11 @@ vmod_init(VRT_CTX, struct vmod_priv *priv, const char *dir)
struct stat st;
char *name;
- if (stat (dir, &st)) {
- fprintf (stderr, "geoip.init: can't stat \"%s\": %s\n",
- dir, strerror (errno));
- abort ();
+ if (stat(dir, &st)) {
+ VSLb(ctx->vsl, SLT_Error,
+ "geoip.init: can't stat \"%s\": %s",
+ dir, strerror(errno));
+ abort();
}
if (S_ISDIR(st.st_mode)) {
@@ -62,7 +73,8 @@ vmod_init(VRT_CTX, struct vmod_priv *priv, const char *dir)
name = strdup (dir);
AN(name);
} else {
- fprintf (stderr, "geoip.init: \"%s\": bad file type\n", dir);
+ VSLb(ctx->vsl, SLT_Error,
+ "geoip.init: \"%s\": bad file type", dir);
abort ();
}
@@ -71,15 +83,16 @@ vmod_init(VRT_CTX, struct vmod_priv *priv, const char *dir)
}
static int
-open_geoip_database(struct geoip_config *conf, MMDB_s *dbptr)
+open_geoip_database(VRT_CTX, struct geoip_config *conf, MMDB_s *dbptr)
{
char *database = conf->database ? conf->database : DEFAULT_DATABASE;
int rc;
rc = MMDB_open(database, MMDB_MODE_MMAP, dbptr);
if (rc != MMDB_SUCCESS) {
- fprintf(stderr, "can't open database \"%s\": %s\n",
- database, MMDB_strerror(rc));
+ VSLb(ctx->vsl, SLT_Error,
+ "can't open database \"%s\": %s",
+ database, MMDB_strerror(rc));
return -1;
}
return 0;
@@ -96,59 +109,39 @@ conv_utf_string (struct ws *ws, MMDB_entry_data_s *dptr)
}
static char *
-wsprintf(struct ws *ws, char const *fmt, ...)
-{
- va_list ap;
- size_t u, n;
- char *p;
-
- va_start(ap, fmt);
- u = WS_Reserve(ws, 0);
- p = ws->f;
- n = vsnprintf(p, u, fmt, ap);
- va_end(ap);
- if (n)
- n++;
- else
- p = NULL;
- WS_Release(ws, n);
- return p;
-}
-
-static char *
conv_uint16(struct ws *ws, MMDB_entry_data_s *dptr)
{
- return wsprintf(ws, "%" PRIu16, dptr->uint16);
+ return WS_Printf(ws, "%" PRIu16, dptr->uint16);
}
static char *
conv_uint32(struct ws *ws, MMDB_entry_data_s *dptr)
{
- return wsprintf(ws, "%" PRIu32, dptr->uint32);
+ return WS_Printf(ws, "%" PRIu32, dptr->uint32);
}
static char *
conv_int32(struct ws *ws, MMDB_entry_data_s *dptr)
{
- return wsprintf(ws, "%" PRIi32, dptr->int32);
+ return WS_Printf(ws, "%" PRIi32, dptr->int32);
}
static char *
conv_bool(struct ws *ws, MMDB_entry_data_s *dptr)
{
- return wsprintf(ws, "%01d", dptr->boolean ? 1 : 0);
+ return WS_Printf(ws, "%01d", dptr->boolean ? 1 : 0);
}
static char *
conv_double(struct ws *ws, MMDB_entry_data_s *dptr)
{
- return wsprintf(ws, "%g", dptr->double_value);
+ return WS_Printf(ws, "%g", dptr->double_value);
}
static char *
conv_float(struct ws *ws, MMDB_entry_data_s *dptr)
{
- return wsprintf(ws, "%g", dptr->float_value);
+ return WS_Printf(ws, "%g", dptr->float_value);
}
static char *(*entry_conv[]) (struct ws *, MMDB_entry_data_s *) = {
@@ -162,26 +155,28 @@ static char *(*entry_conv[]) (struct ws *, MMDB_entry_data_s *) = {
};
static char *
-lookup_geoip_database(struct ws *ws,
- MMDB_s *dbfile, VCL_STRING ipstr,
+lookup_geoip_database(VRT_CTX,
+ MMDB_s *dbfile, VCL_IP ip,
char const *pathstr, char **path)
{
MMDB_lookup_result_s result;
- int gai_error, mmdb_error;
+ int mmdb_error;
int rc;
MMDB_entry_data_s entry_data;
char *retval;
+ const struct sockaddr *sa;
+ socklen_t sl;
+ char ipstr[VTCP_ADDRBUFSIZE];
- result = MMDB_lookup_string(dbfile, ipstr, &gai_error, &mmdb_error);
- if (gai_error) {
- fprintf(stderr, "%s %s: GAI %s\n",
- pathstr, ipstr, gai_strerror(gai_error));
+ if (!(sa = VSA_Get_Sockaddr(ip, &sl)))
return NULL;
- }
+ result = MMDB_lookup_sockaddr(dbfile, sa, &mmdb_error);
if (mmdb_error != MMDB_SUCCESS) {
- fprintf(stderr, "%s %s: MMDB %s\n",
- pathstr, ipstr, MMDB_strerror(mmdb_error));
+ VTCP_name(ip, ipstr, sizeof ipstr, NULL, 0);
+ VSLb(ctx->vsl, SLT_Error,
+ "%s: %s",
+ pathstr, ipstr, MMDB_strerror(mmdb_error));
return NULL;
}
@@ -191,8 +186,10 @@ lookup_geoip_database(struct ws *ws,
rc = MMDB_aget_value(&result.entry, &entry_data,
(const char * const* const) path);
if (rc != MMDB_SUCCESS) {
- fprintf(stderr, "%s %s: MMDB_aget_value %s\n",
- pathstr, ipstr, MMDB_strerror(rc));
+ VTCP_name(ip, ipstr, sizeof ipstr, NULL, 0);
+ VSLb(ctx->vsl, SLT_Error,
+ "%s %s: MMDB_aget_value %s",
+ pathstr, ipstr, MMDB_strerror(rc));
return NULL;
}
@@ -202,11 +199,12 @@ lookup_geoip_database(struct ws *ws,
if (entry_data.type >= 0
&& entry_data.type <= sizeof (entry_conv) / sizeof (entry_conv[0])
&& entry_conv[entry_data.type]) {
- retval = entry_conv[entry_data.type] (ws, &entry_data);
- } else
- retval = wsprintf(ws, "[%s: can't format %s of type %d]",
- ipstr, pathstr, entry_data.type);
-
+ retval = entry_conv[entry_data.type] (ctx->ws, &entry_data);
+ } else {
+ VTCP_name(ip, ipstr, sizeof ipstr, NULL, 0);
+ retval = WS_Printf(ctx->ws, "[%s: can't format %s of type %d]",
+ ipstr, pathstr, entry_data.type);
+ }
return retval;
}
@@ -244,24 +242,24 @@ split(char const *path)
}
VCL_STRING
-vmod_get(VRT_CTX, struct vmod_priv *priv, VCL_STRING ipstr, VCL_STRING path)
+vmod_get(VRT_CTX, struct vmod_priv *priv, VCL_IP ip, VCL_STRING path)
{
struct geoip_config *conf = priv->priv;
MMDB_s dbfile;
char *retval = NULL;
char **pathv;
- if (open_geoip_database(conf, &dbfile))
+ if (open_geoip_database(ctx, conf, &dbfile))
return NULL;
pathv = split(path);
- retval = lookup_geoip_database(ctx->ws, &dbfile, ipstr, path, pathv);
+ retval = lookup_geoip_database(ctx, &dbfile, ip, path, pathv);
free(pathv);
MMDB_close(&dbfile);
return retval;
}
VCL_STRING
-vmod_country_code(VRT_CTX, struct vmod_priv *priv, VCL_STRING ipstr)
+vmod_country_code(VRT_CTX, struct vmod_priv *priv, VCL_IP ip)
{
struct geoip_config *conf = priv->priv;
MMDB_s dbfile;
@@ -272,16 +270,16 @@ vmod_country_code(VRT_CTX, struct vmod_priv *priv, VCL_STRING ipstr)
NULL
};
- if (open_geoip_database(conf, &dbfile))
+ if (open_geoip_database(ctx, conf, &dbfile))
return NULL;
- retval = lookup_geoip_database(ctx->ws, &dbfile, ipstr,
+ retval = lookup_geoip_database(ctx, &dbfile, ip,
"country.iso_code", country_code_path);
MMDB_close(&dbfile);
return retval;
}
VCL_STRING
-vmod_country_name(VRT_CTX, struct vmod_priv *priv, VCL_STRING ipstr)
+vmod_country_name(VRT_CTX, struct vmod_priv *priv, VCL_IP ip)
{
struct geoip_config *conf = priv->priv;
MMDB_s dbfile;
@@ -293,9 +291,9 @@ vmod_country_name(VRT_CTX, struct vmod_priv *priv, VCL_STRING ipstr)
NULL
};
- if (open_geoip_database(conf, &dbfile))
+ if (open_geoip_database(ctx, conf, &dbfile))
return NULL;
- retval = lookup_geoip_database(ctx->ws, &dbfile, ipstr,
+ retval = lookup_geoip_database(ctx, &dbfile, ip,
"country.names.en",
country_name_path);
MMDB_close(&dbfile);
@@ -303,7 +301,7 @@ vmod_country_name(VRT_CTX, struct vmod_priv *priv, VCL_STRING ipstr)
}
VCL_STRING
-vmod_city_name(VRT_CTX, struct vmod_priv *priv, VCL_STRING ipstr)
+vmod_city_name(VRT_CTX, struct vmod_priv *priv, VCL_IP ip)
{
struct geoip_config *conf = priv->priv;
MMDB_s dbfile;
@@ -315,9 +313,9 @@ vmod_city_name(VRT_CTX, struct vmod_priv *priv, VCL_STRING ipstr)
NULL
};
- if (open_geoip_database(conf, &dbfile))
+ if (open_geoip_database(ctx, conf, &dbfile))
return NULL;
- retval = lookup_geoip_database(ctx->ws, &dbfile, ipstr,
+ retval = lookup_geoip_database(ctx, &dbfile, ip,
"city.names.en",
city_name_path);
MMDB_close(&dbfile);
diff --git a/src/vmod_geoip.vcc b/src/vmod_geoip.vcc
index ffe024e..d96dc09 100644
--- a/src/vmod_geoip.vcc
+++ b/src/vmod_geoip.vcc
@@ -17,7 +17,7 @@ Description
must exist. If the pathname refers to a directory, **/GeoLite2-City.mmdb**
will be appended to it.
-$Function STRING get(PRIV_VCL, STRING ip, STRING path)
+$Function STRING get(PRIV_VCL, IP ip, STRING path)
Description
Look up in the database a value described by **path** corresponding to the
@@ -44,30 +44,26 @@ Description
where *X.X.X.X* stands for IP address, *A.B.C* for lookup path, and
*N* for the data type in decimal.
-
- Note that the function takes as its argument the IP address in string
- representation. Care should be taken to ensure proper conversion when
- passing IP addresses, as shown in the example below.
Example
::
- set req.http.X-Country-Code = geoip.get("" + client.ip,
+ set req.http.X-Country-Code = geoip.get(client.ip,
"country.name.en");
-$Function STRING country_code(PRIV_VCL, STRING ip)
+$Function STRING country_code(PRIV_VCL, IP ip)
Description
Returns the ISO 3166-1 alpha-2 country code corresponding to the **ip**.
Equivalent to geoip.get(ip, "country.iso_code").
-$Function STRING country_name(PRIV_VCL, STRING ip)
+$Function STRING country_name(PRIV_VCL, IP ip)
Description
Returns the English name of the country corresponding to **ip**.
Equivalent to geoip.get(ip, "country.names.en"),
-$Function STRING city_name(PRIV_VCL, STRING ip)
+$Function STRING city_name(PRIV_VCL, IP ip)
Description
Returns the name of the city where **ip** is located.

Return to:

Send suggestions and report system problems to the System administrator.