Skip to content

Commit 83cc7f1

Browse files
author
Andriy Pylypenko
committed
Make opensips behave consistently in respect of nsswitch regardless of DNS caching.
1 parent efb9e16 commit 83cc7f1

File tree

1 file changed

+8
-328
lines changed

1 file changed

+8
-328
lines changed

resolve.c

+8-328
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,8 @@ static struct bl_head *failover_bl=0;
8080
#define DNS_REVOLVER_BL_NAME "dns"
8181
#define DNS_BL_EXPIRE 4*60
8282

83-
#define MAX_BUFF_SIZE 8192
84-
#define MAXALIASES 36
8583
#define MAXADDRS 36
8684
#define DNS_MAX_NAME 256
87-
struct hostent global_he;
88-
static char hostbuf[MAX_BUFF_SIZE];
89-
static char *h_addr_ptrs[MAXADDRS];
90-
static char *host_aliases[MAXALIASES];
9185

9286
stat_var *dns_total_queries;
9387
stat_var *dns_slow_queries;
@@ -126,288 +120,14 @@ typedef union {
126120
(s) = ntohl (t_cp); \
127121
} while (0)
128122

129-
static inline unsigned int dns_get16(const u_char *src) {
130-
unsigned int dst;
131-
132-
DNS_GET16(dst, src);
133-
return dst;
134-
}
135-
136-
static inline unsigned int dns_get32(const u_char *src) {
137-
unsigned int dst;
138-
139-
DNS_GET32(dst, src);
140-
return dst;
141-
}
142-
143-
int get_dns_answer(union dns_query *answer,int anslen,char *qname,int qtype,int *min_ttl)
144-
{
145-
register const HEADER *hp;
146-
register int n;
147-
register const unsigned char *cp;
148-
const char* tname;
149-
const unsigned char *eom,*erdata;
150-
int type, class,ttl, buflen, ancount;
151-
int haveanswer, had_error;
152-
char *bp,**ap,**hap;
153-
char tbuf[DNS_MAX_NAME];
154-
int toobig=0;
155-
156-
tname = qname;
157-
global_he.h_name = NULL;
158-
eom = answer->buff + anslen;
159-
160-
hp = &answer->hdr;
161-
ancount = ntohs(hp->ancount);
162-
bp = hostbuf;
163-
buflen = sizeof hostbuf;
164-
165-
cp = answer->buff;
166-
BOUNDED_INCR(DNS_HDR_SIZE);
167-
168-
n = dn_expand(answer->buff, eom, cp, bp, buflen);
169-
if (n < 0) {
170-
LM_ERR("Error expanding name\n");
171-
return -1;
172-
}
173-
BOUNDED_INCR(n+4);
174-
175-
if (qtype == T_A || qtype == T_AAAA) {
176-
n = strlen(bp) + 1;
177-
if (n >= DNS_MAX_NAME) {
178-
LM_ERR("Name too large\n");
179-
return -1;
180-
}
181-
global_he.h_name = bp;
182-
bp += n;
183-
buflen -= n;
184-
/* The qname can be abbreviated, but h_name is now absolute. */
185-
qname = global_he.h_name;
186-
}
187-
188-
ap = host_aliases;
189-
*ap = NULL;
190-
global_he.h_aliases = host_aliases;
191-
hap = h_addr_ptrs;
192-
*hap = NULL;
193-
global_he.h_addr_list = h_addr_ptrs;
194-
haveanswer = 0;
195-
had_error = 0;
196-
while (ancount-- > 0 && cp < eom && !had_error) {
197-
n = dn_expand(answer->buff, eom, cp, bp, buflen);
198-
if (n < 0) {
199-
had_error++;
200-
continue;
201-
}
202-
cp += n; /* name */
203-
BOUNDS_CHECK(cp,3*2+4);
204-
type = dns_get16(cp);
205-
cp += 2; /* type */
206-
class = dns_get16(cp);
207-
cp += 2; /* class*/
208-
ttl = dns_get32(cp);
209-
if (ttl<*min_ttl)
210-
*min_ttl=ttl;
211-
cp +=4;
212-
n = dns_get16(cp);
213-
cp += 2; /* len */
214-
BOUNDS_CHECK(cp, n);
215-
erdata = cp + n;
216-
217-
if (class != C_IN) {
218-
LM_ERR("Got response class != C_IN");
219-
had_error++;
220-
continue;
221-
}
222-
223-
if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
224-
if (ap >= &host_aliases[MAXALIASES-1])
225-
continue;
226-
n = dn_expand(answer->buff, eom, cp, tbuf, sizeof tbuf);
227-
if (n < 0) {
228-
LM_ERR("failed to expand alias\n");
229-
had_error++;
230-
continue;
231-
}
232-
cp += n;
233-
if (cp != erdata)
234-
return -1;
235-
/* Store alias. */
236-
*ap++ = bp;
237-
n = strlen(bp) + 1;
238-
if (n >= DNS_MAX_NAME) {
239-
LM_ERR("alias too long\n");
240-
had_error++;
241-
continue;
242-
}
243-
bp += n;
244-
buflen -= n;
245-
/* Get canonical name. */
246-
n = strlen(tbuf) + 1;
247-
if (n > buflen || n >= DNS_MAX_NAME) {
248-
had_error++;
249-
continue;
250-
}
251-
252-
strcpy(bp, tbuf);
253-
global_he.h_name = bp;
254-
bp += n;
255-
buflen -= n;
256-
continue;
257-
}
258-
259-
if (qtype == T_PTR && type == T_CNAME) {
260-
n = dn_expand(answer->buff, eom, cp, tbuf, sizeof tbuf);
261-
if (n < 0) {
262-
LM_ERR("failed to expand for t_ptr\n");
263-
had_error++;
264-
continue;
265-
}
266-
267-
cp += n;
268-
if (cp != erdata) {
269-
LM_ERR("failure\n");
270-
return -1;
271-
}
272-
/* Get canonical name. */
273-
n = strlen(tbuf) + 1;
274-
if (n > buflen || n >= DNS_MAX_NAME) {
275-
LM_ERR("ptr name too long\n");
276-
had_error++;
277-
continue;
278-
}
279-
strcpy(bp, tbuf);
280-
tname = bp;
281-
bp += n;
282-
buflen -= n;
283-
continue;
284-
}
285-
286-
if (type != qtype) {
287-
LM_ERR("asked for %d, got %d\n",qtype,type);
288-
cp+=n;
289-
continue;
290-
}
291-
292-
switch (type) {
293-
case T_PTR:
294-
if (strcasecmp(tname, bp) != 0) {
295-
LM_ERR("asked for %s, got %s\n",tname,bp);
296-
cp += n;
297-
continue; /* XXX - had_error++ ? */
298-
}
299-
n = dn_expand(answer->buff, eom, cp, bp, buflen);
300-
if (n < 0) {
301-
had_error++;
302-
break;
303-
}
304-
cp += n;
305-
if (cp != erdata) {
306-
LM_ERR("errdata err\n");
307-
return -1;
308-
}
309-
if (!haveanswer)
310-
global_he.h_name = bp;
311-
else if (ap < &host_aliases[MAXALIASES-1])
312-
*ap++ = bp;
313-
else
314-
n = -1;
315-
if (n != -1) {
316-
n = strlen(bp) + 1; /* for the \0 */
317-
if (n >= MAXHOSTNAMELEN) {
318-
had_error++;
319-
break;
320-
}
321-
bp += n;
322-
buflen -= n;
323-
}
324-
break;
325-
case T_A:
326-
case T_AAAA:
327-
if (strcasecmp(global_he.h_name, bp) != 0) {
328-
LM_ERR("asked for %s, got %s\n",global_he.h_name,bp);
329-
cp += n;
330-
continue; /* XXX - had_error++ ? */
331-
}
332-
if (n != global_he.h_length) {
333-
cp += n;
334-
continue;
335-
}
336-
if (!haveanswer) {
337-
register int nn;
338-
339-
global_he.h_name = bp;
340-
nn = strlen(bp) + 1;
341-
bp += nn;
342-
buflen -= nn;
343-
}
344-
345-
buflen -= sizeof(align) - ((u_long)bp % sizeof(align));
346-
bp += sizeof(align) - ((u_long)bp % sizeof(align));
347-
348-
if (bp + n >= &hostbuf[sizeof hostbuf]) {
349-
LM_ERR("size (%d) too big\n", n);
350-
had_error++;
351-
continue;
352-
}
353-
if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
354-
if (!toobig++)
355-
LM_ERR("Too many addresses (%d)\n",MAXADDRS);
356-
cp += n;
357-
continue;
358-
}
359-
360-
memmove(*hap++ = bp, cp, n);
361-
bp += n;
362-
buflen -= n;
363-
cp += n;
364-
if (cp != erdata) {
365-
LM_ERR("failure\n");
366-
return -1;
367-
}
368-
break;
369-
default:
370-
LM_ERR("should never get here\n");
371-
return -1;
372-
}
373-
if (!had_error)
374-
haveanswer++;
375-
}
376-
377-
if (haveanswer) {
378-
*ap = NULL;
379-
*hap = NULL;
380-
if (!global_he.h_name) {
381-
n = strlen(qname) + 1;
382-
if (n > buflen || n >= DNS_MAX_NAME) {
383-
LM_ERR("name too long\n");
384-
return -1;
385-
}
386-
strcpy(bp, qname);
387-
global_he.h_name = bp;
388-
bp += n;
389-
buflen -= n;
390-
}
391-
}
392-
393-
return 0;
394-
}
395-
396123
struct hostent* own_gethostbyname2(char *name,int af)
397124
{
398-
int size,type;
399125
struct hostent *cached_he;
400-
static union dns_query buff;
401126
int min_ttl = INT_MAX;
402127

403128
switch (af) {
404129
case AF_INET:
405-
size=4;
406-
type=T_A;
407-
break;
408130
case AF_INET6:
409-
size=16;
410-
type=T_AAAA;
411131
break;
412132
default:
413133
LM_ERR("Only A and AAAA queries\n");
@@ -427,25 +147,17 @@ struct hostent* own_gethostbyname2(char *name,int af)
427147
}
428148

429149
query:
430-
global_he.h_addrtype=af;
431-
global_he.h_length=size;
432-
433-
size=res_search(name, C_IN, type, buff.buff, sizeof(buff));
434-
if (size < 0) {
150+
cached_he = gethostbyname2(name, af);
151+
if (cached_he == NULL) {
435152
LM_DBG("Domain name not found\n");
436153
if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,NULL,0,1,0) < 0)
437154
LM_ERR("Failed to store %s - %d in cache\n",name,af);
438155
return NULL;
439156
}
440157

441-
if (get_dns_answer(&buff,size,name,type,&min_ttl) < 0) {
442-
LM_ERR("Failed to get dns answer\n");
443-
return NULL;
444-
}
445-
446-
if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,&global_he,-1,0,min_ttl) < 0)
158+
if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,cached_he,-1,0,min_ttl) < 0)
447159
LM_ERR("Failed to store %s - %d in cache\n",name,af);
448-
return &global_he;
160+
return cached_he;
449161
}
450162

451163
inline struct hostent* resolvehost(char* name, int no_ip_test)
@@ -510,12 +222,7 @@ struct hostent * own_gethostbyaddr(void *addr, socklen_t len, int af)
510222
const unsigned char *uaddr = (const u_char *)addr;
511223
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
512224
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
513-
int n;
514-
int ret;
515-
static union dns_query ptr_buff;
516225
socklen_t size;
517-
char qbuf[DNS_MAX_NAME+1];
518-
char *qp=NULL;
519226
int min_ttl=INT_MAX;
520227
struct hostent *cached_he;
521228

@@ -559,44 +266,17 @@ struct hostent * own_gethostbyaddr(void *addr, socklen_t len, int af)
559266
}
560267

561268
query:
562-
switch (af) {
563-
case AF_INET:
564-
sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
565-
(uaddr[3] & 0xff),
566-
(uaddr[2] & 0xff),
567-
(uaddr[1] & 0xff),
568-
(uaddr[0] & 0xff));
569-
break;
570-
case AF_INET6:
571-
qp = qbuf;
572-
for (n = 15; n >= 0; n--) {
573-
qp += sprintf(qp, "%x.%x.",
574-
uaddr[n] & 0xf,
575-
(uaddr[n] >> 4) & 0xf);
576-
}
577-
strcpy(qp, "ip6.arpa");
578-
break;
579-
}
580-
581-
global_he.h_addrtype=af;
582-
global_he.h_length=len;
583-
584-
ret=res_search(qbuf,C_IN,T_PTR,ptr_buff.buff,sizeof(ptr_buff.buff));
585-
if (ret < 0) {
269+
cached_he = gethostbyaddr(addr, len, af);
270+
if (cached_he == NULL) {
586271
LM_DBG("ptr not found\n");
587272
if (dnscache_put_func(addr,T_PTR,NULL,len,1,0) < 0)
588273
LM_ERR("Failed to store PTR in cache\n");
589274
return NULL;
590275
}
591276

592-
if (get_dns_answer(&ptr_buff,ret,qbuf,T_PTR,&min_ttl) < 0) {
593-
LM_ERR("Failed to get dns answer\n");
594-
return NULL;
595-
}
596-
597-
if (dnscache_put_func(addr,T_PTR,&global_he,len,0,min_ttl) < 0)
277+
if (dnscache_put_func(addr,T_PTR,cached_he,len,0,min_ttl) < 0)
598278
LM_ERR("Failed to store PTR in cache\n");
599-
return &global_he;
279+
return cached_he;
600280
}
601281

602282

0 commit comments

Comments
 (0)