Browse code

- t_relay_to renamed to t_relay_to_avp (it behaves very differently then the other t_relay_to functions and it isn't even documented so the name change should have a minimal impact)

- t_relay() can now also take host and port parameters (e.g. t_relay(host,
port)), behaving like a statefull orwad(host, port) version (forward to
host:port using the same protocol on which the message was received)

- t_relay_to_udp(), t_relay_to_tcp() and t_relay_to_tls() work now even with no
parameters: in this case the message is forwarded using the request uri, but
with the specified protocol (equivalent to a t_relay() with a forced
protocol)

Andrei Pelinescu-Onciul authored on 15/05/2008 18:46:12
Showing 3 changed files
... ...
@@ -24,7 +24,16 @@ modules:
24 24
  - blst      - new module containing script blacklist manipulations functions
25 25
                (the source of a message can be blacklisted, removed from the
26 26
                 blacklist or checked for presence in the blacklist).
27
- - tm        - method for canceling unreplied branches can now be selected
27
+ - tm        - t_relay_to renamed to t_relay_to_avp (undocumented function)
28
+             - t_relay() can now also take host and port parameters (e.g.
29
+               t_relay(host, port)), behaving like a statefull 
30
+               forwad(host, port) version (forward to host:port using the same
31
+               protocol on which the message was received)
32
+             - t_relay_to_udp(), t_relay_to_tcp() and t_relay_to_tls() work
33
+               now even with no parameters: in this case the message is 
34
+               forwarded using the request uri, but with the specified protocol
35
+               (equivalent to a t_relay() with a forced protocol)
36
+             - method for canceling unreplied branches can now be selected
28 37
                using the new cancel_b_method tm parameter.
29 38
              - support for adding a 503 reply source to the blacklist for
30 39
                the time specified in the Retry-After header (see the new tm
... ...
@@ -17,11 +17,18 @@
17 17
     <section id="t_relay_to_udp">
18 18
 	<title>
19 19
 	    <function>t_relay_to_udp(ip, port)</function>,
20
+	    <function>t_relay_to_udp()</function>,
20 21
 	    <function>t_relay_to_tcp(ip, port)</function>
22
+	    <function>t_relay_to_tcp()</function>
23
+	    <function>t_relay_to_tls(ip, port)</function>
24
+	    <function>t_relay_to_tls()</function>
21 25
 	</title>
22 26
 	<para>
23
-	    Relay a message statefully to a fixed destination. This along with
24
-	    <function>t_relay</function> is the function most users want to
27
+	    Relay a message statefully using a fixed protocol either to the 
28
+		 specified fixed destination or to a destination derived from the 
29
+		 message uri (if the host address and port are not specified).
30
+		 These along with
31
+	    <function>t_relay</function> are the functions most users want to
25 32
 	    use--all other are mostly for programming. Programmers interested
26 33
 	    in writing <acronym>TM</acronym> logic should review how t_relay is
27 34
 	    implemented in tm.c and how <acronym>TM</acronym> callbacks work.
... ...
@@ -37,11 +44,17 @@
37 37
 		</para>
38 38
 	    </listitem>
39 39
 	</itemizedlist>
40
+	<para>If no parameters are specified the message is sent to a destination
41
+	 derived from the message uri (using sip sepcific DNS lookups), but with 
42
+	 the protocol corresponding to the function name.</para>
40 43
 	<example>
41 44
 	    <title><function>t_relay_to_udp</function> usage</title>
42 45
 	    <programlisting>
43 46
 ...
44
-t_relay_to_udp("1.2.3.4", "5060");
47
+if (src_ip==10.0.0.0/8)
48
+	t_relay_to_udp("1.2.3.4", "5060"); # sent to 1.2.3.4:5060 over udp
49
+else
50
+	t_relay_to_tcp(); # relay to msg. uri, but over tcp
45 51
 ...
46 52
 	    </programlisting>
47 53
 	</example>
... ...
@@ -50,11 +63,29 @@ t_relay_to_udp("1.2.3.4", "5060");
50 50
     <section id="t_relay">
51 51
 	<title>
52 52
 	    <function>t_relay()</function>
53
+	    <function>t_relay(host, port)</function>
53 54
 	</title>
54 55
 	<para>
55
-	    Relay a message statefully to destination indicated in current URI. (If the
56
-	    original URI was rewritten by UsrLoc, RR, strip/prefix, etc., the new URI will
57
-	    be taken). Returns a negative value on failure--you may still want to send a
56
+	    Relay a message statefully either to the destination indicated in the
57
+		current URI (if called without any parameters) or to the specified 
58
+		host and port. In the later case (host and port specified) the protocol
59
+		 used is the same protocol on which the message was received.
60
+	</para>
61
+	<para>
62
+		<function>t_relay()</function> is the statefull version for 
63
+		<function>forward(uri:host, uri:port)</function>
64
+		while <function>t_relay(host, port)</function> is similar to 
65
+		<function>forward(host, port)</function>.
66
+	</para>
67
+	<para>
68
+		In the forward to uri case (<function>t_relay()</function>), if the
69
+	    original URI was rewritten (by UsrLoc, RR, strip/prefix, etc.) the new
70
+		URI will be taken). The destination (including the protocol) is 
71
+		determined from the uri, using SIP specific DNS resolving if needed
72
+		(NAPTR, SRV a.s.o depending also on the dns options).
73
+	</para>
74
+	<para>
75
+		Returns a negative value on failure--you may still want to send a
58 76
 	    negative reply upstream statelessly not to leave upstream UAC in lurch.
59 77
 	</para>
60 78
 	<example>
... ...
@@ -86,6 +86,9 @@
86 86
  *               t_set_max_lifetime(), max_{non}inv_lifetime  (andrei)
87 87
  *  2008-02-05	module config parameters use the configuration framework (Miklos)
88 88
  *  2008-02-29  added t_grep_status(code) (andrei)
89
+ *  2008-05-15  added t_relay(host, port) (similar to forward(host, port)) &
90
+ *               t_relay_to_{udp,tcp,tls}(<no param>) (force protocol, but 
91
+ *               forward to uri)  (andrei)
89 92
  */
90 93
 
91 94
 
... ...
@@ -151,17 +154,21 @@ inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo,
151 151
 				char* bar );
152 152
 inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar );
153 153
 inline static int w_t_relay( struct sip_msg  *p_msg , char *_foo, char *_bar);
154
+inline static int w_t_relay2( struct sip_msg  *p_msg , char *proxy, char*);
154 155
 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg , char *proxy,
155 156
 				 char *);
157
+inline static int w_t_relay_to_udp_uri( struct sip_msg  *p_msg , char*, char*);
156 158
 #ifdef USE_TCP
157 159
 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , char *proxy,
158 160
 				char *);
161
+inline static int w_t_relay_to_tcp_uri( struct sip_msg  *p_msg , char*, char*);
159 162
 #endif
160 163
 #ifdef USE_TLS
161 164
 inline static int w_t_relay_to_tls( struct sip_msg  *p_msg , char *proxy,
162 165
 				char *);
166
+inline static int w_t_relay_to_tls_uri( struct sip_msg  *p_msg , char*, char*);
163 167
 #endif
164
-inline static int w_t_relay_to(struct sip_msg* msg, char* str,char*);
168
+inline static int w_t_relay_to_avp(struct sip_msg* msg, char* str,char*);
165 169
 inline static int w_t_replicate( struct sip_msg  *p_msg ,
166 170
 				char *proxy, /* struct proxy_l *proxy expected */
167 171
 				char *_foo       /* nothing expected */ );
... ...
@@ -236,13 +243,19 @@ static cmd_export_t cmds[]={
236 236
 			REQUEST_ROUTE},
237 237
 	{T_RELAY_TO_UDP,       w_t_relay_to_udp,        2, fixup_hostport2proxy,
238 238
 			REQUEST_ROUTE|FAILURE_ROUTE},
239
+	{T_RELAY_TO_UDP,       w_t_relay_to_udp_uri,    0, 0,
240
+			REQUEST_ROUTE|FAILURE_ROUTE},
239 241
 #ifdef USE_TCP
240 242
 	{T_RELAY_TO_TCP,       w_t_relay_to_tcp,        2, fixup_hostport2proxy,
241 243
 			REQUEST_ROUTE|FAILURE_ROUTE},
244
+	{T_RELAY_TO_TCP,       w_t_relay_to_tcp_uri,    0, 0,
245
+			REQUEST_ROUTE|FAILURE_ROUTE},
242 246
 #endif
243 247
 #ifdef USE_TLS
244 248
 	{T_RELAY_TO_TLS,       w_t_relay_to_tls,        2, fixup_hostport2proxy,
245 249
 			REQUEST_ROUTE|FAILURE_ROUTE},
250
+	{T_RELAY_TO_TLS,       w_t_relay_to_tls_uri,    0, 0,
251
+			REQUEST_ROUTE|FAILURE_ROUTE},
246 252
 #endif
247 253
 	{"t_replicate",        w_t_replicate,           2, fixup_hostport2proxy,
248 254
 			REQUEST_ROUTE},
... ...
@@ -260,7 +273,9 @@ static cmd_export_t cmds[]={
260 260
 			REQUEST_ROUTE},
261 261
 	{T_RELAY,              w_t_relay,               0, 0,
262 262
 			REQUEST_ROUTE | FAILURE_ROUTE },
263
-	{"t_relay_to", w_t_relay_to,  			2, fixup_proto_hostport2proxy,
263
+	{T_RELAY,              w_t_relay2,              2, fixup_hostport2proxy,
264
+			REQUEST_ROUTE | FAILURE_ROUTE },
265
+	{"t_relay_to_avp", w_t_relay_to_avp,  		2, fixup_proto_hostport2proxy,
264 266
 			REQUEST_ROUTE},
265 267
 	{T_FORWARD_NONACK,     w_t_forward_nonack,      2, fixup_hostport2proxy,
266 268
 			REQUEST_ROUTE},
... ...
@@ -1151,8 +1166,8 @@ inline static int w_t_on_reply( struct sip_msg* msg, char *go_to, char *foo )
1151 1151
 
1152 1152
 
1153 1153
 
1154
-inline static int _w_t_relay_to( struct sip_msg  *p_msg ,
1155
-	struct proxy_l *proxy )
1154
+inline static int _w_t_relay_to(struct sip_msg  *p_msg ,
1155
+									struct proxy_l *proxy, int force_proto)
1156 1156
 {
1157 1157
 	struct cell *t;
1158 1158
 
... ...
@@ -1162,7 +1177,7 @@ inline static int _w_t_relay_to( struct sip_msg  *p_msg ,
1162 1162
 			LOG(L_CRIT, "BUG: w_t_relay_to: undefined T\n");
1163 1163
 			return -1;
1164 1164
 		}
1165
-		if (t_forward_nonack(t, p_msg, proxy, PROTO_NONE)<=0 ) {
1165
+		if (t_forward_nonack(t, p_msg, proxy, force_proto)<=0 ) {
1166 1166
 			LOG(L_ERR, "ERROR: w_t_relay_to: t_relay_to failed\n");
1167 1167
 			/* let us save the error code, we might need it later
1168 1168
 			when the failure_route has finished (Miklos) */
... ...
@@ -1172,7 +1187,7 @@ inline static int _w_t_relay_to( struct sip_msg  *p_msg ,
1172 1172
 		return 1;
1173 1173
 	}
1174 1174
 	if (rmode==MODE_REQUEST)
1175
-		return t_relay_to( p_msg, proxy, PROTO_NONE,
1175
+		return t_relay_to( p_msg, proxy, force_proto,
1176 1176
 			0 /* no replication */ );
1177 1177
 	LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
1178 1178
 	return 0;
... ...
@@ -1180,44 +1195,63 @@ inline static int _w_t_relay_to( struct sip_msg  *p_msg ,
1180 1180
 
1181 1181
 
1182 1182
 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg ,
1183
-	char *proxy, /* struct proxy_l *proxy expected */
1184
-	char *_foo       /* nothing expected */ )
1183
+									char *proxy,/* struct proxy_l * expected */
1184
+									char *_foo       /* nothing expected */ )
1185 1185
 {
1186
-	((struct proxy_l *)proxy)->proto=PROTO_UDP;
1187
-	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
1186
+	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_UDP);
1187
+}
1188
+
1189
+/* forward to uri, but force udp as transport */
1190
+inline static int w_t_relay_to_udp_uri( struct sip_msg  *p_msg ,
1191
+										char *_foo, char *_bar   )
1192
+{
1193
+	return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_UDP);
1188 1194
 }
1189 1195
 
1190 1196
 
1191 1197
 #ifdef USE_TCP
1192 1198
 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg ,
1193
-	char *proxy, /* struct proxy_l *proxy expected */
1194
-	char *_foo       /* nothing expected */ )
1199
+									char *proxy, /* struct proxy_l* */
1200
+									char *_foo       /* nothing expected */ )
1195 1201
 {
1196
-	((struct proxy_l *)proxy)->proto=PROTO_TCP;
1197
-	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
1202
+	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TCP);
1203
+}
1204
+
1205
+/* forward to uri, but force tcp as transport */
1206
+inline static int w_t_relay_to_tcp_uri( struct sip_msg  *p_msg ,
1207
+										char *_foo, char *_bar   )
1208
+{
1209
+	return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_TCP);
1198 1210
 }
1199 1211
 #endif
1200 1212
 
1201 1213
 
1202 1214
 #ifdef USE_TLS
1203 1215
 inline static int w_t_relay_to_tls( struct sip_msg  *p_msg ,
1204
-	char *proxy, /* struct proxy_l *proxy expected */
1205
-	char *_foo       /* nothing expected */ )
1216
+									char *proxy, /* struct proxy_l* expected */
1217
+									char *_foo       /* nothing expected */ )
1206 1218
 {
1207
-	((struct proxy_l *)proxy)->proto=PROTO_TLS;
1208
-	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
1219
+	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TLS);
1220
+}
1221
+
1222
+/* forward to uri, but force tls as transport */
1223
+inline static int w_t_relay_to_tls_uri( struct sip_msg  *p_msg ,
1224
+										char *_foo, char *_bar   )
1225
+{
1226
+	return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_TLS);
1209 1227
 }
1210 1228
 #endif
1211 1229
 
1212
-inline static int w_t_relay_to( struct sip_msg  *p_msg ,
1213
-	char *proto_par, 
1214
-	char *addr_par   )
1230
+inline static int w_t_relay_to_avp( struct sip_msg  *p_msg ,
1231
+									char *proto_par, 
1232
+									char *addr_par   )
1215 1233
 {
1216 1234
 	struct proxy_l *proxy;
1217 1235
 	int r = -1;
1236
+	
1218 1237
 	proxy = t_protoaddr2proxy(proto_par, addr_par);
1219 1238
 	if (proxy) {
1220
-		r = _w_t_relay_to(p_msg, proxy);		
1239
+		r = _w_t_relay_to(p_msg, proxy, PROTO_NONE);
1221 1240
 		free_proxy(proxy);
1222 1241
 	}
1223 1242
 	return r;
... ...
@@ -1273,33 +1307,21 @@ inline static int w_t_replicate_to( struct sip_msg  *p_msg ,
1273 1273
 }
1274 1274
 
1275 1275
 inline static int w_t_relay( struct sip_msg  *p_msg ,
1276
-						char *_foo, char *_bar)
1276
+								char *_foo, char *_bar)
1277 1277
 {
1278
-	struct cell *t;
1278
+	return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_NONE);
1279
+}
1279 1280
 
1280
-	if (rmode==MODE_ONFAILURE) {
1281
-		t=get_t();
1282
-		if (!t || t==T_UNDEFINED) {
1283
-			LOG(L_CRIT, "BUG: w_t_relay: undefined T\n");
1284
-			return -1;
1285
-		}
1286
-		if (t_forward_nonack(t, p_msg, ( struct proxy_l *) 0, PROTO_NONE)<=0) {
1287
-			LOG(L_ERR, "ERROR: w_t_relay (failure mode): forwarding failed\n");
1288
-			/* let us save the error code, we might need it later
1289
-			when the failure_route has finished (Miklos) */
1290
-			tm_error=ser_error;
1291
-			return -1;
1292
-		}
1293
-		return 1;
1294
-	}
1295
-	if (rmode==MODE_REQUEST)
1296
-		return t_relay_to( p_msg,
1297
-		(struct proxy_l *) 0 /* no proxy */, PROTO_NONE,
1298
-		0 /* no replication */ );
1299
-	LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
1300
-	return 0;
1281
+
1282
+/* like t_relay but use the specified destination and port and the same proto
1283
+ * as the received msg */
1284
+static int w_t_relay2( struct sip_msg  *p_msg , char *proxy,
1285
+								char *_foo)
1286
+{
1287
+	return _w_t_relay_to(p_msg, (struct proxy_l*) proxy, p_msg->rcv.proto);
1301 1288
 }
1302 1289
 
1290
+
1303 1291
 /* relays CANCEL at the beginning of the script */
1304 1292
 inline static int w_t_relay_cancel( struct sip_msg  *p_msg ,
1305 1293
 						char *_foo, char *_bar)