From a5acaa68db4cc26e342069ad2ef37c1b09e1efc2 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Tue, 28 Nov 2023 18:28:44 +0100 Subject: [PATCH] mgcp-client: Transmit remote IP addr in CRCX if known and port=0 A client may know the IP address during CRCX but not yet the port, or it may simply want to hint an initial IP address so that the MGW can better guess when allocating a local IP address. Related: SYS#6657 Change-Id: I30165dbac5e484011d0acf46af36f105954a501d --- src/libosmo-mgcp-client/mgcp_client.c | 53 ++++++++++++----------- src/libosmo-mgcp-client/mgcp_client_fsm.c | 20 ++++++--- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/libosmo-mgcp-client/mgcp_client.c b/src/libosmo-mgcp-client/mgcp_client.c index ceb959237..8693b1b1c 100644 --- a/src/libosmo-mgcp-client/mgcp_client.c +++ b/src/libosmo-mgcp-client/mgcp_client.c @@ -1302,9 +1302,6 @@ static int add_sdp(struct msgb *msg, struct mgcp_msg *mgcp_msg, struct mgcp_clie local_ip_family = osmo_ip_str_type(local_ip); if (local_ip_family == AF_UNSPEC) return -EINVAL; - audio_ip_family = osmo_ip_str_type(mgcp_msg->audio_ip); - if (audio_ip_family == AF_UNSPEC) - return -EINVAL; /* Add owner/creator (SDP) */ MSGB_PRINTF_OR_RET("o=- %x 23 IN IP%c %s\r\n", mgcp_msg->call_id, @@ -1314,33 +1311,39 @@ static int add_sdp(struct msgb *msg, struct mgcp_msg *mgcp_msg, struct mgcp_clie /* Add session name (none) */ MSGB_PRINTF_OR_RET("s=-\r\n"); - /* Add RTP address and port */ - if (mgcp_msg->audio_port == 0) { - LOGPMGW(mgcp, LOGL_ERROR, - "Invalid port number, can not generate MGCP message\n"); - msgb_free(msg); - return -EINVAL; + /* Add RTP address */ + if (mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_IP) { + audio_ip_family = osmo_ip_str_type(mgcp_msg->audio_ip); + if (audio_ip_family == AF_UNSPEC) + return -EINVAL; + if (strlen(mgcp_msg->audio_ip) <= 0) { + LOGPMGW(mgcp, LOGL_ERROR, + "Empty ip address, can not generate MGCP message\n"); + return -EINVAL; + } + MSGB_PRINTF_OR_RET("c=IN IP%c %s\r\n", + audio_ip_family == AF_INET6 ? '6' : '4', + mgcp_msg->audio_ip); } - if (strlen(mgcp_msg->audio_ip) <= 0) { - LOGPMGW(mgcp, LOGL_ERROR, - "Empty ip address, can not generate MGCP message\n"); - msgb_free(msg); - return -EINVAL; - } - MSGB_PRINTF_OR_RET("c=IN IP%c %s\r\n", - audio_ip_family == AF_INET6 ? '6' : '4', - mgcp_msg->audio_ip); /* Add time description, active time (SDP) */ MSGB_PRINTF_OR_RET("t=0 0\r\n"); - MSGB_PRINTF_OR_RET("m=audio %u RTP/AVP", mgcp_msg->audio_port); - for (i = 0; i < mgcp_msg->codecs_len; i++) { - pt = map_codec_to_pt(mgcp_msg->ptmap, mgcp_msg->ptmap_len, mgcp_msg->codecs[i]); - MSGB_PRINTF_OR_RET(" %u", pt); + /* Add RTP address port and codecs */ + if (mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_PORT) { + if (mgcp_msg->audio_port == 0) { + LOGPMGW(mgcp, LOGL_ERROR, + "Invalid port number, can not generate MGCP message\n"); + return -EINVAL; + } + MSGB_PRINTF_OR_RET("m=audio %u RTP/AVP", mgcp_msg->audio_port); + for (i = 0; i < mgcp_msg->codecs_len; i++) { + pt = map_codec_to_pt(mgcp_msg->ptmap, mgcp_msg->ptmap_len, mgcp_msg->codecs[i]); + MSGB_PRINTF_OR_RET(" %u", pt); + } + MSGB_PRINTF_OR_RET("\r\n"); } - MSGB_PRINTF_OR_RET("\r\n"); /* Add optional codec parameters (fmtp) */ if (mgcp_msg->param_present) { @@ -1470,10 +1473,10 @@ struct msgb *mgcp_msg_gen(struct mgcp_client *mgcp, struct mgcp_msg *mgcp_msg) MSGB_PRINTF_OR_RET("I: %s\r\n", mgcp_msg->conn_id); } - /* Using SDP makes sense when a valid IP/Port combination is specified, + /* Using SDP makes sense when a valid IP or Port is specified, * if we do not know this information yet, we fall back to LCO */ if (mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_IP - && mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_PORT) + || mgcp_msg->presence & MGCP_MSG_PRESENCE_AUDIO_PORT) use_sdp = true; /* Add local connection options (LCO) */ diff --git a/src/libosmo-mgcp-client/mgcp_client_fsm.c b/src/libosmo-mgcp-client/mgcp_client_fsm.c index 432ad848c..218527cfb 100644 --- a/src/libosmo-mgcp-client/mgcp_client_fsm.c +++ b/src/libosmo-mgcp-client/mgcp_client_fsm.c @@ -136,10 +136,19 @@ static void make_crcx_msg(struct mgcp_msg *mgcp_msg, struct mgcp_conn_peer *info static void add_audio(struct mgcp_msg *mgcp_msg, struct mgcp_conn_peer *info) { - mgcp_msg->presence |= MGCP_MSG_PRESENCE_AUDIO_IP | MGCP_MSG_PRESENCE_AUDIO_PORT; - mgcp_msg->audio_ip = info->addr; - mgcp_msg->audio_port = info->port; - mgcp_msg->conn_mode = MGCP_CONN_RECV_SEND; + bool ip_is_set = info->addr[0] != '\0' && + strncmp(info->addr, "::", sizeof(info->addr)) != 0 && + strncmp(info->addr, "0.0.0.0", sizeof(info->addr)) != 0; + if (ip_is_set) { + mgcp_msg->presence |= MGCP_MSG_PRESENCE_AUDIO_IP; + mgcp_msg->audio_ip = info->addr; + } + if (info->port) { + mgcp_msg->presence |= MGCP_MSG_PRESENCE_AUDIO_PORT; + mgcp_msg->audio_port = info->port; + } + if (ip_is_set && info->port) + mgcp_msg->conn_mode = MGCP_CONN_RECV_SEND; } static void set_conn_mode(struct mgcp_msg *mgcp_msg, struct mgcp_conn_peer *peer) @@ -221,8 +230,7 @@ static void fsm_crcx_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data) mgcp_ctx->conn_peer_local.endpoint); make_crcx_msg(&mgcp_msg, &mgcp_ctx->conn_peer_local); - if (mgcp_ctx->conn_peer_local.port) - add_audio(&mgcp_msg, &mgcp_ctx->conn_peer_local); + add_audio(&mgcp_msg, &mgcp_ctx->conn_peer_local); set_conn_mode(&mgcp_msg, &mgcp_ctx->conn_peer_local); msg = mgcp_msg_gen(mgcp_ctx->mgcp, &mgcp_msg);