AST_DECLARE_STRING_FIELDS(
/*! Full URI of the contact */
AST_STRING_FIELD(uri);
+ /*! Outbound proxy to use for qualify */
+ AST_STRING_FIELD(outbound_proxy);
);
/*! Absolute time that this contact is no longer valid after */
struct timeval expiration_time;
AST_DECLARE_STRING_FIELDS(
/*! Voicemail boxes for this AOR */
AST_STRING_FIELD(mailboxes);
+ /*! Outbound proxy for OPTIONS requests */
+ AST_STRING_FIELD(outbound_proxy);
);
/*! Minimum expiration time */
unsigned int minimum_expiration;
*/
struct ast_sip_endpoint *ast_sip_identify_endpoint(pjsip_rx_data *rdata);
+/*!
+ * \brief Set the outbound proxy for an outbound SIP message
+ *
+ * \param tdata The message to set the outbound proxy on
+ * \param proxy SIP uri of the proxy
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_set_outbound_proxy(pjsip_tx_data *tdata, const char *proxy);
+
/*!
* \brief Add a header to an outbound SIP message
*
If <literal>0</literal> never qualify. Time in seconds.
</para></description>
</configOption>
+ <configOption name="outbound_proxy">
+ <synopsis>Outbound proxy used when sending OPTIONS request</synopsis>
+ <description><para>
+ If set the provided URI will be used as the outbound proxy when an
+ OPTIONS request is sent to a contact for qualify purposes.
+ </para></description>
+ </configOption>
</configObject>
<configObject name="aor">
<synopsis>The configuration for a location of an endpoint</synopsis>
authentication is attempted before declaring the contact available.
</para></description>
</configOption>
+ <configOption name="outbound_proxy">
+ <synopsis>Outbound proxy used when sending OPTIONS request</synopsis>
+ <description><para>
+ If set the provided URI will be used as the outbound proxy when an
+ OPTIONS request is sent to a contact for qualify purposes.
+ </para></description>
+ </configOption>
</configObject>
<configObject name="system">
<synopsis>Options that apply to the SIP stack as well as other system-wide settings</synopsis>
return -1;
}
+ /* If an outbound proxy is specified on the endpoint apply it to this request */
+ if (endpoint && !ast_strlen_zero(endpoint->outbound_proxy) &&
+ ast_sip_set_outbound_proxy((*tdata), endpoint->outbound_proxy)) {
+ ast_log(LOG_ERROR, "Unable to apply outbound proxy on request %.*s to endpoint %s\n",
+ (int) pj_strlen(&method->name), pj_strbuf(&method->name), ast_sorcery_object_get_id(endpoint));
+ pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), pool);
+ return -1;
+ }
+
/* We can release this pool since request creation copied all the necessary
* data into the outbound request's pool
*/
}
}
+int ast_sip_set_outbound_proxy(pjsip_tx_data *tdata, const char *proxy)
+{
+ pjsip_route_hdr *route;
+ static const pj_str_t ROUTE_HNAME = { "Route", 5 };
+ pj_str_t tmp;
+
+ pj_strdup2_with_null(tdata->pool, &tmp, proxy);
+ if (!(route = pjsip_parse_hdr(tdata->pool, &ROUTE_HNAME, tmp.ptr, tmp.slen, NULL))) {
+ return -1;
+ }
+
+ pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)route);
+
+ return 0;
+}
+
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
{
pj_str_t hdr_name;
contact->qualify_frequency = aor->qualify_frequency;
contact->authenticate_qualify = aor->authenticate_qualify;
+ if (!ast_strlen_zero(aor->outbound_proxy)) {
+ ast_string_field_set(contact, outbound_proxy, aor->outbound_proxy);
+ }
+
return ast_sorcery_create(ast_sip_get_sorcery(), contact);
}
ast_sorcery_object_field_register_custom(sorcery, "contact", "expiration_time", "", expiration_str2struct, expiration_struct2str, 0, 0);
ast_sorcery_object_field_register(sorcery, "contact", "qualify_frequency", 0, OPT_UINT_T,
PARSE_IN_RANGE, FLDSET(struct ast_sip_contact, qualify_frequency), 0, 86400);
+ ast_sorcery_object_field_register(sorcery, "contact", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, outbound_proxy));
ast_sorcery_object_field_register(sorcery, "aor", "type", "", OPT_NOOP_T, 0, 0);
ast_sorcery_object_field_register(sorcery, "aor", "minimum_expiration", "60", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, minimum_expiration));
ast_sorcery_object_field_register(sorcery, "aor", "remove_existing", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_existing));
ast_sorcery_object_field_register_custom(sorcery, "aor", "contact", "", permanent_uri_handler, NULL, 0, 0);
ast_sorcery_object_field_register(sorcery, "aor", "mailboxes", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, mailboxes));
+ ast_sorcery_object_field_register(sorcery, "aor", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_aor, outbound_proxy));
ast_sip_register_endpoint_formatter(&endpoint_aor_formatter);
return 0;
return -1;
}
+ /* If an outbound proxy is specified set it on this request */
+ if (!ast_strlen_zero(contact->outbound_proxy) &&
+ ast_sip_set_outbound_proxy(tdata, contact->outbound_proxy)) {
+ pjsip_tx_data_dec_ref(tdata);
+ ast_log(LOG_ERROR, "Unable to apply outbound proxy on request to qualify contact %s\n",
+ contact->uri);
+ return -1;
+ }
+
init_start_time(contact);
ao2_ref(contact, +1);
struct ast_sip_aor *aor = arg;
contact->qualify_frequency = aor->qualify_frequency;
+
qualify_and_schedule(contact);
return 0;