Selaa lähdekoodia

- 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 19 vuotta sitten
vanhempi
commit
2f0f1a30df
15 muutettua tiedostoa jossa 221 lisäystä ja 135 poistoa
  1. 1 1
      Makefile.defs
  2. 35 43
      action.c
  3. 4 0
      error.c
  4. 1 0
      error.h
  5. 22 34
      forward.c
  6. 1 1
      forward.h
  7. 12 0
      ip_addr.h
  8. 9 10
      modules/tm/t_funcs.c
  9. 20 34
      modules/tm/t_fwd.c
  10. 1 1
      modules/tm/t_reply.c
  11. 2 0
      modules/tm/uac.c
  12. 49 11
      modules/tm/ut.h
  13. 32 0
      proxy.h
  14. 30 0
      resolve.c
  15. 2 0
      resolve.h

+ 1 - 1
Makefile.defs

@@ -66,7 +66,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 10
 SUBLEVEL =   99
-EXTRAVERSION = -dev38
+EXTRAVERSION = -dev39
 
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
 			$(SUBLEVEL) )

+ 35 - 43
action.c

@@ -62,6 +62,7 @@
 #include "globals.h"
 #include "dset.h"
 #include "onsend.h"
+#include "resolve.h"
 #ifdef USE_TCP
 #include "tcp_server.h"
 #endif
@@ -97,7 +98,6 @@ int do_action(struct action* a, struct sip_msg* msg)
 	int ret;
 	int v;
 	struct dest_info dst;
-	struct proxy_l* p;
 	char* tmp;
 	char *new_uri, *end, *crt;
 	int len;
@@ -105,7 +105,6 @@ int do_action(struct action* a, struct sip_msg* msg)
 	struct sip_uri uri, next_hop;
 	struct sip_uri *u;
 	unsigned short port;
-	int proto;
 	unsigned short flags;
 	int_str name, value;
 
@@ -133,15 +132,16 @@ int do_action(struct action* a, struct sip_msg* msg)
 		case FORWARD_TLS_T:
 #endif
 		case FORWARD_UDP_T:
-
-			if (a->type==FORWARD_UDP_T) proto=PROTO_UDP;
+			/* init dst */
+			init_dest_info(&dst);
+			if (a->type==FORWARD_UDP_T) dst.proto=PROTO_UDP;
 #ifdef USE_TCP
-			else if (a->type==FORWARD_TCP_T) proto= PROTO_TCP;
+			else if (a->type==FORWARD_TCP_T) dst.proto= PROTO_TCP;
 #endif
 #ifdef USE_TLS
-			else if (a->type==FORWARD_TLS_T) proto= PROTO_TLS;
+			else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
 #endif
-			else proto= PROTO_NONE;
+			else dst.proto= PROTO_NONE;
 			if (a->val[0].type==URIHOST_ST){
 				/*parse uri*/
 
@@ -172,11 +172,11 @@ int do_action(struct action* a, struct sip_msg* msg)
 							ret=E_UNSPEC;
 							goto error_fwd_uri;
 				}
-				if (proto == PROTO_NONE){ /* only if proto not set get it
+				if (dst.proto == PROTO_NONE){ /* only if proto not set get it
 											 from the uri */
 					switch(u->proto){
 						case PROTO_NONE:
-							proto=PROTO_UDP;
+							dst.proto=PROTO_UDP;
 							break;
 						case PROTO_UDP:
 #ifdef USE_TCP
@@ -185,7 +185,7 @@ int do_action(struct action* a, struct sip_msg* msg)
 #ifdef USE_TLS
 						case PROTO_TLS:
 #endif
-							proto=u->proto;
+							dst.proto=u->proto;
 							break;
 						default:
 							LOG(L_ERR,"ERROR: do action: forward: bad uri"
@@ -202,29 +202,29 @@ int do_action(struct action* a, struct sip_msg* msg)
 							ret=E_BAD_PROTO;
 							goto error_fwd_uri;
 						}
-						proto=PROTO_TLS;
+						dst.proto=PROTO_TLS;
 					}
 #endif
 				}
-				/* create a temporary proxy*/
-				p=mk_proxy(&u->host, port, proto);
-				if (p==0){
+				if (sip_hostport2su(&dst.to, &u->host, port, dst.proto)<0){
 					LOG(L_ERR, "ERROR:  bad host name in uri,"
 							" dropping packet\n");
 					ret=E_BAD_ADDRESS;
 					goto error_fwd_uri;
 				}
-				ret=forward_request(msg, p, proto);
-				/*free_uri(&uri); -- no longer needed, in sip_msg*/
-				free_proxy(p); /* frees only p content, not p itself */
-				pkg_free(p);
+				ret=forward_request(msg, &dst);
 				if (ret>=0) ret=1;
 			}else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
-				if (proto==PROTO_NONE)
-					proto=msg->rcv.proto;
-				ret=forward_request(msg, (struct proxy_l*)a->val[0].u.data,
-										proto);
-				if (ret>=0) ret=1;
+				if (dst.proto==PROTO_NONE)
+					dst.proto=msg->rcv.proto;
+				proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
+				ret=forward_request(msg, &dst);
+				if (ret>=0){
+					ret=1;
+					proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
+				}else if (ser_error!=E_OK){
+					proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
+				}
 			}else{
 				LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
 						a->val[0].type, a->val[1].type);
@@ -239,16 +239,9 @@ int do_action(struct action* a, struct sip_msg* msg)
 				ret=E_BUG;
 				break;
 			}
-			p=(struct proxy_l*)a->val[0].u.data;
-			if (p->ok==0){
-				if (p->host.h_addr_list[p->addr_idx+1])
-					p->addr_idx++;
-				else
-					p->addr_idx=0;
-				p->ok=1;
-			}
-			ret=hostent2su(&dst.to, &p->host, p->addr_idx,
-						(p->port)?p->port:SIP_PORT );
+			/* init dst */
+			init_dest_info(&dst);
+			ret=proxy2su(&dst.to,  (struct proxy_l*)a->val[0].u.data);
 			if (ret==0){
 				if (p_onsend){
 					tmp=p_onsend->buf;
@@ -257,8 +250,6 @@ int do_action(struct action* a, struct sip_msg* msg)
 					tmp=msg->buf;
 					len=msg->len;
 				}
-				p->tx++;
-				p->tx_bytes+=len;
 				if (a->type==SEND_T){
 					/*udp*/
 					dst.proto=PROTO_UDP; /* not really needed for udp_send */
@@ -271,17 +262,18 @@ int do_action(struct action* a, struct sip_msg* msg)
 				}
 #ifdef USE_TCP
 					else{
-					/*tcp*/
-					dst.proto=PROTO_TCP;
-					dst.id=0;
-					ret=tcp_send(&dst, tmp, len);
+						/*tcp*/
+						dst.proto=PROTO_TCP;
+						dst.id=0;
+						ret=tcp_send(&dst, tmp, len);
 				}
 #endif
+			}else{
+				ret=E_BUG;
+				break;
 			}
-			if (ret<0){
-				p->errors++;
-				p->ok=0;
-			}else ret=1;
+			proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
+			if (ret>=0) ret=1;
 
 			break;
 		case LOG_T:

+ 4 - 0
error.c

@@ -119,6 +119,10 @@ int err2reason_phrase(
 			*sip_error=500;
 			break;
 #endif
+		case E_OK:
+			error_txt="No error";
+			*sip_error=500;
+			break;
 		default:
 			error_txt="I'm terribly sorry, server error occurred";
 			*sip_error=500;

+ 1 - 0
error.h

@@ -29,6 +29,7 @@
 #ifndef error_h
 #define error_h
 
+#define E_OK           0
 #define E_UNSPEC      -1
 #define E_OUT_OF_MEM  -2
 #define E_BAD_RE      -3

+ 22 - 34
forward.c

@@ -261,42 +261,31 @@ found:
 
 
 
-/* parameters:
- *   msg - sip msg
- *   p   - proxy structure to forward to
- *   proto - protocol used
+/* forwards a request to dst
+ * parameters:
+ *   msg       - sip msg
+ *   send_info - filled dest_info structure:
+ *               if the send_socket memeber is null, a send_socket will be 
+ *               choosen automatically
+ * WARNING: don' forget to zero-fill all the  unused members (a non-zero 
+ * random id along with proto==PROTO_TCP can have bad consequences, same for
+ *   a bogus send_socket vaule)
  */
-int forward_request(struct sip_msg* msg, struct proxy_l * p, int proto)
+int forward_request(struct sip_msg* msg, struct dest_info* send_info)
 {
 	unsigned int len;
 	char* buf;
 	char md5[MD5_LEN];
-	struct dest_info send_info;
 	
 	buf=0;
 	
-	/* if error try next ip address if possible */
-	if (p->ok==0){
-		if (p->host.h_addr_list[p->addr_idx+1])
-			p->addr_idx++;
-		else p->addr_idx=0;
-		p->ok=1;
-	}
-	
-	hostent2su(&send_info.to, &p->host, p->addr_idx, 
-				(p->port)?p->port:SIP_PORT);
-	p->tx++;
-	p->tx_bytes+=len;
-	
-	
-	send_info.proto=proto;
-	send_info.id=0;
-	send_info.send_sock=get_send_socket(msg, &send_info.to,
-											send_info.proto);
-	if (send_info.send_sock==0){
+	if (send_info->send_sock==0)
+		send_info->send_sock=get_send_socket(msg, &send_info->to,
+												send_info->proto);
+	if (send_info->send_sock==0){
 		LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d, proto %d "
 				"no corresponding listening socket\n",
-				send_info.to.s.sa_family, send_info.proto);
+				send_info->to.s.sa_family, send_info->proto);
 		ser_error=E_NO_SOCKET;
 		goto error;
 	}
@@ -326,8 +315,8 @@ int forward_request(struct sip_msg* msg, struct proxy_l * p, int proto)
 		}
 	}
 
-	buf = build_req_buf_from_sip_req(msg, &len, send_info.send_sock,
-											send_info.proto);
+	buf = build_req_buf_from_sip_req(msg, &len, send_info->send_sock,
+											send_info->proto);
 	if (!buf){
 		LOG(L_ERR, "ERROR: forward_request: building failed\n");
 		goto error;
@@ -335,17 +324,16 @@ int forward_request(struct sip_msg* msg, struct proxy_l * p, int proto)
 	 /* send it! */
 	DBG("Sending:\n%.*s.\n", (int)len, buf);
 	DBG("orig. len=%d, new_len=%d, proto=%d\n",
-			msg->len, len, send_info.proto );
+			msg->len, len, send_info->proto );
 	
-	if (run_onsend(msg, &send_info, buf, len)==0){
+	if (run_onsend(msg, send_info, buf, len)==0){
 		LOG(L_INFO, "forward_request: request dropped (onsend_route)\n");
 		STATS_TX_DROPS;
+		ser_error=E_OK; /* no error */
 		goto error; /* error ? */
 	}
-	if (msg_send(&send_info, buf, len)<0){
+	if (msg_send(send_info, buf, len)<0){
 		ser_error=E_SEND;
-		p->errors++;
-		p->ok=0;
 		STATS_TX_DROPS;
 		goto error;
 	}
@@ -440,7 +428,7 @@ int forward_reply(struct sip_msg* msg)
 	char* s;
 	int len;
 #endif
-	memset(&dst, 0, sizeof(struct dest_info));	
+	init_dest_info(&dst);
 	new_buf=0;
 	/*check if first via host = us */
 	if (check_via){

+ 1 - 1
forward.h

@@ -60,7 +60,7 @@ struct socket_info* get_send_socket(struct sip_msg* msg,
 									union sockaddr_union* su, int proto);
 struct socket_info* get_out_socket(union sockaddr_union* to, int proto);
 int check_self(str* host, unsigned short port, unsigned short proto);
-int forward_request( struct sip_msg* msg,  struct proxy_l* p, int proto);
+int forward_request( struct sip_msg* msg,  struct dest_info* send_info);
 int update_sock_struct_from_via( union sockaddr_union* to,
 								 struct sip_msg* msg,
 								 struct via_body* via );

+ 12 - 0
ip_addr.h

@@ -547,4 +547,16 @@ static inline struct hostent* ip_addr2he(str* name, struct ip_addr* ip)
 	he.h_name=hostname;
 	return &he;
 }
+
+
+
+/* init a dest_info structure */
+#define init_dest_info(dst) \
+	do{ \
+		(dst)->proto=0; \
+		(dst)->id=0; \
+		(dst)->send_sock=0; \
+		memset(&(dst)->to, 0, sizeof(union sockaddr_union)); \
+	} while(0) 
+
 #endif

+ 9 - 10
modules/tm/t_funcs.c

@@ -202,6 +202,7 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
 	int reply_ret;
 	/* struct hdr_field *hdr; */
 	struct cell *t;
+	struct dest_info dst;
 
 	ret=0;
 
@@ -229,18 +230,16 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
 		DBG( "SER: forwarding ACK  statelessly \n");
 		if (proxy==0) {
 			uri = GET_RURI(p_msg);
-			proxy=uri2proxy(GET_NEXT_HOP(p_msg), proto);
-			if (proxy==0) {
-					ret=E_BAD_ADDRESS;
-					goto done;
+			if (uri2dst(&dst, GET_NEXT_HOP(p_msg), proto)==0){
+				ret=E_BAD_ADDRESS;
+				goto done;
 			}
-			proto=proxy->proto; /* uri2proxy set it correctly */
-			ret=forward_request( p_msg , proxy, proto) ;
-			free_proxy( proxy );	
-			pkg_free( proxy );
+			ret=forward_request( p_msg , &dst) ;
 		} else {
-			proto=get_proto(proto, proxy->proto);
-			ret=forward_request( p_msg , proxy, proto ) ;
+			init_dest_info(&dst);
+			dst.proto=get_proto(proto, proxy->proto);
+			proxy2su(&dst.to, proxy);
+			ret=forward_request( p_msg , &dst) ;
 		}
 		goto done;
 	}

+ 20 - 34
modules/tm/t_fwd.c

@@ -48,6 +48,7 @@
  *  2006-01-27  t_forward_no_ack will return error if a forward on an 
  *              already canceled transaction is attempted (andrei)
  *  2006-02-07  named routes support (andrei)
+ *  2006-04-18  add_uac simplified + switched to struct dest_info (andrei)
  */
 
 #include "defs.h"
@@ -227,10 +228,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
 {
 
 	int ret;
-	short temp_proxy;
-	union sockaddr_union to;
 	unsigned short branch;
-	struct socket_info* send_sock;
 	char *shbuf;
 	unsigned int len;
 
@@ -248,52 +246,44 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
 		goto error;
 	}
 
+	init_dest_info(&t->uac[branch].request.dst);
 	/* check DNS resolution */
 	if (proxy){
-		temp_proxy=0;
-		proto=get_proto(proto, proxy->proto);
+		/* dst filled from the proxy */
+		t->uac[branch].request.dst.proto=get_proto(proto, proxy->proto);
+		proxy2su(&t->uac[branch].request.dst.to, proxy);
 	}else {
-		proxy=uri2proxy( next_hop ? next_hop : uri, proto );
-		if (proxy==0)  {
+		/* dst filled from the uri */
+		if (uri2dst(&t->uac[branch].request.dst,
+						next_hop ? next_hop: uri, proto)==0){
 			ret=E_BAD_ADDRESS;
 			goto error;
 		}
-		proto=proxy->proto; /* uri2proxy will fix it for us */
-		temp_proxy=1;
 	}
 
-	if (proxy->ok==0) {
-		if (proxy->host.h_addr_list[proxy->addr_idx+1])
-			proxy->addr_idx++;
-		else proxy->addr_idx=0;
-		proxy->ok=1;
-	}
-
-	hostent2su( &to, &proxy->host, proxy->addr_idx, 
-		proxy->port ? proxy->port:((proto==PROTO_TLS)?SIPS_PORT:SIP_PORT));
-
-	send_sock=get_send_socket( request, &to , proto);
-	if (send_sock==0) {
+	/* fill dst send_sock */
+	t->uac[branch].request.dst.send_sock =
+			get_send_socket( request, &t->uac[branch].request.dst.to,
+								t->uac[branch].request.dst. proto);
+	if (t->uac[branch].request.dst.send_sock==0) {
 		LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d, proto %d "
 			" (no corresponding listening socket)\n",
-			to.s.sa_family, proto );
+			t->uac[branch].request.dst.to.s.sa_family, 
+			t->uac[branch].request.dst.proto );
 		ret=ser_error=E_NO_SOCKET;
 		goto error01;
 	}
 
 	/* now message printing starts ... */
 	shbuf=print_uac_request( t, request, branch, uri, 
-		&len, send_sock, proto );
+		&len, t->uac[branch].request.dst.send_sock, 
+			t->uac[branch].request.dst.proto );
 	if (!shbuf) {
 		ret=ser_error=E_OUT_OF_MEM;
 		goto error01;
 	}
 
 	/* things went well, move ahead and install new buffer! */
-	t->uac[branch].request.dst.to=to;
-	t->uac[branch].request.dst.send_sock=send_sock;
-	t->uac[branch].request.dst.proto=proto;
-	t->uac[branch].request.dst.id=0;
 	t->uac[branch].request.buffer=shbuf;
 	t->uac[branch].request.buffer_len=len;
 	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,
 	t->nr_of_outgoings++;
 
 	/* update stats */
-	proxy->tx++;
-	proxy->tx_bytes+=len;
-
+	if (proxy){
+		proxy_mark(proxy, 1);
+	}
 	/* done! */	
 	ret=branch;
 		
 error01:
-	if (temp_proxy) {
-		free_proxy( proxy );
-		pkg_free( proxy );
-	}
 error:
 	return ret;
 }

+ 1 - 1
modules/tm/t_reply.c

@@ -322,7 +322,7 @@ static int send_local_ack(struct sip_msg* msg, str* next_hop,
 		LOG(L_ERR, "send_local_ack: Invalid parameter value\n");
 		return -1;
 	}
-
+	init_dest_info(&dst);
 	dst.send_sock = uri2sock(msg, next_hop, &dst.to, PROTO_NONE);
 	if (!dst.send_sock) {
 		LOG(L_ERR, "send_local_ack: no socket found\n");

+ 2 - 0
modules/tm/uac.c

@@ -232,6 +232,8 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
 	set_kr(REQ_FWDED);
 
 	request = &new_cell->uac[0].request;
+	
+	init_dest_info(&request->dst);
 	request->dst.to = to_su;
 	request->dst.send_sock = send_sock;
 	request->dst.proto = send_sock->proto;

+ 49 - 11
modules/tm/ut.h

@@ -35,6 +35,7 @@
  *              specified explicitly (jiri)
  *  2003-07-07  get_proto takes now two protos as arguments (andrei)
  *              tls/sips support for get_proto & uri2proxy (andrei)
+ *  2006-04-13  added uri2dst(), simplified uri2sock() (andrei)
  */
 
 
@@ -52,6 +53,7 @@
 #include "../../forward.h"
 #include "../../mem/mem.h"
 #include "../../parser/msg_parser.h"
+#include "../../resolve.h"
 
 /* a forced_proto takes precedence if != PROTO_NONE */
 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 )
 }
 
 
+
+/*
+ * Convert a URI into a dest_info structure
+ * params: dst - will be filled
+ *         uri - uri in str form
+ *         proto - if != PROTO_NONE, this protocol will be forced over the
+ *                 uri_proto, otherwise the uri proto will be used
+ * returns 0 on error, dst on success
+ */
+inline static struct dest_info *uri2dst(struct dest_info* dst, str *uri, 
+											int proto )
+{
+	struct sip_uri parsed_uri;
+	enum sip_protos uri_proto;
+
+	if (parse_uri(uri->s, uri->len, &parsed_uri) < 0) {
+		LOG(L_ERR, "ERROR: uri2dst: bad_uri: %.*s\n",
+		    uri->len, uri->s );
+		return 0;
+	}
+	
+	if (parsed_uri.type==SIPS_URI_T){
+		if ((parsed_uri.proto!=PROTO_TCP) && (parsed_uri.proto!=PROTO_NONE)){
+			LOG(L_ERR, "ERROR: uri2dst: bad transport  for sips uri: %d\n",
+					parsed_uri.proto);
+			return 0;
+		}else
+			uri_proto=PROTO_TLS;
+	}else
+		uri_proto=parsed_uri.proto;
+	
+	init_dest_info(dst);
+	dst->proto= get_proto(proto, uri_proto);
+	sip_hostport2su(&dst->to, &parsed_uri.host, parsed_uri.port_no,
+						dst->proto);
+	return dst;
+}
+
+
+
 /*
  * Convert a URI into socket_info
  */
 static inline struct socket_info *uri2sock(struct sip_msg* msg, str *uri,
 									union sockaddr_union *to_su, int proto)
 {
-	struct proxy_l *proxy;
 	struct socket_info* send_sock;
+	struct dest_info dst;
 
-	proxy = uri2proxy(uri, proto);
-	if (!proxy) {
-		ser_error = E_BAD_ADDRESS;
+	if (uri2dst(&dst, uri, proto)==0){
 		LOG(L_ERR, "ERROR: uri2sock: Can't create a dst proxy\n");
+		ser_error=E_BAD_ADDRESS;
 		return 0;
 	}
+	*to_su=dst.to; /* copy su */
 	
-	hostent2su(to_su, &proxy->host, proxy->addr_idx, 
-		   (proxy->port) ? proxy->port : SIP_PORT);
-			/* we use proxy->proto since uri2proxy just set it correctly*/
-	send_sock = get_send_socket(msg, to_su, proxy->proto);
+	/* we use dst->proto since uri2dst just set it correctly*/
+	send_sock = get_send_socket(msg, to_su, dst.proto);
 	if (!send_sock) {
 		LOG(L_ERR, "ERROR: uri2sock: no corresponding socket for af %d\n", 
 		    to_su->s.sa_family);
 		ser_error = E_NO_SOCKET;
 	}
-
-	free_proxy(proxy);
-	pkg_free(proxy);
 	return send_sock;
 }
 
+
 #endif /* _TM_UT_H */

+ 32 - 0
proxy.h

@@ -38,6 +38,7 @@
 #include <netdb.h>
 #include "ip_addr.h"
 #include "str.h"
+#include "config.h"
 
 struct proxy_l{
 	struct proxy_l* next;
@@ -66,5 +67,36 @@ struct proxy_l* mk_proxy_from_ip(struct ip_addr* ip, unsigned short port,
 void free_proxy(struct proxy_l* p);
 
 
+
+/* returns 0 on success, -1 on error (unknown af/bug) */
+inline static int proxy2su(union sockaddr_union* su, struct proxy_l* p)
+{
+	/* if error try next ip address if possible */
+	if (p->ok==0){
+		if (p->host.h_addr_list[p->addr_idx+1])
+			p->addr_idx++;
+		else p->addr_idx=0;
+		p->ok=1;
+	}
+	
+	return hostent2su(su, &p->host, p->addr_idx,
+				(p->port)?p->port:((p->proto==PROTO_TLS)?SIPS_PORT:SIP_PORT) );
+}
+
+
+
+/* mark as proxy either as ok (err>=0) or as bad (err<0) */
+inline static void proxy_mark(struct proxy_l* p, int err)
+{
+	if (err<0){
+		p->errors++;
+		p->ok=0;
+	}else{
+		p->tx++;
+	}
+}
+
+
+
 #endif
 

+ 30 - 0
resolve.c

@@ -30,6 +30,7 @@
  *  2003-02-13  added proto to sip_resolvehost, for SRV lookups (andrei)
  *  2003-07-03  default port value set according to proto (andrei)
  *  2005-07-11  added resolv_init (timeouts a.s.o) (andrei)
+ *  2006-04-13  added sip_hostport2su()  (andrei)
  */ 
 
 
@@ -43,6 +44,7 @@
 #include "dprint.h"
 #include "mem/mem.h"
 #include "ip_addr.h"
+#include "error.h"
 
 
 
@@ -587,3 +589,31 @@ skip_srv:
 	he=resolvehost(tmp);
 	return he;
 }
+
+
+
+/* resolve host, port, proto using sip rules (e.g. use SRV if port=0 a.s.o)
+ *  and write the result in the sockaddr_union to
+ *  returns -1 on error (resolve failed), 0 on success */
+int sip_hostport2su(union sockaddr_union* su, str* name, unsigned short port,
+						int proto)
+{
+	struct hostent* he;
+	
+	
+	he=sip_resolvehost(name, &port, proto);
+	if (he==0){
+		ser_error=E_BAD_ADDRESS;
+		LOG(L_ERR, "ERROR: sip_hostport2su: could not resolve hostname:"
+					" \"%.*s\"\n", name->len, name->s);
+		goto error;
+	}
+	/* port filled by sip_resolvehost if empty*/
+	if (hostent2su(su, he, 0, port)<0){
+		ser_error=E_BAD_ADDRESS;
+		goto error;
+	}
+	return 0;
+error:
+	return -1;
+}

+ 2 - 0
resolve.h

@@ -359,4 +359,6 @@ skip_ipv4:
 
 int resolv_init();
 
+int sip_hostport2su(union sockaddr_union* su, str* host, unsigned short port,
+						int proto);
 #endif