Skip to content

topology_hiding: do not warn per request on a non-local send socket#4120

Open
Lt-Flash wants to merge 1 commit into
OpenSIPS:masterfrom
Lt-Flash:fix/th-nonlocal-send-socket
Open

topology_hiding: do not warn per request on a non-local send socket#4120
Lt-Flash wants to merge 1 commit into
OpenSIPS:masterfrom
Lt-Flash:fix/th-nonlocal-send-socket

Conversation

@Lt-Flash

Copy link
Copy Markdown

What

Two problems in topo_no_dlg_seq_handling(), in the branch that restores the send socket recorded in the encoded topology-hiding state: a log line that fires on every sequential request in any multi-node deployment, and — in the same branch — the unusable socket being assigned anyway, clearing whatever the script had already chosen.

1. A WARN per sequential request

When dialog-less topology hiding decodes the state of a sequential request, it looks up the socket the state was created on:

sock = grep_sock_info(&host, (unsigned short)port, proto);
if (!sock) {
    LM_WARN("non-local socket <%.*s>...ignoring\n", bind_buf.len, bind_buf.s);
}

A node not owning that socket is routine, not exceptional: any anycast or load-balanced tier can land a sequential request on a different node than the one that handled the initial request, and a node whose listening set has simply changed hits it too. The result is one WARN per sequential request, per call — on a busy presence deployment that is the bulk of the log.

Dropped to LM_DBG. The R-URI has already been restored by this point, so the request still routes; only the send socket is affected.

2. The failed lookup was not actually ignored

The message says "ignoring", but the assignment sat outside the check:

if (!sock) {
    LM_WARN(... "ignoring" ...);
}
msg->force_send_socket = sock;      /* <-- runs even when sock == NULL */

So on the failure path it stored NULL — wiping any socket the script had already selected (e.g. an earlier force_send_socket() in the route) rather than leaving it alone. The fix only assigns when a local socket was actually found:

if (!sock) {
    LM_DBG("non-local socket <%.*s> - leaving the send socket to the caller\n", ...);
} else {
    msg->force_send_socket = sock;
}

Impact

Log volume on multi-node topology-hiding deployments, and — for scripts that set a send socket before topology_hiding_match() — a silently discarded choice on any request whose state came from another node.

topo_no_dlg_seq_handling() restores the socket recorded in the encoded
state and, when this node does not own it, logged at WARN. That happens
on every sequential request of every call whose state was created
somewhere else, which is routine in any multi-node deployment - an
anycast or load-balanced tier where a sequential request need not land
on the node that handled the initial one, or simply a node whose socket
set has changed since. On a busy presence deployment it fills the log
with one line per request. Dropped to DBG. The R-URI has already been
restored at that point, so the request still routes; only the send
socket is affected.

The same branch also assigned the NULL result to msg->force_send_socket,
which does not ignore the unusable socket as the message claimed - it
clears whatever socket the script had already chosen, for instance via
force_send_socket() earlier in the route. Only assign when a local
socket was actually found.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant