Browse code

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

Andrei Pelinescu-Onciul authored on 12/08/2002 18:22:17
Showing 9 changed files
... ...
@@ -8,7 +8,7 @@
8 8
 VERSION = 0
9 9
 PATCHLEVEL = 8
10 10
 SUBLEVEL = 7
11
-EXTRAVERSION = -7-srv
11
+EXTRAVERSION = -8-srv
12 12
 
13 13
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
14 14
 OS = $(shell uname -s)
... ...
@@ -136,13 +136,29 @@ int update_sock_struct_from_via( union sockaddr_union* to,
136 136
 {
137 137
 	struct hostent* he;
138 138
 	char *host_copy;
139
+	str* name;
140
+	unsigned short port;
139 141
 
140 142
 
141 143
 #ifdef DNS_IP_HACK
142 144
 	int err;
143 145
 	unsigned int ip;
146
+#endif
147
+
144 148
 
145
-	ip=str2ip((unsigned char*)via->host.s,via->host.len,&err);
149
+	if (via->received){
150
+		DBG("update_sock_struct_from_via: using 'received'\n");
151
+		name=&(via->received->value);
152
+		/* making sure that we won't do SRV lookup on "received"
153
+		 * (possible if no DNS_IP_HACK is used)*/
154
+		port=via->port?via->port:SIP_PORT; 
155
+	}else{
156
+		DBG("update_sock_struct_from_via: using via host\n");
157
+		name=&(via->host);
158
+		port=via->port;
159
+	}
160
+#ifdef DNS_IP_HACK
161
+	ip=str2ip((unsigned char*)name->s, name->len,&err);
146 162
 	if (err==0){
147 163
 		to->sin.sin_family=AF_INET;
148 164
 		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,
158 158
 		   - andrei 
159 159
 			Yes -- it happened on generating a 408 by TM; -jiri
160 160
 		*/
161
-		if (via->host.s[via->host.len]){
162
-			host_copy=pkg_malloc( via->host.len+1 );
161
+		if (name->s[name->len]){
162
+			host_copy=pkg_malloc( name->len+1 );
163 163
 			if (!host_copy) {
164 164
 				LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:"
165 165
 								" not enough memory\n");
166 166
 				return -1;
167 167
 			}
168
-			memcpy(host_copy, via->host.s, via->host.len );
169
-			host_copy[via->host.len]=0;
170
-			he=resolvehost(host_copy);
168
+			memcpy(host_copy, name->s, name->len );
169
+			host_copy[name->len]=0;
170
+			DBG("update_sock_struct_from_via: trying SRV lookup\n");
171
+			he=sip_resolvehost(host_copy, &port);
172
+			
171 173
 			pkg_free( host_copy );
172 174
 		}else{
173
-			he=resolvehost(via->host.s);
175
+			DBG("update_sock_struct_from_via: trying SRV lookup\n");
176
+			he=sip_resolvehost(name->s, &port);
174 177
 		}
175
-
178
+		
176 179
 		if (he==0){
177
-			LOG(L_NOTICE, "ERROR:forward_reply:gethostbyname(%s) failure\n",
178
-					via->host.s);
180
+			LOG(L_NOTICE, "ERROR:forward_reply:resolve_host(%s) failure\n",
181
+					name->s);
179 182
 			return -1;
180 183
 		}
181
-		hostent2su(to, he, 0, (via->port)?htons(via->port): htons(SIP_PORT));
184
+		hostent2su(to, he, 0, htons(port));
182 185
 	}
183 186
 	return 1;
184 187
 }
... ...
@@ -26,8 +26,8 @@
26 26
 #define MAX_RECEIVED_SIZE  57
27 27
 
28 28
 /* mallocs for local stuff (not needed to be shared mem?)*/
29
-#define local_malloc pkg_malloc
30
-#define local_free   pkg_free
29
+#define local_malloc(s) pkg_malloc((s))
30
+#define local_free(s)   pkg_free((s))
31 31
 
32 32
 
33 33
 #define append_str(_dest,_src,_len,_msg) \
... ...
@@ -1655,6 +1655,8 @@ parse_again:
1655 1655
 						vb->last_param=param;
1656 1656
 						if (param->type==PARAM_BRANCH)
1657 1657
 							vb->branch=param;
1658
+						else if (param->type==PARAM_RECEIVED)
1659
+							vb->received=param;
1658 1660
 						break;
1659 1661
 					case P_PARAM:
1660 1662
 						break;
... ...
@@ -44,6 +44,7 @@ struct via_body {
44 44
 
45 45
 	     /* shortcuts to "important" params*/
46 46
 	struct via_param* branch;
47
+	struct via_param* received;
47 48
 	
48 49
 	struct via_body* next; /* pointer to next via body string if
49 50
 				  compact via or null */
... ...
@@ -166,12 +166,8 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
166 166
 {
167 167
 	struct proxy_l* p;
168 168
 	struct hostent* he;
169
-	struct rdata* head;
170
-	struct rdata* l;
171
-	struct srv_rdata* srv;
172
-	static char tmp[MAX_DNS_NAME]; /* tmp buff. for SRV lookups*/
173
-	int len;
174 169
 #ifdef DNS_IP_HACK
170
+	int len;
175 171
 	int err;
176 172
 	unsigned int ip;
177 173
 #endif
... ...
@@ -184,7 +180,7 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
184 184
 	}
185 185
 	memset(p,0,sizeof(struct proxy_l));
186 186
 	p->name=name;
187
-	p->port=port?port:SIP_PORT;
187
+	p->port=port;
188 188
 #ifdef DNS_IP_HACK
189 189
 	/* fast ipv4 string to address conversion*/
190 190
 	len=strlen(name);
... ...
@@ -220,44 +216,14 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
220 220
 		}
221 221
 		memcpy(p->host.h_addr_list[0], (char*)&ip, 4);
222 222
 		p->host.h_addr_list[0][4]=0;
223
+		if (p->port==0) p->port=SIP_PORT;
223 224
 
224 225
 		return p;
225 226
 	}
226 227
 #endif
227 228
 	/* fail over to normal lookup */
228 229
 
229
-	/* try SRV if no port specified (draft-ietf-sip-srv-06) */
230
-	if (port==0){
231
-		len=strlen(name);
232
-		if ((len+SRV_PREFIX_LEN+1)>MAX_DNS_NAME){
233
-			LOG(L_WARN, "WARNING: domain name too long (%d), unable"
234
-					" to perform SRV lookup\n", len);
235
-		}else{
236
-			memcpy(tmp, SRV_PREFIX, SRV_PREFIX_LEN);
237
-			memcpy(tmp+SRV_PREFIX_LEN, name, len+1); /*include the ending 0*/
238
-			
239
-			head=get_record(tmp, T_SRV);
240
-			for(l=head; l; l=l->next){
241
-				if (l->type!=T_SRV) continue; /*should never happen*/
242
-				srv=(struct srv_rdata*) l->rdata;
243
-				if (srv==0){
244
-					LOG(L_CRIT, "mk_proxy: BUG: null rdata\n");
245
-					free_rdata_list(head);
246
-					break;
247
-				}
248
-				he=resolvehost(srv->name);
249
-				if (he!=0){
250
-					DBG("mk_proxy: SRV(%s) = %s:%d\n",
251
-							tmp, srv->name, srv->port);
252
-					p->port=srv->port;
253
-					free_rdata_list(head); /*clean up*/
254
-					goto copy_he;
255
-				}
256
-			}
257
-			DBG(" not SRV record found for %s\n", name);
258
-		}
259
-	}
260
-	he=resolvehost(name);
230
+	he=sip_resolvehost(name, &(p->port));
261 231
 	if (he==0){
262 232
 		ser_error=E_BAD_ADDRESS;
263 233
 		LOG(L_CRIT, "ERROR: mk_proxy: could not resolve hostname:"
... ...
@@ -265,7 +231,6 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
265 265
 		free(p);
266 266
 		goto error;
267 267
 	}
268
-copy_he:
269 268
 	if (hostent_cpy(&(p->host), he)!=0){
270 269
 		free(p);
271 270
 		goto error;
... ...
@@ -157,7 +157,7 @@ struct rdata* get_record(char* name, int type)
157 157
 {
158 158
 	int size;
159 159
 	int qno, answers_no;
160
-	int r,i;
160
+	int r;
161 161
 	int ans_len;
162 162
 	static union dns_query buff;
163 163
 	unsigned char* p;
... ...
@@ -304,3 +304,58 @@ error:
304 304
 	return 0;
305 305
 }
306 306
 
307
+
308
+
309
+/* resolves a host name trying SRV lookup if *port==0 or normal A/AAAA lookup
310
+ * if *port!=0.
311
+ * returns: hostent struct & *port filled with the port from the SRV record;
312
+ *  0 on error
313
+ */
314
+struct hostent* sip_resolvehost(char* name, unsigned short* port)
315
+{
316
+	struct hostent* he;
317
+	struct rdata* head;
318
+	struct rdata* l;
319
+	struct srv_rdata* srv;
320
+	static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
321
+	int len;
322
+
323
+	/* try SRV if no port specified (draft-ietf-sip-srv-06) */
324
+	if ((port)&&(*port==0)){
325
+		*port=SIP_PORT; /* just in case we don't find another */
326
+		len=strlen(name);
327
+		if ((len+SRV_PREFIX_LEN+1)>MAX_DNS_NAME){
328
+			LOG(L_WARN, "WARNING: sip_resolvehost: domain name too long (%d),"
329
+						" unable to perform SRV lookup\n", len);
330
+		}else{
331
+			memcpy(tmp, SRV_PREFIX, SRV_PREFIX_LEN);
332
+			memcpy(tmp+SRV_PREFIX_LEN, name, len+1); /*include the ending 0*/
333
+			
334
+			head=get_record(tmp, T_SRV);
335
+			for(l=head; l; l=l->next){
336
+				if (l->type!=T_SRV) continue; /*should never happen*/
337
+				srv=(struct srv_rdata*) l->rdata;
338
+				if (srv==0){
339
+					LOG(L_CRIT, "sip_resolvehost: BUG: null rdata\n");
340
+					free_rdata_list(head);
341
+					break;
342
+				}
343
+				he=resolvehost(srv->name);
344
+				if (he!=0){
345
+					/* we found it*/
346
+					DBG("sip_resolvehost: SRV(%s) = %s:%d\n",
347
+							tmp, srv->name, srv->port);
348
+					*port=srv->port;
349
+					free_rdata_list(head); /*clean up*/
350
+					return he;
351
+				}
352
+			}
353
+			DBG("sip_resolvehost: not SRV record found for %s," 
354
+					" trying 'normal' lookup...\n", name);
355
+		}
356
+	}
357
+	he=resolvehost(name);
358
+	return he;
359
+}
360
+
361
+
... ...
@@ -82,6 +82,7 @@ static inline struct hostent* resolvehost(const char* name)
82 82
 	return he;
83 83
 }
84 84
 
85
+struct hostent* sip_resolvehost(char* name, unsigned short* port);
85 86
 
86 87
 
87 88
 
... ...
@@ -1,6 +1,6 @@
1 1
 SIP/2.0 200 Ok
2
-Via: SIP/2.0/UDP 192.168.99.100
3
-Via: SIP/2.0/UDP 193.175.133.195:5060
2
+Via: SIP/2.0/UDP foo.bar.com
3
+Via: SIP/2.0/UDP mobile55
4 4
 From: <sip:x@foo.bar>
5 5
 To: <sip:y@bar.foo>
6 6
 Call-ID:9437892232b@foo.bar