aboutsummaryrefslogtreecommitdiffstats
path: root/epan/addr_resolv.c
diff options
context:
space:
mode:
authorJoão Valverde <j@v6e.pt>2023-07-06 12:16:29 +0100
committerJoão Valverde <j@v6e.pt>2023-07-08 23:06:49 +0100
commit75a778e8932270dfb3173e1a3a2074b0cacb869a (patch)
treeb2d6e1558e967df316cd823d51f2af9caefeac82 /epan/addr_resolv.c
parentab7896df6c3cee375fa76a01be01931242de5cc5 (diff)
Replace services file with static array
To speed up start-up we no longer read the services file from an external resource. Instead it is compiled statically into the binary in a sorted array. The personal services file is still parsed and loaded at startup, if it exists, to allow users to add custom entries and override global entries. For historical reasons the port list is mostly composed of the same entry for TCP and UDP. To avoid a lot of duplication we add an extra TCP+UDP table and do two lookups for TCP or UDP, one in the TCP+UDP table and the other in the TCP/UDP table. Because the services name space is pretty sparse, with lots of holes, we also use a binary search instead of a linear array with aprox. 49000 entries, where most would be empty.
Diffstat (limited to 'epan/addr_resolv.c')
-rw-r--r--epan/addr_resolv.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c
index f94d94810f..6a526ceb28 100644
--- a/epan/addr_resolv.c
+++ b/epan/addr_resolv.c
@@ -96,6 +96,7 @@
#include <epan/maxmind_db.h>
#include <epan/prefs.h>
#include <epan/uat.h>
+#include "services.h"
#define ENAME_HOSTS "hosts"
#define ENAME_SUBNETS "subnets"
@@ -303,7 +304,6 @@ gchar *g_wka_path = NULL; /* global well-known-addresses file */
gchar *g_manuf_path = NULL; /* global manuf file */
gchar *g_ipxnets_path = NULL; /* global ipxnets file */
gchar *g_pipxnets_path = NULL; /* personal ipxnets file */
-gchar *g_services_path = NULL; /* global services file */
gchar *g_pservices_path = NULL; /* personal services file */
gchar *g_pvlan_path = NULL; /* personal vlans file */
gchar *g_ss7pcs_path = NULL; /* personal ss7pcs file */
@@ -834,11 +834,30 @@ serv_name_lookup(port_type proto, guint port)
{
serv_port_t *serv_port_table = NULL;
const char *name;
+ ws_services_proto_t p;
+ /* first look in the personal services file + cache */
name = _serv_name_lookup(proto, port, &serv_port_table);
if (name != NULL)
return name;
+ /* now look in the global tables */
+ switch( proto) {
+ case PT_TCP: p = ws_tcp; break;
+ case PT_UDP: p = ws_udp; break;
+ case PT_SCTP: p = ws_sctp; break;
+ case PT_DCCP: p = ws_dccp; break;
+ default: ws_assert_not_reached();
+ }
+ name = global_services_lookup(port, p);
+ if (name) {
+ /* Cache result */
+ /* XXX would be nice to avoid the strdup for this name static string but user/custom entries
+ * are dynamic and they share the same table. */
+ add_service_name(proto, port, name);
+ return name;
+ }
+
if (serv_port_table == NULL) {
serv_port_table = wmem_new0(wmem_epan_scope(), serv_port_t);
wmem_map_insert(serv_port_hashtable, GUINT_TO_POINTER(port), serv_port_table);
@@ -857,12 +876,6 @@ initialize_services(void)
ws_assert(serv_port_hashtable == NULL);
serv_port_hashtable = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
- /* Compute the pathname of the services file. */
- if (g_services_path == NULL) {
- g_services_path = get_datafile_path(ENAME_SERVICES);
- }
- parse_services_file(g_services_path);
-
/* Compute the pathname of the personal services file */
if (g_pservices_path == NULL) {
/* Check profile directory before personal configuration */
@@ -883,8 +896,6 @@ static void
service_name_lookup_cleanup(void)
{
serv_port_hashtable = NULL;
- g_free(g_services_path);
- g_services_path = NULL;
g_free(g_pservices_path);
g_pservices_path = NULL;
}
@@ -1002,8 +1013,6 @@ enterprises_cleanup(void)
enterprises_hashtable = NULL;
g_free(g_penterprises_path);
g_penterprises_path = NULL;
- g_free(g_pservices_path);
- g_pservices_path = NULL;
}
/* Fill in an IP4 structure with info from subnets file or just with the