[asterisk-commits] kharwell: trunk r399991 - in /trunk: ./ include/asterisk/ res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Sep 27 13:28:44 CDT 2013
Author: kharwell
Date: Fri Sep 27 13:28:41 2013
New Revision: 399991
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=399991
Log:
res_pjsip: crash when using localnet and external_signaling_address options
There was a collision of mod_data use on the transaction between using a nat
hook and an session response callback. During state change it was assumed
what was in the mod_data was nothing or the response callback. However, it
was possible for it to also contain a nat hook thus resulting in a bad cast
and a crash.
Added the ability to store multiple data elements in mod_data via a hash table.
In this instance, mod_data now stores a hash table of the two values that can
be retrieved using an associated string key.
(closes issue ASTERISK-22394)
Reported by: Rusty Newton
Review: https://reviewboard.asterisk.org/r/2843/
........
Merged revisions 399990 from http://svn.asterisk.org/svn/asterisk/branches/12
Modified:
trunk/ (props changed)
trunk/include/asterisk/res_pjsip.h
trunk/res/res_pjsip.c
trunk/res/res_pjsip.exports.in
trunk/res/res_pjsip_session.c
Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-12-merged' - no diff available.
Modified: trunk/include/asterisk/res_pjsip.h
URL: http://svnview.digium.com/svn/asterisk/trunk/include/asterisk/res_pjsip.h?view=diff&rev=399991&r1=399990&r2=399991
==============================================================================
--- trunk/include/asterisk/res_pjsip.h (original)
+++ trunk/include/asterisk/res_pjsip.h Fri Sep 27 13:28:41 2013
@@ -1504,4 +1504,60 @@
int ast_sip_initialize_sorcery_global(struct ast_sorcery *sorcery);
+/*!
+ * \brief Retrieves the value associated with the given key.
+ *
+ * \param ht the hash table/dictionary to search
+ * \param key the key to find
+ *
+ * \retval the value associated with the key, NULL otherwise.
+ */
+void *ast_sip_dict_get(void *ht, const char *key);
+
+/*!
+ * \brief Using the dictionary stored in mod_data array at a given id,
+ * retrieve the value associated with the given key.
+ *
+ * \param mod_data a module data array
+ * \param id the mod_data array index
+ * \param key the key to find
+ *
+ * \retval the value associated with the key, NULL otherwise.
+ */
+#define ast_sip_mod_data_get(mod_data, id, key) \
+ ast_sip_dict_get(mod_data[id], key)
+
+/*!
+ * \brief Set the value for the given key.
+ *
+ * Note - if the hash table does not exist one is created first, the key/value
+ * pair is set, and the hash table returned.
+ *
+ * \param pool the pool to allocate memory in
+ * \param ht the hash table/dictionary in which to store the key/value pair
+ * \param key the key to associate a value with
+ * \param val the value to associate with a key
+ *
+ * \retval the given, or newly created, hash table.
+ */
+void *ast_sip_dict_set(pj_pool_t* pool, void *ht,
+ const char *key, void *val);
+
+/*!
+ * \brief Utilizing a mod_data array for a given id, set the value
+ * associated with the given key.
+ *
+ * For a given structure's mod_data array set the element indexed by id to
+ * be a dictionary containing the key/val pair.
+ *
+ * \param pool a memory allocation pool
+ * \param mod_data a module data array
+ * \param id the mod_data array index
+ * \param key the key to find
+ * \param val the value to associate with a key
+ */
+#define ast_sip_mod_data_set(pool, mod_data, id, key, val) \
+ mod_data[id] = ast_sip_dict_set(pool, mod_data[id], key, val)
+
+
#endif /* _RES_PJSIP_H */
Modified: trunk/res/res_pjsip.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip.c?view=diff&rev=399991&r1=399990&r2=399991
==============================================================================
--- trunk/res/res_pjsip.c (original)
+++ trunk/res/res_pjsip.c Fri Sep 27 13:28:41 2013
@@ -1836,6 +1836,29 @@
return *servant_id == SIP_SERVANT_ID;
}
+void *ast_sip_dict_get(void *ht, const char *key)
+{
+ unsigned int hval;
+
+ if (!ht) {
+ return NULL;
+ }
+
+ return pj_hash_get(ht, key, PJ_HASH_KEY_STRING, &hval);
+}
+
+void *ast_sip_dict_set(pj_pool_t* pool, void *ht,
+ const char *key, void *val)
+{
+ if (!ht) {
+ ht = pj_hash_create(pool, 11);
+ }
+
+ pj_hash_set(pool, ht, key, PJ_HASH_KEY_STRING, 0, val);
+
+ return ht;
+}
+
static void remove_request_headers(pjsip_endpoint *endpt)
{
const pjsip_hdr *request_headers = pjsip_endpt_get_request_headers(endpt);
Modified: trunk/res/res_pjsip.exports.in
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip.exports.in?view=diff&rev=399991&r1=399990&r2=399991
==============================================================================
--- trunk/res/res_pjsip.exports.in (original)
+++ trunk/res/res_pjsip.exports.in Fri Sep 27 13:28:41 2013
@@ -70,6 +70,8 @@
LINKER_SYMBOL_PREFIXast_sip_initialize_sorcery_global;
LINKER_SYMBOL_PREFIXast_sip_auth_array_init;
LINKER_SYMBOL_PREFIXast_sip_auth_array_destroy;
+ LINKER_SYMBOL_PREFIXast_sip_dict_get;
+ LINKER_SYMBOL_PREFIXast_sip_dict_set;
local:
*;
};
Modified: trunk/res/res_pjsip_session.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_session.c?view=diff&rev=399991&r1=399990&r2=399991
==============================================================================
--- trunk/res/res_pjsip_session.c (original)
+++ trunk/res/res_pjsip_session.c Fri Sep 27 13:28:41 2013
@@ -45,6 +45,9 @@
#define SDP_HANDLER_BUCKETS 11
+#define MOD_DATA_ON_RESPONSE "on_response"
+#define MOD_DATA_NAT_HOOK "nat_hook"
+
/* Some forward declarations */
static void handle_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata);
static void handle_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata);
@@ -127,7 +130,7 @@
}
}
AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
- ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
+ ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
ast_module_ref(ast_module_info->self);
return 0;
}
@@ -144,7 +147,7 @@
if (!ao2_link(sdp_handlers, handler_list)) {
return -1;
}
- ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
+ ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
ast_module_ref(ast_module_info->self);
return 0;
}
@@ -925,7 +928,9 @@
return;
}
- tdata->mod_data[session_module.id] = on_response;
+ ast_sip_mod_data_set(tdata->pool, tdata->mod_data, session_module.id,
+ MOD_DATA_ON_RESPONSE, on_response);
+
handle_outgoing_request(session, tdata);
pjsip_inv_send_msg(session->inv_session, tdata);
return;
@@ -1641,7 +1646,7 @@
pjsip_inv_session *inv = session->inv_session;
struct reschedule_reinvite_data *rrd = reschedule_reinvite_data_alloc(session, delay);
pj_time_val tv;
-
+
if (!rrd || !delay) {
return;
}
@@ -1850,6 +1855,7 @@
static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e)
{
+ ast_sip_session_response_cb cb;
struct ast_sip_session *session = inv->mod_data[session_module.id];
print_debug_details(inv, tsx, e);
if (!session) {
@@ -1904,8 +1910,8 @@
handle_incoming_request(session, e->body.tsx_state.src.rdata);
}
}
- if (tsx->mod_data[session_module.id]) {
- ast_sip_session_response_cb cb = tsx->mod_data[session_module.id];
+ if ((cb = ast_sip_mod_data_get(tsx->mod_data, session_module.id,
+ MOD_DATA_ON_RESPONSE))) {
cb(session, e->body.tsx_state.src.rdata);
}
case PJSIP_EVENT_TRANSPORT_ERROR:
@@ -2073,7 +2079,8 @@
/*! \brief Hook for modifying outgoing messages with SDP to contain the proper address information */
static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_transport *transport)
{
- struct ast_sip_nat_hook *hook = tdata->mod_data[session_module.id];
+ struct ast_sip_nat_hook *hook = ast_sip_mod_data_get(
+ tdata->mod_data, session_module.id, MOD_DATA_NAT_HOOK);
struct pjmedia_sdp_session *sdp;
int stream;
@@ -2107,7 +2114,7 @@
}
/* We purposely do this so that the hook will not be invoked multiple times, ie: if a retransmit occurs */
- tdata->mod_data[session_module.id] = nat_hook;
+ ast_sip_mod_data_set(tdata->pool, tdata->mod_data, session_module.id, MOD_DATA_NAT_HOOK, nat_hook);
}
static int load_module(void)
More information about the asterisk-commits
mailing list