Browse code

- dns srv fixes changes (str2ip6, str2ip)

Andrei Pelinescu-Onciul authored on 05/09/2002 18:03:15
Showing 9 changed files
... ...
@@ -8,7 +8,7 @@
8 8
 VERSION = 0
9 9
 PATCHLEVEL = 8
10 10
 SUBLEVEL = 7
11
-EXTRAVERSION = -10-alias
11
+EXTRAVERSION = -11-srv2
12 12
 
13 13
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
14 14
 OS = $(shell uname -s)
... ...
@@ -232,12 +232,6 @@ int update_sock_struct_from_via( union sockaddr_union* to,
232 232
 	unsigned short port;
233 233
 
234 234
 
235
-#ifdef DNS_IP_HACK
236
-	int err;
237
-	unsigned int ip;
238
-#endif
239
-
240
-
241 235
 	if (via->received){
242 236
 		DBG("update_sock_struct_from_via: using 'received'\n");
243 237
 		name=&(via->received->value);
... ...
@@ -249,48 +243,37 @@ int update_sock_struct_from_via( union sockaddr_union* to,
249 249
 		name=&(via->host);
250 250
 		port=via->port;
251 251
 	}
252
-#ifdef DNS_IP_HACK
253
-	ip=str2ip((unsigned char*)name->s, name->len,&err);
254
-	if (err==0){
255
-		to->sin.sin_family=AF_INET;
256
-		to->sin.sin_port=(via->port)?htons(via->port): htons(SIP_PORT);
257
-		memcpy(&to->sin.sin_addr, (char*)&ip, 4);
258
-	}else
259
-#endif
260
-	{
261
-		/* we do now a malloc/memcpy because gethostbyname loves \0-terminated 
262
-		   strings; -jiri 
263
-		   but only if host is not null terminated
264
-		   (host.s[len] will always be ok for a via)
265
-           BTW: when is via->host.s non null terminated? tm copy?
266
-		   - andrei 
267
-			Yes -- it happened on generating a 408 by TM; -jiri
268
-		*/
269
-		if (name->s[name->len]){
270
-			host_copy=pkg_malloc( name->len+1 );
271
-			if (!host_copy) {
272
-				LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:"
273
-								" not enough memory\n");
274
-				return -1;
275
-			}
276
-			memcpy(host_copy, name->s, name->len );
277
-			host_copy[name->len]=0;
278
-			DBG("update_sock_struct_from_via: trying SRV lookup\n");
279
-			he=sip_resolvehost(host_copy, &port);
280
-			
281
-			pkg_free( host_copy );
282
-		}else{
283
-			DBG("update_sock_struct_from_via: trying SRV lookup\n");
284
-			he=sip_resolvehost(name->s, &port);
285
-		}
286
-		
287
-		if (he==0){
288
-			LOG(L_NOTICE, "ERROR:forward_reply:resolve_host(%s) failure\n",
289
-					name->s);
252
+	/* we do now a malloc/memcpy because gethostbyname loves \0-terminated 
253
+	   strings; -jiri 
254
+	   but only if host is not null terminated
255
+	   (host.s[len] will always be ok for a via)
256
+	    BTW: when is via->host.s non null terminated? tm copy? - andrei 
257
+	    Yes -- it happened on generating a 408 by TM; -jiri
258
+	*/
259
+	if (name->s[name->len]){
260
+		host_copy=pkg_malloc( name->len+1 );
261
+		if (!host_copy) {
262
+			LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:"
263
+							" not enough memory\n");
290 264
 			return -1;
291 265
 		}
292
-		hostent2su(to, he, 0, htons(port));
266
+		memcpy(host_copy, name->s, name->len );
267
+		host_copy[name->len]=0;
268
+		DBG("update_sock_struct_from_via: trying SRV lookup\n");
269
+		he=sip_resolvehost(host_copy, &port);
270
+		
271
+		pkg_free( host_copy );
272
+	}else{
273
+		DBG("update_sock_struct_from_via: trying SRV lookup\n");
274
+		he=sip_resolvehost(name->s, &port);
275
+	}
276
+	
277
+	if (he==0){
278
+		LOG(L_NOTICE, "ERROR:forward_reply:resolve_host(%s) failure\n",
279
+				name->s);
280
+		return -1;
293 281
 	}
282
+	hostent2su(to, he, 0, htons(port));
294 283
 	return 1;
295 284
 }
296 285
 
... ...
@@ -341,6 +341,29 @@ static inline char* ip_addr2a(struct ip_addr* ip)
341 341
 
342 342
 
343 343
 
344
-
345
-
344
+/* converts an ip_addr structure to a hostent, returns pointer to internal
345
+ * statical structure */
346
+static inline struct hostent* ip_addr2he(char* name, int len,
347
+											struct ip_addr* ip)
348
+{
349
+	static struct hostent he;
350
+	static char hostname[256];
351
+	static char* p_aliases[1];
352
+	static char* p_addr[2];
353
+	static char address[16];
354
+	
355
+	p_aliases[0]=0; /* no aliases*/
356
+	p_addr[1]=0; /* only one address*/
357
+	p_addr[0]=address;
358
+	strncpy(hostname, name, (len<256)?len:256);
359
+	if (ip->len>16) return 0;
360
+	memcpy(address, ip->u.addr, ip->len);
361
+	
362
+	he.h_addrtype=ip->af;
363
+	he.h_length=ip->len;
364
+	he.h_addr_list=p_addr;
365
+	he.h_aliases=p_aliases;
366
+	he.h_name=hostname;
367
+	return &he;
368
+}
346 369
 #endif
... ...
@@ -166,11 +166,6 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
166 166
 {
167 167
 	struct proxy_l* p;
168 168
 	struct hostent* he;
169
-#ifdef DNS_IP_HACK
170
-	int len;
171
-	int err;
172
-	unsigned int ip;
173
-#endif
174 169
 
175 170
 	p=(struct proxy_l*) malloc(sizeof(struct proxy_l));
176 171
 	if (p==0){
... ...
@@ -181,47 +176,6 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
181 181
 	memset(p,0,sizeof(struct proxy_l));
182 182
 	p->name=name;
183 183
 	p->port=port;
184
-#ifdef DNS_IP_HACK
185
-	/* fast ipv4 string to address conversion*/
186
-	len=strlen(name);
187
-	ip=str2ip((unsigned char*)name, len, &err);
188
-	if (err==0){
189
-		p->host.h_name=malloc(len+1);
190
-		if (p->host.h_name==0) goto error;
191
-		memcpy(p->host.h_name, name, len);
192
-		p->host.h_aliases=malloc(sizeof(char*));
193
-		if (p->host.h_aliases==0) {
194
-			ser_error=E_OUT_OF_MEM;
195
-			free(p->host.h_name);
196
-			goto error;
197
-		}
198
-		p->host.h_aliases[0]=0;
199
-		p->host.h_addrtype=AF_INET;
200
-		p->host.h_length=4;
201
-		p->host.h_addr_list=malloc(2*sizeof(char*));
202
-		if (p->host.h_addr_list==0){
203
-			ser_error=E_OUT_OF_MEM;
204
-			free(p->host.h_name);
205
-			free(p->host.h_aliases);
206
-			goto error;
207
-		}
208
-		p->host.h_addr_list[1]=0;
209
-		p->host.h_addr_list[0]=malloc(5);
210
-		if (p->host.h_addr_list[0]==0){
211
-			ser_error=E_OUT_OF_MEM;
212
-			free(p->host.h_name);
213
-			free(p->host.h_aliases);
214
-			free(p->host.h_addr_list);
215
-			goto error;
216
-		}
217
-		memcpy(p->host.h_addr_list[0], (char*)&ip, 4);
218
-		p->host.h_addr_list[0][4]=0;
219
-		if (p->port==0) p->port=SIP_PORT;
220
-
221
-		return p;
222
-	}
223
-#endif
224
-	/* fail over to normal lookup */
225 184
 
226 185
 	DBG("DEBUG: mk_proxy: doing DNS lookup...\n");
227 186
 	he=sip_resolvehost(name, &(p->port));
... ...
@@ -8,6 +8,7 @@
8 8
 #include "resolve.h"
9 9
 #include "dprint.h"
10 10
 #include "mem/mem.h"
11
+#include "ip_addr.h"
11 12
 
12 13
 
13 14
 
... ...
@@ -358,6 +359,7 @@ struct hostent* sip_resolvehost(char* name, unsigned short* port)
358 358
 	struct rdata* head;
359 359
 	struct rdata* l;
360 360
 	struct srv_rdata* srv;
361
+	struct ip_addr* ip;
361 362
 	static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
362 363
 	int len;
363 364
 
... ...
@@ -369,6 +371,16 @@ struct hostent* sip_resolvehost(char* name, unsigned short* port)
369 369
 			LOG(L_WARN, "WARNING: sip_resolvehost: domain name too long (%d),"
370 370
 						" unable to perform SRV lookup\n", len);
371 371
 		}else{
372
+			/* check if it's an ip address */
373
+			if ( ((ip=str2ip(name, len))!=0)
374
+#ifdef	USE_IPV6
375
+				  || ((ip=str2ip6(name, len))!=0)
376
+#endif
377
+				){
378
+				/* we are lucky, this is an ip address */
379
+				return ip_addr2he(name,len,ip);
380
+			}
381
+			
372 382
 			memcpy(tmp, SRV_PREFIX, SRV_PREFIX_LEN);
373 383
 			memcpy(tmp+SRV_PREFIX_LEN, name, len+1); /*include the ending 0*/
374 384
 			
... ...
@@ -11,6 +11,8 @@
11 11
 #include <netdb.h>
12 12
 #include <arpa/nameser.h>
13 13
 
14
+#include "ip_addr.h"
15
+
14 16
 
15 17
 #define MAX_QUERY_SIZE 8192
16 18
 #define ANS_SIZE       8192
... ...
@@ -66,28 +68,9 @@ struct rdata* get_record(char* name, int type);
66 66
 void free_rdata_list(struct rdata* head);
67 67
 
68 68
 
69
-/* gethostbyname wrappers
70
- * use this, someday htey will use a local cache */
71
-
72
-static inline struct hostent* resolvehost(const char* name)
73
-{
74
-	struct hostent* he;
75
-	
76
-#ifdef DNS_IP_HACK
77
-#endif
78
-
79
-	he=gethostbyname(name); /*ipv4*/
80 69
 
81
-#ifdef USE_IPV6
82
-	if(he==0){
83
-		/*try ipv6*/
84
-		he=gethostbyname2(name, AF_INET6);
85
-	}
86
-#endif
87
-	return he;
88
-}
89 70
 
90
-struct hostent* sip_resolvehost(char* name, unsigned short* port);
71
+#define rev_resolvehost(ip) gethostbyaddr((ip)->u.addr, (ip)->len, (ip)->af);
91 72
 
92 73
 
93 74
 
... ...
@@ -97,16 +80,53 @@ struct hostent* sip_resolvehost(char* name, unsigned short* port);
97 97
 		(((c)>='a') && ((c)<='f'))? ((c)-'a')+10 : -1 )
98 98
 
99 99
 
100
-#define rev_resolvehost(ip) gethostbyaddr((ip)->u.addr, (ip)->len, (ip)->af);
101 100
 
102 101
 
103 102
 
104
-#if 0
105
-/* returns an ip_addr struct.; on error retunrs 0 and sets err (if !=0)
106
- * the ip_addr struct is static, so subsequent calls will destroy its 
107
- * content */
108
-static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
109
-		int* err)
103
+/* converts a str to an ipv4 address, returns the address or 0 on error
104
+   Warning: the result is a pointer to a statically allocated structure */
105
+static inline struct ip_addr* str2ip(unsigned char* str, unsigned int len)
106
+{
107
+	int i;
108
+	unsigned char *limit;
109
+	unsigned char *init;
110
+	static struct ip_addr ip;
111
+
112
+	/*init*/
113
+	ip.u.addr32[0]=0;
114
+	i=0;
115
+	limit=str+len;
116
+	init=str;
117
+
118
+	for(;str<limit ;str++){
119
+		if (*str=='.'){
120
+				i++;
121
+				if (i>3) goto error_dots;
122
+		}else if ( (*str <= '9' ) && (*str >= '0') ){
123
+				ip.u.addr[i]=ip.u.addr[i]*10+*str-'0';
124
+		}else{
125
+				//error unknown char
126
+				goto error_char;
127
+		}
128
+	}
129
+	ip.af=AF_INET;
130
+	ip.len=4;
131
+	
132
+	return &ip;
133
+
134
+error_dots:
135
+	DBG("str2ip: ERROR: too many dots in [%.*s]\n", (int)len, init);
136
+	return 0;
137
+error_char:
138
+	DBG("str2ip: WARNING: unexpected char %c in %.*s\n", *str,(int)len, init);
139
+	return 0;
140
+}
141
+
142
+
143
+
144
+/* returns an ip_addr struct.; on error returns 0
145
+ * the ip_addr struct is static, so subsequent calls will destroy its content*/
146
+static inline struct ip_addr* str2ip6(unsigned char* str, unsigned int len)
110 147
 {
111 148
 	int i, idx1, rest;
112 149
 	int no_colons;
... ...
@@ -143,6 +163,7 @@ static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
143 143
 				addr=addr_end;
144 144
 			}else{
145 145
 				double_colon=1;
146
+				addr[i]=htons(addr[i]);
146 147
 				i++;
147 148
 			}
148 149
 		}else if ((hex=HEX2I(*str))>=0){
... ...
@@ -153,29 +174,70 @@ static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
153 153
 			goto error_char;
154 154
 		}
155 155
 	}
156
-	
156
+	if (no_colons<2) goto error_too_few_colons;
157
+	if (!double_colon){ /* not ending in ':' */
158
+		addr[i]=htons(addr[i]);
159
+		i++; 
160
+	}
157 161
 	rest=8-i-idx1;
158 162
 	memcpy(addr_start+idx1+rest, addr_end, i*sizeof(unsigned short));
159
-	if (err) *err=0;
160 163
 	return &ip;
161 164
 
162 165
 error_too_many_colons:
163 166
 	DBG("str2ip6: ERROR: too many colons in [%.*s]\n", (int) len, init);
164
-	if (err) *err=1;
167
+	return 0;
168
+
169
+error_too_few_colons:
170
+	DBG("str2ip6: ERROR: too few colons in [%.*s]\n", (int) len, init);
165 171
 	return 0;
166 172
 
167 173
 error_colons:
168 174
 	DBG("str2ip6: ERROR: too many double colons in [%.*s]\n", (int) len, init);
169
-	if (err) *err=1;
170 175
 	return 0;
171 176
 
172 177
 error_char:
173 178
 	DBG("str2ip6: WARNING: unexpected char %c in  [%.*s]\n", *str, (int) len,
174 179
 			init);
175
-	if (err) *err=1;
176 180
 	return 0;
177 181
 }
182
+
183
+
184
+
185
+struct hostent* sip_resolvehost(char* name, unsigned short* port);
186
+
187
+
188
+
189
+/* gethostbyname wrappers
190
+ * use this, someday they will use a local cache */
191
+
192
+static inline struct hostent* resolvehost(const char* name)
193
+{
194
+	struct hostent* he;
195
+#ifdef DNS_IP_HACK
196
+	struct ip_addr* ip;
197
+	int len;
198
+	
199
+	len=strlen(name);
200
+	/* check if it's an ip address */
201
+	if ( ((ip=str2ip(name, len))!=0)
202
+#ifdef	USE_IPV6
203
+		  || ((ip=str2ip6(name, len))!=0)
204
+#endif
205
+		){
206
+		/* we are lucky, this is an ip address */
207
+		return ip_addr2he(name, len, ip);
208
+	}
209
+	
178 210
 #endif
211
+	he=gethostbyname(name); /*ipv4*/
212
+#ifdef USE_IPV6
213
+	if(he==0){
214
+		/*try ipv6*/
215
+		he=gethostbyname2(name, AF_INET6);
216
+	}
217
+#endif
218
+	return he;
219
+}
179 220
 
180 221
 
181 222
 
... ...
@@ -1,15 +1,12 @@
1
-INVITE sip:andrei@iptel.org SIP/2.0
2
-:q
1
+INVITE sip:andrei@mobile69 SIP/2.0
3 2
 Via: SIP/2.0/UDP dorian.fokus.gmd.de 
4
-From: "GMD FOKUS iptlab" <sip:jiri@iptel.org>;tag=b96b0300ed30f1286-2f5d
3
+From: "test" <sip:andrei@iptel.org>;tag=b96b0300ed30f1286-2f5d
5 4
 Call-ID: b96b0300-88d30f-66da-63aa@195.37.78.190
6 5
 CSeq: 101 INVITE
7 6
 Expires: 180
8 7
 Max-Forwards:  0
9
-User-Agent: Cisco-SIP-IP-Phone/2
8
+User-Agent: testing lookups
10 9
 Accept: application/sdp
11
-Contact: sip:jiri@195.37.78.190:5060
12
-Content-Type: application/sdp
13 10
 Content-Length: 225
14 11
 
15 12
 
... ...
@@ -32,7 +32,7 @@ alias="foo.bar"
32 32
 
33 33
 route{
34 34
 	if (myself==uri){
35
-		log("\n\nfrom myself\n\n"); drop;
35
+		log("\n\nfrom myself\n\n");
36 36
 	};
37 37
 	log("\n\n continue \n\n");
38 38
 	forward(uri:host, uri:port);
... ...
@@ -97,49 +97,6 @@ error_char:
97 97
 
98 98
 
99 99
 
100
-/* converts a str to an ipv4 address, returns the address and sets *err
101
- * if error and err!=null
102
- */
103
-static inline unsigned int str2ip(unsigned char* str, unsigned int len,
104
-		int * err)
105
-{
106
-	unsigned int ret;
107
-	int i;
108
-	unsigned char *limit;
109
-	unsigned char *init;
110
-
111
-	/*init*/
112
-	ret=i=0;
113
-	limit=str+len;
114
-	init=str;
115
-
116
-	for(;str<limit ;str++){
117
-		if (*str=='.'){
118
-				i++;
119
-				if (i>3) goto error_dots;
120
-		}else if ( (*str <= '9' ) && (*str >= '0') ){
121
-				((unsigned char*)&ret)[i]=((unsigned char*)&ret)[i]*10+
122
-											*str-'0';
123
-		}else{
124
-				//error unknown char
125
-				goto error_char;
126
-		}
127
-	}
128
-	if (err) *err=0;
129
-	return ret;
130
-
131
-error_dots:
132
-	DBG("str2ip: ERROR: too many dots in [%.*s]\n", (int)len, init);
133
-	if (err) *err=1;
134
-	return 0;
135
-error_char:
136
-	DBG("str2ip: WARNING: unexpected char %c in %.*s\n", *str,(int)len, init);
137
-	if (err) *err=1;
138
-	return 0;
139
-}
140
-
141
-
142
-
143 100
 static inline int btostr( char *p,  unsigned char val)
144 101
 {
145 102
 	unsigned int a,b,i =0;