diff options
author | Vadim Kochan <vadim4j@gmail.com> | 2017-02-04 11:56:14 +0200 |
---|---|---|
committer | Tobias Klauser <tklauser@distanz.ch> | 2017-02-06 17:26:28 +0100 |
commit | 8fd19eefa46b313673d6ba2a0194a68674ef5ea9 (patch) | |
tree | 569da73381afb80fe8eb70d1183fbac0339da4ef /geoip.c | |
parent | 1e1383fea55fb35cec96a352da93c2a31d9e897c (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.c | 114 |
1 files changed, 98 insertions, 16 deletions
@@ -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)) ? : ∅ + 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) ? : ∅ + 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) |