Browse Source

MT#55283 enforce hash table types in callbacks

For typed hash tables, enforce the correct type in the arguments to the
hashing and equality functions.

Adapt existing affected callback functions and change their arguments
from void* to the respective types.

Add reverse casts to GHashFunc and GEqualFunc in instances where these
functions are used in non-typed hash tables (that should be converted at
a later point).

Add convenience macro to create typed wrapper functions for hash tables
that use "direct" hashing (i.e. the pointer value).

Add wrappers for existing GLib functions that have generic arguments so
that they can be used in typed hash tables.

Change-Id: I43bb32969208f4aae49584d95c0df8353df6e2a0
rfuchs/dataport
Richard Fuchs 2 years ago
parent
commit
a140d83975
19 changed files with 88 additions and 69 deletions
  1. +2
    -2
      daemon/call.c
  2. +4
    -5
      daemon/codec.c
  3. +2
    -2
      daemon/cookie_cache.c
  4. +12
    -23
      daemon/ice.c
  5. +8
    -7
      daemon/janus.c
  6. +3
    -1
      daemon/media_player.c
  7. +2
    -2
      daemon/media_socket.c
  8. +10
    -2
      daemon/sdp.c
  9. +1
    -1
      daemon/statistics.c
  10. +2
    -1
      daemon/tcp_listener.c
  11. +3
    -2
      daemon/websocket.c
  12. +3
    -1
      include/call.h
  13. +14
    -0
      lib/auxlib.h
  14. +1
    -1
      lib/codeclib.c
  15. +11
    -1
      lib/containers.h
  16. +1
    -7
      lib/socket.c
  17. +1
    -3
      lib/socket.h
  18. +4
    -4
      lib/str.c
  19. +4
    -4
      lib/str.h

+ 2
- 2
daemon/call.c View File

@ -461,7 +461,7 @@ void kill_calls_timer(GSList *list, const char *url) {
goto destroy;
if (rtpe_config.fmt == XF_KAMAILIO)
dup_tags = g_hash_table_new(str_hash, str_equal);
dup_tags = g_hash_table_new((GHashFunc) str_hash, (GEqualFunc) str_equal);
rwlock_lock_r(&ca->master_lock);
@ -4193,7 +4193,7 @@ struct call_monologue *__monologue_create(call_t *call) {
ret->created = rtpe_now.tv_sec;
ret->associated_tags = g_hash_table_new(g_direct_hash, g_direct_equal);
ret->medias = medias_arr_new();
ret->media_ids = g_hash_table_new(str_hash, str_equal);
ret->media_ids = g_hash_table_new((GHashFunc) str_hash, (GEqualFunc) str_equal);
ret->ssrc_hash = create_ssrc_hash_call();
ret->sdp_attr_print = sdp_insert_monologue_attributes;


+ 4
- 5
daemon/codec.c View File

@ -1043,12 +1043,10 @@ static void __codec_rtcp_timer(struct call_media *receiver) {
// XXX unify with media player into a generic RTCP player
}
static unsigned int __codec_handler_hash(const void *p) {
const struct codec_handler *h = p;
static unsigned int __codec_handler_hash(const struct codec_handler *h) {
return h->source_pt.payload_type ^ GPOINTER_TO_UINT(h->sink);
}
static int __codec_handler_eq(const void *a, const void *b) {
const struct codec_handler *h = a, *j = b;
static int __codec_handler_eq(const struct codec_handler *h, const struct codec_handler *j) {
return h->source_pt.payload_type == j->source_pt.payload_type
&& h->sink == j->sink;
}
@ -4826,7 +4824,8 @@ void codec_tracker_update(struct codec_store *cs, struct codec_store *orig_cs) {
// build our tables
GHashTable *all_clockrates = g_hash_table_new(g_direct_hash, g_direct_equal);
GHashTable *all_supp_codecs = g_hash_table_new_full(str_case_hash, str_case_equal, free,
GHashTable *all_supp_codecs = g_hash_table_new_full((GHashFunc) str_case_hash,
(GEqualFunc) str_case_equal, free,
(GDestroyNotify) g_hash_table_destroy);
for (__auto_type l = cs->codec_prefs.head; l; l = l->next)
__insert_codec_tracker(all_clockrates, all_supp_codecs, sct, l);


+ 2
- 2
daemon/cookie_cache.c View File

@ -9,8 +9,8 @@
#include "str.h"
INLINE void cookie_cache_state_init(struct cookie_cache_state *s) {
s->in_use = g_hash_table_new(str_hash, str_equal);
s->cookies = g_hash_table_new_full(str_hash, str_equal, free, cache_entry_free);
s->in_use = g_hash_table_new((GHashFunc) str_hash, (GEqualFunc) str_equal);
s->cookies = g_hash_table_new_full((GHashFunc) str_hash, (GEqualFunc) str_equal, free, cache_entry_free);
}
INLINE void cookie_cache_state_cleanup(struct cookie_cache_state *s) {
g_hash_table_destroy(s->cookies);


+ 12
- 23
daemon/ice.c View File

@ -87,8 +87,8 @@ const char * const ice_type_strings[] = {
static unsigned int frag_key_hash(const void *A);
static int frag_key_eq(const void *A, const void *B);
static unsigned int frag_key_hash(const struct fragment_key *A);
static int frag_key_eq(const struct fragment_key *A, const struct fragment_key *B);
static void fragment_key_free(struct fragment_key *);
TYPED_GQUEUE(fragment, struct sdp_fragment)
@ -133,13 +133,10 @@ static void ice_update_media_streams(struct call_monologue *ml, sdp_streams_q *s
}
static unsigned int frag_key_hash(const void *A) {
const struct fragment_key *a = A;
static unsigned int frag_key_hash(const struct fragment_key *a) {
return str_hash(&a->call_id) ^ str_hash(&a->from_tag);
}
static int frag_key_eq(const void *A, const void *B) {
const struct fragment_key *a = A;
const struct fragment_key *b = B;
static int frag_key_eq(const struct fragment_key *a, const struct fragment_key *b) {
return str_equal(&a->call_id, &b->call_id)
&& str_equal(&a->from_tag, &b->from_tag);
}
@ -346,39 +343,31 @@ static struct ice_candidate_pair *__pair_candidate(stream_fd *sfd, struct ice_ag
return pair;
}
static unsigned int __pair_hash(const void *p) {
const struct ice_candidate_pair *pair = p;
static unsigned int __pair_hash(const struct ice_candidate_pair *pair) {
return g_direct_hash(pair->local_intf) ^ g_direct_hash(pair->remote_candidate);
}
static int __pair_equal(const void *a, const void *b) {
const struct ice_candidate_pair *A = a, *B = b;
static int __pair_equal(const struct ice_candidate_pair *A, const struct ice_candidate_pair *B) {
return A->local_intf == B->local_intf
&& A->remote_candidate == B->remote_candidate;
}
static unsigned int __cand_hash(const void *p) {
const struct ice_candidate *cand = p;
static unsigned int __cand_hash(const struct ice_candidate *cand) {
return endpoint_hash(&cand->endpoint) ^ cand->component_id;
}
static int __cand_equal(const void *a, const void *b) {
const struct ice_candidate *A = a, *B = b;
static int __cand_equal(const struct ice_candidate *A, const struct ice_candidate *B) {
return endpoint_eq(&A->endpoint, &B->endpoint)
&& A->component_id == B->component_id;
}
static unsigned int __found_hash(const void *p) {
const struct ice_candidate *cand = p;
static unsigned int __found_hash(const struct ice_candidate *cand) {
return str_hash(&cand->foundation) ^ cand->component_id;
}
static int __found_equal(const void *a, const void *b) {
const struct ice_candidate *A = a, *B = b;
static int __found_equal(const struct ice_candidate *A, const struct ice_candidate *B) {
return str_equal(&A->foundation, &B->foundation)
&& A->component_id == B->component_id;
}
static unsigned int __trans_hash(const void *p) {
const uint32_t *tp = p;
static unsigned int __trans_hash(const uint32_t *tp) {
return tp[0] ^ tp[1] ^ tp[2];
}
static int __trans_equal(const void *a, const void *b) {
const uint32_t *A = a, *B = b;
static int __trans_equal(const uint32_t *A, const uint32_t *B) {
return A[0] == B[0] && A[1] == B[1] && A[2] == B[2];
}
static int __pair_prio_cmp(const void *a, const void *b) {


+ 8
- 7
daemon/janus.c View File

@ -14,9 +14,10 @@
#include "ice.h"
#include "log_funcs.h"
TYPED_GHASHTABLE(janus_handles_set, uint64_t, void, g_int64_hash, g_int64_equal, NULL, NULL)
TYPED_GHASHTABLE(janus_handles_set, uint64_t, void, int64_hash, int64_eq, NULL, NULL)
TYPED_DIRECT_FUNCS(websocket_conn_direct_hash, websocket_conn_direct_eq, struct websocket_conn)
TYPED_GHASHTABLE(janus_websockets_ht, struct websocket_conn, struct websocket_conn,
g_direct_hash, g_direct_equal, NULL, NULL)
websocket_conn_direct_hash, websocket_conn_direct_eq, NULL, NULL)
struct janus_session { // "login" session
struct obj obj;
@ -27,7 +28,7 @@ struct janus_session { // "login" session
janus_handles_set handles; // handle ID -> 0x1. handle ID owned by janus_handles
};
TYPED_GHASHTABLE(janus_sessions_ht, uint64_t, struct janus_session, g_int64_hash, g_int64_equal, NULL, NULL)
TYPED_GHASHTABLE(janus_sessions_ht, uint64_t, struct janus_session, int64_hash, int64_eq, NULL, NULL)
struct janus_handle { // corresponds to a conference participant
@ -36,10 +37,10 @@ struct janus_handle { // corresponds to a conference participant
uint64_t room;
};
TYPED_GHASHTABLE(janus_handles_ht, uint64_t, struct janus_handle, g_int64_hash, g_int64_equal, NULL, NULL)
TYPED_GHASHTABLE(janus_handles_ht, uint64_t, struct janus_handle, int64_hash, int64_eq, NULL, NULL)
TYPED_GHASHTABLE(janus_feeds_ht, uint64_t, uint64_t, g_int64_hash, g_int64_equal, g_free, g_free)
TYPED_GHASHTABLE(janus_feeds_ht, uint64_t, uint64_t, int64_hash, int64_eq, g_free, g_free)
struct janus_room {
uint64_t id;
@ -51,10 +52,10 @@ struct janus_room {
janus_feeds_ht feeds; // feed ID -> handle ID
};
TYPED_GHASHTABLE(janus_rooms_ht, uint64_t, struct janus_room, g_int64_hash, g_int64_equal, NULL, NULL)
TYPED_GHASHTABLE(janus_rooms_ht, uint64_t, struct janus_room, int64_hash, int64_eq, NULL, NULL)
TYPED_GHASHTABLE(janus_tokens_ht, char, time_t, g_str_hash, g_str_equal, g_free, g_free)
TYPED_GHASHTABLE(janus_tokens_ht, char, time_t, c_str_hash, c_str_equal, g_free, g_free)
static mutex_t janus_lock;


+ 3
- 1
daemon/media_player.c View File

@ -47,7 +47,9 @@ struct media_player_cache_index {
struct media_player_content_index index;
rtp_payload_type dst_pt;
};
TYPED_GHASHTABLE(media_player_ht, struct media_player, struct media_player, g_direct_hash, g_direct_equal, NULL, NULL) // XXX ref counting players
TYPED_DIRECT_FUNCS(media_player_direct_hash, media_player_direct_eq, struct media_player)
TYPED_GHASHTABLE(media_player_ht, struct media_player, struct media_player, media_player_direct_hash,
media_player_direct_eq, NULL, NULL) // XXX ref counting players
struct media_player_cache_entry {
volatile bool finished;
// "unfinished" elements, only used while decoding is active:


+ 2
- 2
daemon/media_socket.c View File

@ -422,7 +422,7 @@ static GQueue __preferred_lists_for_family[__SF_LAST];
GQueue all_local_interfaces = G_QUEUE_INIT;
TYPED_GHASHTABLE(local_sockets_ht, endpoint_t, stream_fd, endpoint_t_hash, endpoint_t_eq, NULL, stream_fd_put)
TYPED_GHASHTABLE(local_sockets_ht, endpoint_t, stream_fd, endpoint_hash, endpoint_eq, NULL, stream_fd_put)
static rwlock_t local_media_socket_endpoints_lock;
static local_sockets_ht local_media_socket_endpoints;
@ -776,7 +776,7 @@ static void __interface_append(struct intf_config *ifa, sockfamily_t *fam, bool
lif->name = ifa->name;
lif->name_base = ifa->name_base;
lif->preferred_family = fam;
lif->rr_specs = g_hash_table_new(str_hash, str_equal);
lif->rr_specs = g_hash_table_new((GHashFunc) str_hash, (GEqualFunc) str_equal);
g_hash_table_insert(__logical_intf_name_family_hash, lif, lif);
if (ifa->local_address.addr.family == fam) {
q = __interface_list_for_family(fam);


+ 10
- 2
daemon/sdp.c View File

@ -77,9 +77,17 @@ struct sdp_connection {
unsigned int parsed:1;
};
INLINE unsigned int attr_id_hash(const enum attr_id *e) {
int i = *e;
return g_int_hash(&i);
}
INLINE gboolean attr_id_eq(const enum attr_id *a, const enum attr_id *b) {
return *a == *b;
}
TYPED_GQUEUE(attributes, struct sdp_attribute)
TYPED_GHASHTABLE(attr_id_ht, enum attr_id, struct sdp_attribute, g_int_hash, g_int_equal, NULL, NULL)
TYPED_GHASHTABLE(attr_list_ht, enum attr_id, attributes_q, g_int_hash, g_int_equal, NULL, g_queue_free)
TYPED_GHASHTABLE(attr_id_ht, enum attr_id, struct sdp_attribute, attr_id_hash, attr_id_eq, NULL, NULL)
TYPED_GHASHTABLE(attr_list_ht, enum attr_id, attributes_q, attr_id_hash, attr_id_eq, NULL, g_queue_free)
TYPED_GHASHTABLE_LOOKUP_INSERT(attr_list_ht, NULL, attributes_q_new)
struct sdp_attributes {


+ 1
- 1
daemon/statistics.c View File

@ -942,7 +942,7 @@ static void codec_stats_free(struct codec_stats *stats_entry) {
g_slice_free1(sizeof(*stats_entry), stats_entry);
}
TYPED_GHASHTABLE_IMPL(codec_stats_ht, g_str_hash, g_str_equal, NULL, codec_stats_free)
TYPED_GHASHTABLE_IMPL(codec_stats_ht, c_str_hash, c_str_equal, NULL, codec_stats_free)
void statistics_init(void) {
gettimeofday(&rtpe_started, NULL);


+ 2
- 1
daemon/tcp_listener.c View File

@ -26,7 +26,8 @@ struct streambuf_callback {
struct obj *parent;
};
TYPED_GHASHTABLE_IMPL(tcp_streams_ht, g_direct_hash, g_direct_equal, NULL, NULL)
TYPED_DIRECT_FUNCS(tcp_direct_hash, tcp_direct_eq, struct streambuf_stream)
TYPED_GHASHTABLE_IMPL(tcp_streams_ht, tcp_direct_hash, tcp_direct_eq, NULL, NULL)
static void tcp_listener_incoming(int fd, void *p) {


+ 3
- 2
daemon/websocket.c View File

@ -26,8 +26,9 @@ struct websocket_output {
ssize_t content_length;
};
TYPED_DIRECT_FUNCS(janus_session_hash, janus_session_eq, struct janus_session)
TYPED_GHASHTABLE(janus_sessions_ht, struct janus_session, struct janus_session,
g_direct_hash, g_direct_equal, NULL, NULL)
janus_session_hash, janus_session_eq, NULL, NULL)
TYPED_GQUEUE(websocket_message, struct websocket_message)
TYPED_GQUEUE(websocket_output, struct websocket_output)
@ -383,7 +384,7 @@ static const char *websocket_http_ping(struct websocket_message *wm) {
}
TYPED_GHASHTABLE(metric_types_ht, char, void, g_str_hash, g_str_equal, NULL, NULL)
TYPED_GHASHTABLE(metric_types_ht, char, void, c_str_hash, c_str_equal, NULL, NULL)
static const char *websocket_http_metrics(struct websocket_message *wm) {
ilogs(http, LOG_DEBUG, "Respoding to GET /metrics");


+ 3
- 1
include/call.h View File

@ -348,7 +348,9 @@ TYPED_GHASHTABLE(codecs_ht, void, rtp_payload_type, g_direct_hash, g_direct_equa
TYPED_GHASHTABLE(codec_names_ht, str, GQueue, str_case_hash, str_case_equal, str_free, g_queue_free)
TYPED_GHASHTABLE_LOOKUP_INSERT(codec_names_ht, str_free, g_queue_new)
TYPED_GQUEUE(subscription, struct media_subscription)
TYPED_GHASHTABLE(subscription_ht, struct call_media, subscription_list, g_direct_hash, g_direct_equal, NULL, NULL)
TYPED_DIRECT_FUNCS(media_direct_hash, media_direct_eq, struct call_media)
TYPED_GHASHTABLE(subscription_ht, struct call_media, subscription_list, media_direct_hash, media_direct_eq,
NULL, NULL)
struct codec_store {


+ 14
- 0
lib/auxlib.h View File

@ -97,6 +97,13 @@ INLINE void random_string(unsigned char *buf, int len) {
(void) ret;
}
INLINE unsigned int c_str_hash(const char *s) {
return g_str_hash(s);
}
INLINE gboolean c_str_equal(const char *a, const char *b) {
return g_str_equal(a, b);
}
/*** MUTEX ABSTRACTION ***/
@ -464,6 +471,13 @@ INLINE pid_t gettid(void) {
}
#endif
INLINE unsigned int int64_hash(const uint64_t *s) {
return g_int64_hash(s);
}
INLINE gboolean int64_eq(const uint64_t *a, const uint64_t *b) {
return *a == *b;
}
/*** TAINT FUNCTIONS ***/


+ 1
- 1
lib/codeclib.c View File

@ -1581,7 +1581,7 @@ void codeclib_init(int print) {
avformat_network_init();
av_log_set_callback(avlog_ilog);
codecs_ht = g_hash_table_new(str_case_hash, str_case_equal);
codecs_ht = g_hash_table_new((GHashFunc) str_case_hash, (GEqualFunc) str_case_equal);
codecs_ht_by_av = g_hash_table_new(g_direct_hash, g_direct_equal);
cc_init();


+ 11
- 1
lib/containers.h View File

@ -106,7 +106,9 @@
#define TYPED_GHASHTABLE_IMPL(type_name, hash_func, eq_func, key_free_func, value_free_func) \
static inline type_name type_name##_new(void) { \
GHashTable *ht = g_hash_table_new_full(hash_func, eq_func, \
unsigned int (*__hash_func)(__typeof__(((type_name *)0)->__ckey)) = hash_func; \
gboolean (*__eq_func)(__typeof__(((type_name *)0)->__ckey), __typeof__(((type_name *)0)->__ckey)) = eq_func; \
GHashTable *ht = g_hash_table_new_full((GHashFunc) __hash_func, (GEqualFunc) __eq_func, \
(GDestroyNotify) key_free_func, \
(GDestroyNotify) value_free_func); \
return (type_name) { ht }; \
@ -132,6 +134,14 @@
return r; \
}
#define TYPED_DIRECT_FUNCS(hash_name, eq_name, type) \
static inline unsigned int hash_name(const type *a) { \
return g_direct_hash(a); \
} \
static inline gboolean eq_name(const type *a, const type *b) { \
return a == b; \
}
#define TYPED_GQUEUE(type_name, contained_type) \
typedef union type_name##_slist type_name##_slist; \


+ 1
- 7
lib/socket.c View File

@ -542,15 +542,9 @@ gint sockaddr_t_eq(gconstpointer a, gconstpointer b) {
unsigned int endpoint_hash(const endpoint_t *a) {
return sockaddr_hash(&a->address) ^ a->port;
}
bool endpoint_eq(const endpoint_t *a, const endpoint_t *b) {
gboolean endpoint_eq(const endpoint_t *a, const endpoint_t *b) {
return sockaddr_eq(&a->address, &b->address) && a->port == b->port;
}
guint endpoint_t_hash(gconstpointer a) {
return endpoint_hash(a);
}
gint endpoint_t_eq(gconstpointer a, const void *b) {
return endpoint_eq(a, b);
}


+ 1
- 3
lib/socket.h View File

@ -294,9 +294,7 @@ guint sockaddr_t_hash(gconstpointer); // for glib
gint sockaddr_t_eq(gconstpointer, gconstpointer); // true/false, for glib
unsigned int endpoint_hash(const endpoint_t *);
bool endpoint_eq(const endpoint_t *, const endpoint_t *); /* true/false */
guint endpoint_t_hash(gconstpointer); // for glib
gint endpoint_t_eq(gconstpointer, gconstpointer); // true/false, for glib
gboolean endpoint_eq(const endpoint_t *, const endpoint_t *); /* true/false */
INLINE sockfamily_t *get_socket_family_enum(enum socket_families i) {
if (i >= __SF_LAST)


+ 4
- 4
lib/str.c View File

@ -4,7 +4,7 @@
#include <stdarg.h>
/* adapted from g_str_hash() from glib */
guint str_hash(gconstpointer ss) {
guint str_hash(const str *ss) {
const str *s = ss;
guint ret = 5381;
str it = *s;
@ -18,11 +18,11 @@ guint str_hash(gconstpointer ss) {
return ret;
}
gboolean str_equal(gconstpointer a, gconstpointer b) {
gboolean str_equal(const str *a, const str *b) {
return str_cmp_str((str *) a, (str *) b) == 0;
}
guint str_case_hash(gconstpointer ss) {
guint str_case_hash(const str *ss) {
const str *s = ss;
guint ret = 5381;
str it = *s;
@ -36,7 +36,7 @@ guint str_case_hash(gconstpointer ss) {
return ret;
}
gboolean str_case_equal(gconstpointer a, gconstpointer b) {
gboolean str_case_equal(const str *a, const str *b) {
return str_casecmp_str((str *) a, (str *) b) == 0;
}


+ 4
- 4
lib/str.h View File

@ -178,10 +178,10 @@ INLINE GString *g_string_new_str(void);
INLINE str *g_string_free_str(GString *gs);
/* for GHashTables */
guint str_hash(gconstpointer s);
gboolean str_equal(gconstpointer a, gconstpointer b);
guint str_case_hash(gconstpointer s);
gboolean str_case_equal(gconstpointer a, gconstpointer b);
guint str_hash(const str *s);
gboolean str_equal(const str *a, const str *b);
guint str_case_hash(const str *s);
gboolean str_case_equal(const str *a, const str *b);
TYPED_GHASHTABLE(str_case_ht, str, str, str_case_hash, str_case_equal, free, NULL)
TYPED_GHASHTABLE(str_case_value_ht, str, str, str_case_hash, str_case_equal, free, free)


Loading…
Cancel
Save