]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
[Core, mod_sofia] Add switch_uint31_t type. Fix CSeq bigger than 2^31-1. 2459/head
authorAndrey Volk <andywolk@gmail.com>
Tue, 30 Apr 2024 18:14:29 +0000 (21:14 +0300)
committerAndrey Volk <andywolk@gmail.com>
Thu, 9 May 2024 19:20:14 +0000 (22:20 +0300)
src/include/switch_types.h
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia_presence.c
tests/unit/switch_core.c

index d315e46fc8ca9192cf8d88ea4fc05b3eaa9136c6..f8ae00790d97c10df9f10c383c4e3b3ff3e1077b 100644 (file)
@@ -255,6 +255,10 @@ SWITCH_BEGIN_EXTERN_C
 
 typedef uint8_t switch_byte_t;
 
+typedef struct {
+       unsigned int value : 31;
+} switch_uint31_t;
+
 typedef enum {
        SWITCH_PVT_PRIMARY = 0,
        SWITCH_PVT_SECONDARY
index bfd682c1f17fbb9b4f1ac98d08cbf0211610cf2f..8e2b1b483cd98b3367d29924bf66f50040be0a0b 100644 (file)
@@ -776,7 +776,7 @@ struct sofia_profile {
        int watchdog_enabled;
        switch_mutex_t *gw_mutex;
        uint32_t queued_events;
-       uint32_t last_cseq;
+       switch_uint31_t last_cseq;
        int tls_only;
        int tls_verify_date;
        enum tport_tls_verify_policy tls_verify_policy;
index 579cea83e28971f57ab026fedc9de6a3504ed418..48ad579411117f98a071b550c495875a82fc523e 100644 (file)
@@ -2112,12 +2112,12 @@ static int sofia_dialog_probe_callback(void *pArg, int argc, char **argv, char *
 
 #define SOFIA_PRESENCE_COLLISION_DELTA 50
 #define SOFIA_PRESENCE_ROLLOVER_YEAR (86400 * 365 * SOFIA_PRESENCE_COLLISION_DELTA)
-static uint32_t check_presence_epoch(void)
+static switch_uint31_t check_presence_epoch(void)
 {
        time_t now = switch_epoch_time_now(NULL);
-       uint32_t callsequence = (uint32_t)((now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA);
+       switch_uint31_t callsequence = { .value = (uint32_t)((now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA) };
 
-       if (!mod_sofia_globals.presence_year || callsequence >= SOFIA_PRESENCE_ROLLOVER_YEAR) {
+       if (!mod_sofia_globals.presence_year || callsequence.value >= SOFIA_PRESENCE_ROLLOVER_YEAR) {
                struct tm tm;
                switch_mutex_lock(mod_sofia_globals.mutex);
                tm = *(localtime(&now));
@@ -2125,7 +2125,7 @@ static uint32_t check_presence_epoch(void)
                if (tm.tm_year != mod_sofia_globals.presence_year) {
                        mod_sofia_globals.presence_epoch = (uint32_t)now - (tm.tm_yday * 86400) - (tm.tm_hour * 60 * 60) - (tm.tm_min * 60) - tm.tm_sec;
                        mod_sofia_globals.presence_year = tm.tm_year;
-                       callsequence = (uint32_t)(((uint32_t)now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA);
+                       callsequence.value = (uint32_t)(((uint32_t)now - mod_sofia_globals.presence_epoch) * SOFIA_PRESENCE_COLLISION_DELTA);
                }
 
                switch_mutex_unlock(mod_sofia_globals.mutex);
@@ -2136,17 +2136,17 @@ static uint32_t check_presence_epoch(void)
 
 uint32_t sofia_presence_get_cseq(sofia_profile_t *profile)
 {
-       uint32_t callsequence;
+       switch_uint31_t callsequence;
        int diff = 0;
 
        switch_mutex_lock(profile->ireg_mutex);
 
        callsequence = check_presence_epoch();
 
-       if (profile->last_cseq) {
-               diff = callsequence - profile->last_cseq;
+       if (profile->last_cseq.value) {
+               diff = (int)callsequence.value - (int)profile->last_cseq.value;
                if (diff <= 0 && diff > -100000) {
-                       callsequence = ++profile->last_cseq;
+                       callsequence.value = ++profile->last_cseq.value;
                }
        }
 
@@ -2154,8 +2154,7 @@ uint32_t sofia_presence_get_cseq(sofia_profile_t *profile)
 
        switch_mutex_unlock(profile->ireg_mutex);
 
-       return callsequence;
-
+       return (uint32_t)callsequence.value;
 }
 
 
index 1159017571e6a281c6e82bda2754464078bb87eb..2f06966582f94f1528eea1f7e0ee150f9a1353a7 100644 (file)
@@ -53,6 +53,26 @@ FST_CORE_BEGIN("./conf")
                }
                FST_TEARDOWN_END()
 
+               FST_TEST_BEGIN(test_switch_uint31_t_overflow)
+               {
+                       switch_uint31_t x;
+                       uint32_t overflow;
+
+                       x.value = 0x7fffffff;
+                       x.value++;
+
+                       fst_check_int_equals(x.value, 0);
+                       x.value++;
+                       fst_check_int_equals(x.value, 1);
+                       x.value -= 2;
+                       fst_check_int_equals(x.value, 0x7fffffff);
+
+                       overflow = (uint32_t)0x7fffffff + 1;
+                       x.value = overflow;
+                       fst_check_int_equals(x.value, 0);
+               }
+               FST_TEST_END()
+
                FST_TEST_BEGIN(test_switch_parse_cidr_v6)
                {
                        ip_t ip, mask;