BusyBox Bug and Patch Tracking
BusyBox
  

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0000104 [uClibc] Networking Support minor always 02-15-05 11:26 04-28-05 14:26
Reporter dasi View Status public  
Assigned To uClibc
Priority normal Resolution fixed  
Status closed   Product Version 0.9.26
Summary 0000104: resolv.c patch: returning multiple ip in h_addr_list
Description I noticed that uClibc doesn't fill up struct hostent -> h_addr_list member
with a multiple IP's if available. Here is a patch attached, which
provides such functionality. I used it with v0.9.26. It worked fine. I
also tried this path with v0.9.27: patch is aplying succesfuly, but i
wont work because of modifications made in order to support h_aliases.
This path is also IPv6 ready, but i didin't finished it because i don't
use IPv6 at the moment.

see patch in the "Additional Information"
Additional Information Index: resolv.c
===================================================================
--- resolv.c (revision 1000)
+++ resolv.c (working copy)
@@ -212,7 +212,10 @@
        int ttl;
        int rdlength;
        unsigned char * rdata;
- int rdoffset;
+ int rdoffset;
+ char* buf;
+ size_t buflen;
+ size_t add_count;
 };

 enum etc_hosts_action {
@@ -665,7 +668,9 @@
        struct timeval tv;
        fd_set fds;
        struct resolv_header h;
- struct resolv_question q;
+ struct resolv_question q;
+ struct resolv_answer ma;
+ int first_answer = 1;
        int retries = 0;
        unsigned char * packet = malloc(PACKETSZ);
        char *dns, *lookup = malloc(MAXDNAME);
@@ -828,21 +833,55 @@
                }
                DPRINTF("Decoding answer at pos %d\n", pos);

- for (j=0;j<h.ancount;j++)
+ first_answer = 1;
+ for (j=0;j<h.ancount;j++,pos += i)
                {
- i = __decode_answer(packet, pos, a);
+ i = __decode_answer(packet, pos, &ma);

                    if (i<0) {
                        DPRINTF("failed decode %d\n", i);
                        goto again;
                    }
- /* For all but T_SIG, accept first answer */
- if (a->atype != T_SIG)
- break;

- DPRINTF("skipping T_SIG %d\n", i);
- free(a->dotted);
- pos += i;
+ if ( first_answer )
+ {
+ ma.buf = a->buf;
+ ma.buflen = a->buflen;
+ ma.add_count = a->add_count;
+ memcpy(a, &ma, sizeof(ma));
+ if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA)))
+ {
+ break;
+ }
+ if (a->atype != type)
+ {
+ free(a->dotted);
+ continue;
+ }
+ a->add_count = h.ancount - j - 1;
+ if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen)
+ {
+ break;
+ }
+ a->add_count = 0;
+ first_answer = 0;
+ }
+ else
+ {
+ free(ma.dotted);
+ if (ma.atype != type)
+ {
+ continue;
+ }
+ if (a->rdlength != ma.rdlength)
+ {
+ free(a->dotted);
+ DPRINTF("Answer address len(%u) differs from original(%u)\n", ma.rdlength, a->rdlength);
+ goto again;
+ }
+ memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength);
+ ++a->add_count;
+ }
                }

                DPRINTF("Answer name = |%s|\n", a->dotted);
@@ -1711,8 +1750,11 @@
        BIGLOCK;
        __nameserversXX=__nameservers;
        __nameserverXX=__nameserver;
- BIGUNLOCK;
- i = __dns_lookup(buf, T_A, __nameserversXX, __nameserverXX, &packet, &a);
+ BIGUNLOCK;
+ a.buf = buf;
+ a.buflen = buflen;
+ a.add_count = 0;
+ i = __dns_lookup(name, T_A, __nameserversXX, __nameserverXX, &packet, &a);

                if (i < 0) {
                        *h_errnop = HOST_NOT_FOUND;
@@ -1720,26 +1762,30 @@
                        return TRY_AGAIN;
                }

+ if ((a.rdlength + sizeof(struct in_addr*)) * a.add_count + 256 > buflen)
+ {
+ free(a.dotted);
+ free(packet);
+ *h_errnop = NETDB_INTERNAL;
+ DPRINTF("buffer to small(multiple addresses)\n");
+ return ERANGE;
+ }
+ else if(a.add_count > 0)
+ {
+ memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength);
+ addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength);
+ addr_list[0] = in;
+ for (i = 0; i<a.add_count; ++i)
+ addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i);
+ addr_list[a.add_count + 1] = 0;
+ buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf);
+ buf = (char*)&addr_list[a.add_count + 2];
+ }
+
                strncpy(buf, a.dotted, buflen);
                free(a.dotted);

- if (a.atype == T_CNAME) { /* CNAME */
- DPRINTF("Got a CNAME in gethostbyname()\n");
- i = __decode_dotted(packet, a.rdoffset, buf, buflen);
- free(packet);
-
- if (i < 0) {
- *h_errnop = NO_RECOVERY;
- DPRINTF("__decode_dotted\n");
- return -1;
- }
- if (++nest > MAX_RECURSE) {
- *h_errnop = NO_RECOVERY;
- DPRINTF("recursion\n");
- return -1;
- }
- continue;
- } else if (a.atype == T_A) { /* ADDRESS */
+ if (a.atype == T_A) { /* ADDRESS */
                        memcpy(in, a.rdata, sizeof(*in));
                        result_buf->h_name = buf;
                        result_buf->h_addrtype = AF_INET;
@@ -1837,6 +1883,8 @@
            return NETDB_SUCCESS;
        }

+ memset((char *) &a, '\0', sizeof(a));
+
        for (;;) {
        BIGLOCK;
        __nameserversXX=__nameservers;
@@ -1915,7 +1963,9 @@
        *result=NULL;
        if (!addr)
                return EINVAL;
-
+
+ memset((char *) &a, '\0', sizeof(a));
+
        switch (type) {
                case AF_INET:
                        if (len != sizeof(struct in_addr))
Attached Files

- Relationships

- Notes
(0000051)
dasi
02-20-05 02:15

"but i wont work" -> "but it won't work"
 

- Issue History
Date Modified Username Field Change
02-15-05 11:26 dasi New Issue
02-15-05 11:32 dasi Issue Monitored: dasi
02-15-05 11:32 dasi Issue End Monitor: dasi
02-20-05 02:15 dasi Note Added: 0000051
03-16-05 11:56 andersen Assigned To andersen => uClibc
04-28-05 14:26 andersen Status assigned => closed
04-28-05 14:26 andersen Resolution open => fixed


Copyright © 2000 - 2006 Mantis Group
Powered by Mantis Bugtracker