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
... ...
@@ -485,80 +485,6 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
485 485
 				goto error;
486 486
 			}
487 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
-			break;
562 488
 		case LOG_T:
563 489
 			if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
564 490
 				LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
... ...
@@ -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 606
 <INITIAL>{EXIT}	{ count(); yylval.strval=yytext; return EXIT; }
607 607
 <INITIAL>{RETURN}	{ count(); yylval.strval=yytext; return RETURN; }
608 608
 <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 609
 <INITIAL>{LOG}	{ count(); yylval.strval=yytext; return LOG_TOK; }
612 610
 <INITIAL>{ERROR}	{ count(); yylval.strval=yytext; return ERROR; }
613 611
 <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 2412
 		if ($1 && rt==ONSEND_ROUTE) {
2413 2413
 			switch($1->type) {
2414 2414
 				case DROP_T:
2415
-				case SEND_T:
2416
-				case SEND_TCP_T:
2417 2415
 				case LOG_T:
2418 2416
 				case SETFLAG_T:
2419 2417
 				case RESETFLAG_T:
... ...
@@ -3173,24 +3169,6 @@ cmd:
3173 3173
 	| FORWARD_SCTP error { $$=0; yyerror("missing '(' or ')' ?"); }
3174 3174
 	| FORWARD_SCTP LPAREN error RPAREN { $$=0; 
3175 3175
 									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 3176
 	| LOG_TOK LPAREN STRING RPAREN	{$$=mk_action(LOG_T, 2, NUMBER_ST,
3195 3177
 										(void*)(L_DBG+1), STRING_ST, $3);
3196 3178
 									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 40
 
41 41
    1.1. Set alias_subdomains parameter
42 42
    1.2. append_branch usage
43
+   1.3. send usage
43 44
 
44 45
 Chapter 1. Admin Guide
45 46
 
... ...
@@ -58,6 +61,8 @@ Chapter 1. Admin Guide
58 58
    4. Functions
59 59
 
60 60
         4.1. append_branch([ uri, [ q ] ])
61
+        4.2. send([ host [ :port ] ])
62
+        4.3. send_tcp([ host [ :port ] ])
61 63
 
62 64
    5. RPC Commands
63 65
 
... ...
@@ -104,7 +109,7 @@ Chapter 1. Admin Guide
104 104
    'proto:domain:port', allowing to set restrictions on protocol and port
105 105
    as well. Protocol and port are optional.
106 106
 
107
-   Default value is "NULL".
107
+   Default value is “NULL”.
108 108
 
109 109
    Example 1.1. Set alias_subdomains parameter
110 110
 ...
... ...
@@ -115,8 +120,10 @@ modparam("corex", "alias_subdomains", "udp:sip-router.org:5060")
115 115
 4. Functions
116 116
 
117 117
    4.1. append_branch([ uri, [ q ] ])
118
+   4.2. send([ host [ :port ] ])
119
+   4.3. send_tcp([ host [ :port ] ])
118 120
 
119
-4.1. append_branch([ uri, [ q ] ])
121
+4.1.  append_branch([ uri, [ q ] ])
120 122
 
121 123
    Append a new branch to the destination set, useful to build the
122 124
    addresses for parallel forking or redirect replies.
... ...
@@ -138,19 +145,46 @@ modparam("corex", "alias_subdomains", "udp:sip-router.org:5060")
138 138
     append_branch("$avp(uri)", "0.5");
139 139
 ...
140 140
 
141
+4.2.  send([ host [ :port ] ])
142
+
143
+   Send the original SIP message to a specific destination in stateless
144
+   mode. No changes are applied to received message, no Via header is
145
+   added. Host can be an IP address or hostname. Port is optional and
146
+   defaults to 5060. Used protocol: UDP.
147
+
148
+   The parameter is optional and defaults to the destination URI from the
149
+   SIP message if left out. Otherwise it's a string parameter (supporting
150
+   pseudo-variables) in format "hostname" or "hostname:port", where
151
+   hostname" can also be a numeric IP address.
152
+
153
+   This function can be used from REQUEST_ROUTE or FAILURE_ROUTE.
154
+
155
+   Example 1.3. send usage
156
+...
157
+        send();
158
+        send("10.20.15.10");
159
+        send("sip.example.com:5070");
160
+        send("$var(res)");
161
+...
162
+
163
+4.3.  send_tcp([ host [ :port ] ])
164
+
165
+   This function is identical to send() described above, except that it
166
+   sends the SIP message using the TCP protocol instead of UDP.
167
+
141 168
 5. RPC Commands
142 169
 
143 170
    5.1. corex.list_sockets
144 171
    5.2. corex.list_aliases
145 172
 
146
-5.1. corex.list_sockets
173
+5.1.  corex.list_sockets
147 174
 
148 175
    Print the list of sockets the application is listening on.
149 176
 
150 177
    Example:
151 178
                 sercmd corex.list_sockets
152 179
 
153
-5.2. corex.list_aliases
180
+5.2.  corex.list_aliases
154 181
 
155 182
    Print the list of hostname aliases used to match myself condition.
156 183
 
... ...
@@ -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 211
 	}
212 212
 	return 0;
213 213
 }
214
+
215
+int corex_send(sip_msg_t *msg, gparam_t *pu, enum sip_protos proto)
216
+{
217
+	str dest = {0};
218
+	int ret = 0;
219
+	struct sip_uri next_hop, *u;
220
+	struct dest_info dst;
221
+	char *p;
222
+
223
+	if (pu)
224
+	{
225
+		if (fixup_get_svalue(msg, pu, &dest))
226
+		{
227
+			LM_ERR("cannot get the destination parameter\n");
228
+			return -1;
229
+		}
230
+	}
231
+
232
+	init_dest_info(&dst);
233
+
234
+	if (dest.len <= 0)
235
+	{
236
+		/*get next hop uri uri*/
237
+		if (msg->dst_uri.len) {
238
+			ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
239
+							&next_hop);
240
+			u = &next_hop;
241
+		} else {
242
+			ret = parse_sip_msg_uri(msg);
243
+			u = &msg->parsed_uri;
244
+		}
245
+
246
+		if (ret<0) {
247
+			LM_ERR("send() - bad_uri dropping packet\n");
248
+			ret=E_BUG;
249
+			goto error;
250
+		}
251
+	}
252
+	else
253
+	{
254
+		u = &next_hop;
255
+		u->port_no = 5060;
256
+		u->host = dest;
257
+		p = memchr(dest.s, ':', dest.len);
258
+		if (p)
259
+		{
260
+			u->host.len = p - dest.s;
261
+			p++;
262
+			u->port_no = str2s(p, dest.len - (p - dest.s), NULL);
263
+		}
264
+	}
265
+
266
+	ret = sip_hostport2su(&dst.to, &u->host, u->port_no,
267
+				&dst.proto);
268
+	if(ret!=0) {
269
+		LM_ERR("failed to resolve [%.*s]\n", u->host.len,
270
+			ZSW(u->host.s));
271
+		ret=E_BUG;
272
+		goto error;
273
+	}
274
+
275
+	dst.proto = proto;
276
+	if (proto == PROTO_UDP)
277
+	{
278
+		dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
279
+		if (dst.send_sock!=0){
280
+			ret=udp_send(&dst, msg->buf, msg->len);
281
+		}else{
282
+			ret=-1;
283
+		}
284
+	}
285
+#ifdef USE_TCP
286
+	else{
287
+		/*tcp*/
288
+		dst.id=0;
289
+		ret=tcp_send(&dst, 0, msg->buf, msg->len);
290
+	}
291
+#endif
292
+
293
+	if (ret>=0) ret=1;
294
+
295
+
296
+error:
297
+	return ret;
298
+}
... ...
@@ -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 48
 			0, REQUEST_ROUTE | FAILURE_ROUTE },
49 49
 	{"append_branch", (cmd_function)w_append_branch, 2, fixup_spve_spve,
50 50
 			0, REQUEST_ROUTE | FAILURE_ROUTE },
51
+	{"send", (cmd_function)w_send, 0, 0,
52
+			0, REQUEST_ROUTE | FAILURE_ROUTE },
53
+	{"send", (cmd_function)w_send, 1, fixup_spve_spve,
54
+			0, REQUEST_ROUTE | FAILURE_ROUTE },
55
+	{"send_tcp", (cmd_function)w_send_tcp, 0, 0,
56
+			0, REQUEST_ROUTE | FAILURE_ROUTE },
57
+	{"send_tcp", (cmd_function)w_send_tcp, 1, fixup_spve_null,
58
+			0, REQUEST_ROUTE | FAILURE_ROUTE },
51 59
 
52 60
 
53 61
 	{0, 0, 0, 0, 0, 0}
... ...
@@ -123,6 +133,22 @@ static int w_append_branch(sip_msg_t *msg, char *su, char *sq)
123 123
 	return 1;
124 124
 }
125 125
 
126
+/**
127
+ * config wrapper for send() and send_tcp()
128
+ */
129
+static int w_send(sip_msg_t *msg, char *su, char *sq)
130
+{
131
+	if(corex_send(msg, (gparam_t*)su, PROTO_UDP) < 0)
132
+		return -1;
133
+	return 1;
134
+}
135
+static int w_send_tcp(sip_msg_t *msg, char *su, char *sq)
136
+{
137
+	if(corex_send(msg, (gparam_t*)su, PROTO_TCP) < 0)
138
+		return -1;
139
+	return 1;
140
+}
141
+
126 142
 
127 143
 int corex_alias_subdomains_param(modparam_t type, void *val)
128 144
 {
... ...
@@ -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 82
 	{ FORWARD_UDP_T, str_init("forward_udp") },
83 83
 	{ FORWARD_TLS_T, str_init("forward_tls") },
84 84
 	{ FORWARD_SCTP_T, str_init("forward_sctp") },
85
-	{ SEND_TCP_T, str_init("send_tcp") },
86 85
 	{ FORCE_RPORT_T, str_init("force_rport") },
87 86
 	{ ADD_LOCAL_RPORT_T, str_init("add_local_rport") },
88 87
 	{ 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,