Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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;
  }
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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. */
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
    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_);
    }
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
void getaddrinfo_cb(uv_getaddrinfo_t* handle, int status,
        struct addrinfo* response) {

    printf("%s \n", handle->data);

    free(handle);
    uv_freeaddrinfo(response);
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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);
}
Ejemplo n.º 14
0
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);
}
Ejemplo n.º 15
0
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);
}
Ejemplo n.º 16
0
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);
}
Ejemplo n.º 17
0
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);
}
Ejemplo n.º 18
0
 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);
}
Ejemplo n.º 20
0
    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);
    }
Ejemplo n.º 21
0
	// 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);
	}
Ejemplo n.º 22
0
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());
}
Ejemplo n.º 23
0
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);
}
Ejemplo n.º 24
0
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);
}
Ejemplo n.º 25
0
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);
}
Ejemplo n.º 26
0
/**
 * 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;
	}
}
Ejemplo n.º 27
0
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);
}
Ejemplo n.º 28
0
Archivo: dns.c Proyecto: tarruda/luv
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);
}
Ejemplo n.º 29
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);
}
Ejemplo n.º 30
0
/* 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);
}