summaryrefslogtreecommitdiff
path: root/geoip.c
diff options
context:
space:
mode:
authorVadim Kochan <vadim4j@gmail.com>2017-02-04 11:56:14 +0200
committerTobias Klauser <tklauser@distanz.ch>2017-02-06 17:26:28 +0100
commit8fd19eefa46b313673d6ba2a0194a68674ef5ea9 (patch)
tree569da73381afb80fe8eb70d1183fbac0339da4ef /geoip.c
parent1e1383fea55fb35cec96a352da93c2a31d9e897c (diff)
geoip: Fix memory leak when using GeoIPRecord
GeoIP_record_by_ipnum{,_v6} returns allocated pointer to GeoIPRecord with allocated city, region & postal_code which is not freed after the call. Fixed by xstrdup-ing required GeoIPRecord member (city/region) and after calling GeoIPRecord_delete to free the geoip record. Of course it is needed to also free obtained city/region in netsniff-ng, astraceroute & flowtop tools. Fixes #169 Signed-off-by: Vadim Kochan <vadim4j@gmail.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'geoip.c')
-rw-r--r--geoip.c114
1 files changed, 98 insertions, 16 deletions
diff --git a/geoip.c b/geoip.c
index 917b1a7..d95305c 100644
--- a/geoip.c
+++ b/geoip.c
@@ -73,8 +73,6 @@ static GeoIP *gi4_asname = NULL, *gi6_asname = NULL;
static GeoIP *gi4_country = NULL, *gi6_country = NULL;
static GeoIP *gi4_city = NULL, *gi6_city = NULL;
-static GeoIPRecord empty = { NULL };
-
static char *servers[16] = { NULL };
#define CITYV4 (1 << 0)
@@ -261,14 +259,14 @@ static GeoIPRecord *geoip4_get_record(struct sockaddr_in *sa)
{
bug_on(gi4_city == NULL);
- return GeoIP_record_by_ipnum(gi4_city, ntohl(sa->sin_addr.s_addr)) ? : &empty;
+ return GeoIP_record_by_ipnum(gi4_city, ntohl(sa->sin_addr.s_addr));
}
static GeoIPRecord *geoip6_get_record(struct sockaddr_in6 *sa)
{
bug_on(gi6_city == NULL);
- return GeoIP_record_by_ipnum_v6(gi6_city, sa->sin6_addr) ? : &empty;
+ return GeoIP_record_by_ipnum_v6(gi6_city, sa->sin6_addr);
}
const char *geoip4_as_name(struct sockaddr_in *sa)
@@ -287,42 +285,126 @@ const char *geoip6_as_name(struct sockaddr_in6 *sa)
float geoip4_longitude(struct sockaddr_in *sa)
{
- return geoip4_get_record(sa)->longitude;
+ GeoIPRecord *record;
+ float longitude;
+
+ record = geoip4_get_record(sa);
+ if (!record)
+ return 0;
+
+ longitude = record->longitude;
+
+ GeoIPRecord_delete(record);
+ return longitude;
}
float geoip4_latitude(struct sockaddr_in *sa)
{
- return geoip4_get_record(sa)->latitude;
+ GeoIPRecord *record;
+ float latitude;
+
+ record = geoip4_get_record(sa);
+ if (!record)
+ return 0;
+
+ latitude = record->latitude;
+
+ GeoIPRecord_delete(record);
+ return latitude;
}
float geoip6_longitude(struct sockaddr_in6 *sa)
{
- return geoip6_get_record(sa)->longitude;
+ GeoIPRecord *record;
+ float longitude;
+
+ record = geoip6_get_record(sa);
+ if (!record)
+ return 0;
+
+ longitude = record->longitude;
+
+ GeoIPRecord_delete(record);
+ return longitude;
}
float geoip6_latitude(struct sockaddr_in6 *sa)
{
- return geoip6_get_record(sa)->latitude;
+ GeoIPRecord *record;
+ float latitude;
+
+ record = geoip6_get_record(sa);
+ if (!record)
+ return 0;
+
+ latitude = record->latitude;
+
+ GeoIPRecord_delete(record);
+ return latitude;
}
-const char *geoip4_city_name(struct sockaddr_in *sa)
+char *geoip4_city_name(struct sockaddr_in *sa)
{
- return geoip4_get_record(sa)->city;
+ GeoIPRecord *record;
+ char *city = NULL;
+
+ record = geoip4_get_record(sa);
+ if (!record)
+ return NULL;
+
+ if (record->city)
+ city = xstrdup(record->city);
+
+ GeoIPRecord_delete(record);
+ return city;
}
-const char *geoip6_city_name(struct sockaddr_in6 *sa)
+char *geoip6_city_name(struct sockaddr_in6 *sa)
{
- return geoip6_get_record(sa)->city;
+ GeoIPRecord *record;
+ char *city = NULL;
+
+ record = geoip6_get_record(sa);
+ if (!record)
+ return NULL;
+
+ if (record->city)
+ city = xstrdup(record->city);
+
+ GeoIPRecord_delete(record);
+ return city;
}
-const char *geoip4_region_name(struct sockaddr_in *sa)
+char *geoip4_region_name(struct sockaddr_in *sa)
{
- return geoip4_get_record(sa)->region;
+ GeoIPRecord *record;
+ char *region = NULL;
+
+ record = geoip4_get_record(sa);
+ if (!record)
+ return NULL;
+
+ if (record->region)
+ region = xstrdup(record->region);
+
+ GeoIPRecord_delete(record);
+ return region;
}
-const char *geoip6_region_name(struct sockaddr_in6 *sa)
+char *geoip6_region_name(struct sockaddr_in6 *sa)
{
- return geoip6_get_record(sa)->region;
+ GeoIPRecord *record;
+ char *region = NULL;
+
+ record = geoip6_get_record(sa);
+ if (!record)
+ return NULL;
+
+ if (record->region)
+ region = xstrdup(record->region);
+
+ GeoIPRecord_delete(record);
+ return region;
}
const char *geoip4_country_name(struct sockaddr_in *sa)