Fwd: getaddrinfo not working on Android?

1,747 views
Skip to first unread message

Carlos A. M. dos Santos

unread,
May 2, 2009, 8:06:10 AM5/2/09
to andro...@googlegroups.com
No answer, so far. Forwarding to -ndk, where it seems to belong.


---------- Forwarded message ----------
From: Carlos A. M. dos Santos <unix...@gmail.com>
Date: Thu, Apr 30, 2009 at 5:39 PM
Subject: getaddrinfo not working on Android?
To: android-...@googlegroups.com


Hello,

I have a C++ code containing this:

       char* hostname;
...
       struct addrinfo hints;
       struct addrinfo *addi;
       ::memset(&hints, 0, sizeof(hints));
       hints.ai_family = AF_UNSPEC;
       hints.ai_socktype = SOCK_STREAM;
       hints.ai_protocol = IPPROTO_TCP;
       int status = ::getaddrinfo(hostname, "9999", NULL, &addi);
       if (status != 0) {
           fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(status));
           return 1;
       }

If I run it on the emulator I ever get the following message:

      "getaddrinfo failed: servname not supported for ai_socktype"

If I run a similar code on Linux it succeeds. I noticed that Dalvik
uses gethostbyname (in
dalvik/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp)
instead of getaddrinfo.

Is getaddrinfo purposefully not working on Android?

Thanks in advance for your help.

--
My preferred quotation of Robert Louis Stevenson is "You cannot
make an omelette without breaking eggs". Not because I like the
omelettes, but because I like the sound of eggs being broken.

Carlos A. M. dos Santos

unread,
May 2, 2009, 1:19:10 PM5/2/09
to android-...@googlegroups.com, andro...@googlegroups.com
On Thu, Apr 30, 2009 at 5:39 PM, Carlos A. M. dos Santos
<unix...@gmail.com> wrote:
> Hello,
>
> I have a C++ code containing this:
>
>        char* hostname;
> ...
>        struct addrinfo hints;
>        struct addrinfo *addi;
>        ::memset(&hints, 0, sizeof(hints));
>        hints.ai_family = AF_UNSPEC;
>        hints.ai_socktype = SOCK_STREAM;
>        hints.ai_protocol = IPPROTO_TCP;
>        int status = ::getaddrinfo(hostname, "9999", NULL, &addi);
>        if (status != 0) {
>            fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(status));
>            return 1;
>        }
>
> If I run it on the emulator I ever get the following message:
>
>       "getaddrinfo failed: servname not supported for ai_socktype"
>
> If I run a similar code on Linux it succeeds. I noticed that Dalvik
> uses gethostbyname (in
> dalvik/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp)
> instead of getaddrinfo.
>
> Is getaddrinfo purposefully not working on Android?

I just realized that I pasted too many lines. The presence of the
"hints" variable in the code above became misleading. It is important
to point out that the error does not happen if I pass the hints to
getaddrinfo, like this:

struct addrinfo hints;
struct addrinfo *addi;
::memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

int status = ::getaddrinfo(hostname, "9999", &hints, &addi);

I'm intrigued about the different behaviors of Linux and Android when
the hint parameter is NULL. Which one is correct?

David Turner

unread,
May 2, 2009, 1:41:00 PM5/2/09
to andro...@googlegroups.com, android-...@googlegroups.com
Hello,

this certainly looks like a bug, I will take a look at it. In the meantime, please use a hint to work-around it.
Regards

David Turner

unread,
May 5, 2009, 9:23:55 AM5/5/09
to andro...@googlegroups.com, android-...@googlegroups.com
ok, I reproduced the issue and isolated it in the getaddrinfo() implementation (which comes straight from BSD).
Technically, this is not a bug because POSIX states that:

If hints is a null pointer, the behavior shall be as if it referred to a structure containing the value zero for
the ai_flags, ai_socktype, and ai_protocol fields, and AF_UNSPEC for the ai_family field.

the key thing here is that ai_socktype will be set to 0, which on Linux doesn't correspond to any of SOCK_RAW,
SOCK_STREAM or SOCK_DGRAM; and the getaddrinfo() implementation will reject any numerical value passed
in the "servicename" parameter except for SOCK_STREAM or SOCK_DGRAM.

I checked the latest OpenBSD sources and they seem the belong exactly like that too, which probably means that
your code is not, technically speaking, portable.

This is however probably annoying and I will modify the code for the next platform release.
In the meantime, just use a hint :-)

Carlos A. M. dos Santos

unread,
May 5, 2009, 5:05:48 PM5/5/09
to andro...@googlegroups.com, android-...@googlegroups.com
On Tue, May 5, 2009 at 9:23 AM, David Turner <di...@android.com> wrote:
> ok, I reproduced the issue and isolated it in the getaddrinfo()
> implementation (which comes straight from BSD).
> Technically, this is not a bug because POSIX states that:
>
> If hints is a null pointer, the behavior shall be as if it referred to a
> structure containing the value zero for
> the ai_flags, ai_socktype, and ai_protocol fields, and AF_UNSPEC for the
> ai_family field.
>
> the key thing here is that ai_socktype will be set to 0, which on Linux
> doesn't correspond to any of SOCK_RAW,
> SOCK_STREAM or SOCK_DGRAM; and the getaddrinfo() implementation will reject
> any numerical value passed
> in the "servicename" parameter except for SOCK_STREAM or SOCK_DGRAM.
>
> I checked the latest OpenBSD sources and they seem the belong exactly like
> that too, which probably means that
> your code is not, technically speaking, portable.
>
> This is however probably annoying and I will modify the code for the next
> platform release.
> In the meantime, just use a hint :-)

Ok, thanks for your help!

> On Sat, May 2, 2009 at 7:41 PM, David Turner <di...@android.com> wrote:
>>
>> Hello,
>>
>> this certainly looks like a bug, I will take a look at it. In the
>> meantime, please use a hint to work-around it.
>> Regards
>>
>> On Sat, May 2, 2009 at 7:19 PM, Carlos A. M. dos Santos

---8<--

Reply all
Reply to author
Forward
0 new messages