]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip_session.c: Correctly format SDP connection addresses.
authorSean Bright <sean@seanbright.com>
Sat, 27 Jan 2024 14:46:27 +0000 (09:46 -0500)
committerAsterisk Development Team <asteriskteam@digium.com>
Thu, 7 Mar 2024 14:18:40 +0000 (14:18 +0000)
Resolves a regression identified by @justinludwig involving the
rendering of IPv6 addresses in outgoing SDP.

Also updates `media_address` on PJSIP endpoints so that if we are able
to parse the configured value as an IP we store it in a format that we
can directly use later. Based on my reading of the code it appeared
that one could configure `media_address` as:

```
[foo]
type = endpoint
...
media_address = [2001:db8::]
```

And that value would be blindly copied into the outgoing SDP without
regard to its format.

Fixes #541

(cherry picked from commit 9f20b4659fc897b8495c7a4c51dfe4365ab937bd)

res/res_pjsip/pjsip_configuration.c
res/res_pjsip_session.c
res/res_pjsip_t38.c

index 613d06fa5205510590e4eb0cc355d6640bf8c4a5..698ff20f2868f19aa3d071bf6e6db02430b3ae23 100644 (file)
@@ -538,6 +538,29 @@ static int ident_to_str(const void *obj, const intptr_t *args, char **buf)
        return 0;
 }
 
+static int media_address_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+       struct ast_sip_endpoint *endpoint = obj;
+       struct ast_sockaddr addr;
+
+       if (ast_sockaddr_parse(&addr, var->value, 0)) {
+               /* If we're able to parse as an IP, ensure it's formatted correctly for later */
+               ast_string_field_set(endpoint, media.address, ast_sockaddr_stringify_addr_remote(&addr));
+       } else {
+               /* If we weren't able to parse it as an IP, just assume it's a hostname */
+               ast_string_field_set(endpoint, media.address, var->value);
+       }
+
+       return 0;
+}
+
+static int media_address_to_str(const void *obj, const intptr_t *args, char **buf)
+{
+       const struct ast_sip_endpoint *endpoint = obj;
+       *buf = ast_strdup(endpoint->media.address);
+       return 0;
+}
+
 static int redirect_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
 {
        struct ast_sip_endpoint *endpoint = obj;
@@ -2163,7 +2186,7 @@ int ast_res_pjsip_initialize_configuration(void)
        ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "auth", "", inbound_auth_handler, inbound_auths_to_str, NULL, 0, 0);
        ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "outbound_auth", "", outbound_auth_handler, outbound_auths_to_str, NULL, 0, 0);
        ast_sorcery_object_field_register(sip_sorcery, "endpoint", "aors", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, aors));
-       ast_sorcery_object_field_register(sip_sorcery, "endpoint", "media_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.address));
+       ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "media_address", "", media_address_handler, media_address_to_str, NULL, 0, 0);
        ast_sorcery_object_field_register(sip_sorcery, "endpoint", "bind_rtp_to_media_address", "no", OPT_BOOL_T, 1, STRFLDSET(struct ast_sip_endpoint, media.bind_rtp_to_media_address));
        ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "identify_by", "username,ip", ident_handler, ident_to_str, NULL, 0, 0);
        ast_sorcery_object_field_register(sip_sorcery, "endpoint", "direct_media", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.direct_media.enabled));
index b1d2dbdf17724fa0c0c580fba2cc4eb9bf06642f..0ff35736c13cf8c9045cc4cd99b232935914151d 100644 (file)
@@ -5631,8 +5631,8 @@ static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_trans
                 * rewriting. No localnet configured? Always rewrite. */
                if (ast_sip_transport_is_local(transport_state, &our_sdp_addr) || !transport_state->localnet) {
                        ast_debug(5, "%s: Setting external media address to %s\n", ast_sip_session_get_name(session),
-                               ast_sockaddr_stringify_host(&transport_state->external_media_address));
-                       pj_strdup2(tdata->pool, &sdp->conn->addr, ast_sockaddr_stringify_host(&transport_state->external_media_address));
+                               ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
+                       pj_strdup2(tdata->pool, &sdp->conn->addr, ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
                        pj_strassign(&sdp->origin.addr, &sdp->conn->addr);
                }
        }
index 7df35d9b2ae0aa409ae2a934c25f4211d7b158b4..681fabbf73df69affb429e30efe3b6c028569b58 100644 (file)
@@ -1097,8 +1097,8 @@ static void change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struc
        if (ast_sip_transport_is_nonlocal(transport_state, &our_sdp_addr) && transport_state->localnet) {
                return;
        }
-       ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_host(&transport_state->external_media_address));
-       pj_strdup2(tdata->pool, &stream->conn->addr, ast_sockaddr_stringify_host(&transport_state->external_media_address));
+       ast_debug(5, "Setting media address to %s\n", ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
+       pj_strdup2(tdata->pool, &stream->conn->addr, ast_sockaddr_stringify_addr_remote(&transport_state->external_media_address));
 }
 
 /*! \brief Function which destroys the UDPTL instance when session ends */