/*-------------------------------------------------------------------------*\ * Turns a master udp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_setpeername(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); p_timeout tm = &udp->tm; const char *address = luaL_checkstring(L, 2); int connecting = strcmp(address, "*"); const char *port = connecting? luaL_checkstring(L, 3): "0"; struct addrinfo connecthints; const char *err; memset(&connecthints, 0, sizeof(connecthints)); connecthints.ai_socktype = SOCK_DGRAM; /* make sure we try to connect only to the same family */ connecthints.ai_family = udp->family; if (connecting) { err = inet_tryconnect(&udp->sock, &udp->family, address, port, tm, &connecthints); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } auxiliar_setclass(L, "udp{connected}", 1); } else { /* we ignore possible errors because Mac OS X always * returns EAFNOSUPPORT */ inet_trydisconnect(&udp->sock, udp->family, tm); auxiliar_setclass(L, "udp{unconnected}", 1); } /* change class to connected or unconnected depending on address */ lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Turns a master tcp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_connect(lua_State *L) { const char *af_opts[] = {"AF_INET", "AF_INET6", "AF_UNSPEC"}; const char *def_af = "AF_UNSPEC"; p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); const char *address = luaL_checkstring(L, 2); unsigned short port = (unsigned short) luaL_checknumber(L, 3); short family; const char *err; p_timeout tm = timeout_markstart(&tcp->tm); 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_tryconnect(&tcp->sock, address, port, tm, family); /* have to set the class even if it failed due to non-blocking connects */ auxiliar_setclass(L, "tcp{client}", 1); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } /* turn master object into a client object */ 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 tcp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_connect(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); const char *address = luaL_checkstring(L, 2); unsigned short port = (unsigned short) luaL_checknumber(L, 3); p_timeout tm = timeout_markstart(&tcp->tm); const char *err = inet_tryconnect(&tcp->sock, address, port, tm); /* have to set the class even if it failed due to non-blocking connects */ auxiliar_setclass(L, "tcp{client}", 1); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } /* turn master object into a client object */ lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Turns a master udp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_setpeername(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); p_timeout tm = &udp->tm; const char *address = luaL_checkstring(L, 2); int connecting = strcmp(address, "*"); unsigned short port = connecting ? (unsigned short) luaL_checknumber(L, 3) : (unsigned short) luaL_optnumber(L, 3, 0); const char *err = inet_tryconnect(&udp->sock, address, port, tm); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } /* change class to connected or unconnected depending on address */ if (connecting) auxiliar_setclass(L, "udp{connected}", 1); else auxiliar_setclass(L, "udp{unconnected}", 1); lua_pushnumber(L, 1); return 1; }
/*-------------------------------------------------------------------------*\ * Turns a master tcp object into a client object. \*-------------------------------------------------------------------------*/ static int meth_connect(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); const char *address = luaL_checkstring(L, 2); const char *port = luaL_checkstring(L, 3); struct addrinfo connecthints; const char *err; 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; timeout_markstart(&tcp->tm); err = inet_tryconnect(&tcp->sock, address, port, &tcp->tm, &connecthints); /* have to set the class even if it failed due to non-blocking connects */ auxiliar_setclass(L, "tcp{client}", 1); if (err) { lua_pushnil(L); lua_pushstring(L, err); return 2; } lua_pushnumber(L, 1); return 1; }
/** * initialize and open a SACD device or file. */ static sacd_input_t sacd_net_input_open(const char *target) { ServerRequest request; ServerResponse response; sacd_input_t dev = 0; const char *err = 0; t_timeout tm; pb_istream_t input; pb_ostream_t output; uint8_t zero = 0; /* Allocate the library structure */ dev = (sacd_input_t) calloc(sizeof(*dev), 1); if (dev == NULL) { fprintf(stderr, "libsacdread: Could not allocate memory.\n"); return NULL; } dev->input_buffer = (uint8_t *) malloc(MAX_PROCESSING_BLOCK_SIZE * SACD_LSN_SIZE + 1024); if (dev->input_buffer == NULL) { fprintf(stderr, "libsacdread: Could not allocate memory.\n"); goto error; } socket_open(); socket_create(&dev->fd, AF_INET, SOCK_STREAM, 0); socket_setblocking(&dev->fd); timeout_markstart(&tm); err = inet_tryconnect(&dev->fd, substr(target, 0, strchr(target, ':') - target), atoi(strchr(target, ':') + 1), &tm); if (err) { fprintf(stderr, "Failed to connect\n"); goto error; } socket_setblocking(&dev->fd); input = pb_istream_from_socket(&dev->fd); output = pb_ostream_from_socket(&dev->fd); request.type = ServerRequest_Type_DISC_OPEN; if (!pb_encode(&output, ServerRequest_fields, &request)) { fprintf(stderr, "Failed to encode request\n"); goto error; } /* We signal the end of request with a 0 tag. */ pb_write(&output, &zero, 1); if (!pb_decode(&input, ServerResponse_fields, &response)) { fprintf(stderr, "Failed to decode response\n"); goto error; } if (response.result != 0 || response.type != ServerResponse_Type_DISC_OPENED) { fprintf(stderr, "Response result non-zero or disc opened\n"); goto error; } return dev; error: sacd_input_close(dev); return 0; }