Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
Data Structures | Functions | Variables
res_pjsip_rfc3329.c File Reference
#include "asterisk.h"
#include <pjsip.h>
#include <pjsip_ua.h>
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
#include "asterisk/module.h"
#include "asterisk/causes.h"
#include "asterisk/threadpool.h"
Include dependency graph for res_pjsip_rfc3329.c:

Go to the source code of this file.

Data Structures

struct  rfc3329_store_data
 Private data structure used with the modules's datastore. More...
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void add_outgoing_request_headers (struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, struct pjsip_tx_data *tdata, struct ast_datastore *datastore)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static void datastore_destroy_cb (void *data)
 
static int load_module (void)
 
static void rfc3329_incoming_response (struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 
static void rfc3329_options_request (struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, struct pjsip_tx_data *tdata)
 
static void rfc3329_outgoing_request (struct ast_sip_session *session, struct pjsip_tx_data *tdata)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP RFC3329 Support (partial)" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, .requires = "res_pjsip,res_pjsip_session", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_sip_supplement rfc3329_options_supplement
 
static const struct ast_datastore_info rfc3329_store_datastore
 The channel datastore the module uses to store state.
 
static struct ast_sip_session_supplement rfc3329_supplement
 

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 189 of file res_pjsip_rfc3329.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 189 of file res_pjsip_rfc3329.c.

◆ add_outgoing_request_headers()

static void add_outgoing_request_headers ( struct ast_sip_endpoint endpoint,
struct ast_sip_contact contact,
struct pjsip_tx_data *  tdata,
struct ast_datastore datastore 
)
static

Definition at line 109 of file res_pjsip_rfc3329.c.

111{
112 static const pj_str_t security_verify = { "Security-Verify", 15 };
113 struct pjsip_generic_string_hdr *hdr = NULL;
114 struct ast_sip_contact_status *contact_status = NULL;
115 struct rfc3329_store_data *store_data;
116
118 return;
119 }
120
121 contact_status = ast_sip_get_contact_status(contact);
122 hdr = pjsip_msg_find_hdr_by_name(tdata->msg, &security_verify, NULL);
123
124 if (contact_status == NULL) {
125 return;
126 }
127
128 ao2_lock(contact_status);
129 if (AST_VECTOR_SIZE(&contact_status->security_mechanisms) && hdr == NULL) {
130 /* Add Security-Verify headers (with q-value) */
131 ast_sip_add_security_headers(&contact_status->security_mechanisms, "Security-Verify", 0, tdata);
132 }
133 if (datastore) {
134 store_data = datastore->data;
135 if (store_data->last_rx_status_code == 401) {
136 /* Add Security-Client headers (no q-value) */
137 ast_sip_add_security_headers(&endpoint->security_mechanisms, "Security-Client", 0, tdata);
138 }
139 }
140 ao2_unlock(contact_status);
141
142 ao2_cleanup(contact_status);
143}
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_unlock(a)
Definition astobj2.h:729
#define ao2_lock(a)
Definition astobj2.h:717
@ AST_SIP_SECURITY_NEG_MEDIASEC
Definition res_pjsip.h:355
struct ast_sip_contact_status * ast_sip_get_contact_status(const struct ast_sip_contact *contact)
Retrieve the current status for a contact.
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.
#define NULL
Definition resample.c:96
void * data
Definition datastore.h:66
A contact's status.
Definition res_pjsip.h:451
struct ast_sip_security_mechanism_vector security_mechanisms
Definition res_pjsip.h:466
enum ast_sip_security_negotiation security_negotiation
Definition res_pjsip.h:1146
struct ast_sip_security_mechanism_vector security_mechanisms
Definition res_pjsip.h:1148
Private data structure used with the modules's datastore.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition vector.h:620

References ao2_cleanup, ao2_lock, ao2_unlock, ast_sip_add_security_headers(), ast_sip_get_contact_status(), AST_SIP_SECURITY_NEG_MEDIASEC, AST_VECTOR_SIZE, ast_datastore::data, rfc3329_store_data::last_rx_status_code, NULL, ast_sip_contact_status::security_mechanisms, ast_sip_endpoint::security_mechanisms, and ast_sip_endpoint::security_negotiation.

Referenced by rfc3329_options_request(), and rfc3329_outgoing_request().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 189 of file res_pjsip_rfc3329.c.

◆ datastore_destroy_cb()

static void datastore_destroy_cb ( void *  data)
static

Definition at line 42 of file res_pjsip_rfc3329.c.

43{
44 struct rfc3329_store_data *d = data;
45 if (d) {
46 ast_free(d);
47 }
48}
#define ast_free(a)
Definition astmm.h:180
static struct test_val d

References ast_free, and d.

◆ load_module()

static int load_module ( void  )
static

Definition at line 169 of file res_pjsip_rfc3329.c.

170{
174}
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
void ast_sip_register_supplement(struct ast_sip_supplement *supplement)
Register a supplement to SIP out of dialog processing.
Definition res_pjsip.c:1456
static struct ast_sip_supplement rfc3329_options_supplement
static struct ast_sip_session_supplement rfc3329_supplement
#define ast_sip_session_register_supplement(supplement)

References AST_MODULE_LOAD_SUCCESS, ast_sip_register_supplement(), ast_sip_session_register_supplement, rfc3329_options_supplement, and rfc3329_supplement.

◆ rfc3329_incoming_response()

static void rfc3329_incoming_response ( struct ast_sip_session session,
struct pjsip_rx_data *  rdata 
)
static

Definition at line 56 of file res_pjsip_rfc3329.c.

57{
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 };
60 struct ast_sip_contact_status *contact_status = NULL;
61 struct ast_sip_security_mechanism *mech;
62 struct rfc3329_store_data *store_data;
63 pjsip_generic_string_hdr *header;
64 char buf[128];
65 char *hdr_val;
66 char *mechanism;
67
68 if (!session || !session->endpoint || !session->endpoint->security_negotiation
69 || !session->contact || !(contact_status = ast_sip_get_contact_status(session->contact))
70 || !session->inv_session->dlg) {
71 return;
72 }
73
74 ao2_lock(contact_status);
75 if (AST_VECTOR_SIZE(&contact_status->security_mechanisms)) {
76 goto out;
77 }
78
79 if (!datastore
80 && (datastore = ast_sip_session_alloc_datastore(&rfc3329_store_datastore, "rfc3329_store"))
81 && (store_data = ast_calloc(1, sizeof(struct rfc3329_store_data)))) {
82
83 store_data->last_rx_status_code = rdata->msg_info.msg->line.status.code;
84 datastore->data = store_data;
86 } else {
87 ast_log(AST_LOG_WARNING, "Could not store session data. Still attempting requests, but they might be missing necessary headers.\n");
88 }
89
90 header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_security_server, NULL);
91 for (; header;
92 header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_security_server, header->next)) {
93 /* Parse Security-Server headers and add to contact status to use for future requests. */
94 ast_copy_pj_str(buf, &header->hvalue, sizeof(buf));
95 hdr_val = ast_skip_blanks(buf);
96
97 while ((mechanism = ast_strsep(&hdr_val, ',', AST_STRSEP_ALL))) {
98 if (!ast_sip_str_to_security_mechanism(&mech, mechanism)) {
99 AST_VECTOR_APPEND(&contact_status->security_mechanisms, mech);
100 }
101 }
102 }
103
104out:
105 ao2_unlock(contact_status);
106 ao2_cleanup(contact_status);
107}
static struct ast_mansession session
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
#define ast_log
Definition astobj2.c:42
char buf[BUFSIZE]
Definition eagi_proxy.c:66
#define AST_LOG_WARNING
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition res_pjsip.c:2201
int ast_sip_str_to_security_mechanism(struct ast_sip_security_mechanism **security_mechanism, const char *value)
Allocate a security mechanism from a string.
static const struct ast_datastore_info rfc3329_store_datastore
The channel datastore the module uses to store state.
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
@ AST_STRSEP_ALL
Definition strings.h:258
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition utils.c:1871
char *attribute_pure ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition strings.h:161
Structure for a data store object.
Definition datastore.h:64
Structure representing a security mechanism as defined in RFC 3329.
Definition res_pjsip.h:376
struct header * next
FILE * out
Definition utils/frame.c:33
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition vector.h:267

References ao2_cleanup, ao2_lock, ao2_unlock, ast_calloc, ast_copy_pj_str(), ast_log, AST_LOG_WARNING, ast_sip_get_contact_status(), ast_sip_session_add_datastore(), ast_sip_session_alloc_datastore(), ast_sip_session_get_datastore(), ast_sip_str_to_security_mechanism(), ast_skip_blanks(), ast_strsep(), AST_STRSEP_ALL, AST_VECTOR_APPEND, AST_VECTOR_SIZE, buf, rfc3329_store_data::last_rx_status_code, header::next, NULL, out, RAII_VAR, rfc3329_store_datastore, ast_sip_contact_status::security_mechanisms, and session.

◆ rfc3329_options_request()

static void rfc3329_options_request ( struct ast_sip_endpoint endpoint,
struct ast_sip_contact contact,
struct pjsip_tx_data *  tdata 
)
static

Definition at line 159 of file res_pjsip_rfc3329.c.

160{
161 add_outgoing_request_headers(endpoint, contact, tdata, NULL);
162}
static void add_outgoing_request_headers(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, struct pjsip_tx_data *tdata, struct ast_datastore *datastore)

References add_outgoing_request_headers(), and NULL.

◆ rfc3329_outgoing_request()

static void rfc3329_outgoing_request ( struct ast_sip_session session,
struct pjsip_tx_data *  tdata 
)
static

Definition at line 145 of file res_pjsip_rfc3329.c.

146{
147 RAII_VAR(struct ast_datastore *, datastore, ast_sip_session_get_datastore(session, "rfc3329_store"), ao2_cleanup);
148 if (session->contact == NULL) {
149 return;
150 }
151 add_outgoing_request_headers(session->endpoint, session->contact, tdata, datastore);
152}

References add_outgoing_request_headers(), ao2_cleanup, ast_sip_session_get_datastore(), NULL, RAII_VAR, and session.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 176 of file res_pjsip_rfc3329.c.

177{
180 return 0;
181}
void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement)
Unregister a an supplement to SIP out of dialog processing.
Definition res_pjsip.c:1476
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.

References ast_sip_session_unregister_supplement(), ast_sip_unregister_supplement(), rfc3329_options_supplement, and rfc3329_supplement.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP RFC3329 Support (partial)" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, .requires = "res_pjsip,res_pjsip_session", }
static

Definition at line 189 of file res_pjsip_rfc3329.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 189 of file res_pjsip_rfc3329.c.

◆ rfc3329_options_supplement

struct ast_sip_supplement rfc3329_options_supplement
static
Initial value:
= {
.method = "OPTIONS",
.outgoing_request = rfc3329_options_request,
}
static void rfc3329_options_request(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, struct pjsip_tx_data *tdata)

Definition at line 164 of file res_pjsip_rfc3329.c.

164 {
165 .method = "OPTIONS",
166 .outgoing_request = rfc3329_options_request,
167};

Referenced by load_module(), and unload_module().

◆ rfc3329_store_datastore

const struct ast_datastore_info rfc3329_store_datastore
static
Initial value:
= {
.type = "rfc3329_store",
}
static void datastore_destroy_cb(void *data)

The channel datastore the module uses to store state.

Definition at line 51 of file res_pjsip_rfc3329.c.

51 {
52 .type = "rfc3329_store",
53 .destroy = datastore_destroy_cb
54};

Referenced by rfc3329_incoming_response().

◆ rfc3329_supplement

struct ast_sip_session_supplement rfc3329_supplement
static
Initial value:
= {
.incoming_response = rfc3329_incoming_response,
.outgoing_request = rfc3329_outgoing_request,
}
static void rfc3329_incoming_response(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
static void rfc3329_outgoing_request(struct ast_sip_session *session, struct pjsip_tx_data *tdata)

Definition at line 154 of file res_pjsip_rfc3329.c.

154 {
155 .incoming_response = rfc3329_incoming_response,
156 .outgoing_request = rfc3329_outgoing_request,
157};

Referenced by load_module(), and unload_module().