static int
dns_lookup (const char *addr_str, struct sockaddr_in *sa, ev_socklen_t *sa_len)
{
    struct evutil_addrinfo hints;
    struct evutil_addrinfo *answer = NULL;
    int err;

    /* Build the hints to tell getaddrinfo how to act. */
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET; /* only use IPv4 now. */
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP; /* We want a TCP socket */
    /* Only return addresses we can use. */
    hints.ai_flags = EVUTIL_AI_ADDRCONFIG;

    /* Look up the hostname. */
    err = evutil_getaddrinfo(addr_str, NULL, &hints, &answer);
    if (err != 0) {
          seaf_warning("Error while resolving '%s': %s\n",
                       addr_str, evutil_gai_strerror(err));
          return -1;
    }

    *sa = *((struct sockaddr_in *)answer->ai_addr);
    *sa_len = (ev_socklen_t)answer->ai_addrlen;

    evutil_freeaddrinfo (answer);
    return 0;
}
Exemple #2
0
static void
start_listening(struct event_base *base, struct evdns_base *dns,
		const char *laddr, const char *lport)
{
	struct evutil_addrinfo hints;
	struct evutil_addrinfo *ai = NULL;
	int ret;

	if (!evutil_ascii_strcasecmp(laddr, "any"))
		laddr = NULL;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	/* turn NULL hostname into INADDR_ANY, and skip looking up any address
	 * types we don't have an interface to connect to. */
	hints.ai_flags = EVUTIL_AI_PASSIVE|EVUTIL_AI_ADDRCONFIG;

	ret = evutil_getaddrinfo(laddr, lport, &hints, &ai);
	if (ret < 0) {
		log_error("shim: bad listen address: %s",
			  evutil_gai_strerror(ret));
		exit(1);
        }
	
	if (proxy_init(base, dns, ai->ai_addr, ai->ai_addrlen) < 0)
		exit(1);
}
void bev_connect_cb(struct bufferevent* bev, short events, void* arg)
{
	jsonrpc_server_t* server = (jsonrpc_server_t*)arg;
	if(!arg) {
		ERR("Trying to connect null server\n");
		return;
	}

	if (events & (BEV_EVENT_ERROR|BEV_EVENT_EOF)) {
		WARN("Connection error for %.*s:%d\n", STR(server->addr), server->port);
		if (events & BEV_EVENT_ERROR) {
			int err = bufferevent_socket_get_dns_error(bev);
			if(err) {
				ERR("DNS error for %.*s: %s\n",
					STR(server->addr), evutil_gai_strerror(err));
			}
		}
		goto failed;
	} else if(events & BEV_EVENT_CONNECTED) {

		if (server->status == JSONRPC_SERVER_CONNECTED) {
			return;
		}

		server->status = JSONRPC_SERVER_CONNECTED;
		INFO("Connected to host %.*s:%d\n",
				STR(server->addr), server->port);
	}

	return;

failed:
	connect_failed(server);
}
Exemple #4
0
zend_object * ion_stream_get_exception(ion_stream * stream, ion_buffer * bev) {
    zend_ulong         error_ulong = 0;
    int                error_int = 0;
    const char       * error_message;
    zend_object      * exception;
    void             * exception_ce;
    zend_string      * desc = ion_stream_describe(stream);

    if((error_ulong =  bufferevent_get_openssl_error(bev))) { // problem with openssl connection
        error_message = ERR_error_string(error_ulong, NULL);
        exception_ce = ion_ce_ION_CryptoException;
    } else if((error_int =  bufferevent_socket_get_dns_error(bev))) { // DNS problem
        error_message = evutil_gai_strerror(error_int);
        exception_ce = ion_ce_ION_DNSException;
    } else if((error_int = EVUTIL_SOCKET_ERROR())) { // socket problem
        error_message = evutil_socket_error_to_string(error_int);
        exception_ce = ion_ce_ION_StreamException;
    } else { // magic problem
        error_message = "stream corrupted";
        exception_ce = ion_ce_ION_StreamException;
    }

    exception = pion_exception_new_ex(
            exception_ce, 0,
            "%s error: %s", desc->val, error_message
    );
    zend_string_release(desc);
    return exception;
}
Exemple #5
0
/* Bufferevent event callback for the connect_hostname test: remembers what
 * event we got. */
static void
be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx)
{
	struct be_conn_hostname_result *got = ctx;
	if (!got->what) {
		TT_BLATHER(("Got a bufferevent event %d", what));
		got->what = what;

		if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) {
			int r;
			++total_connected_or_failed;
			TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed));
			if ((r = bufferevent_socket_get_dns_error(bev))) {
				got->dnserr = r;
				TT_BLATHER(("DNS error %d: %s", r,
					   evutil_gai_strerror(r)));
			}
			if (total_connected_or_failed >= 5)
				event_base_loopexit(be_connect_hostname_base,
				    NULL);
		}
	} else {
		TT_FAIL(("Two events on one bufferevent. %d,%d",
			got->what, (int)what));
	}
}
Exemple #6
0
static void resolve_cb(int errcode,struct evutil_addrinfo *addr,void *priv) {
  struct dnsreq *dr = (struct dnsreq *)priv;
  struct evutil_addrinfo *ai;
  char *s;
  int n;

  n = 0;
  for(ai=addr;ai;ai=ai->ai_next) {
    s = addrinfo_to_string(ai);
    if(s)
      n++;
    free(s);
  }
  if(!n) {
    // XXX log it
    fprintf(stderr,"dns error='%s'\n",evutil_gai_strerror(errcode));
    dr->cb(0,dr->priv);
  } else {
    n = rand()%n;
    for(ai=addr;ai;ai=ai->ai_next) {
      s = addrinfo_to_string(ai);
      if(s && !n--)
        dr->cb(s,dr->priv);
      free(s);
    }
  }
  if(addr) { evutil_freeaddrinfo(addr); }
  free(dr);
}
Exemple #7
0
void eventcb(struct bufferevent *bev, short events, void *ptr)
{
	int err = EVUTIL_SOCKET_ERROR();
	evutil_socket_t fd =bufferevent_getfd(bev);
	printf("eventcb, fd=%d \n", fd);

    if (events & BEV_EVENT_CONNECTED) {
         /* We're connected to 127.0.0.1:8080.   Ordinarily we'd do
            something here, like start reading or writing. */
		printf("eventcb, BEV_EVENT_CONNECTED \n");
		connected =1;
    } else if (events & BEV_EVENT_ERROR) {
		/* An error occured while connecting. */
		printf("eventcb, BEV_EVENT_ERROR , %d,%s\n", err,evutil_socket_error_to_string(err));
		
		int errdns = bufferevent_socket_get_dns_error(bev);
		if (errdns)
			printf("eventcb, DNS error: %d:%s\n", errdns, evutil_gai_strerror(errdns));
		connected =-1;
	} else{
		/* An error occured while connecting. */
		printf("eventcb, Other ERROR , %d,%s\n", err,evutil_socket_error_to_string(err));
		connected =-1;
	}

	if (connected==-1)
	{
		printf("---- eventcb, bufferevent_free %p \n", bev);
		bufferevent_free(bev);
	}
}
Exemple #8
0
static void *
dns_lookup (void *vdata)
{
    DNSLookupData *data = vdata;
    struct evutil_addrinfo hints;
    struct evutil_addrinfo *answer = NULL;
    int err;
    void *addr;
    char *addr_str;
    socklen_t size;

    /* Build the hints to tell getaddrinfo how to act. */
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET; /* only use IPv4 now. */
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP; /* We want a TCP socket */
    /* Only return addresses we can use. */
    hints.ai_flags = EVUTIL_AI_ADDRCONFIG;

    /* Look up the hostname. */
    err = evutil_getaddrinfo(data->peer->public_addr, NULL, &hints, &answer);
    if (err != 0) {
          ccnet_warning("Error while resolving '%s': %s\n",
                        data->peer->public_addr, evutil_gai_strerror(err));
          return vdata;
    }

    /* just use the first answer */
    if (answer->ai_family == AF_INET) {
        size = INET_ADDRSTRLEN;
        addr = &((struct sockaddr_in *)(answer->ai_addr))->sin_addr;
    } else if (answer->ai_family == AF_INET6) {
        size = INET6_ADDRSTRLEN;
        addr = &((struct sockaddr_in6 *)(answer->ai_addr))->sin6_addr;
    } else
        goto out;

    addr_str = (char *)calloc(size, sizeof(char));
    if (addr_str == NULL) {
        ccnet_error("Out of memory\n");
        goto out;
    }

    if (!inet_ntop(answer->ai_family, addr, addr_str, size)) {
        ccnet_warning("Peer %s domain name %s lookup fail\n",
                      data->peer->name, data->peer->public_addr);
        free(addr_str);
        goto out;
    }

    data->addr_str = addr_str;

out:
    evutil_freeaddrinfo (answer);
    return vdata;
}
static void dns_cb(int errcode, struct evutil_addrinfo *addr, void *ptr)
{
	struct evutil_addrinfo *ai;
	struct timeval tv;
	const char *host = ptr;

	if (errcode) {
		tmate_status_message("%s lookup failure. Retrying in %d seconds (%s)",
				     host, TMATE_DNS_RETRY_TIMEOUT,
				     evutil_gai_strerror(errcode));

		tv.tv_sec = TMATE_DNS_RETRY_TIMEOUT;
		tv.tv_usec = 0;

		evtimer_assign(&tmate_session.ev_dns_retry, tmate_session.ev_base,
			       on_dns_retry, NULL);
		evtimer_add(&tmate_session.ev_dns_retry, &tv);

		return;
	}

	tmate_status_message("Connecting to %s...", host);

	for (ai = addr; ai; ai = ai->ai_next) {
		char buf[128];
		const char *ip = NULL;
		if (ai->ai_family == AF_INET) {
			struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
			ip = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, 128);
		} else if (ai->ai_family == AF_INET6) {
			struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr;
			ip = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, 128);
		}

		tmate_debug("Trying server %s", ip);

		/*
		 * Note: We don't deal with the client list. Clients manage it
		 * and free client structs when necessary.
		 */
		(void)tmate_ssh_client_alloc(&tmate_session, ip);
	}

	evutil_freeaddrinfo(addr);

	/*
	 * XXX For some reason, freeing the DNS resolver makes MacOSX flip out...
	 * not sure what's going on...
	 * evdns_base_free(tmate_session.ev_dnsbase, 0);
	 * tmate_session.ev_dnsbase = NULL;
	 */
}
Exemple #10
0
Fichier : hub.c Projet : nizox/hub
void
hub_add_peer(struct hub *hub, char const *address)
{
  int e;
  char *hostname, *ptr, port[6];
  struct evutil_addrinfo hints, *answer = NULL;
  struct peer *peer;

  if ((ptr = strchr(address, ':')))
  {
    hostname = calloc(ptr - address + 1, sizeof(*hostname));
    if (!hostname) err(1, NULL);
    strncpy(hostname, address, ptr - address);
    strncpy(port, ptr + 1, sizeof(port));
  }
  else
  {
    hostname = (char *) address;
    evutil_snprintf(port, sizeof(port), "%hi", hub->port);
  }

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_flags = EVUTIL_AI_ADDRCONFIG;

  if ((e = evutil_getaddrinfo(hostname, port, &hints, &answer)) < 0)
  {
    fprintf(stderr, "Error while resolving '%s': %s", hostname,
        evutil_gai_strerror(e));
    return;
  }

  if (!answer)
    return;

  peer = calloc(1, sizeof(*peer));
  if (!peer) err(1, NULL);
  peer->name = address;

  peer->addrlen = answer->ai_addrlen;
  peer->addr = malloc(peer->addrlen);
  if (!peer->addr) err(1, NULL);
  memcpy(peer->addr, answer->ai_addr, peer->addrlen);

  peer->next = hub->peers;
  hub->peers = peer;

  evutil_freeaddrinfo(answer);
}
Exemple #11
0
static void _ws_error_event(struct bufferevent *bev, short events, void *ptr)
{
	const char *err_msg;
	int err;
	ws_t ws = (ws_t)ptr;
	assert(ws);

	LIBWS_LOG(LIBWS_DEBUG, "Error raised");

	if (ws->state == WS_STATE_DNS_LOOKUP)
	{
		err = bufferevent_socket_get_dns_error(ws->bev);
		err_msg = evutil_gai_strerror(err);

		LIBWS_LOG(LIBWS_ERR, "DNS error %d: %s", err, err_msg);
	}
	else
	{
		err = EVUTIL_SOCKET_ERROR();
		err_msg = evutil_socket_error_to_string(err);

		LIBWS_LOG(LIBWS_ERR, "%s (%d)", err_msg, err);

		// See if the serve closed on us.
		_ws_read_websocket(ws, bufferevent_get_input(ws->bev));

		if (!ws->received_close)
		{
			ws->server_close_status = WS_CLOSE_STATUS_ABNORMAL_1006;
		}

		if (ws->close_cb)
		{
			LIBWS_LOG(LIBWS_ERR, "Abnormal close by server");
			ws->close_cb(ws, ws->server_close_status, 
				err_msg, strlen(err_msg), ws->close_arg);
		}
	}

	// TODO: Should there even be an erro callback?
	if (ws->err_cb)
	{
		ws->err_cb(ws, err, err_msg, ws->err_arg);
	}
	else
	{
		_ws_shutdown(ws);
	}
}
void eventcb(struct bufferevent *bev, short events, void *ptr)
{
    if (events & BEV_EVENT_CONNECTED) {
         printf("Connect okay.\n");
    } else if (events & (BEV_EVENT_ERROR|BEV_EVENT_EOF)) {
         struct event_base *base = ptr;
         if (events & BEV_EVENT_ERROR) {
		 int err = bufferevent_socket_get_dns_error(bev);
		 if (err)
			 printf("DNS error: %s\n", evutil_gai_strerror(err));
         }
         printf("Closing\n");
         bufferevent_free(bev);
         event_base_loopexit(base, NULL);
    }
}
Exemple #13
0
void CDNSManager::LookupDNSCallback(int _errcode, struct evutil_addrinfo *_addr, void* _context)
{
    DNS_RECORD_t* record = (DNS_RECORD_t*)_context;
 
    if (_errcode)
    {
        LOG_ERROR_STREAM << "Fail to parse " << record->name << ": " << evutil_gai_strerror(_errcode);
    }
    else
    {
        record->address.clear();
        record->visitTime = time(NULL);
        record->status = MAIN_TABLE_RECORD_t::STATUS_e::STATUS_READY;
        if (_addr->ai_canonname)    record->cname = _addr->ai_canonname;

        //
        // get ip addresses
        //
        struct evutil_addrinfo  *ai;
        for (ai = _addr; ai; ai = ai->ai_next) 
        {
            char buf[128] = { 0 };
            const char* ipAddr = NULL;
            if (ai->ai_family == AF_INET) 
            {
                struct sockaddr_in* sin = (struct sockaddr_in *)ai->ai_addr;
                ipAddr = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf));
            }
            else if (ai->ai_family == AF_INET6) 
            {
                struct sockaddr_in6* sin6 = (struct sockaddr_in6 *)ai->ai_addr;
                ipAddr = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
            }

            if (ipAddr)
            {
                record->address += ipAddr;
                record->address += ", ";
            }
        }

        evutil_freeaddrinfo(_addr);
    }

    if (--s_pendingLookupCount == 0)
        event_base_loopexit(CDNSManager::GetInstance()->m_evbase, NULL);        
}
Exemple #14
0
void dns_cb(int errcode, struct evutil_addrinfo *addr, void *ptr)
{
    site_t *si = (site_t *) ptr;
    
    const char *host = si->host;
    if (errcode)
    {
        si->dns_state = ERROR_DNS;
        statis.dns_err_sites++;
        log_error("%s -> %s\n", host, evutil_gai_strerror(errcode));
    }
    else
    {
        struct evutil_addrinfo *ai;
        if (addr->ai_canonname)
            si->cname = strdup(addr->ai_canonname);
        int i = 0;
        for (ai = addr; ai; ai = ai->ai_next)
        {
            if (ai->ai_family == AF_INET)
            {
            	if (i < MAX_ADDRS)
            	{
            		si->addr[i++] = *((struct sockaddr_in *)ai->ai_addr);
            	}
            }
        }
        evutil_freeaddrinfo(addr);
        if(i > 0)
        {
            si->dns_state = DONE_DNS;
            si->next_call = (time_t)0;
            statis.dns_ok_sites++;
            if (!site_empty(si) && !si->in_ready_fifo)
            {
                ready_fifo_put(si);
            }
        }
    }
    statis.dns_calls--;

    /* fetch_dns(); */
    /* fetch_pages(); */
}
Exemple #15
0
void eventcb(struct bufferevent *bev, short events, void *ptr)
{
    struct info *inf = ptr;
    if (events & BEV_EVENT_CONNECTED) {
        printf("Connect okay.\n");
        bufferevent_enable(bev, EV_READ|EV_WRITE);

        submit(bev, inf->msg[0]);
        clock_gettime(CLOCK_REALTIME, &inf->start);

    } else if (events & (BEV_EVENT_ERROR|BEV_EVENT_EOF)) {
         if (events & BEV_EVENT_ERROR) {
                 int err = bufferevent_socket_get_dns_error(bev);
                 if (err)
                         printf("DNS error: %s\n", evutil_gai_strerror(err));
         }
         printf("Closing\n");
         event_base_loopexit(inf->base, NULL);
    }
}
Exemple #16
0
void TS3::telnetEvent(bufferevent *bev, short event, void *parentPtr)
{
	if (event & BEV_EVENT_CONNECTED) {
		LOG(INFO) << "Connected to TeamSpeak server";
	} else if (event & BEV_EVENT_TIMEOUT) {
		bufferevent_enable(bev, EV_READ|EV_WRITE);
		evbuffer_add_printf(bufferevent_get_output(bev), "whoami\n");
	} else if (event & (BEV_EVENT_ERROR|BEV_EVENT_EOF)) {
		auto parent = static_cast<TS3*>(parentPtr);
		if (event & BEV_EVENT_ERROR) {
			int err = bufferevent_socket_get_dns_error(bev);
			if (err)
				LOG(ERROR) << "Can't connect to TeamSpeak server, DNS error: " << evutil_gai_strerror(err);
		}
		LOG(ERROR) << "TeamSpeak connection closed";
		// FIXME needs a reliable restart mechanism, see thread
		parent->SendMessage("TS3 ServerQuery connection closed, fix me please");
		bufferevent_free(bev);
		event_base_loopexit(parent->_base, nullptr);
	}
}
Exemple #17
0
void Spider_Url_Rinse::dns_callback(int errcode, struct evutil_addrinfo *addr, void *ptr)
{
	dns_cb_arg *arg = (dns_cb_arg *)ptr;
	UrlPtr myurl = arg->url_ptr;

	if (errcode)
	{
		LLOG(L_ERROR,"DNS parse error:%s -> %s\n", myurl->domain, evutil_gai_strerror(errcode));
	}
	else
	{
		struct evutil_addrinfo *ai=addr;
		char buf[128];
		const char *s = NULL;
		if (addr->ai_family == AF_INET)
		{
			struct sockaddr_in *sin =(struct sockaddr_in *)ai->ai_addr;
			s = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, 128);	/*从套接口内部数据类型转换为点分十进制 */
		}
		else if (addr->ai_family == AF_INET6)
		{
			struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr;
			s = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf,128);
		}
		if (s)
		{
			myurl->ip=strdup(s);
			arg->pthis->put_url_to_executor(myurl);
			arg->pthis->m_dns_database[std::string(myurl->domain)] = std::string(myurl->ip);
			arg->pthis->record_domain(myurl->domain);
		}
		evutil_freeaddrinfo(addr);
	}

	if (--g_pending_requests == 0)
	{
		event_base_loopexit(arg->pthis->m_evbase, NULL);
	}
}
Exemple #18
0
void socks_resolvecb(int result, struct evutil_addrinfo *ai, void *arg)
{
	struct conninfo *info = arg;

	if (result) {
		char buf[256];
		evutil_snprintf(buf, sizeof(buf), "DNS Failure: %s",
				evutil_gai_strerror(result));
		finish_connection(info, 0, buf);
	} else {
		log_debug("conn: socks resolve %s",
			  format_addr(ai->ai_addr));
		assert(ai->ai_addrlen <= sizeof(info->addr));
		memcpy(&info->addr, ai->ai_addr, ai->ai_addrlen);
		info->addr_len = ai->ai_addrlen;
		bufferevent_socket_connect(info->bev,
					   (struct sockaddr*)&socks_addr,
					   socks_addr_len);
	}

	if (ai)
		evutil_freeaddrinfo(ai);
}
Exemple #19
0
int
conn_set_socks_server(const char *name, int port, enum socks_ver ver)
{
	int ret;
	int rv = -1;	
	struct evutil_addrinfo *ai = NULL;
	struct evutil_addrinfo hint;
	char portstr[NI_MAXSERV];

	assert(ver != SOCKS_NONE);

	evutil_snprintf(portstr, sizeof(portstr), "%d", port);
	memset(&hint, 0, sizeof(hint));
	hint.ai_family = AF_UNSPEC;
	hint.ai_protocol = IPPROTO_TCP;
	hint.ai_socktype = SOCK_STREAM;
	hint.ai_flags = EVUTIL_AI_ADDRCONFIG;

	ret = evutil_getaddrinfo(name, portstr, &hint, &ai);
	if (!ret) {
		rv = 0;
		memset(&socks_addr, 0, sizeof(socks_addr));
		memcpy(&socks_addr, ai->ai_addr, ai->ai_addrlen);
		socks_addr_len = ai->ai_addrlen;
		use_socks = ver;
		log_notice("conn: socks server set to %s",
			   format_addr((struct sockaddr*)&socks_addr));
	} else {
		log_error("conn: can't resolve socks server %s: %s",
			  name, evutil_gai_strerror(ret));
	}
	
	if (ai)
		evutil_freeaddrinfo(ai);

	return rv;
}
Exemple #20
0
void
eventcb(struct bufferevent * bev, short events, void * ptr) {
    if (events & BEV_EVENT_CONNECTED) {
        struct timeval tv;

        tv.tv_sec  = sec;
        tv.tv_usec = usec;

        evtimer_add(sev, &tv);
        return;
    } else if (events & (BEV_EVENT_ERROR | BEV_EVENT_EOF)) {
        struct event_base * base = ptr;
        if (events & BEV_EVENT_ERROR) {
            int err = bufferevent_socket_get_dns_error(bev);

            if (err) {
                printf("DNS error: %s\n", evutil_gai_strerror(err));
            }
        }
        printf("Closing\n");
        bufferevent_free(bev);
        event_base_loopexit(base, NULL);
    }
}
Exemple #21
0
int
rs_packet_send (struct rs_packet *pkt, void *user_data)
{
  struct rs_connection *conn = NULL;
  int err = 0;

  assert (pkt);
  assert (pkt->conn);
  conn = pkt->conn;

  if (_conn_is_open_p (conn))
    packet_do_send (pkt);
  else
    if (_conn_open (conn, pkt))
      return -1;

  assert (conn->evb);
  assert (conn->active_peer);
  assert (conn->fd >= 0);

  conn->user_data = user_data;

  if (conn->bev)		/* TCP */
    {
      bufferevent_setcb (conn->bev, NULL, tcp_write_cb, tcp_event_cb, pkt);
      bufferevent_enable (conn->bev, EV_WRITE);
    }
  else				/* UDP */
    {
      event_assign (conn->wev, conn->evb, event_get_fd (conn->wev),
		    EV_WRITE, event_get_callback (conn->wev), pkt);
      err = event_add (conn->wev, NULL);
      if (err < 0)
	return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
				    "event_add: %s",
				    evutil_gai_strerror (err));
    }

  /* Do dispatch, unless the user wants to do it herself.  */
  if (!conn_user_dispatch_p (conn))
    {
      conn->callbacks.sent_cb = _wcb;
      conn->user_data = pkt;
      rs_debug (("%s: entering event loop\n", __func__));
      err = event_base_dispatch (conn->evb);
      if (err < 0)
	return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
				    "event_base_dispatch: %s",
				    evutil_gai_strerror (err));
      rs_debug (("%s: event loop done\n", __func__));
      conn->callbacks.sent_cb = NULL;
      conn->user_data = NULL;

      if ((pkt->flags & RS_PACKET_SENT) == 0)
	{
	  assert (rs_err_conn_peek_code (conn));
	  return rs_err_conn_peek_code (conn);
	}
    }

  return RSE_OK;
}
void dns_query_cb(int errcode, struct evutil_addrinfo *addr, void *ptr)
{
    P_DNS_STRUCT p_dns = (P_DNS_STRUCT)ptr;

    if (errcode) 
    {
        printf("Query error for: %s -> %s\n", p_dns->hostname, evutil_gai_strerror(errcode)); 
    }
    else
    {
        struct evutil_addrinfo *ai;
        struct sockaddr_in sin;

        for (ai = addr; ai; ai = ai->ai_next) 
        {
            if (ai->ai_family == AF_INET) 
            {
                memset(&sin, 0, sizeof(sin));
                sin.sin_family = AF_INET;
                sin.sin_addr = ((struct sockaddr_in *)ai->ai_addr)->sin_addr;
                sin.sin_port = p_dns->port;

                st_d_print("REQUEST: %s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));

                int remote_socket = ss_connect_srv(&sin);
                if (remote_socket == -1)
                {
                    st_d_error("REQUEST: %s:%d FAILED!", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
                    continue;
                }

                evutil_make_socket_nonblocking(p_dns->p_c_item->socket);
                struct bufferevent *new_bev = 
                    bufferevent_socket_new(p_dns->p_threadobj->base, p_dns->p_c_item->socket, BEV_OPT_CLOSE_ON_FREE); 
                assert(new_bev);
                bufferevent_setcb(new_bev, thread_bufferread_cb_enc, NULL, thread_bufferevent_cb, p_dns->p_trans);
                bufferevent_enable(new_bev, EV_READ|EV_WRITE);

                evutil_make_socket_nonblocking(remote_socket);
                struct bufferevent *new_ext_bev = 
                    bufferevent_socket_new(p_dns->p_threadobj->base, remote_socket , BEV_OPT_CLOSE_ON_FREE); 
                assert(new_ext_bev);
                bufferevent_setcb(new_ext_bev, thread_bufferread_cb_enc, NULL, thread_bufferevent_cb, p_dns->p_trans);
                bufferevent_enable(new_ext_bev, EV_READ|EV_WRITE);

                p_dns->p_trans->bev_d = new_bev;
                p_dns->p_trans->bev_u = new_ext_bev;

                st_d_print("DDDDD: 当前活动连接数:[[[ %d ]]], 任务队列:[[ %d ]]", 
                           slist_count(&p_dns->p_trans->p_activ_item->trans), 
                           slist_count(&p_dns->p_threadobj->conn_queue)); 


                st_d_print("SS5激活客户端Bufferevent使能!");
                CTL_HEAD head;
                memset(&head, 0, CTL_HEAD_LEN);
                head.direct = USR_DAEMON; 
                head.cmd = HD_CMD_SS5_ACT; 
                head.extra_param = p_dns->p_trans->usr_lport; 
                head.mach_uuid = p_dns->p_trans->p_activ_item->mach_uuid; 
                bufferevent_write(p_dns->p_trans->p_activ_item->bev_daemon, &head, CTL_HEAD_LEN); 

                break;

            } 

            st_d_print("ALL REQUEST FOR %s FAILED!", p_dns->hostname); 

        }
        evutil_freeaddrinfo(addr);
    }

    free(p_dns->p_c_item);
    free(p_dns);

    return;
}