コード例 #1
0
ファイル: hostip.c プロジェクト: tankorsmash/quadcow
/* called to check if the name is resolved now */
CURLcode Curl_is_resolved(struct connectdata *conn,
                          struct Curl_dns_entry **dns)
{
  fd_set read_fds, write_fds;
  static const struct timeval tv={0,0};
  int count;
  struct SessionHandle *data = conn->data;
  int nfds;

  FD_ZERO(&read_fds);
  FD_ZERO(&write_fds);
  nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);

  count = select(nfds, &read_fds, &write_fds, NULL,
                 (struct timeval *)&tv);

  if(count)
    ares_process(data->state.areschannel, &read_fds, &write_fds);

  *dns = NULL;

  if(conn->async.done) {
    /* we're done, kill the ares handle */
    if(!conn->async.dns)
      return CURLE_COULDNT_RESOLVE_HOST;
    *dns = conn->async.dns;
  }

  return CURLE_OK;
}
コード例 #2
0
ファイル: ares.c プロジェクト: ahltorp/afssync
static void
ares_worker_thread(char *ptr)
{
    struct timeval tv, max_tv = { 30, 0 };
    fd_set readset, writeset;
    int nfds, ret;

    while (1) {
	
	FD_ZERO(&readset);
	FD_ZERO(&writeset);
	nfds = ares_fds(achannel, &readset, &writeset);
	if (nfds == 0) {
	    tv = max_tv;
	    IOMGR_Sleep(max_tv.tv_sec);
	} else {
	    struct timeval *tvp;

	    tvp = ares_timeout(achannel, &max_tv, &tv);
	    ret = IOMGR_Select(nfds, &readset, &writeset, NULL, tvp);
	    if (ret < 0)
		/* XXX some error, lets ignore that for now */;
	    else if (ret == 0)
		/* timeout */;
	    else 
		ares_process(achannel, &readset, &writeset);
	}
    }
}
コード例 #3
0
ファイル: lua_cares.c プロジェクト: Olegas/runtime
static void
wait_ares(ares_channel channel)
{
    for(;;){
        struct timeval *tvp, tv;
        fd_set read_fds, write_fds, err_fds;
        int nfds;
 
        FD_ZERO(&read_fds);
        FD_ZERO(&write_fds);
        FD_ZERO(&err_fds);
        nfds = ares_fds(channel, &read_fds, &write_fds);
        if (nfds == 0){
            return;
        }
        memcpy(&err_fds, &read_fds, sizeof(read_fds));
        tvp = ares_timeout(channel, NULL, &tv);
        select(nfds, &read_fds, &write_fds, &err_fds, tvp);
        for (int i = 0; i < nfds; i++) {
            if (FD_ISSET(i, &err_fds)) {
                return;
            }
        }
        ares_process(channel, &read_fds, &write_fds);
    }
}
コード例 #4
0
/*
 * Curl_is_resolved() is called repeatedly to check if a previous name resolve
 * request has completed. It should also make sure to time-out if the
 * operation seems to take too long.
 *
 * Returns normal CURLcode errors.
 */
CURLcode Curl_is_resolved(struct connectdata *conn,
                          struct Curl_dns_entry **dns)
{
  fd_set read_fds, write_fds;
  struct timeval tv={0,0};
  struct SessionHandle *data = conn->data;
  int nfds;

  FD_ZERO(&read_fds);
  FD_ZERO(&write_fds);

  nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);

  (void)select(nfds, &read_fds, &write_fds, NULL,
               (struct timeval *)&tv);

  /* Call ares_process() unconditonally here, even if we simply timed out
     above, as otherwise the ares name resolve won't timeout! */
  ares_process(data->state.areschannel, &read_fds, &write_fds);

  *dns = NULL;

  if(conn->async.done) {
    /* we're done, kill the ares handle */
    if(!conn->async.dns) {
      failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
            ares_strerror(conn->async.status));
      return CURLE_COULDNT_RESOLVE_HOST;
    }
    *dns = conn->async.dns;
  }

  return CURLE_OK;
}
コード例 #5
0
ファイル: helper.c プロジェクト: BackupTheBerlios/sipsak-svn
inline unsigned long srv_ares(char *host, int *port, char *srv) {
	int nfds, count, srvh_len;
	char *srvh;
	fd_set read_fds, write_fds;
	struct timeval *tvp, tv;

	caport = 0;
	caadr = 0;
	ca_tmpname = NULL;
#ifdef DEBUG
	printf("!!! ARES query !!!\n");
#endif

	srvh_len = strlen(host) + strlen(srv) + 2;
	srvh = malloc(srvh_len);
	if (srvh == NULL) {
		printf("error: failed to allocate memory (%i) for ares query\n", srvh_len);
		exit_code(2);
	}
	memset(srvh, 0, srvh_len);
	strncpy(srvh, srv, strlen(srv));
	memcpy(srvh + strlen(srv), ".", 1);
	strcpy(srvh + strlen(srv) + 1, host);
#ifdef DEBUG
	printf("hostname: '%s', len: %i\n", srvh, srvh_len);
#endif

	ares_query(channel, srvh, CARES_CLASS_C_IN, CARES_TYPE_SRV, cares_callback, (char *) NULL);
#ifdef DEBUG
	printf("after ares_query\n");
#endif
	/* wait for query to complete */
	while (1) {
		FD_ZERO(&read_fds);
		FD_ZERO(&write_fds);
		nfds = ares_fds(channel, &read_fds, &write_fds);
		if (nfds == 0)
			break;
		tvp = ares_timeout(channel, NULL, &tv);
		count = select(nfds, &read_fds, &write_fds, NULL, tvp);
		if (count < 0 && errno != EINVAL) {
			perror("ares select");
			exit_code(2);
		}
		ares_process(channel, &read_fds, &write_fds);
	}
#ifdef DEBUG
	printf("end of while\n");
#endif
	*port = caport;
	if (caadr == 0 && ca_tmpname != NULL) {
		caadr = getaddress(ca_tmpname);
	}
	if (ca_tmpname != NULL)
		free(ca_tmpname);
	free(srvh);
	return caadr;
}
コード例 #6
0
ファイル: dnstalk.c プロジェクト: gvsurenderreddy/xymon-2
void dns_process_active(listhead_t *activelist, fd_set *fdread, fd_set *fdwrite)
{
	listitem_t *walk;

	// dbgprintf("DNS - process active fds\n");
	for (walk = activelist->head; (walk); walk = walk->next) {
		myconn_t *rec = (myconn_t *)walk->data;

		// dbgprintf("\t%s - proto %s, dnsstatus %s\n", rec->testspec, prototxt[rec->talkprotocol], dnsstatustxt[rec->dnsstatus]);
		if (rec->talkprotocol != TALK_PROTO_DNSQUERY) continue;
		if (rec->dnsstatus != DNS_QUERY_ACTIVE) continue;

		// dbgprintf("DNS query %s processing\n", rec->testspec);
		ares_process(*((ares_channel *)rec->dnschannel), fdread, fdwrite);
	}

	/* ... and the lookup channel ... */
	ares_process(dns_lookupchannel, fdread, fdwrite);
}
コード例 #7
0
ファイル: tt_dns_native.c プロジェクト: newser/TitanSDK
tt_s64_t tt_dns_run_ntv(IN ares_channel ch)
{
    fd_set rfds, wfds;
    int nfds, i;
    int ep = tt_current_task()->iop.sys_iop.ep;
    struct timeval tv;

    FD_ZERO(&rfds);
    FD_ZERO(&wfds);
    nfds = ares_fds(ch, &rfds, &wfds);
    for (i = 0; i < nfds; ++i) {
        __dskt_t *dskt = __DSKT(ch, i);
        tt_bool_t r = TT_BOOL(FD_ISSET(i, &rfds));
        tt_bool_t w = TT_BOOL(FD_ISSET(i, &wfds));

        dskt = __DSKT(ch, i);
        if (r && w) {
            if (dskt->status != __DNS_READ_WRITE) {
                dskt->ev.ev = __DNS_READ_WRITE;
                tt_ep_read_write(ep, dskt->s, &dskt->ev);
                dskt->status = __DNS_READ_WRITE;
            }
        } else if (r) {
            if (dskt->status != __DNS_READ) {
                dskt->ev.ev = __DNS_READ;
                tt_ep_read(ep, dskt->s, &dskt->ev);
                dskt->status = __DNS_READ;
            }
        } else if (w) {
            if (dskt->status != __DNS_WRITE) {
                dskt->ev.ev = __DNS_WRITE;
                tt_ep_write(ep, dskt->s, &dskt->ev);
                dskt->status = __DNS_WRITE;
            }
        } else {
            if ((dskt->s != -1) && (dskt->status != __DNS_NULL)) {
                dskt->ev.ev = __DNS_NULL;
                tt_ep_unread(ep, dskt->s, &__s_null_io_ev);
                dskt->status = __DNS_NULL;
            }
        }
    }
    // to process timer
    ares_process(ch, NULL, NULL);

    if (ares_timeout(ch, NULL, &tv) != NULL) {
        return (tt_s64_t)tv.tv_sec * 1000 + (tt_s64_t)tv.tv_usec / 1000;
    } else {
        return TT_TIME_INFINITE;
    }
}
コード例 #8
0
void *auth_mgr_adns_handler(void *arg)
{
    UNUSED_ARGUMENT(arg);
    int count=0;
    struct timeval *tvp, tv;
    fd_set read_fds, write_fds;
    int nfds;
    prctl(PR_SET_NAME, "nvsd-adns", 0, 0, 0);

    /*Infinite loop, to process all the dns responses. Each channel can handle
     16 name servers in RR fashion. Inside each channel there is one socket
    dedicated for one nameserver. So if there are 2 nameservers in /etc/resol.conf
    , then c-ares will assign 2 fds to the channel*/
    while(1)
    {
        FD_ZERO(&read_fds);
        FD_ZERO(&write_fds);
        pthread_mutex_lock(&cares_mutex);
        nfds = ares_fds(channel, &read_fds, &write_fds);
        if(nfds==0)
        {
            pthread_cond_wait(&cares_cond, &cares_mutex);
            pthread_mutex_unlock(&cares_mutex);
            continue;
        }
        tvp = ares_timeout(channel, NULL, &tv);
        pthread_mutex_unlock(&cares_mutex);
        /*********************************************************
        The default timeout was 5 seconds with default retries
        as 4. The timeout algorith that c-ares adopts, has
        timeout increasing linearly for every retry, and can
        go upto 75secs(~5+~10+~20+~40). To avoid such a big
        block in our select, reduced the timeout to 3secs
        and retries to 2, so max blocking limited to 9 secs
        Changes in ares_init.
        ******************************************************/
        count = select(nfds, &read_fds, &write_fds, NULL, tvp);
        if (count < 0) // && errno != EINVAL)
        {
            //Something is wrong here, lets sleep over it
            DBG_LOG(SEVERE, MOD_AUTHMGR,
                    "select failed in adns for nfds=%d error:%s", nfds, strerror(errno));
            usleep(1000);
            continue;
        }
        pthread_mutex_lock(&cares_mutex);
        ares_process(channel, &read_fds, &write_fds);
        pthread_mutex_unlock(&cares_mutex);
    }
}
コード例 #9
0
ファイル: helper.c プロジェクト: suretec/sipsak
static inline unsigned long srv_ares(char *host, int *port, char *srv) {
	int nfds, count, srvh_len;
	char *srvh;
	fd_set read_fds, write_fds;
	struct timeval *tvp, tv;

	caport = 0;
	caadr = 0;
	ca_tmpname = NULL;
	dbg("starting ARES query\n");

	srvh_len = strlen(host) + strlen(srv) + 2;
	srvh = malloc(srvh_len);
	if (srvh == NULL) {
		printf("error: failed to allocate memory (%i) for ares query\n", srvh_len);
		exit_code(2, __PRETTY_FUNCTION__, "memory allocation failure");
	}
	memset(srvh, 0, srvh_len);
	strncpy(srvh, srv, strlen(srv));
	memcpy(srvh + strlen(srv), ".", 1);
	strcpy(srvh + strlen(srv) + 1, host);
	dbg("hostname: '%s', len: %i\n", srvh, srvh_len);

	ares_query(channel, srvh, CARES_CLASS_C_IN, CARES_TYPE_SRV, cares_callback, (char *) NULL);
	dbg("ares_query finished, waiting for result...\n");
	/* wait for query to complete */
	while (1) {
		FD_ZERO(&read_fds);
		FD_ZERO(&write_fds);
		nfds = ares_fds(channel, &read_fds, &write_fds);
		if (nfds == 0)
			break;
		tvp = ares_timeout(channel, NULL, &tv);
		count = select(nfds, &read_fds, &write_fds, NULL, tvp);
		if (count < 0 && errno != EINVAL) {
			perror("ares select");
			exit_code(2, __PRETTY_FUNCTION__, "ares DNS resolution failure");
		}
		ares_process(channel, &read_fds, &write_fds);
	}
	dbg("ARES answer processed\n");
	*port = caport;
	if (caadr == 0 && ca_tmpname != NULL) {
		caadr = getaddress(ca_tmpname);
	}
	if (ca_tmpname != NULL)
		free(ca_tmpname);
	free(srvh);
	return caadr;
}
コード例 #10
0
	void step() {
		if( state == kResolving ) {
			if( ares ) {
				if( canceling ) {
					ares_cancel(ares);
				}
				int nfds, count;
				fd_set readers, writers;
				struct timeval tv, maxtv, *tvp;
				FD_ZERO(&readers);
				FD_ZERO(&writers);
				nfds = ares_fds(ares, &readers, &writers);
				maxtv.tv_sec = 0;
				maxtv.tv_usec = 1000;
				if (nfds == 0) {
					ares_process(ares, NULL, NULL);
				} else {
					tvp = ares_timeout(ares, &maxtv, &tv);
					count = select(nfds, &readers, &writers, NULL, tvp);
					ares_process(ares, &readers, &writers);
				}
			}
		}
		if( state == kStartDownload ) {
			if( ares )
				ares_destroy( ares );
			ares = 0;
			start_curl();
		}
		if( state == kFinishingOK ) {
			got_done();
		}
		if( state == kFinishingError ) {
			got_error();
		}
		// Nothing to do with other states
	}
コード例 #11
0
ファイル: resolver.cpp プロジェクト: GoBudokai/ozifi
void wait_ares(ares_channel channel) {
    for(;;){
        struct timeval *tvp, tv;
        fd_set read_fds, write_fds;
        int nfds;

        FD_ZERO(&read_fds);
        FD_ZERO(&write_fds);
        nfds = ares_fds(channel, &read_fds, &write_fds);
        if(nfds == 0){
            break;
        }
        tvp = ares_timeout(channel, NULL, &tv);
        select(nfds, &read_fds, &write_fds, NULL, tvp);
        ares_process(channel, &read_fds, &write_fds);
    }
}
コード例 #12
0
ファイル: cidr-rdns.c プロジェクト: Sanguinarious/cidr-rdns
void tehloop(void) {
	fd_set read, write;
	int nfds, count;
	struct timeval tv, *tvp;
	fprintf(stderr, "Starting...\n");
	tv.tv_usec = 100000;
	while(1) {
		FD_ZERO(&read); FD_ZERO(&write);
		nfds = ares_fds(ares_chan, &read, &write);
		if(nfds) {
			tvp = ares_timeout(ares_chan, NULL, &tv);
			count = select(nfds, &read, &write, NULL, tvp);
			ares_process(ares_chan, &read, &write);
			fprintf(stderr, "\rResolved %i of %i", global_counter, global_total);
		} else
			break;
	}
	fprintf(stderr, "\nFinished...\n");
}
コード例 #13
0
ファイル: host.c プロジェクト: mirror/wget
static void
wait_ares (ares_channel channel)
{
  struct ptimer *timer = NULL;

  if (opt.dns_timeout)
    timer = ptimer_new ();

  for (;;)
    {
      struct timeval *tvp, tv;
      fd_set read_fds, write_fds;
      int nfds, rc;

      FD_ZERO (&read_fds);
      FD_ZERO (&write_fds);
      nfds = ares_fds (channel, &read_fds, &write_fds);
      if (nfds == 0)
        break;

      if (timer)
        {
          double max = opt.dns_timeout - ptimer_measure (timer);

          tv.tv_sec = (long) max;
          tv.tv_usec = 1000000 * (max - (long) max);
          tvp = ares_timeout (channel, &tv, &tv);
        }
      else
        tvp = ares_timeout (channel, NULL, &tv);

      rc = select (nfds, &read_fds, &write_fds, NULL, tvp);
      if (rc == 0 && timer && ptimer_measure (timer) >= opt.dns_timeout)
        ares_cancel (channel);
      else
        ares_process (channel, &read_fds, &write_fds);
    }
  if (timer)
    ptimer_destroy (timer);
}
コード例 #14
0
ファイル: mosquitto.c プロジェクト: SSSang2/mosquittoSlave
int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets)
{
#ifdef HAVE_PSELECT
	struct timespec local_timeout;
#else
	struct timeval local_timeout;
#endif
	fd_set readfds, writefds;
	int fdcount;
	int rc;
	char pairbuf;
	int maxfd = 0;

	if(!mosq || max_packets < 1) return MOSQ_ERR_INVAL;
#ifndef WIN32
	if(mosq->sock >= FD_SETSIZE || mosq->sockpairR >= FD_SETSIZE){
		return MOSQ_ERR_INVAL;
	}
#endif

	FD_ZERO(&readfds);
	FD_ZERO(&writefds);
	if(mosq->sock != INVALID_SOCKET){
		maxfd = mosq->sock;
		FD_SET(mosq->sock, &readfds);
		pthread_mutex_lock(&mosq->current_out_packet_mutex);
		pthread_mutex_lock(&mosq->out_packet_mutex);
		if(mosq->out_packet || mosq->current_out_packet){
			FD_SET(mosq->sock, &writefds);
		}
#ifdef WITH_TLS
		if(mosq->ssl){
			if(mosq->want_write){
				FD_SET(mosq->sock, &writefds);
				mosq->want_write = false;
			}else if(mosq->want_connect){
				/* Remove possible FD_SET from above, we don't want to check
				 * for writing if we are still connecting, unless want_write is
				 * definitely set. The presence of outgoing packets does not
				 * matter yet. */
				FD_CLR(mosq->sock, &writefds);
			}
		}
#endif
		pthread_mutex_unlock(&mosq->out_packet_mutex);
		pthread_mutex_unlock(&mosq->current_out_packet_mutex);
	}else{
#ifdef WITH_SRV
		if(mosq->achan){
			pthread_mutex_lock(&mosq->state_mutex);
			if(mosq->state == mosq_cs_connect_srv){
				rc = ares_fds(mosq->achan, &readfds, &writefds);
				if(rc > maxfd){
					maxfd = rc;
				}
			}else{
				pthread_mutex_unlock(&mosq->state_mutex);
				return MOSQ_ERR_NO_CONN;
			}
			pthread_mutex_unlock(&mosq->state_mutex);
		}
#else
		return MOSQ_ERR_NO_CONN;
#endif
	}
	if(mosq->sockpairR != INVALID_SOCKET){
		/* sockpairR is used to break out of select() before the timeout, on a
		 * call to publish() etc. */
		FD_SET(mosq->sockpairR, &readfds);
		if(mosq->sockpairR > maxfd){
			maxfd = mosq->sockpairR;
		}
	}

	if(timeout >= 0){
		local_timeout.tv_sec = timeout/1000;
#ifdef HAVE_PSELECT
		local_timeout.tv_nsec = (timeout-local_timeout.tv_sec*1000)*1e6;
#else
		local_timeout.tv_usec = (timeout-local_timeout.tv_sec*1000)*1000;
#endif
	}else{
		local_timeout.tv_sec = 1;
#ifdef HAVE_PSELECT
		local_timeout.tv_nsec = 0;
#else
		local_timeout.tv_usec = 0;
#endif
	}

#ifdef HAVE_PSELECT
	fdcount = pselect(maxfd+1, &readfds, &writefds, NULL, &local_timeout, NULL);
#else
	fdcount = select(maxfd+1, &readfds, &writefds, NULL, &local_timeout);
#endif
	if(fdcount == -1){
#ifdef WIN32
		errno = WSAGetLastError();
#endif
		if(errno == EINTR){
			return MOSQ_ERR_SUCCESS;
		}else{
			return MOSQ_ERR_ERRNO;
		}
	}else{
		if(mosq->sock != INVALID_SOCKET){
			if(FD_ISSET(mosq->sock, &readfds)){
#ifdef WITH_TLS
				if(mosq->want_connect){
					rc = mosquitto__socket_connect_tls(mosq);
					if(rc) return rc;
				}else
#endif
				{
					do{
						rc = mosquitto_loop_read(mosq, max_packets);

						if(rc || mosq->sock == INVALID_SOCKET){
							return rc;
						}
					}while(SSL_DATA_PENDING(mosq));
				}
			}
			if(mosq->sockpairR != INVALID_SOCKET && FD_ISSET(mosq->sockpairR, &readfds)){
#ifndef WIN32
				if(read(mosq->sockpairR, &pairbuf, 1) == 0){
				}
#else
				recv(mosq->sockpairR, &pairbuf, 1, 0);
#endif
				/* Fake write possible, to stimulate output write even though
				 * we didn't ask for it, because at that point the publish or
				 * other command wasn't present. */
				FD_SET(mosq->sock, &writefds);
			}
			if(FD_ISSET(mosq->sock, &writefds)){
#ifdef WITH_TLS
				if(mosq->want_connect){
					rc = mosquitto__socket_connect_tls(mosq);
					if(rc) return rc;
				}else
#endif
				{
					rc = mosquitto_loop_write(mosq, max_packets);
					if(rc || mosq->sock == INVALID_SOCKET){
						return rc;
					}
				}
			}
		}
#ifdef WITH_SRV
		if(mosq->achan){
			ares_process(mosq->achan, &readfds, &writefds);
		}
#endif
	}
	return mosquitto_loop_misc(mosq);
}
コード例 #15
0
ファイル: linux_glibc_hook.cpp プロジェクト: HunterChen/libgo
    int gethostbyaddr_with_ares(const void *addr, int addrlen, int af,
            struct hostent *ret_h, char *buf, size_t &buflen,
            struct hostent **result, int *h_errnop)
    {
        int err = 0;
        if (!h_errnop) h_errnop = &err;

        cares_async_context ctx;
        ctx.called = false;
        ctx.errnop = h_errnop;
        ctx.ret = 0;
        ctx.result = result;
        ctx.buf = buf;
        ctx.buflen = &buflen;

        ares_channel c;
        ares_init(&c);
        ares_gethostbyaddr(c, addr, addrlen, af,
                [](void * arg, int status, int timeouts, struct hostent *hostent)
                {
                    cares_async_context *ctx = (cares_async_context *)arg;
                    ctx->called = true;
                    if (status != ARES_SUCCESS) {
                        *ctx->result = nullptr;

                        switch (status) {
                        case ARES_ENODATA:
                            *ctx->errnop = NO_DATA;
                            break;

                        case ARES_EBADNAME:
                            *ctx->errnop = NO_RECOVERY;
                            break;

                        case ARES_ENOTFOUND:
                        default:
                            *ctx->errnop = HOST_NOT_FOUND;
                            break;
                        }

                        ctx->ret = -1;
                        return ;
                    }

                    if (!hostent_dup(hostent, *ctx->result, ctx->buf, *ctx->buflen)) {
                        *ctx->result = nullptr;
                        *ctx->errnop = ENOEXEC;    // 奇怪的错误码.
                        ctx->ret = -1;
                        return ;
                    }

                    *ctx->errnop = 0;
                    ctx->ret = 0;
                }, &ctx);

        fd_set readers, writers;
        FD_ZERO(&readers);
        FD_ZERO(&writers);

        int nfds = ares_fds(c, &readers, &writers);
        if (nfds) {
            struct timeval tv, *tvp;
            tvp = ares_timeout(c, NULL, &tv);
            int count = select(nfds, &readers, &writers, NULL, tvp);
            if (count > 0) {
                ares_process(c, &readers, &writers);
            }
        }

        if (ctx.called)
            return ctx.ret;

        // No yet invoke callback.
        *result = nullptr;
        *h_errnop = HOST_NOT_FOUND; // TODO
        return -1;
    }
コード例 #16
0
ファイル: hostip.c プロジェクト: tankorsmash/quadcow
/* This is a function that locks and waits until the name resolve operation
   has completed.

   If 'entry' is non-NULL, make it point to the resolved dns entry

   Return CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
   CURLE_OPERATION_TIMEDOUT if a time-out occurred.
*/
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
                              struct Curl_dns_entry **entry)
{
  CURLcode rc=CURLE_OK;
  struct SessionHandle *data = conn->data;
  struct timeval now = Curl_tvnow();
  bool timedout = FALSE;
  long timeout = 300; /* default name resolve timeout in seconds */
  long elapsed = 0; /* time taken so far */

  /* now, see if there's a connect timeout or a regular timeout to
     use instead of the default one */
  if(conn->data->set.connecttimeout)
    timeout = conn->data->set.connecttimeout;
  else if(conn->data->set.timeout)
    timeout = conn->data->set.timeout;

  /* Wait for the name resolve query to complete. */
  while (1) {
    int nfds=0;
    fd_set read_fds, write_fds;
    struct timeval *tvp, tv, store;
    int count;

    store.tv_sec = (int)(timeout - elapsed);
    store.tv_usec = 0;
    
    FD_ZERO(&read_fds);
    FD_ZERO(&write_fds);
    nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
    if (nfds == 0)
      break;
    tvp = ares_timeout(data->state.areschannel,
                       &store, &tv);
    count = select(nfds, &read_fds, &write_fds, NULL, tvp);
    if (count < 0 && errno != EINVAL)
      break;
    else if(!count) {
      /* timeout */
      timedout = TRUE;
      break;
    }
    ares_process(data->state.areschannel, &read_fds, &write_fds);

    elapsed = Curl_tvdiff(Curl_tvnow(), now)/1000; /* spent time */
  }

  /* Operation complete, if the lookup was successful we now have the entry
     in the cache. */
    
  if(entry)
    *entry = conn->async.dns;

  if(!conn->async.dns) {
    /* a name was not resolved */
    if(timedout || (conn->async.status == ARES_ETIMEOUT)) {
      failf(data, "Resolving host timed out: %s", conn->name);
      rc = CURLE_OPERATION_TIMEDOUT;
    }
    else if(conn->async.done) {
      failf(data, "Could not resolve host: %s (%s)", conn->name,
            ares_strerror(conn->async.status));
      rc = CURLE_COULDNT_RESOLVE_HOST;
    }
    else
      rc = CURLE_OPERATION_TIMEDOUT;

    /* close the connection, since we can't return failure here without
       cleaning up this connection properly */
    Curl_disconnect(conn);
  }
  
  return rc;
}
コード例 #17
0
ファイル: adig.c プロジェクト: HengeSense/Technokats-Website
int main(int argc, char **argv)
{
  ares_channel channel;
  int c, i, optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A;
  int status, nfds, count;
  struct ares_options options;
  struct hostent *hostent;
  fd_set read_fds, write_fds;
  struct timeval *tvp, tv;

#ifdef USE_WINSOCK
  WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
  WSADATA wsaData;
  WSAStartup(wVersionRequested, &wsaData);
#endif

  options.flags = ARES_FLAG_NOCHECKRESP;
  options.servers = NULL;
  options.nservers = 0;
  while ((c = ares_getopt(argc, argv, "df:s:c:t:T:U:")) != -1)
    {
      switch (c)
        {
        case 'd':
#ifdef WATT32
          dbug_init();
#endif
          break;

        case 'f':
          /* Add a flag. */
          for (i = 0; i < nflags; i++)
            {
              if (strcmp(flags[i].name, optarg) == 0)
                break;
            }
          if (i == nflags)
            usage();
          options.flags |= flags[i].value;
          break;

        case 's':
          /* Add a server, and specify servers in the option mask. */
          if (ares_inet_pton(AF_INET, optarg, &inaddr) <= 0)
            {
              hostent = gethostbyname(optarg);
              if (!hostent || hostent->h_addrtype != AF_INET)
                {
                  fprintf(stderr, "adig: server %s not found.\n", optarg);
                  return 1;
                }
              memcpy(&inaddr, hostent->h_addr, sizeof(struct in_addr));
            }
          options.servers = realloc(options.servers, (options.nservers + 1)
                                    * sizeof(struct in_addr));
          if (!options.servers)
            {
              fprintf(stderr, "Out of memory!\n");
              return 1;
            }
          memcpy(&options.servers[options.nservers], &inaddr,
                 sizeof(struct in_addr));
          options.nservers++;
          optmask |= ARES_OPT_SERVERS;
          break;

        case 'c':
          /* Set the query class. */
          for (i = 0; i < nclasses; i++)
            {
              if (strcasecmp(classes[i].name, optarg) == 0)
                break;
            }
          if (i == nclasses)
            usage();
          dnsclass = classes[i].value;
          break;

        case 't':
          /* Set the query type. */
          for (i = 0; i < ntypes; i++)
            {
              if (strcasecmp(types[i].name, optarg) == 0)
                break;
            }
          if (i == ntypes)
            usage();
          type = types[i].value;
          break;

        case 'T':
          /* Set the TCP port number. */
          if (!ISDIGIT(*optarg))
            usage();
          options.tcp_port = (unsigned short)strtol(optarg, NULL, 0);
          optmask |= ARES_OPT_TCP_PORT;
          break;

        case 'U':
          /* Set the UDP port number. */
          if (!ISDIGIT(*optarg))
            usage();
          options.udp_port = (unsigned short)strtol(optarg, NULL, 0);
          optmask |= ARES_OPT_UDP_PORT;
          break;
        }
    }
  argc -= optind;
  argv += optind;
  if (argc == 0)
    usage();

  status = ares_init_options(&channel, &options, optmask);

  if (status != ARES_SUCCESS)
    {
      fprintf(stderr, "ares_init_options: %s\n",
              ares_strerror(status));
      return 1;
    }

  /* Initiate the queries, one per command-line argument.  If there is
   * only one query to do, supply NULL as the callback argument;
   * otherwise, supply the query name as an argument so we can
   * distinguish responses for the user when printing them out.
   */
  if (argc == 1)
    ares_query(channel, *argv, dnsclass, type, callback, (char *) NULL);
  else
    {
      for (; *argv; argv++)
        ares_query(channel, *argv, dnsclass, type, callback, *argv);
    }

  /* Wait for all queries to complete. */
  while (1)
    {
      FD_ZERO(&read_fds);
      FD_ZERO(&write_fds);
      nfds = ares_fds(channel, &read_fds, &write_fds);
      if (nfds == 0)
        break;
      tvp = ares_timeout(channel, NULL, &tv);
      count = select(nfds, &read_fds, &write_fds, NULL, tvp);
      if (count < 0 && SOCKERRNO != EINVAL)
        {
          perror("select");
          return 1;
        }
      ares_process(channel, &read_fds, &write_fds);
    }

  ares_destroy(channel);

#ifdef USE_WINSOCK
  WSACleanup();
#endif

  return 0;
}
コード例 #18
0
ファイル: adig.c プロジェクト: changloong/gool
int main(int argc, char **argv)
{
  ares_channel channel;
  int c, i, optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A;
  int status, nfds, count;
  struct ares_options options;
  struct hostent *hostent;
  fd_set read_fds, write_fds;
  struct timeval *tvp, tv;
  struct ares_addr_node *srvr, *servers = NULL;

#ifdef USE_WINSOCK
  WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
  WSADATA wsaData;
  WSAStartup(wVersionRequested, &wsaData);
#endif

  status = ares_library_init(ARES_LIB_INIT_ALL);
  if (status != ARES_SUCCESS)
    {
      fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status));
      return 1;
    }

  options.flags = ARES_FLAG_NOCHECKRESP;
  options.servers = NULL;
  options.nservers = 0;
  while ((c = ares_getopt(argc, argv, "df:s:c:t:T:U:")) != -1)
    {
      switch (c)
        {
        case 'd':
#ifdef WATT32
          dbug_init();
#endif
          break;

        case 'f':
          /* Add a flag. */
          for (i = 0; i < nflags; i++)
            {
              if (strcmp(flags[i].name, optarg) == 0)
                break;
            }
          if (i < nflags)
            options.flags |= flags[i].value;
          else
            usage();
          break;

        case 's':
          /* User-specified name servers override default ones. */
          srvr = malloc(sizeof(struct ares_addr_node));
          if (!srvr)
            {
              fprintf(stderr, "Out of memory!\n");
              destroy_addr_list(servers);
              return 1;
            }
          append_addr_list(&servers, srvr);
          if (ares_inet_pton(AF_INET, optarg, &srvr->addr.addr4) > 0)
            srvr->family = AF_INET;
          else if (ares_inet_pton(AF_INET6, optarg, &srvr->addr.addr6) > 0)
            srvr->family = AF_INET6;
          else
            {
              hostent = gethostbyname(optarg);
              if (!hostent)
                {
                  fprintf(stderr, "adig: server %s not found.\n", optarg);
                  destroy_addr_list(servers);
                  return 1;
                }
              switch (hostent->h_addrtype)
                {
                  case AF_INET:
                    srvr->family = AF_INET;
                    memcpy(&srvr->addr.addr4, hostent->h_addr,
                           sizeof(srvr->addr.addr4));
                    break;
                  case AF_INET6:
                    srvr->family = AF_INET6;
                    memcpy(&srvr->addr.addr6, hostent->h_addr,
                           sizeof(srvr->addr.addr6));
                    break;
                  default:
                    fprintf(stderr,
                      "adig: server %s unsupported address family.\n", optarg);
                    destroy_addr_list(servers);
                    return 1;
                }
            }
          /* Notice that calling ares_init_options() without servers in the
           * options struct and with ARES_OPT_SERVERS set simultaneously in
           * the options mask, results in an initialization with no servers.
           * When alternative name servers have been specified these are set
           * later calling ares_set_servers() overriding any existing server
           * configuration. To prevent initial configuration with default
           * servers that will be discarded later, ARES_OPT_SERVERS is set.
           * If this flag is not set here the result shall be the same but
           * ares_init_options() will do needless work. */
          optmask |= ARES_OPT_SERVERS;
          break;

        case 'c':
          /* Set the query class. */
          for (i = 0; i < nclasses; i++)
            {
              if (strcasecmp(classes[i].name, optarg) == 0)
                break;
            }
          if (i < nclasses)
            dnsclass = classes[i].value;
          else
            usage();
          break;

        case 't':
          /* Set the query type. */
          for (i = 0; i < ntypes; i++)
            {
              if (strcasecmp(types[i].name, optarg) == 0)
                break;
            }
          if (i < ntypes)
            type = types[i].value;
          else
            usage();
          break;

        case 'T':
          /* Set the TCP port number. */
          if (!ISDIGIT(*optarg))
            usage();
          options.tcp_port = (unsigned short)strtol(optarg, NULL, 0);
          optmask |= ARES_OPT_TCP_PORT;
          break;

        case 'U':
          /* Set the UDP port number. */
          if (!ISDIGIT(*optarg))
            usage();
          options.udp_port = (unsigned short)strtol(optarg, NULL, 0);
          optmask |= ARES_OPT_UDP_PORT;
          break;
        }
    }
  argc -= optind;
  argv += optind;
  if (argc == 0)
    usage();

  status = ares_init_options(&channel, &options, optmask);

  if (status != ARES_SUCCESS)
    {
      fprintf(stderr, "ares_init_options: %s\n",
              ares_strerror(status));
      return 1;
    }

  if(servers)
    {
      status = ares_set_servers(channel, servers);
      destroy_addr_list(servers);
      if (status != ARES_SUCCESS)
        {
          fprintf(stderr, "ares_init_options: %s\n",
                  ares_strerror(status));
          return 1;
        }
    }

  /* Initiate the queries, one per command-line argument.  If there is
   * only one query to do, supply NULL as the callback argument;
   * otherwise, supply the query name as an argument so we can
   * distinguish responses for the user when printing them out.
   */
  if (argc == 1)
    ares_query(channel, *argv, dnsclass, type, callback, (char *) NULL);
  else
    {
      for (; *argv; argv++)
        ares_query(channel, *argv, dnsclass, type, callback, *argv);
    }

  /* Wait for all queries to complete. */
  for (;;)
    {
      FD_ZERO(&read_fds);
      FD_ZERO(&write_fds);
      nfds = ares_fds(channel, &read_fds, &write_fds);
      if (nfds == 0)
        break;
      tvp = ares_timeout(channel, NULL, &tv);
      count = select(nfds, &read_fds, &write_fds, NULL, tvp);
      if (count < 0 && SOCKERRNO != EINVAL)
        {
          perror("select");
          return 1;
        }
      ares_process(channel, &read_fds, &write_fds);
    }

  ares_destroy(channel);

  ares_library_cleanup();

#ifdef USE_WINSOCK
  WSACleanup();
#endif

  return 0;
}
コード例 #19
0
ファイル: ahost.c プロジェクト: 18965050/gevent
int main(int argc, char **argv)
{
  struct ares_options options;
  int optmask = 0;
  ares_channel channel;
  int status, nfds, c, addr_family = AF_INET;
  fd_set read_fds, write_fds;
  struct timeval *tvp, tv;
  struct in_addr addr4;
  struct ares_in6_addr addr6;

#ifdef USE_WINSOCK
  WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
  WSADATA wsaData;
  WSAStartup(wVersionRequested, &wsaData);
#endif

  memset(&options, 0, sizeof(options));

  status = ares_library_init(ARES_LIB_INIT_ALL);
  if (status != ARES_SUCCESS)
    {
      fprintf(stderr, "ares_library_init: %s\n", ares_strerror(status));
      return 1;
    }

  while ((c = ares_getopt(argc,argv,"dt:hs:")) != -1)
    {
      switch (c)
        {
        case 'd':
#ifdef WATT32
          dbug_init();
#endif
          break;
        case 's':
          optmask |= ARES_OPT_DOMAINS;
          options.ndomains++;
          options.domains = realloc(options.domains,
                                    options.ndomains * sizeof(char *));
          options.domains[options.ndomains - 1] = strdup(optarg);
          break;
        case 't':
          if (!strcasecmp(optarg,"a"))
            addr_family = AF_INET;
          else if (!strcasecmp(optarg,"aaaa"))
            addr_family = AF_INET6;
          else if (!strcasecmp(optarg,"u"))
            addr_family = AF_UNSPEC;
          else
            usage();
          break;
        case 'h':
        default:
          usage();
          break;
        }
    }

  argc -= optind;
  argv += optind;
  if (argc < 1)
    usage();

  status = ares_init_options(&channel, &options, optmask);
  if (status != ARES_SUCCESS)
    {
      fprintf(stderr, "ares_init: %s\n", ares_strerror(status));
      return 1;
    }

  /* Initiate the queries, one per command-line argument. */
  for ( ; *argv; argv++)
    {
      if (ares_inet_pton(AF_INET, *argv, &addr4) == 1)
        {
          ares_gethostbyaddr(channel, &addr4, sizeof(addr4), AF_INET, callback,
                             *argv);
        }
      else if (ares_inet_pton(AF_INET6, *argv, &addr6) == 1)
        {
          ares_gethostbyaddr(channel, &addr6, sizeof(addr6), AF_INET6, callback,
                             *argv);
        }
      else
        {
          ares_gethostbyname(channel, *argv, addr_family, callback, *argv);
        }
    }

  /* Wait for all queries to complete. */
  for (;;)
    {
      int res;
      FD_ZERO(&read_fds);
      FD_ZERO(&write_fds);
      nfds = ares_fds(channel, &read_fds, &write_fds);
      if (nfds == 0)
        break;
      tvp = ares_timeout(channel, NULL, &tv);
      res = select(nfds, &read_fds, &write_fds, NULL, tvp);
      if (-1 == res)
        break;
      ares_process(channel, &read_fds, &write_fds);
    }

  ares_destroy(channel);

  ares_library_cleanup();

#ifdef USE_WINSOCK
  WSACleanup();
#endif

  return 0;
}
コード例 #20
0
/*
 * Curl_wait_for_resolv() waits for a resolve to finish. This function should
 * be avoided since using this risk getting the multi interface to "hang".
 *
 * If 'entry' is non-NULL, make it point to the resolved dns entry
 *
 * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
 * CURLE_OPERATION_TIMEDOUT if a time-out occurred.
 */
CURLcode Curl_wait_for_resolv(struct connectdata *conn,
                              struct Curl_dns_entry **entry)
{
  CURLcode rc=CURLE_OK;
  struct SessionHandle *data = conn->data;
  long timeout = CURL_TIMEOUT_RESOLVE; /* default name resolve timeout */

  /* now, see if there's a connect timeout or a regular timeout to
     use instead of the default one */
  if(conn->data->set.connecttimeout)
    timeout = conn->data->set.connecttimeout;
  else if(conn->data->set.timeout)
    timeout = conn->data->set.timeout;

  /* We convert the number of seconds into number of milliseconds here: */
  if(timeout < 2147483)
    /* maximum amount of seconds that can be multiplied with 1000 and
       still fit within 31 bits */
    timeout *= 1000;
  else
    timeout = 0x7fffffff; /* ridiculous amount of time anyway */

  /* Wait for the name resolve query to complete. */
  while (1) {
    int nfds=0;
    fd_set read_fds, write_fds;
    struct timeval *tvp, tv, store;
    int count;
    struct timeval now = Curl_tvnow();
    long timediff;

    store.tv_sec = (int)timeout/1000;
    store.tv_usec = (timeout%1000)*1000;

    FD_ZERO(&read_fds);
    FD_ZERO(&write_fds);
    nfds = ares_fds(data->state.areschannel, &read_fds, &write_fds);
    if (nfds == 0)
      /* no file descriptors means we're done waiting */
      break;
    tvp = ares_timeout(data->state.areschannel, &store, &tv);
    count = select(nfds, &read_fds, &write_fds, NULL, tvp);
    if (count < 0 && errno != EINVAL)
      break;

    ares_process(data->state.areschannel, &read_fds, &write_fds);

    timediff = Curl_tvdiff(Curl_tvnow(), now); /* spent time */
    timeout -= timediff?timediff:1; /* always deduct at least 1 */
    if (timeout < 0) {
      /* our timeout, so we cancel the ares operation */
      ares_cancel(data->state.areschannel);
      break;
    }
  }

  /* Operation complete, if the lookup was successful we now have the entry
     in the cache. */

  if(entry)
    *entry = conn->async.dns;

  if(!conn->async.dns) {
    /* a name was not resolved */
    if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) {
      failf(data, "Resolving host timed out: %s", conn->host.dispname);
      rc = CURLE_OPERATION_TIMEDOUT;
    }
    else if(conn->async.done) {
      failf(data, "Could not resolve host: %s (%s)", conn->host.dispname,
            ares_strerror(conn->async.status));
      rc = CURLE_COULDNT_RESOLVE_HOST;
    }
    else
      rc = CURLE_OPERATION_TIMEDOUT;

    /* close the connection, since we can't return failure here without
       cleaning up this connection properly */
    conn->bits.close = TRUE;
  }

  return rc;
}
コード例 #21
0
ファイル: mux.c プロジェクト: davidben/zephyr
void
mux_loop(void)
{
    int i, nfds;
    fd_set inputs, outputs;
    struct timeval tv, *tvp;

    mux_end_loop_p = 0;

    for (;;) {
	/*
	 * Exit if mux_end_loop_p has been set to true by a handler:
	 */
	if (mux_end_loop_p)
	  break;
	tvp = NULL;
	tv.tv_sec = 0;
	if (have_tty) {
#ifdef CMU_ZWGCPLUS
            tv.tv_sec = plus_timequeue_events();
           if (tv.tv_sec > 10) tv.tv_sec = 10;
#else
	    tv.tv_sec = 10;
#endif
	    tv.tv_usec = 0;
#ifdef CMU_ZWGCPLUS
	} else {
	   tv.tv_sec = plus_timequeue_events();
	   tv.tv_usec = 0;
#endif
	}
	if (tv.tv_sec)
	 tvp = &tv;

	/*
	 * Do a select on all the file descriptors we care about to
	 * wait until at least one of them has input available:
	 */
	inputs = input_sources;
	FD_ZERO(&outputs);

#ifdef HAVE_ARES
	nfds = ares_fds(achannel, &inputs, &outputs);
	if (nfds < max_source + 1)
	    nfds = max_source + 1;
	tvp = ares_timeout(achannel, tvp, &tv);
#else
	nfds = max_source + 1;
#endif

	i = select(nfds, &inputs, &outputs, NULL, tvp);

	if (i == -1) {
	    if (errno == EINTR)
		continue;    /* on a signal restart checking mux_loop_end_p */
	    else
		FATAL_TRAP( errno, "while selecting" );
	}
	else if (i == 0) {
	    if (have_tty && !check_tty()) {
		mux_end_loop_p = 1;
		continue;
	    }
	}

#ifdef HAVE_ARES
	ares_process(achannel, &inputs, &outputs);
#endif

	/*
	 * Call all input handlers whose corresponding file descriptors have
	 * input:
	 */
	for(i=0; i<=max_source; i++)
	  if (FD_ISSET(i, &inputs) && input_handler[i]) {
#ifdef DEBUG
	      if (zwgc_debug)
		fprintf(stderr,
			"mux_loop...activity on fd %d, calling %lx(%lx)\n",
			i, (unsigned long)input_handler[i],
			 (unsigned long)input_handler_arg[i]);
#endif
	      input_handler[i](input_handler_arg[i]);
	  }
    }
}
コード例 #22
0
ファイル: p_dns.c プロジェクト: gandaro/piebnc
/**
 * Tell the DNS resolver that the select() has finished and it can check if any of its sockets had any data
 * on it.
 *
 * This function should be called after calling p_dns_fds() and select(). It ignores any file descriptors that
 * do not belong to it (e.g. IRC connections).
 */
void p_dns_process(fd_set *read_fds, fd_set *write_fds)
{
    pcontext;
    ares_process(resolver, read_fds, write_fds);
}
コード例 #23
0
ファイル: dns_handler.cpp プロジェクト: HalfDemon/MCPP
	void DNSHandler::worker () {
	
		//	FD sets used for selecting
		fd_set readable;
		fd_set writeable;
		//	Maximum file descriptor to pass
		//	to select
		int nfds;
		//	The timeout for select
		struct timeval tv;
	
		//	Loop until shutdown
		for (;;) {
		
			//	Zero FDs
			FD_ZERO(&readable);
			FD_ZERO(&writeable);			
			
			if (lock.Execute([&] () mutable {
			
				//	Wait for there to be something actionable,
				//	either pending queries, or a shutdown command
				while (!stop && (queries.size()==0)) wait.Sleep(lock);
				
				//	If the command to shutdown has been given,
				//	do that at once
				if (stop) return true;
				
				//	Get the file descriptors from libcares
				nfds=ares_fds(
					channel,
					&readable,
					&writeable
				);
				//	Get the timeout from libcares
				ares_timeout(
					channel,
					nullptr,
					&tv
				);
				
				return false;
			
			})) break;
			
			//	If there's a message pending on
			//	the worker end of the socket pair,
			//	we want to be woken up, so 
			
			//	If there's a message pending
			//	on the worker end of the socket
			//	pair, we want to be woken up,
			//	so we're checking for readability
			nfds=control.Add(readable,nfds);
			
			//	Wait for something to happen
			if (select(
				nfds,
				&readable,
				&writeable,
				nullptr,
				&tv
			)==
			#ifdef ENVIRONMENT_WINDOWS
			SOCKET_ERROR
			#else
			-1
			#endif
			) raise_os();
			
			//	Did something happen with the
			//	control socket?
			if (control.Is(readable)) {
			
				//	Check to see if a shutdown command
				//	is coming through the control socket,
				//	if so end at once
				if (should_stop()) break;
			
				//	Remove it in case it matters to
				//	libcares what's in the fd_set
				control.Clear(readable);
			
			}
			
			//	Call libcares
			lock.Execute([&] () mutable {
			
				ares_process(
					channel,
					&readable,
					&writeable
				);
			
			});
		
		}
	
	}