diff --git a/daemon/call.c b/daemon/call.c index da9e3b350..c43fc81c8 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -689,8 +689,8 @@ struct call_media *call_media_new(struct call *call) { med->call = call; med->codecs_recv = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL); med->codecs_send = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL); - med->codec_names_recv = g_hash_table_new_full(str_hash, str_equal, NULL, (void (*)(void*)) g_queue_free); - med->codec_names_send = g_hash_table_new_full(str_hash, str_equal, NULL, (void (*)(void*)) g_queue_free); + med->codec_names_recv = g_hash_table_new_full(str_case_hash, str_case_equal, NULL, (void (*)(void*)) g_queue_free); + med->codec_names_send = g_hash_table_new_full(str_case_hash, str_case_equal, NULL, (void (*)(void*)) g_queue_free); return med; } diff --git a/daemon/codec.c b/daemon/codec.c index 569feebab..fdc42c4de 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -1343,7 +1343,7 @@ void codec_rtp_payload_types(struct call_media *media, struct call_media *other_ struct call *call = media->call; struct rtp_payload_type *pt; static const str str_all = STR_CONST_INIT("all"); - GHashTable *removed = g_hash_table_new_full(str_hash, str_equal, NULL, __payload_queue_free); + GHashTable *removed = g_hash_table_new_full(str_case_hash, str_case_equal, NULL, __payload_queue_free); int strip_all = 0, mask_all = 0; // start fresh diff --git a/lib/codeclib.c b/lib/codeclib.c index 28d60e96a..9ce37c842 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -725,7 +725,7 @@ void codeclib_init(int print) { avformat_network_init(); av_log_set_callback(avlog_ilog); - codecs_ht = g_hash_table_new(str_hash, str_equal); + codecs_ht = g_hash_table_new(str_case_hash, str_case_equal); codecs_ht_by_av = g_hash_table_new(g_direct_hash, g_direct_equal); for (int i = 0; i < G_N_ELEMENTS(__codec_defs); i++) { diff --git a/lib/str.c b/lib/str.c index 6de12c085..96cad05f7 100644 --- a/lib/str.c +++ b/lib/str.c @@ -22,6 +22,24 @@ gboolean str_equal(gconstpointer a, gconstpointer b) { return str_cmp_str((str *) a, (str *) b) == 0; } +guint str_case_hash(gconstpointer ss) { + const str *s = ss; + guint ret = 5381; + str it = *s; + + while (it.len > 0) { + ret = (ret << 5) + ret + (*it.s & 0xdf); + it.s++; + it.len--; + } + + return ret; +} + +gboolean str_case_equal(gconstpointer a, gconstpointer b) { + return str_casecmp_str((str *) a, (str *) b) == 0; +} + str *__str_sprintf(const char *fmt, ...) { str *ret; va_list ap; diff --git a/lib/str.h b/lib/str.h index 80172f73d..e296097c5 100644 --- a/lib/str.h +++ b/lib/str.h @@ -51,6 +51,7 @@ INLINE int str_cmp(const str *a, const char *b); INLINE int str_cmp_len(const str *a, const char *b, int len); /* compares two str objects */ INLINE int str_cmp_str(const str *a, const str *b); +INLINE int str_casecmp_str(const str *a, const str *b); /* compares two str objects, allows either to be NULL */ INLINE int str_cmp_str0(const str *a, const str *b); /* inits a str object from a regular string. returns out */ @@ -100,6 +101,8 @@ 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); /* returns a new str object, duplicates the pointers but doesn't duplicate the contents */ INLINE str *str_slice_dup(const str *); @@ -182,6 +185,20 @@ INLINE int str_cmp_str(const str *a, const str *b) { return 0; return memcmp(a->s, b->s, a->len); } +INLINE int str_casecmp_str(const str *a, const str *b) { + if (a->len < b->len) + return -1; + if (a->len > b->len) + return 1; + if (a->len == 0 && b->len == 0) + return 0; + // fail if any strings contains a null byte + if (memchr(a->s, '\0', a->len)) + return -1; + if (memchr(b->s, '\0', a->len)) + return 1; + return strncasecmp(a->s, b->s, a->len); +} INLINE int str_cmp_str0(const str *a, const str *b) { if (!a) { if (!b) diff --git a/t/auto-daemon-tests.pl b/t/auto-daemon-tests.pl index f5ca14fb6..123ad3432 100755 --- a/t/auto-daemon-tests.pl +++ b/t/auto-daemon-tests.pl @@ -1387,6 +1387,161 @@ rcv($sock_a, $port_b, rtpm(0, 2014, 4000+160*14, $ssrc, "\x00" x 160)); +($sock_a, $sock_b) = new_call([qw(198.51.100.1 2210)], [qw(198.51.100.3 2212)]); + +($port_a) = offer('one codec with one for transcoding, lower case', { ICE => 'remove', replace => ['origin'], + codec => { transcode => ['PCMA'] }}, < ['origin'] }, < 'remove', replace => ['origin'], + codec => { transcode => ['pcma'] }}, < ['origin'] }, <