void Spider_Url_Rinse::dns_parse(UrlPtrVec& url_array) { for (unsigned int i = 0; i < url_array.size() ; ++i) { struct evutil_addrinfo hints; struct evdns_getaddrinfo_request *req; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = EVUTIL_AI_CANONNAME; hints.ai_protocol = IPPROTO_TCP; ++g_pending_requests; dns_cb_arg *arg = (dns_cb_arg *) calloc(sizeof(dns_cb_arg), 1); arg->url_ptr = url_array[i]; arg->pthis=this; req =evdns_getaddrinfo(m_evdnsbase, arg->url_ptr->domain, NULL, &hints, (evdns_getaddrinfo_cb)dns_callback, arg); if (req == NULL) { LLOG(L_WARN,"evdns_getaddrifo return null."); } } if (g_pending_requests) { int ret=event_base_loop(m_evbase, 0); if( ret!=0 ) LLOG(L_ERROR, "event_base_loop error code %d", ret); } return; }
void create_dns(site_t *si) { assert(si->dns_state == WAIT_DNS); assert(!si->in_ready_fifo && !si->in_wait_fifo); struct evutil_addrinfo hints; struct evdns_getaddrinfo_request *req; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = EVUTIL_AI_CANONNAME; /* Unless we specify a socktype, we'll get at least two entries for * each address: one for TCP and one for UDP. That's not what we * want. */ hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; req = evdns_getaddrinfo( dns_base, si->host, NULL /* no service name given */, &hints, dns_cb, si); if (req == NULL) { log_warn(" [request for %s returned immediately]\n", si->host); return; } /* update the number of dns calls*/ statis.dns_calls++; }
event_type<evdns_getaddrinfo_request> CDNSResolve::Resolve(const event_type<evdns_base>& dns_base, const char* host, const char* port, const evutil_addrinfo* hints) { assert(host != nullptr); assert(port != nullptr); // evdns_getaddrinfo may return NULL on success. event_type<evdns_getaddrinfo_request> result; result.reset(evdns_getaddrinfo(dns_base, host, port, hints, dns_callback, this)); return result; }
int conn_connect_bufferevent(struct bufferevent *bev, struct evdns_base *dns, int family, const char *name, int port, conn_connectcb conncb, void *arg) { struct conninfo *info; int rv = -1; info = mem_calloc(1, sizeof(*info)); info->bev = bev; info->on_connect = conncb; info->cbarg = arg; info->connecting = 1; info->socks = use_socks; bufferevent_setcb(bev, conn_readcb, NULL, conn_errorcb, info); if (use_socks != SOCKS_NONE) { info->host = mem_strdup(name); info->port = port; if (use_socks == SOCKS_4a) { rv = bufferevent_socket_connect(bev, (struct sockaddr*)&socks_addr, socks_addr_len); return rv; } #ifndef DISABLE_DIRECT_CONNECTIONS else { struct evutil_addrinfo hint; char portstr[NI_MAXSERV]; evutil_snprintf(portstr, sizeof(portstr), "%d", port); memset(&hint, 0, sizeof(hint)); hint.ai_family = AF_INET; hint.ai_protocol = IPPROTO_TCP; hint.ai_socktype = SOCK_STREAM; evdns_getaddrinfo(dns, name, portstr, &hint, socks_resolvecb, info); return 0; } #endif } #ifdef DISABLE_DIRECT_CONNECTIONS { const char *msg; msg = "Direct connections disabled, but I have no SOCKS 4a " "proxy to connect to!"; log_error("conn: %s", msg); finish_connection(info, 0, msg); } #else rv = bufferevent_socket_connect_hostname(bev, dns, family, name, port); #endif return rv; }
// XXX cancel timeout void dns_resolve(struct evdns_base *edb,const char *hostname, dns_cb cb,void *priv) { struct evutil_addrinfo hints; struct dnsreq *dr; memset(&hints,0,sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = EVUTIL_AI_CANONNAME; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; dr = safe_malloc(sizeof(struct dnsreq)); dr->cb = cb; dr->priv = priv; evdns_getaddrinfo(edb,hostname,0,&hints,resolve_cb,dr); }
void CDNSManager::lookupDNS(const DNS_RECORD_t& _record) { struct evutil_addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = EVUTIL_AI_CANONNAME; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; struct evdns_getaddrinfo_request* req = evdns_getaddrinfo( m_dnsbase, _record.name.c_str(), NULL, &hints, LookupDNSCallback, (void*)&_record); ON_ERROR_PRINT_MSG(req, == , NULL, "Fail to call evdns_getaddrinfo."); }
static void ts_conn_host(const char *hostname, unsigned short port, struct ts_session *session) { struct evutil_addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* Unless we specify a socktype, we'll get at least two entries for * each address: one for TCP and one for UDP. That's not what we * want. */ hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; char port_buf[6]; evutil_snprintf(port_buf, sizeof(port_buf), "%d", (int)port); /* We will run a non-blocking dns resolve */ struct ts_server_ctx *ctx = session->ctx; ts_log_d("start to resolve host %s", hostname); evdns_getaddrinfo(ctx->dnsbase, hostname, port_buf, &hints, ts_dns_resolved, session); }
static void lookup_and_connect(void) { struct evutil_addrinfo hints; if (!ev_dnsbase) ev_dnsbase = evdns_base_new(ev_base, 1); if (!ev_dnsbase) tmate_fatal("Cannot initialize the DNS lookup service"); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = 0; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; tmate_info("Looking up %s...", TMATE_HOST); (void)evdns_getaddrinfo(ev_dnsbase, TMATE_HOST, NULL, &hints, dns_cb, NULL); }
static void lookup_and_connect(void) { struct evutil_addrinfo hints; const char *tmate_server_host; if (!tmate_session.ev_dnsbase) tmate_session.ev_dnsbase = evdns_base_new(tmate_session.ev_base, 1); if (!tmate_session.ev_dnsbase) tmate_fatal("Cannot initialize the DNS lookup service"); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = EVUTIL_AI_ADDRCONFIG; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; tmate_server_host = options_get_string(global_options, "tmate-server-host"); tmate_info("Looking up %s...", tmate_server_host); (void)evdns_getaddrinfo(tmate_session.ev_dnsbase, tmate_server_host, NULL, &hints, dns_cb, (void *)tmate_server_host); }
void main() { struct event_base *base; base = event_base_new(); struct evutil_addrinfo hints; struct evutil_addrinfo *answer = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; struct evdns_base* dns_base = evdns_base_new(base, 1); if(dns_base == NULL) { printf("Error initializing DNS base\n"); exit(1); } struct evdns_getaddrinfo_request *req = evdns_getaddrinfo(dns_base, "www.google.com", "https", &hints, resolve_callback, dns_base); int err = event_base_loop(base, EVLOOP_ONCE); }
static void test_getaddrinfo_async(void *arg) { struct basic_test_data *data = arg; struct evutil_addrinfo hints, *a; struct gai_outcome local_outcome; struct gai_outcome a_out[12]; int i; struct evdns_getaddrinfo_request *r; char buf[128]; struct evdns_server_port *port = NULL; ev_uint16_t dns_port = 0; int n_dns_questions = 0; struct evdns_base *dns_base = evdns_base_new(data->base, 0); /* for localhost */ evdns_base_load_hosts(dns_base, NULL); memset(a_out, 0, sizeof(a_out)); n_gai_results_pending = 10000; /* don't think about exiting yet. */ /* 1. Try some cases that will never hit the asynchronous resolver. */ /* 1a. Simple case with a symbolic service name */ memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; memset(&local_outcome, 0, sizeof(local_outcome)); r = evdns_getaddrinfo(dns_base, "1.2.3.4", "http", &hints, gai_cb, &local_outcome); tt_int_op(r,==,0); if (!local_outcome.err) { tt_ptr_op(local_outcome.ai,!=,NULL); test_ai_eq(local_outcome.ai, "1.2.3.4:80", SOCK_STREAM, IPPROTO_TCP); evutil_freeaddrinfo(local_outcome.ai); local_outcome.ai = NULL; } else {
/** * 这里有一个竞争条件:如果这里不能建立libevent连接,或者发送HD_CMD_SS5_ACT之前就收到了 * EOF的事件,那么客户端就会存在一个僵尸的trans连接,客户端目前是单线程的,必须消除这种 * 消耗 * * 目前想到的处理方式就是,在拆除trans的同时,额外的向客户端主通道发送一个命令 */ static void thread_process(int fd, short which, void *arg) { P_THREAD_OBJ p_threadobj = (P_THREAD_OBJ)arg; P_TRANS_ITEM p_trans = NULL; P_SLIST_HEAD p_list = NULL; P_C_ITEM p_c_item = NULL; struct bufferevent *new_bev = NULL; char buf[1]; CTL_HEAD head; if (read(fd, buf, 1) != 1) { st_d_error("Can't read from libevent pipe\n"); return; } switch (buf[0]) { case 'D': // DAEMON->USR p_list = slist_fetch(&p_threadobj->conn_queue); if (!p_list) { st_d_error("无法从任务队列中获取任务!"); return; } p_c_item = list_entry(p_list, C_ITEM, list); p_trans = (P_TRANS_ITEM)p_c_item->arg.ptr; new_bev = bufferevent_socket_new(p_threadobj->base, p_c_item->socket, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(new_bev, thread_bufferread_cb, NULL, thread_bufferevent_cb, p_trans); bufferevent_enable(new_bev, EV_READ|EV_WRITE); p_trans->bev_d = new_bev; free(p_c_item); if (p_trans->bev_u == NULL || p_trans->usr_lport == 0 || p_trans->p_activ_item == NULL) { SYS_ABORT("USR SIDE SHOULD BE OK ALREAY!!!"); } st_d_print("WORKTHREAD-> DAEMON_USR(%d) OK!", p_trans->usr_lport); st_d_print("DDDDD: 当前活动连接数:[[[ %d ]]],任务队列:[[ %d ]]", slist_count(&p_trans->p_activ_item->trans), slist_count(&p_threadobj->conn_queue)); st_d_print("激活客户端Bufferevent使能!"); memset(&head, 0, CTL_HEAD_LEN); head.direct = USR_DAEMON; head.cmd = HD_CMD_CONN_ACT; head.extra_param = p_trans->usr_lport; head.mach_uuid = p_trans->p_activ_item->mach_uuid; bufferevent_write(p_trans->p_activ_item->bev_daemon, &head, CTL_HEAD_LEN); head.direct = DAEMON_USR; bufferevent_write(p_trans->p_activ_item->bev_usr, &head, CTL_HEAD_LEN); break; case 'U': //USR->DAEMON p_list = slist_fetch(&p_threadobj->conn_queue); if (!p_list) { st_d_error("无法从任务队列中获取任务!"); return; } p_c_item = list_entry(p_list, C_ITEM, list); p_trans = (P_TRANS_ITEM)p_c_item->arg.ptr; new_bev = bufferevent_socket_new(p_threadobj->base, p_c_item->socket, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(new_bev, thread_bufferread_cb, NULL, thread_bufferevent_cb, p_trans); bufferevent_enable(new_bev, EV_READ|EV_WRITE); p_trans->bev_u = new_bev; free(p_c_item); st_d_print("WORKTHREAD-> USR_DAEMON(%d) OK!", p_trans->usr_lport); break; case 'S': // DAEMON->USR p_list = slist_fetch(&p_threadobj->conn_queue); if (!p_list) { st_d_error("无法从任务队列中获取任务!"); return; } p_c_item = list_entry(p_list, C_ITEM, list); p_trans = (P_TRANS_ITEM)p_c_item->arg.ptr; assert(p_trans->is_enc); assert(p_trans->dat); encrypt_ctx_init(&p_trans->ctx_enc, p_trans->usr_lport, p_trans->p_activ_item->enc_key, 1); encrypt_ctx_init(&p_trans->ctx_dec, p_trans->usr_lport, p_trans->p_activ_item->enc_key, 0); int remote_socket = 0; char* buf = (char *)p_trans->dat; if (buf[3] == 0x01) { struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; memcpy(&sin.sin_addr.s_addr, &buf[4], 4); memcpy(&sin.sin_port, &buf[4+4], 2); free(p_trans->dat); st_d_print("REQUEST: %s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); remote_socket = ss_connect_srv(&sin); if (remote_socket == -1) { free(p_c_item); st_d_error("CONNECT ERROR!"); return; } } else { char remote_addr[128]; unsigned short remote_port = 0; memset(remote_addr, 0, sizeof(remote_addr)); strncpy(remote_addr, &buf[4+1], buf[4]); memcpy(&remote_port, &buf[4+1+buf[4]], 2); free(p_trans->dat); P_DNS_STRUCT p_dns = (P_DNS_STRUCT)calloc(sizeof(DNS_STRUCT), 1); if (!p_dns) { st_d_error("申请内存失败:%d", sizeof(DNS_STRUCT)); free(p_c_item); return; } st_d_print("REQUEST: %s:%d", remote_addr, ntohs(remote_port)); strncpy(p_dns->hostname, remote_addr, sizeof(p_dns->hostname)); p_dns->port = remote_port; p_dns->p_c_item = p_c_item; p_dns->p_threadobj = p_threadobj; p_dns->p_trans = p_trans; struct evutil_addrinfo hints; struct evdns_getaddrinfo_request *req; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_flags = EVUTIL_AI_CANONNAME; /* Unless we specify a socktype, we'll get at least two entries for * each address: one for TCP and one for UDP. That's not what we * want. */ hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; req = evdns_getaddrinfo( srvopt.evdns_base, remote_addr, NULL /* no service name given */, &hints, dns_query_cb, p_dns); if (req == NULL) { printf(" [request for %s returned immediately]\n", remote_addr); /* No need to free user_data or decrement n_pending_requests; that * happened in the callback. */ } return; } evutil_make_socket_nonblocking(p_c_item->socket); struct bufferevent *new_bev = bufferevent_socket_new(p_threadobj->base, 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_trans); bufferevent_enable(new_bev, EV_READ|EV_WRITE); evutil_make_socket_nonblocking(remote_socket); struct bufferevent *new_ext_bev = bufferevent_socket_new(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_trans); bufferevent_enable(new_ext_bev, EV_READ|EV_WRITE); p_trans->bev_d = new_bev; p_trans->bev_u = new_ext_bev; free(p_c_item); st_d_print("DDDDD: 当前活动连接数:[[[ %d ]]], 任务队列:[[ %d ]]", slist_count(&p_trans->p_activ_item->trans), slist_count(&p_threadobj->conn_queue)); st_d_print("SS5激活客户端Bufferevent使能!"); memset(&head, 0, CTL_HEAD_LEN); head.direct = USR_DAEMON; head.cmd = HD_CMD_SS5_ACT; head.extra_param = p_trans->usr_lport; head.mach_uuid = p_trans->p_activ_item->mach_uuid; bufferevent_write(p_trans->p_activ_item->bev_daemon, &head, CTL_HEAD_LEN); break; default: SYS_ABORT("WHAT DO I GET: %c", buf[0]); break; } return; }
void EvdnsWrapper::async_getaddrinfo(const char* nodename, const char* servname, evutil_addrinfo* hints, GetAddrCallBack* c){ c->add_shared(); evdns_getaddrinfo(this->evbase, nodename, servname, hints, on_remote_servername_resolved, c); }