Browse code

core/corex: move send()/send_tcp() to corex module

As suggested by miconda on sr-dev, move send() and send_tcp() out of core
and into the new corex module in order to make them support pseudo variables.
This changes:

- drops SEND and SEND_TCP tokens from config parser
- remove related config parser code relying on SEND_T and SEND_TCP_T
- augment corex module to provide the functions removed from core
- update corex docs

Richard Fuchs authored on 30/11/2012 19:00:09
Showing 12 changed files
... ...
@@ -484,80 +484,6 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
484 484
 				ret=E_BUG;
485 485
 				goto error;
486 486
 			}
487
-			break;
488
-		case SEND_T:
489
-		case SEND_TCP_T:
490
-			if (a->val[0].type==URIHOST_ST){
491
-				/*get next hop uri uri*/
492
-				if (msg->dst_uri.len) {
493
-					ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
494
-									&next_hop);
495
-					u = &next_hop;
496
-				} else {
497
-					ret = parse_sip_msg_uri(msg);
498
-					u = &msg->parsed_uri;
499
-				}
500
-
501
-				if (ret<0) {
502
-					LM_ERR("send() - bad_uri dropping packet\n");
503
-					ret=E_BUG;
504
-					goto error;
505
-				}
506
-				/* init dst */
507
-				init_dest_info(&dst);
508
-				ret = sip_hostport2su(&dst.to, &u->host, u->port_no,
509
-							&dst.proto);
510
-				if(ret!=0) {
511
-					LM_ERR("failed to resolve [%.*s]\n", u->host.len,
512
-						ZSW(u->host.s));
513
-					ret=E_BUG;
514
-					goto error;
515
-				}
516
-			} else {
517
-				if ((a->val[0].type!= PROXY_ST)|(a->val[1].type!=NUMBER_ST)){
518
-					LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
519
-							a->val[0].type, a->val[1].type);
520
-					ret=E_BUG;
521
-					goto error;
522
-				}
523
-				/* init dst */
524
-				init_dest_info(&dst);
525
-				ret=proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
526
-				if(ret==0)
527
-					proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
528
-			}
529
-			if (ret==0){
530
-				if (p_onsend){
531
-					tmp=p_onsend->buf;
532
-					len=p_onsend->len;
533
-				}else{
534
-					tmp=msg->buf;
535
-					len=msg->len;
536
-				}
537
-				if (a->type==SEND_T){
538
-					/*udp*/
539
-					dst.proto=PROTO_UDP; /* not really needed for udp_send */
540
-					dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
541
-					if (dst.send_sock!=0){
542
-						ret=udp_send(&dst, tmp, len);
543
-					}else{
544
-						ret=-1;
545
-					}
546
-				}
547
-#ifdef USE_TCP
548
-					else{
549
-						/*tcp*/
550
-						dst.proto=PROTO_TCP;
551
-						dst.id=0;
552
-						ret=tcp_send(&dst, 0, tmp, len);
553
-				}
554
-#endif
555
-			}else{
556
-				ret=E_BUG;
557
-				goto error;
558
-			}
559
-			if (ret>=0) ret=1;
560
-
561 487
 			break;
562 488
 		case LOG_T:
563 489
 			if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
... ...
@@ -195,8 +195,6 @@ DROP	"drop"
195 195
 EXIT	"exit"
196 196
 RETURN	"return"
197 197
 BREAK	"break"
198
-SEND	send
199
-SEND_TCP	send_tcp
200 198
 LOG		log
201 199
 ERROR	error
202 200
 ROUTE	route
... ...
@@ -606,8 +604,6 @@ IMPORTFILE      "import_file"
606 604
 <INITIAL>{EXIT}	{ count(); yylval.strval=yytext; return EXIT; }
607 605
 <INITIAL>{RETURN}	{ count(); yylval.strval=yytext; return RETURN; }
608 606
 <INITIAL>{BREAK}	{ count(); yylval.strval=yytext; return BREAK; }
609
-<INITIAL>{SEND}	{ count(); yylval.strval=yytext; return SEND; }
610
-<INITIAL>{SEND_TCP}	{ count(); yylval.strval=yytext; return SEND_TCP; }
611 607
 <INITIAL>{LOG}	{ count(); yylval.strval=yytext; return LOG_TOK; }
612 608
 <INITIAL>{ERROR}	{ count(); yylval.strval=yytext; return ERROR; }
613 609
 <INITIAL>{SETFLAG}	{ count(); yylval.strval=yytext; return SETFLAG; }
... ...
@@ -305,8 +305,6 @@ extern char *finame;
305 305
 %token FORWARD_TLS
306 306
 %token FORWARD_SCTP
307 307
 %token FORWARD_UDP
308
-%token SEND
309
-%token SEND_TCP
310 308
 %token EXIT
311 309
 %token DROP
312 310
 %token RETURN
... ...
@@ -2412,8 +2410,6 @@ fcmd:
2412 2410
 		if ($1 && rt==ONSEND_ROUTE) {
2413 2411
 			switch($1->type) {
2414 2412
 				case DROP_T:
2415
-				case SEND_T:
2416
-				case SEND_TCP_T:
2417 2413
 				case LOG_T:
2418 2414
 				case SETFLAG_T:
2419 2415
 				case RESETFLAG_T:
... ...
@@ -3173,24 +3169,6 @@ cmd:
3173 3169
 	| FORWARD_SCTP error { $$=0; yyerror("missing '(' or ')' ?"); }
3174 3170
 	| FORWARD_SCTP LPAREN error RPAREN { $$=0; 
3175 3171
 									yyerror("bad forward_tls argument"); }
3176
-	| SEND LPAREN RPAREN { $$=mk_action(SEND_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
3177
-	| SEND LPAREN host RPAREN	{ $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
3178
-	| SEND LPAREN STRING RPAREN { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
3179
-	| SEND LPAREN ip RPAREN		{ $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
3180
-	| SEND LPAREN host COMMA NUMBER RPAREN	{ $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
3181
-	| SEND LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
3182
-	| SEND LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
3183
-	| SEND error { $$=0; yyerror("missing '(' or ')' ?"); }
3184
-	| SEND LPAREN error RPAREN { $$=0; yyerror("bad send argument"); }
3185
-	| SEND_TCP LPAREN RPAREN { $$=mk_action(SEND_TCP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0); set_cfg_pos($$); }
3186
-	| SEND_TCP LPAREN host RPAREN	{ $$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
3187
-	| SEND_TCP LPAREN STRING RPAREN { $$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, 0); set_cfg_pos($$); }
3188
-	| SEND_TCP LPAREN ip RPAREN	{ $$=mk_action(SEND_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); set_cfg_pos($$); }
3189
-	| SEND_TCP LPAREN host COMMA NUMBER RPAREN	{ $$=mk_action(	SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$);}
3190
-	| SEND_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(SEND_TCP_T, 2, STRING_ST, $3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
3191
-	| SEND_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(SEND_TCP_T, 2, IP_ST, (void*)$3, NUMBER_ST, (void*)$5); set_cfg_pos($$); }
3192
-	| SEND_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
3193
-	| SEND_TCP LPAREN error RPAREN { $$=0; yyerror("bad send_tcp argument"); }
3194 3172
 	| LOG_TOK LPAREN STRING RPAREN	{$$=mk_action(LOG_T, 2, NUMBER_ST,
3195 3173
 										(void*)(L_DBG+1), STRING_ST, $3);
3196 3174
 									set_cfg_pos($$); }
... ...
@@ -10,7 +10,7 @@ Daniel-Constantin Mierla
10 10
 
11 11
    <miconda@gmail.com>
12 12
 
13
-   Copyright � 2012 asipto.com
13
+   Copyright © 2012 asipto.com
14 14
      __________________________________________________________________
15 15
 
16 16
    Table of Contents
... ...
@@ -30,6 +30,8 @@ Daniel-Constantin Mierla
30 30
         4. Functions
31 31
 
32 32
               4.1. append_branch([ uri, [ q ] ])
33
+              4.2. send([ host [ :port ] ])
34
+              4.3. send_tcp([ host [ :port ] ])
33 35
 
34 36
         5. RPC Commands
35 37
 
... ...
@@ -40,6 +42,7 @@ Daniel-Constantin Mierla
40 42
 
41 43
    1.1. Set alias_subdomains parameter
42 44
    1.2. append_branch usage
45
+   1.3. send usage
43 46
 
44 47
 Chapter 1. Admin Guide
45 48
 
... ...
@@ -58,6 +61,8 @@ Chapter 1. Admin Guide
58 61
    4. Functions
59 62
 
60 63
         4.1. append_branch([ uri, [ q ] ])
64
+        4.2. send([ host [ :port ] ])
65
+        4.3. send_tcp([ host [ :port ] ])
61 66
 
62 67
    5. RPC Commands
63 68
 
... ...
@@ -104,7 +109,7 @@ Chapter 1. Admin Guide
104 109
    'proto:domain:port', allowing to set restrictions on protocol and port
105 110
    as well. Protocol and port are optional.
106 111
 
107
-   Default value is "NULL".
112
+   Default value is “NULL”.
108 113
 
109 114
    Example 1.1. Set alias_subdomains parameter
110 115
 ...
... ...
@@ -115,8 +120,10 @@ modparam("corex", "alias_subdomains", "udp:sip-router.org:5060")
115 120
 4. Functions
116 121
 
117 122
    4.1. append_branch([ uri, [ q ] ])
123
+   4.2. send([ host [ :port ] ])
124
+   4.3. send_tcp([ host [ :port ] ])
118 125
 
119
-4.1. append_branch([ uri, [ q ] ])
126
+4.1.  append_branch([ uri, [ q ] ])
120 127
 
121 128
    Append a new branch to the destination set, useful to build the
122 129
    addresses for parallel forking or redirect replies.
... ...
@@ -138,19 +145,46 @@ modparam("corex", "alias_subdomains", "udp:sip-router.org:5060")
138 145
     append_branch("$avp(uri)", "0.5");
139 146
 ...
140 147
 
148
+4.2.  send([ host [ :port ] ])
149
+
150
+   Send the original SIP message to a specific destination in stateless
151
+   mode. No changes are applied to received message, no Via header is
152
+   added. Host can be an IP address or hostname. Port is optional and
153
+   defaults to 5060. Used protocol: UDP.
154
+
155
+   The parameter is optional and defaults to the destination URI from the
156
+   SIP message if left out. Otherwise it's a string parameter (supporting
157
+   pseudo-variables) in format "hostname" or "hostname:port", where
158
+   hostname" can also be a numeric IP address.
159
+
160
+   This function can be used from REQUEST_ROUTE or FAILURE_ROUTE.
161
+
162
+   Example 1.3. send usage
163
+...
164
+        send();
165
+        send("10.20.15.10");
166
+        send("sip.example.com:5070");
167
+        send("$var(res)");
168
+...
169
+
170
+4.3.  send_tcp([ host [ :port ] ])
171
+
172
+   This function is identical to send() described above, except that it
173
+   sends the SIP message using the TCP protocol instead of UDP.
174
+
141 175
 5. RPC Commands
142 176
 
143 177
    5.1. corex.list_sockets
144 178
    5.2. corex.list_aliases
145 179
 
146
-5.1. corex.list_sockets
180
+5.1.  corex.list_sockets
147 181
 
148 182
    Print the list of sockets the application is listening on.
149 183
 
150 184
    Example:
151 185
                 sercmd corex.list_sockets
152 186
 
153
-5.2. corex.list_aliases
187
+5.2.  corex.list_aliases
154 188
 
155 189
    Print the list of hostname aliases used to match myself condition.
156 190
 
... ...
@@ -27,6 +27,8 @@
27 27
 #include "../../dprint.h"
28 28
 #include "../../dset.h"
29 29
 #include "../../forward.h"
30
+#include "../../parser/parse_uri.h"
31
+#include "../../resolve.h"
30 32
 
31 33
 #include "corex_lib.h"
32 34
 
... ...
@@ -211,3 +213,88 @@ int corex_register_check_self(void)
211 213
 	}
212 214
 	return 0;
213 215
 }
216
+
217
+int corex_send(sip_msg_t *msg, gparam_t *pu, enum sip_protos proto)
218
+{
219
+	str dest = {0};
220
+	int ret = 0;
221
+	struct sip_uri next_hop, *u;
222
+	struct dest_info dst;
223
+	char *p;
224
+
225
+	if (pu)
226
+	{
227
+		if (fixup_get_svalue(msg, pu, &dest))
228
+		{
229
+			LM_ERR("cannot get the destination parameter\n");
230
+			return -1;
231
+		}
232
+	}
233
+
234
+	init_dest_info(&dst);
235
+
236
+	if (dest.len <= 0)
237
+	{
238
+		/*get next hop uri uri*/
239
+		if (msg->dst_uri.len) {
240
+			ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
241
+							&next_hop);
242
+			u = &next_hop;
243
+		} else {
244
+			ret = parse_sip_msg_uri(msg);
245
+			u = &msg->parsed_uri;
246
+		}
247
+
248
+		if (ret<0) {
249
+			LM_ERR("send() - bad_uri dropping packet\n");
250
+			ret=E_BUG;
251
+			goto error;
252
+		}
253
+	}
254
+	else
255
+	{
256
+		u = &next_hop;
257
+		u->port_no = 5060;
258
+		u->host = dest;
259
+		p = memchr(dest.s, ':', dest.len);
260
+		if (p)
261
+		{
262
+			u->host.len = p - dest.s;
263
+			p++;
264
+			u->port_no = str2s(p, dest.len - (p - dest.s), NULL);
265
+		}
266
+	}
267
+
268
+	ret = sip_hostport2su(&dst.to, &u->host, u->port_no,
269
+				&dst.proto);
270
+	if(ret!=0) {
271
+		LM_ERR("failed to resolve [%.*s]\n", u->host.len,
272
+			ZSW(u->host.s));
273
+		ret=E_BUG;
274
+		goto error;
275
+	}
276
+
277
+	dst.proto = proto;
278
+	if (proto == PROTO_UDP)
279
+	{
280
+		dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
281
+		if (dst.send_sock!=0){
282
+			ret=udp_send(&dst, msg->buf, msg->len);
283
+		}else{
284
+			ret=-1;
285
+		}
286
+	}
287
+#ifdef USE_TCP
288
+	else{
289
+		/*tcp*/
290
+		dst.id=0;
291
+		ret=tcp_send(&dst, 0, msg->buf, msg->len);
292
+	}
293
+#endif
294
+
295
+	if (ret>=0) ret=1;
296
+
297
+
298
+error:
299
+	return ret;
300
+}
... ...
@@ -25,6 +25,7 @@
25 25
 #include "../../mod_fix.h"
26 26
 
27 27
 int corex_append_branch(sip_msg_t *msg, gparam_t *pu, gparam_t *pq);
28
+int corex_send(sip_msg_t *msg, gparam_t *pu, enum sip_protos proto);
28 29
 
29 30
 int corex_add_alias_subdomains(char* aliasval);
30 31
 
... ...
@@ -34,6 +34,8 @@
34 34
 MODULE_VERSION
35 35
 
36 36
 static int w_append_branch(sip_msg_t *msg, char *su, char *sq);
37
+static int w_send(sip_msg_t *msg, char *su, char *sq);
38
+static int w_send_tcp(sip_msg_t *msg, char *su, char *sq);
37 39
 
38 40
 int corex_alias_subdomains_param(modparam_t type, void *val);
39 41
 
... ...
@@ -48,6 +50,14 @@ static cmd_export_t cmds[]={
48 50
 			0, REQUEST_ROUTE | FAILURE_ROUTE },
49 51
 	{"append_branch", (cmd_function)w_append_branch, 2, fixup_spve_spve,
50 52
 			0, REQUEST_ROUTE | FAILURE_ROUTE },
53
+	{"send", (cmd_function)w_send, 0, 0,
54
+			0, REQUEST_ROUTE | FAILURE_ROUTE },
55
+	{"send", (cmd_function)w_send, 1, fixup_spve_spve,
56
+			0, REQUEST_ROUTE | FAILURE_ROUTE },
57
+	{"send_tcp", (cmd_function)w_send_tcp, 0, 0,
58
+			0, REQUEST_ROUTE | FAILURE_ROUTE },
59
+	{"send_tcp", (cmd_function)w_send_tcp, 1, fixup_spve_null,
60
+			0, REQUEST_ROUTE | FAILURE_ROUTE },
51 61
 
52 62
 
53 63
 	{0, 0, 0, 0, 0, 0}
... ...
@@ -123,6 +133,22 @@ static int w_append_branch(sip_msg_t *msg, char *su, char *sq)
123 133
 	return 1;
124 134
 }
125 135
 
136
+/**
137
+ * config wrapper for send() and send_tcp()
138
+ */
139
+static int w_send(sip_msg_t *msg, char *su, char *sq)
140
+{
141
+	if(corex_send(msg, (gparam_t*)su, PROTO_UDP) < 0)
142
+		return -1;
143
+	return 1;
144
+}
145
+static int w_send_tcp(sip_msg_t *msg, char *su, char *sq)
146
+{
147
+	if(corex_send(msg, (gparam_t*)su, PROTO_TCP) < 0)
148
+		return -1;
149
+	return 1;
150
+}
151
+
126 152
 
127 153
 int corex_alias_subdomains_param(modparam_t type, void *val)
128 154
 {
... ...
@@ -132,6 +132,52 @@ modparam("corex", "alias_subdomains", "udp:sip-router.org:5060")
132 132
 </programlisting>
133 133
 	    </example>
134 134
 	</section>
135
+
136
+	<section>
137
+		<title>
138
+			<function moreinfo="none">send([ host [ :port ] ])</function>
139
+		</title>
140
+		<para>
141
+			Send the original SIP message to a specific destination in stateless
142
+			mode. No changes are applied to received message, no Via header is
143
+			added. Host can be an IP address or hostname. Port is optional and
144
+			defaults to 5060. Used protocol: UDP.
145
+		</para>
146
+		<para>
147
+			The parameter is optional and defaults to the destination URI from
148
+			the SIP message if left out. Otherwise it's a string parameter
149
+			(supporting pseudo-variables) in format
150
+			"<emphasis>hostname</emphasis>" or
151
+			"<emphasis>hostname</emphasis>:<emphasis>port</emphasis>",
152
+			where <emphasis>hostname</emphasis>" can also be a numeric IP
153
+			address.
154
+		</para>
155
+		<para>
156
+			This function can be used from REQUEST_ROUTE or FAILURE_ROUTE.
157
+		</para>
158
+		<example>
159
+		<title><function>send</function> usage</title>
160
+		<programlisting format="linespecific">
161
+...
162
+	send();
163
+	send("10.20.15.10");
164
+	send("sip.example.com:5070");
165
+	send("$var(res)");
166
+...
167
+</programlisting>
168
+		</example>
169
+	</section>
170
+
171
+	<section>
172
+		<title>
173
+			<function moreinfo="none">send_tcp([ host [ :port ] ])</function>
174
+		</title>
175
+		<para>
176
+			This function is identical to <emphasis>send()</emphasis>
177
+			described above, except that it sends the SIP message using the
178
+			TCP protocol instead of UDP.
179
+		</para>
180
+	</section>
135 181
 	</section>
136 182
 
137 183
 	<section>
... ...
@@ -46,7 +46,6 @@ static str _dbg_action_special[] = {
46 46
 
47 47
 static dbg_action_t _dbg_action_list[] = {
48 48
 	{ FORWARD_T, str_init("forward") },
49
-	{ SEND_T, str_init("send") },
50 49
 	{ LOG_T, str_init("log") },
51 50
 	{ ERROR_T, str_init("error") },
52 51
 	{ ROUTE_T, str_init("route") },
... ...
@@ -82,7 +81,6 @@ static dbg_action_t _dbg_action_list[] = {
82 81
 	{ FORWARD_UDP_T, str_init("forward_udp") },
83 82
 	{ FORWARD_TLS_T, str_init("forward_tls") },
84 83
 	{ FORWARD_SCTP_T, str_init("forward_sctp") },
85
-	{ SEND_TCP_T, str_init("send_tcp") },
86 84
 	{ FORCE_RPORT_T, str_init("force_rport") },
87 85
 	{ ADD_LOCAL_RPORT_T, str_init("add_local_rport") },
88 86
 	{ SET_ADV_ADDR_T, str_init("set_adv_addr") },
... ...
@@ -663,8 +663,6 @@ int fix_actions(struct action* a)
663 663
 			case FORWARD_TCP_T:
664 664
 			case FORWARD_SCTP_T:
665 665
 			case FORWARD_UDP_T:
666
-			case SEND_T:
667
-			case SEND_TCP_T:
668 666
 					switch(t->val[0].type){
669 667
 						case IP_ST:
670 668
 							tmp=strdup(ip_addr2a(
... ...
@@ -371,12 +371,6 @@ void print_action(struct action* t)
371 371
 		case FORWARD_UDP_T:
372 372
 			DBG("forward_udp(");
373 373
 			break;
374
-		case SEND_T:
375
-			DBG("send(");
376
-			break;
377
-		case SEND_TCP_T:
378
-			DBG("send_tcp(");
379
-			break;
380 374
 		case DROP_T:
381 375
 			DBG("drop(");
382 376
 			break;
... ...
@@ -79,7 +79,7 @@ enum _expr_l_type{
79 79
 	   SNDAF_O, RETCODE_O, SELECT_O, PVAR_O, RVEXP_O, SELECT_UNFIXED_O};
80 80
 /* action types */
81 81
 enum action_type{
82
-		FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
82
+		FORWARD_T=1, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
83 83
 		SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T,
84 84
 		SET_PORT_T, SET_URI_T, SET_HOSTPORTTRANS_T, SET_HOSTALL_T,
85 85
 		SET_USERPHONE_T,
... ...
@@ -100,7 +100,6 @@ enum action_type{
100 100
 		FORWARD_UDP_T,
101 101
 		FORWARD_TLS_T,
102 102
 		FORWARD_SCTP_T,
103
-		SEND_TCP_T,
104 103
 		FORCE_RPORT_T,
105 104
 		ADD_LOCAL_RPORT_T,
106 105
 		SET_ADV_ADDR_T,