QUIC: Update IETF draft URL (draft-08)
[metze/wireshark/wip.git] / epan / geoip_db.c
index 3be70713a260b437c1eca32c29b0ddf087eadc15..164dec0496be31200d3c79f8bb8419ba01a071aa 100644 (file)
 #include <epan/prefs.h>
 #include <epan/value_string.h>
 
-#include <wsutil/report_err.h>
+#include <wsutil/report_message.h>
 #include <wsutil/file_util.h>
 
 /* This needs to match NUM_GEOIP_COLS in hostlist_table.h */
 #define MAX_GEOIP_DBS 13
 
+/*
+ * GeoIP_free is patched into our GeoIP distribution on Windows.
+ * See bug 13598.
+ */
+#ifndef HAVE_GEOIP_FREE
+#define GeoIP_free  free
+#endif
+
 /* Column names for each database type */
 value_string geoip_type_name_vals[] = {
     { GEOIP_COUNTRY_EDITION,        "Country" },
@@ -142,9 +150,7 @@ static void geoip_db_path_free_cb(void* p) {
     g_free(m->path);
 }
 
-/* called every time the user presses "Apply" or "OK in the list of
- * GeoIP directories, and also once on startup */
-static void geoip_db_post_update_cb(void) {
+static void geoip_dat_cleanup(void) {
     GeoIP *gi;
     guint i;
 
@@ -163,16 +169,22 @@ static void geoip_db_post_update_cb(void) {
          * databases as they weren't created by GeoIP_new()
          * or GeoIP_open() */
         gi = g_array_index(geoip_dat_arr, GeoIP *, i);
-        if (gi) {
-            g_free(gi);
-        }
+        g_free(gi);
         gi = g_array_index(geoip_dat_arr, GeoIP *, i+1);
-        if (gi) {
-            g_free(gi);
-        }
+        g_free(gi);
         /* finally, free the array itself */
         g_array_free(geoip_dat_arr, TRUE);
+        geoip_dat_arr = NULL;
     }
+}
+
+/* called every time the user presses "Apply" or "OK in the list of
+ * GeoIP directories, and also once on startup */
+static void geoip_db_post_update_cb(void) {
+    guint i;
+    GeoIP* gi;
+
+    geoip_dat_cleanup();
 
     /* allocate the array */
     geoip_dat_arr = g_array_new(FALSE, FALSE, sizeof(GeoIP *));
@@ -203,6 +215,11 @@ static void geoip_db_post_update_cb(void) {
     g_array_append_val(geoip_dat_arr, gi);
 }
 
+static void geoip_db_cleanup(void)
+{
+    geoip_dat_cleanup();
+}
+
 /**
  * Initialize GeoIP lookups
  */
@@ -228,6 +245,7 @@ geoip_db_pref_init(module_t *nameres)
             NULL,
             geoip_db_path_free_cb,
             geoip_db_post_update_cb,
+            geoip_db_cleanup,
             geoip_db_paths_fields);
 
     prefs_register_uat_preference(nameres,
@@ -279,9 +297,10 @@ geoip_db_lookup_latlon4(guint32 addr, float *lat, float *lon) {
                 case GEOIP_CITY_EDITION_REV0:
                 case GEOIP_CITY_EDITION_REV1:
                     gir = GeoIP_record_by_ipnum(gi, addr);
-                    if(gir) {
+                    if (gir) {
                         *lat = gir->latitude;
                         *lon = gir->longitude;
+                        GeoIPRecord_delete(gir);
                         return 0;
                     }
                     return -1;
@@ -322,7 +341,8 @@ char *
 geoip_db_lookup_ipv4(guint dbnum, guint32 addr, const char *not_found) {
     GeoIP *gi;
     GeoIPRecord *gir;
-    const char *raw_val;
+    char *name;
+    const char *country;
     char *val, *ret = NULL;
 
     if (dbnum > geoip_db_num_dbs()) {
@@ -335,9 +355,9 @@ geoip_db_lookup_ipv4(guint dbnum, guint32 addr, const char *not_found) {
     if (gi) {
         switch (gi->databaseType) {
             case GEOIP_COUNTRY_EDITION:
-                raw_val = GeoIP_country_name_by_ipnum(gi, addr);
-                if (raw_val) {
-                    ret = db_val_to_utf_8(raw_val, gi);
+                country = GeoIP_country_name_by_ipnum(gi, addr);
+                if (country) {
+                    ret = db_val_to_utf_8(country, gi);
                 }
                 break;
 
@@ -351,14 +371,17 @@ geoip_db_lookup_ipv4(guint dbnum, guint32 addr, const char *not_found) {
                 } else if (gir && gir->city) {
                     ret = db_val_to_utf_8(gir->city, gi);
                 }
+                if (gir)
+                    GeoIPRecord_delete(gir);
                 break;
 
             case GEOIP_ORG_EDITION:
             case GEOIP_ISP_EDITION:
             case GEOIP_ASNUM_EDITION:
-                raw_val = GeoIP_name_by_ipnum(gi, addr);
-                if (raw_val) {
-                    ret = db_val_to_utf_8(raw_val, gi);
+                name = GeoIP_name_by_ipnum(gi, addr);
+                if (name) {
+                    ret = db_val_to_utf_8(name, gi);
+                    GeoIP_free(name);
                 }
                 break;
 
@@ -443,10 +466,11 @@ geoip_db_lookup_latlon6(geoipv6_t addr _U_, float *lat _U_, float *lon _U_) {
 #endif /* NUM_DB_TYPES */
 
 char *
-geoip_db_lookup_ipv6(guint dbnum, struct e_in6_addr addr, const char *not_found) {
+geoip_db_lookup_ipv6(guint dbnum, ws_in6_addr addr, const char *not_found) {
     GeoIP *gi;
     geoipv6_t gaddr;
-    const char *raw_val;
+    char *name;
+    const char *country;
     char *val, *ret = NULL;
 #if NUM_DB_TYPES > 31
     GeoIPRecord *gir;
@@ -464,9 +488,9 @@ geoip_db_lookup_ipv6(guint dbnum, struct e_in6_addr addr, const char *not_found)
     if (gi) {
         switch (gi->databaseType) {
             case GEOIP_COUNTRY_EDITION_V6:
-                raw_val = GeoIP_country_name_by_ipnum_v6(gi, gaddr);
-                if (raw_val) {
-                    ret = db_val_to_utf_8(raw_val, gi);
+                country = GeoIP_country_name_by_ipnum_v6(gi, gaddr);
+                if (country) {
+                    ret = db_val_to_utf_8(country, gi);
                 }
                 break;
 
@@ -486,9 +510,10 @@ geoip_db_lookup_ipv6(guint dbnum, struct e_in6_addr addr, const char *not_found)
             case GEOIP_ORG_EDITION_V6:
             case GEOIP_ISP_EDITION_V6:
             case GEOIP_ASNUM_EDITION_V6:
-                raw_val = GeoIP_name_by_ipnum_v6(gi, gaddr);
-                if (raw_val) {
-                    ret = db_val_to_utf_8(raw_val, gi);
+                name = GeoIP_name_by_ipnum_v6(gi, gaddr);
+                if (name) {
+                    ret = db_val_to_utf_8(name, gi);
+                    GeoIP_free(name);
                 }
                 break;
 #endif /* NUM_DB_TYPES */
@@ -539,7 +564,7 @@ geoip_db_lookup_ipv6(guint dbnum, struct e_in6_addr addr, const char *not_found)
 #else /* HAVE_GEOIP_V6 */
 
 char *
-geoip_db_lookup_ipv6(guint dbnum _U_, struct e_in6_addr addr _U_, const char *not_found) {
+geoip_db_lookup_ipv6(guint dbnum _U_, ws_in6_addr addr _U_, const char *not_found) {
     if (not_found == NULL)
         return NULL;