Skip to content

Commit

Permalink
b2b_sdp_demux: fix matching entities for SERVER
Browse files Browse the repository at this point in the history
Thanks go to Suchi Sahoo from Five9 for reporting it
  • Loading branch information
razvancrainea committed Oct 31, 2022
1 parent 7186dbb commit e485856
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 35 deletions.
28 changes: 28 additions & 0 deletions modules/b2b_entities/b2be_load.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#define _B2BE_LOAD_H_

#include "../../bin_interface.h"
#include "../../parser/parse_from.h"

#define B2BCB_TRIGGER_EVENT (1<<0)
#define B2BCB_RECV_EVENT (1<<1)
Expand Down Expand Up @@ -230,4 +231,31 @@ static inline b2b_dlginfo_t *b2b_dup_dlginfo(b2b_dlginfo_t *info)
return b2b_new_dlginfo(&info->callid, &info->fromtag, &info->totag);
}

static inline b2b_dlginfo_t *b2b_fill_dlginfo(struct sip_msg *msg, str *b2b_key)
{
static b2b_dlginfo_t dlginfo;
str callid, fromtag;

if (msg->callid==NULL || msg->callid->body.s==NULL)
{
LM_ERR("failed to parse callid header\n");
return NULL;
}
callid = msg->callid->body;

if (msg->from->parsed == NULL)
{
if (parse_from_header(msg) < 0) {
LM_ERR("cannot parse From header\n");
return NULL;
}
}
fromtag = ((struct to_body*)msg->from->parsed)->tag_value;

dlginfo.totag = *b2b_key;
dlginfo.callid = callid;
dlginfo.fromtag= fromtag;
return &dlginfo;
}

#endif
30 changes: 4 additions & 26 deletions modules/b2b_logic/logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,36 +192,14 @@ int b2b_add_dlginfo(str* key, str* entity_key, int src, b2b_dlginfo_t* dlginfo,

int msg_add_dlginfo(b2bl_entity_id_t* entity, struct sip_msg* msg, str* totag)
{
str callid, fromtag;
b2b_dlginfo_t dlginfo;

if( msg->callid==NULL || msg->callid->body.s==NULL)
b2b_dlginfo_t *dlginfo = b2b_fill_dlginfo(msg, totag);
if (!dlginfo)
{
LM_ERR("failed to parse callid header\n");
LM_ERR("cannot fill dlginfo!\n");
return -1;
}
callid = msg->callid->body;

if (msg->from->parsed == NULL)
{
if ( parse_from_header( msg )<0 )
{
LM_ERR("cannot parse From header\n");
return -1;
}
}
fromtag = ((struct to_body*)msg->from->parsed)->tag_value;

if (totag)
dlginfo.totag = *totag;
else {
dlginfo.totag.s = 0;
dlginfo.totag.len = 0;
}
dlginfo.callid = callid;
dlginfo.fromtag= fromtag;

if(entity_add_dlginfo(entity, &dlginfo) < 0)
if(entity_add_dlginfo(entity, dlginfo) < 0)
{
LM_ERR("Failed to add dialoginfo\n");
return -1;
Expand Down
38 changes: 29 additions & 9 deletions modules/b2b_sdp_demux/b2b_sdp_demux.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ struct b2b_sdp_stream {
struct list_head list;
struct list_head ordered;
};
static int b2b_sdp_ack(int type, str *key);
static int b2b_sdp_ack(int type, str *key, b2b_dlginfo_t *dlginfo);
static int b2b_sdp_reply(str *b2b_key, b2b_dlginfo_t *dlginfo,
int type, int method, int code, str *body);
static int b2b_sdp_client_sync(struct b2b_sdp_client *client, str *body);
Expand Down Expand Up @@ -229,6 +229,7 @@ struct b2b_sdp_ctx {
time_t sess_id;
str sess_ip;
gen_lock_t lock;
b2b_dlginfo_t *dlginfo;
struct list_head clients;
struct list_head streams;
struct list_head contexts;
Expand Down Expand Up @@ -547,6 +548,8 @@ static void b2b_sdp_ctx_free(void *param)
return;
if (ctx->b2b_key.s)
shm_free(ctx->b2b_key.s);
if (ctx->dlginfo)
shm_free(ctx->dlginfo);
shm_free(ctx->sess_ip.s);
shm_free(ctx);
}
Expand Down Expand Up @@ -887,6 +890,7 @@ static int b2b_sdp_client_reinvite(struct sip_msg *msg, struct b2b_sdp_client *c
req_data.b2b_key = &client->ctx->b2b_key;
req_data.method = &method;
req_data.body = body;
req_data.dlginfo = client->ctx->dlginfo;
LM_INFO("[%.*s][%.*s] server request INVITE sent\n",
client->ctx->callid.len, client->ctx->callid.s,
client->ctx->b2b_key.len, client->ctx->b2b_key.s);
Expand Down Expand Up @@ -946,6 +950,7 @@ static void b2b_sdp_server_send_bye(struct b2b_sdp_ctx *ctx)
req_data.et = B2B_SERVER;
req_data.b2b_key = &ctx->b2b_key;
req_data.method = &method;
req_data.dlginfo = ctx->dlginfo;
if (b2b_api.send_request(&req_data) < 0)
LM_ERR("[%.*s] cannot send upstream BYE\n", ctx->callid.len, ctx->callid.s);
else
Expand Down Expand Up @@ -1001,6 +1006,7 @@ static int b2b_sdp_client_bye(struct sip_msg *msg, struct b2b_sdp_client *client
req_data.b2b_key = &ctx->b2b_key;
req_data.method = &method;
req_data.body = body;
req_data.dlginfo = ctx->dlginfo;
if (b2b_api.send_request(&req_data) < 0)
LM_ERR("[%.*s] cannot send upstream INVITE\n",
ctx->callid.len, ctx->callid.s);
Expand Down Expand Up @@ -1162,7 +1168,7 @@ static int b2b_sdp_client_sync(struct b2b_sdp_client *client, str *body)
return ret;
}

static int b2b_sdp_ack(int type, str *key)
static int b2b_sdp_ack(int type, str *key, b2b_dlginfo_t *dlginfo)
{
char *etype = (type==B2B_CLIENT?"client":"server");
str ack = str_init(ACK);
Expand All @@ -1171,6 +1177,7 @@ static int b2b_sdp_ack(int type, str *key)
req.et = type;
req.b2b_key = key;
req.method = &ack;
req.dlginfo = dlginfo;
req.no_cb = 1; /* do not call callback */

LM_INFO("[%.*s] %s request ACK sent\n", key->len, key->s, etype);
Expand All @@ -1187,7 +1194,7 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien
/* only ACK if not fake reply, or not a dummy message as
* built in the dlg.c tm callback */
if (msg != FAKED_REPLY && msg->REPLY_STATUS < 300) {
if (b2b_sdp_ack(B2B_CLIENT, &client->b2b_key) < 0)
if (b2b_sdp_ack(B2B_CLIENT, &client->b2b_key, client->dlginfo) < 0)
LM_ERR("[%.*s] Cannot ack session for key %.*s\n",
client->ctx->callid.len, client->ctx->callid.s,
client->b2b_key.len, client->b2b_key.s);
Expand Down Expand Up @@ -1240,11 +1247,11 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien
/* avoid sending reply under lock */
if (body) {
/* we are done - answer the call */
if (b2b_sdp_reply(&ctx->b2b_key, NULL, B2B_SERVER, METHOD_INVITE, 200, body) < 0)
if (b2b_sdp_reply(&ctx->b2b_key, ctx->dlginfo, B2B_SERVER, METHOD_INVITE, 200, body) < 0)
LM_CRIT("could not answer B2B call!\n");
pkg_free(body->s);
} else if (ret == -2) {
b2b_sdp_reply(&ctx->b2b_key, NULL, B2B_SERVER, METHOD_INVITE, 503, NULL);
b2b_sdp_reply(&ctx->b2b_key, ctx->dlginfo, B2B_SERVER, METHOD_INVITE, 503, NULL);
}
if (ret < 0 && ctx->clients_no == 0) {
/* no more remaining clients - terminate the entity as well */
Expand All @@ -1266,6 +1273,15 @@ int b2b_sdp_client_dlginfo(str *logic_key, str *key, int src, b2b_dlginfo_t *inf
return 0;
}

static b2b_dlginfo_t *b2b_sdp_server_dlginfo(struct sip_msg *msg, str * b2b_key)
{
b2b_dlginfo_t *info = b2b_fill_dlginfo(msg, b2b_key);
if (!info)
return NULL;

return b2b_dup_dlginfo(info);
}

static int b2b_sdp_client_notify(struct sip_msg *msg, str *key, int type,
str *logic_key, void *param, int flags)
{
Expand Down Expand Up @@ -1394,7 +1410,7 @@ static int b2b_sdp_server_reply_invite(struct sip_msg *msg, struct b2b_sdp_ctx *
/* re-INVITE failed - reply the same code to the client
* that started the challenging */
if (msg != FAKED_REPLY && msg->REPLY_STATUS < 300)
if (b2b_sdp_ack(B2B_SERVER, &ctx->b2b_key) < 0)
if (b2b_sdp_ack(B2B_SERVER, &ctx->b2b_key, ctx->dlginfo) < 0)
LM_ERR("Cannot ack recording session for server key %.*s\n",
ctx->b2b_key.len, ctx->b2b_key.s);

Expand Down Expand Up @@ -1454,7 +1470,8 @@ static int b2b_sdp_server_reply_bye(struct sip_msg *msg, struct b2b_sdp_ctx *ctx

static int b2b_sdp_server_bye(struct sip_msg *msg, struct b2b_sdp_ctx *ctx)
{
b2b_sdp_reply(&ctx->b2b_key, NULL, B2B_SERVER, msg->REQ_METHOD, 200, NULL);
b2b_sdp_reply(&ctx->b2b_key, ctx->dlginfo, B2B_SERVER,
msg->REQ_METHOD, 200, NULL);
b2b_sdp_ctx_release(ctx, 1);
return 0;
}
Expand Down Expand Up @@ -1506,7 +1523,8 @@ static int b2b_sdp_server_invite(struct sip_msg *msg, struct b2b_sdp_ctx *ctx)

return 0;
error:
b2b_sdp_reply(&ctx->b2b_key, NULL, B2B_SERVER, METHOD_INVITE, 606, NULL);
b2b_sdp_reply(&ctx->b2b_key, ctx->dlginfo, B2B_SERVER,
METHOD_INVITE, 606, NULL);
return -1;
}

Expand All @@ -1526,7 +1544,8 @@ static int b2b_sdp_server_notify(struct sip_msg *msg, str *key, int type,
if (ctx->pending_no) {
lock_release(&ctx->lock);
LM_INFO("we still have pending clients!\n");
b2b_sdp_reply(&ctx->b2b_key, NULL, B2B_SERVER, msg->REQ_METHOD, 491, NULL);
b2b_sdp_reply(&ctx->b2b_key, ctx->dlginfo, B2B_SERVER,
msg->REQ_METHOD, 491, NULL);
return -1;
}
lock_release(&ctx->lock);
Expand Down Expand Up @@ -1608,6 +1627,7 @@ static int b2b_sdp_demux_start(struct sip_msg *msg, str *uri,
b2b_api.entity_delete(B2B_SERVER, b2b_key, NULL, 1, 1);
return -1;
}
ctx->dlginfo = b2b_sdp_server_dlginfo(msg, b2b_key);
/* we need to wait for all pending clients */
ctx->pending_no = ctx->clients_no;

Expand Down

0 comments on commit e485856

Please sign in to comment.