Thread overview
Using gethostbyname_r instead of gethostbyname in std.socket
Oct 07, 2016
MWumpusZ
Oct 08, 2016
Jakob Ovrum
Oct 10, 2016
MWumpusZ
October 07, 2016
We are currently using phobos from http://downloads.dlang.org/releases/2016/dmd.2.071.0.linux.zip

Phobos' InternetAddress contained therein uses gethostbyname and not gethostbyname_r; std.socket imports core.sys.posix.netdb, which only makes gethostbyname available.

gethostbyname_r would be made available by importing std.c.linux.socket, but this is marked as deprecated in favour of core.sys.posix.BLAH

The use of gethostbyname is a problem for us because, even though std.socket synchronises access to the function, we are using a third party (non-D) library in our application which also uses gethostbyname, and of course that library doesn't care about the synchronisation in std.socket.


Is there a reason why gethostbyname_r isn't usually used?
Even for those environments which don't have it, version(linux) (or whatever) in core.sys.posix.netdb should be able to deal with that easily, shouldn't it?
October 08, 2016
On Friday, 7 October 2016 at 08:38:24 UTC, MWumpusZ wrote:
> We are currently using phobos from http://downloads.dlang.org/releases/2016/dmd.2.071.0.linux.zip
>
> Phobos' InternetAddress contained therein uses gethostbyname and not gethostbyname_r; std.socket imports core.sys.posix.netdb, which only makes gethostbyname available.
>
> gethostbyname_r would be made available by importing std.c.linux.socket, but this is marked as deprecated in favour of core.sys.posix.BLAH
>
> The use of gethostbyname is a problem for us because, even though std.socket synchronises access to the function, we are using a third party (non-D) library in our application which also uses gethostbyname, and of course that library doesn't care about the synchronisation in std.socket.
>
>
> Is there a reason why gethostbyname_r isn't usually used?
> Even for those environments which don't have it, version(linux) (or whatever) in core.sys.posix.netdb should be able to deal with that easily, shouldn't it?

gethostbyname_r is a GNU extension and not standard POSIX. That means it's only available on GNU/Linux systems that additionally don't use an alternative libc. gettaddrinfo is a more recent standard reentrant function with more functionality.

InternetHost.getHostByName uses gethostbyname_r if visible and otherwise falls back to gethostbyname. There doesn't appear to be a condition in which gethostbyname_r would be visible, probably as a result of moving from std.c.linux to core.sys.posix. InternetHost.getHostByName is public so it can be used directly, but apart from that it appears to be used internally twice:

  1) in getAddress when getaddrinfo is not available.
  1) always used in the constructor of InternetAddress.

I guess #2 is the issue you're having. The doc for InternetAddress does say it uses InternetHost internally, and the docs do recommend getAddress over using Internet{Host, Address} directly, but maybe InternetHost.getHostByName should use getAddress internally to benefit from getaddrinfo. If not, it should probably at least warn about not being reentrant.

I don't know what OS still doesn't have getaddrinfo. Ideally we could deprecate all these bad legacy types and functions.
October 10, 2016
On Saturday, 8 October 2016 at 13:46:28 UTC, Jakob Ovrum wrote:
...
> The doc for InternetAddress does say it uses InternetHost internally, and the docs do recommend getAddress over using Internet{Host, Address} directly,

I have no idea why we don't use std.socket.getAddress; I'll look into that.  If switching over is viable (which I imagine it is) and sufficient, then that sounds like a great solution short term.

> but maybe InternetHost.getHostByName should use getAddress internally to benefit from getaddrinfo.

Sounds good :)  I can't comment on what wider impact that might have though.

> If not, it should probably at least warn about not being reentrant.

It is "kind of" reentrant - it has synchronisation around the gethostbyname call.  Things fall apart when gethostbyname is accessed directly, e.g. by a third party library, as is the case in our application.