Explorar el Código

- dns srv fixes changes (str2ip6, str2ip)

Andrei Pelinescu-Onciul hace 23 años
padre
commit
4c9f3fdec6
Se han modificado 9 ficheros con 164 adiciones y 176 borrados
  1. 1 1
      Makefile.defs
  2. 28 45
      forward.c
  3. 25 2
      ip_addr.h
  4. 0 46
      proxy.c
  5. 12 0
      resolve.c
  6. 94 32
      resolve.h
  7. 3 6
      test/inv_srv.sip
  8. 1 1
      test/stateless.cfg
  9. 0 43
      ut.h

+ 1 - 1
Makefile.defs

@@ -8,7 +8,7 @@
 VERSION = 0
 PATCHLEVEL = 8
 SUBLEVEL = 7
-EXTRAVERSION = -10-alias
+EXTRAVERSION = -11-srv2
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s)

+ 28 - 45
forward.c

@@ -232,12 +232,6 @@ int update_sock_struct_from_via( union sockaddr_union* to,
 	unsigned short port;
 
 
-#ifdef DNS_IP_HACK
-	int err;
-	unsigned int ip;
-#endif
-
-
 	if (via->received){
 		DBG("update_sock_struct_from_via: using 'received'\n");
 		name=&(via->received->value);
@@ -249,48 +243,37 @@ int update_sock_struct_from_via( union sockaddr_union* to,
 		name=&(via->host);
 		port=via->port;
 	}
-#ifdef DNS_IP_HACK
-	ip=str2ip((unsigned char*)name->s, name->len,&err);
-	if (err==0){
-		to->sin.sin_family=AF_INET;
-		to->sin.sin_port=(via->port)?htons(via->port): htons(SIP_PORT);
-		memcpy(&to->sin.sin_addr, (char*)&ip, 4);
-	}else
-#endif
-	{
-		/* we do now a malloc/memcpy because gethostbyname loves \0-terminated 
-		   strings; -jiri 
-		   but only if host is not null terminated
-		   (host.s[len] will always be ok for a via)
-           BTW: when is via->host.s non null terminated? tm copy?
-		   - andrei 
-			Yes -- it happened on generating a 408 by TM; -jiri
-		*/
-		if (name->s[name->len]){
-			host_copy=pkg_malloc( name->len+1 );
-			if (!host_copy) {
-				LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:"
-								" not enough memory\n");
-				return -1;
-			}
-			memcpy(host_copy, name->s, name->len );
-			host_copy[name->len]=0;
-			DBG("update_sock_struct_from_via: trying SRV lookup\n");
-			he=sip_resolvehost(host_copy, &port);
-			
-			pkg_free( host_copy );
-		}else{
-			DBG("update_sock_struct_from_via: trying SRV lookup\n");
-			he=sip_resolvehost(name->s, &port);
-		}
-		
-		if (he==0){
-			LOG(L_NOTICE, "ERROR:forward_reply:resolve_host(%s) failure\n",
-					name->s);
+	/* we do now a malloc/memcpy because gethostbyname loves \0-terminated 
+	   strings; -jiri 
+	   but only if host is not null terminated
+	   (host.s[len] will always be ok for a via)
+	    BTW: when is via->host.s non null terminated? tm copy? - andrei 
+	    Yes -- it happened on generating a 408 by TM; -jiri
+	*/
+	if (name->s[name->len]){
+		host_copy=pkg_malloc( name->len+1 );
+		if (!host_copy) {
+			LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:"
+							" not enough memory\n");
 			return -1;
 		}
-		hostent2su(to, he, 0, htons(port));
+		memcpy(host_copy, name->s, name->len );
+		host_copy[name->len]=0;
+		DBG("update_sock_struct_from_via: trying SRV lookup\n");
+		he=sip_resolvehost(host_copy, &port);
+		
+		pkg_free( host_copy );
+	}else{
+		DBG("update_sock_struct_from_via: trying SRV lookup\n");
+		he=sip_resolvehost(name->s, &port);
+	}
+	
+	if (he==0){
+		LOG(L_NOTICE, "ERROR:forward_reply:resolve_host(%s) failure\n",
+				name->s);
+		return -1;
 	}
+	hostent2su(to, he, 0, htons(port));
 	return 1;
 }
 

+ 25 - 2
ip_addr.h

@@ -341,6 +341,29 @@ static inline char* ip_addr2a(struct ip_addr* ip)
 
 
 
-
-
+/* converts an ip_addr structure to a hostent, returns pointer to internal
+ * statical structure */
+static inline struct hostent* ip_addr2he(char* name, int len,
+											struct ip_addr* ip)
+{
+	static struct hostent he;
+	static char hostname[256];
+	static char* p_aliases[1];
+	static char* p_addr[2];
+	static char address[16];
+	
+	p_aliases[0]=0; /* no aliases*/
+	p_addr[1]=0; /* only one address*/
+	p_addr[0]=address;
+	strncpy(hostname, name, (len<256)?len:256);
+	if (ip->len>16) return 0;
+	memcpy(address, ip->u.addr, ip->len);
+	
+	he.h_addrtype=ip->af;
+	he.h_length=ip->len;
+	he.h_addr_list=p_addr;
+	he.h_aliases=p_aliases;
+	he.h_name=hostname;
+	return &he;
+}
 #endif

+ 0 - 46
proxy.c

@@ -166,11 +166,6 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
 {
 	struct proxy_l* p;
 	struct hostent* he;
-#ifdef DNS_IP_HACK
-	int len;
-	int err;
-	unsigned int ip;
-#endif
 
 	p=(struct proxy_l*) malloc(sizeof(struct proxy_l));
 	if (p==0){
@@ -181,47 +176,6 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
 	memset(p,0,sizeof(struct proxy_l));
 	p->name=name;
 	p->port=port;
-#ifdef DNS_IP_HACK
-	/* fast ipv4 string to address conversion*/
-	len=strlen(name);
-	ip=str2ip((unsigned char*)name, len, &err);
-	if (err==0){
-		p->host.h_name=malloc(len+1);
-		if (p->host.h_name==0) goto error;
-		memcpy(p->host.h_name, name, len);
-		p->host.h_aliases=malloc(sizeof(char*));
-		if (p->host.h_aliases==0) {
-			ser_error=E_OUT_OF_MEM;
-			free(p->host.h_name);
-			goto error;
-		}
-		p->host.h_aliases[0]=0;
-		p->host.h_addrtype=AF_INET;
-		p->host.h_length=4;
-		p->host.h_addr_list=malloc(2*sizeof(char*));
-		if (p->host.h_addr_list==0){
-			ser_error=E_OUT_OF_MEM;
-			free(p->host.h_name);
-			free(p->host.h_aliases);
-			goto error;
-		}
-		p->host.h_addr_list[1]=0;
-		p->host.h_addr_list[0]=malloc(5);
-		if (p->host.h_addr_list[0]==0){
-			ser_error=E_OUT_OF_MEM;
-			free(p->host.h_name);
-			free(p->host.h_aliases);
-			free(p->host.h_addr_list);
-			goto error;
-		}
-		memcpy(p->host.h_addr_list[0], (char*)&ip, 4);
-		p->host.h_addr_list[0][4]=0;
-		if (p->port==0) p->port=SIP_PORT;
-
-		return p;
-	}
-#endif
-	/* fail over to normal lookup */
 
 	DBG("DEBUG: mk_proxy: doing DNS lookup...\n");
 	he=sip_resolvehost(name, &(p->port));

+ 12 - 0
resolve.c

@@ -8,6 +8,7 @@
 #include "resolve.h"
 #include "dprint.h"
 #include "mem/mem.h"
+#include "ip_addr.h"
 
 
 
@@ -358,6 +359,7 @@ struct hostent* sip_resolvehost(char* name, unsigned short* port)
 	struct rdata* head;
 	struct rdata* l;
 	struct srv_rdata* srv;
+	struct ip_addr* ip;
 	static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
 	int len;
 
@@ -369,6 +371,16 @@ struct hostent* sip_resolvehost(char* name, unsigned short* port)
 			LOG(L_WARN, "WARNING: sip_resolvehost: domain name too long (%d),"
 						" unable to perform SRV lookup\n", len);
 		}else{
+			/* check if it's an ip address */
+			if ( ((ip=str2ip(name, len))!=0)
+#ifdef	USE_IPV6
+				  || ((ip=str2ip6(name, len))!=0)
+#endif
+				){
+				/* we are lucky, this is an ip address */
+				return ip_addr2he(name,len,ip);
+			}
+			
 			memcpy(tmp, SRV_PREFIX, SRV_PREFIX_LEN);
 			memcpy(tmp+SRV_PREFIX_LEN, name, len+1); /*include the ending 0*/
 			

+ 94 - 32
resolve.h

@@ -11,6 +11,8 @@
 #include <netdb.h>
 #include <arpa/nameser.h>
 
+#include "ip_addr.h"
+
 
 #define MAX_QUERY_SIZE 8192
 #define ANS_SIZE       8192
@@ -66,28 +68,9 @@ struct rdata* get_record(char* name, int type);
 void free_rdata_list(struct rdata* head);
 
 
-/* gethostbyname wrappers
- * use this, someday htey will use a local cache */
-
-static inline struct hostent* resolvehost(const char* name)
-{
-	struct hostent* he;
-	
-#ifdef DNS_IP_HACK
-#endif
-
-	he=gethostbyname(name); /*ipv4*/
 
-#ifdef USE_IPV6
-	if(he==0){
-		/*try ipv6*/
-		he=gethostbyname2(name, AF_INET6);
-	}
-#endif
-	return he;
-}
 
-struct hostent* sip_resolvehost(char* name, unsigned short* port);
+#define rev_resolvehost(ip) gethostbyaddr((ip)->u.addr, (ip)->len, (ip)->af);
 
 
 
@@ -97,16 +80,53 @@ struct hostent* sip_resolvehost(char* name, unsigned short* port);
 		(((c)>='a') && ((c)<='f'))? ((c)-'a')+10 : -1 )
 
 
-#define rev_resolvehost(ip) gethostbyaddr((ip)->u.addr, (ip)->len, (ip)->af);
 
 
 
-#if 0
-/* returns an ip_addr struct.; on error retunrs 0 and sets err (if !=0)
- * the ip_addr struct is static, so subsequent calls will destroy its 
- * content */
-static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
-		int* err)
+/* converts a str to an ipv4 address, returns the address or 0 on error
+   Warning: the result is a pointer to a statically allocated structure */
+static inline struct ip_addr* str2ip(unsigned char* str, unsigned int len)
+{
+	int i;
+	unsigned char *limit;
+	unsigned char *init;
+	static struct ip_addr ip;
+
+	/*init*/
+	ip.u.addr32[0]=0;
+	i=0;
+	limit=str+len;
+	init=str;
+
+	for(;str<limit ;str++){
+		if (*str=='.'){
+				i++;
+				if (i>3) goto error_dots;
+		}else if ( (*str <= '9' ) && (*str >= '0') ){
+				ip.u.addr[i]=ip.u.addr[i]*10+*str-'0';
+		}else{
+				//error unknown char
+				goto error_char;
+		}
+	}
+	ip.af=AF_INET;
+	ip.len=4;
+	
+	return &ip;
+
+error_dots:
+	DBG("str2ip: ERROR: too many dots in [%.*s]\n", (int)len, init);
+	return 0;
+error_char:
+	DBG("str2ip: WARNING: unexpected char %c in %.*s\n", *str,(int)len, init);
+	return 0;
+}
+
+
+
+/* returns an ip_addr struct.; on error returns 0
+ * the ip_addr struct is static, so subsequent calls will destroy its content*/
+static inline struct ip_addr* str2ip6(unsigned char* str, unsigned int len)
 {
 	int i, idx1, rest;
 	int no_colons;
@@ -143,6 +163,7 @@ static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
 				addr=addr_end;
 			}else{
 				double_colon=1;
+				addr[i]=htons(addr[i]);
 				i++;
 			}
 		}else if ((hex=HEX2I(*str))>=0){
@@ -153,29 +174,70 @@ static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
 			goto error_char;
 		}
 	}
-	
+	if (no_colons<2) goto error_too_few_colons;
+	if (!double_colon){ /* not ending in ':' */
+		addr[i]=htons(addr[i]);
+		i++; 
+	}
 	rest=8-i-idx1;
 	memcpy(addr_start+idx1+rest, addr_end, i*sizeof(unsigned short));
-	if (err) *err=0;
 	return &ip;
 
 error_too_many_colons:
 	DBG("str2ip6: ERROR: too many colons in [%.*s]\n", (int) len, init);
-	if (err) *err=1;
+	return 0;
+
+error_too_few_colons:
+	DBG("str2ip6: ERROR: too few colons in [%.*s]\n", (int) len, init);
 	return 0;
 
 error_colons:
 	DBG("str2ip6: ERROR: too many double colons in [%.*s]\n", (int) len, init);
-	if (err) *err=1;
 	return 0;
 
 error_char:
 	DBG("str2ip6: WARNING: unexpected char %c in  [%.*s]\n", *str, (int) len,
 			init);
-	if (err) *err=1;
 	return 0;
 }
+
+
+
+struct hostent* sip_resolvehost(char* name, unsigned short* port);
+
+
+
+/* gethostbyname wrappers
+ * use this, someday they will use a local cache */
+
+static inline struct hostent* resolvehost(const char* name)
+{
+	struct hostent* he;
+#ifdef DNS_IP_HACK
+	struct ip_addr* ip;
+	int len;
+	
+	len=strlen(name);
+	/* check if it's an ip address */
+	if ( ((ip=str2ip(name, len))!=0)
+#ifdef	USE_IPV6
+		  || ((ip=str2ip6(name, len))!=0)
+#endif
+		){
+		/* we are lucky, this is an ip address */
+		return ip_addr2he(name, len, ip);
+	}
+	
 #endif
+	he=gethostbyname(name); /*ipv4*/
+#ifdef USE_IPV6
+	if(he==0){
+		/*try ipv6*/
+		he=gethostbyname2(name, AF_INET6);
+	}
+#endif
+	return he;
+}
 
 
 

+ 3 - 6
test/inv_srv.sip

@@ -1,15 +1,12 @@
-INVITE sip:[email protected] SIP/2.0
-:q
+INVITE sip:andrei@mobile69 SIP/2.0
 Via: SIP/2.0/UDP dorian.fokus.gmd.de 
-From: "GMD FOKUS iptlab" <sip:jir[email protected]>;tag=b96b0300ed30f1286-2f5d
+From: "test" <sip:andre[email protected]>;tag=b96b0300ed30f1286-2f5d
 Call-ID: [email protected]
 CSeq: 101 INVITE
 Expires: 180
 Max-Forwards:  0
-User-Agent: Cisco-SIP-IP-Phone/2
+User-Agent: testing lookups
 Accept: application/sdp
-Contact: sip:[email protected]:5060
-Content-Type: application/sdp
 Content-Length: 225
 
 

+ 1 - 1
test/stateless.cfg

@@ -32,7 +32,7 @@ alias="foo.bar"
 
 route{
 	if (myself==uri){
-		log("\n\nfrom myself\n\n"); drop;
+		log("\n\nfrom myself\n\n");
 	};
 	log("\n\n continue \n\n");
 	forward(uri:host, uri:port);

+ 0 - 43
ut.h

@@ -97,49 +97,6 @@ error_char:
 
 
 
-/* converts a str to an ipv4 address, returns the address and sets *err
- * if error and err!=null
- */
-static inline unsigned int str2ip(unsigned char* str, unsigned int len,
-		int * err)
-{
-	unsigned int ret;
-	int i;
-	unsigned char *limit;
-	unsigned char *init;
-
-	/*init*/
-	ret=i=0;
-	limit=str+len;
-	init=str;
-
-	for(;str<limit ;str++){
-		if (*str=='.'){
-				i++;
-				if (i>3) goto error_dots;
-		}else if ( (*str <= '9' ) && (*str >= '0') ){
-				((unsigned char*)&ret)[i]=((unsigned char*)&ret)[i]*10+
-											*str-'0';
-		}else{
-				//error unknown char
-				goto error_char;
-		}
-	}
-	if (err) *err=0;
-	return ret;
-
-error_dots:
-	DBG("str2ip: ERROR: too many dots in [%.*s]\n", (int)len, init);
-	if (err) *err=1;
-	return 0;
-error_char:
-	DBG("str2ip: WARNING: unexpected char %c in %.*s\n", *str,(int)len, init);
-	if (err) *err=1;
-	return 0;
-}
-
-
-
 static inline int btostr( char *p,  unsigned char val)
 {
 	unsigned int a,b,i =0;