From ee8b3a26f34ef4540b21691577423f545714fc7d Mon Sep 17 00:00:00 2001 From: Liviu Chircu Date: Fri, 8 Nov 2024 17:27:18 +0200 Subject: [PATCH] usrloc: Make the contact branch flags replication more robust The Contact branch flags are now replicated as strings, to prevent any mis-matches with the neighbour nodes, which may use different internal representations of the same flags (e.g. due to different opensips.cfg). usrloc BIN packet version updated: now at version "4". Backwards-compatible with version "3" usrloc packets. Credits to Michael Ulitskiy and Bogdan Iancu for helping debug this! --- bin_interface.h | 30 ++++++++++++++------- modules/usrloc/ul_cluster.c | 52 +++++++++++++++++++------------------ modules/usrloc/ul_cluster.h | 4 +-- 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/bin_interface.h b/bin_interface.h index 1db49240e91..8f98612f329 100644 --- a/bin_interface.h +++ b/bin_interface.h @@ -45,19 +45,29 @@ #define is_valid_bin_packet(_p) \ (memcmp(_p, BIN_PACKET_MARKER, BIN_PACKET_MARKER_SIZE) == 0) +/* make sure a BIN packet has an exact version or a range of versions */ +#define ensure_bin_version(pkt, needed) _ensure_bin_version(pkt, needed, "") +#define ensure_bin_version2(pkt, v1, v2) _ensure_bin_version2(pkt, v1, v2, "") #define _ensure_bin_version(pkt, needed, pkt_desc) \ do { \ - if (get_bin_pkg_version(pkt) != (needed)) { \ - if (pkt_desc && *pkt_desc) \ - LM_INFO("discarding %s, ver %d: need ver %d\n", \ - pkt_desc, get_bin_pkg_version(pkt), (needed)); \ - else \ - LM_INFO("discarding packet type %d, ver %d: need ver %d\n", \ - pkt->type, get_bin_pkg_version(pkt), (needed)); \ - return; \ - } \ + if (get_bin_pkg_version(pkt) != (needed)) \ + _bin_version_error_return(pkt, pkt_desc, needed) \ } while (0) -#define ensure_bin_version(pkt, needed) _ensure_bin_version(pkt, needed, "") +#define _ensure_bin_version2(pkt, vmin, vmax, pkt_desc) \ + do { \ + if (get_bin_pkg_version(pkt)<(vmin) || get_bin_pkg_version(pkt)>(vmax)) \ + _bin_version_error_return(pkt, pkt_desc, vmax) \ + } while (0) +#define _bin_version_error_return(pkt, pkt_desc, needed) \ + { \ + if (pkt_desc && *pkt_desc) \ + LM_INFO("discarding %s (%d), ver %d: need ver %d\n", \ + pkt_desc, pkt->type, get_bin_pkg_version(pkt), (needed)); \ + else \ + LM_INFO("discarding packet type %d, ver %d: need ver %d\n", \ + pkt->type, get_bin_pkg_version(pkt), (needed)); \ + return; \ + } typedef unsigned bin_packet_flags_t; #define BINFL_SYSMEM (1U<<0) diff --git a/modules/usrloc/ul_cluster.c b/modules/usrloc/ul_cluster.c index 29c7eb424c4..af89da492e2 100644 --- a/modules/usrloc/ul_cluster.c +++ b/modules/usrloc/ul_cluster.c @@ -229,7 +229,8 @@ void bin_push_contact(bin_packet_t *packet, urecord_t *r, ucontact_t *c, bin_push_str(packet, c->sock?get_socket_internal_name(c->sock):NULL); bin_push_int(packet, c->cseq); bin_push_int(packet, c->flags); - bin_push_int(packet, c->cflags); + st = bitmask_to_flag_list(FLAG_TYPE_BRANCH, c->cflags); + bin_push_str(packet, &st); bin_push_int(packet, c->methods); st.s = (char *)&c->last_modified; @@ -317,7 +318,8 @@ void replicate_ucontact_update(urecord_t *r, ucontact_t *ct, bin_push_str(&packet, ct->sock?get_socket_internal_name(ct->sock):NULL); bin_push_int(&packet, ct->cseq); bin_push_int(&packet, ct->flags); - bin_push_int(&packet, ct->cflags); + st = bitmask_to_flag_list(FLAG_TYPE_BRANCH, ct->cflags); + bin_push_str(&packet, &st); bin_push_int(&packet, ct->methods); st.s = (char *)&ct->last_modified; @@ -501,7 +503,7 @@ static int receive_ucontact_insert(bin_packet_t *packet) { static ucontact_info_t ci; static str d, aor, contact_str, callid, - user_agent, path, attr, st, sock, kv_str; + user_agent, path, attr, st, sock, kv_str, cflags_str; udomain_t *domain; urecord_t *record; ucontact_t *contact, *ct; @@ -558,12 +560,18 @@ static int receive_ucontact_insert(bin_packet_t *packet) if (!ci.sock) LM_DBG("non-local socket <%.*s>\n", sock.len, sock.s); } else { - ci.sock = NULL; + ci.sock = NULL; } bin_pop_int(packet, &ci.cseq); bin_pop_int(packet, &ci.flags); - bin_pop_int(packet, &ci.cflags); + if (pkg_ver <= UL_BIN_V3) { + bin_pop_int(packet, &ci.cflags); + } else { + bin_pop_str(packet, &cflags_str); + ci.cflags = flag_list_to_bitmask( + (str_const *)&cflags_str, FLAG_TYPE_BRANCH, FLAG_DELIM, 0); + } bin_pop_int(packet, &ci.methods); bin_pop_str(packet, &st); @@ -666,7 +674,7 @@ static int receive_ucontact_update(bin_packet_t *packet) { static ucontact_info_t ci; static str d, aor, contact_str, callid, - user_agent, path, attr, st, kv_str, sock; + user_agent, path, attr, st, kv_str, sock, cflags_str; udomain_t *domain; urecord_t *record; ucontact_t *contact; @@ -725,7 +733,13 @@ static int receive_ucontact_update(bin_packet_t *packet) bin_pop_int(packet, &ci.cseq); bin_pop_int(packet, &ci.flags); - bin_pop_int(packet, &ci.cflags); + if (pkg_ver <= UL_BIN_V3) { + bin_pop_int(packet, &ci.cflags); + } else { + bin_pop_str(packet, &cflags_str); + ci.cflags = flag_list_to_bitmask( + (str_const *)&cflags_str, FLAG_TYPE_BRANCH, FLAG_DELIM, 0); + } bin_pop_int(packet, &ci.methods); bin_pop_str(packet, &st); @@ -912,48 +926,36 @@ void receive_binary_packets(bin_packet_t *pkt) { int rc; - /* Supported smooth BIN transitions: - UL_BIN_V2 -> UL_BIN_V3: the "cmatch" has been added - (assume: CT_MATCH_CONTACT_CALLID if not present) - */ - short ver = get_bin_pkg_version(pkt); - LM_DBG("received a binary packet [%d]!\n", pkt->type); switch (pkt->type) { case REPL_URECORD_INSERT: - if (ver != UL_BIN_V2) - ensure_bin_version(pkt, UL_BIN_VERSION); + _ensure_bin_version2(pkt, UL_BIN_V2, UL_BIN_V4, "usrloc aor-ins packet"); rc = receive_urecord_insert(pkt); break; case REPL_URECORD_DELETE: - if (ver != UL_BIN_V2) - ensure_bin_version(pkt, UL_BIN_VERSION); + _ensure_bin_version2(pkt, UL_BIN_V2, UL_BIN_V4, "usrloc aor-del packet"); rc = receive_urecord_delete(pkt); break; case REPL_UCONTACT_INSERT: - if (ver != UL_BIN_V2) - ensure_bin_version(pkt, UL_BIN_VERSION); + _ensure_bin_version2(pkt, UL_BIN_V2, UL_BIN_V4, "usrloc ct-ins packet"); rc = receive_ucontact_insert(pkt); break; case REPL_UCONTACT_UPDATE: - if (ver != UL_BIN_V2) - ensure_bin_version(pkt, UL_BIN_VERSION); + _ensure_bin_version2(pkt, UL_BIN_V2, UL_BIN_V4, "usrloc ct-upd packet"); rc = receive_ucontact_update(pkt); break; case REPL_UCONTACT_DELETE: - if (ver != UL_BIN_V2) - ensure_bin_version(pkt, UL_BIN_VERSION); + _ensure_bin_version2(pkt, UL_BIN_V2, UL_BIN_V4, "usrloc ct-del packet"); rc = receive_ucontact_delete(pkt); break; case SYNC_PACKET_TYPE: - if (ver != UL_BIN_V2) - _ensure_bin_version(pkt, UL_BIN_VERSION, "usrloc sync packet"); + _ensure_bin_version2(pkt, UL_BIN_V2, UL_BIN_V4, "usrloc sync packet"); rc = receive_sync_packet(pkt); break; diff --git a/modules/usrloc/ul_cluster.h b/modules/usrloc/ul_cluster.h index 592377a8e85..43e7b482ca6 100644 --- a/modules/usrloc/ul_cluster.h +++ b/modules/usrloc/ul_cluster.h @@ -40,8 +40,8 @@ #define UL_BIN_V2 2 #define UL_BIN_V3 3 // added "cmatch" (default: CT_MATCH_CONTACT_CALLID) - -#define UL_BIN_VERSION UL_BIN_V3 +#define UL_BIN_V4 4 // changed 'ct.cflags' from int bitmask to string repr +#define UL_BIN_VERSION UL_BIN_V4 extern int location_cluster; extern struct clusterer_binds clusterer_api;