aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlorian Zeitz <florob@babelmonkeys.de>2011-06-15 00:51:02 +0200
committerSam Roberts <vieuxtech@gmail.com>2012-04-11 13:33:34 -0700
commit594f826aa129f8b497c37fe08429eff5651dac9d (patch)
tree85b80f9cde7bae3b32742c93f127de87b9e4dc98 /src
parent5874d47f550a2f278ca35ccda96d49ccf0ca7e36 (diff)
downloadluasocket-594f826aa129f8b497c37fe08429eff5651dac9d.tar.gz
luasocket-594f826aa129f8b497c37fe08429eff5651dac9d.tar.bz2
luasocket-594f826aa129f8b497c37fe08429eff5651dac9d.zip
Add support for connecting to IPv6 hosts
Diffstat (limited to 'src')
-rw-r--r--src/inet.c42
-rw-r--r--src/inet.h4
-rw-r--r--src/socket.lua10
-rw-r--r--src/tcp.c52
-rw-r--r--src/udp.c37
5 files changed, 86 insertions, 59 deletions
diff --git a/src/inet.c b/src/inet.c
index 962acec..ecec363 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -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\*-------------------------------------------------------------------------*/
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 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/*-------------------------------------------------------------------------*\
diff --git a/src/inet.h b/src/inet.h
index e008844..0f32ff1 100644
--- a/src/inet.h
+++ b/src/inet.h
@@ -25,8 +25,8 @@
25int inet_open(lua_State *L); 25int inet_open(lua_State *L);
26 26
27const char *inet_trycreate(p_socket ps, int domain, int type); 27const char *inet_trycreate(p_socket ps, int domain, int type);
28const char *inet_tryconnect(p_socket ps, const char *address, 28const char *inet_tryconnect(p_socket ps, const char *address,
29 unsigned short port, p_timeout tm); 29 const char *serv, p_timeout tm, struct addrinfo *connecthints);
30const char *inet_trybind(p_socket ps, const char *address, const char *serv, 30const char *inet_trybind(p_socket ps, const char *address, const char *serv,
31 struct addrinfo *bindhints); 31 struct addrinfo *bindhints);
32 32
diff --git a/src/socket.lua b/src/socket.lua
index 7a77fbc..734da3c 100644
--- a/src/socket.lua
+++ b/src/socket.lua
@@ -17,7 +17,15 @@ module("socket")
17-- Exported auxiliar functions 17-- Exported auxiliar functions
18----------------------------------------------------------------------------- 18-----------------------------------------------------------------------------
19function connect(address, port, laddress, lport) 19function connect(address, port, laddress, lport)
20 local sock, err = socket.tcp() 20 if address == "*" then address = "0.0.0.0" end
21 local addrinfo, err = socket.dns.getaddrinfo(address);
22 if not addrinfo then return nil, err end
23 local sock, err;
24 if addrinfo[1].family == "inet" then
25 sock, err = socket.tcp()
26 else
27 sock, err = socket.tcp6()
28 end
21 if not sock then return nil, err end 29 if not sock then return nil, err end
22 if laddress then 30 if laddress then
23 local res, err = sock:bind(laddress, lport, -1) 31 local res, err = sock:bind(laddress, lport, -1)
diff --git a/src/tcp.c b/src/tcp.c
index 4f5eea9..b069136 100644
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -1,10 +1,10 @@
1/*=========================================================================*\ 1/*=========================================================================*\
2* TCP object 2* TCP object
3* LuaSocket toolkit 3* LuaSocket toolkit
4* 4*
5* RCS ID: $Id: tcp.c,v 1.42 2009/05/27 09:31:35 diego Exp $ 5* RCS ID: $Id: tcp.c,v 1.42 2009/05/27 09:31:35 diego Exp $
6\*=========================================================================*/ 6\*=========================================================================*/
7#include <string.h> 7#include <string.h>
8 8
9#include "lua.h" 9#include "lua.h"
10#include "lauxlib.h" 10#include "lauxlib.h"
@@ -97,7 +97,7 @@ int tcp_open(lua_State *L)
97 auxiliar_add2group(L, "tcp{client}", "tcp{any}"); 97 auxiliar_add2group(L, "tcp{client}", "tcp{any}");
98 auxiliar_add2group(L, "tcp{server}", "tcp{any}"); 98 auxiliar_add2group(L, "tcp{server}", "tcp{any}");
99 /* define library functions */ 99 /* define library functions */
100 luaL_openlib(L, NULL, func, 0); 100 luaL_openlib(L, NULL, func, 0);
101 return 0; 101 return 0;
102} 102}
103 103
@@ -150,7 +150,7 @@ static int meth_getfd(lua_State *L)
150static int meth_setfd(lua_State *L) 150static int meth_setfd(lua_State *L)
151{ 151{
152 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); 152 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
153 tcp->sock = (t_socket) luaL_checknumber(L, 2); 153 tcp->sock = (t_socket) luaL_checknumber(L, 2);
154 return 0; 154 return 0;
155} 155}
156 156
@@ -162,8 +162,8 @@ static int meth_dirty(lua_State *L)
162} 162}
163 163
164/*-------------------------------------------------------------------------*\ 164/*-------------------------------------------------------------------------*\
165* Waits for and returns a client object attempting connection to the 165* Waits for and returns a client object attempting connection to the
166* server object 166* server object
167\*-------------------------------------------------------------------------*/ 167\*-------------------------------------------------------------------------*/
168static int meth_accept(lua_State *L) 168static int meth_accept(lua_State *L)
169{ 169{
@@ -178,20 +178,20 @@ static int meth_accept(lua_State *L)
178 /* initialize structure fields */ 178 /* initialize structure fields */
179 socket_setnonblocking(&sock); 179 socket_setnonblocking(&sock);
180 clnt->sock = sock; 180 clnt->sock = sock;
181 io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, 181 io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv,
182 (p_error) socket_ioerror, &clnt->sock); 182 (p_error) socket_ioerror, &clnt->sock);
183 timeout_init(&clnt->tm, -1, -1); 183 timeout_init(&clnt->tm, -1, -1);
184 buffer_init(&clnt->buf, &clnt->io, &clnt->tm); 184 buffer_init(&clnt->buf, &clnt->io, &clnt->tm);
185 return 1; 185 return 1;
186 } else { 186 } else {
187 lua_pushnil(L); 187 lua_pushnil(L);
188 lua_pushstring(L, socket_strerror(err)); 188 lua_pushstring(L, socket_strerror(err));
189 return 2; 189 return 2;
190 } 190 }
191} 191}
192 192
193/*-------------------------------------------------------------------------*\ 193/*-------------------------------------------------------------------------*\
194* Binds an object to an address 194* Binds an object to an address
195\*-------------------------------------------------------------------------*/ 195\*-------------------------------------------------------------------------*/
196static int meth_bind(lua_State *L) 196static int meth_bind(lua_State *L)
197{ 197{
@@ -219,12 +219,18 @@ static int meth_bind(lua_State *L)
219\*-------------------------------------------------------------------------*/ 219\*-------------------------------------------------------------------------*/
220static int meth_connect(lua_State *L) 220static int meth_connect(lua_State *L)
221{ 221{
222
223 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); 222 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
224 const char *address = luaL_checkstring(L, 2); 223 const char *address = luaL_checkstring(L, 2);
225 unsigned short port = (unsigned short) luaL_checknumber(L, 3); 224 const char *port = luaL_checkstring(L, 3);
226 p_timeout tm = timeout_markstart(&tcp->tm); 225 struct addrinfo connecthints;
227 const char *err = inet_tryconnect(&tcp->sock, address, port, tm); 226 const char *err;
227 memset(&connecthints, 0, sizeof(connecthints));
228 connecthints.ai_socktype = SOCK_STREAM;
229 /* make sure we try to connect only to the same family */
230 connecthints.ai_family = tcp->domain;
231 timeout_markstart(&tcp->tm);
232 err = inet_tryconnect(&tcp->sock, address, port,
233 &tcp->tm, &connecthints);
228 /* have to set the class even if it failed due to non-blocking connects */ 234 /* have to set the class even if it failed due to non-blocking connects */
229 auxiliar_setclass(L, "tcp{client}", 1); 235 auxiliar_setclass(L, "tcp{client}", 1);
230 if (err) { 236 if (err) {
@@ -237,7 +243,7 @@ static int meth_connect(lua_State *L)
237} 243}
238 244
239/*-------------------------------------------------------------------------*\ 245/*-------------------------------------------------------------------------*\
240* Closes socket used by object 246* Closes socket used by object
241\*-------------------------------------------------------------------------*/ 247\*-------------------------------------------------------------------------*/
242static int meth_close(lua_State *L) 248static int meth_close(lua_State *L)
243{ 249{
@@ -322,7 +328,7 @@ static int meth_settimeout(lua_State *L)
322* Library functions 328* Library functions
323\*=========================================================================*/ 329\*=========================================================================*/
324/*-------------------------------------------------------------------------*\ 330/*-------------------------------------------------------------------------*\
325* Creates a master tcp object 331* Creates a master tcp object
326\*-------------------------------------------------------------------------*/ 332\*-------------------------------------------------------------------------*/
327static int tcp_create(lua_State *L, int domain) { 333static int tcp_create(lua_State *L, int domain) {
328 t_socket sock; 334 t_socket sock;
@@ -341,7 +347,7 @@ static int tcp_create(lua_State *L, int domain) {
341 (void *)&yes, sizeof(yes)); 347 (void *)&yes, sizeof(yes));
342 } 348 }
343 tcp->sock = sock; 349 tcp->sock = sock;
344 io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, 350 io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
345 (p_error) socket_ioerror, &tcp->sock); 351 (p_error) socket_ioerror, &tcp->sock);
346 timeout_init(&tcp->tm, -1, -1); 352 timeout_init(&tcp->tm, -1, -1);
347 buffer_init(&tcp->buf, &tcp->io, &tcp->tm); 353 buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
@@ -367,19 +373,19 @@ static const char *tryconnect6(const char *remoteaddr, const char *remoteserv,
367 struct addrinfo *iterator = NULL, *resolved = NULL; 373 struct addrinfo *iterator = NULL, *resolved = NULL;
368 const char *err = NULL; 374 const char *err = NULL;
369 /* try resolving */ 375 /* try resolving */
370 err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv, 376 err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv,
371 connecthints, &resolved)); 377 connecthints, &resolved));
372 if (err != NULL) { 378 if (err != NULL) {
373 if (resolved) freeaddrinfo(resolved); 379 if (resolved) freeaddrinfo(resolved);
374 return err; 380 return err;
375 } 381 }
376 /* iterate over all returned addresses trying to connect */ 382 /* iterate over all returned addresses trying to connect */
377 for (iterator = resolved; iterator; iterator = iterator->ai_next) { 383 for (iterator = resolved; iterator; iterator = iterator->ai_next) {
378 p_timeout tm = timeout_markstart(&tcp->tm); 384 p_timeout tm = timeout_markstart(&tcp->tm);
379 /* create new socket if one wasn't created by the bind stage */ 385 /* create new socket if one wasn't created by the bind stage */
380 if (tcp->sock == SOCKET_INVALID) { 386 if (tcp->sock == SOCKET_INVALID) {
381 err = socket_strerror(socket_create(&tcp->sock, 387 err = socket_strerror(socket_create(&tcp->sock,
382 iterator->ai_family, iterator->ai_socktype, 388 iterator->ai_family, iterator->ai_socktype,
383 iterator->ai_protocol)); 389 iterator->ai_protocol));
384 if (err != NULL) { 390 if (err != NULL) {
385 freeaddrinfo(resolved); 391 freeaddrinfo(resolved);
@@ -389,7 +395,7 @@ static const char *tryconnect6(const char *remoteaddr, const char *remoteserv,
389 socket_setnonblocking(&tcp->sock); 395 socket_setnonblocking(&tcp->sock);
390 } 396 }
391 /* finally try connecting to remote address */ 397 /* finally try connecting to remote address */
392 err = socket_strerror(socket_connect(&tcp->sock, 398 err = socket_strerror(socket_connect(&tcp->sock,
393 (SA *) iterator->ai_addr, 399 (SA *) iterator->ai_addr,
394 iterator->ai_addrlen, tm)); 400 iterator->ai_addrlen, tm));
395 /* if success, break out of loop */ 401 /* if success, break out of loop */
@@ -410,7 +416,7 @@ static int global_connect6(lua_State *L) {
410 struct addrinfo bindhints, connecthints; 416 struct addrinfo bindhints, connecthints;
411 const char *err = NULL; 417 const char *err = NULL;
412 /* initialize tcp structure */ 418 /* initialize tcp structure */
413 io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, 419 io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
414 (p_error) socket_ioerror, &tcp->sock); 420 (p_error) socket_ioerror, &tcp->sock);
415 timeout_init(&tcp->tm, -1, -1); 421 timeout_init(&tcp->tm, -1, -1);
416 buffer_init(&tcp->buf, &tcp->io, &tcp->tm); 422 buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
@@ -432,7 +438,7 @@ static int global_connect6(lua_State *L) {
432 memset(&connecthints, 0, sizeof(connecthints)); 438 memset(&connecthints, 0, sizeof(connecthints));
433 connecthints.ai_socktype = SOCK_STREAM; 439 connecthints.ai_socktype = SOCK_STREAM;
434 /* make sure we try to connect only to the same family */ 440 /* make sure we try to connect only to the same family */
435 connecthints.ai_family = bindhints.ai_family; 441 connecthints.ai_family = bindhints.ai_family;
436 err = tryconnect6(remoteaddr, remoteserv, &connecthints, tcp); 442 err = tryconnect6(remoteaddr, remoteserv, &connecthints, tcp);
437 if (err) { 443 if (err) {
438 socket_destroy(&tcp->sock); 444 socket_destroy(&tcp->sock);
diff --git a/src/udp.c b/src/udp.c
index fcfbbb7..cc04fc8 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -1,10 +1,10 @@
1/*=========================================================================*\ 1/*=========================================================================*\
2* UDP object 2* UDP object
3* LuaSocket toolkit 3* LuaSocket toolkit
4* 4*
5* RCS ID: $Id: udp.c,v 1.30 2009/05/27 09:31:35 diego Exp $ 5* RCS ID: $Id: udp.c,v 1.30 2009/05/27 09:31:35 diego Exp $
6\*=========================================================================*/ 6\*=========================================================================*/
7#include <string.h> 7#include <string.h>
8 8
9#include "lua.h" 9#include "lua.h"
10#include "lauxlib.h" 10#include "lauxlib.h"
@@ -18,10 +18,10 @@
18/* min and max macros */ 18/* min and max macros */
19#ifndef MIN 19#ifndef MIN
20#define MIN(x, y) ((x) < (y) ? x : y) 20#define MIN(x, y) ((x) < (y) ? x : y)
21#endif 21#endif
22#ifndef MAX 22#ifndef MAX
23#define MAX(x, y) ((x) > (y) ? x : y) 23#define MAX(x, y) ((x) > (y) ? x : y)
24#endif 24#endif
25 25
26/*=========================================================================*\ 26/*=========================================================================*\
27* Internal function prototypes 27* Internal function prototypes
@@ -109,7 +109,7 @@ int udp_open(lua_State *L)
109 auxiliar_add2group(L, "udp{connected}", "select{able}"); 109 auxiliar_add2group(L, "udp{connected}", "select{able}");
110 auxiliar_add2group(L, "udp{unconnected}", "select{able}"); 110 auxiliar_add2group(L, "udp{unconnected}", "select{able}");
111 /* define library functions */ 111 /* define library functions */
112 luaL_openlib(L, NULL, func, 0); 112 luaL_openlib(L, NULL, func, 0);
113 return 0; 113 return 0;
114} 114}
115 115
@@ -156,12 +156,12 @@ static int meth_sendto(lua_State *L) {
156 struct sockaddr_in addr; 156 struct sockaddr_in addr;
157 int err; 157 int err;
158 memset(&addr, 0, sizeof(addr)); 158 memset(&addr, 0, sizeof(addr));
159 if (!inet_aton(ip, &addr.sin_addr)) 159 if (!inet_aton(ip, &addr.sin_addr))
160 luaL_argerror(L, 3, "invalid ip address"); 160 luaL_argerror(L, 3, "invalid ip address");
161 addr.sin_family = AF_INET; 161 addr.sin_family = AF_INET;
162 addr.sin_port = htons(port); 162 addr.sin_port = htons(port);
163 timeout_markstart(tm); 163 timeout_markstart(tm);
164 err = socket_sendto(&udp->sock, data, count, &sent, 164 err = socket_sendto(&udp->sock, data, count, &sent,
165 (SA *) &addr, sizeof(addr), tm); 165 (SA *) &addr, sizeof(addr), tm);
166 if (err != IO_DONE) { 166 if (err != IO_DONE) {
167 lua_pushnil(L); 167 lua_pushnil(L);
@@ -206,7 +206,7 @@ static int meth_receivefrom(lua_State *L) {
206 p_timeout tm = &udp->tm; 206 p_timeout tm = &udp->tm;
207 timeout_markstart(tm); 207 timeout_markstart(tm);
208 count = MIN(count, sizeof(buffer)); 208 count = MIN(count, sizeof(buffer));
209 err = socket_recvfrom(&udp->sock, buffer, count, &got, 209 err = socket_recvfrom(&udp->sock, buffer, count, &got,
210 (SA *) &addr, &addr_len, tm); 210 (SA *) &addr, &addr_len, tm);
211 if (err == IO_DONE) { 211 if (err == IO_DONE) {
212 lua_pushlstring(L, buffer, got); 212 lua_pushlstring(L, buffer, got);
@@ -288,10 +288,17 @@ static int meth_setpeername(lua_State *L) {
288 p_timeout tm = &udp->tm; 288 p_timeout tm = &udp->tm;
289 const char *address = luaL_checkstring(L, 2); 289 const char *address = luaL_checkstring(L, 2);
290 int connecting = strcmp(address, "*"); 290 int connecting = strcmp(address, "*");
291 unsigned short port = connecting ? 291 const char *port = connecting ?
292 (unsigned short) luaL_checknumber(L, 3) : 292 luaL_checkstring(L, 3) :
293 (unsigned short) luaL_optnumber(L, 3, 0); 293 luaL_optstring(L, 3, "0");
294 const char *err = inet_tryconnect(&udp->sock, address, port, tm); 294 struct addrinfo connecthints;
295 const char *err;
296 memset(&connecthints, 0, sizeof(connecthints));
297 connecthints.ai_socktype = SOCK_DGRAM;
298 /* make sure we try to connect only to the same family */
299 connecthints.ai_family = udp->domain;
300 err = inet_tryconnect(&udp->sock, address, port,
301 tm, &connecthints);
295 if (err) { 302 if (err) {
296 lua_pushnil(L); 303 lua_pushnil(L);
297 lua_pushstring(L, err); 304 lua_pushstring(L, err);
@@ -305,7 +312,7 @@ static int meth_setpeername(lua_State *L) {
305} 312}
306 313
307/*-------------------------------------------------------------------------*\ 314/*-------------------------------------------------------------------------*\
308* Closes socket used by object 315* Closes socket used by object
309\*-------------------------------------------------------------------------*/ 316\*-------------------------------------------------------------------------*/
310static int meth_close(lua_State *L) { 317static int meth_close(lua_State *L) {
311 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); 318 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
@@ -341,13 +348,13 @@ static int meth_setsockname(lua_State *L) {
341* Library functions 348* Library functions
342\*=========================================================================*/ 349\*=========================================================================*/
343/*-------------------------------------------------------------------------*\ 350/*-------------------------------------------------------------------------*\
344* Creates a master udp object 351* Creates a master udp object
345\*-------------------------------------------------------------------------*/ 352\*-------------------------------------------------------------------------*/
346static int udp_create(lua_State *L, int domain) { 353static int udp_create(lua_State *L, int domain) {
347 t_socket sock; 354 t_socket sock;
348 const char *err = inet_trycreate(&sock, domain, SOCK_DGRAM); 355 const char *err = inet_trycreate(&sock, domain, SOCK_DGRAM);
349 /* try to allocate a system socket */ 356 /* try to allocate a system socket */
350 if (!err) { 357 if (!err) {
351 /* allocate udp object */ 358 /* allocate udp object */
352 p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); 359 p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp));
353 auxiliar_setclass(L, "udp{unconnected}", -1); 360 auxiliar_setclass(L, "udp{unconnected}", -1);