Skip to content

Commit 95101ce

Browse files
committed
Accept AI_ADDRCONFIG in getaddrinfo()
Fixes #71
1 parent f8b05f4 commit 95101ce

File tree

1 file changed

+37
-5
lines changed

1 file changed

+37
-5
lines changed

socket/getaddrinfo.c

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <stdlib.h>
99
#include "sockets_global.h"
1010
#include <arpa/inet.h>
11+
#include <net/if.h>
12+
#include <ifaddrs.h>
1113

1214
/*
1315
* Converts the current herrno error value into an EAI_* error code.
@@ -90,6 +92,31 @@ static struct addrinfo *makeipv4info(int type, int proto, uint32_t ip, uint16_t
9092
}
9193

9294

95+
/*
96+
* AI_ADDRCONFIG check: Build a mask containing a bit set for each address
97+
* family configured in the system.
98+
*
99+
*/
100+
static int addrconfig(uint32_t *mask)
101+
{
102+
struct ifaddrs *ifaddrs, *ifa;
103+
104+
if (getifaddrs(&ifaddrs) < 0)
105+
return -1;
106+
107+
*mask = 0;
108+
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next)
109+
if (ifa->ifa_addr && (ifa->ifa_flags & IFF_UP))
110+
{
111+
if (ifa->ifa_addr->sa_family < ((unsigned short)(sizeof(*mask) * 8)))
112+
*mask |= (uint32_t)1 << ifa->ifa_addr->sa_family;
113+
}
114+
115+
freeifaddrs(ifaddrs);
116+
return 0;
117+
}
118+
119+
93120
/*
94121
* getaddrinfo() non-thread-safe IPv4-only implementation
95122
* Address-family-independent hostname to address resolution.
@@ -107,19 +134,23 @@ int __getaddrinfo(const char *node, const char *service, const struct addrinfo *
107134
int protocol = 0;
108135
int flags = 0;
109136
const char *name = NULL;
137+
uint32_t mask = (uint32_t)~0UL;
110138

111139
*res = NULL;
112140

113141
if (hints != NULL)
114142
{
115143
flags = hints->ai_flags;
116144

117-
if (flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST))
145+
if (flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG))
118146
return EAI_BADFLAGS;
119147
/* only accept AF_INET and AF_UNSPEC */
120148
if (hints->ai_family && (hints->ai_family != AF_INET))
121149
return EAI_FAMILY;
122150

151+
if ((hints->ai_flags & AI_ADDRCONFIG) != 0 && addrconfig(&mask) < 0)
152+
return EAI_FAIL;
153+
123154
/* protocol sanity check */
124155
switch (hints->ai_socktype)
125156
{
@@ -184,15 +215,16 @@ int __getaddrinfo(const char *node, const char *service, const struct addrinfo *
184215
struct servent *sp;
185216

186217
d = strtoul(service, &end, 0);
187-
if (!end[0]) {
188-
if (d > 65535)
189-
return (EAI_SERVICE);
218+
if (!end[0])
219+
{
220+
if (d > 65535UL)
221+
return EAI_SERVICE;
190222
port = htons((unsigned short) d);
191223
} else
192224
{
193225
sp = getservbyname(service, NULL);
194226
if (sp == NULL)
195-
return (EAI_SERVICE);
227+
return EAI_SERVICE;
196228
port = sp->s_port;
197229
}
198230
}

0 commit comments

Comments
 (0)