cURL / Mailing Lists / curl-library / Single Mail

curl-library

DNS Resolve problems on 2.4.18 Linux

From: Dan C <dan_c_curl_at_yahoo.com>
Date: Thu, 23 Oct 2003 09:32:58 -0700 (PDT)

 have been using curl in a project at work and found that curl would not resolve host names at all on our Linux kernel based on 2.4.18 source. (glibc 2.2.5).
I traced the problem down to the gethostbyname_r in iphost.c ( the six parameter version ) gethostbyname returns a negative 1 (-1) and then modifies errno to ERANGE or EAGAIN. This seems to be counter to what the man page says for Glibc2 (see below).
 
We are using curl-7.10.3, but the source is the same in 7.10.7. ( Should we upgrade to 7.10.8 or wait). We don't care about the asynch dns cache as we have our own and would turn that off anyway in the configure..)
 
Source in question (iphost.c):
      res=gethostbyname_r(hostname,
        (struct hostent *)buf,
        (char *)buf + sizeof(struct hostent),
        step_size - sizeof(struct hostent),
        &h, /* DIFFERENCE */
        &h_errnop);

      /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
         sudden this function returns EAGAIN if the given buffer size is too
         ...
         ...
         If anyone has a better fix, please tell us!
      */
 
      if (( ERANGE == res ) || (EAGAIN == res)) {
          step_size+=200;
          continue;
      }
      break;
    } while(step_size <= CURL_NAMELOOKUP_SIZE);

 

So I modified the check to first check if ret is less than zero and then check errono (which works) and if that fails to default back to the original check for compatibitlty. (Feel free to "optimize" the if... I made it this way to be the most readable.)
 
     if (( res < 0 ) && ((ERANGE == errno) || (EAGAIN == errno))) {
          step_size+=200;
          continue;
      } else if (( ERANGE == res ) || (EAGAIN == res)) {
          step_size+=200;
          continue;
      }
      break;
    } while(step_size <= CURL_NAMELOOKUP_SIZE);
 
From the man page gethostbyname :
Glibc2 also has reentrant versions gethostbyname_r() and gethostbyname2_r(). These
       return 0 on success and nonzero on error. The result of the call is now stored in
       the struct with address ret. After the call, *result will be NULL on error or
       point to the result on success. Auxiliary data is stored in the buffer buf of
       length buflen. (If the buffer is too small, these functions will return ERANGE.)
       No global variable h_errno is modified, but the address of a variable in which to
       store error numbers is passed in h_errnop.
 
- Dan

---------------------------------
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search

-------------------------------------------------------
This SF.net email is sponsored by: The SF.net Donation Program.
Do you like what SourceForge.net is doing for the Open
Source Community? Make a contribution, and help us add new
features and functionality. Click here: http://sourceforge.net/donate/
Received on 2003-10-25