Browse Source

- now ser uses received= if present
- if no receive present, SRV is used even for Vias

Andrei Pelinescu-Onciul 23 years ago
parent
commit
5bc22c810b
9 changed files with 99 additions and 56 deletions
  1. 1 1
      Makefile.defs
  2. 30 11
      forward.c
  3. 2 2
      msg_translator.c
  4. 2 0
      parser/parse_via.c
  5. 1 0
      parser/parse_via.h
  6. 4 39
      proxy.c
  7. 56 1
      resolve.c
  8. 1 0
      resolve.h
  9. 2 2
      test/repl1.sip

+ 1 - 1
Makefile.defs

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

+ 30 - 11
forward.c

@@ -136,13 +136,29 @@ int update_sock_struct_from_via( union sockaddr_union* to,
 {
 {
 	struct hostent* he;
 	struct hostent* he;
 	char *host_copy;
 	char *host_copy;
+	str* name;
+	unsigned short port;
 
 
 
 
 #ifdef DNS_IP_HACK
 #ifdef DNS_IP_HACK
 	int err;
 	int err;
 	unsigned int ip;
 	unsigned int ip;
+#endif
+
 
 
-	ip=str2ip((unsigned char*)via->host.s,via->host.len,&err);
+	if (via->received){
+		DBG("update_sock_struct_from_via: using 'received'\n");
+		name=&(via->received->value);
+		/* making sure that we won't do SRV lookup on "received"
+		 * (possible if no DNS_IP_HACK is used)*/
+		port=via->port?via->port:SIP_PORT; 
+	}else{
+		DBG("update_sock_struct_from_via: using via host\n");
+		name=&(via->host);
+		port=via->port;
+	}
+#ifdef DNS_IP_HACK
+	ip=str2ip((unsigned char*)name->s, name->len,&err);
 	if (err==0){
 	if (err==0){
 		to->sin.sin_family=AF_INET;
 		to->sin.sin_family=AF_INET;
 		to->sin.sin_port=(via->port)?htons(via->port): htons(SIP_PORT);
 		to->sin.sin_port=(via->port)?htons(via->port): htons(SIP_PORT);
@@ -158,27 +174,30 @@ int update_sock_struct_from_via( union sockaddr_union* to,
 		   - andrei 
 		   - andrei 
 			Yes -- it happened on generating a 408 by TM; -jiri
 			Yes -- it happened on generating a 408 by TM; -jiri
 		*/
 		*/
-		if (via->host.s[via->host.len]){
-			host_copy=pkg_malloc( via->host.len+1 );
+		if (name->s[name->len]){
+			host_copy=pkg_malloc( name->len+1 );
 			if (!host_copy) {
 			if (!host_copy) {
 				LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:"
 				LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:"
 								" not enough memory\n");
 								" not enough memory\n");
 				return -1;
 				return -1;
 			}
 			}
-			memcpy(host_copy, via->host.s, via->host.len );
-			host_copy[via->host.len]=0;
-			he=resolvehost(host_copy);
+			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 );
 			pkg_free( host_copy );
 		}else{
 		}else{
-			he=resolvehost(via->host.s);
+			DBG("update_sock_struct_from_via: trying SRV lookup\n");
+			he=sip_resolvehost(name->s, &port);
 		}
 		}
-
+		
 		if (he==0){
 		if (he==0){
-			LOG(L_NOTICE, "ERROR:forward_reply:gethostbyname(%s) failure\n",
-					via->host.s);
+			LOG(L_NOTICE, "ERROR:forward_reply:resolve_host(%s) failure\n",
+					name->s);
 			return -1;
 			return -1;
 		}
 		}
-		hostent2su(to, he, 0, (via->port)?htons(via->port): htons(SIP_PORT));
+		hostent2su(to, he, 0, htons(port));
 	}
 	}
 	return 1;
 	return 1;
 }
 }

+ 2 - 2
msg_translator.c

@@ -26,8 +26,8 @@
 #define MAX_RECEIVED_SIZE  57
 #define MAX_RECEIVED_SIZE  57
 
 
 /* mallocs for local stuff (not needed to be shared mem?)*/
 /* mallocs for local stuff (not needed to be shared mem?)*/
-#define local_malloc pkg_malloc
-#define local_free   pkg_free
+#define local_malloc(s) pkg_malloc((s))
+#define local_free(s)   pkg_free((s))
 
 
 
 
 #define append_str(_dest,_src,_len,_msg) \
 #define append_str(_dest,_src,_len,_msg) \

+ 2 - 0
parser/parse_via.c

@@ -1655,6 +1655,8 @@ parse_again:
 						vb->last_param=param;
 						vb->last_param=param;
 						if (param->type==PARAM_BRANCH)
 						if (param->type==PARAM_BRANCH)
 							vb->branch=param;
 							vb->branch=param;
+						else if (param->type==PARAM_RECEIVED)
+							vb->received=param;
 						break;
 						break;
 					case P_PARAM:
 					case P_PARAM:
 						break;
 						break;

+ 1 - 0
parser/parse_via.h

@@ -44,6 +44,7 @@ struct via_body {
 
 
 	     /* shortcuts to "important" params*/
 	     /* shortcuts to "important" params*/
 	struct via_param* branch;
 	struct via_param* branch;
+	struct via_param* received;
 	
 	
 	struct via_body* next; /* pointer to next via body string if
 	struct via_body* next; /* pointer to next via body string if
 				  compact via or null */
 				  compact via or null */

+ 4 - 39
proxy.c

@@ -166,12 +166,8 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
 {
 {
 	struct proxy_l* p;
 	struct proxy_l* p;
 	struct hostent* he;
 	struct hostent* he;
-	struct rdata* head;
-	struct rdata* l;
-	struct srv_rdata* srv;
-	static char tmp[MAX_DNS_NAME]; /* tmp buff. for SRV lookups*/
-	int len;
 #ifdef DNS_IP_HACK
 #ifdef DNS_IP_HACK
+	int len;
 	int err;
 	int err;
 	unsigned int ip;
 	unsigned int ip;
 #endif
 #endif
@@ -184,7 +180,7 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
 	}
 	}
 	memset(p,0,sizeof(struct proxy_l));
 	memset(p,0,sizeof(struct proxy_l));
 	p->name=name;
 	p->name=name;
-	p->port=port?port:SIP_PORT;
+	p->port=port;
 #ifdef DNS_IP_HACK
 #ifdef DNS_IP_HACK
 	/* fast ipv4 string to address conversion*/
 	/* fast ipv4 string to address conversion*/
 	len=strlen(name);
 	len=strlen(name);
@@ -220,44 +216,14 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
 		}
 		}
 		memcpy(p->host.h_addr_list[0], (char*)&ip, 4);
 		memcpy(p->host.h_addr_list[0], (char*)&ip, 4);
 		p->host.h_addr_list[0][4]=0;
 		p->host.h_addr_list[0][4]=0;
+		if (p->port==0) p->port=SIP_PORT;
 
 
 		return p;
 		return p;
 	}
 	}
 #endif
 #endif
 	/* fail over to normal lookup */
 	/* fail over to normal lookup */
 
 
-	/* try SRV if no port specified (draft-ietf-sip-srv-06) */
-	if (port==0){
-		len=strlen(name);
-		if ((len+SRV_PREFIX_LEN+1)>MAX_DNS_NAME){
-			LOG(L_WARN, "WARNING: domain name too long (%d), unable"
-					" to perform SRV lookup\n", len);
-		}else{
-			memcpy(tmp, SRV_PREFIX, SRV_PREFIX_LEN);
-			memcpy(tmp+SRV_PREFIX_LEN, name, len+1); /*include the ending 0*/
-			
-			head=get_record(tmp, T_SRV);
-			for(l=head; l; l=l->next){
-				if (l->type!=T_SRV) continue; /*should never happen*/
-				srv=(struct srv_rdata*) l->rdata;
-				if (srv==0){
-					LOG(L_CRIT, "mk_proxy: BUG: null rdata\n");
-					free_rdata_list(head);
-					break;
-				}
-				he=resolvehost(srv->name);
-				if (he!=0){
-					DBG("mk_proxy: SRV(%s) = %s:%d\n",
-							tmp, srv->name, srv->port);
-					p->port=srv->port;
-					free_rdata_list(head); /*clean up*/
-					goto copy_he;
-				}
-			}
-			DBG(" not SRV record found for %s\n", name);
-		}
-	}
-	he=resolvehost(name);
+	he=sip_resolvehost(name, &(p->port));
 	if (he==0){
 	if (he==0){
 		ser_error=E_BAD_ADDRESS;
 		ser_error=E_BAD_ADDRESS;
 		LOG(L_CRIT, "ERROR: mk_proxy: could not resolve hostname:"
 		LOG(L_CRIT, "ERROR: mk_proxy: could not resolve hostname:"
@@ -265,7 +231,6 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
 		free(p);
 		free(p);
 		goto error;
 		goto error;
 	}
 	}
-copy_he:
 	if (hostent_cpy(&(p->host), he)!=0){
 	if (hostent_cpy(&(p->host), he)!=0){
 		free(p);
 		free(p);
 		goto error;
 		goto error;

+ 56 - 1
resolve.c

@@ -157,7 +157,7 @@ struct rdata* get_record(char* name, int type)
 {
 {
 	int size;
 	int size;
 	int qno, answers_no;
 	int qno, answers_no;
-	int r,i;
+	int r;
 	int ans_len;
 	int ans_len;
 	static union dns_query buff;
 	static union dns_query buff;
 	unsigned char* p;
 	unsigned char* p;
@@ -304,3 +304,58 @@ error:
 	return 0;
 	return 0;
 }
 }
 
 
+
+
+/* resolves a host name trying SRV lookup if *port==0 or normal A/AAAA lookup
+ * if *port!=0.
+ * returns: hostent struct & *port filled with the port from the SRV record;
+ *  0 on error
+ */
+struct hostent* sip_resolvehost(char* name, unsigned short* port)
+{
+	struct hostent* he;
+	struct rdata* head;
+	struct rdata* l;
+	struct srv_rdata* srv;
+	static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
+	int len;
+
+	/* try SRV if no port specified (draft-ietf-sip-srv-06) */
+	if ((port)&&(*port==0)){
+		*port=SIP_PORT; /* just in case we don't find another */
+		len=strlen(name);
+		if ((len+SRV_PREFIX_LEN+1)>MAX_DNS_NAME){
+			LOG(L_WARN, "WARNING: sip_resolvehost: domain name too long (%d),"
+						" unable to perform SRV lookup\n", len);
+		}else{
+			memcpy(tmp, SRV_PREFIX, SRV_PREFIX_LEN);
+			memcpy(tmp+SRV_PREFIX_LEN, name, len+1); /*include the ending 0*/
+			
+			head=get_record(tmp, T_SRV);
+			for(l=head; l; l=l->next){
+				if (l->type!=T_SRV) continue; /*should never happen*/
+				srv=(struct srv_rdata*) l->rdata;
+				if (srv==0){
+					LOG(L_CRIT, "sip_resolvehost: BUG: null rdata\n");
+					free_rdata_list(head);
+					break;
+				}
+				he=resolvehost(srv->name);
+				if (he!=0){
+					/* we found it*/
+					DBG("sip_resolvehost: SRV(%s) = %s:%d\n",
+							tmp, srv->name, srv->port);
+					*port=srv->port;
+					free_rdata_list(head); /*clean up*/
+					return he;
+				}
+			}
+			DBG("sip_resolvehost: not SRV record found for %s," 
+					" trying 'normal' lookup...\n", name);
+		}
+	}
+	he=resolvehost(name);
+	return he;
+}
+
+

+ 1 - 0
resolve.h

@@ -82,6 +82,7 @@ static inline struct hostent* resolvehost(const char* name)
 	return he;
 	return he;
 }
 }
 
 
+struct hostent* sip_resolvehost(char* name, unsigned short* port);
 
 
 
 
 
 

+ 2 - 2
test/repl1.sip

@@ -1,6 +1,6 @@
 SIP/2.0 200 Ok
 SIP/2.0 200 Ok
-Via: SIP/2.0/UDP 192.168.99.100
-Via: SIP/2.0/UDP 193.175.133.195:5060
+Via: SIP/2.0/UDP foo.bar.com
+Via: SIP/2.0/UDP mobile55
 From: <sip:[email protected]>
 From: <sip:[email protected]>
 To: <sip:[email protected]>
 To: <sip:[email protected]>
 Call-ID:[email protected]
 Call-ID:[email protected]