⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dnskey.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 4 页
字号:
    idtoa(&cr->sgw_id, gwidb, sizeof(gwidb));    zero(&cr->query);    {	err_t ugh = build_dns_name(cr->query.name_buf, cr->qtid	    , id, typename, gwidb);	if (ugh != NULL)	{	    release_adns_continuation(cr);	    return ugh;	}    }    if (next_query == NULL)	next_query = cr;    unsent_ADNS_queries = TRUE;    return NULL;}/* send remaining ADNS queries (until pipe full or none left) * * This is a co-routine, so it uses static variables to * preserve state across calls. */bool unsent_ADNS_queries = FALSE;voidsend_unsent_ADNS_queries(void){    static const unsigned char *buf_end = NULL;	/* NOTE STATIC */    static const unsigned char *buf_cur = NULL;	/* NOTE STATIC */    if (adns_qfd == NULL_FD)	return;	/* nothing useful to do */    for (;;)    {	if (buf_cur != buf_end)	{	    static int try = 0;	/* NOTE STATIC */	    size_t n = buf_end - buf_cur;	    ssize_t r = write(adns_qfd, buf_cur, n);	    if (r == -1)	    {		switch (errno)		{		case EINTR:		    continue;	/* try again now */		case EAGAIN:		    DBG(DBG_DNS, DBG_log("EAGAIN writing to ADNS"));		    break;	/* try again later */		default:		    try++;		    log_errno((e, "error %d writing DNS query", try));		    break;	/* try again later */		}		unsent_ADNS_queries = TRUE;		break;	/* done! */	    }	    else	    {		passert(r >= 0);		try = 0;		buf_cur += r;	    }	}	else	{	    if (next_query == NULL)	    {		unsent_ADNS_queries = FALSE;		break;	/* done! */	    }#ifdef USE_LWRES	    next_query->used = FALSE;	    {		/* NOTE STATIC: */		static unsigned char qbuf[LWDNSQ_CMDBUF_LEN + 1];	/* room for NUL */		snprintf(qbuf, sizeof(qbuf), "%s %lu %s\n"		    , rr_typename(next_query->type)		    , next_query->qtid		    , next_query->query.name_buf);		DBG(DBG_DNS, DBG_log("lwdnsq query: %.*s", (int)(strlen(qbuf) - 1), qbuf));		buf_cur = qbuf;		buf_end = qbuf + strlen(qbuf);	    }#else /* !USE_LWRES */	    next_query->query.debugging = next_query->debugging;	    next_query->query.serial = next_query->qtid;	    next_query->query.len = sizeof(next_query->query);	    next_query->query.qmagic = ADNS_Q_MAGIC;	    next_query->query.type = next_query->type;	    buf_cur = (const void *)&next_query->query;	    buf_end = buf_cur + sizeof(next_query->query);#endif /* !USE_LWRES */	    next_query = next_query->next;	    adns_in_flight++;	}    }}#ifdef USE_LWRES/* Process a line of lwdnsq answer. * Returns with error message iff lwdnsq result is malformed. * Most errors will be in DNS data and will be handled by cr->cont_fn. */static err_tprocess_lwdnsq_answer(char *ts){    err_t ugh = NULL;    char *rest;    char *p;    char *endofnumber;    struct adns_continuation *cr = NULL;    unsigned long qtid;    time_t anstime;	/* time of answer */    char *atype;	/* type of answer */    long ttl;	/* ttl of answer; int, but long for conversion */    bool AuthenticatedData = FALSE;    static char scratch_null_str[] = "";	/* cannot be const, but isn't written */    /* query transaction id */    rest = ts;    p = strsep(&rest, " \t");    if (p == NULL)	return "lwdnsq: answer missing query transaction ID";    qtid = strtoul(p, &endofnumber, 10);    if (*endofnumber != '\0')	return "lwdnsq: malformed query transaction ID";    cr = continuation_for_qtid(qtid);    if (qtid != 0 && cr == NULL)	return "lwdnsq: unrecognized qtid";	/* can't happen! */    /* time */    p = strsep(&rest, " \t");    if (p == NULL)	return "lwdnsq: missing time";    anstime = strtoul(p, &endofnumber, 10);    if (*endofnumber != '\0')	return "lwdnsq: malformed time";    /* TTL */    p = strsep(&rest, " \t");    if (p == NULL)	return "lwdnsq: missing TTL";    ttl = strtol(p, &endofnumber, 10);    if (*endofnumber != '\0')	return "lwdnsq: malformed TTL";    /* type */    atype = strsep(&rest, " \t");    if (atype == NULL)	return "lwdnsq: missing type";    /* if rest is NULL, make it "", otherwise eat whitespace after type */    rest = rest == NULL? scratch_null_str : rest + strspn(rest, " \t");    if (strncasecmp(atype, "AD-", 3) == 0)    {	AuthenticatedData = TRUE;	atype += 3;    }    /* deal with each type */    if (cr == NULL)    {	/* we don't actually know which this applies to */	return builddiag("lwdnsq: 0 qtid invalid with %s", atype);    }    else if (strcaseeq(atype, "START"))    {	/* ignore */    }    else if (strcaseeq(atype, "DONE"))    {	if (!cr->used)	{	    /* "no results returned by lwdnsq" should not happen */	    cr->cont_fn(cr		, cr->gateways_from_dns == NULL#ifdef USE_KEYRR		  && cr->keys_from_dns == NULL#endif /* USE_KEYRR */		    ? "no results returned by lwdnsq" : NULL);	    cr->used = TRUE;	}	reset_globals();	release_adns_continuation(cr);	adns_in_flight--;    }    else if (strcaseeq(atype, "RETRY"))    {	if (!cr->used)	{	    cr->cont_fn(cr, rest);	    cr->used = TRUE;	}    }    else if (strcaseeq(atype, "TIMEOUT"))    {   /* for now, treat as if it was a fatal error, and run failure	 * shunt. Later, we will consider a valid answer and re-evaluate	 * life, the universe and everything	 */	if (!cr->used)	{	    cr->cont_fn(cr, rest);	    cr->used = TRUE;	}    }    else if (strcaseeq(atype, "FATAL"))    {	if (!cr->used)	{	    cr->cont_fn(cr, rest);	    cr->used = TRUE;	}    }    else if (strcaseeq(atype, "DNSSEC"))    {	/* ignore */    }    else if (strcaseeq(atype, "NAME"))    {	/* ignore */    }    else if (strcaseeq(atype, "TXT"))    {	char *end = rest + strlen(rest);	err_t txt_ugh;	if (*rest == '"' && end[-1] == '"')	{	    /* strip those pesky quotes */	    rest++;	    *--end = '\0';	}	txt_ugh = process_txt_rr_body(rest	    , TRUE	    , AuthenticatedData? DAL_SIGNED : DAL_NOTSEC	    , cr);	if (txt_ugh != NULL)	{	    DBG(DBG_DNS,		DBG_log("error processing TXT resource record (%s) while processing: %s"			, txt_ugh, rest));	    cr->cont_fn(cr, txt_ugh);	    cr->used = TRUE;	}    }    else if (strcaseeq(atype, "SIG"))    {	/* record the SIG records for posterity */	if (cr->last_info != NULL)	{	    pfreeany(cr->last_info->dns_sig);	    cr->last_info->dns_sig = clone_str(rest, "sigrecord");	}    }    else if (strcaseeq(atype, "A"))    {	/* ignore */    }    else if (strcaseeq(atype, "AAAA"))    {	/* ignore */    }    else if (strcaseeq(atype, "CNAME"))    {	/* ignore */    }    else if (strcaseeq(atype, "CNAMEFROM"))    {	/* ignore */    }    else if (strcaseeq(atype, "PTR"))    {	/* ignore */    }#ifdef USE_KEYRR    else if (strcaseeq(atype, "KEY"))    {	err_t key_ugh = process_lwdnsq_key(rest	    , AuthenticatedData? DAL_SIGNED : DAL_NOTSEC	    , cr);	if (key_ugh != NULL)	{	    DBG(DBG_DNS,		DBG_log("error processing KEY resource record (%s) while processing: %s"			, key_ugh, rest));	    cr->cont_fn(cr, key_ugh);	    cr->used = TRUE;	}    }#endif /* USE_KEYRR */    else    {	ugh = "lwdnsq: unrecognized type";    }    return ugh;}#endif /* USE_LWRES */static voidrecover_adns_die(void){    struct adns_continuation *cr = NULL;    adns_pid = 0;    if(adns_restart_count < ADNS_RESTART_MAX) {	adns_restart_count++;	/* next DNS query will restart it */	/* we have to walk the list of the outstanding requests,	 * and redo them!	 */	cr = continuations;	/* find the head of the list */	if(continuations != NULL) {	    for (; cr->previous != NULL; cr = cr->previous);	}	next_query = cr;	if(next_query != NULL) {	    unsent_ADNS_queries = TRUE;	}    }}void reset_adns_restart_count(void){    adns_restart_count=0;}voidhandle_adns_answer(void){  /* These are retained across calls to handle_adns_answer. */    static size_t buflen = 0;	/* bytes in answer buffer */#ifndef USE_LWRES    static struct adns_answer buf;#else /* USE_LWRES */    static char buf[LWDNSQ_RESULT_LEN_MAX];    static char buf_copy[LWDNSQ_RESULT_LEN_MAX];#endif /* USE_LWRES */    ssize_t n;    passert(buflen < sizeof(buf));    n = read(adns_afd, (unsigned char *)&buf + buflen, sizeof(buf) - buflen);    if (n < 0)    {	if (errno != EINTR)	{	    log_errno((e, "error reading answer from adns"));	    /* ??? how can we recover? */	}	n = 0;	/* now n reflects amount read */    }    else if (n == 0)    {	/* EOF */	if (adns_in_flight != 0)	{	    openswan_log("EOF from ADNS with %d queries outstanding (restarts %d)"		 , adns_in_flight, adns_restart_count);	    recover_adns_die();	}	if (buflen != 0)	{	    openswan_log("EOF from ADNS with %lu bytes of a partial answer outstanding"		 "(restarts %d)"		 , (unsigned long)buflen		 ,  adns_restart_count);	    recover_adns_die();	}	stop_adns();	return;    }    else    {	passert(adns_in_flight > 0);    }    buflen += n;#ifndef USE_LWRES    while (buflen >= offsetof(struct adns_answer, ans) && buflen >= buf.len)    {	/* we've got a tasty answer -- process it */	err_t ugh;	struct adns_continuation *cr = continuation_for_qtid(buf.serial);	/* assume it works */	const char *typename = rr_typename(cr->query.type);	const char *name_buf = cr->query.name_buf;#ifdef USE_KEYRR	passert(cr->keys_from_dns == NULL);#endif /* USE_KEYRR */	passert(cr->gateways_from_dns == NULL);	adns_in_flight--;	if (buf.result == -1)	{	    /* newer resolvers support statp->res_h_errno as well as h_errno.	     * That might be better, but older resolvers don't.	     * See resolver(3), if you have it.	     * The undocumented(!) h_errno values are defined in	     * /usr/include/netdb.h.	     */	    switch (buf.h_errno_val)	    {	    case NO_DATA:		ugh = builddiag("no %s record for %s", typename, name_buf);		break;	    case HOST_NOT_FOUND:		ugh = builddiag("no host %s for %s record", name_buf, typename);		break;	    default:		ugh = builddiag("failure querying DNS for %s of %s: %s"		    , typename, name_buf, hstrerror(buf.h_errno_val));		break;	    }	}	else if (buf.result > (int) sizeof(buf.ans))	{	    ugh = builddiag("(INTERNAL ERROR) answer too long (%ld) for buffer"		, (long)buf.result);	}	else	{	    ugh = process_dns_answer(cr, buf.ans, buf.result);	    if (ugh != NULL)		ugh = builddiag("failure processing %s record of DNS answer for %s: %s"		    , typename, name_buf, ugh);	}	DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS,	    DBG_log(BLANK_FORMAT);	    if (ugh == NULL)		DBG_log("asynch DNS answer %lu for %s of %s"		    , cr->query.serial, typename, name_buf);	    else		DBG_log("asynch DNS answer %lu %s", cr->query.serial, ugh);	    );	passert(GLOBALS_ARE_RESET());	cr->cont_fn(cr, ugh);	reset_globals();	release_adns_continuation(cr);	/* shift out answer that we've consumed */	buflen -= buf.len;	memmove((unsigned char *)&buf, (unsigned char *)&buf + buf.len, buflen);    }#else /* USE_LWRES */    for (;;)    {	err_t ugh;	char *nlp = memchr(buf, '\n', buflen);	if (nlp == NULL)	    break;	/* we've got a line */	*nlp++ = '\0';	DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS	    , DBG_log("lwdns: %s", buf));	/* process lwdnsq_answer may modify buf, so make a copy. */	memcpy(buf_copy, buf, nlp-buf);	ugh = process_lwdnsq_answer(buf_copy);	if (ugh != NULL)	    openswan_log("failure processing lwdnsq output: %s; record: %s"		 , ugh, buf);	passert(GLOBALS_ARE_RESET());	reset_globals();	/* shift out answer that we've consumed */	buflen -= nlp - buf;	memmove(buf, nlp, buflen);    }#endif /* USE_LWRES */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -