diff options
Diffstat (limited to 'res')
-rw-r--r-- | res/res_pjproject.c | 2 | ||||
-rw-r--r-- | res/res_pjsip/location.c | 5 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_configuration.c | 2 | ||||
-rw-r--r-- | res/res_pjsip_exten_state.c | 7 | ||||
-rw-r--r-- | res/res_pjsip_outbound_registration.c | 6 | ||||
-rw-r--r-- | res/res_pjsip_session.c | 90 | ||||
-rw-r--r-- | res/res_pjsip_t38.c | 13 | ||||
-rw-r--r-- | res/stasis/app.c | 9 | ||||
-rw-r--r-- | res/stasis/messaging.c | 12 |
9 files changed, 94 insertions, 52 deletions
diff --git a/res/res_pjproject.c b/res/res_pjproject.c index 86b2502e5..6137898a3 100644 --- a/res/res_pjproject.c +++ b/res/res_pjproject.c @@ -234,7 +234,7 @@ static void capture_buildopts_cb(int level, const char *data, int len) } dup = ast_strdup(ast_skip_blanks(data)); - if (AST_VECTOR_ADD_SORTED(&buildopts, dup, strcmp)) { + if (dup && AST_VECTOR_ADD_SORTED(&buildopts, dup, strcmp)) { ast_free(dup); } } diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index 9945c7c10..0d7b3da31 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -1219,6 +1219,11 @@ static int contact_apply_handler(const struct ast_sorcery *sorcery, void *object struct ast_sip_contact_status *status; struct ast_sip_contact *contact = object; + if (ast_strlen_zero(contact->uri)) { + ast_log(LOG_ERROR, "A URI on dynamic contact '%s' is empty\n", + ast_sorcery_object_get_id(contact)); + return -1; + } status = ast_res_pjsip_find_or_create_contact_status(contact); ao2_cleanup(status); diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index a6afe5e53..168d86989 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -508,6 +508,8 @@ int ast_sip_auth_vector_init(struct ast_sip_auth_vector *auths, const char *valu goto failure; } if (AST_VECTOR_APPEND(auths, val)) { + ast_free(val); + goto failure; } } diff --git a/res/res_pjsip_exten_state.c b/res/res_pjsip_exten_state.c index 95a40829e..3e756134c 100644 --- a/res/res_pjsip_exten_state.c +++ b/res/res_pjsip_exten_state.c @@ -729,8 +729,11 @@ static int exten_state_publisher_state_cb(const char *context, const char *exten } ao2_ref(publisher, +1); - AST_VECTOR_APPEND(&pub_data->pubs, publisher); - ast_debug(5, "'%s' will publish exten state\n", publisher->name); + if (AST_VECTOR_APPEND(&pub_data->pubs, publisher)) { + ao2_ref(publisher, -1); + } else { + ast_debug(5, "'%s' will publish exten state\n", publisher->name); + } } ao2_iterator_destroy(&publisher_iter); diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c index 7fa6e2c10..d9afcd284 100644 --- a/res/res_pjsip_outbound_registration.c +++ b/res/res_pjsip_outbound_registration.c @@ -1385,10 +1385,10 @@ static int sip_outbound_registration_perform(void *data) AST_VECTOR_INIT(&state->client_state->outbound_auths, AST_VECTOR_SIZE(®istration->outbound_auths)); for (i = 0; i < AST_VECTOR_SIZE(®istration->outbound_auths); ++i) { - const char *name = ast_strdup(AST_VECTOR_GET(®istration->outbound_auths, i)); + char *name = ast_strdup(AST_VECTOR_GET(®istration->outbound_auths, i)); - if (name) { - AST_VECTOR_APPEND(&state->client_state->outbound_auths, name); + if (name && AST_VECTOR_APPEND(&state->client_state->outbound_auths, name)) { + ast_free(name); } } state->client_state->retry_interval = registration->retry_interval; diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index dda0421b5..781d3e4eb 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -691,7 +691,10 @@ static int handle_incoming_sdp(struct ast_sip_session *session, const pjmedia_sd if (!stream) { return -1; } - ast_stream_topology_set_stream(session->pending_media_state->topology, i, stream); + if (ast_stream_topology_set_stream(session->pending_media_state->topology, i, stream)) { + ast_stream_free(stream); + return -1; + } } session_media = ast_sip_session_media_state_add(session, session->pending_media_state, ast_media_type_from_str(media), i); @@ -1762,7 +1765,10 @@ static int sdp_requires_deferral(struct ast_sip_session *session, const pjmedia_ /* As this is only called on an incoming SDP offer before processing it is not possible * for streams and their media sessions to exist. */ - ast_stream_topology_set_stream(session->pending_media_state->topology, i, stream); + if (ast_stream_topology_set_stream(session->pending_media_state->topology, i, stream)) { + ast_stream_free(stream); + return -1; + } session_media = ast_sip_session_media_state_add(session, session->pending_media_state, ast_media_type_from_str(media), i); if (!session_media) { @@ -3476,6 +3482,36 @@ static void session_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e) /* XXX STUB */ } +static int session_end_if_disconnected(int id, pjsip_inv_session *inv) +{ + struct ast_sip_session *session; + + if (inv->state != PJSIP_INV_STATE_DISCONNECTED) { + return 0; + } + + /* + * We are locking because ast_sip_dialog_get_session() needs + * the dialog locked to get the session by other threads. + */ + pjsip_dlg_inc_lock(inv->dlg); + session = inv->mod_data[id]; + inv->mod_data[id] = NULL; + pjsip_dlg_dec_lock(inv->dlg); + + /* + * Pass the session ref held by session->inv_session to + * session_end_completion(). + */ + if (session + && ast_sip_push_task(session->serializer, session_end_completion, session)) { + /* Do it anyway even though this is not the right thread. */ + session_end_completion(session); + } + + return 1; +} + static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e) { ast_sip_session_response_cb cb; @@ -3500,6 +3536,17 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans /* The session has ended. Ignore the transaction change. */ return; } + + /* + * If the session is disconnected really nothing else to do unless currently transacting + * a BYE. If a BYE then hold off destruction until the transaction timeout occurs. This + * has to be done for BYEs because sometimes the dialog can be in a disconnected + * state but the BYE request transaction has not yet completed. + */ + if (tsx->method.id != PJSIP_BYE_METHOD && session_end_if_disconnected(id, inv)) { + return; + } + switch (e->body.tsx_state.type) { case PJSIP_EVENT_TX_MSG: /* When we create an outgoing request, we do not have access to the transaction that @@ -3622,49 +3669,12 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans } break; case PJSIP_EVENT_TRANSPORT_ERROR: - if (inv->state == PJSIP_INV_STATE_DISCONNECTED) { - /* - * Clear the module data now to block session_inv_on_state_changed() - * from calling session_end() if it hasn't already done so. - */ - inv->mod_data[id] = NULL; - - /* - * Pass the session ref held by session->inv_session to - * session_end_completion(). - */ - if (session - && ast_sip_push_task(session->serializer, session_end_completion, session)) { - /* Do it anyway even though this is not the right thread. */ - session_end_completion(session); - } - return; - } - break; case PJSIP_EVENT_TIMER: /* * The timer event is run by the pjsip monitor thread and not * by the session serializer. */ - if (inv->state == PJSIP_INV_STATE_DISCONNECTED) { - /* - * We are locking because ast_sip_dialog_get_session() needs - * the dialog locked to get the session by other threads. - */ - pjsip_dlg_inc_lock(inv->dlg); - session = inv->mod_data[id]; - inv->mod_data[id] = NULL; - pjsip_dlg_dec_lock(inv->dlg); - - /* - * Pass the session ref held by session->inv_session to - * session_end_completion(). - */ - if (session - && ast_sip_push_task(session->serializer, session_end_completion, session)) { - /* Do it anyway even though this is not the right thread. */ - session_end_completion(session); - } + if (session_end_if_disconnected(id, inv)) { return; } break; diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c index 48cbab37b..8f1905f6e 100644 --- a/res/res_pjsip_t38.c +++ b/res/res_pjsip_t38.c @@ -363,7 +363,11 @@ static struct ast_sip_session_media_state *t38_create_media_state(struct ast_sip } ast_stream_set_state(stream, AST_STREAM_STATE_SENDRECV); - ast_stream_topology_set_stream(media_state->topology, 0, stream); + if (ast_stream_topology_set_stream(media_state->topology, 0, stream)) { + ast_stream_free(stream); + ast_sip_session_media_state_free(media_state); + return NULL; + } caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT); if (!caps) { @@ -371,9 +375,14 @@ static struct ast_sip_session_media_state *t38_create_media_state(struct ast_sip return NULL; } - ast_format_cap_append(caps, ast_format_t38, 0); ast_stream_set_formats(stream, caps); + /* stream holds a reference to cap, release the local reference + * now so we don't have to deal with it in the error condition. */ ao2_ref(caps, -1); + if (ast_format_cap_append(caps, ast_format_t38, 0)) { + ast_sip_session_media_state_free(media_state); + return NULL; + } session_media = ast_sip_session_media_state_add(session, media_state, AST_MEDIA_TYPE_IMAGE, 0); if (!session_media) { diff --git a/res/stasis/app.c b/res/stasis/app.c index 0b44bf3c6..a1ef5c0b6 100644 --- a/res/stasis/app.c +++ b/res/stasis/app.c @@ -588,6 +588,7 @@ static int message_received_handler(const char *endpoint_id, struct ast_json *js { RAII_VAR(struct ast_endpoint_snapshot *, snapshot, NULL, ao2_cleanup); struct ast_json *json_endpoint; + struct ast_json *message; struct stasis_app *app = pvt; char *tech; char *resource; @@ -613,11 +614,15 @@ static int message_received_handler(const char *endpoint_id, struct ast_json *js return -1; } - app_send(app, ast_json_pack("{s: s, s: o, s: o, s: o}", + message = ast_json_pack("{s: s, s: o, s: o, s: o}", "type", "TextMessageReceived", "timestamp", ast_json_timeval(ast_tvnow(), NULL), "endpoint", json_endpoint, - "message", ast_json_ref(json_msg))); + "message", ast_json_ref(json_msg)); + if (message) { + app_send(app, message); + ast_json_unref(message); + } return 0; } diff --git a/res/stasis/messaging.c b/res/stasis/messaging.c index d398bb6d4..77a58745a 100644 --- a/res/stasis/messaging.c +++ b/res/stasis/messaging.c @@ -457,7 +457,11 @@ static struct message_subscription *get_or_create_subscription(struct ast_endpoi ao2_link(endpoint_subscriptions, sub); } else { ast_rwlock_wrlock(&tech_subscriptions_lock); - AST_VECTOR_APPEND(&tech_subscriptions, ao2_bump(sub)); + if (AST_VECTOR_APPEND(&tech_subscriptions, ao2_bump(sub))) { + /* Release the ao2_bump that was for the vector and allocation references. */ + ao2_ref(sub, -2); + sub = NULL; + } ast_rwlock_unlock(&tech_subscriptions_lock); } @@ -485,7 +489,11 @@ int messaging_app_subscribe_endpoint(const char *app_name, struct ast_endpoint * ao2_unlock(sub); return -1; } - AST_VECTOR_APPEND(&sub->applications, tuple); + if (AST_VECTOR_APPEND(&sub->applications, tuple)) { + ao2_ref(tuple, -1); + ao2_unlock(sub); + return -1; + } ao2_unlock(sub); ast_debug(3, "App '%s' subscribed to messages from endpoint '%s'\n", app_name, endpoint ? ast_endpoint_get_id(endpoint) : "-- ALL --"); |