23 #include <pjsip_simple.h> 24 #include <pjsip/sip_transaction.h> 27 #include <pjmedia/errno.h> 3264 #define MOD_DATA_CONTACT "contact" 3267 #define SERIALIZER_POOL_SIZE 8 3292 time_t t = time(
NULL);
3295 strftime(date,
sizeof(date),
"%a, %d %b %Y %T GMT", &tm);
3302 pjsip_module **module = data;
3304 ast_log(
LOG_ERROR,
"There is no PJSIP endpoint. Unable to register services\n");
3308 ast_log(
LOG_ERROR,
"Unable to register module %.*s\n", (
int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
3311 ast_debug(1,
"Registered SIP service %.*s (%p)\n", (
int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name), *module);
3322 pjsip_module **module = data;
3327 ast_debug(1,
"Unregistered SIP service %.*s\n", (
int) pj_strlen(&(*module)->name), pj_strbuf(&(*module)->name));
3340 if (registered_authenticator) {
3341 ast_log(
LOG_WARNING,
"Authenticator %p is already registered. Cannot register a new one\n", registered_authenticator);
3344 registered_authenticator = auth;
3345 ast_debug(1,
"Registered SIP authenticator module %p\n", auth);
3352 if (registered_authenticator != auth) {
3353 ast_log(
LOG_WARNING,
"Trying to unregister authenticator %p but authenticator %p registered\n",
3354 auth, registered_authenticator);
3357 registered_authenticator =
NULL;
3358 ast_debug(1,
"Unregistered SIP authenticator %p\n", auth);
3364 && !pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_options_method)) {
3365 ast_debug(3,
"Skipping OPTIONS authentication due to endpoint configuration\n");
3369 if (!registered_authenticator) {
3370 ast_log(
LOG_WARNING,
"No SIP authenticator registered. Assuming authentication is not required\n");
3378 pjsip_rx_data *rdata, pjsip_tx_data *tdata)
3380 if (!registered_authenticator) {
3381 ast_log(
LOG_WARNING,
"No SIP authenticator registered. Assuming authentication is successful\n");
3391 if (registered_outbound_authenticator) {
3392 ast_log(
LOG_WARNING,
"Outbound authenticator %p is already registered. Cannot register a new one\n", registered_outbound_authenticator);
3395 registered_outbound_authenticator = auth;
3396 ast_debug(1,
"Registered SIP outbound authenticator module %p\n", auth);
3403 if (registered_outbound_authenticator != auth) {
3404 ast_log(
LOG_WARNING,
"Trying to unregister outbound authenticator %p but outbound authenticator %p registered\n",
3405 auth, registered_outbound_authenticator);
3408 registered_outbound_authenticator =
NULL;
3409 ast_debug(1,
"Unregistered SIP outbound authenticator %p\n", auth);
3413 pjsip_tx_data *old_request, pjsip_tx_data **new_request)
3415 if (!registered_outbound_authenticator) {
3416 ast_log(
LOG_WARNING,
"No SIP outbound authenticator registered. Cannot respond to authentication challenge\n");
3434 char *prev, *current, *identifier_order;
3438 id_list_item =
ast_calloc(1,
sizeof(*id_list_item));
3439 if (!id_list_item) {
3446 ast_debug(1,
"Register endpoint identifier %s(%p)\n", name ?:
"", identifier);
3465 while ((current = strchr(current,
','))) {
3467 if (!strncmp(prev, name, current - prev)
3468 && strlen(name) == current - prev) {
3476 if (!strcmp(prev, name)) {
3521 ast_debug(1,
"Unregistered endpoint identifier %p\n", identifier);
3545 pjsip_generic_string_hdr *hdr;
3548 hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str,
NULL);
3553 pj_strdup_with_null(rdata->tp_info.pool, &hdr_val, &hdr->hvalue);
3574 e->
command =
"pjsip dump endpt [details]";
3576 "Usage: pjsip dump endpt [details]\n" 3577 " Dump the res_pjsip endpt internals.\n" 3579 "Warning: PJPROJECT documents that the function used by this\n" 3580 "CLI command may cause a crash when asking for details because\n" 3581 "it tries to access all active memory pools.\n";
3589 e->
command =
"pjsip dump endpt";
3591 "Usage: pjsip dump endpt\n" 3592 " Dump the res_pjsip endpt internals.\n";
3600 || (a->
argc == 4 && strcasecmp(a->
argv[3],
"details"))) {
3611 #define ENDPOINT_IDENTIFIER_FORMAT "%-20.20s\n" 3616 e->
command =
"pjsip show identifiers";
3617 e->
usage =
"Usage: pjsip show identifiers\n" 3618 " List all registered endpoint identifiers\n";
3633 iter->
name ? iter->
name :
"name not specified");
3637 #undef ENDPOINT_IDENTIFIER_FORMAT 3646 e->
command =
"pjsip show settings";
3647 e->
usage =
"Usage: pjsip show settings\n" 3648 " Show global and system configuration options\n";
3656 ast_cli(a->
fd,
"Could not allocate output buffer.\n");
3662 ast_cli(a->
fd,
"Error retrieving settings.\n");
3724 pjsip_rx_data *rdata)
3730 if (uri->port == rdata->pkt_info.src_port
3731 && !pj_strcmp(&uri->host,
3732 pj_cstr(&host_name, rdata->pkt_info.src_name))
3734 && PJSIP_TRANSPORT_IS_RELIABLE(rdata->tp_info.transport)) {
3738 if (!strcasecmp(
"WSS", rdata->tp_info.transport->type_name)) {
3740 pj_cstr(&type_name,
"ws");
3742 pj_cstr(&type_name, rdata->tp_info.transport->type_name);
3745 if (!pj_stricmp(&uri->transport_param, &type_name)
3748 || !pj_stricmp(&uri->transport_param,
3749 pj_cstr(&type_name,
"ws")))) {
3763 pjsip_sip_uri *sip_uri,
char *
buf,
size_t buf_len)
3767 pjsip_param *x_transport;
3774 x_transport = pjsip_param_find(&sip_uri->other_param, &x_name);
3792 pjsip_tpselector *selector)
3795 pjsip_tpselector sel = { .type = PJSIP_TPSELECTOR_NONE, };
3797 uri = pjsip_uri_get_uri(dlg->target);
3804 pjsip_dlg_set_transport(dlg, selector);
3806 if (selector == &sel) {
3814 const char *
domain,
const pj_str_t *target, pjsip_tpselector *selector)
3816 pj_str_t
tmp, local_addr;
3818 pjsip_sip_uri *sip_uri;
3819 pjsip_transport_type_e
type;
3821 char default_user[PJSIP_MAX_URL_SIZE];
3825 user = default_user;
3829 pj_strdup_with_null(pool, &tmp, target);
3831 if (!(uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0)) ||
3832 (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
3836 sip_uri = pjsip_uri_get_uri(uri);
3839 type = pjsip_transport_get_type_from_name(&sip_uri->transport_param);
3840 if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) {
3841 if (type == PJSIP_TRANSPORT_UNSPECIFIED
3842 || !(pjsip_transport_get_flag_from_type(type) & PJSIP_TRANSPORT_SECURE)) {
3843 type = PJSIP_TRANSPORT_TLS;
3845 }
else if (!sip_uri->transport_param.slen) {
3846 type = PJSIP_TRANSPORT_UDP;
3847 }
else if (type == PJSIP_TRANSPORT_UNSPECIFIED) {
3852 if (pj_strchr(&sip_uri->host,
':')) {
3853 type |= PJSIP_TRANSPORT_IPV6;
3858 from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
3859 from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
3862 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ?
";transport=" :
"",
3863 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) :
"");
3868 from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
3869 from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
3873 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ?
";transport=" :
"",
3874 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) :
"");
3880 &local_addr, &local_port) != PJ_SUCCESS) {
3883 pj_strdup(pool, &local_addr, pj_gethostname());
3884 local_port = pjsip_transport_get_default_port_for_type(PJSIP_TRANSPORT_UDP);
3888 if (pj_strchr(&local_addr,
':')) {
3889 type |= PJSIP_TRANSPORT_IPV6;
3892 from->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
3893 from->slen = pj_ansi_snprintf(from->ptr, PJSIP_MAX_URL_SIZE,
3896 (type & PJSIP_TRANSPORT_IPV6) ?
"[" :
"",
3897 (
int)local_addr.slen,
3899 (type & PJSIP_TRANSPORT_IPV6) ?
"]" :
"",
3901 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ?
";transport=" :
"",
3902 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) :
"");
3913 if (!transport_state) {
3920 if (transport_state->
flow) {
3925 selector->type = PJSIP_TPSELECTOR_TRANSPORT;
3926 selector->u.transport = transport_state->
transport;
3927 pjsip_transport_add_ref(selector->u.transport);
3928 }
else if (transport_state->
factory) {
3929 selector->type = PJSIP_TPSELECTOR_LISTENER;
3930 selector->u.listener = transport_state->
factory;
3936 }
else if (transport->
flow) {
3938 #ifdef HAVE_PJSIP_TRANSPORT_DISABLE_CONNECTION_REUSE 3939 selector->disable_connection_reuse = PJ_TRUE;
3941 ast_log(
LOG_WARNING,
"Connection reuse could not be disabled on transport '%s' as support is not available\n",
3948 if (transport_state->
flow) {
3976 pjsip_sip_uri *sip_uri, pjsip_tpselector *selector)
3978 char transport_name[128];
3989 if (selector->type == PJSIP_TPSELECTOR_TRANSPORT && selector->u.transport) {
3990 pjsip_transport_dec_ref(selector->u.transport);
3996 pjsip_sip_uri *sip_uri;
3998 static const pj_str_t STR_PHONE = {
"phone", 5 };
4000 if (!endpoint || !endpoint->
usereqphone || (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri))) {
4004 sip_uri = pjsip_uri_get_uri(uri);
4006 if (!pj_strlen(&sip_uri->user)) {
4010 if (pj_strbuf(&sip_uri->user)[0] ==
'+') {
4015 for (; i < pj_strlen(&sip_uri->user); i++) {
4021 if (i < pj_strlen(&sip_uri->user)) {
4025 sip_uri->user_param = STR_PHONE;
4029 const char *uri,
const char *request_user)
4031 char enclosed_uri[PJSIP_MAX_URL_SIZE];
4034 pjsip_dialog *dlg =
NULL;
4036 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
4037 static const pj_str_t HCONTACT = {
"Contact", 7 };
4039 snprintf(enclosed_uri,
sizeof(enclosed_uri),
"<%s>", uri);
4040 pj_cstr(&remote_uri, enclosed_uri);
4042 pj_cstr(&target_uri, uri);
4044 res = pjsip_dlg_create_uac(pjsip_ua_instance(), &local_uri,
NULL, &remote_uri, &target_uri, &dlg);
4045 if (res == PJ_SUCCESS && !(PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target))) {
4048 res = PJSIP_EINVALIDURI;
4049 pjsip_dlg_terminate(dlg);
4051 if (res != PJ_SUCCESS) {
4052 if (res == PJSIP_EINVALIDURI) {
4054 "Endpoint '%s': Could not create dialog to invalid URI '%s'. Is endpoint registered and reachable?\n",
4067 pjsip_dlg_terminate(dlg);
4075 pj_strdup_with_null(dlg->pool, &dlg->local.info_str, &local_uri);
4076 dlg->local.info->uri = pjsip_parse_uri(dlg->pool, dlg->local.info_str.ptr, dlg->local.info_str.slen, 0);
4077 if (!dlg->local.info->uri) {
4079 "Could not parse URI '%s' for endpoint '%s'\n",
4082 pjsip_dlg_terminate(dlg);
4086 dlg->local.contact = pjsip_parse_hdr(dlg->pool, &HCONTACT, local_uri.ptr, local_uri.slen,
NULL);
4089 pjsip_sip_uri *sip_uri;
4091 sip_uri = pjsip_uri_get_uri(dlg->local.contact->uri);
4092 pj_strdup2(dlg->pool, &sip_uri->user, endpoint->
contact_user);
4097 pjsip_sip_uri *sip_uri;
4099 if (PJSIP_URI_SCHEME_IS_SIP(dlg->target) || PJSIP_URI_SCHEME_IS_SIPS(dlg->target)) {
4100 sip_uri = pjsip_uri_get_uri(dlg->target);
4101 pj_strdup2(dlg->pool, &sip_uri->user, request_user);
4103 if (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) || PJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri)) {
4104 sip_uri = pjsip_uri_get_uri(dlg->remote.info->uri);
4105 pj_strdup2(dlg->pool, &sip_uri->user, request_user);
4114 pjsip_route_hdr route_set, *route;
4115 static const pj_str_t ROUTE_HNAME = {
"Route", 5 };
4118 pj_list_init(&route_set);
4120 pj_strdup2_with_null(dlg->pool, &tmp, outbound_proxy);
4121 if (!(route = pjsip_parse_hdr(dlg->pool, &ROUTE_HNAME, tmp.ptr, tmp.slen,
NULL))) {
4122 ast_log(
LOG_ERROR,
"Could not create dialog to endpoint '%s' as outbound proxy URI '%s' is not valid\n",
4125 pjsip_dlg_terminate(dlg);
4128 pj_list_insert_nodes_before(&route_set, route);
4130 pjsip_dlg_set_route_set(dlg, &route_set);
4150 pjsip_rr_hdr *record_route;
4152 if (PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri)) {
4156 record_route = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_RECORD_ROUTE,
NULL);
4158 if (PJSIP_URI_SCHEME_IS_SIPS(&record_route->name_addr)) {
4164 contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
NULL);
4166 if (PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
4175 const pj_str_t *
contact, pjsip_dialog **p_dlg);
4182 pjsip_transport_type_e
type = rdata->tp_info.transport->key.type;
4183 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
4185 pjsip_contact_hdr *contact_hdr;
4189 contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
NULL);
4195 transport = rdata->tp_info.transport;
4196 if (selector.type == PJSIP_TPSELECTOR_TRANSPORT) {
4197 transport = selector.u.transport;
4199 type = transport->key.type;
4201 contact.ptr = pj_pool_alloc(rdata->tp_info.pool, PJSIP_MAX_URL_SIZE);
4202 contact.slen = pj_ansi_snprintf(contact.ptr, PJSIP_MAX_URL_SIZE,
4203 "<%s:%s%.*s%s:%d%s%s>",
4205 (type & PJSIP_TRANSPORT_IPV6) ?
"[" :
"",
4206 (
int)transport->local_name.host.slen,
4207 transport->local_name.host.ptr,
4208 (type & PJSIP_TRANSPORT_IPV6) ?
"]" :
"",
4209 transport->local_name.port,
4210 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ?
";transport=" :
"",
4211 (type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) :
"");
4213 *status = create_fun(pjsip_ua_instance(), rdata, &contact, &dlg);
4214 if (*status != PJ_SUCCESS) {
4215 char err[PJ_ERR_MSG_SIZE];
4217 pj_strerror(*status, err,
sizeof(err));
4225 pjsip_dlg_set_transport(dlg, &selector);
4235 #ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK 4238 dlg =
create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
4240 pjsip_dlg_dec_lock(dlg);
4250 pjsip_rx_data *rdata, pj_status_t *
status)
4252 #ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK 4253 return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
4264 pjsip_dlg_inc_lock(dlg);
4272 char *transport_type,
const char *local_name,
int local_port,
const char *
contact)
4280 pj_list_init(&rdata->msg_info.parse_err);
4282 rdata->tp_info.transport = PJ_POOL_ZALLOC_T(rdata->tp_info.pool, pjsip_transport);
4283 if (!rdata->tp_info.transport) {
4287 ast_copy_string(rdata->pkt_info.packet, packet,
sizeof(rdata->pkt_info.packet));
4288 ast_copy_string(rdata->pkt_info.src_name, src_name,
sizeof(rdata->pkt_info.src_name));
4289 rdata->pkt_info.src_port = src_port;
4290 pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&tmp, src_name), &rdata->pkt_info.src_addr);
4291 pj_sockaddr_set_port(&rdata->pkt_info.src_addr, src_port);
4293 pjsip_parse_rdata(packet, strlen(packet), rdata);
4294 if (!rdata->msg_info.msg || !pj_list_empty(&rdata->msg_info.parse_err)) {
4299 pjsip_contact_hdr *contact_hdr;
4301 contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
NULL);
4303 contact_hdr->uri = pjsip_parse_uri(rdata->tp_info.pool, (
char *)contact,
4304 strlen(contact), PJSIP_PARSE_URI_AS_NAMEADDR);
4305 if (!contact_hdr->uri) {
4312 pj_strdup2(rdata->tp_info.pool, &rdata->msg_info.via->recvd_param, rdata->pkt_info.src_name);
4313 rdata->msg_info.via->rport_param = -1;
4315 rdata->tp_info.transport->key.type = pjsip_transport_get_type_from_name(pj_cstr(&tmp, transport_type));
4316 rdata->tp_info.transport->type_name = transport_type;
4317 pj_strdup2(rdata->tp_info.pool, &rdata->tp_info.transport->local_name.host, local_name);
4318 rdata->tp_info.transport->local_name.port = local_port;
4324 char *transport_type,
const char *local_name,
int local_port)
4327 local_name, local_port,
NULL);
4331 static const pjsip_method
info_method = {PJSIP_OTHER_METHOD, {
"INFO", 4} };
4338 {
"INVITE", &pjsip_invite_method },
4339 {
"CANCEL", &pjsip_cancel_method },
4340 {
"ACK", &pjsip_ack_method },
4341 {
"BYE", &pjsip_bye_method },
4342 {
"REGISTER", &pjsip_register_method },
4343 {
"OPTIONS", &pjsip_options_method },
4344 {
"SUBSCRIBE", &pjsip_subscribe_method },
4345 {
"NOTIFY", &pjsip_notify_method },
4355 if (!strcmp(method,
methods[i].method)) {
4364 if (pjsip_dlg_create_request(dlg, method, -1, tdata) != PJ_SUCCESS) {
4374 .name = {
"Out of dialog supplement hook", 29 },
4376 .priority = PJSIP_MOD_PRIORITY_APPLICATION - 1,
4381 const char *uri,
struct ast_sip_contact *provided_contact, pjsip_tx_data **tdata)
4384 pj_str_t remote_uri;
4387 pjsip_tpselector selector = { .type = PJSIP_TPSELECTOR_NONE, };
4389 const char *fromuser;
4406 pj_cstr(&remote_uri,
contact->uri);
4408 pj_cstr(&remote_uri, uri);
4418 sip_uri = pjsip_parse_uri(pool, remote_uri.ptr, remote_uri.slen, 0);
4419 if (!sip_uri || (!PJSIP_URI_SCHEME_IS_SIP(sip_uri) && !PJSIP_URI_SCHEME_IS_SIPS(sip_uri))) {
4420 ast_log(
LOG_ERROR,
"Unable to create outbound %.*s request to endpoint %s as URI '%s' is not valid\n",
4421 (
int) pj_strlen(&method->name), pj_strbuf(&method->name),
4423 pj_strbuf(&remote_uri));
4432 endpoint ? endpoint->
fromdomain :
NULL, &remote_uri, &selector)) {
4433 ast_log(
LOG_ERROR,
"Unable to create From header for %.*s request to endpoint %s\n",
4434 (
int) pj_strlen(&method->name), pj_strbuf(&method->name),
4442 &from, &remote_uri, &from, NULL, -1, NULL, tdata) != PJ_SUCCESS) {
4443 ast_log(
LOG_ERROR,
"Unable to create outbound %.*s request to endpoint %s\n",
4444 (
int) pj_strlen(&method->name), pj_strbuf(&method->name),
4451 pjsip_tx_data_set_transport(*tdata, &selector);
4456 pjsip_contact_hdr *contact_hdr;
4457 pjsip_sip_uri *contact_uri;
4458 static const pj_str_t HCONTACT = {
"Contact", 7 };
4459 static const pj_str_t HCONTACTSHORT = {
"m", 1 };
4461 contact_hdr = pjsip_msg_find_hdr_by_names((*tdata)->msg, &HCONTACT, &HCONTACTSHORT, NULL);
4463 contact_uri = pjsip_uri_get_uri(contact_hdr->uri);
4464 pj_strdup2((*tdata)->pool, &contact_uri->user, endpoint->
contact_user);
4474 ast_log(
LOG_ERROR,
"Unable to apply outbound proxy on request %.*s to endpoint %s as outbound proxy URI '%s' is not valid\n",
4537 if (supplement == iter) {
4547 if (pjsip_dlg_send_request(dlg, tdata, -1,
NULL) != PJ_SUCCESS) {
4562 pj_cstr(&method, supplement_method);
4564 return pj_stristr(&method, message_method) ? PJ_TRUE : PJ_FALSE;
4567 #define TIMER_INACTIVE 0 4568 #define TIMEOUT_TIMER2 5 4577 void (*callback)(
void *token, pjsip_event *e);
4611 void (*callback)(
void *token, pjsip_event *e);
4639 if (e->body.tsx_state.type == PJSIP_EVENT_TIMER) {
4640 ast_debug(2,
"%p: PJSIP tsx timer expired\n", req_wrapper);
4644 ast_debug(3,
"%p: Timeout already handled\n", req_wrapper);
4649 ast_debug(2,
"%p: PJSIP tsx response received\n", req_wrapper);
4660 int timers_cancelled = 0;
4662 ast_debug(3,
"%p: Cancelling timer\n", req_wrapper);
4664 timers_cancelled = pj_timer_heap_cancel_if_active(
4667 if (timers_cancelled > 0) {
4671 ast_debug(3,
"%p: Timer cancelled\n", req_wrapper);
4679 ast_debug(3,
"%p: Timer already expired\n", req_wrapper);
4690 if (!cb_called && req_wrapper->
callback) {
4692 ast_debug(2,
"%p: Callbacks executed\n", req_wrapper);
4708 ast_debug(2,
"%p: Internal tsx timer expired after %d msec\n",
4709 req_wrapper, req_wrapper->
timeout);
4718 ast_debug(3,
"%p: Timeout already handled\n", req_wrapper);
4724 ast_debug(3,
"%p: Timer handled here\n", req_wrapper);
4730 if (!cb_called && req_wrapper->
callback) {
4733 PJSIP_EVENT_INIT_TX_MSG(event, req_wrapper->
tdata);
4734 event.body.tsx_state.type = PJSIP_EVENT_TIMER;
4737 ast_debug(2,
"%p: Callbacks executed\n", req_wrapper);
4747 pjsip_tx_data_dec_ref(req_wrapper->
tdata);
4748 ast_debug(2,
"%p: wrapper destroyed\n", req_wrapper);
4752 pjsip_tx_data *
tdata, pj_int32_t
timeout,
void *token, pjsip_endpt_send_callback cb)
4755 pj_status_t ret_val;
4760 pjsip_tx_data_dec_ref(tdata);
4767 pjsip_tx_data_dec_ref(tdata);
4771 ast_debug(2,
"%p: Wrapper created\n", req_wrapper);
4779 pjsip_tx_data_add_ref(tdata);
4782 pj_time_val timeout_timer_val = { timeout / 1000, timeout % 1000 };
4784 req_wrapper->
timeout_timer = PJ_POOL_ALLOC_T(tdata->pool, pj_timer_entry);
4786 ast_debug(2,
"%p: Set timer to %d msec\n", req_wrapper, timeout);
4795 ret_val = pj_timer_heap_schedule(pjsip_endpt_get_timer_heap(endpt),
4797 if (ret_val != PJ_SUCCESS) {
4799 "Failed to set timer. Not sending %.*s request to endpoint %s.\n",
4800 (
int) pj_strlen(&tdata->msg->line.req.method.name),
4801 pj_strbuf(&tdata->msg->line.req.method.name),
4803 ao2_t_ref(req_wrapper, -2,
"Drop timer and routine ref");
4804 pjsip_tx_data_dec_ref(tdata);
4814 if (ret_val != PJ_SUCCESS) {
4815 char errmsg[PJ_ERR_MSG_SIZE];
4823 pj_strerror(ret_val, errmsg,
sizeof(errmsg));
4825 (
int) ret_val, errmsg, (
int) pj_strlen(&tdata->msg->line.req.method.name),
4826 pj_strbuf(&tdata->msg->line.req.method.name),
4830 int timers_cancelled;
4833 timers_cancelled = pj_timer_heap_cancel_if_active(
4834 pjsip_endpt_get_timer_heap(endpt),
4836 if (timers_cancelled > 0) {
4847 ret_val = PJ_SUCCESS;
4863 ret_val = PJ_SUCCESS;
4875 if (!tdata || !tdata->dest_info.addr.count
4876 || (tdata->dest_info.cur_addr == tdata->dest_info.addr.count - 1)) {
4882 ++tdata->dest_info.cur_addr;
4884 via = (pjsip_via_hdr*)pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA,
NULL);
4885 via->branch_param.slen = 0;
4887 pjsip_tx_data_invalidate_msg(tdata);
4897 pjsip_transaction *tsx;
4898 pjsip_tx_data *tdata;
4905 tsx = e->body.tsx_state.tsx;
4907 switch (tsx->status_code) {
4913 e->body.tsx_state.src.rdata, tsx->last_tx, &tdata);
4918 tdata = tsx->last_tx;
4923 pjsip_tx_data_add_ref(tdata);
4930 req_data, send_request_cb) == PJ_SUCCESS;
4943 if (e->type == PJSIP_EVENT_TSX_STATE) {
4944 switch(e->body.tsx_state.type) {
4945 case PJSIP_EVENT_TRANSPORT_ERROR:
4946 case PJSIP_EVENT_TIMER:
4956 case PJSIP_EVENT_RX_MSG:
4957 challenge = e->body.tsx_state.src.rdata;
4995 void (*callback)(
void *token, pjsip_event *e))
5003 pjsip_tx_data_dec_ref(tdata);
5036 void (*callback)(
void *token, pjsip_event *e))
5038 ast_assert(tdata->msg->type == PJSIP_REQUEST_MSG);
5049 pjsip_route_hdr *route;
5050 static const pj_str_t ROUTE_HNAME = {
"Route", 5 };
5053 pj_strdup2_with_null(tdata->pool, &tmp, proxy);
5054 if (!(route = pjsip_parse_hdr(tdata->pool, &ROUTE_HNAME, tmp.ptr, tmp.slen,
NULL))) {
5058 pj_list_insert_nodes_before(&tdata->msg->hdr, (pjsip_hdr*)route);
5067 pjsip_generic_string_hdr *hdr;
5069 pj_cstr(&hdr_name, name);
5070 pj_cstr(&hdr_value, value);
5072 hdr = pjsip_generic_string_hdr_create(tdata->pool, &hdr_name, &hdr_value);
5074 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *) hdr);
5084 pj_cstr(&type, body->
type);
5085 pj_cstr(&subtype, body->
subtype);
5088 return pjsip_msg_body_create(pool, &type, &subtype, &body_text);
5094 tdata->msg->body = pjsip_body;
5102 pjsip_msg_body *body = pjsip_multipart_create(tdata->pool,
NULL,
NULL);
5104 for (i = 0; i < num_bodies; ++i) {
5105 pjsip_multipart_part *part = pjsip_multipart_create_part(tdata->pool);
5107 pjsip_multipart_add_part(tdata->pool, body, part);
5110 tdata->msg->body = body;
5116 size_t combined_size = strlen(body_text) + tdata->msg->body->len;
5119 ast_str_set(&body_buffer, 0,
"%.*s%s", (
int) tdata->msg->body->len, (
char *) tdata->msg->body->data, body_text);
5121 tdata->msg->body->data = pj_pool_alloc(tdata->pool, combined_size);
5122 pj_memcpy(tdata->msg->body->data,
ast_str_buffer(body_buffer), combined_size);
5123 tdata->msg->body->len = combined_size;
5181 memset(&std, 0,
sizeof(std));
5184 std.
task = sip_task;
5207 return sip_task(task_data);
5234 return sip_task(task_data);
5242 size_t chars_to_copy =
MIN(size - 1, pj_strlen(src));
5243 memcpy(dest, pj_strbuf(src), chars_to_copy);
5244 dest[chars_to_copy] =
'\0';
5249 int res =
ast_asprintf(dest,
"%.*s", (
int)pj_strlen(src), pj_strbuf(src));
5263 if (!content_type) {
5267 pjsip_media_type_init2(&compare, type, subtype);
5269 return pjsip_media_type_cmp(content_type, &compare, 0) ? 0 : -1;
5279 while (monitor_continue) {
5280 const pj_time_val delay = {0, 10};
5288 monitor_continue = 0;
5289 pj_thread_join(monitor_thread);
5294 #define SIP_SERVANT_ID 0x5E2F1D 5298 pj_thread_desc *
desc;
5300 uint32_t *servant_id;
5304 ast_log(
LOG_ERROR,
"Could not set SIP servant ID in thread-local storage.\n");
5311 ast_log(
LOG_ERROR,
"Could not get thread desc from thread-local storage. Expect awful things to occur\n");
5314 pj_bzero(*desc,
sizeof(*desc));
5316 if (pj_thread_register(
"Asterisk Thread", *desc, &thread) != PJ_SUCCESS) {
5323 uint32_t *servant_id;
5325 if (monitor_thread &&
5326 pthread_self() == *(pthread_t *)pj_thread_get_os_handle(monitor_thread)) {
5340 unsigned int hval = 0;
5346 return pj_hash_get(ht, key, PJ_HASH_KEY_STRING, &hval);
5350 const char *key,
void *
val)
5353 ht = pj_hash_create(pool, 11);
5356 pj_hash_set(pool, ht, key, PJ_HASH_KEY_STRING, 0, val);
5365 if (pjsip_rdata_get_dlg(rdata)) {
5388 pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ,
NULL);
5413 if (status != PJ_SUCCESS) {
5414 pjsip_tx_data_dec_ref(tdata);
5417 return status == PJ_SUCCESS ? 0 : -1;
5422 pjsip_transaction *tsx;
5424 if (pjsip_tsx_create_uas(
NULL, rdata, &tsx) != PJ_SUCCESS) {
5433 pjsip_tx_data_dec_ref(tdata);
5436 pjsip_tsx_recv_msg(tsx, rdata);
5440 if (pjsip_tsx_send_msg(tsx, tdata) != PJ_SUCCESS) {
5441 pjsip_tx_data_dec_ref(tdata);
5475 if (af == pj_AF_INET()) {
5477 }
else if (af == pj_AF_INET6()) {
5485 char *
buf,
size_t buf_len)
5517 if (!strcasecmp(dtmf_mode,
"info")) {
5519 }
else if (!strcasecmp(dtmf_mode,
"rfc4733")) {
5521 }
else if (!strcasecmp(dtmf_mode,
"inband")) {
5523 }
else if (!strcasecmp(dtmf_mode,
"none")) {
5525 }
else if (!strcasecmp(dtmf_mode,
"auto")) {
5527 }
else if (!strcasecmp(dtmf_mode,
"auto_info")) {
5538 if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, ALL)) {
5540 }
else if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, ALL)) {
5541 value =
"local_merge";
5542 }
else if (ast_sip_call_codec_pref_test(pref, LOCAL) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, FIRST)) {
5543 value =
"local_first";
5544 }
else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, INTERSECT) && ast_sip_call_codec_pref_test(pref, ALL)) {
5546 }
else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, ALL)) {
5547 value =
"remote_merge";
5548 }
else if (ast_sip_call_codec_pref_test(pref, REMOTE) && ast_sip_call_codec_pref_test(pref, UNION) && ast_sip_call_codec_pref_test(pref, FIRST)) {
5549 value =
"remote_first";
5561 if (strcmp(pref_str,
"local") == 0) {
5563 }
else if (is_outgoing && strcmp(pref_str,
"local_merge") == 0) {
5565 }
else if (strcmp(pref_str,
"local_first") == 0) {
5567 }
else if (strcmp(pref_str,
"remote") == 0) {
5569 }
else if (is_outgoing && strcmp(pref_str,
"remote_merge") == 0) {
5571 }
else if (strcmp(pref_str,
"remote_first") == 0) {
5589 pjsip_name_addr *id_name_addr;
5590 pjsip_sip_uri *id_uri;
5592 id_name_addr = (pjsip_name_addr *) id_hdr->uri;
5593 id_uri = pjsip_uri_get_uri(id_name_addr->uri);
5597 int name_buf_len = strlen(id->
name.
str) * 2 + 1;
5601 pj_strdup2(pool, &id_name_addr->display, name_buf);
5603 pj_strdup2(pool, &id_name_addr->display,
NULL);
5608 pj_strdup2(pool, &id_uri->user, id->
number.
str);
5615 const pjsip_hdr *
request_headers = pjsip_endpt_get_request_headers(endpt);
5616 pjsip_hdr *iter = request_headers->next;
5618 while (iter != request_headers) {
5619 pjsip_hdr *to_erase = iter;
5621 pj_list_erase(to_erase);
5635 #ifdef TEST_FRAMEWORK 5642 info->name =
"xml_sanitization_end_null";
5643 info->category =
"/res/res_pjsip/";
5644 info->summary =
"Ensure XML sanitization works as expected with a long string";
5645 info->description =
"This test sanitizes a string which exceeds the output\n" 5646 "buffer size. Once done the string is confirmed to be NULL terminated.";
5653 if (sanitized[7] !=
'\0') {
5667 info->name =
"xml_sanitization_exceeds_buffer";
5668 info->category =
"/res/res_pjsip/";
5669 info->summary =
"Ensure XML sanitization does not exceed buffer when output won't fit";
5670 info->description =
"This test sanitizes a string which before sanitization would\n" 5671 "fit within the output buffer. After sanitization, however, the string would\n" 5672 "exceed the buffer. Once done the string is confirmed to be NULL terminated.";
5679 if (sanitized[7] !=
'\0') {
5718 if (monitor_thread) {
5720 monitor_thread =
NULL;
5730 pj_pool_release(temp_pool);
5735 if (caching_pool.lock) {
5746 const unsigned int flags = 0;
5754 if (pjsip_endpt_create(&caching_pool.factory,
"SIP", &
ast_pjsip_endpoint) != PJ_SUCCESS) {
5755 ast_log(
LOG_ERROR,
"Failed to create PJSIP endpoint structure. Aborting load\n");
5764 memory_pool = pj_pool_create(&caching_pool.factory,
"SIP", 1024, 1024,
NULL);
5766 ast_log(
LOG_ERROR,
"Failed to create memory pool for SIP. Aborting load\n");
5783 monitor_continue = 1;
5785 NULL, PJ_THREAD_DEFAULT_STACK_SIZE * 2, 0, &monitor_thread);
5786 if (status != PJ_SUCCESS) {
5807 pjmedia_strerror(0,
NULL, 0);
5815 if (pj_init() != PJ_SUCCESS) {
5819 if (pjlib_util_init() != PJ_SUCCESS) {
5824 if (pj_register_strerror(PJMEDIA_ERRNO_START, PJ_ERRNO_SPACE_SIZE, pjmedia_strerror)
5826 ast_log(
LOG_WARNING,
"Failed to register pjmedia error codes. Codes will not be decoded.\n");
5830 ast_log(
LOG_ERROR,
"Failed to initialize SIP 'system' configuration section. Aborting load\n");
5838 if (!sip_threadpool) {
5844 if (!sip_serializer_pool) {
5845 ast_log(
LOG_ERROR,
"Failed to create SIP serializer pool. Aborting load\n");
5860 ast_log(
LOG_ERROR,
"Failed to initialize SIP transport monitor. Aborting load\n");
5868 ast_log(
LOG_ERROR,
"Failed to pre-initialize OPTIONS handling. Aborting load\n");
5873 ast_log(
LOG_ERROR,
"Failed to initialize SIP configuration. Aborting load\n");
5881 ast_log(
LOG_ERROR,
"Failed to initialize SIP transport management. Aborting load\n");
5886 ast_log(
LOG_ERROR,
"Failed to register distributor module. Aborting load\n");
5891 ast_log(
LOG_ERROR,
"Failed to initialize supplement hooks. Aborting load\n");
5896 ast_log(
LOG_ERROR,
"Failed to initialize OPTIONS handling. Aborting load\n");