gethostbyname problem

View: New views
9 Messages — Rating Filter:   Alert me  

gethostbyname problem

by David Francois :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I have some troubles with the gethostbyname function on uclibc-0.9.29.

I have developed a short program which does periodically a gethostbyname.
The problem is if I change the network interface (ETH to WLAN for example) while this short program is running, the gethostbyname function returns a host not found error,  but the network is correctly mounted since I can ping  any URLs or IP address.

When I remount the previous unmounted network interface, the program logs the IP address of the given server.

Here the source  code:

#include <netdb.h>
#include <stdio.h>
#include <stdint.h>
extern int h_errno;


int main(int argn, char* argv[])
{
    struct hostent* host;

    while (1)
    {
        host = gethostbyname(argv[1]);
        if (host)
        {
            printf("Host: %s, addr: %d.%d.%d.%d\n", argv[1], ((uint8_t*)host->h_addr_list[0])[0],
                    ((uint8_t*)host->h_addr_list[0])[1],
                    ((uint8_t*)host->h_addr_list[0])[2],
                    ((uint8_t*)host->h_addr_list[0])[3]);
        }
        else
        {
            printf("lookup error %d: %s\n", h_errno, hstrerror(h_errno));
        }
        fflush(stdout);
        sleep(1);
    }

    return 0;
}


Thanks for your help,

D. FRANCOIS

_______________________________________________
uClibc mailing list
uClibc@...
http://lists.busybox.net/mailman/listinfo/uclibc

Re: gethostbyname problem

by chickenandporn :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Oct 12, 2009 at 12:41, David Francois
<dfrancois@...>wrote:

> Hi,
>
> I have some troubles with the gethostbyname function on uclibc-0.9.29.
>
> I have developed a short program which does periodically a gethostbyname.
> The problem is if I change the network interface (ETH to WLAN for example)
> while this short program is running, the gethostbyname function returns a
> host not found error,  but the network is correctly mounted since I can ping
>  any URLs or IP address.
>
> When I remount the previous unmounted network interface, the program logs
> the IP address of the given server.
>
> Here the source  code:
> [...]


Rather than generically pinging, you might want to focus on whether you can
reach your DNS servers.  gethostbyname() should be sending UDP/53 in the
wire and getting responses, but changing adapters might break the outbound
or return path.

Allan
--
allanc@...  "金鱼" http://linkedin.com/in/goldfish
_______________________________________________
uClibc mailing list
uClibc@...
http://lists.busybox.net/mailman/listinfo/uclibc

Parent Message unknown gethostbyname problem

by Cuero Bugot :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

We actually found the problem with gethostbyname on uClibc.
When we change the network interface, the /etc/resolv.conf is also and apparently the uClibc resolve code is not reloading the nameserver configuration files.
To fixe it we did a very simple patch (attached)  (against version uClibc 0.9.29).

The idea is that if a ns lookup fails then the nameserver file is reloaded. I believe that the overhead of reloading the nameservers in case of ns lookup failure is really small.

The patch is a few line long in libc/inet/resolv.c file.

I have seen that in head version of resolv.c has been refactored a little (which is a good thing), but this prb has not been taken care of. Instead there is a new thing (which I believe is actually not very usefull): the nameserver file is reloaded every 256 seconds.

The reload on failure patch could be applied on head version.

Is anybody interested ? How can we go further ?

Regards

C.



_______________________________________________
uClibc mailing list
uClibc@...
http://lists.busybox.net/mailman/listinfo/uclibc

resolv-nameserver.patch (1K) Download Attachment

Re: gethostbyname problem

by Bernhard Reutner-Fischer :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Oct 13, 2009 at 06:11:48AM -0700, Cuero Bugot wrote:
>Hi all,
>
>We actually found the problem with gethostbyname on uClibc.
>When we change the network interface, the /etc/resolv.conf is also and apparently the uClibc resolve code is not reloading the nameserver configuration files.
>To fixe it we did a very simple patch (attached)  (against version uClibc 0.9.29).

We moved to git. See http://git.uclibc.org/uClibc
>
>The idea is that if a ns lookup fails then the nameserver file is reloaded. I believe that the overhead of reloading the nameservers in case of ns lookup failure is really small.

I'm not sure i understand what you say? Your scenario sounds (to me,
correct me if i'm wrong) like:
If resolv.conf changes then reload resolv.conf ¹)

>The patch is a few line long in libc/inet/resolv.c file.
>
>I have seen that in head version of resolv.c has been refactored a little (which is a good thing), but this prb has not been taken care of. Instead there is a new thing (which I believe is actually not very usefull): the nameserver file is reloaded every 256 seconds.

That's not too helpful either, yes. ¹)
>
>The reload on failure patch could be applied on head version.

As mentioned above, svn isn't used anymore.
>
>Is anybody interested ? How can we go further ?

Not terribly interrested (the resolver could need a complete rewrite
against the SUSv4 requirements), but..

Denys, apparently you added that rereading, got a better idea than
the +60b below?

¹) attached

diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 6611466..552d8b5 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -312,6 +312,7 @@ Domain name in a message can be represented as either:
 #include <arpa/nameser.h>
 #include <sys/utsname.h>
 #include <sys/un.h>
+#include <sys/stat.h>
 #include <bits/uClibc_mutex.h>
 
 /* poll() is not supported in kernel <= 2.0, therefore if __NR_poll is
@@ -948,19 +949,18 @@ static char *skip_and_NUL_space(char *p)
 /* Must be called under __resolv_lock. */
 void attribute_hidden __open_nameservers(void)
 {
- static uint8_t last_time;
-
  char szBuffer[MAXLEN_searchdomain];
  FILE *fp;
  int i;
  sockaddr46_t sa;
+ static time_t resolv_conf_mtime;
 
  if (!__res_sync) {
- /* Provide for periodic reread of /etc/resolv.conf */
- /* cur_time "ticks" every 256 seconds */
- uint8_t cur_time = ((unsigned)time(NULL)) >> 8;
- if (last_time != cur_time) {
- last_time = cur_time;
+ /* Reread /etc/resolv.conf if it was modified.  */
+ struct stat sb;
+ stat("/etc/resolv.conf", &sb);
+ if ((difftime(resolv_conf_mtime, sb.st_mtime)) < 0) {
+ resolv_conf_mtime = sb.st_mtime;
  __close_nameservers(); /* force config reread */
  }
  }
@@ -969,6 +969,7 @@ void attribute_hidden __open_nameservers(void)
  goto sync;
 
  fp = fopen("/etc/resolv.conf", "r");
+#ifdef FALLBACK_TO_CONFIG_RESOLVCONF
  if (!fp) {
  /* If we do not have a pre-populated /etc/resolv.conf then
    try to use the one from /etc/config which exists on numerous
@@ -976,6 +977,7 @@ void attribute_hidden __open_nameservers(void)
    may be the only /etc dir that was mounted rw.  */
  fp = fopen("/etc/config/resolv.conf", "r");
  }
+#endif
 
  if (fp) {
  while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {

_______________________________________________
uClibc mailing list
uClibc@...
http://lists.busybox.net/mailman/listinfo/uclibc

Re: gethostbyname problem

by Denys Vlasenko-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tuesday 13 October 2009 19:11, Bernhard Reutner-Fischer wrote:

> On Tue, Oct 13, 2009 at 06:11:48AM -0700, Cuero Bugot wrote:
> >Hi all,
> >
> >We actually found the problem with gethostbyname on uClibc.
> >When we change the network interface, the /etc/resolv.conf is also and apparently the uClibc resolve code is not reloading the nameserver configuration files.
> >To fixe it we did a very simple patch (attached)  (against version uClibc 0.9.29).
>
> We moved to git. See http://git.uclibc.org/uClibc
> >
> >The idea is that if a ns lookup fails then the nameserver file is reloaded. I believe that the overhead of reloading the nameservers in case of ns lookup failure is really small.
>
> I'm not sure i understand what you say? Your scenario sounds (to me,
> correct me if i'm wrong) like:
> If resolv.conf changes then reload resolv.conf ¹)
>
> >The patch is a few line long in libc/inet/resolv.c file.
> >
> >I have seen that in head version of resolv.c has been refactored a little (which is a good thing), but this prb has not been taken care of. Instead there is a new thing (which I believe is actually not very usefull): the nameserver file is reloaded every 256 seconds.
>
> That's not too helpful either, yes. ¹)
> >
> >The reload on failure patch could be applied on head version.
>
> As mentioned above, svn isn't used anymore.
> >
> >Is anybody interested ? How can we go further ?
>
> Not terribly interrested (the resolver could need a complete rewrite
> against the SUSv4 requirements), but..
>
> Denys, apparently you added that rereading, got a better idea than
> the +60b below?

Perhaps I thought time() is cheaper than stat(), but
this patch will make us see new /etc/resolv.conf
at once -> better user experience. I like it.


+       static time_t resolv_conf_mtime;
...
+               struct stat sb;
+               stat("/etc/resolv.conf", &sb);
+               if ((difftime(resolv_conf_mtime, sb.st_mtime)) < 0) {

To use difftime here looks like overkill:

double difftime(time_t time1, time_t time0);

You don't need the difference. You only want to know whether it
has changed, right?



I propose using:

        static unsigned resolv_conf_mtime;
...
        if (resolv_conf_mtime != (unsigned)sb.st_mtime) < 0) {

I use "unsigned" in order to minimize statics - time_t is a long, and
there is no need to use 8 bytes on amd64 etc where 4 is quite enough.

We can explicitly use uint32_t there if you are concerned we'll
ever get arches with sizeof(int) > 4.
(Rob doesn't think we will. 640k should be enough for anyone).

Apart from that, looks ok.

--
vda
_______________________________________________
uClibc mailing list
uClibc@...
http://lists.busybox.net/mailman/listinfo/uclibc

Re: gethostbyname problem

by Bernhard Reutner-Fischer :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Oct 13, 2009 at 09:02:10PM +0200, Denys Vlasenko wrote:

>Perhaps I thought time() is cheaper than stat(), but

that's what i thought, yes :)

>this patch will make us see new /etc/resolv.conf
>at once -> better user experience. I like it.
>
>
>+       static time_t resolv_conf_mtime;
>...
>+               struct stat sb;
>+               stat("/etc/resolv.conf", &sb);
>+               if ((difftime(resolv_conf_mtime, sb.st_mtime)) < 0) {
>
>To use difftime here looks like overkill:
>
>double difftime(time_t time1, time_t time0);
>
>You don't need the difference. You only want to know whether it
>has changed, right?

erm, yes.
>
>
>
>I propose using:
>
>        static unsigned resolv_conf_mtime;
>...
>        if (resolv_conf_mtime != (unsigned)sb.st_mtime) < 0) {
s/) < 0//
>
>I use "unsigned" in order to minimize statics - time_t is a long, and
>there is no need to use 8 bytes on amd64 etc where 4 is quite enough.
>
>We can explicitly use uint32_t there if you are concerned we'll
>ever get arches with sizeof(int) > 4.

I'd go for time_t, just because i'm paranoid.

May i ask you to apply such a thing (with whatever type you think is
safe)? TIA!
cheers,
_______________________________________________
uClibc mailing list
uClibc@...
http://lists.busybox.net/mailman/listinfo/uclibc

Re: gethostbyname problem

by Bernhard Reutner-Fischer :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Oct 13, 2009 at 09:10:58PM +0200, Bernhard Reutner-Fischer wrote:

>On Tue, Oct 13, 2009 at 09:02:10PM +0200, Denys Vlasenko wrote:
>>I propose using:
>>
>>        static unsigned resolv_conf_mtime;
>>...
>>        if (resolv_conf_mtime != (unsigned)sb.st_mtime) < 0) {
>s/) < 0//
>>
>>I use "unsigned" in order to minimize statics - time_t is a long, and
>>there is no need to use 8 bytes on amd64 etc where 4 is quite enough.
>>
>>We can explicitly use uint32_t there if you are concerned we'll

Let's just store the least significant few bits (ought to be enough for
seeing if mtime changed).

thanks :)

>>ever get arches with sizeof(int) > 4.
>
>I'd go for time_t, just because i'm paranoid.
>
>May i ask you to apply such a thing (with whatever type you think is
>safe)? TIA!
>cheers,
_______________________________________________
uClibc mailing list
uClibc@...
http://lists.busybox.net/mailman/listinfo/uclibc

Re: gethostbyname problem

by Denys Vlasenko-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tuesday 13 October 2009 21:10, Bernhard Reutner-Fischer wrote:
> >We can explicitly use uint32_t there if you are concerned we'll
> >ever get arches with sizeof(int) > 4.
>
> I'd go for time_t, just because i'm paranoid.

Paranoid scenario is: you update resolv.conf exactly 2^N seconds
after it was last updated, and oh no, uclibc does not notice that.
N here is bit width of the variable.

I'd use uint32_t. 2^32 secs = 136 years.

> May i ask you to apply such a thing (with whatever type you think is
> safe)? TIA!

Done.

--
vda
_______________________________________________
uClibc mailing list
uClibc@...
http://lists.busybox.net/mailman/listinfo/uclibc

Re: gethostbyname problem

by Denys Vlasenko-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Oct 13, 2009 at 7:11 PM, Bernhard Reutner-Fischer
<rep.dot.nop@...> wrote:
> Not terribly interrested (the resolver could need a complete rewrite
> against the SUSv4 requirements), but..

I am willing to debug/fix resolver bugs since I spent some time
cleaning it up and know the code.

Please send resolver-related bugs my way (i.e. insert my email
in TO or CC so that I notice it).
--
vda
_______________________________________________
uClibc mailing list
uClibc@...
http://lists.busybox.net/mailman/listinfo/uclibc