Asterisk - The Open Source Telephony Project GIT-master-f36a736
pjsip_global_headers.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2013, Digium, Inc.
5 *
6 * Mark Michelson <mmichelson@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19#include "asterisk.h"
20
21#include <pjsip.h>
22#include <pjlib.h>
23
24#include "asterisk/res_pjsip.h"
27
28static pj_status_t add_request_headers(pjsip_tx_data *tdata);
29static pj_status_t add_response_headers(pjsip_tx_data *tdata);
30
31/*!
32 * \brief Indicator we've already handled a specific request/response
33 *
34 * PJSIP tends to reuse requests and responses. If we already have added
35 * headers to a request or response, we mark the message with this value
36 * so that we know not to re-add the headers again.
37 */
38static unsigned int handled_id = 0xCA115785;
39
40static pjsip_module global_header_mod = {
41 .name = {"Global headers", 13},
42 .priority = PJSIP_MOD_PRIORITY_APPLICATION,
43 .on_tx_request = add_request_headers,
44 .on_tx_response = add_response_headers,
45};
46
47struct header {
51 );
53};
54
55static struct header *alloc_header(const char *name, const char *value)
56{
57 struct header *alloc;
58
59 alloc = ast_calloc_with_stringfields(1, struct header, 32);
60
61 if (!alloc) {
62 return NULL;
63 }
64
67
68 return alloc;
69}
70
71static void destroy_header(struct header *to_destroy)
72{
74 ast_free(to_destroy);
75}
76
78
81
82static void add_headers_to_message(struct header_list *headers, pjsip_tx_data *tdata)
83{
84 struct header *iter;
86 if (tdata->mod_data[global_header_mod.id] == &handled_id) {
87 return;
88 }
89 AST_LIST_TRAVERSE(headers, iter, next) {
90 pj_str_t name;
91 pjsip_generic_string_hdr *hdr;
92
93 hdr = pjsip_msg_find_hdr_by_name(tdata->msg, pj_cstr(&name, iter->name), NULL);
94 if (hdr) {
95 continue;
96 }
97
98 ast_sip_add_header(tdata, iter->name, iter->value);
99 };
100 tdata->mod_data[global_header_mod.id] = &handled_id;
101}
102
103static pj_status_t add_request_headers(pjsip_tx_data *tdata)
104{
106
107 return PJ_SUCCESS;
108}
109
110static pj_status_t add_response_headers(pjsip_tx_data *tdata)
111{
113
114 return PJ_SUCCESS;
115}
116
117static void remove_header(struct header_list *headers, const char *to_remove)
118{
119 struct header *iter;
120 AST_LIST_TRAVERSE_SAFE_BEGIN(headers, iter, next) {
121 if (!strcasecmp(iter->name, to_remove)) {
123 destroy_header(iter);
124 break;
125 }
126 }
128}
129
130static int add_header(struct header_list *headers, const char *name, const char *value, int replace)
131{
132 struct header *to_add = NULL;
133
134 if (!ast_strlen_zero(value)) {
135 to_add = alloc_header(name, value);
136 if (!to_add) {
137 return -1;
138 }
139 }
140
141 AST_RWLIST_WRLOCK(headers);
142 if (replace) {
143 remove_header(headers, name);
144 }
145 if (to_add) {
146 AST_LIST_INSERT_TAIL(headers, to_add, next);
147 }
148 AST_RWLIST_UNLOCK(headers);
149
150 return 0;
151}
152
153int ast_sip_add_global_request_header(const char *name, const char *value, int replace)
154{
156}
157
158int ast_sip_add_global_response_header(const char *name, const char *value, int replace)
159{
161}
162
164{
167
169}
170
171static void destroy_headers(struct header_list *headers)
172{
173 struct header *iter;
174
175 while ((iter = AST_RWLIST_REMOVE_HEAD(headers, next))) {
176 destroy_header(iter);
177 }
179}
180
182{
185
187}
ast_mutex_t lock
Definition: app_sla.c:331
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
static const char name[]
Definition: format_mp3.c:68
static int replace(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
Definition: func_strings.c:888
A set of macros to manage forward-linked lists.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_RWLIST_HEAD_INIT(head)
Initializes an rwlist head structure.
Definition: linkedlists.h:639
#define AST_RWLIST_REMOVE_HEAD
Definition: linkedlists.h:844
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:410
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_RWLIST_HEAD(name, type)
Defines a structure to be used to hold a read/write list of specified type.
Definition: linkedlists.h:199
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
#define AST_RWLIST_HEAD_DESTROY(head)
Destroys an rwlist head structure.
Definition: linkedlists.h:667
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:583
static void destroy_header(struct header *to_destroy)
static void destroy_headers(struct header_list *headers)
static struct header * alloc_header(const char *name, const char *value)
static pjsip_module global_header_mod
static void remove_header(struct header_list *headers, const char *to_remove)
static int add_header(struct header_list *headers, const char *name, const char *value, int replace)
static unsigned int handled_id
Indicator we've already handled a specific request/response.
void ast_sip_initialize_global_headers(void)
static void add_headers_to_message(struct header_list *headers, pjsip_tx_data *tdata)
int ast_sip_add_global_request_header(const char *name, const char *value, int replace)
static struct header_list request_headers
static pj_status_t add_response_headers(pjsip_tx_data *tdata)
static struct header_list response_headers
int ast_sip_add_global_response_header(const char *name, const char *value, int replace)
static pj_status_t add_request_headers(pjsip_tx_data *tdata)
void ast_sip_destroy_global_headers(void)
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:133
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition: res_pjsip.c:117
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message.
Definition: res_pjsip.c:2008
#define NULL
Definition: resample.c:96
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
Definition: stringfields.h:341
#define ast_calloc_with_stringfields(n, type, size)
Allocate a structure with embedded stringfields in a single allocation.
Definition: stringfields.h:432
#define AST_STRING_FIELD(name)
Declare a string field.
Definition: stringfields.h:303
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
const ast_string_field value
const ast_string_field name
struct header * next
int value
Definition: syslog.c:37