Skip to content

Commit

Permalink
aaa_diameter: Reply to requests when E_DM_REQUEST not used
Browse files Browse the repository at this point in the history
At the end of the day, we are a Diameter peer, so we should also reply
to requests even if the opensips.cfg script does not require any
server-side support (e.g. perhaps it's only pushing Diameter requests).
  • Loading branch information
liviuchircu committed Feb 29, 2024
1 parent 1083c0e commit dd56be4
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 15 deletions.
14 changes: 14 additions & 0 deletions modules/aaa_diameter/aaa_diameter.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ str dm_realm = str_init("diameter.test");
str dm_peer_identity = str_init("server"); /* a.k.a. server.diameter.test */
static str dm_aaa_url = {NULL, 0};
int dm_answer_timeout = 2000; /* ms */
int dm_server_autoreply_error; /* ensures we always reply with *something* */

static const cmd_export_t cmds[]= {
{"dm_send_request", (cmd_function)dm_send_request, {
Expand Down Expand Up @@ -200,6 +201,19 @@ static int dm_check_config(void)
return -1;
}

LM_INFO("Diameter server support enabled\n");

if (get_script_route_ID_by_name_str(
&str_init(DMEV_REQ_NAME), sroutes->event, EVENT_RT_NO) < 0) {
LM_NOTICE("Diameter server event "DMEV_REQ_NAME" not used in opensips script"
", auto-replying error code 3001 to any Diameter request\n");
dm_server_autoreply_error = 1;
} else if (!is_script_func_used("dm_send_answer", -1)) {
LM_NOTICE("Diameter 'dm_send_answer()' function not used in opensips script"
", auto-replying error code 3001 to any Diameter request\n");
dm_server_autoreply_error = 1;
}

return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions modules/aaa_diameter/dm_evi.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ int dm_init_evi(void)
}

/* First publish the events */
dmev_req_id = evi_publish_event(str_init("E_DM_REQUEST"));
dmev_req_id = evi_publish_event(str_init(DMEV_REQ_NAME));
if (dmev_req_id == EVI_ERROR) {
LM_ERR("cannot register 'request' event\n");
return -1;
Expand Down Expand Up @@ -169,7 +169,7 @@ void dm_raise_event_request(int sender, void *dm_req)
}

if (evi_raise_event(dmev_req_id, dmev_req_params) < 0)
LM_ERR("failed to raise 'E_DM_REQUEST' event\n");
LM_ERR("failed to raise '"DMEV_REQ_NAME"' event\n");

out:
shm_free(job->sessid.s);
Expand Down
1 change: 1 addition & 0 deletions modules/aaa_diameter/dm_evi.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ typedef struct _dm_ipc_event_req {
str avps_json;
} dm_ipc_event_req;

#define DMEV_REQ_NAME "E_DM_REQUEST"
extern str dmev_req_pname_sessid;
extern str dmev_req_pname_appid;
extern str dmev_req_pname_cmdcode;
Expand Down
17 changes: 16 additions & 1 deletion modules/aaa_diameter/dm_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,12 +548,27 @@ static int dm_receive_req(struct msg **_req, struct avp * avp, struct session *
init_str(&avp_arr, cJSON_PrintUnformatted(avps));

/* keep the request for a while in order to be able to generate the answer */
dm_update_unreplied_req(req);
if (!dm_server_autoreply_error)
dm_update_unreplied_req(req);

if (dm_dispatch_event_req(req, &tid, hdr->msg_appl, hdr->msg_code, &avp_arr))
LM_ERR("failed to dispatch DM Request (tid: %.*s, %d/%d)\n", tid.len,
tid.s, hdr->msg_appl, hdr->msg_code);

if (dm_server_autoreply_error) {
struct dm_message dm;

memset(&dm, 0, sizeof dm);

dm.fd_req = req;
dm.app_id = hdr->msg_appl;
dm.cmd_code = hdr->msg_code;

if (dm_send_custom_rpl(&dm, 1) != 0)
LM_ERR("failed to auto-reply with error, tid: %.*s, %d/%d\n", tid.len,
tid.s, hdr->msg_appl, hdr->msg_code);
}

goto out;

error:
Expand Down
1 change: 1 addition & 0 deletions modules/aaa_diameter/dm_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ extern char *dm_conf_filename;
extern char *extra_avps_file;
extern struct _dm_dict dm_dict;
extern int dm_answer_timeout;
extern int dm_server_autoreply_error;
int dm_remove_unreplied_req(struct msg *req);

int freeDiameter_init(void);
Expand Down
31 changes: 19 additions & 12 deletions modules/aaa_diameter/dm_peer.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ static inline int dm_add_session(struct msg *msg, struct dict_object *model)
}


static int dm_auth(struct dm_message *msg)
static int dm_send_auth(struct dm_message *msg)
{
struct msg *dmsg;
struct dm_avp *dm_avp;
Expand Down Expand Up @@ -246,7 +246,7 @@ static int dm_auth(struct dm_message *msg)
}


static int dm_acct(struct dm_message *msg)
static int dm_send_acct(struct dm_message *msg)
{
struct msg *dmsg;
struct avp *avp;
Expand Down Expand Up @@ -450,7 +450,7 @@ static int dm_pack_avps(void *root, struct list_head *subavps)
}


static int dm_custom_req(struct dm_message *msg)
static int dm_send_custom_req(struct dm_message *msg)
{
str tid_str;
struct msg *dmsg;
Expand Down Expand Up @@ -509,23 +509,30 @@ static int dm_custom_req(struct dm_message *msg)
}


static int dm_custom_rpl(struct dm_message *dm)
int dm_send_custom_rpl(struct dm_message *dm, int is_error)
{
struct msg *ans = (struct msg *)dm->fd_req;
int rc;
int rc, flags = 0;

if (dm_remove_unreplied_req(ans) != 0) {
if (!dm_server_autoreply_error && dm_remove_unreplied_req(ans) != 0) {
LM_ERR("unable to build answer, request is no longer available "
"(timeout: %d s)\n", dm_unreplied_req_timeout);
return -1;
}

rc = fd_msg_new_answer_from_req(fd_g_config->cnf_dict, &ans, 0);
if (is_error)
flags |= MSGFL_ANSW_ERROR;

rc = fd_msg_new_answer_from_req(fd_g_config->cnf_dict, &ans, flags);
if (rc != 0) {
LM_ERR("failed to create answer message, error: %d\n", rc);
goto error;
}

if (is_error)
FD_CHECK(fd_msg_rescode_set(ans, "DIAMETER_COMMAND_UNSUPPORTED",
"Command Not Implemented", NULL, 1));

/* App id */
{
struct msg_hdr *h;
Expand All @@ -534,7 +541,7 @@ static int dm_custom_rpl(struct dm_message *dm)
}

/* include all AVPs passed from script level */
if (dm_pack_avps(ans, &dm->avps) != 0) {
if (!dm_server_autoreply_error && dm_pack_avps(ans, &dm->avps) != 0) {
LM_ERR("failed to pack AVPs\n");
return -1;
}
Expand All @@ -555,13 +562,13 @@ static inline int dm_peer_send_msg(struct dm_message *msg)

switch (am->type) {
case AAA_AUTH:
return dm_auth(msg);
return dm_send_auth(msg);
case AAA_ACCT:
return dm_acct(msg);
return dm_send_acct(msg);
case AAA_CUSTOM_REQ:
return dm_custom_req(msg);
return dm_send_custom_req(msg);
case AAA_CUSTOM_RPL:
return dm_custom_rpl(msg);
return dm_send_custom_rpl(msg, 0);
default:
LM_ERR("unsupported AAA message type (%d), skipping\n", am->type);
}
Expand Down
1 change: 1 addition & 0 deletions modules/aaa_diameter/dm_peer.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ extern pthread_mutex_t *msg_send_lk;

int dm_init_peer(void);
void dm_peer_loop(int _);
int dm_send_custom_rpl(struct dm_message *dm, int is_error);

#endif

0 comments on commit dd56be4

Please sign in to comment.