diff options
Diffstat (limited to 'vendor/luasocket/src/tcp.c')
-rw-r--r-- | vendor/luasocket/src/tcp.c | 480 |
1 files changed, 480 insertions, 0 deletions
diff --git a/vendor/luasocket/src/tcp.c b/vendor/luasocket/src/tcp.c new file mode 100644 index 00000000..e84db845 --- /dev/null +++ b/vendor/luasocket/src/tcp.c | |||
@@ -0,0 +1,480 @@ | |||
1 | /*=========================================================================*\ | ||
2 | * TCP object | ||
3 | * LuaSocket toolkit | ||
4 | \*=========================================================================*/ | ||
5 | #include "luasocket.h" | ||
6 | |||
7 | #include "auxiliar.h" | ||
8 | #include "socket.h" | ||
9 | #include "inet.h" | ||
10 | #include "options.h" | ||
11 | #include "tcp.h" | ||
12 | |||
13 | #include <string.h> | ||
14 | |||
15 | /*=========================================================================*\ | ||
16 | * Internal function prototypes | ||
17 | \*=========================================================================*/ | ||
18 | static int global_create(lua_State *L); | ||
19 | static int global_create4(lua_State *L); | ||
20 | static int global_create6(lua_State *L); | ||
21 | static int global_connect(lua_State *L); | ||
22 | static int meth_connect(lua_State *L); | ||
23 | static int meth_listen(lua_State *L); | ||
24 | static int meth_getfamily(lua_State *L); | ||
25 | static int meth_bind(lua_State *L); | ||
26 | static int meth_send(lua_State *L); | ||
27 | static int meth_getstats(lua_State *L); | ||
28 | static int meth_setstats(lua_State *L); | ||
29 | static int meth_getsockname(lua_State *L); | ||
30 | static int meth_getpeername(lua_State *L); | ||
31 | static int meth_shutdown(lua_State *L); | ||
32 | static int meth_receive(lua_State *L); | ||
33 | static int meth_accept(lua_State *L); | ||
34 | static int meth_close(lua_State *L); | ||
35 | static int meth_getoption(lua_State *L); | ||
36 | static int meth_setoption(lua_State *L); | ||
37 | static int meth_gettimeout(lua_State *L); | ||
38 | static int meth_settimeout(lua_State *L); | ||
39 | static int meth_getfd(lua_State *L); | ||
40 | static int meth_setfd(lua_State *L); | ||
41 | static int meth_dirty(lua_State *L); | ||
42 | |||
43 | /* tcp object methods */ | ||
44 | static luaL_Reg tcp_methods[] = { | ||
45 | {"__gc", meth_close}, | ||
46 | {"__tostring", auxiliar_tostring}, | ||
47 | {"accept", meth_accept}, | ||
48 | {"bind", meth_bind}, | ||
49 | {"close", meth_close}, | ||
50 | {"connect", meth_connect}, | ||
51 | {"dirty", meth_dirty}, | ||
52 | {"getfamily", meth_getfamily}, | ||
53 | {"getfd", meth_getfd}, | ||
54 | {"getoption", meth_getoption}, | ||
55 | {"getpeername", meth_getpeername}, | ||
56 | {"getsockname", meth_getsockname}, | ||
57 | {"getstats", meth_getstats}, | ||
58 | {"setstats", meth_setstats}, | ||
59 | {"listen", meth_listen}, | ||
60 | {"receive", meth_receive}, | ||
61 | {"send", meth_send}, | ||
62 | {"setfd", meth_setfd}, | ||
63 | {"setoption", meth_setoption}, | ||
64 | {"setpeername", meth_connect}, | ||
65 | {"setsockname", meth_bind}, | ||
66 | {"settimeout", meth_settimeout}, | ||
67 | {"gettimeout", meth_gettimeout}, | ||
68 | {"shutdown", meth_shutdown}, | ||
69 | {NULL, NULL} | ||
70 | }; | ||
71 | |||
72 | /* socket option handlers */ | ||
73 | static t_opt optget[] = { | ||
74 | {"keepalive", opt_get_keepalive}, | ||
75 | {"reuseaddr", opt_get_reuseaddr}, | ||
76 | {"reuseport", opt_get_reuseport}, | ||
77 | {"tcp-nodelay", opt_get_tcp_nodelay}, | ||
78 | #ifdef TCP_KEEPIDLE | ||
79 | {"tcp-keepidle", opt_get_tcp_keepidle}, | ||
80 | #endif | ||
81 | #ifdef TCP_KEEPCNT | ||
82 | {"tcp-keepcnt", opt_get_tcp_keepcnt}, | ||
83 | #endif | ||
84 | #ifdef TCP_KEEPINTVL | ||
85 | {"tcp-keepintvl", opt_get_tcp_keepintvl}, | ||
86 | #endif | ||
87 | {"linger", opt_get_linger}, | ||
88 | {"error", opt_get_error}, | ||
89 | {"recv-buffer-size", opt_get_recv_buf_size}, | ||
90 | {"send-buffer-size", opt_get_send_buf_size}, | ||
91 | {NULL, NULL} | ||
92 | }; | ||
93 | |||
94 | static t_opt optset[] = { | ||
95 | {"keepalive", opt_set_keepalive}, | ||
96 | {"reuseaddr", opt_set_reuseaddr}, | ||
97 | {"reuseport", opt_set_reuseport}, | ||
98 | {"tcp-nodelay", opt_set_tcp_nodelay}, | ||
99 | #ifdef TCP_KEEPIDLE | ||
100 | {"tcp-keepidle", opt_set_tcp_keepidle}, | ||
101 | #endif | ||
102 | #ifdef TCP_KEEPCNT | ||
103 | {"tcp-keepcnt", opt_set_tcp_keepcnt}, | ||
104 | #endif | ||
105 | #ifdef TCP_KEEPINTVL | ||
106 | {"tcp-keepintvl", opt_set_tcp_keepintvl}, | ||
107 | #endif | ||
108 | {"ipv6-v6only", opt_set_ip6_v6only}, | ||
109 | {"linger", opt_set_linger}, | ||
110 | {"recv-buffer-size", opt_set_recv_buf_size}, | ||
111 | {"send-buffer-size", opt_set_send_buf_size}, | ||
112 | #ifdef TCP_DEFER_ACCEPT | ||
113 | {"tcp-defer-accept", opt_set_tcp_defer_accept}, | ||
114 | #endif | ||
115 | #ifdef TCP_FASTOPEN | ||
116 | {"tcp-fastopen", opt_set_tcp_fastopen}, | ||
117 | #endif | ||
118 | #ifdef TCP_FASTOPEN_CONNECT | ||
119 | {"tcp-fastopen-connect", opt_set_tcp_fastopen_connect}, | ||
120 | #endif | ||
121 | {NULL, NULL} | ||
122 | }; | ||
123 | |||
124 | /* functions in library namespace */ | ||
125 | static luaL_Reg func[] = { | ||
126 | {"tcp", global_create}, | ||
127 | {"tcp4", global_create4}, | ||
128 | {"tcp6", global_create6}, | ||
129 | {"connect", global_connect}, | ||
130 | {NULL, NULL} | ||
131 | }; | ||
132 | |||
133 | /*-------------------------------------------------------------------------*\ | ||
134 | * Initializes module | ||
135 | \*-------------------------------------------------------------------------*/ | ||
136 | int tcp_open(lua_State *L) | ||
137 | { | ||
138 | /* create classes */ | ||
139 | auxiliar_newclass(L, "tcp{master}", tcp_methods); | ||
140 | auxiliar_newclass(L, "tcp{client}", tcp_methods); | ||
141 | auxiliar_newclass(L, "tcp{server}", tcp_methods); | ||
142 | /* create class groups */ | ||
143 | auxiliar_add2group(L, "tcp{master}", "tcp{any}"); | ||
144 | auxiliar_add2group(L, "tcp{client}", "tcp{any}"); | ||
145 | auxiliar_add2group(L, "tcp{server}", "tcp{any}"); | ||
146 | /* define library functions */ | ||
147 | luaL_setfuncs(L, func, 0); | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | /*=========================================================================*\ | ||
152 | * Lua methods | ||
153 | \*=========================================================================*/ | ||
154 | /*-------------------------------------------------------------------------*\ | ||
155 | * Just call buffered IO methods | ||
156 | \*-------------------------------------------------------------------------*/ | ||
157 | static int meth_send(lua_State *L) { | ||
158 | p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); | ||
159 | return buffer_meth_send(L, &tcp->buf); | ||
160 | } | ||
161 | |||
162 | static int meth_receive(lua_State *L) { | ||
163 | p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); | ||
164 | return buffer_meth_receive(L, &tcp->buf); | ||
165 | } | ||
166 | |||
167 | static int meth_getstats(lua_State *L) { | ||
168 | p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); | ||
169 | return buffer_meth_getstats(L, &tcp->buf); | ||
170 | } | ||
171 | |||
172 | static int meth_setstats(lua_State *L) { | ||
173 | p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); | ||
174 | return buffer_meth_setstats(L, &tcp->buf); | ||
175 | } | ||
176 | |||
177 | /*-------------------------------------------------------------------------*\ | ||
178 | * Just call option handler | ||
179 | \*-------------------------------------------------------------------------*/ | ||
180 | static int meth_getoption(lua_State *L) | ||
181 | { | ||
182 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
183 | return opt_meth_getoption(L, optget, &tcp->sock); | ||
184 | } | ||
185 | |||
186 | static int meth_setoption(lua_State *L) | ||
187 | { | ||
188 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
189 | return opt_meth_setoption(L, optset, &tcp->sock); | ||
190 | } | ||
191 | |||
192 | /*-------------------------------------------------------------------------*\ | ||
193 | * Select support methods | ||
194 | \*-------------------------------------------------------------------------*/ | ||
195 | static int meth_getfd(lua_State *L) | ||
196 | { | ||
197 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
198 | lua_pushnumber(L, (int) tcp->sock); | ||
199 | return 1; | ||
200 | } | ||
201 | |||
202 | /* this is very dangerous, but can be handy for those that are brave enough */ | ||
203 | static int meth_setfd(lua_State *L) | ||
204 | { | ||
205 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
206 | tcp->sock = (t_socket) luaL_checknumber(L, 2); | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static int meth_dirty(lua_State *L) | ||
211 | { | ||
212 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
213 | lua_pushboolean(L, !buffer_isempty(&tcp->buf)); | ||
214 | return 1; | ||
215 | } | ||
216 | |||
217 | /*-------------------------------------------------------------------------*\ | ||
218 | * Waits for and returns a client object attempting connection to the | ||
219 | * server object | ||
220 | \*-------------------------------------------------------------------------*/ | ||
221 | static int meth_accept(lua_State *L) | ||
222 | { | ||
223 | p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1); | ||
224 | p_timeout tm = timeout_markstart(&server->tm); | ||
225 | t_socket sock; | ||
226 | const char *err = inet_tryaccept(&server->sock, server->family, &sock, tm); | ||
227 | /* if successful, push client socket */ | ||
228 | if (err == NULL) { | ||
229 | p_tcp clnt = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | ||
230 | auxiliar_setclass(L, "tcp{client}", -1); | ||
231 | /* initialize structure fields */ | ||
232 | memset(clnt, 0, sizeof(t_tcp)); | ||
233 | socket_setnonblocking(&sock); | ||
234 | clnt->sock = sock; | ||
235 | io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, | ||
236 | (p_error) socket_ioerror, &clnt->sock); | ||
237 | timeout_init(&clnt->tm, -1, -1); | ||
238 | buffer_init(&clnt->buf, &clnt->io, &clnt->tm); | ||
239 | clnt->family = server->family; | ||
240 | return 1; | ||
241 | } else { | ||
242 | lua_pushnil(L); | ||
243 | lua_pushstring(L, err); | ||
244 | return 2; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | /*-------------------------------------------------------------------------*\ | ||
249 | * Binds an object to an address | ||
250 | \*-------------------------------------------------------------------------*/ | ||
251 | static int meth_bind(lua_State *L) { | ||
252 | p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); | ||
253 | const char *address = luaL_checkstring(L, 2); | ||
254 | const char *port = luaL_checkstring(L, 3); | ||
255 | const char *err; | ||
256 | struct addrinfo bindhints; | ||
257 | memset(&bindhints, 0, sizeof(bindhints)); | ||
258 | bindhints.ai_socktype = SOCK_STREAM; | ||
259 | bindhints.ai_family = tcp->family; | ||
260 | bindhints.ai_flags = AI_PASSIVE; | ||
261 | err = inet_trybind(&tcp->sock, &tcp->family, address, port, &bindhints); | ||
262 | if (err) { | ||
263 | lua_pushnil(L); | ||
264 | lua_pushstring(L, err); | ||
265 | return 2; | ||
266 | } | ||
267 | lua_pushnumber(L, 1); | ||
268 | return 1; | ||
269 | } | ||
270 | |||
271 | /*-------------------------------------------------------------------------*\ | ||
272 | * Turns a master tcp object into a client object. | ||
273 | \*-------------------------------------------------------------------------*/ | ||
274 | static int meth_connect(lua_State *L) { | ||
275 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
276 | const char *address = luaL_checkstring(L, 2); | ||
277 | const char *port = luaL_checkstring(L, 3); | ||
278 | struct addrinfo connecthints; | ||
279 | const char *err; | ||
280 | memset(&connecthints, 0, sizeof(connecthints)); | ||
281 | connecthints.ai_socktype = SOCK_STREAM; | ||
282 | /* make sure we try to connect only to the same family */ | ||
283 | connecthints.ai_family = tcp->family; | ||
284 | timeout_markstart(&tcp->tm); | ||
285 | err = inet_tryconnect(&tcp->sock, &tcp->family, address, port, | ||
286 | &tcp->tm, &connecthints); | ||
287 | /* have to set the class even if it failed due to non-blocking connects */ | ||
288 | auxiliar_setclass(L, "tcp{client}", 1); | ||
289 | if (err) { | ||
290 | lua_pushnil(L); | ||
291 | lua_pushstring(L, err); | ||
292 | return 2; | ||
293 | } | ||
294 | lua_pushnumber(L, 1); | ||
295 | return 1; | ||
296 | } | ||
297 | |||
298 | /*-------------------------------------------------------------------------*\ | ||
299 | * Closes socket used by object | ||
300 | \*-------------------------------------------------------------------------*/ | ||
301 | static int meth_close(lua_State *L) | ||
302 | { | ||
303 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
304 | socket_destroy(&tcp->sock); | ||
305 | lua_pushnumber(L, 1); | ||
306 | return 1; | ||
307 | } | ||
308 | |||
309 | /*-------------------------------------------------------------------------*\ | ||
310 | * Returns family as string | ||
311 | \*-------------------------------------------------------------------------*/ | ||
312 | static int meth_getfamily(lua_State *L) | ||
313 | { | ||
314 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
315 | if (tcp->family == AF_INET6) { | ||
316 | lua_pushliteral(L, "inet6"); | ||
317 | return 1; | ||
318 | } else if (tcp->family == AF_INET) { | ||
319 | lua_pushliteral(L, "inet4"); | ||
320 | return 1; | ||
321 | } else { | ||
322 | lua_pushliteral(L, "inet4"); | ||
323 | return 1; | ||
324 | } | ||
325 | } | ||
326 | |||
327 | /*-------------------------------------------------------------------------*\ | ||
328 | * Puts the sockt in listen mode | ||
329 | \*-------------------------------------------------------------------------*/ | ||
330 | static int meth_listen(lua_State *L) | ||
331 | { | ||
332 | p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); | ||
333 | int backlog = (int) luaL_optnumber(L, 2, 32); | ||
334 | int err = socket_listen(&tcp->sock, backlog); | ||
335 | if (err != IO_DONE) { | ||
336 | lua_pushnil(L); | ||
337 | lua_pushstring(L, socket_strerror(err)); | ||
338 | return 2; | ||
339 | } | ||
340 | /* turn master object into a server object */ | ||
341 | auxiliar_setclass(L, "tcp{server}", 1); | ||
342 | lua_pushnumber(L, 1); | ||
343 | return 1; | ||
344 | } | ||
345 | |||
346 | /*-------------------------------------------------------------------------*\ | ||
347 | * Shuts the connection down partially | ||
348 | \*-------------------------------------------------------------------------*/ | ||
349 | static int meth_shutdown(lua_State *L) | ||
350 | { | ||
351 | /* SHUT_RD, SHUT_WR, SHUT_RDWR have the value 0, 1, 2, so we can use method index directly */ | ||
352 | static const char* methods[] = { "receive", "send", "both", NULL }; | ||
353 | p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); | ||
354 | int how = luaL_checkoption(L, 2, "both", methods); | ||
355 | socket_shutdown(&tcp->sock, how); | ||
356 | lua_pushnumber(L, 1); | ||
357 | return 1; | ||
358 | } | ||
359 | |||
360 | /*-------------------------------------------------------------------------*\ | ||
361 | * Just call inet methods | ||
362 | \*-------------------------------------------------------------------------*/ | ||
363 | static int meth_getpeername(lua_State *L) | ||
364 | { | ||
365 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
366 | return inet_meth_getpeername(L, &tcp->sock, tcp->family); | ||
367 | } | ||
368 | |||
369 | static int meth_getsockname(lua_State *L) | ||
370 | { | ||
371 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
372 | return inet_meth_getsockname(L, &tcp->sock, tcp->family); | ||
373 | } | ||
374 | |||
375 | /*-------------------------------------------------------------------------*\ | ||
376 | * Just call tm methods | ||
377 | \*-------------------------------------------------------------------------*/ | ||
378 | static int meth_settimeout(lua_State *L) | ||
379 | { | ||
380 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
381 | return timeout_meth_settimeout(L, &tcp->tm); | ||
382 | } | ||
383 | |||
384 | static int meth_gettimeout(lua_State *L) | ||
385 | { | ||
386 | p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||
387 | return timeout_meth_gettimeout(L, &tcp->tm); | ||
388 | } | ||
389 | |||
390 | /*=========================================================================*\ | ||
391 | * Library functions | ||
392 | \*=========================================================================*/ | ||
393 | /*-------------------------------------------------------------------------*\ | ||
394 | * Creates a master tcp object | ||
395 | \*-------------------------------------------------------------------------*/ | ||
396 | static int tcp_create(lua_State *L, int family) { | ||
397 | p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | ||
398 | memset(tcp, 0, sizeof(t_tcp)); | ||
399 | /* set its type as master object */ | ||
400 | auxiliar_setclass(L, "tcp{master}", -1); | ||
401 | /* if family is AF_UNSPEC, we leave the socket invalid and | ||
402 | * store AF_UNSPEC into family. This will allow it to later be | ||
403 | * replaced with an AF_INET6 or AF_INET socket upon first use. */ | ||
404 | tcp->sock = SOCKET_INVALID; | ||
405 | tcp->family = family; | ||
406 | io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, | ||
407 | (p_error) socket_ioerror, &tcp->sock); | ||
408 | timeout_init(&tcp->tm, -1, -1); | ||
409 | buffer_init(&tcp->buf, &tcp->io, &tcp->tm); | ||
410 | if (family != AF_UNSPEC) { | ||
411 | const char *err = inet_trycreate(&tcp->sock, family, SOCK_STREAM, 0); | ||
412 | if (err != NULL) { | ||
413 | lua_pushnil(L); | ||
414 | lua_pushstring(L, err); | ||
415 | return 2; | ||
416 | } | ||
417 | socket_setnonblocking(&tcp->sock); | ||
418 | } | ||
419 | return 1; | ||
420 | } | ||
421 | |||
422 | static int global_create(lua_State *L) { | ||
423 | return tcp_create(L, AF_UNSPEC); | ||
424 | } | ||
425 | |||
426 | static int global_create4(lua_State *L) { | ||
427 | return tcp_create(L, AF_INET); | ||
428 | } | ||
429 | |||
430 | static int global_create6(lua_State *L) { | ||
431 | return tcp_create(L, AF_INET6); | ||
432 | } | ||
433 | |||
434 | static int global_connect(lua_State *L) { | ||
435 | const char *remoteaddr = luaL_checkstring(L, 1); | ||
436 | const char *remoteserv = luaL_checkstring(L, 2); | ||
437 | const char *localaddr = luaL_optstring(L, 3, NULL); | ||
438 | const char *localserv = luaL_optstring(L, 4, "0"); | ||
439 | int family = inet_optfamily(L, 5, "unspec"); | ||
440 | p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | ||
441 | struct addrinfo bindhints, connecthints; | ||
442 | const char *err = NULL; | ||
443 | /* initialize tcp structure */ | ||
444 | memset(tcp, 0, sizeof(t_tcp)); | ||
445 | io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, | ||
446 | (p_error) socket_ioerror, &tcp->sock); | ||
447 | timeout_init(&tcp->tm, -1, -1); | ||
448 | buffer_init(&tcp->buf, &tcp->io, &tcp->tm); | ||
449 | tcp->sock = SOCKET_INVALID; | ||
450 | tcp->family = AF_UNSPEC; | ||
451 | /* allow user to pick local address and port */ | ||
452 | memset(&bindhints, 0, sizeof(bindhints)); | ||
453 | bindhints.ai_socktype = SOCK_STREAM; | ||
454 | bindhints.ai_family = family; | ||
455 | bindhints.ai_flags = AI_PASSIVE; | ||
456 | if (localaddr) { | ||
457 | err = inet_trybind(&tcp->sock, &tcp->family, localaddr, | ||
458 | localserv, &bindhints); | ||
459 | if (err) { | ||
460 | lua_pushnil(L); | ||
461 | lua_pushstring(L, err); | ||
462 | return 2; | ||
463 | } | ||
464 | } | ||
465 | /* try to connect to remote address and port */ | ||
466 | memset(&connecthints, 0, sizeof(connecthints)); | ||
467 | connecthints.ai_socktype = SOCK_STREAM; | ||
468 | /* make sure we try to connect only to the same family */ | ||
469 | connecthints.ai_family = tcp->family; | ||
470 | err = inet_tryconnect(&tcp->sock, &tcp->family, remoteaddr, remoteserv, | ||
471 | &tcp->tm, &connecthints); | ||
472 | if (err) { | ||
473 | socket_destroy(&tcp->sock); | ||
474 | lua_pushnil(L); | ||
475 | lua_pushstring(L, err); | ||
476 | return 2; | ||
477 | } | ||
478 | auxiliar_setclass(L, "tcp{client}", -1); | ||
479 | return 1; | ||
480 | } | ||