diff options
Diffstat (limited to 'src/tcp.c')
-rw-r--r-- | src/tcp.c | 52 |
1 files changed, 29 insertions, 23 deletions
@@ -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) | |||
150 | static int meth_setfd(lua_State *L) | 150 | static 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 | \*-------------------------------------------------------------------------*/ |
168 | static int meth_accept(lua_State *L) | 168 | static 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 | \*-------------------------------------------------------------------------*/ |
196 | static int meth_bind(lua_State *L) | 196 | static int meth_bind(lua_State *L) |
197 | { | 197 | { |
@@ -219,12 +219,18 @@ static int meth_bind(lua_State *L) | |||
219 | \*-------------------------------------------------------------------------*/ | 219 | \*-------------------------------------------------------------------------*/ |
220 | static int meth_connect(lua_State *L) | 220 | static 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 | \*-------------------------------------------------------------------------*/ |
242 | static int meth_close(lua_State *L) | 248 | static 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 | \*-------------------------------------------------------------------------*/ |
327 | static int tcp_create(lua_State *L, int domain) { | 333 | static 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); |