diff options
author | João Valverde <j@v6e.pt> | 2023-07-06 12:16:29 +0100 |
---|---|---|
committer | João Valverde <j@v6e.pt> | 2023-07-08 23:06:49 +0100 |
commit | 75a778e8932270dfb3173e1a3a2074b0cacb869a (patch) | |
tree | b2d6e1558e967df316cd823d51f2af9caefeac82 /epan/addr_resolv.c | |
parent | ab7896df6c3cee375fa76a01be01931242de5cc5 (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.c | 31 |
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 |