... | ... |
@@ -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 | 174 |
- andrei |
159 | 175 |
Yes -- it happened on generating a 408 by TM; -jiri |
160 | 176 |
*/ |
161 |
- if (via->host.s[via->host.len]){ |
|
162 |
- host_copy=pkg_malloc( via->host.len+1 ); |
|
177 |
+ if (name->s[name->len]){ |
|
178 |
+ host_copy=pkg_malloc( name->len+1 ); |
|
163 | 179 |
if (!host_copy) { |
164 | 180 |
LOG(L_NOTICE, "ERROR: update_sock_struct_from_via:" |
165 | 181 |
" not enough memory\n"); |
166 | 182 |
return -1; |
167 | 183 |
} |
168 |
- memcpy(host_copy, via->host.s, via->host.len ); |
|
169 |
- host_copy[via->host.len]=0; |
|
170 |
- he=resolvehost(host_copy); |
|
184 |
+ memcpy(host_copy, name->s, name->len ); |
|
185 |
+ host_copy[name->len]=0; |
|
186 |
+ DBG("update_sock_struct_from_via: trying SRV lookup\n"); |
|
187 |
+ he=sip_resolvehost(host_copy, &port); |
|
188 |
+ |
|
171 | 189 |
pkg_free( host_copy ); |
172 | 190 |
}else{ |
173 |
- he=resolvehost(via->host.s); |
|
191 |
+ DBG("update_sock_struct_from_via: trying SRV lookup\n"); |
|
192 |
+ he=sip_resolvehost(name->s, &port); |
|
174 | 193 |
} |
175 |
- |
|
194 |
+ |
|
176 | 195 |
if (he==0){ |
177 |
- LOG(L_NOTICE, "ERROR:forward_reply:gethostbyname(%s) failure\n", |
|
178 |
- via->host.s); |
|
196 |
+ LOG(L_NOTICE, "ERROR:forward_reply:resolve_host(%s) failure\n", |
|
197 |
+ name->s); |
|
179 | 198 |
return -1; |
180 | 199 |
} |
181 |
- hostent2su(to, he, 0, (via->port)?htons(via->port): htons(SIP_PORT)); |
|
200 |
+ hostent2su(to, he, 0, htons(port)); |
|
182 | 201 |
} |
183 | 202 |
return 1; |
184 | 203 |
} |
... | ... |
@@ -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) \ |
... | ... |
@@ -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 | 180 |
} |
185 | 181 |
memset(p,0,sizeof(struct proxy_l)); |
186 | 182 |
p->name=name; |
187 |
- p->port=port?port:SIP_PORT; |
|
183 |
+ p->port=port; |
|
188 | 184 |
#ifdef DNS_IP_HACK |
189 | 185 |
/* fast ipv4 string to address conversion*/ |
190 | 186 |
len=strlen(name); |
... | ... |
@@ -220,44 +216,14 @@ struct proxy_l* mk_proxy(char* name, unsigned short port) |
220 | 216 |
} |
221 | 217 |
memcpy(p->host.h_addr_list[0], (char*)&ip, 4); |
222 | 218 |
p->host.h_addr_list[0][4]=0; |
219 |
+ if (p->port==0) p->port=SIP_PORT; |
|
223 | 220 |
|
224 | 221 |
return p; |
225 | 222 |
} |
226 | 223 |
#endif |
227 | 224 |
/* fail over to normal lookup */ |
228 | 225 |
|
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); |
|
226 |
+ he=sip_resolvehost(name, &(p->port)); |
|
261 | 227 |
if (he==0){ |
262 | 228 |
ser_error=E_BAD_ADDRESS; |
263 | 229 |
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 | 231 |
free(p); |
266 | 232 |
goto error; |
267 | 233 |
} |
268 |
-copy_he: |
|
269 | 234 |
if (hostent_cpy(&(p->host), he)!=0){ |
270 | 235 |
free(p); |
271 | 236 |
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 |
+ |