Coverage Report

Created: 2025-08-29 06:53

/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