Skip to content

Commit

Permalink
usrloc: Make the contact branch flags replication more robust
Browse files Browse the repository at this point in the history
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!
  • Loading branch information
liviuchircu committed Nov 8, 2024
1 parent eea7b4e commit ee8b3a2
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 37 deletions.
30 changes: 20 additions & 10 deletions bin_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
52 changes: 27 additions & 25 deletions modules/usrloc/ul_cluster.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions modules/usrloc/ul_cluster.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit ee8b3a2

Please sign in to comment.