31 #include "asterisk/res_pjsip.h"
32 #include "asterisk/res_pjsip_session.h"
35 #include "asterisk/threadpool.h"
39 int last_rx_status_code;
42 static void datastore_destroy_cb(
void *data)
52 .
type =
"rfc3329_store",
53 .destroy = datastore_destroy_cb
56 static void rfc3329_incoming_response(
struct ast_sip_session *session,
struct pjsip_rx_data *rdata)
58 RAII_VAR(
struct ast_datastore *, datastore, ast_sip_session_get_datastore(session,
"rfc3329_store"), ao2_cleanup);
59 static const pj_str_t str_security_server = {
"Security-Server", 15 };
63 pjsip_generic_string_hdr *
header;
69 || !session->
contact || !(contact_status = ast_sip_get_contact_status(session->
contact))
74 ao2_lock(contact_status);
80 && (datastore = ast_sip_session_alloc_datastore(&rfc3329_store_datastore,
"rfc3329_store"))
83 store_data->last_rx_status_code = rdata->msg_info.msg->line.status.code;
84 datastore->data = store_data;
85 ast_sip_session_add_datastore(session, datastore);
87 ast_log(AST_LOG_WARNING,
"Could not store session data. Still attempting requests, but they might be missing necessary headers.\n");
90 header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_security_server, NULL);
92 header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_security_server, header->next)) {
94 ast_copy_pj_str(buf, &header->hvalue,
sizeof(buf));
105 ao2_unlock(contact_status);
106 ao2_cleanup(contact_status);
112 static const pj_str_t security_verify = {
"Security-Verify", 15 };
113 struct pjsip_generic_string_hdr *hdr = NULL;
121 contact_status = ast_sip_get_contact_status(contact);
122 hdr = pjsip_msg_find_hdr_by_name(tdata->msg, &security_verify, NULL);
124 if (contact_status == NULL) {
128 ao2_lock(contact_status);
134 store_data = datastore->
data;
135 if (store_data->last_rx_status_code == 401) {
140 ao2_unlock(contact_status);
142 ao2_cleanup(contact_status);
145 static void rfc3329_outgoing_request(
struct ast_sip_session *session,
struct pjsip_tx_data *tdata)
147 RAII_VAR(
struct ast_datastore *, datastore, ast_sip_session_get_datastore(session,
"rfc3329_store"), ao2_cleanup);
148 if (session->
contact == NULL) {
151 add_outgoing_request_headers(session->
endpoint, session->
contact, tdata, datastore);
156 .outgoing_request = rfc3329_outgoing_request,
161 add_outgoing_request_headers(endpoint, contact, tdata, NULL);
166 .outgoing_request = rfc3329_options_request,
169 static int load_module(
void)
171 ast_sip_session_register_supplement(&rfc3329_supplement);
172 ast_sip_register_supplement(&rfc3329_options_supplement);
176 static int unload_module(
void)
178 ast_sip_session_unregister_supplement(&rfc3329_supplement);
179 ast_sip_unregister_supplement(&rfc3329_options_supplement);
183 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,
"PJSIP RFC3329 Support (partial)",
184 .support_level = AST_MODULE_SUPPORT_CORE,
186 .unload = unload_module,
188 .requires =
"res_pjsip,res_pjsip_session",
struct ast_sip_endpoint * endpoint
Asterisk main include file. File version handling, generic pbx functions.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Structure for a data store type.
Structure for a data store object.
struct pjsip_inv_session * inv_session
A structure describing a SIP session.
int ast_sip_add_security_headers(struct ast_sip_security_mechanism_vector *security_mechanisms, const char *header_name, int add_qval, pjsip_tx_data *tdata)
Add security headers to transmission data.
struct ast_sip_security_mechanism_vector security_mechanisms
Structure representing a security mechanism as defined in RFC 3329.
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
void(* incoming_response)(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
Called on an incoming SIP response This method is always called from a SIP servant thread...
An entity with which Asterisk communicates.
enum ast_sip_security_negotiation security_negotiation
Private data structure used with the modules's datastore.
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
#define ast_calloc(num, len)
A wrapper for calloc()
A supplement to SIP message processing.
A supplement to SIP message processing.
Internal Asterisk hangup causes.
int ast_sip_str_to_security_mechanism(struct ast_sip_security_mechanism **security_mechanism, const char *value)
Allocate a security mechanism from a string.
#define ASTERISK_GPL_KEY
The text the key() function should return.
struct ast_sip_contact * contact
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.