Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
Functions | Variables
res_pjsip_path.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/strings.h"
Include dependency graph for res_pjsip_path.c:

Go to the source code of this file.

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int add_supported (pjsip_tx_data *tdata)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static struct ast_sip_aorfind_aor (struct ast_sip_contact *contact)
 
static struct ast_sip_aorfind_aor2 (struct ast_sip_endpoint *endpoint, pjsip_uri *uri)
 
static struct ast_sip_contactfind_contact (struct ast_sip_aor *aor, pjsip_uri *uri)
 
static int load_module (void)
 
static int path_get_string (pj_pool_t *pool, struct ast_sip_contact *contact, pj_str_t *path_str)
 Get the path string associated with this contact and tdata.
 
static void path_outgoing_request (struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, pjsip_tx_data *tdata)
 
static void path_outgoing_response (struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, pjsip_tx_data *tdata)
 
static void path_session_outgoing_request (struct ast_sip_session *session, pjsip_tx_data *tdata)
 
static void path_session_outgoing_response (struct ast_sip_session *session, 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 Path Header Support" , .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 const pj_str_t PATH_NAME = { "Path", 4 }
 
static struct ast_sip_session_supplement path_session_supplement
 
static struct ast_sip_supplement path_supplement
 
static pj_str_t PATH_SUPPORTED_NAME = { "path", 4 }
 

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 332 of file res_pjsip_path.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 332 of file res_pjsip_path.c.

◆ add_supported()

static int add_supported ( pjsip_tx_data *  tdata)
static

Definition at line 174 of file res_pjsip_path.c.

175{
176 pjsip_supported_hdr *hdr;
177 int i;
178
179 hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
180 if (!hdr) {
181 /* insert a new Supported header */
182 hdr = pjsip_supported_hdr_create(tdata->pool);
183 if (!hdr) {
184 return -1;
185 }
186
187 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)hdr);
188 }
189
190 /* Don't add the value if it's already there */
191 for (i = 0; i < hdr->count; ++i) {
192 if (pj_stricmp(&hdr->values[i], &PATH_SUPPORTED_NAME) == 0) {
193 return 0;
194 }
195 }
196
197 if (hdr->count >= PJSIP_GENERIC_ARRAY_MAX_COUNT) {
198 return -1;
199 }
200
201 /* add on to the existing Supported header */
202 pj_strassign(&hdr->values[hdr->count++], &PATH_SUPPORTED_NAME);
203
204 return 0;
205}
static pj_str_t PATH_SUPPORTED_NAME
#define NULL
Definition resample.c:96

References NULL, and PATH_SUPPORTED_NAME.

Referenced by path_outgoing_request(), and path_outgoing_response().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 332 of file res_pjsip_path.c.

◆ find_aor()

static struct ast_sip_aor * find_aor ( struct ast_sip_contact contact)
static

Definition at line 39 of file res_pjsip_path.c.

40{
41 if (!contact) {
42 return NULL;
43 }
44 if (ast_strlen_zero(contact->aor)) {
45 return NULL;
46 }
47
48 return ast_sip_location_retrieve_aor(contact->aor);
49}
struct ast_sip_aor * ast_sip_location_retrieve_aor(const char *aor_name)
Retrieve a named AOR.
Definition location.c:147
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
const ast_string_field aor
Definition res_pjsip.h:412

References ast_sip_contact::aor, ast_sip_location_retrieve_aor(), ast_strlen_zero(), and NULL.

Referenced by path_outgoing_request(), and path_outgoing_response().

◆ find_aor2()

static struct ast_sip_aor * find_aor2 ( struct ast_sip_endpoint endpoint,
pjsip_uri *  uri 
)
static

Definition at line 51 of file res_pjsip_path.c.

52{
53 char *configured_aors, *aor_name;
54 const pj_str_t *uri_username;
55 const pj_str_t *uri_hostname;
56 char *domain_name;
57 char *username;
58 struct ast_str *id = NULL;
59
60 if (ast_strlen_zero(endpoint->aors)) {
61 return NULL;
62 }
63
64 uri_hostname = ast_sip_pjsip_uri_get_hostname(uri);
65 domain_name = ast_alloca(uri_hostname->slen + 1);
66 ast_copy_pj_str(domain_name, uri_hostname, uri_hostname->slen + 1);
67
68 uri_username = ast_sip_pjsip_uri_get_username(uri);
69 username = ast_alloca(uri_username->slen + 1);
70 ast_copy_pj_str(username, uri_username, uri_username->slen + 1);
71
72 /*
73 * We may want to match without any user options getting
74 * in the way.
75 */
77
78 configured_aors = ast_strdupa(endpoint->aors);
79
80 /* Iterate the configured AORs to see if the user or the user+domain match */
81 while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
82 struct ast_sip_domain_alias *alias = NULL;
83
84 if (ast_strlen_zero(aor_name)) {
85 continue;
86 }
87
88 if (!strcmp(username, aor_name)) {
89 break;
90 }
91
92 if (!id && !(id = ast_str_create(strlen(username) + uri_hostname->slen + 2))) {
93 aor_name = NULL;
94 break;
95 }
96
97 ast_str_set(&id, 0, "%s@", username);
98 if ((alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain_name))) {
99 ast_str_append(&id, 0, "%s", alias->domain);
100 ao2_cleanup(alias);
101 } else {
102 ast_str_append(&id, 0, "%s", domain_name);
103 }
104
105 if (!strcmp(aor_name, ast_str_buffer(id))) {
106 break;
107 }
108 }
109 ast_free(id);
110
111 if (ast_strlen_zero(aor_name)) {
112 return NULL;
113 }
114
115 return ast_sip_location_retrieve_aor(aor_name);
116}
char * strsep(char **str, const char *delims)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition astmm.h:288
#define ast_free(a)
Definition astmm.h:180
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
#define ao2_cleanup(obj)
Definition astobj2.h:1934
const pj_str_t * ast_sip_pjsip_uri_get_username(pjsip_uri *uri)
Get the user portion of the pjsip_uri.
Definition res_pjsip.c:3477
#define AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(str)
Truncate the URI user field options string if enabled.
Definition res_pjsip.h:3504
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
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
const pj_str_t * ast_sip_pjsip_uri_get_hostname(pjsip_uri *uri)
Get the host portion of the pjsip_uri.
Definition res_pjsip.c:3496
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition sorcery.c:1917
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition strings.h:1139
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition strings.h:1113
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition strings.h:223
const ast_string_field domain
Definition res_pjsip.h:321
const ast_string_field aors
Definition res_pjsip.h:1080
Support for dynamic strings.
Definition strings.h:623

References ao2_cleanup, ast_sip_endpoint::aors, ast_alloca, ast_copy_pj_str(), ast_free, ast_sip_get_sorcery(), ast_sip_location_retrieve_aor(), ast_sip_pjsip_uri_get_hostname(), ast_sip_pjsip_uri_get_username(), AST_SIP_USER_OPTIONS_TRUNCATE_CHECK, ast_sorcery_retrieve_by_id(), ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_strdupa, ast_strip(), ast_strlen_zero(), ast_sip_domain_alias::domain, NULL, and strsep().

Referenced by path_outgoing_request().

◆ find_contact()

static struct ast_sip_contact * find_contact ( struct ast_sip_aor aor,
pjsip_uri *  uri 
)
static

Definition at line 118 of file res_pjsip_path.c.

119{
120 struct ao2_iterator it_contacts;
121 struct ast_sip_contact *contact;
122 char contact_buf[512];
123 int contact_buf_len;
124 int res = 0;
125
126 RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
127
128 if (!(contacts = ast_sip_location_retrieve_aor_contacts(aor))) {
129 /* No contacts are available, skip it as well */
130 return NULL;
131 } else if (!ao2_container_count(contacts)) {
132 /* We were given a container but no contacts are in it... */
133 return NULL;
134 }
135
136 contact_buf_len = pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, uri, contact_buf, 512);
137 contact_buf[contact_buf_len] = '\0';
138
139 it_contacts = ao2_iterator_init(contacts, 0);
140 for (; (contact = ao2_iterator_next(&it_contacts)); ao2_ref(contact, -1)) {
141 if (!strcmp(contact_buf, contact->uri)) {
142 res = 1;
143 break;
144 }
145 }
146 ao2_iterator_destroy(&it_contacts);
147 if (!res) {
148 return NULL;
149 }
150 return contact;
151}
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct ao2_container * ast_sip_location_retrieve_aor_contacts(const struct ast_sip_aor *aor)
Retrieve all contacts currently available for an AOR.
Definition location.c:247
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition astobj2.h:1821
Contact associated with an address of record.
Definition res_pjsip.h:390
const ast_string_field uri
Definition res_pjsip.h:412
#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

References ao2_cleanup, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_sip_contact::aor, ast_sip_location_retrieve_aor_contacts(), NULL, RAII_VAR, and ast_sip_contact::uri.

Referenced by path_outgoing_request().

◆ load_module()

static int load_module ( void  )
static

Definition at line 311 of file res_pjsip_path.c.

312{
315
317}
@ 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 path_supplement
static struct ast_sip_session_supplement path_session_supplement
#define ast_sip_session_register_supplement(supplement)

References AST_MODULE_LOAD_SUCCESS, ast_sip_register_supplement(), ast_sip_session_register_supplement, path_session_supplement, and path_supplement.

◆ path_get_string()

static int path_get_string ( pj_pool_t *  pool,
struct ast_sip_contact contact,
pj_str_t *  path_str 
)
static

Get the path string associated with this contact and tdata.

Parameters
pool
contactThe URI identifying the associated contact
path_strThe place to store the retrieved path information
Return values
zeroon success
non-zeroon failure or no available path information

Definition at line 164 of file res_pjsip_path.c.

165{
166 if (!contact || ast_strlen_zero(contact->path)) {
167 return -1;
168 }
169
170 *path_str = pj_strdup3(pool, contact->path);
171 return 0;
172}
const ast_string_field path
Definition res_pjsip.h:412

References ast_strlen_zero(), and ast_sip_contact::path.

Referenced by path_outgoing_response().

◆ path_outgoing_request()

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

Definition at line 216 of file res_pjsip_path.c.

217{
218 RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
219
220 if (!endpoint) {
221 return;
222 }
223
224 aor = find_aor(contact);
225 if (!aor) {
226 aor = find_aor2(endpoint, tdata->msg->line.req.uri);
227 }
228 if (!aor || !aor->support_path) {
229 return;
230 }
231
232 if (add_supported(tdata)) {
233 return;
234 }
235
236 if (!contact) {
237 contact = find_contact(aor, tdata->msg->line.req.uri);
238 if (contact) {
239 if (!ast_strlen_zero(contact->path)) {
240 ast_sip_set_outbound_proxy(tdata, contact->path);
241 }
242 ao2_ref(contact, -1);
243 contact = NULL;
244 }
245 } else {
246 if (!ast_strlen_zero(contact->path)) {
247 ast_sip_set_outbound_proxy(tdata, contact->path);
248 }
249 }
250}
int ast_sip_set_outbound_proxy(pjsip_tx_data *tdata, const char *proxy)
Set the outbound proxy for an outbound SIP message.
Definition res_pjsip.c:1992
static struct ast_sip_aor * find_aor(struct ast_sip_contact *contact)
static struct ast_sip_contact * find_contact(struct ast_sip_aor *aor, pjsip_uri *uri)
static int add_supported(pjsip_tx_data *tdata)
static struct ast_sip_aor * find_aor2(struct ast_sip_endpoint *endpoint, pjsip_uri *uri)
A SIP address of record.
Definition res_pjsip.h:478

References add_supported(), ao2_cleanup, ao2_ref, ast_sip_contact::aor, ast_sip_set_outbound_proxy(), ast_strlen_zero(), ast_sip_contact::endpoint, find_aor(), find_aor2(), find_contact(), NULL, ast_sip_contact::path, and RAII_VAR.

Referenced by path_session_outgoing_request().

◆ path_outgoing_response()

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

Definition at line 265 of file res_pjsip_path.c.

266{
267 struct pjsip_status_line status = tdata->msg->line.status;
268 pj_str_t path_dup;
269 pjsip_generic_string_hdr *path_hdr;
270 RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
271 pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
272 const pj_str_t REGISTER_METHOD = {"REGISTER", 8};
273
274 if (!endpoint
275 || !pj_stristr(&REGISTER_METHOD, &cseq->method.name)
276 || !PJSIP_IS_STATUS_IN_CLASS(status.code, 200)) {
277 return;
278 }
279
280 aor = find_aor(contact);
281 if (!aor || !aor->support_path || add_supported(tdata)
282 || path_get_string(tdata->pool, contact, &path_dup)) {
283 return;
284 }
285
286 path_hdr = pjsip_generic_string_hdr_create(tdata->pool, &PATH_NAME, &path_dup);
287 if (!path_hdr) {
288 return;
289 }
290
291 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)path_hdr);
292}
jack_status_t status
Definition app_jack.c:149
static int path_get_string(pj_pool_t *pool, struct ast_sip_contact *contact, pj_str_t *path_str)
Get the path string associated with this contact and tdata.
static const pj_str_t PATH_NAME

References add_supported(), ao2_cleanup, find_aor(), NULL, path_get_string(), PATH_NAME, RAII_VAR, and status.

Referenced by path_session_outgoing_response().

◆ path_session_outgoing_request()

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

Definition at line 252 of file res_pjsip_path.c.

253{
254 path_outgoing_request(session->endpoint, session->contact, tdata);
255}
static struct ast_mansession session
static void path_outgoing_request(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, pjsip_tx_data *tdata)

References path_outgoing_request(), and session.

◆ path_session_outgoing_response()

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

Definition at line 294 of file res_pjsip_path.c.

295{
296 path_outgoing_response(session->endpoint, session->contact, tdata);
297}
static void path_outgoing_response(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, pjsip_tx_data *tdata)

References path_outgoing_response(), and session.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 319 of file res_pjsip_path.c.

320{
323 return 0;
324}
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(), path_session_supplement, and path_supplement.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP Path Header Support" , .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 332 of file res_pjsip_path.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 332 of file res_pjsip_path.c.

◆ PATH_NAME

const pj_str_t PATH_NAME = { "Path", 4 }
static

Definition at line 36 of file res_pjsip_path.c.

36{ "Path", 4 };

Referenced by path_outgoing_response().

◆ path_session_supplement

struct ast_sip_session_supplement path_session_supplement
static
Initial value:
= {
.outgoing_request = path_session_outgoing_request,
.outgoing_response = path_session_outgoing_response,
}
@ AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL
Definition res_pjsip.h:3339
static void path_session_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
static void path_session_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)

Definition at line 305 of file res_pjsip_path.c.

305 {
306 .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL - 100,
307 .outgoing_request = path_session_outgoing_request,
308 .outgoing_response = path_session_outgoing_response,
309};

Referenced by load_module(), and unload_module().

◆ path_supplement

struct ast_sip_supplement path_supplement
static
Initial value:
= {
.outgoing_request = path_outgoing_request,
.outgoing_response = path_outgoing_response,
}

Definition at line 299 of file res_pjsip_path.c.

299 {
300 .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL - 100,
301 .outgoing_request = path_outgoing_request,
302 .outgoing_response = path_outgoing_response,
303};

Referenced by load_module(), and unload_module().

◆ PATH_SUPPORTED_NAME

pj_str_t PATH_SUPPORTED_NAME = { "path", 4 }
static

Definition at line 37 of file res_pjsip_path.c.

37{ "path", 4 };

Referenced by add_supported().