/src/opensips/core_cmds.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2019 OpenSIPS Solutions |
3 | | * |
4 | | * This file is part of opensips, a free SIP server. |
5 | | * |
6 | | * opensips is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version |
10 | | * |
11 | | * opensips is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | * |
20 | | */ |
21 | | |
22 | | /* |
23 | | * Script functions exported by the OpenSIPS core |
24 | | */ |
25 | | |
26 | | #include "action.h" |
27 | | #include "dprint.h" |
28 | | #include "proxy.h" |
29 | | #include "forward.h" |
30 | | #include "parser/msg_parser.h" |
31 | | #include "parser/parse_uri.h" |
32 | | #include "ut.h" |
33 | | #include "mem/mem.h" |
34 | | #include "globals.h" |
35 | | #include "dset.h" |
36 | | #include "flags.h" |
37 | | #include "serialize.h" |
38 | | #include "blacklists.h" |
39 | | #include "status_report.h" |
40 | | #include "cachedb/cachedb.h" |
41 | | #include "msg_translator.h" |
42 | | #include "mod_fix.h" |
43 | | /* needed by tcpconn_add_alias() */ |
44 | | #include "net/tcp_conn_defs.h" |
45 | | |
46 | | static int fixup_forward_dest(void** param); |
47 | | static int fixup_destination(void** param); |
48 | | static int fixup_free_destination(void** param); |
49 | | static int fixup_mflag(void** param); |
50 | | static int fixup_bflag(void** param); |
51 | | static int fixup_qvalue(void** param); |
52 | | static int fixup_branch_keep(void** param); |
53 | | static int fixup_branch_index(void** param); |
54 | | static int fixup_f_send_sock(void** param); |
55 | | static int fixup_blacklist_name(void** param); |
56 | | static int fixup_blacklist(void** param); |
57 | | static int fixup_blacklist_ip(void** param); |
58 | | static int fixup_blacklist_free(void** param); |
59 | | static int fixup_check_wrvar(void** param); |
60 | | static int fixup_avp_list(void** param); |
61 | | static int fixup_check_avp(void** param); |
62 | | static int fixup_event_name(void** param); |
63 | | static int fixup_event_name_subs(void** param); |
64 | | static int fixup_format_string(void** param); |
65 | | static int fixup_nt_string(void** param); |
66 | | static int fixup_nt_str(void** param); |
67 | | static int fixup_nt_str_free(void** param); |
68 | | static int fixup_via_hdl(void** param); |
69 | | static int fixup_append_mbranch_flags(void** param); |
70 | | |
71 | | |
72 | | static int w_forward(struct sip_msg *msg, struct proxy_l *dest); |
73 | | static int w_send(struct sip_msg *msg, struct proxy_l *dest, str *headers); |
74 | | static int w_setflag(struct sip_msg *msg, void *flag); |
75 | | static int w_resetflag(struct sip_msg *msg, void *flag); |
76 | | static int w_isflagset(struct sip_msg *msg, void *flag); |
77 | | static int w_setbflag(struct sip_msg *msg, void *flag, int *branch_idx); |
78 | | static int w_resetbflag(struct sip_msg *msg, void *flag, int *branch_idx); |
79 | | static int w_isbflagset(struct sip_msg *msg, void *flag, int *branch_idx); |
80 | | static int w_sethost(struct sip_msg *msg, str *host); |
81 | | static int w_sethostport(struct sip_msg *msg, str *hostport); |
82 | | static int w_setuser(struct sip_msg *msg, str *user); |
83 | | static int w_setuserpass(struct sip_msg *msg, str *userpass); |
84 | | static int w_setport(struct sip_msg *msg, str *port); |
85 | | static int w_seturi(struct sip_msg *msg, str *uri); |
86 | | static int w_prefix(struct sip_msg *msg, str *prefix); |
87 | | static int w_strip(struct sip_msg *msg, int *nchars); |
88 | | static int w_strip_tail(struct sip_msg *msg, int *nchars); |
89 | | static int w_append_branch_old(struct sip_msg *msg, str *uri, int *qvalue); |
90 | | static int w_append_msg_branch(struct sip_msg *msg, str *uri, int *qvalue, |
91 | | void *flags); |
92 | | static int w_remove_msg_branch(struct sip_msg *msg, int *branch); |
93 | | static int w_move_msg_branch(struct sip_msg *msg, |
94 | | int *src_idx, int *dst_idx, int *keep); |
95 | | static int w_swap_msg_branches(struct sip_msg *msg, |
96 | | int *src_idx, int *dst_idx); |
97 | | static int w_pv_printf(struct sip_msg *msg, pv_spec_t *var, str *fmt_str); |
98 | | static int w_revert_uri(struct sip_msg *msg); |
99 | | static int w_setdsturi(struct sip_msg *msg, str *uri); |
100 | | static int w_resetdsturi(struct sip_msg *msg); |
101 | | static int w_isdsturiset(struct sip_msg *msg); |
102 | | static int w_force_rport(struct sip_msg *msg); |
103 | | static int w_add_local_rport(struct sip_msg *msg); |
104 | | static int w_force_tcp_alias(struct sip_msg *msg, int *port); |
105 | | static int w_set_adv_address(struct sip_msg *msg, str *adv_addr); |
106 | | static int w_set_adv_port(struct sip_msg *msg, str *adv_port); |
107 | | static int w_f_send_sock(struct sip_msg *msg, struct socket_info *si); |
108 | | static int w_serialize_branches(struct sip_msg *msg, int *clear_prev, |
109 | | int *keep_ord); |
110 | | static int w_next_branches(struct sip_msg *msg); |
111 | | static int w_use_blacklist(struct sip_msg *msg, struct bl_head *list); |
112 | | static int w_unuse_blacklist(struct sip_msg *msg, struct bl_head *list); |
113 | | static int w_cache_store(struct sip_msg *msg, str *id, str *attr, str *val, |
114 | | int *expire); |
115 | | static int w_cache_remove(struct sip_msg *msg, str *id, str *attr); |
116 | | static int w_cache_fetch(struct sip_msg *msg, str *id, str *attr, |
117 | | pv_spec_t *res); |
118 | | static int w_cache_counter_fetch(struct sip_msg *msg, str *id, str *attr, |
119 | | pv_spec_t *res); |
120 | | static int w_cache_add(struct sip_msg *msg, str *id, str *attr, |
121 | | int *inc, int *expire, pv_spec_t *new_val); |
122 | | static int w_cache_sub(struct sip_msg *msg, str *id, str *attr, |
123 | | int *dec, int *expire, pv_spec_t *new_val); |
124 | | static int w_cache_raw_query(struct sip_msg *msg, str *id, str *raw_query, |
125 | | pvname_list_t *avp_list); |
126 | | static int w_raise_event(struct sip_msg *msg, void *ev_id, pv_spec_t *attrs_avp, |
127 | | pv_spec_t *vals_avp); |
128 | | static int w_subscribe_event(struct sip_msg *msg, str *name, str *socket, |
129 | | int *expire); |
130 | | static int w_construct_uri(struct sip_msg *msg, str *proto, str *user, |
131 | | str *domain, str *port, str *extra, pv_spec_t *result); |
132 | | static int w_get_timestamp(struct sip_msg *msg, pv_spec_t *sec_avp, |
133 | | pv_spec_t *usec_avp); |
134 | | static int w_script_trace(struct sip_msg *msg, int *log_level, |
135 | | pv_elem_t *fmt_string, void *info_str); |
136 | | static int w_is_myself(struct sip_msg *msg, str *host, int *port); |
137 | | static int w_print_avps(struct sip_msg* msg, char* foo, char *bar); |
138 | | static int w_set_via_handling(struct sip_msg* msg, int flags); |
139 | | |
140 | | #ifndef FUZZ_BUILD |
141 | | static |
142 | | #endif |
143 | | const cmd_export_t core_cmds[]={ |
144 | | {"forward", (cmd_function)w_forward, { |
145 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, |
146 | | fixup_forward_dest, fixup_free_destination}, {0,0,0}}, |
147 | | ALL_ROUTES}, |
148 | | {"send", (cmd_function)w_send, { |
149 | | {CMD_PARAM_STR, fixup_destination, 0}, |
150 | | {CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, |
151 | | ALL_ROUTES}, |
152 | | {"setflag", (cmd_function)w_setflag, { |
153 | | {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_mflag, 0}, {0,0,0}}, |
154 | | ALL_ROUTES}, |
155 | | {"resetflag", (cmd_function)w_resetflag, { |
156 | | {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_mflag, 0}, {0,0,0}}, |
157 | | ALL_ROUTES}, |
158 | | {"isflagset", (cmd_function)w_isflagset, { |
159 | | {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_mflag, 0}, {0,0,0}}, |
160 | | ALL_ROUTES}, |
161 | | {"setbflag", (cmd_function)w_setbflag, { |
162 | | {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_bflag, 0}, |
163 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, |
164 | | ALL_ROUTES}, |
165 | | {"resetbflag", (cmd_function)w_resetbflag, { |
166 | | {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_bflag, 0}, |
167 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, |
168 | | ALL_ROUTES}, |
169 | | {"isbflagset", (cmd_function)w_isbflagset, { |
170 | | {CMD_PARAM_STR|CMD_PARAM_STATIC, fixup_bflag, 0}, |
171 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, |
172 | | ALL_ROUTES}, |
173 | | {"sethost", (cmd_function)w_sethost, { |
174 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
175 | | ALL_ROUTES}, |
176 | | {"sethostport", (cmd_function)w_sethostport, { |
177 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
178 | | ALL_ROUTES}, |
179 | | {"setuser", (cmd_function)w_setuser, { |
180 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
181 | | ALL_ROUTES}, |
182 | | {"setuserpass", (cmd_function)w_setuserpass, { |
183 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
184 | | ALL_ROUTES}, |
185 | | {"setport", (cmd_function)w_setport, { |
186 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
187 | | ALL_ROUTES}, |
188 | | {"seturi", (cmd_function)w_seturi, { |
189 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
190 | | ALL_ROUTES}, |
191 | | {"prefix", (cmd_function)w_prefix, { |
192 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
193 | | ALL_ROUTES}, |
194 | | {"strip", (cmd_function)w_strip, { |
195 | | {CMD_PARAM_INT, 0, 0}, {0,0,0}}, |
196 | | ALL_ROUTES}, |
197 | | {"strip_tail", (cmd_function)w_strip_tail, { |
198 | | {CMD_PARAM_INT, 0, 0}, {0,0,0}}, |
199 | | ALL_ROUTES}, |
200 | | {"append_branch_old", (cmd_function)w_append_branch_old, { |
201 | | {CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0}, |
202 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, |
203 | | fixup_qvalue, 0}, {0,0,0}}, |
204 | | ALL_ROUTES}, |
205 | | {"append_msg_branch", (cmd_function)w_append_msg_branch, { |
206 | | {CMD_PARAM_STR, 0, 0}, |
207 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, |
208 | | fixup_qvalue, 0}, |
209 | | {CMD_PARAM_STR|CMD_PARAM_OPT,fixup_append_mbranch_flags,0}, |
210 | | {0,0,0}}, |
211 | | ALL_ROUTES}, |
212 | | {"remove_msg_branch", (cmd_function)w_remove_msg_branch, { |
213 | | {CMD_PARAM_INT, 0, 0}, {0,0,0}}, |
214 | | ALL_ROUTES}, |
215 | | {"move_msg_branch", (cmd_function)w_move_msg_branch, { |
216 | | {CMD_PARAM_INT|CMD_PARAM_OPT, fixup_branch_index, 0}, |
217 | | {CMD_PARAM_INT|CMD_PARAM_OPT, fixup_branch_index, 0}, |
218 | | {CMD_PARAM_STR|CMD_PARAM_OPT, fixup_branch_keep, 0}, |
219 | | {0,0,0}}, |
220 | | ALL_ROUTES}, |
221 | | {"swap_msg_branches", (cmd_function)w_swap_msg_branches, { |
222 | | {CMD_PARAM_INT|CMD_PARAM_OPT, fixup_branch_index, 0}, |
223 | | {CMD_PARAM_INT|CMD_PARAM_OPT, fixup_branch_index, 0}, |
224 | | {0,0,0}}, |
225 | | ALL_ROUTES}, |
226 | | {"pv_printf", (cmd_function)w_pv_printf, { |
227 | | {CMD_PARAM_VAR, 0, 0}, |
228 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
229 | | ALL_ROUTES}, |
230 | | {"revert_uri", (cmd_function)w_revert_uri, { |
231 | | {0, 0, 0}, {0,0,0}}, |
232 | | ALL_ROUTES}, |
233 | | {"setdsturi", (cmd_function)w_setdsturi, { |
234 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
235 | | ALL_ROUTES}, |
236 | | {"resetdsturi", (cmd_function)w_resetdsturi, { |
237 | | {0, 0, 0}, {0,0,0}}, |
238 | | ALL_ROUTES}, |
239 | | {"isdsturiset", (cmd_function)w_isdsturiset, { |
240 | | {0, 0, 0}, {0,0,0}}, |
241 | | ALL_ROUTES}, |
242 | | {"force_rport", (cmd_function)w_force_rport, { |
243 | | {0, 0, 0}, {0,0,0}}, |
244 | | ALL_ROUTES}, |
245 | | {"add_local_rport", (cmd_function)w_add_local_rport, { |
246 | | {0, 0, 0}, {0,0,0}}, |
247 | | ALL_ROUTES}, |
248 | | {"force_tcp_alias", (cmd_function)w_force_tcp_alias, { |
249 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, |
250 | | ALL_ROUTES}, |
251 | | {"set_advertised_address", (cmd_function)w_set_adv_address, { |
252 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
253 | | ALL_ROUTES}, |
254 | | {"set_advertised_port", (cmd_function)w_set_adv_port, { |
255 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
256 | | ALL_ROUTES}, |
257 | | {"force_send_socket", (cmd_function)w_f_send_sock, { |
258 | | {CMD_PARAM_STR, fixup_f_send_sock, 0}, {0,0,0}}, |
259 | | ALL_ROUTES}, |
260 | | {"serialize_branches", (cmd_function)w_serialize_branches, { |
261 | | {CMD_PARAM_INT, 0, 0}, |
262 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, |
263 | | ALL_ROUTES}, |
264 | | {"next_branches", (cmd_function)w_next_branches, { |
265 | | {0, 0, 0}, {0,0,0}}, |
266 | | ALL_ROUTES}, |
267 | | {"use_blacklist", (cmd_function)w_use_blacklist, { |
268 | | {CMD_PARAM_STR, fixup_blacklist, 0}, {0,0,0}}, |
269 | | ALL_ROUTES}, |
270 | | {"unuse_blacklist", (cmd_function)w_unuse_blacklist, { |
271 | | {CMD_PARAM_STR, fixup_blacklist, 0}, {0,0,0}}, |
272 | | ALL_ROUTES}, |
273 | | {"check_blacklist_rule", (cmd_function)w_check_blacklist, { |
274 | | {CMD_PARAM_STR, fixup_blacklist, 0}, |
275 | | {CMD_PARAM_STR, fixup_blacklist_ip, fixup_blacklist_free}, /* ip */ |
276 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, /* port */ |
277 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, |
278 | | fixup_blacklist_proto, 0}, /* proto */ |
279 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, |
280 | | fixup_nt_str, fixup_nt_str_free}, /* pattern */ |
281 | | {0,0,0}}, |
282 | | ALL_ROUTES}, |
283 | | {"add_blacklist_rule", (cmd_function)w_add_blacklist_rule, { |
284 | | {CMD_PARAM_STR, fixup_blacklist_name, 0}, |
285 | | {CMD_PARAM_STR, fixup_blacklist_net, fixup_blacklist_net_free}, /* ip */ |
286 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, /* port */ |
287 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, |
288 | | fixup_blacklist_proto, 0}, /* proto */ |
289 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, |
290 | | fixup_nt_str, fixup_nt_str_free}, /* pattern */ |
291 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, /* expire */ |
292 | | {0,0,0}}, |
293 | | ALL_ROUTES}, |
294 | | {"del_blacklist_rule", (cmd_function)w_del_blacklist_rule, { |
295 | | {CMD_PARAM_STR, fixup_blacklist_name, 0}, |
296 | | {CMD_PARAM_STR, fixup_blacklist_net, fixup_blacklist_net_free}, /* ip */ |
297 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, /* port */ |
298 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, |
299 | | fixup_blacklist_proto, 0}, /* proto */ |
300 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_FIX_NULL, |
301 | | fixup_nt_str, fixup_nt_str_free}, /* pattern */ |
302 | | {0,0,0}}, |
303 | | ALL_ROUTES}, |
304 | | {"cache_store", (cmd_function)w_cache_store, { |
305 | | {CMD_PARAM_STR, 0, 0}, |
306 | | {CMD_PARAM_STR, 0, 0}, |
307 | | {CMD_PARAM_STR, 0, 0}, |
308 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, |
309 | | ALL_ROUTES}, |
310 | | {"cache_remove", (cmd_function)w_cache_remove, { |
311 | | {CMD_PARAM_STR, 0, 0}, |
312 | | {CMD_PARAM_STR, 0, 0}, {0,0,0}}, |
313 | | ALL_ROUTES}, |
314 | | {"cache_fetch", (cmd_function)w_cache_fetch, { |
315 | | {CMD_PARAM_STR, 0, 0}, |
316 | | {CMD_PARAM_STR, 0, 0}, |
317 | | {CMD_PARAM_VAR, fixup_check_wrvar, 0}, {0,0,0}}, |
318 | | ALL_ROUTES}, |
319 | | {"cache_counter_fetch", (cmd_function)w_cache_counter_fetch, { |
320 | | {CMD_PARAM_STR, 0, 0}, |
321 | | {CMD_PARAM_STR, 0, 0}, |
322 | | {CMD_PARAM_VAR, fixup_check_wrvar, 0}, {0,0,0}}, |
323 | | ALL_ROUTES}, |
324 | | {"cache_add", (cmd_function)w_cache_add, { |
325 | | {CMD_PARAM_STR, 0, 0}, |
326 | | {CMD_PARAM_STR, 0, 0}, |
327 | | {CMD_PARAM_INT, 0, 0}, |
328 | | {CMD_PARAM_INT, 0, 0}, |
329 | | {CMD_PARAM_VAR|CMD_PARAM_OPT, fixup_check_wrvar, 0}, {0,0,0}}, |
330 | | ALL_ROUTES}, |
331 | | {"cache_sub", (cmd_function)w_cache_sub, { |
332 | | {CMD_PARAM_STR, 0, 0}, |
333 | | {CMD_PARAM_STR, 0, 0}, |
334 | | {CMD_PARAM_INT, 0, 0}, |
335 | | {CMD_PARAM_INT, 0, 0}, |
336 | | {CMD_PARAM_VAR|CMD_PARAM_OPT, fixup_check_wrvar, 0}, {0,0,0}}, |
337 | | ALL_ROUTES}, |
338 | | {"cache_raw_query", (cmd_function)w_cache_raw_query, { |
339 | | {CMD_PARAM_STR, 0, 0}, |
340 | | {CMD_PARAM_STR, 0, 0}, |
341 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_NO_EXPAND, fixup_avp_list, 0}, {0,0,0}}, |
342 | | ALL_ROUTES}, |
343 | | {"raise_event", (cmd_function)w_raise_event, { |
344 | | {CMD_PARAM_STR, fixup_event_name, 0}, |
345 | | {CMD_PARAM_VAR|CMD_PARAM_OPT, fixup_check_avp, 0}, |
346 | | {CMD_PARAM_VAR|CMD_PARAM_OPT, fixup_check_avp, 0}, {0,0,0}}, |
347 | | ALL_ROUTES}, |
348 | | {"subscribe_event", (cmd_function)w_subscribe_event, { |
349 | | {CMD_PARAM_STR, fixup_event_name_subs, 0}, |
350 | | {CMD_PARAM_STR, 0, 0}, |
351 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, |
352 | | ALL_ROUTES}, |
353 | | {"construct_uri", (cmd_function)w_construct_uri, { |
354 | | {CMD_PARAM_STR, 0, 0}, |
355 | | {CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0}, |
356 | | {CMD_PARAM_STR, 0, 0}, |
357 | | {CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0}, |
358 | | {CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0}, |
359 | | {CMD_PARAM_VAR, fixup_check_avp, 0}, {0,0,0}}, |
360 | | ALL_ROUTES}, |
361 | | {"get_timestamp", (cmd_function)w_get_timestamp, { |
362 | | {CMD_PARAM_VAR, fixup_check_avp, 0}, |
363 | | {CMD_PARAM_VAR, fixup_check_avp, 0}, {0,0,0}}, |
364 | | ALL_ROUTES}, |
365 | | {"script_trace", (cmd_function)w_script_trace, { |
366 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, |
367 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_NO_EXPAND, fixup_format_string, 0}, |
368 | | {CMD_PARAM_STR|CMD_PARAM_OPT|CMD_PARAM_STATIC, fixup_nt_string, 0}, |
369 | | {0,0,0}}, |
370 | | ALL_ROUTES}, |
371 | | {"is_myself", (cmd_function)w_is_myself, { |
372 | | {CMD_PARAM_STR, 0, 0}, |
373 | | {CMD_PARAM_INT|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, |
374 | | ALL_ROUTES}, |
375 | | {"sr_check_status", (cmd_function)w_sr_check_status, { |
376 | | {CMD_PARAM_STR, fixup_sr_group, 0}, |
377 | | {CMD_PARAM_STR|CMD_PARAM_OPT, 0, 0}, {0,0,0}}, |
378 | | ALL_ROUTES}, |
379 | | {"avp_print", (cmd_function)w_print_avps, {{0, 0, 0}}, |
380 | | ALL_ROUTES}, |
381 | | {"set_via_handling", (cmd_function)w_set_via_handling, { |
382 | | {CMD_PARAM_STR, fixup_via_hdl, 0}, {0,0,0}}, |
383 | | ALL_ROUTES}, |
384 | | {0,0,{{0,0,0}},0} |
385 | | }; |
386 | | |
387 | | |
388 | | const cmd_export_t* find_core_cmd_export_t(const char* name, int flags) |
389 | 0 | { |
390 | 0 | const cmd_export_t* cmd; |
391 | |
|
392 | 0 | for(cmd=core_cmds; cmd && cmd->name; cmd++){ |
393 | 0 | if((strcmp(name, cmd->name)==0)&&((cmd->flags & flags) == flags)){ |
394 | 0 | LM_DBG("found <%s> core function\n", name); |
395 | 0 | return cmd; |
396 | 0 | } |
397 | 0 | } |
398 | | |
399 | 0 | LM_DBG("<%s> not found \n", name); |
400 | 0 | return 0; |
401 | 0 | } |
402 | | |
403 | | |
404 | | static int fixup_destination(void** param) |
405 | 0 | { |
406 | 0 | str *s = (str*)*param; |
407 | 0 | str host; |
408 | 0 | int proto=PROTO_NONE, port; |
409 | |
|
410 | 0 | if (parse_phostport(s->s, s->len, &host.s, &host.len, &port, &proto) != 0) { |
411 | 0 | LM_ERR("Failed to parse destination\n"); |
412 | 0 | return E_CFG; |
413 | 0 | } |
414 | 0 | *param = mk_proxy(&host,(unsigned short)port, proto, 0); |
415 | 0 | if (*param==0) { |
416 | 0 | LM_ERR("Failed to create proxy struct\n"); |
417 | 0 | return E_CFG; |
418 | 0 | } |
419 | | |
420 | 0 | return 0; |
421 | 0 | } |
422 | | |
423 | | static int fixup_free_destination(void** param) |
424 | 0 | { |
425 | 0 | free_proxy(*param); |
426 | 0 | pkg_free(*param); |
427 | 0 | return 0; |
428 | 0 | } |
429 | | |
430 | | static int fixup_forward_dest(void** param) |
431 | 0 | { |
432 | 0 | if (sl_fwd_disabled>0) { |
433 | 0 | LM_ERR("stateless forwarding disabled, but forward() " |
434 | 0 | "is used!!\n"); |
435 | 0 | return E_CFG; |
436 | 0 | } |
437 | 0 | sl_fwd_disabled = 0; |
438 | |
|
439 | 0 | if (*param == NULL) |
440 | 0 | return 0; |
441 | 0 | return fixup_destination(param); |
442 | 0 | } |
443 | | |
444 | | static int fixup_mflag(void** param) |
445 | 0 | { |
446 | 0 | if ((*param = (void*)(long)fixup_flag(FLAG_TYPE_MSG, (str*)*param)) == |
447 | 0 | (void*)(long)NAMED_FLAG_ERROR) { |
448 | 0 | LM_ERR("Fixup flag failed!\n"); |
449 | 0 | return E_CFG; |
450 | 0 | } |
451 | | |
452 | 0 | return 0; |
453 | 0 | } |
454 | | |
455 | | static int fixup_bflag(void** param) |
456 | 0 | { |
457 | 0 | if ((*param = (void*)(long)fixup_flag(FLAG_TYPE_BRANCH, (str*)*param)) == |
458 | 0 | (void*)(long)NAMED_FLAG_ERROR) { |
459 | 0 | LM_ERR("Fixup flag failed!\n"); |
460 | 0 | return E_CFG; |
461 | 0 | } |
462 | | |
463 | 0 | return 0; |
464 | 0 | } |
465 | | |
466 | | static int fixup_qvalue(void** param) |
467 | 0 | { |
468 | 0 | int rc; |
469 | 0 | qvalue_t q; |
470 | 0 | str *s = (str*)*param; |
471 | |
|
472 | 0 | if (s==NULL) { |
473 | 0 | *param = (void*)(long)Q_UNSPECIFIED; |
474 | 0 | return 0; |
475 | 0 | } |
476 | | |
477 | 0 | if ((rc = str2q(&q, s->s, s->len)) < 0) { |
478 | 0 | LM_ERR("Bad qvalue (%.*s): %s\n", s->len, s->s, qverr2str(rc)); |
479 | 0 | return E_CFG; |
480 | 0 | } |
481 | | |
482 | 0 | *param = (void*)(long)q; |
483 | 0 | return 0; |
484 | 0 | } |
485 | | |
486 | | static int fixup_branch_keep(void** param) |
487 | 0 | { |
488 | 0 | str *s = (str*)*param; |
489 | | |
490 | | /* default value is to discard */ |
491 | 0 | *param = (void*)(long)0; |
492 | 0 | if (!s) |
493 | 0 | return 0; |
494 | | |
495 | 0 | if (str_strcasecmp(s, _str("keep")) == 0) |
496 | 0 | *param = (void*)(long)1; |
497 | 0 | return 0; |
498 | 0 | } |
499 | | |
500 | | static int fixup_branch_index(void** param) |
501 | 0 | { |
502 | 0 | int *i = (int *)*param; |
503 | | |
504 | | /* default value is -1 */ |
505 | 0 | if (!i || *i < 0) |
506 | 0 | *param = NULL; /* normalize to NULL */ |
507 | 0 | else if (*i >= MAX_BRANCHES) { |
508 | 0 | LM_ERR("invalid branch index %d\n", *i); |
509 | 0 | return -1; |
510 | 0 | } |
511 | | /* else allow the branch provisioned */ |
512 | | |
513 | 0 | return 0; |
514 | 0 | } |
515 | | |
516 | | static int fixup_f_send_sock(void** param) |
517 | 0 | { |
518 | 0 | str *s = (str*)*param; |
519 | 0 | str host, host_nt; |
520 | 0 | int proto=PROTO_NONE, port; |
521 | 0 | struct hostent* he; |
522 | 0 | const struct socket_info* si; |
523 | 0 | struct ip_addr ip; |
524 | |
|
525 | 0 | if (parse_phostport(s->s, s->len, &host.s, &host.len, &port, &proto) != 0) { |
526 | 0 | LM_ERR("Failed to parse socket\n"); |
527 | 0 | return E_CFG; |
528 | 0 | } |
529 | 0 | if (pkg_nt_str_dup(&host_nt, &host) < 0) { |
530 | 0 | LM_ERR("oom\n"); |
531 | 0 | return E_OUT_OF_MEM; |
532 | 0 | } |
533 | | |
534 | 0 | he=resolvehost(host_nt.s,0); |
535 | 0 | if (he==0){ |
536 | 0 | LM_ERR(" could not resolve %s\n", host_nt.s); |
537 | 0 | goto error; |
538 | 0 | } |
539 | 0 | hostent2ip_addr(&ip, he, 0); |
540 | 0 | si=find_si(&ip, port, proto); |
541 | 0 | if (si==0){ |
542 | 0 | LM_ERR("bad force_send_socket" |
543 | 0 | " argument: %s:%d (opensips doesn't listen on it)\n", |
544 | 0 | host_nt.s, port); |
545 | 0 | goto error; |
546 | 0 | } |
547 | | |
548 | 0 | pkg_free(host_nt.s); |
549 | |
|
550 | 0 | const void **_param = (const void **)param; |
551 | 0 | *_param = si; |
552 | 0 | return 0; |
553 | | |
554 | 0 | error: |
555 | 0 | pkg_free(host_nt.s); |
556 | 0 | return E_BAD_ADDRESS; |
557 | 0 | } |
558 | | |
559 | | static int fixup_blacklist_name(void** param) |
560 | 0 | { |
561 | 0 | str *s = (str*)*param; |
562 | 0 | *param = get_bl_head_by_name(s); |
563 | 0 | if (!*param) { |
564 | 0 | LM_ERR("blacklist %.*s not configured\n", s->len, s->s); |
565 | 0 | return E_CFG; |
566 | 0 | } |
567 | 0 | return 0; |
568 | 0 | } |
569 | | |
570 | | static int fixup_blacklist(void** param) |
571 | 0 | { |
572 | 0 | str *s = (str*)*param; |
573 | |
|
574 | 0 | if (!str_strcasecmp(s, _str("all"))) { |
575 | 0 | *param = NULL; |
576 | 0 | return 0; |
577 | 0 | } else { |
578 | 0 | return fixup_blacklist_name(param); |
579 | 0 | } |
580 | 0 | } |
581 | | |
582 | | static int fixup_blacklist_free(void** param) |
583 | 0 | { |
584 | 0 | pkg_free(*param); |
585 | 0 | return 0; |
586 | 0 | } |
587 | | |
588 | | static int fixup_blacklist_ip(void** param) |
589 | 0 | { |
590 | 0 | str *s = (str*)*param; |
591 | 0 | struct ip_addr *ip_pkg; |
592 | 0 | struct ip_addr *ip = str2ip(s); |
593 | 0 | if (!ip) |
594 | 0 | return E_BAD_ADDRESS; |
595 | 0 | ip_pkg = pkg_malloc(sizeof *ip_pkg); |
596 | 0 | if (!ip_pkg) |
597 | 0 | return E_OUT_OF_MEM; |
598 | 0 | memcpy(ip_pkg, ip, sizeof *ip_pkg); |
599 | 0 | *param = ip_pkg; |
600 | 0 | return 0; |
601 | 0 | } |
602 | | |
603 | | static int fixup_check_wrvar(void** param) |
604 | 0 | { |
605 | 0 | if (((pv_spec_t *)*param)->setf == NULL) { |
606 | 0 | LM_ERR("Output parameter must be a writable variable\n"); |
607 | 0 | return E_CFG; |
608 | 0 | } |
609 | | |
610 | 0 | return 0; |
611 | 0 | } |
612 | | |
613 | | static int fixup_avp_list(void** param) |
614 | 0 | { |
615 | 0 | str *s = (str*)*param; |
616 | |
|
617 | 0 | *param = parse_pvname_list(s, PVT_AVP); |
618 | 0 | if (!*param) { |
619 | 0 | LM_ERR("Failed to parse AVP list\n"); |
620 | 0 | return E_UNSPEC; |
621 | 0 | } |
622 | | |
623 | 0 | return 0; |
624 | 0 | } |
625 | | |
626 | | static int fixup_check_avp(void** param) |
627 | 0 | { |
628 | 0 | if (((pv_spec_t *)*param)->type != PVT_AVP) { |
629 | 0 | LM_ERR("Parameter must be an AVP\n"); |
630 | 0 | return E_CFG; |
631 | 0 | } |
632 | | |
633 | 0 | return 0; |
634 | 0 | } |
635 | | |
636 | | static int fixup_event_name(void** param) |
637 | 0 | { |
638 | 0 | str *s = (str*)*param; |
639 | 0 | event_id_t ev_id; |
640 | |
|
641 | 0 | ev_id = evi_get_id(s); |
642 | 0 | if (ev_id == EVI_ERROR) { |
643 | 0 | ev_id = evi_publish_event(*s); |
644 | 0 | if (ev_id == EVI_ERROR) { |
645 | 0 | LM_ERR("cannot subscribe event\n"); |
646 | 0 | return E_UNSPEC; |
647 | 0 | } |
648 | 0 | } |
649 | | |
650 | 0 | *param = (void*)(long)ev_id; |
651 | 0 | return 0; |
652 | 0 | } |
653 | | |
654 | | static int fixup_event_name_subs(void** param) |
655 | 0 | { |
656 | 0 | str *s = (str*)*param; |
657 | 0 | event_id_t ev_id; |
658 | |
|
659 | 0 | ev_id = evi_get_id(s); |
660 | 0 | if (ev_id == EVI_ERROR) { |
661 | 0 | ev_id = evi_publish_event(*s); |
662 | 0 | if (ev_id == EVI_ERROR) { |
663 | 0 | LM_ERR("cannot subscribe event\n"); |
664 | 0 | return E_UNSPEC; |
665 | 0 | } |
666 | 0 | } |
667 | | |
668 | 0 | return 0; |
669 | 0 | } |
670 | | |
671 | | static int fixup_format_string(void** param) |
672 | 0 | { |
673 | 0 | str *s = (str*)*param; |
674 | |
|
675 | 0 | if (pv_parse_format(s, (pv_elem_t**)param) < 0) { |
676 | 0 | LM_ERR("Failed to parse format string\n"); |
677 | 0 | return E_CFG; |
678 | 0 | } |
679 | | |
680 | 0 | return 0; |
681 | 0 | } |
682 | | |
683 | | static int fixup_nt_string(void** param) |
684 | 0 | { |
685 | 0 | str *s = (str*)*param; |
686 | 0 | str s_nt; |
687 | |
|
688 | 0 | if (pkg_nt_str_dup(&s_nt, s) < 0) { |
689 | 0 | LM_ERR("oom\n"); |
690 | 0 | return E_OUT_OF_MEM; |
691 | 0 | } |
692 | | |
693 | 0 | *param = s_nt.s; |
694 | 0 | return 0; |
695 | 0 | } |
696 | | |
697 | | static int fixup_nt_str(void** param) |
698 | 0 | { |
699 | 0 | str *s = (str*)*param; |
700 | 0 | str *s_nt; |
701 | |
|
702 | 0 | s_nt = pkg_malloc(sizeof *s_nt + (s?s->len:0) + 1); |
703 | 0 | if (!s_nt) |
704 | 0 | return E_OUT_OF_MEM; |
705 | 0 | s_nt->s = (char *)(s_nt + 1); |
706 | 0 | if (s) { |
707 | 0 | s_nt->len = s->len; |
708 | 0 | memcpy(s_nt->s, s->s, s->len); |
709 | 0 | } else { |
710 | 0 | s_nt->len = 0; |
711 | 0 | } |
712 | 0 | s_nt->s[s_nt->len] = '\0'; |
713 | |
|
714 | 0 | *param = s_nt; |
715 | 0 | return 0; |
716 | 0 | } |
717 | | |
718 | | static int fixup_nt_str_free(void** param) |
719 | 0 | { |
720 | 0 | pkg_free(((str *)*param)->s); |
721 | 0 | return 0; |
722 | 0 | } |
723 | | |
724 | | static int w_forward(struct sip_msg *msg, struct proxy_l *dest) |
725 | 0 | { |
726 | 0 | struct sip_uri next_hop, *u; |
727 | 0 | struct proxy_l* p; |
728 | 0 | int ret; |
729 | |
|
730 | 0 | if (!dest) { |
731 | | /* parse uri and build a proxy */ |
732 | 0 | if (msg->dst_uri.len) { |
733 | 0 | ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len, |
734 | 0 | &next_hop); |
735 | 0 | u = &next_hop; |
736 | 0 | } else { |
737 | 0 | ret = parse_sip_msg_uri(msg); |
738 | 0 | u = &msg->parsed_uri; |
739 | 0 | } |
740 | 0 | if (ret<0) { |
741 | 0 | LM_ERR("forward: bad_uri dropping packet\n"); |
742 | 0 | return E_BAD_ADDRESS; |
743 | 0 | } |
744 | | /* create a temporary proxy*/ |
745 | 0 | p=mk_proxy(u->maddr_val.len?&u->maddr_val:&u->host, |
746 | 0 | u->port_no, u->proto, (u->type==SIPS_URI_T)?1:0 ); |
747 | 0 | if (p==0){ |
748 | 0 | LM_ERR("bad host name in uri, dropping packet\n"); |
749 | 0 | return E_BAD_ADDRESS; |
750 | 0 | } |
751 | 0 | } else { |
752 | 0 | if (0==(p=clone_proxy(dest))) { |
753 | 0 | LM_ERR("failed to clone proxy, dropping packet\n"); |
754 | 0 | return E_OUT_OF_MEM; |
755 | 0 | } |
756 | 0 | } |
757 | | |
758 | 0 | ret=forward_request(msg, p); |
759 | 0 | free_proxy(p); /* frees only p content, not p itself */ |
760 | 0 | pkg_free(p); |
761 | |
|
762 | 0 | if (ret==0) |
763 | 0 | ret=1; |
764 | 0 | return ret; |
765 | 0 | } |
766 | | |
767 | | static int w_send(struct sip_msg *msg, struct proxy_l *dest, str *headers) |
768 | 0 | { |
769 | 0 | int ret; |
770 | 0 | union sockaddr_union* to; |
771 | 0 | struct proxy_l* p; |
772 | 0 | int len; |
773 | 0 | char* tmp; |
774 | |
|
775 | 0 | to=(union sockaddr_union*) |
776 | 0 | pkg_malloc(sizeof(union sockaddr_union)); |
777 | 0 | if (to==0){ |
778 | 0 | LM_ERR("memory allocation failure\n"); |
779 | 0 | return E_OUT_OF_MEM; |
780 | 0 | } |
781 | 0 | if (0==(p=clone_proxy(dest))) { |
782 | 0 | LM_ERR("failed to clone proxy, dropping packet\n"); |
783 | 0 | return E_OUT_OF_MEM; |
784 | 0 | } |
785 | 0 | ret=hostent2su(to, &p->host, p->addr_idx, |
786 | 0 | (p->port)?p->port:SIP_PORT ); |
787 | 0 | if (ret==0){ |
788 | 0 | if (headers) { |
789 | | /* build new msg */ |
790 | 0 | tmp = pkg_malloc(msg->len + headers->len); |
791 | 0 | if (!tmp) { |
792 | 0 | LM_ERR("memory allocation failure\n"); |
793 | 0 | return E_OUT_OF_MEM; |
794 | 0 | } |
795 | 0 | LM_DBG("searching for first line %d\n", |
796 | 0 | msg->first_line.len); |
797 | | /* search first line of previous msg */ |
798 | | /* copy headers */ |
799 | 0 | len = msg->first_line.len; |
800 | 0 | memcpy(tmp, msg->buf, len); |
801 | 0 | memcpy(tmp + len, headers->s, headers->len); |
802 | 0 | memcpy(tmp + len + headers->len, |
803 | 0 | msg->buf + len, msg->len - len); |
804 | 0 | ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/, |
805 | 0 | tmp, msg->len + headers->len, msg); |
806 | 0 | pkg_free(tmp); |
807 | 0 | } else { |
808 | 0 | ret = msg_send(0/*send_sock*/, p->proto, to, 0/*id*/, |
809 | 0 | msg->buf, msg->len, msg); |
810 | 0 | } |
811 | 0 | if (ret!=0 && p->host.h_addr_list[p->addr_idx+1]) |
812 | 0 | p->addr_idx++; |
813 | 0 | } |
814 | | |
815 | 0 | free_proxy(p); /* frees only p content, not p itself */ |
816 | 0 | pkg_free(p); |
817 | 0 | pkg_free(to); |
818 | |
|
819 | 0 | if (ret==0) |
820 | 0 | ret=1; |
821 | 0 | return ret; |
822 | 0 | } |
823 | | |
824 | | static int w_setflag(struct sip_msg *msg, void *flag) |
825 | 0 | { |
826 | 0 | return setflag(msg, (flag_t)(long)flag); |
827 | 0 | } |
828 | | |
829 | | static int w_resetflag(struct sip_msg *msg, void *flag) |
830 | 0 | { |
831 | 0 | return resetflag(msg, (flag_t)(long)flag); |
832 | 0 | } |
833 | | |
834 | | static int w_isflagset(struct sip_msg *msg, void *flag) |
835 | 0 | { |
836 | 0 | return isflagset(msg, (flag_t)(long)flag); |
837 | 0 | } |
838 | | |
839 | | static int w_setbflag(struct sip_msg *msg, void *flag, int *branch_idx) |
840 | 0 | { |
841 | 0 | return setbflag(msg, branch_idx ? *branch_idx : 0, (flag_t)(long)flag); |
842 | 0 | } |
843 | | |
844 | | static int w_resetbflag(struct sip_msg *msg, void *flag, int *branch_idx) |
845 | 0 | { |
846 | 0 | return resetbflag(msg, branch_idx ? *branch_idx : 0, (flag_t)(long)flag); |
847 | 0 | } |
848 | | |
849 | | static int w_isbflagset(struct sip_msg *msg, void *flag, int *branch_idx) |
850 | 0 | { |
851 | 0 | return isbflagset(msg, branch_idx ? *branch_idx : 0, (flag_t)(long)flag); |
852 | 0 | } |
853 | | |
854 | | static int w_sethost(struct sip_msg *msg, str *host) |
855 | 0 | { |
856 | 0 | return rewrite_ruri(msg, host, 0, RW_RURI_HOST) ? -1 : 1; |
857 | 0 | } |
858 | | |
859 | | static int w_sethostport(struct sip_msg *msg, str *hostport) |
860 | 0 | { |
861 | 0 | return rewrite_ruri(msg, hostport, 0, RW_RURI_HOSTPORT) ? -1 : 1; |
862 | 0 | } |
863 | | |
864 | | static int w_setuser(struct sip_msg *msg, str *user) |
865 | 0 | { |
866 | 0 | return rewrite_ruri(msg, user, 0, RW_RURI_USER) ? -1 : 1; |
867 | 0 | } |
868 | | |
869 | | static int w_setuserpass(struct sip_msg *msg, str *userpass) |
870 | 0 | { |
871 | 0 | return rewrite_ruri(msg, userpass, 0, RW_RURI_USERPASS) ? -1 : 1; |
872 | 0 | } |
873 | | |
874 | | static int w_setport(struct sip_msg *msg, str *port) |
875 | 0 | { |
876 | 0 | return rewrite_ruri(msg, port, 0, RW_RURI_PORT) ? -1 : 1; |
877 | 0 | } |
878 | | |
879 | | static int w_seturi(struct sip_msg *msg, str *uri) |
880 | 0 | { |
881 | 0 | if (set_ruri(msg, uri) ) { |
882 | 0 | LM_ERR("failed to set new RURI\n"); |
883 | 0 | return E_OUT_OF_MEM; |
884 | 0 | } |
885 | | |
886 | 0 | return 1; |
887 | 0 | } |
888 | | |
889 | | static int w_prefix(struct sip_msg *msg, str *prefix) |
890 | 0 | { |
891 | 0 | return rewrite_ruri(msg, prefix, 0, RW_RURI_PREFIX) ? -1 : 1; |
892 | 0 | } |
893 | | |
894 | | static int w_strip(struct sip_msg *msg, int *nchars) |
895 | 0 | { |
896 | 0 | return rewrite_ruri(msg, 0, *nchars, RW_RURI_STRIP) ? -1 : 1; |
897 | 0 | } |
898 | | |
899 | | static int w_strip_tail(struct sip_msg *msg, int *nchars) |
900 | 0 | { |
901 | 0 | return rewrite_ruri(msg, 0, *nchars, RW_RURI_STRIP_TAIL) ? -1 : 1; |
902 | 0 | } |
903 | | |
904 | | static int w_append_branch_old(struct sip_msg *msg, str *uri, int *qvalue) |
905 | 0 | { |
906 | 0 | struct msg_branch branch; |
907 | 0 | int ret; |
908 | 0 | qvalue_t q = (int)(long)qvalue; |
909 | |
|
910 | 0 | memset( &branch, 0, sizeof branch); |
911 | |
|
912 | 0 | if (!uri) { |
913 | 0 | branch.uri = *GET_RURI(msg); |
914 | 0 | branch.dst_uri = msg->dst_uri; |
915 | 0 | branch.path = msg->path_vec; |
916 | 0 | branch.q = (q==Q_UNSPECIFIED) ? get_ruri_q(msg) : q; |
917 | 0 | branch.force_send_socket = msg->force_send_socket; |
918 | 0 | branch.bflags = msg->ruri_bflags; |
919 | 0 | ret = append_msg_branch(&branch); |
920 | | /* reset all branch info */ |
921 | 0 | msg->force_send_socket = 0; |
922 | 0 | setb0flags(msg,0); |
923 | 0 | set_ruri_q(msg,Q_UNSPECIFIED); |
924 | 0 | if(msg->dst_uri.s!=0) |
925 | 0 | pkg_free(msg->dst_uri.s); |
926 | 0 | msg->dst_uri.s = 0; |
927 | 0 | msg->dst_uri.len = 0; |
928 | 0 | if(msg->path_vec.s!=0) |
929 | 0 | pkg_free(msg->path_vec.s); |
930 | 0 | msg->path_vec.s = 0; |
931 | 0 | msg->path_vec.len = 0; |
932 | |
|
933 | 0 | return ret; |
934 | 0 | } else { |
935 | 0 | branch.uri = *uri; |
936 | 0 | branch.dst_uri = msg->dst_uri; |
937 | 0 | branch.path = msg->path_vec; |
938 | 0 | branch.q = q; |
939 | 0 | branch.force_send_socket = msg->force_send_socket; |
940 | 0 | branch.bflags = msg->ruri_bflags; |
941 | 0 | return append_msg_branch(&branch); |
942 | 0 | } |
943 | 0 | } |
944 | | |
945 | | |
946 | | static str append_mbranch_flag_names[] = |
947 | | { |
948 | | str_init("inherite"), |
949 | | STR_NULL |
950 | | }; |
951 | | |
952 | | static int fixup_append_mbranch_flags(void** param) |
953 | 0 | { |
954 | 0 | return fixup_named_flags(param, append_mbranch_flag_names, NULL, NULL); |
955 | 0 | } |
956 | | |
957 | | |
958 | | static int w_append_msg_branch(struct sip_msg *msg, str *uri, int *qvalue, |
959 | | void *flags) |
960 | 0 | { |
961 | 0 | unsigned int opts = (unsigned int)(unsigned long)flags; |
962 | 0 | struct msg_branch branch; |
963 | 0 | qvalue_t q = (int)(long)qvalue; |
964 | |
|
965 | 0 | if (ZSTRP(uri)) { |
966 | 0 | LM_ERR("appending emptry URI :(\n"); |
967 | 0 | return -1; |
968 | 0 | } |
969 | | |
970 | 0 | memset( &branch, 0, sizeof branch); |
971 | 0 | branch.uri = *uri; |
972 | |
|
973 | 0 | if ( opts & (1<<0) ) { |
974 | | /* inherite the rest of the branch attrs from RURI branch */ |
975 | 0 | branch.dst_uri = msg->dst_uri; |
976 | 0 | branch.path = msg->path_vec; |
977 | 0 | branch.q = (q==Q_UNSPECIFIED) ? get_ruri_q(msg) : q; |
978 | 0 | branch.force_send_socket = msg->force_send_socket; |
979 | 0 | branch.bflags = msg->ruri_bflags; |
980 | 0 | } else { |
981 | 0 | branch.q = q; |
982 | 0 | } |
983 | 0 | return append_msg_branch(&branch); |
984 | 0 | } |
985 | | |
986 | | static int w_remove_msg_branch(struct sip_msg *msg, int *branch) |
987 | 0 | { |
988 | 0 | return (remove_msg_branch(*branch)==0) ? 1 : -1 ; |
989 | 0 | } |
990 | | |
991 | | static int w_move_msg_branch(struct sip_msg *msg, int *src_idx, |
992 | | int *dst_idx, int *keep) |
993 | 0 | { |
994 | 0 | return (move_msg_branch(msg, |
995 | 0 | (src_idx?*src_idx:-1), (dst_idx?*dst_idx:-1), (keep?1:0))==0) ? 1 : -1; |
996 | 0 | } |
997 | | |
998 | | static int w_swap_msg_branches(struct sip_msg *msg, int *src_idx, int *dst_idx) |
999 | 0 | { |
1000 | 0 | return (swap_msg_branches(msg, |
1001 | 0 | (src_idx?*src_idx:-1), (dst_idx?*dst_idx:-1))==0) ? 1 : -1 ; |
1002 | 0 | } |
1003 | | |
1004 | | static int w_pv_printf(struct sip_msg *msg, pv_spec_t *var, str *fmt_str) |
1005 | 0 | { |
1006 | 0 | pv_value_t val; |
1007 | |
|
1008 | 0 | if(!pv_is_w(var)) |
1009 | 0 | { |
1010 | 0 | LM_ERR("read only PV in first parameter of pv_printf\n"); |
1011 | 0 | return -1; |
1012 | 0 | } |
1013 | | |
1014 | 0 | val.flags = PV_VAL_STR; |
1015 | 0 | val.rs = *fmt_str; |
1016 | |
|
1017 | 0 | if(pv_set_value(msg, var, EQ_T, &val)<0) |
1018 | 0 | { |
1019 | 0 | LM_ERR("setting PV failed\n"); |
1020 | 0 | return -1; |
1021 | 0 | } |
1022 | | |
1023 | 0 | return 1; |
1024 | 0 | } |
1025 | | |
1026 | | static int w_revert_uri(struct sip_msg *msg) |
1027 | 14.5k | { |
1028 | 14.5k | if (msg->new_uri.s) { |
1029 | 0 | pkg_free(msg->new_uri.s); |
1030 | 0 | msg->new_uri.len=0; |
1031 | 0 | msg->new_uri.s=0; |
1032 | 0 | msg->parsed_uri_ok=0; /* invalidate current parsed uri*/ |
1033 | 0 | }; |
1034 | | |
1035 | 14.5k | return 1; |
1036 | 14.5k | } |
1037 | | |
1038 | | static int w_setdsturi(struct sip_msg *msg, str *uri) |
1039 | 0 | { |
1040 | 0 | if(set_dst_uri(msg, uri)!=0) |
1041 | 0 | return -1; |
1042 | 0 | else |
1043 | 0 | return 1; |
1044 | 0 | } |
1045 | | |
1046 | | static int w_resetdsturi(struct sip_msg *msg) |
1047 | 11.0k | { |
1048 | 11.0k | reset_dst_uri(msg); |
1049 | | |
1050 | 11.0k | return 1; |
1051 | 11.0k | } |
1052 | | |
1053 | | static int w_isdsturiset(struct sip_msg *msg) |
1054 | 11.1k | { |
1055 | 11.1k | if(msg->dst_uri.s==0 || msg->dst_uri.len<=0) |
1056 | 11.1k | return -1; |
1057 | 0 | else |
1058 | 0 | return 1; |
1059 | | |
1060 | 0 | return 1; |
1061 | 11.1k | } |
1062 | | |
1063 | | static int w_force_rport(struct sip_msg *msg) |
1064 | 8.48k | { |
1065 | 8.48k | msg->msg_flags|=FL_FORCE_RPORT; |
1066 | | |
1067 | 8.48k | return 1; |
1068 | 8.48k | } |
1069 | | |
1070 | | static int w_add_local_rport(struct sip_msg *msg) |
1071 | 6.59k | { |
1072 | 6.59k | msg->msg_flags|=FL_FORCE_LOCAL_RPORT; |
1073 | 6.59k | return 1; |
1074 | | |
1075 | 6.59k | } |
1076 | | |
1077 | | static int w_force_tcp_alias(struct sip_msg *msg, int *port) |
1078 | 0 | { |
1079 | 0 | unsigned short p; |
1080 | |
|
1081 | 0 | if (is_tcp_based_proto(msg->rcv.proto)) { |
1082 | 0 | if (!port) p=msg->via1->port; |
1083 | 0 | else |
1084 | 0 | p=*port; |
1085 | |
|
1086 | 0 | if (tcpconn_add_alias(NULL, msg->rcv.proto_reserved1, p, |
1087 | 0 | msg->rcv.proto)!=0){ |
1088 | 0 | LM_WARN("tcp alias failed\n"); |
1089 | 0 | return E_UNSPEC; |
1090 | 0 | } |
1091 | 0 | } |
1092 | | |
1093 | 0 | return 1; |
1094 | 0 | } |
1095 | | |
1096 | | static int w_set_adv_address(struct sip_msg *msg, str *adv_addr) |
1097 | 0 | { |
1098 | 0 | LM_DBG("setting adv address = [%.*s]\n", adv_addr->len, adv_addr->s); |
1099 | | |
1100 | | /* duplicate the advertised address into private memory */ |
1101 | 0 | if (adv_addr->len > msg->set_global_address.len) { |
1102 | 0 | msg->set_global_address.s = pkg_realloc(msg->set_global_address.s, |
1103 | 0 | adv_addr->len); |
1104 | 0 | if (!msg->set_global_address.s) { |
1105 | 0 | LM_ERR("out of pkg mem\n"); |
1106 | 0 | return E_OUT_OF_MEM; |
1107 | 0 | } |
1108 | 0 | } |
1109 | 0 | memcpy(msg->set_global_address.s, adv_addr->s, adv_addr->len); |
1110 | 0 | msg->set_global_address.len = adv_addr->len; |
1111 | |
|
1112 | 0 | return 1; |
1113 | 0 | } |
1114 | | |
1115 | | static int w_set_adv_port(struct sip_msg *msg, str *adv_port) |
1116 | 0 | { |
1117 | 0 | LM_DBG("setting adv port '%.*s'\n", adv_port->len, adv_port->s); |
1118 | | |
1119 | | /* duplicate the advertised port into private memory */ |
1120 | 0 | if (adv_port->len > msg->set_global_port.len) { |
1121 | 0 | msg->set_global_port.s = pkg_realloc(msg->set_global_port.s, |
1122 | 0 | adv_port->len); |
1123 | 0 | if (!msg->set_global_port.s) { |
1124 | 0 | LM_ERR("out of pkg mem\n"); |
1125 | 0 | return E_OUT_OF_MEM; |
1126 | 0 | } |
1127 | 0 | } |
1128 | 0 | memcpy(msg->set_global_port.s, adv_port->s, adv_port->len); |
1129 | 0 | msg->set_global_port.len = adv_port->len; |
1130 | |
|
1131 | 0 | return 1; |
1132 | 0 | } |
1133 | | |
1134 | | static int w_f_send_sock(struct sip_msg *msg, struct socket_info *si) |
1135 | 0 | { |
1136 | 0 | msg->force_send_socket=(const struct socket_info *)si; |
1137 | |
|
1138 | 0 | return 1; |
1139 | 0 | } |
1140 | | |
1141 | | static int w_serialize_branches(struct sip_msg *msg, int *clear_prev, |
1142 | | int *keep_ord) |
1143 | 0 | { |
1144 | 0 | if (serialize_branches(msg,*clear_prev, |
1145 | 0 | keep_ord ? *keep_ord : 0)!=0) { |
1146 | 0 | LM_ERR("serialize_branches failed\n"); |
1147 | 0 | return E_UNSPEC; |
1148 | 0 | } |
1149 | | |
1150 | 0 | return 1; |
1151 | 0 | } |
1152 | | |
1153 | | static int w_next_branches(struct sip_msg *msg) |
1154 | 9.15k | { |
1155 | 9.15k | int ret; |
1156 | | |
1157 | 9.15k | if ((ret = next_branches(msg)) < 0) |
1158 | 9.15k | LM_DBG("no more branches\n"); |
1159 | | |
1160 | 9.15k | return ret; |
1161 | 9.15k | } |
1162 | | |
1163 | | static int w_use_blacklist(struct sip_msg *msg, struct bl_head *list) |
1164 | 0 | { |
1165 | 0 | mark_for_search(list, 1); |
1166 | |
|
1167 | 0 | return 1; |
1168 | 0 | } |
1169 | | |
1170 | | static int w_unuse_blacklist(struct sip_msg *msg, struct bl_head *list) |
1171 | 0 | { |
1172 | 0 | mark_for_search(list, 0); |
1173 | |
|
1174 | 0 | return 1; |
1175 | 0 | } |
1176 | | |
1177 | | static int w_cache_store(struct sip_msg *msg, str *id, str *attr, str *val, |
1178 | | int *expire) |
1179 | 0 | { |
1180 | 0 | if (!attr->s || !attr->len) { |
1181 | 0 | LM_ERR("attribute cannot be empty\n"); |
1182 | 0 | return E_UNSPEC; |
1183 | 0 | } |
1184 | 0 | if (!attr->s || !attr->len) { |
1185 | 0 | LM_ERR("value cannot be empty\n"); |
1186 | 0 | return E_UNSPEC; |
1187 | 0 | } |
1188 | | |
1189 | 0 | return cachedb_store(id, attr, val, expire ? *expire : 0); |
1190 | 0 | } |
1191 | | |
1192 | | static int w_cache_remove(struct sip_msg *msg, str *id, str *attr) |
1193 | 0 | { |
1194 | 0 | if (!attr->s || !attr->len) { |
1195 | 0 | LM_ERR("attribute cannot be empty\n"); |
1196 | 0 | return E_UNSPEC; |
1197 | 0 | } |
1198 | | |
1199 | 0 | return cachedb_remove(id, attr); |
1200 | 0 | } |
1201 | | |
1202 | | static int w_cache_fetch(struct sip_msg *msg, str *id, str *attr, |
1203 | | pv_spec_t *res) |
1204 | 0 | { |
1205 | 0 | str aux = {0, 0}; |
1206 | 0 | int ret; |
1207 | 0 | pv_value_t val; |
1208 | |
|
1209 | 0 | if (!attr->s || !attr->len) { |
1210 | 0 | LM_ERR("attribute cannot be empty\n"); |
1211 | 0 | return E_UNSPEC; |
1212 | 0 | } |
1213 | | |
1214 | 0 | ret = cachedb_fetch(id, attr, &aux); |
1215 | 0 | if(ret > 0) |
1216 | 0 | { |
1217 | 0 | val.rs = aux; |
1218 | 0 | val.flags = PV_VAL_STR; |
1219 | 0 | fix_val_str_flags(val); |
1220 | |
|
1221 | 0 | if (pv_set_value(msg, res, 0, &val) < 0) { |
1222 | 0 | LM_ERR("cannot set the variable value\n"); |
1223 | 0 | pkg_free(aux.s); |
1224 | 0 | return -1; |
1225 | 0 | } |
1226 | 0 | pkg_free(aux.s); |
1227 | 0 | } |
1228 | | |
1229 | 0 | return ret; |
1230 | 0 | } |
1231 | | |
1232 | | static int w_cache_counter_fetch(struct sip_msg *msg, str *id, str *attr, |
1233 | | pv_spec_t *res) |
1234 | 0 | { |
1235 | 0 | int aux_counter; |
1236 | 0 | int ret; |
1237 | 0 | pv_value_t val; |
1238 | |
|
1239 | 0 | if (!attr->s || !attr->len) { |
1240 | 0 | LM_ERR("attribute cannot be empty\n"); |
1241 | 0 | return E_UNSPEC; |
1242 | 0 | } |
1243 | | |
1244 | 0 | ret = cachedb_counter_fetch(id, attr, &aux_counter); |
1245 | 0 | if(ret > 0) |
1246 | 0 | { |
1247 | 0 | val.ri = aux_counter; |
1248 | 0 | val.flags = PV_TYPE_INT|PV_VAL_INT; |
1249 | |
|
1250 | 0 | if (pv_set_value(msg, res, 0, &val) < 0) { |
1251 | 0 | LM_ERR("cannot set the variable value\n"); |
1252 | 0 | return -1; |
1253 | 0 | } |
1254 | 0 | } |
1255 | | |
1256 | 0 | return ret; |
1257 | 0 | } |
1258 | | |
1259 | | static int w_cache_add(struct sip_msg *msg, str *id, str *attr, |
1260 | | int *inc, int *expire, pv_spec_t *new_val) |
1261 | 0 | { |
1262 | 0 | int ret; |
1263 | 0 | pv_value_t val; |
1264 | 0 | int aux_counter; |
1265 | |
|
1266 | 0 | if (!attr->s || !attr->len) { |
1267 | 0 | LM_ERR("attribute cannot be empty\n"); |
1268 | 0 | return E_UNSPEC; |
1269 | 0 | } |
1270 | | |
1271 | 0 | ret = cachedb_add(id, attr, *inc, *expire, &aux_counter); |
1272 | | |
1273 | | /* Return the new value */ |
1274 | 0 | if (ret > 0 && new_val) { |
1275 | 0 | val.ri = aux_counter; |
1276 | 0 | val.flags = PV_TYPE_INT|PV_VAL_INT; |
1277 | |
|
1278 | 0 | if (pv_set_value(msg, new_val, 0, &val) < 0) { |
1279 | 0 | LM_ERR("cannot set the variable value\n"); |
1280 | 0 | return -1; |
1281 | 0 | } |
1282 | 0 | } |
1283 | | |
1284 | 0 | return ret; |
1285 | 0 | } |
1286 | | |
1287 | | static int w_cache_sub(struct sip_msg *msg, str *id, str *attr, |
1288 | | int *dec, int *expire, pv_spec_t *new_val) |
1289 | 0 | { |
1290 | 0 | int ret; |
1291 | 0 | pv_value_t val; |
1292 | 0 | int aux_counter; |
1293 | |
|
1294 | 0 | if (!attr->s || !attr->len) { |
1295 | 0 | LM_ERR("attribute cannot be empty\n"); |
1296 | 0 | return E_UNSPEC; |
1297 | 0 | } |
1298 | | |
1299 | 0 | ret = cachedb_sub(id, attr, *dec, *expire, &aux_counter); |
1300 | | |
1301 | | /* Return the new value */ |
1302 | 0 | if (ret > 0 && new_val) { |
1303 | 0 | val.ri = aux_counter; |
1304 | 0 | val.flags = PV_TYPE_INT|PV_VAL_INT; |
1305 | |
|
1306 | 0 | if (pv_set_value(msg, new_val, 0, &val) < 0) { |
1307 | 0 | LM_ERR("cannot set the variable value\n"); |
1308 | 0 | return -1; |
1309 | 0 | } |
1310 | 0 | } |
1311 | | |
1312 | 0 | return ret; |
1313 | 0 | } |
1314 | | |
1315 | | static int w_cache_raw_query(struct sip_msg *msg, str *id, str *raw_query_s, |
1316 | | pvname_list_t *avp_list) |
1317 | 0 | { |
1318 | 0 | cdb_raw_entry **cdb_reply = NULL; |
1319 | 0 | int num_cols=0,i,j; |
1320 | 0 | int num_rows=0; |
1321 | 0 | pvname_list_t *it; |
1322 | 0 | int_str avp_val; |
1323 | 0 | int_str avp_name; |
1324 | 0 | unsigned short avp_type; |
1325 | 0 | int ret; |
1326 | |
|
1327 | 0 | if (!raw_query_s || !raw_query_s->s || !raw_query_s->len) { |
1328 | 0 | LM_ERR("raw query cannot be empty\n"); |
1329 | 0 | return E_UNSPEC; |
1330 | 0 | } |
1331 | | |
1332 | 0 | if (!avp_list) |
1333 | 0 | return cachedb_raw_query(id, raw_query_s, NULL,0,NULL); |
1334 | | |
1335 | 0 | for (it=avp_list;it;it=it->next) |
1336 | 0 | num_cols++; |
1337 | |
|
1338 | 0 | LM_DBG("The query expects %d fields per result\n", num_cols); |
1339 | |
|
1340 | 0 | ret = cachedb_raw_query(id, raw_query_s, &cdb_reply, num_cols, &num_rows); |
1341 | 0 | if (ret >= 0 && num_cols > 0) { |
1342 | 0 | for (i=num_rows-1; i>=0;i--) { |
1343 | 0 | it=avp_list; |
1344 | 0 | for (j=0;j < num_cols;j++) { |
1345 | 0 | avp_type = 0; |
1346 | 0 | if (pv_get_avp_name(msg,&it->sname.pvp,&avp_name.n, |
1347 | 0 | &avp_type) != 0) { |
1348 | 0 | LM_ERR("cannot get avp name [%d/%d]\n",i,j); |
1349 | 0 | goto next_avp; |
1350 | 0 | } |
1351 | | |
1352 | 0 | switch (cdb_reply[i][j].type) { |
1353 | 0 | case CDB_INT32: |
1354 | 0 | avp_val.n = cdb_reply[i][j].val.n; |
1355 | 0 | break; |
1356 | 0 | case CDB_STR: |
1357 | 0 | avp_type |= AVP_VAL_STR; |
1358 | 0 | avp_val.s = cdb_reply[i][j].val.s; |
1359 | 0 | break; |
1360 | 0 | case CDB_NULL: |
1361 | 0 | avp_type |= AVP_VAL_NULL; |
1362 | 0 | avp_val.s = cdb_reply[i][j].val.s; |
1363 | 0 | break; |
1364 | 0 | default: |
1365 | 0 | LM_WARN("Unknown type %d\n",cdb_reply[i][j].type); |
1366 | 0 | goto next_avp; |
1367 | 0 | } |
1368 | 0 | if (add_avp(avp_type,avp_name.n,avp_val) != 0) { |
1369 | 0 | LM_ERR("Unable to add AVP\n"); |
1370 | 0 | free_raw_fetch(cdb_reply,num_cols,num_rows); |
1371 | 0 | return -1; |
1372 | 0 | } |
1373 | 0 | next_avp: |
1374 | 0 | if (it) { |
1375 | 0 | it = it->next; |
1376 | 0 | if (it==NULL) |
1377 | 0 | break; |
1378 | 0 | } |
1379 | 0 | } |
1380 | 0 | } |
1381 | 0 | free_raw_fetch(cdb_reply,num_cols,num_rows); |
1382 | 0 | } |
1383 | | |
1384 | 0 | return ret; |
1385 | 0 | } |
1386 | | |
1387 | | static int w_raise_event(struct sip_msg *msg, void *ev_id, pv_spec_t *attrs_avp, |
1388 | | pv_spec_t *vals_avp) |
1389 | 0 | { |
1390 | |
|
1391 | 0 | if (evi_raise_script_event(msg, (event_id_t)(long)ev_id, attrs_avp, |
1392 | 0 | vals_avp) <= 0) { |
1393 | 0 | LM_ERR("cannot raise event\n"); |
1394 | 0 | return E_UNSPEC; |
1395 | 0 | } |
1396 | | |
1397 | 0 | return 1; |
1398 | 0 | } |
1399 | | |
1400 | | static int w_subscribe_event(struct sip_msg *msg, str *name, str *socket, |
1401 | | int *expire) |
1402 | 0 | { |
1403 | 0 | return evi_event_subscribe(*name, *socket, expire ? *expire : 0, 0); |
1404 | 0 | } |
1405 | | |
1406 | | static int w_construct_uri(struct sip_msg *msg, str *proto, str *user, |
1407 | | str *domain, str *port, str *extra, pv_spec_t *result_avp) |
1408 | 0 | { |
1409 | 0 | str result; |
1410 | 0 | int_str res; |
1411 | 0 | int avp_name; |
1412 | 0 | unsigned short avp_type; |
1413 | |
|
1414 | 0 | result.s = construct_uri(proto, user, domain, port, extra, &result.len); |
1415 | 0 | if (result.s) |
1416 | 0 | { |
1417 | 0 | if (pv_get_avp_name( msg, &(result_avp->pvp), &avp_name, |
1418 | 0 | &avp_type)!=0){ |
1419 | 0 | LM_CRIT("BUG in getting AVP name\n"); |
1420 | 0 | return -1; |
1421 | 0 | } |
1422 | | |
1423 | 0 | res.s = result; |
1424 | 0 | if (add_avp(AVP_VAL_STR|avp_type, avp_name, res)<0){ |
1425 | 0 | LM_ERR("cannot add AVP\n"); |
1426 | 0 | return -1; |
1427 | 0 | } |
1428 | 0 | } |
1429 | | |
1430 | 0 | return 1; |
1431 | 0 | } |
1432 | | |
1433 | | static int w_get_timestamp(struct sip_msg *msg, pv_spec_t *sec_avp, |
1434 | | pv_spec_t *usec_avp) |
1435 | 0 | { |
1436 | 0 | int sec,usec; |
1437 | 0 | int avp_name; |
1438 | 0 | int_str res; |
1439 | 0 | unsigned short avp_type; |
1440 | |
|
1441 | 0 | if (get_timestamp(&sec,&usec) == 0) { |
1442 | 0 | if (pv_get_avp_name(msg, &(sec_avp->pvp), &avp_name, |
1443 | 0 | &avp_type) != 0) { |
1444 | 0 | LM_CRIT("BUG in getting AVP name\n"); |
1445 | 0 | return -1; |
1446 | 0 | } |
1447 | | |
1448 | 0 | res.n = sec; |
1449 | 0 | if (add_avp(avp_type, avp_name, res) < 0) { |
1450 | 0 | LM_ERR("cannot add AVP\n"); |
1451 | 0 | return -1; |
1452 | 0 | } |
1453 | | |
1454 | 0 | if (pv_get_avp_name(msg, &(usec_avp->pvp), &avp_name, |
1455 | 0 | &avp_type) != 0) { |
1456 | 0 | LM_CRIT("BUG in getting AVP name\n"); |
1457 | 0 | return -1; |
1458 | 0 | } |
1459 | | |
1460 | 0 | res.n = usec; |
1461 | 0 | if (add_avp(avp_type, avp_name, res) < 0) { |
1462 | 0 | LM_ERR("cannot add AVP\n"); |
1463 | 0 | return -1; |
1464 | 0 | } |
1465 | 0 | } else { |
1466 | 0 | LM_ERR("failed to get time\n"); |
1467 | 0 | return -1; |
1468 | 0 | } |
1469 | | |
1470 | 0 | return 1; |
1471 | 0 | } |
1472 | | |
1473 | | static int w_script_trace(struct sip_msg *msg, int *log_level, |
1474 | | pv_elem_t *fmt_string, void *info_str) |
1475 | 0 | { |
1476 | 0 | if (!log_level && !fmt_string && !info_str) { |
1477 | 0 | use_script_trace = 0; |
1478 | 0 | return 1; |
1479 | 0 | } else if (!log_level) { |
1480 | | // this should not happen, it's just a super precaution |
1481 | | // and no LM_xxx here, as it assumes a valid log_level |
1482 | 0 | return E_CFG; |
1483 | 0 | } else if (!fmt_string) { |
1484 | 0 | LM_ERR("Missing 'pv_format_string' parameter\n"); |
1485 | 0 | return E_CFG; |
1486 | 0 | } |
1487 | | |
1488 | 0 | use_script_trace = 1; |
1489 | |
|
1490 | 0 | script_trace_info = (char*)info_str; |
1491 | |
|
1492 | 0 | script_trace_log_level = *log_level; |
1493 | 0 | script_trace_elem = *fmt_string; |
1494 | |
|
1495 | 0 | return 1; |
1496 | 0 | } |
1497 | | |
1498 | | static int w_is_myself(struct sip_msg *msg, str *host, int *port) |
1499 | 0 | { |
1500 | 0 | if (check_self(host, port ? *port : 0, 0)) |
1501 | 0 | return 1; |
1502 | 0 | else |
1503 | 0 | return -1; |
1504 | 0 | } |
1505 | | |
1506 | | static int w_print_avps(struct sip_msg* msg, char* foo, char *bar) |
1507 | 7.88k | { |
1508 | 7.88k | struct usr_avp **avp_list; |
1509 | 7.88k | struct usr_avp *avp; |
1510 | 7.88k | int_str val; |
1511 | 7.88k | str *name; |
1512 | | |
1513 | | /* go through all list */ |
1514 | 7.88k | avp_list = get_avp_list(); |
1515 | 7.88k | avp = *avp_list; |
1516 | | |
1517 | 7.88k | LM_INFO("----------- All AVPs in this context --------\n"); |
1518 | 7.88k | LM_INFO(" (SIP txn, script event, timer route, etc.)\n"); |
1519 | 7.88k | for ( ; avp ; avp=avp->next) |
1520 | 0 | { |
1521 | 0 | LM_INFO("p=%p, flags=0x%04X\n",avp, avp->flags); |
1522 | 0 | name = get_avp_name(avp); |
1523 | 0 | LM_INFO(" name=<%.*s>\n",name->len,name->s); |
1524 | 0 | LM_INFO(" id=<%d>\n",avp->id); |
1525 | 0 | get_avp_val( avp, &val); |
1526 | 0 | if (avp->flags&AVP_VAL_STR) |
1527 | 0 | { |
1528 | 0 | LM_INFO(" val_str=<%.*s / %d>\n",val.s.len,val.s.s, |
1529 | 0 | val.s.len); |
1530 | 0 | } else { |
1531 | 0 | LM_INFO(" val_int=<%d>\n",val.n); |
1532 | 0 | } |
1533 | 0 | } |
1534 | 7.88k | LM_INFO("---------------- END ALL AVPs ---------------\n"); |
1535 | | |
1536 | 7.88k | return 1; |
1537 | 7.88k | } |
1538 | | |
1539 | | |
1540 | | static str via_hdl_flag_names[] = { |
1541 | | str_init("force-rport"), |
1542 | | str_init("add-local-rport"), |
1543 | | str_init("reply-to-via"), |
1544 | | str_init("force-tcp-alias"), |
1545 | | STR_NULL |
1546 | | }; |
1547 | | enum via_hdl_flags { |
1548 | | VIA_HDL_FORCE_RPORT, |
1549 | | VIA_HDL_ADD_LOCAL_RPORT, |
1550 | | VIA_HDL_REPLY_TO_VIA, |
1551 | | VIA_HDL_FORCE_TCP_ALIAS, |
1552 | | }; |
1553 | | static int fixup_via_hdl(void** param) |
1554 | 0 | { |
1555 | 0 | return fixup_named_flags(param, via_hdl_flag_names, NULL, NULL); |
1556 | 0 | } |
1557 | | |
1558 | | static int w_set_via_handling(struct sip_msg* msg, int flags) |
1559 | 0 | { |
1560 | 0 | if (flags & (1<<VIA_HDL_FORCE_RPORT)) |
1561 | 0 | msg->msg_flags |= FL_FORCE_RPORT; |
1562 | |
|
1563 | 0 | if (flags & (1<<VIA_HDL_ADD_LOCAL_RPORT)) |
1564 | 0 | msg->msg_flags|=FL_FORCE_LOCAL_RPORT; |
1565 | |
|
1566 | 0 | if (flags & (1<<VIA_HDL_REPLY_TO_VIA)) |
1567 | 0 | msg->msg_flags |= FL_REPLY_TO_VIA; |
1568 | |
|
1569 | 0 | if (flags & (1<<VIA_HDL_FORCE_TCP_ALIAS)) |
1570 | 0 | w_force_tcp_alias( msg, 0); |
1571 | |
|
1572 | 0 | return 1; |
1573 | 0 | } |
1574 | | |