aboutsummaryrefslogtreecommitdiff
path: root/src/inet.c
diff options
context:
space:
mode:
authorFlorian Zeitz <florob@babelmonkeys.de>2011-06-14 01:17:07 +0200
committerSam Roberts <vieuxtech@gmail.com>2012-04-11 13:33:34 -0700
commit923eef192925cae29223974dbf1addd59b4b0f28 (patch)
treefa8a9daf1b6acd5a7b9d0b6528d0aba8147ac8d0 /src/inet.c
parent5c33ef99977587dd9ae4e013d2d43aa8bf493ad1 (diff)
downloadluasocket-923eef192925cae29223974dbf1addd59b4b0f28.tar.gz
luasocket-923eef192925cae29223974dbf1addd59b4b0f28.tar.bz2
luasocket-923eef192925cae29223974dbf1addd59b4b0f28.zip
Rework binding IPv6 sockets by harmonizing it with the IPv4 variant
Diffstat (limited to 'src/inet.c')
-rw-r--r--src/inet.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/src/inet.c b/src/inet.c
index 21a97c9..95b7af3 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -56,7 +56,7 @@ static int inet_gethost(const char *address, struct hostent **hp) {
56 struct in_addr addr; 56 struct in_addr addr;
57 if (inet_aton(address, &addr)) 57 if (inet_aton(address, &addr))
58 return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp); 58 return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp);
59 else 59 else
60 return socket_gethostbyname(address, hp); 60 return socket_gethostbyname(address, hp);
61} 61}
62 62
@@ -66,7 +66,7 @@ static int inet_gethost(const char *address, struct hostent **hp) {
66\*-------------------------------------------------------------------------*/ 66\*-------------------------------------------------------------------------*/
67static int inet_global_tohostname(lua_State *L) { 67static int inet_global_tohostname(lua_State *L) {
68 const char *address = luaL_checkstring(L, 1); 68 const char *address = luaL_checkstring(L, 1);
69 struct hostent *hp = NULL; 69 struct hostent *hp = NULL;
70 int err = inet_gethost(address, &hp); 70 int err = inet_gethost(address, &hp);
71 if (err != IO_DONE) { 71 if (err != IO_DONE) {
72 lua_pushnil(L); 72 lua_pushnil(L);
@@ -85,7 +85,7 @@ static int inet_global_tohostname(lua_State *L) {
85static int inet_global_toip(lua_State *L) 85static int inet_global_toip(lua_State *L)
86{ 86{
87 const char *address = luaL_checkstring(L, 1); 87 const char *address = luaL_checkstring(L, 1);
88 struct hostent *hp = NULL; 88 struct hostent *hp = NULL;
89 int err = inet_gethost(address, &hp); 89 int err = inet_gethost(address, &hp);
90 if (err != IO_DONE) { 90 if (err != IO_DONE) {
91 lua_pushnil(L); 91 lua_pushnil(L);
@@ -136,7 +136,7 @@ static int inet_global_toip6(lua_State *L)
136 lua_settable(L, -3); 136 lua_settable(L, -3);
137 lua_settable(L, -3); 137 lua_settable(L, -3);
138 i++; 138 i++;
139 } 139 }
140 freeaddrinfo(resolved); 140 freeaddrinfo(resolved);
141 return 1; 141 return 1;
142} 142}
@@ -244,14 +244,14 @@ static void inet_pushresolved(lua_State *L, struct hostent *hp)
244/*-------------------------------------------------------------------------*\ 244/*-------------------------------------------------------------------------*\
245* Tries to create a new inet socket 245* Tries to create a new inet socket
246\*-------------------------------------------------------------------------*/ 246\*-------------------------------------------------------------------------*/
247const char *inet_trycreate(p_socket ps, int type) { 247const char *inet_trycreate(p_socket ps, int domain, int type) {
248 return socket_strerror(socket_create(ps, AF_INET, type, 0)); 248 return socket_strerror(socket_create(ps, domain, type, 0));
249} 249}
250 250
251/*-------------------------------------------------------------------------*\ 251/*-------------------------------------------------------------------------*\
252* Tries to connect to remote address (address, port) 252* Tries to connect to remote address (address, port)
253\*-------------------------------------------------------------------------*/ 253\*-------------------------------------------------------------------------*/
254const char *inet_tryconnect(p_socket ps, const char *address, 254const char *inet_tryconnect(p_socket ps, const char *address,
255 unsigned short port, p_timeout tm) 255 unsigned short port, p_timeout tm)
256{ 256{
257 struct sockaddr_in remote; 257 struct sockaddr_in remote;
@@ -276,25 +276,35 @@ const char *inet_tryconnect(p_socket ps, const char *address,
276/*-------------------------------------------------------------------------*\ 276/*-------------------------------------------------------------------------*\
277* Tries to bind socket to (address, port) 277* Tries to bind socket to (address, port)
278\*-------------------------------------------------------------------------*/ 278\*-------------------------------------------------------------------------*/
279const char *inet_trybind(p_socket ps, const char *address, unsigned short port) 279const char *inet_trybind(p_socket ps, const char *address, const char *serv,
280 struct addrinfo *bindhints)
280{ 281{
281 struct sockaddr_in local; 282 struct addrinfo *iterator = NULL, *resolved = NULL;
282 int err; 283 const char *err = NULL;
283 memset(&local, 0, sizeof(local)); 284 /* translate luasocket special values to C */
284 /* address is either wildcard or a valid ip address */ 285 if (strcmp(address, "*") == 0) address = NULL;
285 local.sin_addr.s_addr = htonl(INADDR_ANY); 286 if (!serv) serv = "0";
286 local.sin_port = htons(port); 287 /* try resolving */
287 local.sin_family = AF_INET; 288 err = socket_gaistrerror(getaddrinfo(address, serv,
288 if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) { 289 bindhints, &resolved));
289 struct hostent *hp = NULL; 290 if (err) {
290 struct in_addr **addr; 291 if (resolved) freeaddrinfo(resolved);
291 err = socket_gethostbyname(address, &hp); 292 return err;
292 if (err != IO_DONE) return socket_hoststrerror(err);
293 addr = (struct in_addr **) hp->h_addr_list;
294 memcpy(&local.sin_addr, *addr, sizeof(struct in_addr));
295 } 293 }
296 err = socket_bind(ps, (SA *) &local, sizeof(local)); 294 /* iterate over resolved addresses until one is good */
297 return socket_strerror(err); 295 for (iterator = resolved; iterator; iterator = iterator->ai_next) {
296 /* try binding to local address */
297 err = socket_strerror(socket_bind(ps,
298 (SA *) iterator->ai_addr,
299 iterator->ai_addrlen));
300 /* if faiiled, we try the next one */
301 if (err != NULL) socket_destroy(ps);
302 /* if success, we abort loop */
303 else break;
304 }
305 /* cleanup and return error */
306 freeaddrinfo(resolved);
307 return err;
298} 308}
299 309
300/*-------------------------------------------------------------------------*\ 310/*-------------------------------------------------------------------------*\