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 98
 	int ret;
98 99
 	int v;
99 100
 	struct dest_info dst;
100
-	struct proxy_l* p;
101 101
 	char* tmp;
102 102
 	char *new_uri, *end, *crt;
103 103
 	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 132
 		case FORWARD_TLS_T:
134 133
 #endif
135 134
 		case FORWARD_UDP_T:
136
-
137
-			if (a->type==FORWARD_UDP_T) proto=PROTO_UDP;
135
+			/* init dst */
136
+			init_dest_info(&dst);
137
+			if (a->type==FORWARD_UDP_T) dst.proto=PROTO_UDP;
138 138
 #ifdef USE_TCP
139
-			else if (a->type==FORWARD_TCP_T) proto= PROTO_TCP;
139
+			else if (a->type==FORWARD_TCP_T) dst.proto= PROTO_TCP;
140 140
 #endif
141 141
 #ifdef USE_TLS
142
-			else if (a->type==FORWARD_TLS_T) proto= PROTO_TLS;
142
+			else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
143 143
 #endif
144
-			else proto= PROTO_NONE;
144
+			else dst.proto= PROTO_NONE;
145 145
 			if (a->val[0].type==URIHOST_ST){
146 146
 				/*parse uri*/
147 147
 
... ...
@@ -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 250
 					tmp=msg->buf;
258 251
 					len=msg->len;
259 252
 				}
260
-				p->tx++;
261
-				p->tx_bytes+=len;
262 253
 				if (a->type==SEND_T){
263 254
 					/*udp*/
264 255
 					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 262
 				}
272 263
 #ifdef USE_TCP
273 264
 					else{
274
-					/*tcp*/
275
-					dst.proto=PROTO_TCP;
276
-					dst.id=0;
277
-					ret=tcp_send(&dst, tmp, len);
265
+						/*tcp*/
266
+						dst.proto=PROTO_TCP;
267
+						dst.id=0;
268
+						ret=tcp_send(&dst, tmp, len);
278 269
 				}
279 270
 #endif
271
+			}else{
272
+				ret=E_BUG;
273
+				break;
280 274
 			}
281
-			if (ret<0){
282
-				p->errors++;
283
-				p->ok=0;
284
-			}else ret=1;
275
+			proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
276
+			if (ret>=0) ret=1;
285 277
 
286 278
 			break;
287 279
 		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 315
 		}
327 316
 	}
328 317
 
329
-	buf = build_req_buf_from_sip_req(msg, &len, send_info.send_sock,
330
-											send_info.proto);
318
+	buf = build_req_buf_from_sip_req(msg, &len, send_info->send_sock,
319
+											send_info->proto);
331 320
 	if (!buf){
332 321
 		LOG(L_ERR, "ERROR: forward_request: building failed\n");
333 322
 		goto error;
... ...
@@ -335,17 +324,16 @@ int forward_request(struct sip_msg* msg, struct proxy_l * p, int proto)
335 324
 	 /* send it! */
336 325
 	DBG("Sending:\n%.*s.\n", (int)len, buf);
337 326
 	DBG("orig. len=%d, new_len=%d, proto=%d\n",
338
-			msg->len, len, send_info.proto );
327
+			msg->len, len, send_info->proto );
339 328
 	
340
-	if (run_onsend(msg, &send_info, buf, len)==0){
329
+	if (run_onsend(msg, send_info, buf, len)==0){
341 330
 		LOG(L_INFO, "forward_request: request dropped (onsend_route)\n");
342 331
 		STATS_TX_DROPS;
332
+		ser_error=E_OK; /* no error */
343 333
 		goto error; /* error ? */
344 334
 	}
345
-	if (msg_send(&send_info, buf, len)<0){
335
+	if (msg_send(send_info, buf, len)<0){
346 336
 		ser_error=E_SEND;
347
-		p->errors++;
348
-		p->ok=0;
349 337
 		STATS_TX_DROPS;
350 338
 		goto error;
351 339
 	}
... ...
@@ -440,7 +428,7 @@ int forward_reply(struct sip_msg* msg)
440 428
 	char* s;
441 429
 	int len;
442 430
 #endif
443
-	memset(&dst, 0, sizeof(struct dest_info));	
431
+	init_dest_info(&dst);
444 432
 	new_buf=0;
445 433
 	/*check if first via host = us */
446 434
 	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 230
 		DBG( "SER: forwarding ACK  statelessly \n");
230 231
 		if (proxy==0) {
231 232
 			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;
233
+			if (uri2dst(&dst, GET_NEXT_HOP(p_msg), proto)==0){
234
+				ret=E_BAD_ADDRESS;
235
+				goto done;
236 236
 			}
237
-			proto=proxy->proto; /* uri2proxy set it correctly */
238
-			ret=forward_request( p_msg , proxy, proto) ;
239
-			free_proxy( proxy );	
240
-			pkg_free( proxy );
237
+			ret=forward_request( p_msg , &dst) ;
241 238
 		} else {
242
-			proto=get_proto(proto, proxy->proto);
243
-			ret=forward_request( p_msg , proxy, proto ) ;
239
+			init_dest_info(&dst);
240
+			dst.proto=get_proto(proto, proxy->proto);
241
+			proxy2su(&dst.to, proxy);
242
+			ret=forward_request( p_msg , &dst) ;
244 243
 		}
245 244
 		goto done;
246 245
 	}
... ...
@@ -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 228
 {
228 229
 
229 230
 	int ret;
230
-	short temp_proxy;
231
-	union sockaddr_union to;
232 231
 	unsigned short branch;
233
-	struct socket_info* send_sock;
234 232
 	char *shbuf;
235 233
 	unsigned int len;
236 234
 
... ...
@@ -248,52 +246,44 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
248 246
 		goto error;
249 247
 	}
250 248
 
249
+	init_dest_info(&t->uac[branch].request.dst);
251 250
 	/* check DNS resolution */
252 251
 	if (proxy){
253
-		temp_proxy=0;
254
-		proto=get_proto(proto, proxy->proto);
252
+		/* dst filled from the proxy */
253
+		t->uac[branch].request.dst.proto=get_proto(proto, proxy->proto);
254
+		proxy2su(&t->uac[branch].request.dst.to, proxy);
255 255
 	}else {
256
-		proxy=uri2proxy( next_hop ? next_hop : uri, proto );
257
-		if (proxy==0)  {
256
+		/* dst filled from the uri */
257
+		if (uri2dst(&t->uac[branch].request.dst,
258
+						next_hop ? next_hop: uri, proto)==0){
258 259
 			ret=E_BAD_ADDRESS;
259 260
 			goto error;
260 261
 		}
261
-		proto=proxy->proto; /* uri2proxy will fix it for us */
262
-		temp_proxy=1;
263 262
 	}
264 263
 
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) {
264
+	/* fill dst send_sock */
265
+	t->uac[branch].request.dst.send_sock =
266
+			get_send_socket( request, &t->uac[branch].request.dst.to,
267
+								t->uac[branch].request.dst. proto);
268
+	if (t->uac[branch].request.dst.send_sock==0) {
277 269
 		LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d, proto %d "
278 270
 			" (no corresponding listening socket)\n",
279
-			to.s.sa_family, proto );
271
+			t->uac[branch].request.dst.to.s.sa_family, 
272
+			t->uac[branch].request.dst.proto );
280 273
 		ret=ser_error=E_NO_SOCKET;
281 274
 		goto error01;
282 275
 	}
283 276
 
284 277
 	/* now message printing starts ... */
285 278
 	shbuf=print_uac_request( t, request, branch, uri, 
286
-		&len, send_sock, proto );
279
+		&len, t->uac[branch].request.dst.send_sock, 
280
+			t->uac[branch].request.dst.proto );
287 281
 	if (!shbuf) {
288 282
 		ret=ser_error=E_OUT_OF_MEM;
289 283
 		goto error01;
290 284
 	}
291 285
 
292 286
 	/* 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 287
 	t->uac[branch].request.buffer=shbuf;
298 288
 	t->uac[branch].request.buffer_len=len;
299 289
 	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 292
 	t->nr_of_outgoings++;
303 293
 
304 294
 	/* update stats */
305
-	proxy->tx++;
306
-	proxy->tx_bytes+=len;
307
-
295
+	if (proxy){
296
+		proxy_mark(proxy, 1);
297
+	}
308 298
 	/* done! */	
309 299
 	ret=branch;
310 300
 		
311 301
 error01:
312
-	if (temp_proxy) {
313
-		free_proxy( proxy );
314
-		pkg_free( proxy );
315
-	}
316 302
 error:
317 303
 	return ret;
318 304
 }
... ...
@@ -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 53
 #include "../../forward.h"
53 54
 #include "../../mem/mem.h"
54 55
 #include "../../parser/msg_parser.h"
56
+#include "../../resolve.h"
55 57
 
56 58
 /* a forced_proto takes precedence if != PROTO_NONE */
57 59
 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 132
 }
131 133
 
132 134
 
135
+
136
+/*
137
+ * Convert a URI into a dest_info structure
138
+ * params: dst - will be filled
139
+ *         uri - uri in str form
140
+ *         proto - if != PROTO_NONE, this protocol will be forced over the
141
+ *                 uri_proto, otherwise the uri proto will be used
142
+ * returns 0 on error, dst on success
143
+ */
144
+inline static struct dest_info *uri2dst(struct dest_info* dst, str *uri, 
145
+											int proto )
146
+{
147
+	struct sip_uri parsed_uri;
148
+	enum sip_protos uri_proto;
149
+
150
+	if (parse_uri(uri->s, uri->len, &parsed_uri) < 0) {
151
+		LOG(L_ERR, "ERROR: uri2dst: bad_uri: %.*s\n",
152
+		    uri->len, uri->s );
153
+		return 0;
154
+	}
155
+	
156
+	if (parsed_uri.type==SIPS_URI_T){
157
+		if ((parsed_uri.proto!=PROTO_TCP) && (parsed_uri.proto!=PROTO_NONE)){
158
+			LOG(L_ERR, "ERROR: uri2dst: bad transport  for sips uri: %d\n",
159
+					parsed_uri.proto);
160
+			return 0;
161
+		}else
162
+			uri_proto=PROTO_TLS;
163
+	}else
164
+		uri_proto=parsed_uri.proto;
165
+	
166
+	init_dest_info(dst);
167
+	dst->proto= get_proto(proto, uri_proto);
168
+	sip_hostport2su(&dst->to, &parsed_uri.host, parsed_uri.port_no,
169
+						dst->proto);
170
+	return dst;
171
+}
172
+
173
+
174
+
133 175
 /*
134 176
  * Convert a URI into socket_info
135 177
  */
136 178
 static inline struct socket_info *uri2sock(struct sip_msg* msg, str *uri,
137 179
 									union sockaddr_union *to_su, int proto)
138 180
 {
139
-	struct proxy_l *proxy;
140 181
 	struct socket_info* send_sock;
182
+	struct dest_info dst;
141 183
 
142
-	proxy = uri2proxy(uri, proto);
143
-	if (!proxy) {
144
-		ser_error = E_BAD_ADDRESS;
184
+	if (uri2dst(&dst, uri, proto)==0){
145 185
 		LOG(L_ERR, "ERROR: uri2sock: Can't create a dst proxy\n");
186
+		ser_error=E_BAD_ADDRESS;
146 187
 		return 0;
147 188
 	}
189
+	*to_su=dst.to; /* copy su */
148 190
 	
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);
191
+	/* we use dst->proto since uri2dst just set it correctly*/
192
+	send_sock = get_send_socket(msg, to_su, dst.proto);
153 193
 	if (!send_sock) {
154 194
 		LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
155 195
 		    to_su->s.sa_family);
156 196
 		ser_error = E_NO_SOCKET;
157 197
 	}
158
-
159
-	free_proxy(proxy);
160
-	pkg_free(proxy);
161 198
 	return send_sock;
162 199
 }
163 200
 
201
+
164 202
 #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 67
 void free_proxy(struct proxy_l* p);
67 68
 
68 69
 
70
+
71
+/* returns 0 on success, -1 on error (unknown af/bug) */
72
+inline static int proxy2su(union sockaddr_union* su, struct proxy_l* p)
73
+{
74
+	/* if error try next ip address if possible */
75
+	if (p->ok==0){
76
+		if (p->host.h_addr_list[p->addr_idx+1])
77
+			p->addr_idx++;
78
+		else p->addr_idx=0;
79
+		p->ok=1;
80
+	}
81
+	
82
+	return hostent2su(su, &p->host, p->addr_idx,
83
+				(p->port)?p->port:((p->proto==PROTO_TLS)?SIPS_PORT:SIP_PORT) );
84
+}
85
+
86
+
87
+
88
+/* mark as proxy either as ok (err>=0) or as bad (err<0) */
89
+inline static void proxy_mark(struct proxy_l* p, int err)
90
+{
91
+	if (err<0){
92
+		p->errors++;
93
+		p->ok=0;
94
+	}else{
95
+		p->tx++;
96
+	}
97
+}
98
+
99
+
100
+
69 101
 #endif
70 102
 
... ...
@@ -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 44
 #include "dprint.h"
44 45
 #include "mem/mem.h"
45 46
 #include "ip_addr.h"
47
+#include "error.h"
46 48
 
47 49
 
48 50
 
... ...
@@ -587,3 +589,31 @@ skip_srv:
587 589
 	he=resolvehost(tmp);
588 590
 	return he;
589 591
 }
592
+
593
+
594
+
595
+/* resolve host, port, proto using sip rules (e.g. use SRV if port=0 a.s.o)
596
+ *  and write the result in the sockaddr_union to
597
+ *  returns -1 on error (resolve failed), 0 on success */
598
+int sip_hostport2su(union sockaddr_union* su, str* name, unsigned short port,
599
+						int proto)
600
+{
601
+	struct hostent* he;
602
+	
603
+	
604
+	he=sip_resolvehost(name, &port, proto);
605
+	if (he==0){
606
+		ser_error=E_BAD_ADDRESS;
607
+		LOG(L_ERR, "ERROR: sip_hostport2su: could not resolve hostname:"
608
+					" \"%.*s\"\n", name->len, name->s);
609
+		goto error;
610
+	}
611
+	/* port filled by sip_resolvehost if empty*/
612
+	if (hostent2su(su, he, 0, port)<0){
613
+		ser_error=E_BAD_ADDRESS;
614
+		goto error;
615
+	}
616
+	return 0;
617
+error:
618
+	return -1;
619
+}
... ...
@@ -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