/*-------------------------------------------------------------------------*\ * Binds an object to an address \*-------------------------------------------------------------------------*/ static int meth_bind(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); const char *address = luaL_checkstring(L, 2); unsigned short port = (unsigned short) luaL_checknumber(L, 3); const char *af_opts[] = {"AF_INET", "AF_INET6", "AF_UNSPEC"}; const char *def_af = "AF_UNSPEC"; const char *err; short family; switch(luaL_checkoption(L, 4, def_af, af_opts)) { case 0 : family = AF_INET ; break; case 1 : family = AF_INET6 ; break; case 2 : family = AF_UNSPEC ; break; default : family = AF_UNSPEC ; break; } err = inet_trybind(&tcp->sock, address, port, family); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Turns a master object into a server object \*-------------------------------------------------------------------------*/ static int meth_setsockname(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); const char *address = luaL_checkstring(L, 2); unsigned short port = (unsigned short) luaL_checknumber(L, 3); const char *err = inet_trybind(&udp->sock, address, port); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Binds an object to an address \*-------------------------------------------------------------------------*/ static int meth_bind(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); const char *address = luaL_checkstring(L, 2); unsigned short port = (unsigned short) luaL_checknumber(L, 3); const char *err = inet_trybind(&tcp->sock, address, port); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } lua_pushnumber(L, 1); return 1; }
static int global_connect(lua_State *L) { const char *remoteaddr = luaL_checkstring(L, 1); const char *remoteserv = luaL_checkstring(L, 2); const char *localaddr = luaL_optstring(L, 3, NULL); const char *localserv = luaL_optstring(L, 4, "0"); int family = inet_optfamily(L, 5, "unspec"); p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); struct addrinfo bindhints, connecthints; const char *err = NULL; /* initialize tcp structure */ memset(tcp, 0, sizeof(t_tcp)); io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, (p_error) socket_ioerror, &tcp->sock); timeout_init(&tcp->tm, -1, -1); buffer_init(&tcp->buf, &tcp->io, &tcp->tm); tcp->sock = SOCKET_INVALID; tcp->family = AF_UNSPEC; /* allow user to pick local address and port */ memset(&bindhints, 0, sizeof(bindhints)); bindhints.ai_socktype = SOCK_STREAM; bindhints.ai_family = family; bindhints.ai_flags = AI_PASSIVE; if (localaddr) { err = inet_trybind(&tcp->sock, &tcp->family, localaddr, localserv, &bindhints); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } } /* try to connect to remote address and port */ memset(&connecthints, 0, sizeof(connecthints)); connecthints.ai_socktype = SOCK_STREAM; /* make sure we try to connect only to the same family */ connecthints.ai_family = tcp->family; err = inet_tryconnect(&tcp->sock, &tcp->family, remoteaddr, remoteserv, &tcp->tm, &connecthints); if (err) { socket_destroy(&tcp->sock); lua_pushnil(L); lua_pushstring(L, err); return 2; } auxiliar_setclass(L, "tcp{client}", -1); return 1; }
/*-------------------------------------------------------------------------*\ * Turns a master object into a server object \*-------------------------------------------------------------------------*/ static int meth_setsockname(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); const char *address = luaL_checkstring(L, 2); const char *port = luaL_checkstring(L, 3); const char *err; struct addrinfo bindhints; memset(&bindhints, 0, sizeof(bindhints)); bindhints.ai_socktype = SOCK_DGRAM; bindhints.ai_family = udp->family; bindhints.ai_flags = AI_PASSIVE; err = inet_trybind(&udp->sock, address, port, &bindhints); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Binds an object to an address \*-------------------------------------------------------------------------*/ static int meth_bind(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); const char *address = luaL_checkstring(L, 2); const char *port = luaL_checkstring(L, 3); const char *err; struct addrinfo bindhints; memset(&bindhints, 0, sizeof(bindhints)); bindhints.ai_socktype = SOCK_STREAM; bindhints.ai_family = tcp->family; bindhints.ai_flags = AI_PASSIVE; err = inet_trybind(&tcp->sock, &tcp->family, address, port, &bindhints); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } lua_pushnumber(L, 1); return 1; }