Browse code

- more dest_info conversions: - forward_request takes now a dest_info parameter - various something2dst conversions functions - got rid of the temprary mk_proxy when forwarding after the uri - updated all the affected modules

WARNING: not tested, use with care

Andrei Pelinescu-Onciul authored on 18/04/2006 19:56:48
Showing 15 changed files
... ...
@@ -66,7 +66,7 @@ MAIN_NAME=ser
66 66
 VERSION = 0
67 67
 PATCHLEVEL = 10
68 68
 SUBLEVEL =   99
69
-EXTRAVERSION = -dev38
69
+EXTRAVERSION = -dev39
70 70
 
71 71
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
72 72
 			$(SUBLEVEL) )
... ...
@@ -62,6 +62,7 @@
62 62
 #include "globals.h"
63 63
 #include "dset.h"
64 64
 #include "onsend.h"
65
+#include "resolve.h"
65 66
 #ifdef USE_TCP
66 67
 #include "tcp_server.h"
67 68
 #endif
... ...
@@ -97,7 +98,6 @@ int do_action(struct action* a, struct sip_msg* msg)
97 97
 	int ret;
98 98
 	int v;
99 99
 	struct dest_info dst;
100
-	struct proxy_l* p;
101 100
 	char* tmp;
102 101
 	char *new_uri, *end, *crt;
103 102
 	int len;
... ...
@@ -105,7 +105,6 @@ int do_action(struct action* a, struct sip_msg* msg)
105 105
 	struct sip_uri uri, next_hop;
106 106
 	struct sip_uri *u;
107 107
 	unsigned short port;
108
-	int proto;
109 108
 	unsigned short flags;
110 109
 	int_str name, value;
111 110
 
... ...
@@ -133,15 +132,16 @@ int do_action(struct action* a, struct sip_msg* msg)
133 133
 		case FORWARD_TLS_T:
134 134
 #endif
135 135
 		case FORWARD_UDP_T:
136
-
137
-			if (a->type==FORWARD_UDP_T) proto=PROTO_UDP;
136
+			/* init dst */
137
+			init_dest_info(&dst);
138
+			if (a->type==FORWARD_UDP_T) dst.proto=PROTO_UDP;
138 139
 #ifdef USE_TCP
139
-			else if (a->type==FORWARD_TCP_T) proto= PROTO_TCP;
140
+			else if (a->type==FORWARD_TCP_T) dst.proto= PROTO_TCP;
140 141
 #endif
141 142
 #ifdef USE_TLS
142
-			else if (a->type==FORWARD_TLS_T) proto= PROTO_TLS;
143
+			else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
143 144
 #endif
144
-			else proto= PROTO_NONE;
145
+			else dst.proto= PROTO_NONE;
145 146
 			if (a->val[0].type==URIHOST_ST){
146 147
 				/*parse uri*/
147 148
 
... ...
@@ -172,11 +172,11 @@ int do_action(struct action* a, struct sip_msg* msg)
172 172
 							ret=E_UNSPEC;
173 173
 							goto error_fwd_uri;
174 174
 				}
175
-				if (proto == PROTO_NONE){ /* only if proto not set get it
175
+				if (dst.proto == PROTO_NONE){ /* only if proto not set get it
176 176
 											 from the uri */
177 177
 					switch(u->proto){
178 178
 						case PROTO_NONE:
179
-							proto=PROTO_UDP;
179
+							dst.proto=PROTO_UDP;
180 180
 							break;
181 181
 						case PROTO_UDP:
182 182
 #ifdef USE_TCP
... ...
@@ -185,7 +185,7 @@ int do_action(struct action* a, struct sip_msg* msg)
185 185
 #ifdef USE_TLS
186 186
 						case PROTO_TLS:
187 187
 #endif
188
-							proto=u->proto;
188
+							dst.proto=u->proto;
189 189
 							break;
190 190
 						default:
191 191
 							LOG(L_ERR,"ERROR: do action: forward: bad uri"
... ...
@@ -202,29 +202,29 @@ int do_action(struct action* a, struct sip_msg* msg)
202 202
 							ret=E_BAD_PROTO;
203 203
 							goto error_fwd_uri;
204 204
 						}
205
-						proto=PROTO_TLS;
205
+						dst.proto=PROTO_TLS;
206 206
 					}
207 207
 #endif
208 208
 				}
209
-				/* create a temporary proxy*/
210
-				p=mk_proxy(&u->host, port, proto);
211
-				if (p==0){
209
+				if (sip_hostport2su(&dst.to, &u->host, port, dst.proto)<0){
212 210
 					LOG(L_ERR, "ERROR:  bad host name in uri,"
213 211
 							" dropping packet\n");
214 212
 					ret=E_BAD_ADDRESS;
215 213
 					goto error_fwd_uri;
216 214
 				}
217
-				ret=forward_request(msg, p, proto);
218
-				/*free_uri(&uri); -- no longer needed, in sip_msg*/
219
-				free_proxy(p); /* frees only p content, not p itself */
220
-				pkg_free(p);
215
+				ret=forward_request(msg, &dst);
221 216
 				if (ret>=0) ret=1;
222 217
 			}else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
223
-				if (proto==PROTO_NONE)
224
-					proto=msg->rcv.proto;
225
-				ret=forward_request(msg, (struct proxy_l*)a->val[0].u.data,
226
-										proto);
227
-				if (ret>=0) ret=1;
218
+				if (dst.proto==PROTO_NONE)
219
+					dst.proto=msg->rcv.proto;
220
+				proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
221
+				ret=forward_request(msg, &dst);
222
+				if (ret>=0){
223
+					ret=1;
224
+					proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
225
+				}else if (ser_error!=E_OK){
226
+					proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
227
+				}
228 228
 			}else{
229 229
 				LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
230 230
 						a->val[0].type, a->val[1].type);
... ...
@@ -239,16 +239,9 @@ int do_action(struct action* a, struct sip_msg* msg)
239 239
 				ret=E_BUG;
240 240
 				break;
241 241
 			}
242
-			p=(struct proxy_l*)a->val[0].u.data;
243
-			if (p->ok==0){
244
-				if (p->host.h_addr_list[p->addr_idx+1])
245
-					p->addr_idx++;
246
-				else
247
-					p->addr_idx=0;
248
-				p->ok=1;
249
-			}
250
-			ret=hostent2su(&dst.to, &p->host, p->addr_idx,
251
-						(p->port)?p->port:SIP_PORT );
242
+			/* init dst */
243
+			init_dest_info(&dst);
244
+			ret=proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
252 245
 			if (ret==0){
253 246
 				if (p_onsend){
254 247
 					tmp=p_onsend->buf;
... ...
@@ -257,8 +250,6 @@ int do_action(struct action* a, struct sip_msg* msg)
257 257
 					tmp=msg->buf;
258 258
 					len=msg->len;
259 259
 				}
260
-				p->tx++;
261
-				p->tx_bytes+=len;
262 260
 				if (a->type==SEND_T){
263 261
 					/*udp*/
264 262
 					dst.proto=PROTO_UDP; /* not really needed for udp_send */
... ...
@@ -271,17 +262,18 @@ int do_action(struct action* a, struct sip_msg* msg)
271 271
 				}
272 272
 #ifdef USE_TCP
273 273
 					else{
274
-					/*tcp*/
275
-					dst.proto=PROTO_TCP;
276
-					dst.id=0;
277
-					ret=tcp_send(&dst, tmp, len);
274
+						/*tcp*/
275
+						dst.proto=PROTO_TCP;
276
+						dst.id=0;
277
+						ret=tcp_send(&dst, tmp, len);
278 278
 				}
279 279
 #endif
280
+			}else{
281
+				ret=E_BUG;
282
+				break;
280 283
 			}
281
-			if (ret<0){
282
-				p->errors++;
283
-				p->ok=0;
284
-			}else ret=1;
284
+			proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
285
+			if (ret>=0) ret=1;
285 286
 
286 287
 			break;
287 288
 		case LOG_T:
... ...
@@ -119,6 +119,10 @@ int err2reason_phrase(
119 119
 			*sip_error=500;
120 120
 			break;
121 121
 #endif
122
+		case E_OK:
123
+			error_txt="No error";
124
+			*sip_error=500;
125
+			break;
122 126
 		default:
123 127
 			error_txt="I'm terribly sorry, server error occurred";
124 128
 			*sip_error=500;
... ...
@@ -29,6 +29,7 @@
29 29
 #ifndef error_h
30 30
 #define error_h
31 31
 
32
+#define E_OK           0
32 33
 #define E_UNSPEC      -1
33 34
 #define E_OUT_OF_MEM  -2
34 35
 #define E_BAD_RE      -3
... ...
@@ -261,42 +261,31 @@ found:
261 261
 
262 262
 
263 263
 
264
-/* parameters:
265
- *   msg - sip msg
266
- *   p   - proxy structure to forward to
267
- *   proto - protocol used
264
+/* forwards a request to dst
265
+ * parameters:
266
+ *   msg       - sip msg
267
+ *   send_info - filled dest_info structure:
268
+ *               if the send_socket memeber is null, a send_socket will be 
269
+ *               choosen automatically
270
+ * WARNING: don' forget to zero-fill all the  unused members (a non-zero 
271
+ * random id along with proto==PROTO_TCP can have bad consequences, same for
272
+ *   a bogus send_socket vaule)
268 273
  */
269
-int forward_request(struct sip_msg* msg, struct proxy_l * p, int proto)
274
+int forward_request(struct sip_msg* msg, struct dest_info* send_info)
270 275
 {
271 276
 	unsigned int len;
272 277
 	char* buf;
273 278
 	char md5[MD5_LEN];
274
-	struct dest_info send_info;
275 279
 	
276 280
 	buf=0;
277 281
 	
278
-	/* if error try next ip address if possible */
279
-	if (p->ok==0){
280
-		if (p->host.h_addr_list[p->addr_idx+1])
281
-			p->addr_idx++;
282
-		else p->addr_idx=0;
283
-		p->ok=1;
284
-	}
285
-	
286
-	hostent2su(&send_info.to, &p->host, p->addr_idx, 
287
-				(p->port)?p->port:SIP_PORT);
288
-	p->tx++;
289
-	p->tx_bytes+=len;
290
-	
291
-	
292
-	send_info.proto=proto;
293
-	send_info.id=0;
294
-	send_info.send_sock=get_send_socket(msg, &send_info.to,
295
-											send_info.proto);
296
-	if (send_info.send_sock==0){
282
+	if (send_info->send_sock==0)
283
+		send_info->send_sock=get_send_socket(msg, &send_info->to,
284
+												send_info->proto);
285
+	if (send_info->send_sock==0){
297 286
 		LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d, proto %d "
298 287
 				"no corresponding listening socket\n",
299
-				send_info.to.s.sa_family, send_info.proto);
288
+				send_info->to.s.sa_family, send_info->proto);
300 289
 		ser_error=E_NO_SOCKET;
301 290
 		goto error;
302 291
 	}
... ...
@@ -326,8 +315,8 @@ int forward_request(struct sip_msg* msg, struct proxy_l * p, int proto)
326 326
 		}
327 327
 	}
328 328
 
329
-	buf = build_req_buf_from_sip_req(msg, &len, send_info.send_sock,
330
-											send_info.proto);
329
+	buf = build_req_buf_from_sip_req(msg, &len, send_info->send_sock,
330
+											send_info->proto);
331 331
 	if (!buf){
332 332
 		LOG(L_ERR, "ERROR: forward_request: building failed\n");
333 333
 		goto error;
... ...
@@ -335,17 +324,16 @@ int forward_request(struct sip_msg* msg, struct proxy_l * p, int proto)
335 335
 	 /* send it! */
336 336
 	DBG("Sending:\n%.*s.\n", (int)len, buf);
337 337
 	DBG("orig. len=%d, new_len=%d, proto=%d\n",
338
-			msg->len, len, send_info.proto );
338
+			msg->len, len, send_info->proto );
339 339
 	
340
-	if (run_onsend(msg, &send_info, buf, len)==0){
340
+	if (run_onsend(msg, send_info, buf, len)==0){
341 341
 		LOG(L_INFO, "forward_request: request dropped (onsend_route)\n");
342 342
 		STATS_TX_DROPS;
343
+		ser_error=E_OK; /* no error */
343 344
 		goto error; /* error ? */
344 345
 	}
345
-	if (msg_send(&send_info, buf, len)<0){
346
+	if (msg_send(send_info, buf, len)<0){
346 347
 		ser_error=E_SEND;
347
-		p->errors++;
348
-		p->ok=0;
349 348
 		STATS_TX_DROPS;
350 349
 		goto error;
351 350
 	}
... ...
@@ -440,7 +428,7 @@ int forward_reply(struct sip_msg* msg)
440 440
 	char* s;
441 441
 	int len;
442 442
 #endif
443
-	memset(&dst, 0, sizeof(struct dest_info));	
443
+	init_dest_info(&dst);
444 444
 	new_buf=0;
445 445
 	/*check if first via host = us */
446 446
 	if (check_via){
... ...
@@ -60,7 +60,7 @@ struct socket_info* get_send_socket(struct sip_msg* msg,
60 60
 									union sockaddr_union* su, int proto);
61 61
 struct socket_info* get_out_socket(union sockaddr_union* to, int proto);
62 62
 int check_self(str* host, unsigned short port, unsigned short proto);
63
-int forward_request( struct sip_msg* msg,  struct proxy_l* p, int proto);
63
+int forward_request( struct sip_msg* msg,  struct dest_info* send_info);
64 64
 int update_sock_struct_from_via( union sockaddr_union* to,
65 65
 								 struct sip_msg* msg,
66 66
 								 struct via_body* via );
... ...
@@ -547,4 +547,16 @@ static inline struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
547 547
 	he.h_name=hostname;
548 548
 	return &he;
549 549
 }
550
+
551
+
552
+
553
+/* init a dest_info structure */
554
+#define init_dest_info(dst) \
555
+	do{ \
556
+		(dst)->proto=0; \
557
+		(dst)->id=0; \
558
+		(dst)->send_sock=0; \
559
+		memset(&(dst)->to, 0, sizeof(union sockaddr_union)); \
560
+	} while(0) 
561
+
550 562
 #endif
... ...
@@ -202,6 +202,7 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
202 202
 	int reply_ret;
203 203
 	/* struct hdr_field *hdr; */
204 204
 	struct cell *t;
205
+	struct dest_info dst;
205 206
 
206 207
 	ret=0;
207 208
 
... ...
@@ -229,18 +230,16 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
229 229
 		DBG( "SER: forwarding ACK  statelessly \n");
230 230
 		if (proxy==0) {
231 231
 			uri = GET_RURI(p_msg);
232
-			proxy=uri2proxy(GET_NEXT_HOP(p_msg), proto);
233
-			if (proxy==0) {
234
-					ret=E_BAD_ADDRESS;
235
-					goto done;
232
+			if (uri2dst(&dst, GET_NEXT_HOP(p_msg), proto)==0){
233
+				ret=E_BAD_ADDRESS;
234
+				goto done;
236 235
 			}
237
-			proto=proxy->proto; /* uri2proxy set it correctly */
238
-			ret=forward_request( p_msg , proxy, proto) ;
239
-			free_proxy( proxy );	
240
-			pkg_free( proxy );
236
+			ret=forward_request( p_msg , &dst) ;
241 237
 		} else {
242
-			proto=get_proto(proto, proxy->proto);
243
-			ret=forward_request( p_msg , proxy, proto ) ;
238
+			init_dest_info(&dst);
239
+			dst.proto=get_proto(proto, proxy->proto);
240
+			proxy2su(&dst.to, proxy);
241
+			ret=forward_request( p_msg , &dst) ;
244 242
 		}
245 243
 		goto done;
246 244
 	}
... ...
@@ -48,6 +48,7 @@
48 48
  *  2006-01-27  t_forward_no_ack will return error if a forward on an 
49 49
  *              already canceled transaction is attempted (andrei)
50 50
  *  2006-02-07  named routes support (andrei)
51
+ *  2006-04-18  add_uac simplified + switched to struct dest_info (andrei)
51 52
  */
52 53
 
53 54
 #include "defs.h"
... ...
@@ -227,10 +228,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
227 227
 {
228 228
 
229 229
 	int ret;
230
-	short temp_proxy;
231
-	union sockaddr_union to;
232 230
 	unsigned short branch;
233
-	struct socket_info* send_sock;
234 231
 	char *shbuf;
235 232
 	unsigned int len;
236 233
 
... ...
@@ -248,52 +246,44 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
248 248
 		goto error;
249 249
 	}
250 250
 
251
+	init_dest_info(&t->uac[branch].request.dst);
251 252
 	/* check DNS resolution */
252 253
 	if (proxy){
253
-		temp_proxy=0;
254
-		proto=get_proto(proto, proxy->proto);
254
+		/* dst filled from the proxy */
255
+		t->uac[branch].request.dst.proto=get_proto(proto, proxy->proto);
256
+		proxy2su(&t->uac[branch].request.dst.to, proxy);
255 257
 	}else {
256
-		proxy=uri2proxy( next_hop ? next_hop : uri, proto );
257
-		if (proxy==0)  {
258
+		/* dst filled from the uri */
259
+		if (uri2dst(&t->uac[branch].request.dst,
260
+						next_hop ? next_hop: uri, proto)==0){
258 261
 			ret=E_BAD_ADDRESS;
259 262
 			goto error;
260 263
 		}
261
-		proto=proxy->proto; /* uri2proxy will fix it for us */
262
-		temp_proxy=1;
263 264
 	}
264 265
 
265
-	if (proxy->ok==0) {
266
-		if (proxy->host.h_addr_list[proxy->addr_idx+1])
267
-			proxy->addr_idx++;
268
-		else proxy->addr_idx=0;
269
-		proxy->ok=1;
270
-	}
271
-
272
-	hostent2su( &to, &proxy->host, proxy->addr_idx, 
273
-		proxy->port ? proxy->port:((proto==PROTO_TLS)?SIPS_PORT:SIP_PORT));
274
-
275
-	send_sock=get_send_socket( request, &to , proto);
276
-	if (send_sock==0) {
266
+	/* fill dst send_sock */
267
+	t->uac[branch].request.dst.send_sock =
268
+			get_send_socket( request, &t->uac[branch].request.dst.to,
269
+								t->uac[branch].request.dst. proto);
270
+	if (t->uac[branch].request.dst.send_sock==0) {
277 271
 		LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d, proto %d "
278 272
 			" (no corresponding listening socket)\n",
279
-			to.s.sa_family, proto );
273
+			t->uac[branch].request.dst.to.s.sa_family, 
274
+			t->uac[branch].request.dst.proto );
280 275
 		ret=ser_error=E_NO_SOCKET;
281 276
 		goto error01;
282 277
 	}
283 278
 
284 279
 	/* now message printing starts ... */
285 280
 	shbuf=print_uac_request( t, request, branch, uri, 
286
-		&len, send_sock, proto );
281
+		&len, t->uac[branch].request.dst.send_sock, 
282
+			t->uac[branch].request.dst.proto );
287 283
 	if (!shbuf) {
288 284
 		ret=ser_error=E_OUT_OF_MEM;
289 285
 		goto error01;
290 286
 	}
291 287
 
292 288
 	/* things went well, move ahead and install new buffer! */
293
-	t->uac[branch].request.dst.to=to;
294
-	t->uac[branch].request.dst.send_sock=send_sock;
295
-	t->uac[branch].request.dst.proto=proto;
296
-	t->uac[branch].request.dst.id=0;
297 289
 	t->uac[branch].request.buffer=shbuf;
298 290
 	t->uac[branch].request.buffer_len=len;
299 291
 	t->uac[branch].uri.s=t->uac[branch].request.buffer+
... ...
@@ -302,17 +292,13 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
302 302
 	t->nr_of_outgoings++;
303 303
 
304 304
 	/* update stats */
305
-	proxy->tx++;
306
-	proxy->tx_bytes+=len;
307
-
305
+	if (proxy){
306
+		proxy_mark(proxy, 1);
307
+	}
308 308
 	/* done! */	
309 309
 	ret=branch;
310 310
 		
311 311
 error01:
312
-	if (temp_proxy) {
313
-		free_proxy( proxy );
314
-		pkg_free( proxy );
315
-	}
316 312
 error:
317 313
 	return ret;
318 314
 }
... ...
@@ -322,7 +322,7 @@ static int send_local_ack(struct sip_msg* msg, str* next_hop,
322 322
 		LOG(L_ERR, "send_local_ack: Invalid parameter value\n");
323 323
 		return -1;
324 324
 	}
325
-
325
+	init_dest_info(&dst);
326 326
 	dst.send_sock = uri2sock(msg, next_hop, &dst.to, PROTO_NONE);
327 327
 	if (!dst.send_sock) {
328 328
 		LOG(L_ERR, "send_local_ack: no socket found\n");
... ...
@@ -232,6 +232,8 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
232 232
 	set_kr(REQ_FWDED);
233 233
 
234 234
 	request = &new_cell->uac[0].request;
235
+	
236
+	init_dest_info(&request->dst);
235 237
 	request->dst.to = to_su;
236 238
 	request->dst.send_sock = send_sock;
237 239
 	request->dst.proto = send_sock->proto;
... ...
@@ -35,6 +35,7 @@
35 35
  *              specified explicitly (jiri)
36 36
  *  2003-07-07  get_proto takes now two protos as arguments (andrei)
37 37
  *              tls/sips support for get_proto & uri2proxy (andrei)
38
+ *  2006-04-13  added uri2dst(), simplified uri2sock() (andrei)
38 39
  */
39 40
 
40 41
 
... ...
@@ -52,6 +53,7 @@
52 52
 #include "../../forward.h"
53 53
 #include "../../mem/mem.h"
54 54
 #include "../../parser/msg_parser.h"
55
+#include "../../resolve.h"
55 56
 
56 57
 /* a forced_proto takes precedence if != PROTO_NONE */
57 58
 inline static enum sip_protos get_proto(enum sip_protos force_proto,
... ...
@@ -130,35 +132,71 @@ inline static struct proxy_l *uri2proxy( str *uri, int proto )
130 130
 }
131 131
 
132 132
 
133
+
134
+/*
135
+ * Convert a URI into a dest_info structure
136
+ * params: dst - will be filled
137
+ *         uri - uri in str form
138
+ *         proto - if != PROTO_NONE, this protocol will be forced over the
139
+ *                 uri_proto, otherwise the uri proto will be used
140
+ * returns 0 on error, dst on success
141
+ */
142
+inline static struct dest_info *uri2dst(struct dest_info* dst, str *uri, 
143
+											int proto )
144
+{
145
+	struct sip_uri parsed_uri;
146
+	enum sip_protos uri_proto;
147
+
148
+	if (parse_uri(uri->s, uri->len, &parsed_uri) < 0) {
149
+		LOG(L_ERR, "ERROR: uri2dst: bad_uri: %.*s\n",
150
+		    uri->len, uri->s );
151
+		return 0;
152
+	}
153
+	
154
+	if (parsed_uri.type==SIPS_URI_T){
155
+		if ((parsed_uri.proto!=PROTO_TCP) && (parsed_uri.proto!=PROTO_NONE)){
156
+			LOG(L_ERR, "ERROR: uri2dst: bad transport  for sips uri: %d\n",
157
+					parsed_uri.proto);
158
+			return 0;
159
+		}else
160
+			uri_proto=PROTO_TLS;
161
+	}else
162
+		uri_proto=parsed_uri.proto;
163
+	
164
+	init_dest_info(dst);
165
+	dst->proto= get_proto(proto, uri_proto);
166
+	sip_hostport2su(&dst->to, &parsed_uri.host, parsed_uri.port_no,
167
+						dst->proto);
168
+	return dst;
169
+}
170
+
171
+
172
+
133 173
 /*
134 174
  * Convert a URI into socket_info
135 175
  */
136 176
 static inline struct socket_info *uri2sock(struct sip_msg* msg, str *uri,
137 177
 									union sockaddr_union *to_su, int proto)
138 178
 {
139
-	struct proxy_l *proxy;
140 179
 	struct socket_info* send_sock;
180
+	struct dest_info dst;
141 181
 
142
-	proxy = uri2proxy(uri, proto);
143
-	if (!proxy) {
144
-		ser_error = E_BAD_ADDRESS;
182
+	if (uri2dst(&dst, uri, proto)==0){
145 183
 		LOG(L_ERR, "ERROR: uri2sock: Can't create a dst proxy\n");
184
+		ser_error=E_BAD_ADDRESS;
146 185
 		return 0;
147 186
 	}
187
+	*to_su=dst.to; /* copy su */
148 188
 	
149
-	hostent2su(to_su, &proxy->host, proxy->addr_idx, 
150
-		   (proxy->port) ? proxy->port : SIP_PORT);
151
-			/* we use proxy->proto since uri2proxy just set it correctly*/
152
-	send_sock = get_send_socket(msg, to_su, proxy->proto);
189
+	/* we use dst->proto since uri2dst just set it correctly*/
190
+	send_sock = get_send_socket(msg, to_su, dst.proto);
153 191
 	if (!send_sock) {
154 192
 		LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
155 193
 		    to_su->s.sa_family);
156 194
 		ser_error = E_NO_SOCKET;
157 195
 	}
158
-
159
-	free_proxy(proxy);
160
-	pkg_free(proxy);
161 196
 	return send_sock;
162 197
 }
163 198
 
199
+
164 200
 #endif /* _TM_UT_H */
... ...
@@ -38,6 +38,7 @@
38 38
 #include <netdb.h>
39 39
 #include "ip_addr.h"
40 40
 #include "str.h"
41
+#include "config.h"
41 42
 
42 43
 struct proxy_l{
43 44
 	struct proxy_l* next;
... ...
@@ -66,5 +67,36 @@ struct proxy_l* mk_proxy_from_ip(struct ip_addr* ip, unsigned short port,
66 66
 void free_proxy(struct proxy_l* p);
67 67
 
68 68
 
69
+
70
+/* returns 0 on success, -1 on error (unknown af/bug) */
71
+inline static int proxy2su(union sockaddr_union* su, struct proxy_l* p)
72
+{
73
+	/* if error try next ip address if possible */
74
+	if (p->ok==0){
75
+		if (p->host.h_addr_list[p->addr_idx+1])
76
+			p->addr_idx++;
77
+		else p->addr_idx=0;
78
+		p->ok=1;
79
+	}
80
+	
81
+	return hostent2su(su, &p->host, p->addr_idx,
82
+				(p->port)?p->port:((p->proto==PROTO_TLS)?SIPS_PORT:SIP_PORT) );
83
+}
84
+
85
+
86
+
87
+/* mark as proxy either as ok (err>=0) or as bad (err<0) */
88
+inline static void proxy_mark(struct proxy_l* p, int err)
89
+{
90
+	if (err<0){
91
+		p->errors++;
92
+		p->ok=0;
93
+	}else{
94
+		p->tx++;
95
+	}
96
+}
97
+
98
+
99
+
69 100
 #endif
70 101
 
... ...
@@ -30,6 +30,7 @@
30 30
  *  2003-02-13  added proto to sip_resolvehost, for SRV lookups (andrei)
31 31
  *  2003-07-03  default port value set according to proto (andrei)
32 32
  *  2005-07-11  added resolv_init (timeouts a.s.o) (andrei)
33
+ *  2006-04-13  added sip_hostport2su()  (andrei)
33 34
  */ 
34 35
 
35 36
 
... ...
@@ -43,6 +44,7 @@
43 43
 #include "dprint.h"
44 44
 #include "mem/mem.h"
45 45
 #include "ip_addr.h"
46
+#include "error.h"
46 47
 
47 48
 
48 49
 
... ...
@@ -587,3 +589,31 @@ skip_srv:
587 587
 	he=resolvehost(tmp);
588 588
 	return he;
589 589
 }
590
+
591
+
592
+
593
+/* resolve host, port, proto using sip rules (e.g. use SRV if port=0 a.s.o)
594
+ *  and write the result in the sockaddr_union to
595
+ *  returns -1 on error (resolve failed), 0 on success */
596
+int sip_hostport2su(union sockaddr_union* su, str* name, unsigned short port,
597
+						int proto)
598
+{
599
+	struct hostent* he;
600
+	
601
+	
602
+	he=sip_resolvehost(name, &port, proto);
603
+	if (he==0){
604
+		ser_error=E_BAD_ADDRESS;
605
+		LOG(L_ERR, "ERROR: sip_hostport2su: could not resolve hostname:"
606
+					" \"%.*s\"\n", name->len, name->s);
607
+		goto error;
608
+	}
609
+	/* port filled by sip_resolvehost if empty*/
610
+	if (hostent2su(su, he, 0, port)<0){
611
+		ser_error=E_BAD_ADDRESS;
612
+		goto error;
613
+	}
614
+	return 0;
615
+error:
616
+	return -1;
617
+}
... ...
@@ -359,4 +359,6 @@ skip_ipv4:
359 359
 
360 360
 int resolv_init();
361 361
 
362
+int sip_hostport2su(union sockaddr_union* su, str* host, unsigned short port,
363
+						int proto);
362 364
 #endif