From fb68746eedb591ac19d16585c9a90954f0f67c5d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 16 Jun 2011 14:37:22 -0500 Subject: [PATCH] add parallelism to sofia by offsetting sip messages to the concerned sessions and using multiple queue threads for message handling --- libs/apr/include/apr_pools.h | 2 +- libs/apr/memory/unix/apr_pools.c | 8 +- src/include/switch_types.h | 1 + src/mod/endpoints/mod_sofia/mod_sofia.c | 25 +- src/mod/endpoints/mod_sofia/mod_sofia.h | 78 +++- src/mod/endpoints/mod_sofia/sofia.c | 367 ++++++++++++++----- src/mod/endpoints/mod_sofia/sofia_glue.c | 7 +- src/mod/endpoints/mod_sofia/sofia_presence.c | 75 ++-- src/mod/endpoints/mod_sofia/sofia_reg.c | 42 ++- src/mod/endpoints/mod_sofia/sofia_sla.c | 21 +- src/switch_core_memory.c | 32 +- src/switch_core_session.c | 8 +- src/switch_core_state_machine.c | 1 + 13 files changed, 480 insertions(+), 187 deletions(-) diff --git a/libs/apr/include/apr_pools.h b/libs/apr/include/apr_pools.h index 5c82b38747..74ed59e35b 100644 --- a/libs/apr/include/apr_pools.h +++ b/libs/apr/include/apr_pools.h @@ -409,7 +409,7 @@ APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b); * @param pool The pool to tag * @param tag The tag */ -APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag); +APR_DECLARE(char *) apr_pool_tag(apr_pool_t *pool, const char *tag); #if APR_HAS_THREADS /** diff --git a/libs/apr/memory/unix/apr_pools.c b/libs/apr/memory/unix/apr_pools.c index 42c64967cd..99e1888b1f 100644 --- a/libs/apr/memory/unix/apr_pools.c +++ b/libs/apr/memory/unix/apr_pools.c @@ -1895,9 +1895,13 @@ APR_DECLARE(int) apr_pool_is_ancestor(apr_pool_t *a, apr_pool_t *b) return 0; } -APR_DECLARE(void) apr_pool_tag(apr_pool_t *pool, const char *tag) +APR_DECLARE(char *) apr_pool_tag(apr_pool_t *pool, const char *tag) { - pool->tag = tag; + if (tag) { + pool->tag = tag; + } + + return pool->tag; } diff --git a/src/include/switch_types.h b/src/include/switch_types.h index bf5d5d88ea..e84fb1082a 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -799,6 +799,7 @@ typedef enum { SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS, SWITCH_MESSAGE_INDICATE_JITTER_BUFFER, SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH, + SWITCH_MESSAGE_INDICATE_SIGNAL_DATA, SWITCH_MESSAGE_INVALID } switch_core_session_message_types_t; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index a7e6d99dc2..979d80037d 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1366,6 +1366,15 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi private_object_t *tech_pvt = switch_core_session_get_private(session); switch_status_t status = SWITCH_STATUS_SUCCESS; + if (msg->message_id == SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) { + sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) msg->pointer_arg; + switch_mutex_lock(tech_pvt->sofia_mutex); + sofia_process_dispatch_event(&de); + switch_mutex_unlock(tech_pvt->sofia_mutex); + goto end; + } + + if (switch_channel_down(channel) || !tech_pvt || sofia_test_flag(tech_pvt, TFLAG_BYE)) { status = SWITCH_STATUS_FALSE; goto end; @@ -2158,7 +2167,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi to_host = switch_channel_get_variable(channel, "sip_to_host"); } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Challenging call %s\n", to_uri); - sofia_reg_auth_challenge(NULL, tech_pvt->profile, tech_pvt->nh, REG_INVITE, to_host, 0); + sofia_reg_auth_challenge(NULL, tech_pvt->profile, tech_pvt->nh, NULL, REG_INVITE, to_host, 0); switch_channel_hangup(channel, SWITCH_CAUSE_USER_CHALLENGE); } else if (code == 484 && msg->numeric_arg) { const char *to = switch_channel_get_variable(channel, "sip_to_uri"); @@ -4640,7 +4649,6 @@ static void general_event_handler(switch_event_t *event) nua_notify(nh, NUTAG_NEWSUB(1), - NUTAG_WITH_THIS(profile->nua), TAG_IF(dst->route_uri, NUTAG_PROXY(dst->contact)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)), SIPTAG_EVENT_STR(es), TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_END()); @@ -4826,7 +4834,6 @@ static void general_event_handler(switch_event_t *event) } nua_info(nh, - NUTAG_WITH_THIS(profile->nua), TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(cd, SIPTAG_CONTENT_DISPOSITION_STR(cd)), TAG_IF(alert_info, SIPTAG_ALERT_INFO_STR(alert_info)), @@ -5219,11 +5226,18 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) { int sanity = 0; + int i; + switch_console_del_complete_func("::sofia::list_profiles"); switch_console_set_complete("del sofia"); switch_mutex_lock(mod_sofia_globals.mutex); + + for (i = 0; i < mod_sofia_globals.msg_queue_len; i++) { + switch_queue_push(mod_sofia_globals.msg_queue[i], NULL); + } + if (mod_sofia_globals.running == 1) { mod_sofia_globals.running = 0; } @@ -5245,6 +5259,11 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) } } + for (i = 0; i < mod_sofia_globals.msg_queue_len; i++) { + switch_status_t st; + switch_thread_join(&st, mod_sofia_globals.msg_queue_thread[i]); + } + //switch_yield(1000000); su_deinit(); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index db8a6ff9e3..6542bae615 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -134,6 +134,16 @@ typedef enum { DTMF_NONE } sofia_dtmf_t; +typedef struct sofia_dispatch_event_s { + nua_saved_event_t event[1]; + nua_handle_t *nh; + nua_event_data_t const *data; + su_time_t when; + sip_t *sip; + nua_t *nua; + sofia_profile_t *profile; +} sofia_dispatch_event_t; + struct sofia_private { char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1]; sofia_gateway_t *gateway; @@ -143,11 +153,13 @@ struct sofia_private { int destroy_me; int is_call; int is_static; + sofia_dispatch_event_t *de; }; #define set_param(ptr,val) if (ptr) {free(ptr) ; ptr = NULL;} if (val) {ptr = strdup(val);} #define set_anchor(t,m) if (t->Anchor) {delete t->Anchor;} t->Anchor = new SipMessage(m); -#define sofia_private_free(_pvt) if (_pvt && ! _pvt->is_static) {free(_pvt); _pvt = NULL;} +//#define sofia_private_free(_pvt) if (_pvt && ! _pvt->is_static) {free(_pvt); _pvt = NULL;} +#define sofia_private_free(_pvt) _pvt = NULL /* Local Structures */ /*************************************************************************************************************************************************************/ @@ -300,6 +312,9 @@ typedef enum { TFLAG_MAX } TFLAGS; +#define SOFIA_MAX_MSG_QUEUE 25 +#define SOFIA_MSG_QUEUE_SIZE 10 + struct mod_sofia_globals { switch_memory_pool_t *pool; switch_hash_t *profile_hash; @@ -313,6 +328,9 @@ struct mod_sofia_globals { char hostname[512]; switch_queue_t *presence_queue; switch_queue_t *mwi_queue; + switch_queue_t *msg_queue[SOFIA_MAX_MSG_QUEUE]; + switch_thread_t *msg_queue_thread[SOFIA_MAX_MSG_QUEUE]; + int msg_queue_len; struct sofia_private destroy_private; struct sofia_private keep_private; switch_event_node_t *in_node; @@ -541,7 +559,7 @@ struct sofia_profile { switch_mutex_t *ireg_mutex; switch_mutex_t *gateway_mutex; sofia_gateway_t *gateways; - su_home_t *home; + //su_home_t *home; switch_hash_t *chat_hash; //switch_core_db_t *master_db; switch_thread_rwlock_t *rwlock; @@ -773,6 +791,8 @@ typedef struct { } sofia_nat_parse_t; +#define NUTAG_WITH_THIS_MSG(msg) nutag_with, tag_ptr_v(msg) + #define sofia_test_pflag(obj, flag) ((obj)->pflags[flag] ? 1 : 0) #define sofia_set_pflag(obj, flag) (obj)->pflags[flag] = 1 #define sofia_set_pflag_locked(obj, flag) assert(obj->flag_mutex != NULL);\ @@ -814,19 +834,24 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s void sofia_presence_establish_presence(sofia_profile_t *profile); -void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]); +void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); -void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]); +void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); -void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]); +void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_event_callback(nua_event_t event, int status, char const *phrase, - nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]); + nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + tagi_t tags[]); void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void *obj); @@ -851,9 +876,11 @@ void sofia_presence_mwi_event_handler(switch_event_t *event); void sofia_glue_track_event_handler(switch_event_t *event); void sofia_presence_cancel(void); switch_status_t config_sofia(int reload, char *profile_name); -void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_regtype_t regtype, const char *realm, int stale); +void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de, + sofia_regtype_t regtype, const char *realm, int stale); auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization, - sip_t const *sip, const char *regstr, char *np, size_t nplen, char *ip, switch_event_t **v_event, + sip_t const *sip, + sofia_dispatch_event_t *de, const char *regstr, char *np, size_t nplen, char *ip, switch_event_t **v_event, long exptime, sofia_regtype_t regtype, const char *to_user, switch_event_t **auth_params, long *reg_count); @@ -861,21 +888,28 @@ void sofia_reg_handle_sip_r_challenge(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, - switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip, tagi_t tags[]); + switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_reg_handle_sip_r_register(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_handle_sip_i_options(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, - sip_t const *sip, tagi_t tags[]); + sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_presence_handle_sip_i_message(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, - sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]); + sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_presence_handle_sip_r_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, - sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]); + sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_presence_handle_sip_i_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, - sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]); + sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic); void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex); @@ -892,6 +926,7 @@ void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp); switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status); void sofia_glue_do_xfer_invite(switch_core_session_t *session); uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, + sofia_dispatch_event_t *de, sofia_regtype_t regtype, char *key, uint32_t keylen, switch_event_t **v_event, const char *is_nat); extern switch_endpoint_interface_t *sofia_endpoint_interface; void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip); @@ -1008,14 +1043,19 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t * * SLA (shared line appearance) entrypoints */ -void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip, long exptime, const char *full_contact); -void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); -void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); +void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip, + sofia_dispatch_event_t *de, long exptime, const char *full_contact); +void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); +void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_sla_handle_sip_r_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); -void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); +void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); /* * Logging control functions @@ -1072,5 +1112,7 @@ switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, swi void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl); void sofia_glue_check_dtmf_type(private_object_t *tech_pvt); void sofia_glue_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str); -char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np); +char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_dispatch_event_t *de, sofia_nat_parse_t *np); void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on); +void sofia_process_dispatch_event(sofia_dispatch_event_t **dep); + diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index bf9ff4e7c4..026c3c9ba1 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -54,6 +54,7 @@ extern su_log_t su_log_default[]; void sofia_handle_sip_i_reinvite(switch_core_session_t *session, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); static void set_variable_sip_param(switch_channel_t *channel, char *header_type, sip_param_t const *params); @@ -63,18 +64,22 @@ static void set_variable_sip_param(switch_channel_t *channel, char *header_type, static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); static void sofia_handle_sip_r_options(switch_core_session_t *session, int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, - nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]); + nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]); void sofia_handle_sip_r_notify(switch_core_session_t *session, int status, char const *phrase, - nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]) + nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { if (status >= 300 && sip && sip->sip_call_id) { @@ -156,28 +161,29 @@ static char *strip_quotes(const char *in) return r; } -static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip, switch_core_session_t *session) +static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip, + switch_core_session_t *session, nua_handle_t *nh) { switch_channel_t *channel = switch_core_session_get_channel(session); char *full; if (sip) { if (sip->sip_route) { - if ((full = sip_header_as_string(profile->home, (void *) sip->sip_route))) { + if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_route))) { const char *v = switch_channel_get_variable(channel, "sip_full_route"); if (!v) { switch_channel_set_variable(channel, "sip_full_route", full); } - su_free(profile->home, full); + su_free(nh->nh_home, full); } } if (sip->sip_via) { - if ((full = sip_header_as_string(profile->home, (void *) sip->sip_via))) { + if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_via))) { const char *v = switch_channel_get_variable(channel, "sip_full_via"); if (!v) { switch_channel_set_variable(channel, "sip_full_via", full); } - su_free(profile->home, full); + su_free(nh->nh_home, full); } } if (sip->sip_from) { @@ -187,9 +193,9 @@ static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip, swit switch_channel_set_variable(channel, "sip_from_display", p); } if (p != sip->sip_from->a_display) free(p); - if ((full = sip_header_as_string(profile->home, (void *) sip->sip_from))) { + if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_from))) { switch_channel_set_variable(channel, "sip_full_from", full); - su_free(profile->home, full); + su_free(nh->nh_home, full); } } if (sip->sip_to) { @@ -201,16 +207,17 @@ static void extract_header_vars(sofia_profile_t *profile, sip_t const *sip, swit if (p != sip->sip_to->a_display) free(p); - if ((full = sip_header_as_string(profile->home, (void *) sip->sip_to))) { + if ((full = sip_header_as_string(nh->nh_home, (void *) sip->sip_to))) { switch_channel_set_variable(channel, "sip_full_to", full); - su_free(profile->home, full); + su_free(nh->nh_home, full); } } } } -static void extract_vars(sofia_profile_t *profile, sip_t const *sip, switch_core_session_t *session) +static void extract_vars(sofia_profile_t *profile, sip_t const *sip, + switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); @@ -246,7 +253,8 @@ static void extract_vars(sofia_profile_t *profile, sip_t const *sip, switch_core void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, char const *phrase, - nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]) + nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { switch_channel_t *channel = NULL; private_object_t *tech_pvt = NULL; @@ -271,7 +279,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) { if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) { - sofia_sla_handle_sip_i_notify(nua, profile, nh, sip, tags); + sofia_sla_handle_sip_i_notify(nua, profile, nh, sip, de, tags); goto end; } } @@ -279,7 +287,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, /* Automatically return a 200 OK for Event: keep-alive */ if (!strcasecmp(sip->sip_event->o_type, "keep-alive")) { /* XXX MTK - is this right? in this case isn't sofia is already sending a 200 itself also? */ - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); goto end; } @@ -357,7 +365,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, } } } - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } /* if no session, assume it could be an incoming notify from a gateway subscription */ @@ -371,7 +379,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, switch_channel_answer(channel); switch_channel_set_variable(channel, "auto_answer_destination", switch_channel_get_variable(channel, "destination_number")); switch_ivr_session_transfer(session, "auto_answer", NULL, NULL); - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); goto end; } } @@ -421,7 +429,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, if (sip && sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "message-summary")) { /* unsolicited mwi, just say ok */ - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); if (sofia_test_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)) { const char *mwi_status = NULL; @@ -433,7 +441,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, if (sip->sip_to && sip->sip_to->a_url && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host && sip->sip_payload && sip->sip_payload->pl_data ) { - sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), NULL); + sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), NULL); for (x = 0; x < profile->acl_count; x++) { last_acl = profile->acl[x]; if (!(acl_ok = switch_check_network_list_ip(network_ip, last_acl))) { @@ -470,7 +478,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, } } else { - nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } end: @@ -485,7 +493,8 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, void sofia_handle_sip_i_bye(switch_core_session_t *session, int status, char const *phrase, - nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]) + nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { const char *tmp; switch_channel_t *channel; @@ -544,7 +553,7 @@ void sofia_handle_sip_i_bye(switch_core_session_t *session, int status, sofia_glue_set_extra_headers(channel, sip, SOFIA_SIP_BYE_HEADER_PREFIX); switch_channel_hangup(channel, cause); - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END()); switch_safe_free(extra_headers); @@ -636,7 +645,8 @@ void sofia_send_callee_id(switch_core_session_t *session, const char *name, cons } } -void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t send) +void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, + switch_bool_t send) { switch_channel_t *channel = switch_core_session_get_channel(session); sip_p_asserted_identity_t *passerted = NULL; @@ -760,11 +770,12 @@ void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *pro switch_safe_free(dup); } - -void sofia_event_callback(nua_event_t event, +//sofia_dispatch_event_t *de +static void our_sofia_event_callback(nua_event_t event, int status, char const *phrase, - nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]) + nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { struct private_object *tech_pvt = NULL; auth_res_t auth_res = AUTH_FORBIDDEN; @@ -774,6 +785,13 @@ void sofia_event_callback(nua_event_t event, int locked = 0; int check_destroy = 1; + + if (sofia_private && sofia_private->de) { + sofia_dispatch_event_t *qde = sofia_private->de; + sofia_private->de = NULL; + sofia_process_dispatch_event(&qde); + } + profile->last_sip_event = switch_time_now(); /* sofia_private will be == &mod_sofia_globals.keep_private whenever a request is done with a new handle that has to be @@ -855,8 +873,8 @@ void sofia_event_callback(nua_event_t event, if (authorization) { char network_ip[80]; - sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), NULL); - auth_res = sofia_reg_parse_auth(profile, authorization, sip, + sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), NULL); + auth_res = sofia_reg_parse_auth(profile, authorization, sip, de, (char *) sip->sip_request->rq_method_name, tech_pvt->key, strlen(tech_pvt->key), network_ip, NULL, 0, REG_INVITE, NULL, NULL, NULL); } @@ -873,7 +891,7 @@ void sofia_event_callback(nua_event_t event, } if (sip && (status == 401 || status == 407)) { - sofia_reg_handle_sip_r_challenge(status, phrase, nua, profile, nh, sofia_private, session, gateway, sip, tags); + sofia_reg_handle_sip_r_challenge(status, phrase, nua, profile, nh, sofia_private, session, gateway, sip, de, tags); goto done; } @@ -922,7 +940,7 @@ void sofia_event_callback(nua_event_t event, switch_channel_set_variable(channel, "sip_call_id", sip->sip_call_id->i_id); } - extract_header_vars(profile, sip, session); + extract_header_vars(profile, sip, session, nh); sofia_glue_tech_track(tech_pvt->profile, session); } } @@ -938,49 +956,49 @@ void sofia_event_callback(nua_event_t event, sofia_handle_sip_r_message(status, profile, nh, sip); break; case nua_r_invite: - sofia_handle_sip_r_invite(session, status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_handle_sip_r_invite(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_r_options: - sofia_handle_sip_r_options(session, status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_handle_sip_r_options(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_i_bye: - sofia_handle_sip_i_bye(session, status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_handle_sip_i_bye(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_r_notify: - sofia_handle_sip_r_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_handle_sip_r_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_i_notify: - sofia_handle_sip_i_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_handle_sip_i_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_r_register: - sofia_reg_handle_sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_reg_handle_sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_i_options: - sofia_handle_sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_handle_sip_i_options(status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_i_invite: if (session) { - sofia_handle_sip_i_reinvite(session, nua, profile, nh, sofia_private, sip, tags); + sofia_handle_sip_i_reinvite(session, nua, profile, nh, sofia_private, sip, de, tags); } else { - sofia_handle_sip_i_invite(nua, profile, nh, sofia_private, sip, tags); + sofia_handle_sip_i_invite(nua, profile, nh, sofia_private, sip, de, tags); } break; case nua_i_publish: - sofia_presence_handle_sip_i_publish(nua, profile, nh, sofia_private, sip, tags); + sofia_presence_handle_sip_i_publish(nua, profile, nh, sofia_private, sip, de, tags); break; case nua_i_register: - //nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), NUTAG_WITH_THIS(nua), TAG_END()); + //nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); //nua_handle_destroy(nh); - sofia_reg_handle_sip_i_register(nua, profile, nh, sofia_private, sip, tags); + sofia_reg_handle_sip_i_register(nua, profile, nh, sofia_private, sip, de, tags); break; case nua_i_state: - sofia_handle_sip_i_state(session, status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_handle_sip_i_state(session, status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_i_message: - sofia_presence_handle_sip_i_message(status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_presence_handle_sip_i_message(status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_i_info: - sofia_handle_sip_i_info(nua, profile, nh, session, sip, tags); + sofia_handle_sip_i_info(nua, profile, nh, session, sip, de, tags); break; case nua_i_update: break; @@ -993,13 +1011,13 @@ void sofia_event_callback(nua_event_t event, break; case nua_i_refer: if (session) - sofia_handle_sip_i_refer(nua, profile, nh, session, sip, tags); + sofia_handle_sip_i_refer(nua, profile, nh, session, sip, de, tags); break; case nua_r_subscribe: - sofia_presence_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_presence_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_i_subscribe: - sofia_presence_handle_sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_presence_handle_sip_i_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags); break; case nua_r_authenticate: @@ -1072,6 +1090,7 @@ void sofia_event_callback(nua_event_t event, } sofia_private->destroy_me = 12; sofia_private_free(sofia_private); + } if (gateway) { @@ -1087,6 +1106,169 @@ void sofia_event_callback(nua_event_t event, } } +void sofia_process_dispatch_event(sofia_dispatch_event_t **dep) +{ + sofia_dispatch_event_t *de = *dep; + *dep = NULL; + + our_sofia_event_callback(de->data->e_event, de->data->e_status, de->data->e_phrase, de->nua, de->profile, + de->nh, nua_handle_magic(de->nh), de->sip, de, (tagi_t *) de->data->e_tags); + nua_handle_unref(de->nh); + nua_stack_unref(de->nua); + nua_destroy_event(de->event); + free(de); +} + + +void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj) +{ + void *pop; + switch_queue_t *q = (switch_queue_t *) obj; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MSG Thread Started\n"); + + while (mod_sofia_globals.running == 1) { + + if (switch_queue_pop(q, &pop) == SWITCH_STATUS_SUCCESS) { + sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop; + + if (!pop) { + break; + } + + sofia_process_dispatch_event(&de); + } + } + + while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) { + sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop; + nua_handle_unref(de->nh); + nua_destroy_event(de->event); + free(de); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MSG Thread Ended\n"); + + return NULL; +} + +static int IDX = 0; + +static void sofia_msg_thread_start(int idx) +{ + + if (idx >= SOFIA_MAX_MSG_QUEUE || (idx < mod_sofia_globals.msg_queue_len && mod_sofia_globals.msg_queue_thread[idx])) { + return; + } + + switch_mutex_lock(mod_sofia_globals.mutex); + + if (idx >= mod_sofia_globals.msg_queue_len) { + int i; + mod_sofia_globals.msg_queue_len = idx + 1; + + for (i = 0; i < mod_sofia_globals.msg_queue_len; i++) { + if (!mod_sofia_globals.msg_queue[i]) { + switch_threadattr_t *thd_attr = NULL; + + switch_queue_create(&mod_sofia_globals.msg_queue[i], SOFIA_MSG_QUEUE_SIZE, mod_sofia_globals.pool); + + switch_threadattr_create(&thd_attr, mod_sofia_globals.pool); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_increase(thd_attr); + switch_thread_create(&mod_sofia_globals.msg_queue_thread[i], + thd_attr, + sofia_msg_thread_run, + mod_sofia_globals.msg_queue[i], + mod_sofia_globals.pool); + } + } + } + + switch_mutex_unlock(mod_sofia_globals.mutex); +} + + +static void sofia_queue_message(sofia_dispatch_event_t *de) +{ + int idx = 0; + + again: + + switch_mutex_lock(mod_sofia_globals.mutex); + idx = IDX; + IDX++; + if (IDX >= mod_sofia_globals.msg_queue_len) IDX = 0; + switch_mutex_unlock(mod_sofia_globals.mutex); + + sofia_msg_thread_start(idx); + + if (switch_queue_trypush(mod_sofia_globals.msg_queue[idx], de) != SWITCH_STATUS_SUCCESS) { + if (mod_sofia_globals.msg_queue_len < SOFIA_MAX_MSG_QUEUE) { + sofia_msg_thread_start(idx + 1); + goto again; + } else { + switch_queue_push(mod_sofia_globals.msg_queue[idx], de); + } + } +} + + +void sofia_event_callback(nua_event_t event, + int status, + char const *phrase, + nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + tagi_t tags[]) +{ + sofia_dispatch_event_t *de; + + de = calloc(1, sizeof *de); + nua_save_event(nua, de->event); + de->nh = nua_handle_ref(nh); + de->data = nua_event_data(de->event); + de->sip = sip_object(de->data->e_msg); + de->profile = profile; + de->nua = nua_stack_ref(nua); + + if (event == nua_i_invite && !sofia_private) { + if (!(sofia_private = su_alloc(nh->nh_home, sizeof(*sofia_private)))) { + abort(); + } + + memset(sofia_private, 0, sizeof(*sofia_private)); + sofia_private->is_call++; + sofia_private->de = de; + nua_handle_bind(nh, sofia_private); + return; + } + + if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) { + switch_core_session_message_t *msg; + switch_core_session_t *session; + + if (!zstr(sofia_private->uuid)) { + if ((session = switch_core_session_locate(sofia_private->uuid))) { + msg = switch_core_session_alloc(session, sizeof(*msg)); + msg->message_id = SWITCH_MESSAGE_INDICATE_SIGNAL_DATA; + msg->from = __FILE__; + msg->numeric_arg = status; + msg->pointer_arg = de; + + if (switch_core_session_running(session)) { + switch_core_session_queue_message(session, msg); + } else { + switch_core_session_receive_message(session, msg); + } + switch_core_session_rwunlock(session); + return; + } + } + } + + sofia_queue_message(de); +} + + void event_handler(switch_event_t *event) { char *subclass, *sql; @@ -1484,7 +1666,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void switch_mutex_unlock(mod_sofia_globals.mutex); profile->s_root = su_root_create(NULL); - profile->home = su_home_new(sizeof(*profile->home)); + //profile->home = su_home_new(sizeof(*profile->home)); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating agent for %s\n", profile->name); @@ -1727,7 +1909,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void } } - su_home_unref(profile->home); + //su_home_unref(profile->home); su_root_destroy(profile->s_root); //pool = profile->pool; @@ -3201,6 +3383,15 @@ switch_status_t config_sofia(int reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_CID_IN_1XX); } + } else if (!strcasecmp(var, "message-threads")) { + int num = atoi(val); + + if (num < 1 || num >= SOFIA_MAX_MSG_QUEUE) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "message-threads must be between 1 and %d", SOFIA_MAX_MSG_QUEUE); + } else { + sofia_msg_thread_start(num); + } + } else if (!strcasecmp(var, "disable-hold")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_DISABLE_HOLD); @@ -4065,6 +4256,7 @@ const char *sofia_gateway_status_name(sofia_gateway_status_t status) static void sofia_handle_sip_r_options(switch_core_session_t *session, int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { sofia_gateway_t *gateway = NULL; @@ -4130,6 +4322,7 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { char *call_info = NULL; @@ -4144,7 +4337,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status switch_caller_profile_t *caller_profile = NULL; int has_t38 = 0; - sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port); + sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port); switch_channel_set_variable_printf(channel, "sip_local_network_addr", "%s", profile->extsipip ? profile->extsipip : profile->sipip); switch_channel_set_variable(channel, "sip_reply_host", network_ip); @@ -4648,7 +4841,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); } - extract_header_vars(profile, sip, session); + extract_header_vars(profile, sip, session, nh); extract_vars(profile, sip, session); sofia_glue_tech_track(tech_pvt->profile, session); sofia_clear_flag(tech_pvt, TFLAG_RECOVERING); @@ -4715,6 +4908,7 @@ static void launch_media_on_hold(switch_core_session_t *session) static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { const char *l_sdp = NULL, *r_sdp = NULL; @@ -5531,6 +5725,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, tech_pvt->sofia_private = NULL; } + nua_handle_unref(tech_pvt->nh); tech_pvt->nh = NULL; if (nh) { @@ -5693,7 +5888,8 @@ nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces) } -void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]) +void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { /* Incoming refer */ sip_from_t const *from; @@ -5710,7 +5906,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_memory_pool_t *npool; if (!(profile->mflags & MFLAG_REFER)) { - nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); goto done; } @@ -5725,7 +5921,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t home = su_home_new(sizeof(*home)); switch_assert(home != NULL); - nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS(nua), SIPTAG_EXPIRES_STR("60"), TAG_END()); + nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"), TAG_END()); if (sip->sip_referred_by) { full_ref_by = sip_header_as_string(home, (void *) sip->sip_referred_by); @@ -6205,7 +6401,8 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t } -static switch_status_t create_info_event(sip_t const *sip, nua_handle_t *nh, switch_event_t **revent) +static switch_status_t create_info_event(sip_t const *sip, + nua_handle_t *nh, switch_event_t **revent) { sip_alert_info_t *alert_info = sip_alert_info(sip); switch_event_t *event; @@ -6269,7 +6466,8 @@ static switch_status_t create_info_event(sip_t const *sip, nua_handle_t *nh, swi return SWITCH_STATUS_SUCCESS; } -void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, tagi_t tags[]) +void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, switch_core_session_t *session, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { /* placeholder for string searching */ const char *signal_ptr; @@ -6295,17 +6493,17 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t if (switch_core_session_queue_event(session, &event) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "queued freeswitch event for INFO\n"); nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"), - SIPTAG_PAYLOAD_STR("+OK MESSAGE QUEUED"), NUTAG_WITH_THIS(nua), TAG_END()); + SIPTAG_PAYLOAD_STR("+OK MESSAGE QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } else { switch_event_destroy(&event); nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"), - SIPTAG_PAYLOAD_STR("-ERR MESSAGE NOT QUEUED"), NUTAG_WITH_THIS(nua), TAG_END()); + SIPTAG_PAYLOAD_STR("-ERR MESSAGE NOT QUEUED"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } } } else { nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/session-event-response"), - SIPTAG_PAYLOAD_STR("-ERR INVALID SESSION"), NUTAG_WITH_THIS(nua), TAG_END()); + SIPTAG_PAYLOAD_STR("-ERR INVALID SESSION"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } @@ -6326,10 +6524,10 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t if ((status = switch_api_execute(cmd, arg, NULL, &stream)) == SWITCH_STATUS_SUCCESS) { nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response"), - SIPTAG_PAYLOAD_STR(stream.data), NUTAG_WITH_THIS(nua), TAG_END()); + SIPTAG_PAYLOAD_STR(stream.data), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } else { nua_respond(nh, SIP_200_OK, SIPTAG_CONTENT_TYPE_STR("freeswitch/api-response"), - SIPTAG_PAYLOAD_STR("-ERR INVALID COMMAND"), NUTAG_WITH_THIS(nua), TAG_END()); + SIPTAG_PAYLOAD_STR("-ERR INVALID COMMAND"), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } switch_safe_free(stream.data); @@ -6337,7 +6535,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t return; } - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); return; } @@ -6438,7 +6636,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t } /* Send 200 OK response */ - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "IGNORE INFO DTMF(%c) (This channel was not configured to use INFO DTMF!)\n", dtmf.digit); @@ -6450,7 +6648,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t if (!zstr(clientcode_header)) { switch_channel_set_variable(channel, "call_clientcode", clientcode_header); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Setting CMC to %s\n", clientcode_header); - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } goto end; } @@ -6458,7 +6656,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t if ((rec_header = sofia_glue_get_unknown_header(sip, "record"))) { if (zstr(profile->record_template)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Record attempted but no template defined.\n"); - nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, 488, "Recording not enabled", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } else { if (!strcasecmp(rec_header, "on")) { char *file = NULL, *tmp = NULL; @@ -6471,7 +6669,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Recording %s to %s\n", switch_channel_get_name(channel), file); switch_safe_free(tmp); - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); if (file != profile->record_template) { free(file); file = NULL; @@ -6483,9 +6681,9 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Done recording %s to %s\n", switch_channel_get_name(channel), file); switch_ivr_stop_record_session(session, file); - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } else { - nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, 488, "Nothing to stop", NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } } } @@ -6499,7 +6697,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "dispatched freeswitch event for INFO\n"); } - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); return; @@ -6507,6 +6705,7 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t void sofia_handle_sip_i_reinvite(switch_core_session_t *session, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { char *call_info = NULL; @@ -6519,7 +6718,7 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session, char via_space[2048]; char branch[16] = ""; - sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port); + sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port); switch_stun_random_string(branch, sizeof(branch) - 1, "0123456789abcdef"); switch_snprintf(via_space, sizeof(via_space), "SIP/2.0/UDP %s;rport=%d;branch=%s", network_ip, network_port, branch); @@ -6548,7 +6747,8 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session, } } -void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, tagi_t tags[]) +void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { switch_core_session_t *session = NULL; char key[128] = ""; @@ -6605,7 +6805,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ goto fail; } - sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port); + sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port); if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)) { if (sip && sip->sip_via) { @@ -6765,7 +6965,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) { calling_myself++; } else { - if (sofia_reg_handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key), &v_event, NULL)) { + if (sofia_reg_handle_register(nua, profile, nh, sip, de, REG_INVITE, key, sizeof(key), &v_event, NULL)) { if (v_event) { switch_event_destroy(&v_event); } @@ -6964,7 +7164,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ check_decode(from_user, session); } - extract_header_vars(profile, sip, session); + extract_header_vars(profile, sip, session, nh); if (sip->sip_request->rq_url) { const char *req_uri = url_set_chanvars(session, sip->sip_request->rq_url, sip_req); @@ -7200,9 +7400,9 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } if ((alert_info = sip_alert_info(sip))) { - char *tmp = sip_header_as_string(profile->home, (void *) alert_info); + char *tmp = sip_header_as_string(nh->nh_home, (void *) alert_info); switch_channel_set_variable(channel, "alert_info", tmp); - su_free(profile->home, tmp); + su_free(nh->nh_home, tmp); } if ((call_info = sip_call_info(sip))) { @@ -7528,20 +7728,14 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); } - if (!(sofia_private = malloc(sizeof(*sofia_private)))) { - abort(); - } - memset(sofia_private, 0, sizeof(*sofia_private)); - sofia_private->is_call++; tech_pvt->sofia_private = sofia_private; - + tech_pvt->nh = nua_handle_ref(nh); + if (profile->pres_type && sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)) { sofia_presence_set_chat_hash(tech_pvt, sip); } switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid)); - nua_handle_bind(nh, tech_pvt->sofia_private); - tech_pvt->nh = nh; if (sip && switch_core_session_thread_launch(session) == SWITCH_STATUS_SUCCESS) { const char *dialog_from_user = "", *dialog_from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = ""; @@ -7661,9 +7855,10 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ void sofia_handle_sip_i_options(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } void sofia_info_send_sipfrag(switch_core_session_t *aleg, switch_core_session_t *bleg) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 6fcf2e30cd..767558c045 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2202,6 +2202,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) switch_safe_free(d_url); return SWITCH_STATUS_FALSE; } + nua_handle_ref(tech_pvt->nh); if (tech_pvt->dest && (strstr(tech_pvt->dest, ";fs_nat") || strstr(tech_pvt->dest, ";received") || ((val = switch_channel_get_variable(channel, "sip_sticky_contact")) && switch_true(val)))) { @@ -2290,7 +2291,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) switch_safe_free(d_url); - if (!(sofia_private = malloc(sizeof(*sofia_private)))) { + if (!(sofia_private = su_alloc(tech_pvt->nh->nh_home, sizeof(*sofia_private)))) { abort(); } @@ -6484,7 +6485,7 @@ void sofia_glue_parse_rtp_bugs(switch_rtp_bug_flag_t *flag_pole, const char *str } } -char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np) +char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_dispatch_event_t *de, sofia_nat_parse_t *np) { char *contact_str = NULL; const char *contact_host;//, *contact_user; @@ -6507,7 +6508,7 @@ char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sof np = &lnp; } - sofia_glue_get_addr(nua_current_request(profile->nua), np->network_ip, sizeof(np->network_ip), &np->network_port); + sofia_glue_get_addr(de->data->e_msg, np->network_ip, sizeof(np->network_ip), &np->network_port); if (sofia_glue_check_nat(profile, np->network_ip)) { np->is_auto_nat = 1; diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 2ca69c5f57..34c6799991 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -2094,6 +2094,7 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char * void sofia_presence_handle_sip_i_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { @@ -2128,7 +2129,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, to = sip->sip_to; contact = sip->sip_contact; - if (!(contact_str = sofia_glue_gen_contact_str(profile, sip, &np))) { + if (!(contact_str = sofia_glue_gen_contact_str(profile, sip, de, &np))) { nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END()); return; } @@ -2138,7 +2139,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END()); - event = sip_header_as_string(profile->home, (void *) sip->sip_event); + event = sip_header_as_string(nh->nh_home, (void *) sip->sip_event); /* the following could be refactored back to the calling event handler in sofia.c XXX MTK */ @@ -2146,7 +2147,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) { /* only fire this on <200 to try to avoid resubscribes. probably better ways to do this? */ if (status < 200) { - sofia_sla_handle_sip_i_subscribe(nua, contact_str, profile, nh, sip, tags); + sofia_sla_handle_sip_i_subscribe(nua, contact_str, profile, nh, sip, de, tags); } switch_safe_free(contact_str); return; @@ -2200,14 +2201,14 @@ void sofia_presence_handle_sip_i_subscribe(int status, } if (!(proto && to_user && to_host)) { - nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); goto end; } } call_id = sip->sip_call_id->i_id; - full_from = sip_header_as_string(profile->home, (void *) sip->sip_from); - full_via = sip_header_as_string(profile->home, (void *) sip->sip_via); + full_from = sip_header_as_string(nh->nh_home, (void *) sip->sip_from); + full_via = sip_header_as_string(nh->nh_home, (void *) sip->sip_via); if (sip->sip_expires && sip->sip_expires->ex_delta > 31536000) { sip->sip_expires->ex_delta = 31536000; @@ -2256,7 +2257,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, } else { sip_accept_t *ap = sip->sip_accept; char accept[256] = ""; - full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent); + full_agent = sip_header_as_string(nh->nh_home, (void *) sip->sip_user_agent); while (ap) { switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : ""); ap = ap->ac_next; @@ -2342,7 +2343,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, nua_respond(nh, SIP_202_ACCEPTED, TAG_IF(new_contactstr, SIPTAG_CONTACT_STR(new_contactstr)), - NUTAG_WITH_THIS(nua), + NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EXPIRES_STR(exp_delta_str), TAG_IF(sticky, NUTAG_PROXY(sticky)), TAG_END()); switch_safe_free(new_contactstr); @@ -2354,7 +2355,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, char *p = NULL; if (sip->sip_call_info) { - full_call_info = sip_header_as_string(profile->home, (void *) sip->sip_call_info); + full_call_info = sip_header_as_string(nh->nh_home, (void *) sip->sip_call_info); if ((p = strchr(full_call_info, ';'))) { p++; } @@ -2382,7 +2383,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE); } - su_free(profile->home, full_call_info); + su_free(nh->nh_home, full_call_info); } @@ -2392,7 +2393,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, char *p; if (sip->sip_call_info) { - full_call_info = sip_header_as_string(profile->home, (void *) sip->sip_call_info); + full_call_info = sip_header_as_string(nh->nh_home, (void *) sip->sip_call_info); if ((p = strchr(full_call_info, ';'))) { p++; } @@ -2424,7 +2425,7 @@ void sofia_presence_handle_sip_i_subscribe(int status, sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE); sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE); - su_free(profile->home, full_call_info); + su_free(nh->nh_home, full_call_info); } } else if (!strcasecmp(event, "call-info")) { sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE); @@ -2499,17 +2500,17 @@ void sofia_presence_handle_sip_i_subscribe(int status, if (event) { - su_free(profile->home, event); + su_free(nh->nh_home, event); } if (full_from) { - su_free(profile->home, full_from); + su_free(nh->nh_home, full_from); } if (full_via) { - su_free(profile->home, full_via); + su_free(nh->nh_home, full_via); } if (full_agent) { - su_free(profile->home, full_agent); + su_free(nh->nh_home, full_agent); } switch_safe_free(d_user); @@ -2538,6 +2539,7 @@ sofia_gateway_subscription_t *sofia_find_gateway_subscription(sofia_gateway_t *g void sofia_presence_handle_sip_r_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { sip_event_t const *o = NULL; @@ -2557,7 +2559,7 @@ void sofia_presence_handle_sip_r_subscribe(int status, /* the following could possibly be refactored back towards the calling event handler in sofia.c XXX MTK */ if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) { if (!strcasecmp(o->o_type, "dialog") && msg_params_find(o->o_params, "sla")) { - sofia_sla_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, tags); + sofia_sla_handle_sip_r_subscribe(status, phrase, nua, profile, nh, sofia_private, sip, de, tags); return; } } @@ -2604,21 +2606,26 @@ void sofia_presence_handle_sip_r_subscribe(int status, } } +struct cpc { + sofia_profile_t *profile; + sofia_dispatch_event_t *de; +}; + static int sofia_counterpath_crutch(void *pArg, int argc, char **argv, char **columnNames) { nua_handle_t *nh; - sofia_profile_t *profile = (sofia_profile_t *) pArg; + struct cpc *crutch = (struct cpc *) pArg; char *call_id = argv[0]; char *pl = argv[1]; char *event_type = argv[2]; long exp_delta = atol(argv[3]); - if ((nh = nua_handle_by_call_id(profile->nua, call_id))) { + if ((nh = nua_handle_by_call_id(crutch->profile->nua, call_id))) { char sstr[128] = "", expstr[128] = ""; switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta); switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", exp_delta); nua_notify(nh, - NUTAG_WITH_THIS(profile->nua), + NUTAG_WITH_THIS_MSG(crutch->de->data->e_msg), SIPTAG_EXPIRES_STR(expstr), SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EVENT_STR(event_type), SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END()); @@ -2641,6 +2648,7 @@ uint32_t sofia_presence_contact_count(sofia_profile_t *profile, const char *cont } void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { @@ -2669,12 +2677,12 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) { /* also it probably is unsafe to dereference so many things in a row without testing XXX MTK */ if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) { - sofia_sla_handle_sip_i_publish(nua, profile, nh, sip, tags); + sofia_sla_handle_sip_i_publish(nua, profile, nh, sip, de, tags); return; } } - contact_str = sofia_glue_gen_contact_str(profile, sip, NULL); + contact_str = sofia_glue_gen_contact_str(profile, sip, de, NULL); if (from) { from_user = (char *) from->a_url->url_user; @@ -2704,7 +2712,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n char *open_closed = "", *note_txt = ""; if (sip->sip_user_agent) { - full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent); + full_agent = sip_header_as_string(nh->nh_home, (void *) sip->sip_user_agent); } if ((tuple = switch_xml_child(xml, "tuple")) && (status = switch_xml_child(tuple, "status")) @@ -2741,7 +2749,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n /* if (count > 1) let's not and say we did or all the clients who subscribe to their own presence will think they selves is offline */ - event_type = sip_header_as_string(profile->home, (void *) sip->sip_event); + event_type = sip_header_as_string(nh->nh_home, (void *) sip->sip_event); if (count < 2) { if ((sql = switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' " @@ -2760,10 +2768,14 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n } } else if (contact_str) { + struct cpc crutch; + + crutch.profile = profile; + crutch.de = de; sql = switch_mprintf("select call_id,'%q','%q','%ld' from sip_subscriptions where sub_to_user='%q' and sub_to_host='%q' " "and contact = '%q' ", payload->pl_data ? payload->pl_data : "", event_type, exp_delta, from_user, from_host, contact_str); - sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_counterpath_crutch, profile); + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_counterpath_crutch, &crutch); switch_safe_free(sql); } @@ -2781,11 +2793,11 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n } if (event_type) { - su_free(profile->home, event_type); + su_free(nh->nh_home, event_type); } if (full_agent) { - su_free(profile->home, full_agent); + su_free(nh->nh_home, full_agent); } switch_xml_free(xml); @@ -2802,9 +2814,9 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n switch_stun_random_string(etag, 8, NULL); if (sub_count > 0) { - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END()); } else { - nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } switch_safe_free(contact_str); @@ -2820,6 +2832,7 @@ void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip) void sofia_presence_handle_sip_i_message(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { if (sip) { @@ -2866,7 +2879,7 @@ void sofia_presence_handle_sip_i_message(int status, char *full_from; char proto[512] = SOFIA_CHAT_PROTO; - full_from = sip_header_as_string(profile->home, (void *) sip->sip_from); + full_from = sip_header_as_string(nh->nh_home, (void *) sip->sip_from); if ((p = strchr(to_user, '+'))) { switch_copy_string(proto, to_user, sizeof(proto)); @@ -2911,7 +2924,7 @@ void sofia_presence_handle_sip_i_message(int status, switch_safe_free(to_addr); switch_safe_free(from_addr); if (full_from) { - su_free(profile->home, full_from); + su_free(nh->nh_home, full_from); } } } diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 730576f949..5fb5089d66 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -875,7 +875,8 @@ switch_console_callback_match_t *sofia_reg_find_reg_url_multi(sofia_profile_t *p } -void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_regtype_t regtype, const char *realm, int stale) +void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_dispatch_event_t *de, + sofia_regtype_t regtype, const char *realm, int stale) { switch_uuid_t uuid; char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; @@ -895,9 +896,9 @@ void sofia_reg_auth_challenge(nua_t *nua, sofia_profile_t *profile, nua_handle_t auth_str = switch_mprintf("Digest realm=\"%q\", nonce=\"%q\",%s algorithm=MD5, qop=\"auth\"", realm, uuid_str, stale ? " stale=true," : ""); if (regtype == REG_REGISTER) { - nua_respond(nh, SIP_401_UNAUTHORIZED, TAG_IF(nua, NUTAG_WITH_THIS(nua)), SIPTAG_WWW_AUTHENTICATE_STR(auth_str), TAG_END()); + nua_respond(nh, SIP_401_UNAUTHORIZED, TAG_IF((nua && de), NUTAG_WITH_THIS_MSG(de->data->e_msg)), SIPTAG_WWW_AUTHENTICATE_STR(auth_str), TAG_END()); } else if (regtype == REG_INVITE) { - nua_respond(nh, SIP_407_PROXY_AUTH_REQUIRED, TAG_IF(nua, NUTAG_WITH_THIS(nua)), SIPTAG_PROXY_AUTHENTICATE_STR(auth_str), TAG_END()); + nua_respond(nh, SIP_407_PROXY_AUTH_REQUIRED, TAG_IF((nua && de), NUTAG_WITH_THIS_MSG(de->data->e_msg)), SIPTAG_PROXY_AUTHENTICATE_STR(auth_str), TAG_END()); } switch_safe_free(auth_str); @@ -916,7 +917,8 @@ uint32_t sofia_reg_reg_count(sofia_profile_t *profile, const char *user, const c return atoi(buf); } -uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, sofia_regtype_t regtype, char *key, +uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, + sofia_dispatch_event_t *de, sofia_regtype_t regtype, char *key, uint32_t keylen, switch_event_t **v_event, const char *is_nat) { sip_to_t const *to = NULL; @@ -976,11 +978,11 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand /* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */ switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL); - sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port); + sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port); snprintf(network_port_c, sizeof(network_port_c), "%d", network_port); - snprintf(url_ip, sizeof(url_ip), (msg_addrinfo(nua_current_request(nua)))->ai_addr->sa_family == AF_INET6 ? "[%s]" : "%s", network_ip); + snprintf(url_ip, sizeof(url_ip), (msg_addrinfo(de->data->e_msg))->ai_addr->sa_family == AF_INET6 ? "[%s]" : "%s", network_ip); expires = sip->sip_expires; authorization = sip->sip_authorization; @@ -1011,7 +1013,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can not do authorization without a complete header in REGISTER request from %s:%d\n", network_ip, network_port); - nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); switch_goto_int(r, 1, end); } @@ -1139,7 +1141,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand char *v_contact_str = NULL; const char *username = "unknown"; const char *realm = reg_host; - if ((auth_res = sofia_reg_parse_auth(profile, authorization, sip, sip->sip_request->rq_method_name, + if ((auth_res = sofia_reg_parse_auth(profile, authorization, sip, de, sip->sip_request->rq_method_name, key, keylen, network_ip, v_event, exptime, regtype, to_user, &auth_params, ®_count)) == AUTH_STALE) { stale = 1; } @@ -1270,10 +1272,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand if (auth_res != AUTH_OK && !stale) { if (auth_res == AUTH_FORBIDDEN) { - nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); forbidden = 1; } else { - nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_401_UNAUTHORIZED, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } if (profile->debug) { @@ -1317,7 +1319,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand realm = from_host; } - sofia_reg_auth_challenge(nua, profile, nh, regtype, realm, stale); + sofia_reg_auth_challenge(nua, profile, nh, de, regtype, realm, stale); if (profile->debug) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send challenge for [%s@%s]\n", to_user, to_host); @@ -1639,7 +1641,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand switch_rfc822_date(date, switch_micro_time_now()); nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(sip->sip_contact), - TAG_IF(path_val, SIPTAG_PATH_STR(path_val)), NUTAG_WITH_THIS(nua), SIPTAG_DATE_STR(date), TAG_END()); + TAG_IF(path_val, SIPTAG_PATH_STR(path_val)), NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_DATE_STR(date), TAG_END()); if (s_event) { switch_event_fire(&s_event); @@ -1650,7 +1652,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand } if (*contact_str && sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE_SYLANTRO)) { - sofia_sla_handle_register(nua, profile, sip, exptime, contact_str); + sofia_sla_handle_register(nua, profile, sip, de, exptime, contact_str); } switch_goto_int(r, 1, end); @@ -1670,6 +1672,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { char key[128] = ""; @@ -1692,7 +1695,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h } #endif - sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port); + sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port); if (!(sip->sip_contact && sip->sip_contact->m_url)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT! ip: %s, port: %i\n", network_ip, network_port); @@ -1701,7 +1704,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h } if (!(profile->mflags & MFLAG_REGISTER)) { - nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); goto end; } @@ -1765,7 +1768,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h type = REG_AUTO_REGISTER; } else if (!ok) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "IP %s Rejected by register acl \"%s\"\n", network_ip, profile->reg_acl[x]); - nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_403_FORBIDDEN, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); goto end; } } @@ -1783,7 +1786,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h is_nat = NULL; } - sofia_reg_handle_register(nua, profile, nh, sip, type, key, sizeof(key), &v_event, is_nat); + sofia_reg_handle_register(nua, profile, nh, sip, de, type, key, sizeof(key), &v_event, is_nat); if (v_event) { switch_event_destroy(&v_event); @@ -1799,6 +1802,7 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h void sofia_reg_handle_sip_r_register(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { if (status >= 500) { @@ -1867,7 +1871,8 @@ void sofia_reg_handle_sip_r_register(int status, void sofia_reg_handle_sip_r_challenge(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, - switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip, tagi_t tags[]) + switch_core_session_t *session, sofia_gateway_t *gateway, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { sip_www_authenticate_t const *authenticate = NULL; char const *realm = NULL; @@ -2066,6 +2071,7 @@ static int sofia_reg_regcount_callback(void *pArg, int argc, char **argv, char * auth_res_t sofia_reg_parse_auth(sofia_profile_t *profile, sip_authorization_t const *authorization, sip_t const *sip, + sofia_dispatch_event_t *de, const char *regstr, char *np, size_t nplen, diff --git a/src/mod/endpoints/mod_sofia/sofia_sla.c b/src/mod/endpoints/mod_sofia/sofia_sla.c index 05eba011bb..bd79920d1a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_sla.c +++ b/src/mod/endpoints/mod_sofia/sofia_sla.c @@ -68,7 +68,8 @@ int sofia_sla_supported(sip_t const *sip) } -void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip, long exptime, const char *full_contact) +void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip, + sofia_dispatch_event_t *de, long exptime, const char *full_contact) { nua_handle_t *nh = NULL; char exp_str[256] = ""; @@ -83,7 +84,7 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const char *route_uri = NULL; char port_str[25] = ""; - sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port); + sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port); sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'", mod_sofia_globals.hostname, profile->name, contact_str); @@ -137,13 +138,15 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const free(contact_str); } -void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]) +void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { /* at present there's no SLA versions that we deal with that do publish. to be safe, we say "OK" */ - nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END()); } -void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]) +void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { char *aor = NULL; char *subscriber = NULL; @@ -156,7 +159,7 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url); - sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port); + sofia_glue_get_addr(de->data->e_msg, network_ip, sizeof(network_ip), &network_port); /* * XXX MTK FIXME - we don't look at the tag to see if NUTAG_SUBSTATE(nua_substate_terminated) or * a Subscription-State header with state "terminated" and/or expiration of 0. So we never forget @@ -225,7 +228,7 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia sla_contact = switch_mprintf("", profile->sla_contact, profile->sipip, port_str, sofia_glue_transport2str(transport)); } - nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(sla_contact), NUTAG_WITH_THIS(nua), TAG_IF(route_uri, NUTAG_PROXY(route_uri)), SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* you thought the OTHER time was fake... need delta here FIXME XXX MTK */ + nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(sla_contact), NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_IF(route_uri, NUTAG_PROXY(route_uri)), SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* you thought the OTHER time was fake... need delta here FIXME XXX MTK */ SIPTAG_EXPIRES_STR("300"), /* likewise, totally fake - FIXME XXX MTK */ /* sofia_presence says something about needing TAG_IF(sticky, NUTAG_PROXY(sticky)) for NAT stuff? */ TAG_END()); @@ -245,6 +248,7 @@ struct sla_notify_helper { void sofia_sla_handle_sip_r_subscribe(int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { if (status >= 300) { @@ -270,7 +274,8 @@ void sofia_sla_handle_sip_r_subscribe(int status, } } -void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]) +void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, + sofia_dispatch_event_t *de, tagi_t tags[]) { char *sql = NULL; struct sla_notify_helper helper; diff --git a/src/switch_core_memory.c b/src/switch_core_memory.c index 7e6abf9c77..8af979bdb6 100644 --- a/src/switch_core_memory.c +++ b/src/switch_core_memory.c @@ -80,8 +80,8 @@ SWITCH_DECLARE(void *) switch_core_perform_session_alloc(switch_core_session_t * #ifdef DEBUG_ALLOC if (memory > 500) - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_CONSOLE, "Session Allocate %d\n", - (int) memory); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Session Allocate %s %d\n", + apr_pool_tag(session->pool, NULL), (int) memory); #endif ptr = apr_palloc(session->pool, memory); @@ -113,7 +113,8 @@ SWITCH_DECLARE(void *) switch_core_perform_permanent_alloc(switch_size_t memory, #endif #ifdef DEBUG_ALLOC - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %d\n", (int) memory); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %s %d\n", + apr_pool_tag(memory_manager.memory_pool, NULL), (int) memory); #endif ptr = apr_palloc(memory_manager.memory_pool, memory); @@ -154,7 +155,8 @@ SWITCH_DECLARE(char *) switch_core_perform_permanent_strdup(const char *todup, c switch_assert(duped != NULL); #ifdef DEBUG_ALLOC - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %d\n", (int) len); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %s %d\n", + apr_pool_tag(memory_manager.memory_pool, NULL), (int) len); #endif #ifdef LOCK_MORE @@ -221,12 +223,13 @@ SWITCH_DECLARE(char *) switch_core_sprintf(switch_memory_pool_t *pool, const cha SWITCH_DECLARE(char *) switch_core_perform_session_strdup(switch_core_session_t *session, const char *todup, const char *file, const char *func, int line) { char *duped = NULL; - switch_assert(session != NULL); - switch_assert(session->pool != NULL); #ifdef DEBUG_ALLOC switch_size_t len; #endif + switch_assert(session != NULL); + switch_assert(session->pool != NULL); + if (!todup) { return NULL; } @@ -245,8 +248,8 @@ SWITCH_DECLARE(char *) switch_core_perform_session_strdup(switch_core_session_t #ifdef DEBUG_ALLOC len = strlen(todup); if (len > 500) - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(session), SWITCH_LOG_CONSOLE, "Sess Strdup Allocate %d\n", - (int) len); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Sess Strdup Allocate %s %ld\n", + apr_pool_tag(session->pool, NULL), strlen(todup)); #endif duped = apr_pstrdup(session->pool, todup); @@ -284,7 +287,8 @@ SWITCH_DECLARE(char *) switch_core_perform_strdup(switch_memory_pool_t *pool, co #ifdef DEBUG_ALLOC if (len > 500) - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "core strdup Allocate %d\n", (int) len); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Core Strdup Allocate %s %d\n", + apr_pool_tag(pool, NULL), (int)len); #endif duped = apr_pstrmemdup(pool, todup, len); @@ -392,12 +396,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memor #endif #endif -#ifdef DEBUG_ALLOC2 - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "New Pool\n"); -#endif tmp = switch_core_sprintf(*pool, "%s:%d", file, line); apr_pool_tag(*pool, tmp); +#ifdef DEBUG_ALLOC2 + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "New Pool %s\n", apr_pool_tag(*pool, NULL)); +#endif + #ifdef USE_MEM_LOCK switch_mutex_unlock(memory_manager.mem_lock); @@ -453,7 +458,8 @@ SWITCH_DECLARE(void *) switch_core_perform_alloc(switch_memory_pool_t *pool, swi #ifdef DEBUG_ALLOC if (memory > 500) - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Core Allocate %d\n", (int) memory); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Core Allocate %s %d\n", + apr_pool_tag(pool, NULL), (int) memory); /*switch_assert(memory < 20000); */ #endif diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 89a78f51e3..9b20347fe3 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -669,10 +669,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_perform_receive_message(swit goto end; } - if (switch_channel_down(session->channel)) { - switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line, - switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "%s skip receive message [%s] (channel is hungup already)\n", - switch_channel_get_name(session->channel), message_names[message->message_id]); + if (switch_channel_down(session->channel) && message->message_id != SWITCH_MESSAGE_INDICATE_SIGNAL_DATA) { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, message->_file, message->_func, message->_line, + switch_core_session_get_uuid(session), SWITCH_LOG_DEBUG, "%s skip receive message [%s] (channel is hungup already)\n", + switch_channel_get_name(session->channel), message_names[message->message_id]); } else if (session->endpoint_interface->io_routines->receive_message) { status = session->endpoint_interface->io_routines->receive_message(session, message); diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 6551b2b777..3c8bd28c55 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -401,6 +401,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) if (endstate == switch_channel_get_running_state(session->channel)) { if (endstate == CS_NEW) { switch_cond_next(); + switch_ivr_parse_all_events(session); if (!--new_loops) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s Timeout waiting for next instruction in CS_NEW!\n", session->uuid_str);