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 243
 		name=&(via->host);
250 244
 		port=via->port;
251 245
 	}
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);
246
+	/* we do now a malloc/memcpy because gethostbyname loves \0-terminated 
247
+	   strings; -jiri 
248
+	   but only if host is not null terminated
249
+	   (host.s[len] will always be ok for a via)
250
+	    BTW: when is via->host.s non null terminated? tm copy? - andrei 
251
+	    Yes -- it happened on generating a 408 by TM; -jiri
252
+	*/
253
+	if (name->s[name->len]){
254
+		host_copy=pkg_malloc( name->len+1 );
255
+		if (!host_copy) {
256
+			LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:"
257
+							" not enough memory\n");
290 258
 			return -1;
291 259
 		}
292
-		hostent2su(to, he, 0, htons(port));
260
+		memcpy(host_copy, name->s, name->len );
261
+		host_copy[name->len]=0;
262
+		DBG("update_sock_struct_from_via: trying SRV lookup\n");
263
+		he=sip_resolvehost(host_copy, &port);
264
+		
265
+		pkg_free( host_copy );
266
+	}else{
267
+		DBG("update_sock_struct_from_via: trying SRV lookup\n");
268
+		he=sip_resolvehost(name->s, &port);
269
+	}
270
+	
271
+	if (he==0){
272
+		LOG(L_NOTICE, "ERROR:forward_reply:resolve_host(%s) failure\n",
273
+				name->s);
274
+		return -1;
293 275
 	}
276
+	hostent2su(to, he, 0, htons(port));
294 277
 	return 1;
295 278
 }
296 279
 
... ...
@@ -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 176
 	memset(p,0,sizeof(struct proxy_l));
182 177
 	p->name=name;
183 178
 	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 179
 
226 180
 	DBG("DEBUG: mk_proxy: doing DNS lookup...\n");
227 181
 	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 359
 	struct rdata* head;
359 360
 	struct rdata* l;
360 361
 	struct srv_rdata* srv;
362
+	struct ip_addr* ip;
361 363
 	static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
362 364
 	int len;
363 365
 
... ...
@@ -369,6 +371,16 @@ struct hostent* sip_resolvehost(char* name, unsigned short* port)
369 371
 			LOG(L_WARN, "WARNING: sip_resolvehost: domain name too long (%d),"
370 372
 						" unable to perform SRV lookup\n", len);
371 373
 		}else{
374
+			/* check if it's an ip address */
375
+			if ( ((ip=str2ip(name, len))!=0)
376
+#ifdef	USE_IPV6
377
+				  || ((ip=str2ip6(name, len))!=0)
378
+#endif
379
+				){
380
+				/* we are lucky, this is an ip address */
381
+				return ip_addr2he(name,len,ip);
382
+			}
383
+			
372 384
 			memcpy(tmp, SRV_PREFIX, SRV_PREFIX_LEN);
373 385
 			memcpy(tmp+SRV_PREFIX_LEN, name, len+1); /*include the ending 0*/
374 386
 			
... ...
@@ -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 68
 void free_rdata_list(struct rdata* head);
67 69
 
68 70
 
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 71
 
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 72
 
90
-struct hostent* sip_resolvehost(char* name, unsigned short* port);
73
+#define rev_resolvehost(ip) gethostbyaddr((ip)->u.addr, (ip)->len, (ip)->af);
91 74
 
92 75
 
93 76
 
... ...
@@ -97,16 +80,53 @@ struct hostent* sip_resolvehost(char* name, unsigned short* port);
97 80
 		(((c)>='a') && ((c)<='f'))? ((c)-'a')+10 : -1 )
98 81
 
99 82
 
100
-#define rev_resolvehost(ip) gethostbyaddr((ip)->u.addr, (ip)->len, (ip)->af);
101 83
 
102 84
 
103 85
 
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)
86
+/* converts a str to an ipv4 address, returns the address or 0 on error
87
+   Warning: the result is a pointer to a statically allocated structure */
88
+static inline struct ip_addr* str2ip(unsigned char* str, unsigned int len)
89
+{
90
+	int i;
91
+	unsigned char *limit;
92
+	unsigned char *init;
93
+	static struct ip_addr ip;
94
+
95
+	/*init*/
96
+	ip.u.addr32[0]=0;
97
+	i=0;
98
+	limit=str+len;
99
+	init=str;
100
+
101
+	for(;str<limit ;str++){
102
+		if (*str=='.'){
103
+				i++;
104
+				if (i>3) goto error_dots;
105
+		}else if ( (*str <= '9' ) && (*str >= '0') ){
106
+				ip.u.addr[i]=ip.u.addr[i]*10+*str-'0';
107
+		}else{
108
+				//error unknown char
109
+				goto error_char;
110
+		}
111
+	}
112
+	ip.af=AF_INET;
113
+	ip.len=4;
114
+	
115
+	return &ip;
116
+
117
+error_dots:
118
+	DBG("str2ip: ERROR: too many dots in [%.*s]\n", (int)len, init);
119
+	return 0;
120
+error_char:
121
+	DBG("str2ip: WARNING: unexpected char %c in %.*s\n", *str,(int)len, init);
122
+	return 0;
123
+}
124
+
125
+
126
+
127
+/* returns an ip_addr struct.; on error returns 0
128
+ * the ip_addr struct is static, so subsequent calls will destroy its content*/
129
+static inline struct ip_addr* str2ip6(unsigned char* str, unsigned int len)
110 130
 {
111 131
 	int i, idx1, rest;
112 132
 	int no_colons;
... ...
@@ -143,6 +163,7 @@ static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
143 163
 				addr=addr_end;
144 164
 			}else{
145 165
 				double_colon=1;
166
+				addr[i]=htons(addr[i]);
146 167
 				i++;
147 168
 			}
148 169
 		}else if ((hex=HEX2I(*str))>=0){
... ...
@@ -153,29 +174,70 @@ static /*inline*/ struct ip_addr* str2ip6(unsigned char* str, unsigned int len,
153 174
 			goto error_char;
154 175
 		}
155 176
 	}
156
-	
177
+	if (no_colons<2) goto error_too_few_colons;
178
+	if (!double_colon){ /* not ending in ':' */
179
+		addr[i]=htons(addr[i]);
180
+		i++; 
181
+	}
157 182
 	rest=8-i-idx1;
158 183
 	memcpy(addr_start+idx1+rest, addr_end, i*sizeof(unsigned short));
159
-	if (err) *err=0;
160 184
 	return &ip;
161 185
 
162 186
 error_too_many_colons:
163 187
 	DBG("str2ip6: ERROR: too many colons in [%.*s]\n", (int) len, init);
164
-	if (err) *err=1;
188
+	return 0;
189
+
190
+error_too_few_colons:
191
+	DBG("str2ip6: ERROR: too few colons in [%.*s]\n", (int) len, init);
165 192
 	return 0;
166 193
 
167 194
 error_colons:
168 195
 	DBG("str2ip6: ERROR: too many double colons in [%.*s]\n", (int) len, init);
169
-	if (err) *err=1;
170 196
 	return 0;
171 197
 
172 198
 error_char:
173 199
 	DBG("str2ip6: WARNING: unexpected char %c in  [%.*s]\n", *str, (int) len,
174 200
 			init);
175
-	if (err) *err=1;
176 201
 	return 0;
177 202
 }
203
+
204
+
205
+
206
+struct hostent* sip_resolvehost(char* name, unsigned short* port);
207
+
208
+
209
+
210
+/* gethostbyname wrappers
211
+ * use this, someday they will use a local cache */
212
+
213
+static inline struct hostent* resolvehost(const char* name)
214
+{
215
+	struct hostent* he;
216
+#ifdef DNS_IP_HACK
217
+	struct ip_addr* ip;
218
+	int len;
219
+	
220
+	len=strlen(name);
221
+	/* check if it's an ip address */
222
+	if ( ((ip=str2ip(name, len))!=0)
223
+#ifdef	USE_IPV6
224
+		  || ((ip=str2ip6(name, len))!=0)
225
+#endif
226
+		){
227
+		/* we are lucky, this is an ip address */
228
+		return ip_addr2he(name, len, ip);
229
+	}
230
+	
178 231
 #endif
232
+	he=gethostbyname(name); /*ipv4*/
233
+#ifdef USE_IPV6
234
+	if(he==0){
235
+		/*try ipv6*/
236
+		he=gethostbyname2(name, AF_INET6);
237
+	}
238
+#endif
239
+	return he;
240
+}
179 241
 
180 242
 
181 243
 
... ...
@@ -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;