diff options
author | Florian Zeitz <florob@babelmonkeys.de> | 2011-06-15 00:51:02 +0200 |
---|---|---|
committer | Sam Roberts <vieuxtech@gmail.com> | 2012-04-11 13:33:34 -0700 |
commit | 594f826aa129f8b497c37fe08429eff5651dac9d (patch) | |
tree | 85b80f9cde7bae3b32742c93f127de87b9e4dc98 /src/inet.c | |
parent | 5874d47f550a2f278ca35ccda96d49ccf0ca7e36 (diff) | |
download | luasocket-594f826aa129f8b497c37fe08429eff5651dac9d.tar.gz luasocket-594f826aa129f8b497c37fe08429eff5651dac9d.tar.bz2 luasocket-594f826aa129f8b497c37fe08429eff5651dac9d.zip |
Add support for connecting to IPv6 hosts
Diffstat (limited to 'src/inet.c')
-rw-r--r-- | src/inet.c | 42 |
1 files changed, 24 insertions, 18 deletions
@@ -252,25 +252,31 @@ const char *inet_trycreate(p_socket ps, int domain, int type) { | |||
252 | * Tries to connect to remote address (address, port) | 252 | * Tries to connect to remote address (address, port) |
253 | \*-------------------------------------------------------------------------*/ | 253 | \*-------------------------------------------------------------------------*/ |
254 | const char *inet_tryconnect(p_socket ps, const char *address, | 254 | const char *inet_tryconnect(p_socket ps, const char *address, |
255 | unsigned short port, p_timeout tm) | 255 | const char *serv, p_timeout tm, struct addrinfo *connecthints) |
256 | { | 256 | { |
257 | struct sockaddr_in remote; | 257 | struct addrinfo *iterator = NULL, *resolved = NULL; |
258 | int err; | 258 | const char *err = NULL; |
259 | memset(&remote, 0, sizeof(remote)); | 259 | /* try resolving */ |
260 | remote.sin_family = AF_INET; | 260 | err = socket_gaistrerror(getaddrinfo(address, serv, |
261 | remote.sin_port = htons(port); | 261 | connecthints, &resolved)); |
262 | if (strcmp(address, "*")) { | 262 | if (err != NULL) { |
263 | if (!inet_aton(address, &remote.sin_addr)) { | 263 | if (resolved) freeaddrinfo(resolved); |
264 | struct hostent *hp = NULL; | 264 | return err; |
265 | struct in_addr **addr; | 265 | } |
266 | err = socket_gethostbyname(address, &hp); | 266 | /* iterate over all returned addresses trying to connect */ |
267 | if (err != IO_DONE) return socket_hoststrerror(err); | 267 | for (iterator = resolved; iterator; iterator = iterator->ai_next) { |
268 | addr = (struct in_addr **) hp->h_addr_list; | 268 | timeout_markstart(tm); |
269 | memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr)); | 269 | /* try connecting to remote address */ |
270 | } | 270 | err = socket_strerror(socket_connect(ps, |
271 | } else remote.sin_family = AF_UNSPEC; | 271 | (SA *) iterator->ai_addr, |
272 | err = socket_connect(ps, (SA *) &remote, sizeof(remote), tm); | 272 | iterator->ai_addrlen, tm)); |
273 | return socket_strerror(err); | 273 | /* if success, break out of loop */ |
274 | if (err == NULL) break; | ||
275 | } | ||
276 | |||
277 | freeaddrinfo(resolved); | ||
278 | /* here, if err is set, we failed */ | ||
279 | return err; | ||
274 | } | 280 | } |
275 | 281 | ||
276 | /*-------------------------------------------------------------------------*\ | 282 | /*-------------------------------------------------------------------------*\ |