Skip to content

Commit

Permalink
Fix gethostbyaddr for IPv6 arguments, remove mutable state
Browse files Browse the repository at this point in the history
caml_gethostbyaddr always calls gethostbyaddr with address type AF_INET,
i.e., IPv4, even when its argument is an IPv6 address. This commit also
removes a file-local mutable variable for the sake of domain safety.
  • Loading branch information
OlivierNicole committed Jul 28, 2022
1 parent 13f23d5 commit 0f0ac10
Showing 1 changed file with 30 additions and 15 deletions.
45 changes: 30 additions & 15 deletions otherlibs/unix/gethost.c
Expand Up @@ -36,22 +36,22 @@
#define GETHOSTBYNAME_IS_REENTRANT 1
#endif

static int entry_h_length;

static value alloc_one_addr(char const *a)
static value alloc_one_addr_ipv4(char const *a)
{
struct in_addr addr;
#ifdef HAS_IPV6
struct in6_addr addr6;
if (entry_h_length == 16) {
memmove(&addr6, a, 16);
return caml_unix_alloc_inet6_addr(&addr6);
}
#endif
memmove (&addr, a, 4);
return caml_unix_alloc_inet_addr(&addr);
}

#ifdef HAS_IPV6
static value alloc_one_addr_ipv6(char const *a)
{
struct in6_addr addr6;
memmove(&addr6, a, 16);
return caml_unix_alloc_inet6_addr(&addr6);
}
#endif

static value alloc_host_entry(struct hostent *entry)
{
CAMLparam0();
Expand All @@ -65,9 +65,10 @@ static value alloc_host_entry(struct hostent *entry)
aliases = caml_copy_string_array((const char**)entry->h_aliases);
else
aliases = Atom(0);
entry_h_length = entry->h_length;
addr_list =
caml_alloc_array(alloc_one_addr, (const char**)entry->h_addr_list);
caml_alloc_array((entry->h_addrtype == AF_INET6) ?
alloc_one_addr_ipv6 : alloc_one_addr_ipv4,
(const char**)entry->h_addr_list);
res = caml_alloc_small(4, 0);
Field(res, 0) = name;
Field(res, 1) = aliases;
Expand All @@ -84,28 +85,42 @@ CAMLprim value caml_unix_gethostbyaddr(value a)
{
struct in_addr adr = GET_INET_ADDR(a);
struct hostent * hp;
int addr_type;
socklen_t addr_len;
#if HAS_IPV6
if (caml_string_length(a) == 16) {
addr_type = AF_INET6;
addr_len = 16;
}
else {
addr_type = AF_INET;
addr_len = 4;
}
#else
addr_type = AF_INET;
#endif
#if HAS_GETHOSTBYADDR_R == 7
struct hostent h;
char buffer[NETDB_BUFFER_SIZE];
int h_errnop;
caml_enter_blocking_section();
hp = gethostbyaddr_r((char *) &adr, 4, AF_INET,
hp = gethostbyaddr_r((char *) &adr, addr_len, addr_type,
&h, buffer, sizeof(buffer), &h_errnop);
caml_leave_blocking_section();
#elif HAS_GETHOSTBYADDR_R == 8
struct hostent h;
char buffer[NETDB_BUFFER_SIZE];
int h_errnop, rc;
caml_enter_blocking_section();
rc = gethostbyaddr_r((char *) &adr, 4, AF_INET,
rc = gethostbyaddr_r((char *) &adr, addr_len, addr_type,
&h, buffer, sizeof(buffer), &hp, &h_errnop);
caml_leave_blocking_section();
if (rc != 0) hp = NULL;
#else
#ifdef GETHOSTBYADDR_IS_REENTRANT
caml_enter_blocking_section();
#endif
hp = gethostbyaddr((char *) &adr, 4, AF_INET);
hp = gethostbyaddr((char *) &adr, addr_type, addr_type);
#ifdef GETHOSTBYADDR_IS_REENTRANT
caml_leave_blocking_section();
#endif
Expand Down

0 comments on commit 0f0ac10

Please sign in to comment.