From d29b2f236f6c7da79cc3aa1ff3472617ac3f9e41 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Fri, 29 Nov 2019 14:19:41 +0100 Subject: gsup_server: send routing error back to the correct peer If a peer attempts to add a route to an ipa-name that we already have in the routing system, don't send the routing error to the peer that already has the name, but to the peer that attempts to re-use it and would cause the collision. This is fixing a situation where for example a locally attached MSC has name 'MSC-1', and a remote site is proxying GSUP here for a remote MSC that also has the name 'MSC-1'. Send the routing error back to the proxy, not local 'MSC-1'. Change-Id: Icafaedc11b5925149d338bdcb987ae985a7323d6 --- src/gsup_server.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/gsup_server.c b/src/gsup_server.c index 35ad4e4..d028c93 100644 --- a/src/gsup_server.c +++ b/src/gsup_server.c @@ -65,19 +65,30 @@ int osmo_gsup_conn_send(struct osmo_gsup_conn *conn, struct msgb *msg) static void gsup_server_send_req_response(struct osmo_gsup_req *req, struct osmo_gsup_message *response) { struct osmo_gsup_server *server = req->cb_data; + struct osmo_gsup_peer_id *routing; struct osmo_gsup_conn *conn = NULL; struct msgb *msg = osmo_gsup_msgb_alloc("GSUP Tx"); int rc; - switch (req->source_name.type) { + if (response->message_type == OSMO_GSUP_MSGT_ROUTING_ERROR + && !osmo_gsup_peer_id_is_empty(&req->via_proxy)) { + /* If a routing error occured, we need to route back via the immediate sending peer, not via the + * intended final recipient -- because one source of routing errors is a duplicate name for a recipient. + * If we resolve to req->source_name, we may send to a completely unrelated recipient. */ + routing = &req->via_proxy; + } else { + routing = &req->source_name; + } + switch (routing->type) { case OSMO_GSUP_PEER_ID_IPA_NAME: - conn = gsup_route_find_by_ipa_name(server, &req->source_name.ipa_name); + conn = gsup_route_find_by_ipa_name(server, &routing->ipa_name); break; default: LOG_GSUP_REQ(req, LOGL_ERROR, "GSUP peer id kind not supported: %s\n", - osmo_gsup_peer_id_type_name(req->source_name.type)); + osmo_gsup_peer_id_type_name(routing->type)); break; } + if (!conn) { LOG_GSUP_REQ(req, LOGL_ERROR, "GSUP client that sent this request not found, cannot respond\n"); msgb_free(msg); -- cgit v1.2.3