Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIP plugin: custom (non-standard) headers on incoming events (requests) #1873

Merged
merged 8 commits into from
Nov 27, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 99 additions & 8 deletions plugins/janus_sip.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
"outbound_proxy" : "<outbound proxy to use, if any; optional>",
"headers" : "<array of key/value objects, to specify custom headers to add to the SIP REGISTER; optional>",
"contact_params" : "<array of key/value objects, to specify custom Contact URI params to add to the SIP REGISTER; optional>",
"incoming_header_prefixes" : "<array of strings, to specify custom (non-standard) headers to read on incoming SIP events; optional>",
"refresh" : <true|false; if true, only uses the SIP REGISTER as an update and not a new registration; optional>",
"master_id" : <ID of an already registered account, if this is an helper for multiple calls (more on that later); optional>
}
Expand Down Expand Up @@ -206,6 +207,7 @@
"call_id" : "<value of SIP Call-ID header for related call>",
"result" : {
"event" : "ringing",
"headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
}
}
\endverbatim
Expand All @@ -221,7 +223,8 @@
"call_id" : "<value of SIP Call-ID header for related call>",
"result" : {
"event" : "accepted",
"username" : "<SIP URI of the callee>"
"username" : "<SIP URI of the callee>",
"headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
}
}
\endverbatim
Expand All @@ -242,7 +245,8 @@
"call_id" : "<value of SIP Call-ID header for related call>",
"result" : {
"event" : "progress",
"username" : "<SIP URI of the callee>"
"username" : "<SIP URI of the callee>",
"headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
}
}
\endverbatim
Expand Down Expand Up @@ -283,7 +287,8 @@
"displayname" : "<display name of the caller, if available; optional>",
"referred_by" : "<SIP URI of the transferor, if this is a transfer; optional>",
"replaces" : "<call-ID of the call that this is supposed to replace, if this is an attended transfer; optional>",
"srtp" : "<whether the caller mandates (sdes_mandatory) or offers (sdes_optional) SRTP support; optional>"
"srtp" : "<whether the caller mandates (sdes_mandatory) or offers (sdes_optional) SRTP support; optional>",
"headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
}
}
\endverbatim
Expand Down Expand Up @@ -388,7 +393,8 @@
"event" : "message",
"sender" : "<SIP URI of the message sender>",
"displayname" : "<display name of the sender, if available; optional>",
"content" : "<content of the message>"
"content" : "<content of the message>",
"headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
}
}
\endverbatim
Expand All @@ -415,7 +421,8 @@
"sender" : "<SIP URI of the message sender>",
"displayname" : "<display name of the sender, if available; optional>",
"type" : "<content type of the message>",
"content" : "<content of the message>"
"content" : "<content of the message>",
"headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
}
}
\endverbatim
Expand Down Expand Up @@ -445,7 +452,8 @@
"notify" : "<name of the event that the user is subscribed to, e.g., 'message-summary'>",
"substate" : "<substate of the subscription, e.g., 'active'>",
"content-type" : "<content-type of the message>"
"content" : "<content of the message>"
"content" : "<content of the message>",
"headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
}
}
\endverbatim
Expand Down Expand Up @@ -561,7 +569,8 @@
"refer_id" : <unique ID, internal to Janus, of this referral>,
"refer_to" : "<SIP URI to call>",
"referred_by" : "<SIP URI of the transferor; optional>",
"replaces" : "<call-ID of the call this transfer is supposed to replace; optional, and only present for attended transfers>"
"replaces" : "<call-ID of the call this transfer is supposed to replace; optional, and only present for attended transfers>",
"headers" : "<object with key/value strings; custom headers extracted from SIP event based on incoming_header_prefix defined in register request; optional>"
}
}
\endverbatim
Expand Down Expand Up @@ -697,7 +706,8 @@ static struct janus_json_parameter register_parameters[] = {
{"headers", JSON_OBJECT, 0},
{"contact_params", JSON_OBJECT, 0},
{"master_id", JANUS_JSON_INTEGER, 0},
{"refresh", JANUS_JSON_BOOL, 0}
{"refresh", JANUS_JSON_BOOL, 0},
{"incoming_header_prefixes", JSON_ARRAY, 0}
};
static struct janus_json_parameter subscribe_parameters[] = {
{"to", JSON_STRING, 0},
Expand Down Expand Up @@ -963,6 +973,7 @@ typedef struct janus_sip_session {
janus_refcount ref;
janus_mutex mutex;
char *hangup_reason_header;
GList *incoming_header_prefixes;
} janus_sip_session;
static GHashTable *sessions;
static GHashTable *identities;
Expand Down Expand Up @@ -1072,6 +1083,10 @@ static void janus_sip_session_free(const janus_refcount *session_ref) {
g_free(session->hangup_reason_header);
session->hangup_reason_header = NULL;
}
if(session->incoming_header_prefixes) {
g_list_free_full(session->incoming_header_prefixes, g_free);
session->incoming_header_prefixes = NULL;
}
janus_sip_srtp_cleanup(session);
g_free(session);
}
Expand Down Expand Up @@ -1385,6 +1400,29 @@ static void janus_sip_remove_quotes(char *str) {
}
}

static json_t *janus_sip_get_incoming_headers(const sip_t *sip, const janus_sip_session *session) {
json_t *headers = json_object();
if(!sip)
return headers;
sip_unknown_t *unknown_header = sip->sip_unknown;
while(unknown_header != NULL) {
GList *temp = session->incoming_header_prefixes;
while(temp != NULL) {
char *header_prefix = (char *) temp->data;
if(header_prefix != NULL && unknown_header->un_name != NULL) {
if(strncasecmp(unknown_header->un_name, header_prefix, strlen(header_prefix)) == 0) {
const char *header_name = g_strdup(unknown_header->un_name);
json_object_set(headers, header_name, json_string(unknown_header->un_value));
break;
}
}
temp = temp->next;
}
unknown_header = unknown_header->un_next;
}
return headers;
}

/* Error codes */
#define JANUS_SIP_ERROR_UNKNOWN_ERROR 499
#define JANUS_SIP_ERROR_NO_MESSAGE 440
Expand Down Expand Up @@ -2706,6 +2744,19 @@ static void *janus_sip_handler(void *data) {
g_hash_table_insert(masters, GUINT_TO_POINTER(session->master_id), session);
janus_mutex_unlock(&sessions_mutex);
}

json_t *header_prefixes_json = json_object_get(root, "incoming_header_prefixes");
if(header_prefixes_json) {
size_t index = 0;
json_t *value = NULL;

json_array_foreach(header_prefixes_json, index, value) {
const char *header_prefix = json_string_value(value);
if(header_prefix)
session->incoming_header_prefixes = g_list_append(session->incoming_header_prefixes, g_strdup(header_prefix));
}
}

/* If this is a refresh, get rid of the old values */
if(refresh) {
/* Cleanup old values */
Expand Down Expand Up @@ -4465,6 +4516,10 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase,
if(sip->sip_from && sip->sip_from->a_display) {
json_object_set_new(calling, "displayname", json_string(sip->sip_from->a_display));
}
if(session->incoming_header_prefixes) {
json_t *headers = janus_sip_get_incoming_headers(sip, session);
json_object_set_new(calling, "headers", headers);
}
char *referred_by = NULL;
if(sip->sip_referred_by && sip->sip_referred_by->b_url) {
char *rby_text = url_as_string(session->stack->s_home, sip->sip_referred_by->b_url);
Expand Down Expand Up @@ -4583,6 +4638,10 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase,
json_object_set_new(result, "replaces", json_string(replaces));
g_free(replaces);
}
if(session->incoming_header_prefixes) {
json_t *headers = janus_sip_get_incoming_headers(sip, session);
json_object_set_new(result, "headers", headers);
}
su_free(session->stack->s_home, refer_to);
if(custom_headers != NULL)
su_free(session->stack->s_home, custom_headers);
Expand Down Expand Up @@ -4615,6 +4674,10 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase,
}
json_object_set_new(result, "type", json_string(type));
json_object_set_new(result, "content", json_string(payload));
if(session->incoming_header_prefixes) {
json_t *headers = janus_sip_get_incoming_headers(sip, session);
json_object_set_new(result, "headers", headers);
}
json_object_set_new(info, "result", result);
int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, info, NULL);
JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
Expand Down Expand Up @@ -4645,6 +4708,10 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase,
json_object_set_new(result, "displayname", json_string(sip->sip_from->a_display));
}
json_object_set_new(result, "content", json_string(payload));
if(session->incoming_header_prefixes) {
json_t *headers = janus_sip_get_incoming_headers(sip, session);
json_object_set_new(result, "headers", headers);
}
json_object_set_new(message, "result", result);
int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, message, NULL);
JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
Expand Down Expand Up @@ -4681,6 +4748,10 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase,
if(sip->sip_content_type != NULL)
json_object_set_new(result, "content-type", json_string(sip->sip_content_type->c_type));
json_object_set_new(result, "content", json_string(sip->sip_payload->pl_data));
if(session->incoming_header_prefixes) {
json_t *headers = janus_sip_get_incoming_headers(sip, session);
json_object_set_new(result, "headers", headers);
}
json_object_set_new(notify, "result", result);
int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, notify, NULL);
JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
Expand Down Expand Up @@ -4768,6 +4839,10 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase,
json_object_set_new(ringing, "sip", json_string("event"));
json_t *result = json_object();
json_object_set_new(result, "event", json_string("ringing"));
if(session->incoming_header_prefixes) {
json_t *headers = janus_sip_get_incoming_headers(sip, session);
json_object_set_new(result, "headers", headers);
}
json_object_set_new(ringing, "result", result);
json_object_set_new(ringing, "call_id", json_string(session->callid));
int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, ringing, NULL);
Expand Down Expand Up @@ -4975,6 +5050,10 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase,
json_object_set_new(calling, "username", json_string(session->callee));
if(is_focus)
json_object_set_new(calling, "isfocus", json_true());
if(session->incoming_header_prefixes) {
json_t *headers = janus_sip_get_incoming_headers(sip, session);
json_object_set_new(calling, "headers", headers);
}
json_object_set_new(call, "result", calling);
json_object_set_new(call, "call_id", json_string(session->callid));
int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, call, jsep);
Expand Down Expand Up @@ -5137,6 +5216,10 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase,
json_object_set_new(result, "event", json_string("registration_failed"));
json_object_set_new(result, "code", json_integer(status));
json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
if(session->incoming_header_prefixes) {
json_t *headers = janus_sip_get_incoming_headers(sip, session);
json_object_set_new(result, "headers", headers);
}
json_object_set_new(event, "result", result);
int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event, NULL);
JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
Expand All @@ -5161,6 +5244,10 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase,
json_t *result = json_object();
json_object_set_new(result, "event", json_string("subscribe_succeeded"));
json_object_set_new(result, "code", json_integer(status));
if(session->incoming_header_prefixes) {
json_t *headers = janus_sip_get_incoming_headers(sip, session);
json_object_set_new(result, "headers", headers);
}
json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
json_object_set_new(event, "result", result);
int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event, NULL);
Expand Down Expand Up @@ -5227,6 +5314,10 @@ void janus_sip_sofia_callback(nua_event_t event, int status, char const *phrase,
json_object_set_new(result, "event", json_string("subscribe_failed"));
json_object_set_new(result, "code", json_integer(status));
json_object_set_new(result, "reason", json_string(phrase ? phrase : ""));
if(session->incoming_header_prefixes) {
json_t *headers = janus_sip_get_incoming_headers(sip, session);
json_object_set_new(result, "headers", headers);
}
json_object_set_new(event, "result", result);
int ret = gateway->push_event(session->handle, &janus_sip_plugin, session->transaction, event, NULL);
JANUS_LOG(LOG_VERB, " >> Pushing event to peer: %d (%s)\n", ret, janus_get_api_error(ret));
Expand Down