diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 170a19151a70d47aadf75bc53384c0be51d13b95..c13369ff5f349e93b44a7d32fb9f4b2266159235 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -2859,6 +2859,7 @@ static int create_out_of_dialog_request(const pjsip_method *method, struct ast_s pj_pool_t *pool; pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, }; pjsip_uri *sip_uri; + const char *fromuser; if (ast_strlen_zero(uri)) { if (!endpoint && (!contact || ast_strlen_zero(contact->uri))) { @@ -2905,7 +2906,8 @@ static int create_out_of_dialog_request(const pjsip_method *method, struct ast_s return -1; } - if (sip_dialog_create_from(pool, &from, endpoint ? endpoint->fromuser : NULL, + fromuser = endpoint ? (!ast_strlen_zero(endpoint->fromuser) ? endpoint->fromuser : ast_sorcery_object_get_id(endpoint)) : NULL; + if (sip_dialog_create_from(pool, &from, fromuser, endpoint ? endpoint->fromdomain : NULL, &remote_uri, &selector)) { ast_log(LOG_ERROR, "Unable to create From header for %.*s request to endpoint %s\n", (int) pj_strlen(&method->name), pj_strbuf(&method->name), @@ -3200,6 +3202,7 @@ static pj_status_t endpt_send_request(struct ast_sip_endpoint *endpoint, struct send_request_wrapper *req_wrapper; pj_status_t ret_val; pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint(); + pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, }; /* Create wrapper to detect if the callback was actually called on an error. */ req_wrapper = ao2_alloc(sizeof(*req_wrapper), send_request_wrapper_destructor); @@ -3250,6 +3253,11 @@ static pj_status_t endpt_send_request(struct ast_sip_endpoint *endpoint, */ ao2_ref(req_wrapper, +1); + if (endpoint) { + sip_get_tpselector_from_endpoint(endpoint, &selector); + pjsip_tx_data_set_transport(tdata, &selector); + } + ret_val = pjsip_endpt_send_request(endpt, tdata, -1, req_wrapper, endpt_send_request_cb); if (ret_val != PJ_SUCCESS) { char errmsg[PJ_ERR_MSG_SIZE]; diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c index 4cce558367800eddda55cda89866f73b0ee64267..e12481a147cde75a8ce612115dac5fed19895f9f 100644 --- a/res/res_pjsip/pjsip_options.c +++ b/res/res_pjsip/pjsip_options.c @@ -237,31 +237,12 @@ static void init_start_time(const struct ast_sip_contact *contact) /*! * \internal - * \brief Match a container contact object with the contact sorcery id looking for. - * - * \param obj pointer to the (user-defined part) of an object. - * \param arg callback argument from ao2_callback() - * \param flags flags from ao2_callback() - * - * \return Values are a combination of enum _cb_results. - */ -static int match_contact_id(void *obj, void *arg, int flags) -{ - struct ast_sip_contact *contact = obj; - const char *looking_for = arg; - - return strcmp(ast_sorcery_object_get_id(contact), looking_for) ? 0 : CMP_MATCH; -} - -/*! - * \internal - * \brief For an endpoint try to match the given contact sorcery id. + * \brief For an endpoint try to match the given contact->aor. */ static int on_endpoint(void *obj, void *arg, int flags) { struct ast_sip_endpoint *endpoint = obj; - struct ast_sip_contact *contact; - char *looking_for = arg; + char *contact_aor = arg; char *aor_name; char *aors; @@ -271,24 +252,7 @@ static int on_endpoint(void *obj, void *arg, int flags) aors = ast_strdupa(endpoint->aors); while ((aor_name = ast_strip(strsep(&aors, ",")))) { - struct ast_sip_aor *aor; - struct ao2_container *contacts; - - aor = ast_sip_location_retrieve_aor(aor_name); - if (!aor) { - continue; - } - - contacts = ast_sip_location_retrieve_aor_contacts(aor); - ao2_ref(aor, -1); - if (!contacts) { - continue; - } - - contact = ao2_callback(contacts, 0, match_contact_id, looking_for); - ao2_ref(contacts, -1); - if (contact) { - ao2_ref(contact, -1); + if (!strcmp(contact_aor, aor_name)) { return CMP_MATCH; } } @@ -302,12 +266,26 @@ static int on_endpoint(void *obj, void *arg, int flags) */ static struct ast_sip_endpoint *find_an_endpoint(struct ast_sip_contact *contact) { - char *looking_for = (char *) ast_sorcery_object_get_id(contact); - struct ao2_container *endpoints = ast_sip_get_endpoints(); + struct ao2_container *endpoints; struct ast_sip_endpoint *endpoint; + struct ast_variable *var; + char *aor = ast_alloca(strlen(contact->aor) + 3); + + sprintf(aor, "%%%s%%", contact->aor); + var = ast_variable_new("aors LIKE", aor, ""); + endpoints = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), + "endpoint", AST_RETRIEVE_FLAG_MULTIPLE, var); + + ast_variables_destroy(var); - endpoint = ao2_callback(endpoints, 0, on_endpoint, looking_for); + /* + * Because aors are a string list, we have to use a pattern match but since a simple + * pattern match could return an endpoint that has an aor of "aaabccc" when searching + * for "abc", we still have to iterate over them to find an exact aor match. + */ + endpoint = ao2_callback(endpoints, 0, on_endpoint, (char *)contact->aor); ao2_ref(endpoints, -1); + return endpoint; } @@ -346,23 +324,18 @@ static int qualify_contact(struct ast_sip_endpoint *endpoint, struct ast_sip_con pjsip_tx_data *tdata; RAII_VAR(struct ast_sip_endpoint *, endpoint_local, NULL, ao2_cleanup); - if (contact->authenticate_qualify) { + if (endpoint) { endpoint_local = ao2_bump(endpoint); + } else { + endpoint_local = find_an_endpoint(contact); if (!endpoint_local) { - /* - * Find the "first" endpoint to completely qualify the contact - any - * endpoint that is associated with the contact should do. - */ - endpoint_local = find_an_endpoint(contact); - if (!endpoint_local) { - ast_log(LOG_ERROR, "Unable to find an endpoint to qualify contact %s\n", - contact->uri); - return -1; - } + ast_log(LOG_ERROR, "Unable to find an endpoint to qualify contact %s\n", + contact->uri); + return -1; } } - if (ast_sip_create_request("OPTIONS", NULL, NULL, NULL, contact, &tdata)) { + if (ast_sip_create_request("OPTIONS", NULL, endpoint_local, NULL, contact, &tdata)) { ast_log(LOG_ERROR, "Unable to create request to qualify contact %s\n", contact->uri); return -1;