static void client_handshake_domain_resolved(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res) { server_ctx *ctx = (server_ctx *)resolver->data; if (status) { if (uv_last_error(ctx->client.loop).code == UV_ENOENT) { LOGI("Resolve error, NXDOMAIN"); } else { SHOW_UV_ERROR(ctx->client.loop); } HANDLE_CLOSE((uv_handle_t*)(void *)&ctx->client, handshake_client_close_cb); uv_freeaddrinfo(res); free(resolver); return; } ctx->remote_ip = ((struct sockaddr_in*)(res->ai_addr))->sin_addr.s_addr; int n = uv_read_start((uv_stream_t *)(void *)&ctx->client, client_handshake_alloc_cb, client_handshake_read_cb); if (n) { HANDLE_CLOSE((uv_handle_t*)(void *)&ctx->client, handshake_client_close_cb); SHOW_UV_ERROR(ctx->client.loop); } uv_freeaddrinfo(res); free(resolver); }
static void on_get_host_addrs_(uv_getaddrinfo_t *req, int status, struct addrinfo *addrs) { wsn_client_ctx_t *client = CONTAINER_OF(req, wsn_client_ctx_t, getaddrinfo_req); uv_timer_stop(&client->timer_handle); if (status < 0) { wsn_report_err(WSN_ERR_GET_ADDR_INFO, "Failed to getaddrinfo for client to (\"%s\"): %s", client->conf->host, uv_strerror(status)); uv_freeaddrinfo(addrs); return; } int ipv4_naddrs = 0; int ipv6_naddrs = 0; for (struct addrinfo *ai = addrs; ai != NULL; ai = ai->ai_next) { if (ai->ai_family == AF_INET) { ipv4_naddrs += 1; } else if (ai->ai_family == AF_INET6) { ipv6_naddrs += 1; } } if (ipv4_naddrs == 0 && ipv6_naddrs == 0) { wsn_report_err(WSN_ERR_GET_ADDR_INFO, "Remote host (\"%s\") has no IPv4/6 addresses", client->conf->host); uv_freeaddrinfo(addrs); return; } union { struct sockaddr addr; struct sockaddr_in addr4; struct sockaddr_in6 addr6; } s; for (struct addrinfo *ai = addrs; ai != NULL; ai = ai->ai_next) { if (ai->ai_family == AF_INET) { s.addr4 = *(const struct sockaddr_in *) ai->ai_addr; s.addr4.sin_port = htons(client->conf->port); } else if (ai->ai_family == AF_INET6) { s.addr6 = *(const struct sockaddr_in6 *) ai->ai_addr; s.addr6.sin6_port = htons(client->conf->port); } else { continue; } client->host_addr = s.addr; break; } uv_freeaddrinfo(addrs); if (wsn_client_start_connect_(client) != 0) { uv_stop(client->loop); return; } }
void TSockSys::OnGetHost(uv_getaddrinfo_t* RequestHnd, int Status, struct addrinfo* AddrInfo) { // get SockHost PSockHost SockHost; if (SockSys.HndToSockHostH.IsKey((uint64)RequestHnd)) { SockHost = SockSys.HndToSockHostH.GetDat((uint64)RequestHnd); SockSys.HndToSockHostH.DelKey((uint64)RequestHnd); } else { free(RequestHnd); uv_freeaddrinfo(AddrInfo); SaveToErrLog("SockSys.OnGetHost: unkown RequestId"); return; } // get SockEvent PSockEvent SockEvent; if (SockHost->IsSockEvent()) { SockEvent = SockHost->GetSockEvent(); } else { free(RequestHnd); uv_freeaddrinfo(AddrInfo); SaveToErrLog("SockSys.OnGetHost: SockHost without SockEvent"); return; } // parse results if (Status == 0) { SockHost->Status = shsOk; // temporary buffer for storing IPs char _addr[64] = {'\0'}; // iterate over all the resolved IPs struct addrinfo* AddrInfoIter = AddrInfo; while (AddrInfoIter != NULL) { //if (AddrInfoIter->ai_family //AF_INET6 // get IP as string if (AddrInfoIter->ai_family == AF_INET) { uv_ip4_name((struct sockaddr_in*)AddrInfoIter->ai_addr, _addr, sizeof(_addr)); } else if (AddrInfoIter->ai_family == AF_INET6) { uv_ip6_name((struct sockaddr_in6*)AddrInfoIter->ai_addr, _addr, sizeof(_addr)); } TStr IpNum(_addr); // add to SockHost SockHost->AddIpNum(IpNum); // go to the next IP on the list AddrInfoIter = AddrInfoIter->ai_next; } } else if (Status == -1) { // something went wrong SockHost->Status = shsError; SockHost->ErrMsg = "SockSys.OnGetHost: " + SockSys.GetLastErr(); } else { // unkown status SockHost->Status = shsError; SockHost->ErrMsg = TStr::Fmt("SockSys.OnGetHost: unkown status %d", Status); } // clean up free(RequestHnd); uv_freeaddrinfo(AddrInfo); // callback SockEvent->OnGetHost(SockHost); }
static void getaddrinfo_cb(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { ASSERT(status == UV_EAI_CANCELED); ASSERT(res == NULL); uv_freeaddrinfo(res); /* Should not crash. */ }
void parse_dns_cb(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res) { LOG_DEBUG("status: %d", status); void **ud_t = resolver->data; PARSE_CB cb_t = ud_t[0]; void *user_data_t = ud_t[1]; free(ud_t); free(resolver); unsigned ip = 0; unsigned short port = 0; if (status <0) { LOG_DEBUG("error stop strerror: %s, err_name: %s", uv_strerror(status), uv_err_name(status)); } else { ip = ((struct sockaddr_in*) res->ai_addr)->sin_addr.s_addr; port = ((struct sockaddr_in*) res->ai_addr)->sin_port; } LOG_DEBUG("ip: %u, port: %u", ip, port); uv_freeaddrinfo(res); cb_t(status, ip, ntohs(port), user_data_t); }
void client::onResolved(uv_getaddrinfo_t* resolver_, int status_, struct addrinfo* res_) { if (status_ == -1) { throw std::runtime_error(uv_err_name(status_)); } int r = 0; data_t* data = (data_t*)resolver_->data; //char addr[17] = {'\0'}; //uv_ip4_name((struct sockaddr_in*)res_->ai_addr, addr, 16); //@TODO add ip6 support //std::cout << "Resolved ip : " << addr << std::endl; uv_tcp_init(data->loop, &data->sock); data->connect_req.data = data; r = uv_tcp_connect( &(data->connect_req), &(data->sock), (const sockaddr*)res_->ai_addr, onConnect ); if (r) { throw std::runtime_error(uv_err_name(r)); } uv_freeaddrinfo(res_); }
static grpc_error *blocking_resolve_address_impl( const char *name, const char *default_port, grpc_resolved_addresses **addresses) { char *host; char *port; struct addrinfo hints; uv_getaddrinfo_t req; int s; grpc_error *err; req.addrinfo = NULL; err = try_split_host_port(name, default_port, &host, &port); if (err != GRPC_ERROR_NONE) { goto done; } /* Call getaddrinfo */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ hints.ai_socktype = SOCK_STREAM; /* stream socket */ hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ s = uv_getaddrinfo(uv_default_loop(), &req, NULL, host, port, &hints); err = handle_addrinfo_result(s, req.addrinfo, addresses); done: gpr_free(host); gpr_free(port); if (req.addrinfo) { uv_freeaddrinfo(req.addrinfo); } return err; }
void getaddrinfo_cb(uv_getaddrinfo_t* handle, int status, struct addrinfo* response) { printf("%s \n", handle->data); free(handle); uv_freeaddrinfo(response); }
static void getaddrinfo_cb(uv_getaddrinfo_t* handle, int status, struct addrinfo* res) { ASSERT(status == 0); calls_completed++; if (calls_initiated < TOTAL_CALLS) { getaddrinfo_initiate(handle); } uv_freeaddrinfo(res); }
void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) { auto client = getClient(req->data); if (!client) { return; } if (status < 0) { if (!client->m_quiet) { LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); } return client->reconnect(); } addrinfo *ptr = res; std::vector<addrinfo*> ipv4; std::vector<addrinfo*> ipv6; while (ptr != nullptr) { if (ptr->ai_family == AF_INET) { ipv4.push_back(ptr); } if (ptr->ai_family == AF_INET6) { ipv6.push_back(ptr); } ptr = ptr->ai_next; } if (ipv4.empty() && ipv6.empty()) { if (!client->m_quiet) { LOG_ERR("[%s:%u] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_url.host(), client->m_url.port()); } uv_freeaddrinfo(res); return client->reconnect(); } client->connect(ipv4, ipv6); uv_freeaddrinfo(res); }
void httpreq_on_resolved(uv_getaddrinfo_t* resolver, int status, struct addrinfo* res) { if(status == -1) { printf("ERROR: httpreq_on_resolved(), cannot resoleve. @todo clean memory\n"); return; } HTTPRequest* req = static_cast<HTTPRequest*>(resolver->data); uv_tcp_init(req->loop, &req->tcp_req); uv_tcp_connect(&req->connect_req, &req->tcp_req, *(struct sockaddr_in*)res->ai_addr, httpreq_on_connect); uv_freeaddrinfo(res); }
int connect_to_next_address(ActivePeer * peer, bool swap_stack) { LOG(DEBUG) << peer; struct addrinfo const * ai = peer->_.ai_next; debug_address(ai); int rc = UV_EAI_FAIL; while (ai && (rc = uv_tcp_connect(&peer->connect_req_, &peer->handle_, ai->ai_addr, on_active_connection))) { LOG(ai ? INFO : WARNING) << "uv_tcp_connect: [" << uv_err_name(rc) << "] " << uv_strerror(rc); if (swap_stack) { switch (rc) { case -ECONNABORTED: /* your kernel hates you */ case -EPROTONOSUPPORT: case -EPFNOSUPPORT: case -EAFNOSUPPORT: case -EPROTOTYPE: case -EINVAL: LOG(INFO) << "destroying socket and retrying"; uv_close((uv_handle_t*)&peer->handle_, swap_stack_on_close); } return 0; } ai = ai->ai_next; debug_address(ai); } /* 'ai' is either NULL or the one that is pending... */ if (!(peer->_.ai_next = ai ? ai->ai_next : NULL)) { if(peer->_.ai) { /* on_active_connection(*, -1) could call us again */ uv_freeaddrinfo(peer->_.ai); } peer->_.ai = NULL; } if (rc) { LOG(DEBUG) << "unable to issue a(nother) connect request"; } else { LOG(DEBUG) << "issued a connect request"; } return rc; }
static void getaddrinfo_cb(uv_getaddrinfo_t* handle, int status, struct addrinfo* res) { struct getaddrinfo_req* req; ASSERT(status == 0); req = container_of(handle, struct getaddrinfo_req, handle); uv_freeaddrinfo(res); if (--req->counter) getaddrinfo_do(req); }
static void getaddrinfo_callback(uv_getaddrinfo_t *req, int status, struct addrinfo *res) { request *r = (request *)req->data; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_error *error; error = handle_addrinfo_result(status, res, r->addresses); grpc_exec_ctx_sched(&exec_ctx, r->on_done, error, NULL); grpc_exec_ctx_finish(&exec_ctx); gpr_free(r->hints); gpr_free(r); gpr_free(req); uv_freeaddrinfo(res); }
static void on_address_resolved(uv_getaddrinfo_t *resolver, int status, struct addrinfo *result) { rig_pb_stream_t *stream = rut_container_of(resolver, stream, resolver); uv_loop_t *loop = rut_uv_shell_get_loop(stream->shell); char ip_address[17] = {'\0'}; c_return_if_fail(stream->resolving); if (status < 0) { c_warning("Failed to resolve slave address \"%s\": %s", stream->hostname, uv_strerror(status)); rut_closure_list_invoke(&stream->on_error_closures, rig_pb_stream_callback_t, stream); /* NB: we were at least keeping the stream alive while * waiting for the resolve request to finish... */ stream->resolving = false; rut_object_unref(stream); return; } uv_ip4_name((struct sockaddr_in*)result->ai_addr, ip_address, 16); c_message("stream: Resolved address of \"%s\" = %s", stream->hostname, ip_address); uv_tcp_init(loop, &stream->tcp.socket); stream->tcp.socket.data = stream; /* NB: we took a reference to keep the stream alive while * resolving the address, so conceptually we are now handing * the reference over to keep the stream alive while waiting * for it to connect... */ stream->resolving = false; stream->connecting = true; stream->connection_request.data = stream; uv_tcp_connect(&stream->connection_request, &stream->tcp.socket, result->ai_addr, on_connect); uv_freeaddrinfo(result); }
void on_resolved_callback(uv_getaddrinfo_t* resolver, int status, struct addrinfo * res) { Client* c = static_cast<Client*>(resolver->data); if(status == -1) { printf("ERROR: getaddrinfo callback error: \n");//, uv_err_name(uv_last_error(c->loop))); ::exit(0); } char addr[17] = {'\0'}; uv_ip4_name((struct sockaddr_in*) res->ai_addr, addr, 16); printf("Found host: %s\n", addr); uv_tcp_init(c->loop, &c->socket); uv_tcp_connect(&c->connect_req, &c->socket, (struct sockaddr *)res->ai_addr, on_connect_callback); uv_freeaddrinfo(res); }
static void client_handshake_domain_resolved(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res) { server_ctx *ctx = (server_ctx *)resolver->data; if (status) { if (uv_last_error(ctx->client.loop).code == UV_ENOENT) { LOGI("Resolve error, NXDOMAIN"); } else { SHOW_UV_ERROR(ctx->client.loop); } uv_close((uv_handle_t*)(void *)&ctx->client, handshake_client_close_cb); uv_freeaddrinfo(res); free(resolver); return; } if (res->ai_family == AF_INET) { // IPv4 memcpy(ctx->remote_ip, &((struct sockaddr_in*)(res->ai_addr))->sin_addr.s_addr, 4); ctx->remote_ip_type = ADDRTYPE_IPV4; } else if (res->ai_family == AF_INET6) { memcpy(ctx->remote_ip, &((struct sockaddr_in6*)(res->ai_addr))->sin6_addr.s6_addr, 16); ctx->remote_ip_type = ADDRTYPE_IPV6; } else { FATAL("dns resolve failed!"); } if (do_handshake((uv_stream_t *)(void *)&ctx->client) == 1) { int n = uv_read_start((uv_stream_t *)(void *)&ctx->client, client_handshake_alloc_cb, client_handshake_read_cb); if (n) { uv_close((uv_handle_t*)(void *)&ctx->client, handshake_client_close_cb); SHOW_UV_ERROR(ctx->client.loop); } } uv_freeaddrinfo(res); free(resolver); }
error resolve(const std::string& addr, ResolveCallback callback) { callbacks::store(get()->data, internal::uv_cid_resolve, callback); return error(uv_getaddrinfo(m_loop, get(), [](uv_getaddrinfo_t* req, int status, struct addrinfo* res) { std::shared_ptr<addrinfo> res_holder(res, [](addrinfo* res) { uv_freeaddrinfo(res); }); char addr[128] = {'\0'}; bool is_ip4; error err = read_addr_info(status, res, addr, is_ip4); callbacks::invoke<decltype(callback)>(req->data, internal::uv_cid_resolve, err, is_ip4, addr); }, addr.c_str(), 0, 0)); }
void httpconnection_on_resolved(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { HTTPConnection* c = static_cast<HTTPConnection*>(req->data); if(status == -1) { RX_ERROR("> cannot revolve host: %s", c->host.c_str()); return; } char ip[17] = {0}; uv_ip4_name((struct sockaddr_in*)res->ai_addr, ip, 16); int r = uv_tcp_connect(&c->connect_req, c->sock, *(struct sockaddr_in*)res->ai_addr, httpconnection_on_connect); uv_freeaddrinfo(res); }
static void on_resolve(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { Resolver* resolver = static_cast<Resolver*>(req->data); if (status != 0) { resolver->status_ = FAILED_UNABLE_TO_RESOLVE; } else if (!resolver->address_.init(res->ai_addr)) { resolver->status_ = FAILED_UNSUPPORTED_ADDRESS_FAMILY; } else { resolver->status_ = SUCCESS; } resolver->cb_(resolver); delete resolver; uv_freeaddrinfo(res); }
// Called after address resolution completes static void uvOnResolve(uv_getaddrinfo_t *handle, int status, struct addrinfo *response) { if (status == -1) { OnDisconnect(DISCO_RESOLVE); } else { _server_addr = response->ai_addr[0]; CAT_ENFORCE(!uv_udp_bind(&_uv_udp, &_server_addr, 0)); SendHello(); CAT_ENFORCE(!uv_timer_init(&_uv_loop, &_uv_hello)); CAT_ENFORCE(!uv_timer_start(&_uv_hello, callback, 200, 200)); } uv_freeaddrinfo(response); }
static void address_cb(uv_getaddrinfo_t *req, int status, struct addrinfo *addrs) { struct addrinfo *ai; char addrbuf[INET6_ADDRSTRLEN + 1]; const void *addrv; union { struct sockaddr addr; struct sockaddr_in addr4; struct sockaddr_in6 addr6; } s; if (status < 0) { printf("get address info has cancel it\n"); return; } for (ai = addrs; ai != NULL; ai = ai->ai_next) { printf("==> GET AN ADDRESS\n"); printf(" FAMILY:%s\n",ai->ai_family == AF_INET ? "IPV4" : "IPV6"); if (ai->ai_family == AF_INET) { s.addr4 = *(const struct sockaddr_in *)ai->ai_addr; addrv = &s.addr4.sin_addr; } else if (ai->ai_family == AF_INET6) { s.addr6 = *(const struct sockaddr_in6 *)ai->ai_addr; addrv = &s.addr6.sin6_addr; } else { printf("UNREACHABLE\n"); return; } if (uv_inet_ntop(s.addr.sa_family, addrv, addrbuf, sizeof(addrbuf))) { printf("UNREACHABLE\n"); return; } printf(" ADDRESS:%s\n",addrbuf); } uv_freeaddrinfo(addrs); uv_stop(uv_default_loop()); }
static void luv_getaddrinfo_cb(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { lua_State* L = luv_state(req->loop); int nargs; if (status < 0) { luv_status(L, status); nargs = 1; } else { lua_pushnil(L); luv_pushaddrinfo(L, res); nargs = 2; } luv_fulfill_req(L, (luv_req_t*)req->data, nargs); luv_cleanup_req(L, (luv_req_t*)req->data); req->data = NULL; if (res) uv_freeaddrinfo(res); }
void on_resolved(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res) { if (status < 0) { fprintf(stderr, "getaddrinfo callback error %s\n", uv_err_name(status)); return; } char addr[17] = {'\0'}; uv_ip4_name((struct sockaddr_in*) res->ai_addr, addr, 16); fprintf(stderr, "%s\n", addr); uv_connect_t *connect_req = (uv_connect_t*) malloc(sizeof(uv_connect_t)); uv_tcp_t *socket = (uv_tcp_t*) malloc(sizeof(uv_tcp_t)); uv_tcp_init(loop, socket); uv_tcp_connect(connect_req, socket, (const struct sockaddr*) res->ai_addr, on_connect); uv_freeaddrinfo(res); }
void net_resolve_cb(uv_getaddrinfo_t *rv, int stat, net_ai * ai) { net_t * net = (net_t*) rv->data; err_t err; socketPair_t dest; char addr[INET6_ADDRSTRLEN]; int ret; if (stat != 0) { err = uv_last_error(net->loop); if (net->error_cb) { net->error_cb(net, err, (char *) uv_strerror(err)); } else { printf("error(%s:%d) %s", net->hostname, net->port, (char *) uv_strerror(err)); net_free(net); } return; } uv_ip4_name((socketPair_t *) ai->ai_addr, addr, INET6_ADDRSTRLEN); dest = uv_ip4_addr(addr, net->port); /* * create tcp instance. */ uv_tcp_init(net->loop, net->handle); ret = uv_tcp_connect(net->conn, net->handle, dest, net_connect_cb); if (ret != NET_OK) { err = uv_last_error(net->loop); if (net->error_cb) { net->error_cb(net, err, (char *) uv_strerror(err)); } else { printf("error(%s:%d) %s", net->hostname, net->port, (char *) uv_strerror(err)); net_free(net); } return; } /* * free */ uv_freeaddrinfo(ai); }
/** * the static callback called by the C-level routines in uv. it's main job is to call a C++ level callback to do the work with higher layers * * from uv.h * typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, * int status, * struct addrinfo* res); */ void UVEventLoop::OnResolved(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res) { UVResolver* ocCBp=nullptr; if (resolver) { ocCBp=static_cast<UVResolver*>(resolver->data); } sockaddr adr; if (status >= 0 && res->ai_addr) { adr = *res->ai_addr; if (ocCBp && ocCBp->client && ocCBp->client->address) { *ocCBp->client->address = adr; } uv_freeaddrinfo(res); } if (ocCBp) { if (ocCBp->bindCB) { (*ocCBp->bindCB)(&adr, status); } ocCBp->disposed = true; } }
static void getaddrinfo_callback(uv_getaddrinfo_t *req, int status, struct addrinfo *res) { request *r = (request *)req->data; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_error *error; int retry_status; gpr_free(req); retry_status = retry_named_port_failure(status, r, getaddrinfo_callback); if (retry_status == 0) { // The request is being retried. Nothing should be done here return; } /* Either no retry was attempted, or the retry failed. Either way, the original error probably has more interesting information */ error = handle_addrinfo_result(status, res, r->addresses); grpc_closure_sched(&exec_ctx, r->on_done, error); grpc_exec_ctx_finish(&exec_ctx); gpr_free(r->hints); gpr_free(r); uv_freeaddrinfo(res); }
static void on_addrinfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { luv_callback_t* callback = req->data; lua_State* L = callback->L; struct addrinfo* curr = res; char ip[INET6_ADDRSTRLEN]; const char *addr; int port; int i = 1; /* Get the callback and remove the reference to it. */ lua_rawgeti(L, LUA_REGISTRYINDEX, callback->ref); luaL_unref(L, LUA_REGISTRYINDEX, callback->ref); free(callback); free(req); lua_newtable(L); for (curr = res; curr; curr = curr->ai_next) { if (curr->ai_family == AF_INET || curr->ai_family == AF_INET6) { lua_newtable(L); if (curr->ai_family == AF_INET) { addr = (char*) &((struct sockaddr_in*) curr->ai_addr)->sin_addr; port = ((struct sockaddr_in*) curr->ai_addr)->sin_port; lua_pushstring(L, "IPv4"); lua_setfield(L, -2, "family"); } else { addr = (char*) &((struct sockaddr_in6*) curr->ai_addr)->sin6_addr; port = ((struct sockaddr_in6*) curr->ai_addr)->sin6_port; lua_pushstring(L, "IPv6"); lua_setfield(L, -2, "family"); } uv_inet_ntop(curr->ai_family, addr, ip, INET6_ADDRSTRLEN); lua_pushstring(L, ip); lua_setfield(L, -2, "addr"); if (ntohs(port)) { lua_pushinteger(L, ntohs(port)); lua_setfield(L, -2, "port"); } if (curr->ai_socktype == SOCK_STREAM) { lua_pushstring(L, "STREAM"); lua_setfield(L, -2, "socktype"); } else if (curr->ai_socktype == SOCK_DGRAM) { lua_pushstring(L, "DGRAM"); lua_setfield(L, -2, "socktype"); } switch (curr->ai_protocol) { #ifdef AF_UNIX case AF_UNIX: lua_pushstring(L, "UNIX"); break; #endif #ifdef AF_INET case AF_INET: lua_pushstring(L, "INET"); break; #endif #ifdef AF_INET6 case AF_INET6: lua_pushstring(L, "INET6"); break; #endif #ifdef AF_IPX case AF_IPX: lua_pushstring(L, "IPX"); break; #endif #ifdef AF_NETLINK case AF_NETLINK: lua_pushstring(L, "NETLINK"); break; #endif #ifdef AF_X25 case AF_X25: lua_pushstring(L, "X25"); break; #endif #ifdef AF_AX25 case AF_AX25: lua_pushstring(L, "AX25"); break; #endif #ifdef AF_ATMPVC case AF_ATMPVC: lua_pushstring(L, "ATMPVC"); break; #endif #ifdef AF_APPLETALK case AF_APPLETALK: lua_pushstring(L, "APPLETALK"); break; #endif #ifdef AF_PACKET case AF_PACKET: lua_pushstring(L, "PACKET"); break; #endif default: lua_pushstring(L, NULL); } lua_setfield(L, -2, "protocol"); lua_pushstring(L, curr->ai_canonname); lua_setfield(L, -2, "canonname"); lua_rawseti(L, -2, i++); } } uv_freeaddrinfo(res); luv_call(L, 1, 0); }
int HTTPServerListen(HTTPServerRef const server, strarg_t const address, strarg_t const port) { if(!server) return 0; assertf(!server->socket->data, "HTTPServer already listening"); int rc; rc = uv_tcp_init(async_loop, server->socket); if(rc < 0) return rc; server->socket->data = server; struct addrinfo const hints = { .ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_NUMERICSERV | AI_PASSIVE, .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_protocol = 0, // ??? }; struct addrinfo *info; rc = async_getaddrinfo(address, port, &hints, &info); if(rc < 0) { HTTPServerClose(server); return rc; } int bound = 0; rc = 0; for(struct addrinfo *each = info; each; each = each->ai_next) { rc = uv_tcp_bind(server->socket, each->ai_addr, 0); if(rc >= 0) bound++; } uv_freeaddrinfo(info); if(!bound) { HTTPServerClose(server); if(rc < 0) return rc; return UV_EADDRNOTAVAIL; } rc = uv_listen((uv_stream_t *)server->socket, 511, connection_cb); if(rc < 0) { HTTPServerClose(server); return rc; } return 0; } int HTTPServerListenSecure(HTTPServerRef const server, strarg_t const address, strarg_t const port, struct tls **const tlsptr) { if(!server) return 0; int rc = HTTPServerListen(server, address, port); if(rc < 0) return rc; server->secure = *tlsptr; *tlsptr = NULL; return 0; } void HTTPServerClose(HTTPServerRef const server) { if(!server) return; if(!server->socket->data) return; if(server->secure) tls_close(server->secure); tls_free(server->secure); server->secure = NULL; async_close((uv_handle_t *)server->socket); } static void connection(uv_stream_t *const socket) { HTTPServerRef const server = socket->data; HTTPConnectionRef conn; int rc = HTTPConnectionCreateIncomingSecure(socket, server->secure, 0, &conn); if(rc < 0) { fprintf(stderr, "HTTP server connection error %s\n", uv_strerror(rc)); return; } assert(conn); for(;;) { server->listener(server->context, server, conn); rc = HTTPConnectionDrainMessage(conn); if(rc < 0) break; } HTTPConnectionFree(&conn); }
/* Bind a server to each address that getaddrinfo() reported. */ static void do_bind(uv_getaddrinfo_t *req, int status, struct addrinfo *addrs) { char addrbuf[INET6_ADDRSTRLEN + 1]; unsigned int ipv4_naddrs; unsigned int ipv6_naddrs; server_state *state; server_config *cf; struct addrinfo *ai; const void *addrv; const char *what; uv_loop_t *loop; server_ctx *sx; unsigned int n; int err; union { struct sockaddr addr; struct sockaddr_in addr4; struct sockaddr_in6 addr6; } s; state = CONTAINER_OF(req, server_state, getaddrinfo_req); loop = state->loop; cf = &state->config; if (status < 0) { pr_err("getaddrinfo(\"%s\"): %s", cf->bind_host, uv_strerror(status)); uv_freeaddrinfo(addrs); return; } ipv4_naddrs = 0; ipv6_naddrs = 0; for (ai = addrs; ai != NULL; ai = ai->ai_next) { if (ai->ai_family == AF_INET) { ipv4_naddrs += 1; } else if (ai->ai_family == AF_INET6) { ipv6_naddrs += 1; } } if (ipv4_naddrs == 0 && ipv6_naddrs == 0) { pr_err("%s has no IPv4/6 addresses", cf->bind_host); uv_freeaddrinfo(addrs); return; } state->servers = xmalloc((ipv4_naddrs + ipv6_naddrs) * sizeof(state->servers[0])); n = 0; for (ai = addrs; ai != NULL; ai = ai->ai_next) { if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) { continue; } if (ai->ai_family == AF_INET) { s.addr4 = *(const struct sockaddr_in *) ai->ai_addr; s.addr4.sin_port = htons(cf->bind_port); addrv = &s.addr4.sin_addr; } else if (ai->ai_family == AF_INET6) { s.addr6 = *(const struct sockaddr_in6 *) ai->ai_addr; s.addr6.sin6_port = htons(cf->bind_port); addrv = &s.addr6.sin6_addr; } else { UNREACHABLE(); } if (uv_inet_ntop(s.addr.sa_family, addrv, addrbuf, sizeof(addrbuf))) { UNREACHABLE(); } sx = state->servers + n; sx->loop = loop; sx->idle_timeout = state->config.idle_timeout; CHECK(0 == uv_tcp_init(loop, &sx->tcp_handle)); what = "uv_tcp_bind"; err = uv_tcp_bind(&sx->tcp_handle, &s.addr, 0); if (err == 0) { what = "uv_listen"; err = uv_listen((uv_stream_t *) &sx->tcp_handle, 128, on_connection); } if (err != 0) { pr_err("%s(\"%s:%hu\"): %s", what, addrbuf, cf->bind_port, uv_strerror(err)); while (n > 0) { n -= 1; uv_close((uv_handle_t *) (state->servers + n), NULL); } break; } pr_info("listening on %s:%hu", addrbuf, cf->bind_port); n += 1; } uv_freeaddrinfo(addrs); }