Eric Faurot <[email protected]> writes:

> On Sat, Feb 25, 2017 at 07:24:48PM +0100, Jeremie Courreges-Anglas wrote:
>> Jeremie Courreges-Anglas <[email protected]> writes:
>> 
>> > This flag is useful for software that wants to rely on the resolver to
>> > perform DNSSEC validation.  Among the use cases there are DANE and SSHFP
>> > records, and the obvious interfaces that I think are useful are
>> > res_mkquery and getrrsetbyname.  The latter still doesn't support
>> > DNSSEC, another diff will follow.
>> 
>> Diff on top of the previous one.  I'd like to make getrrsetbyname(3)
>> "use" RES_USE_DNSSEC again.  This would improve support for ssh -o
>> VerifyHostKeyDNS (SSHFP records).
>> 
>> The "easy" way would be something like:
>> 
>> Index: getrrsetbyname_async.c
>> ===================================================================
>> RCS file: /d/cvs/src/lib/libc/asr/getrrsetbyname_async.c,v
>> retrieving revision 1.11
>> diff -u -p -p -u -r1.11 getrrsetbyname_async.c
>> --- getrrsetbyname_async.c   23 Feb 2017 17:04:02 -0000      1.11
>> +++ getrrsetbyname_async.c   25 Feb 2017 17:25:25 -0000
>> @@ -42,6 +42,7 @@ getrrsetbyname_async(const char *hostnam
>>      struct asr_query *as;
>>  
>>      ac = _asr_use_resolver(asr);
>> +    ac->ac_options |= RES_USE_DNSSEC;
>>      if ((as = _asr_async_new(ac, ASR_GETRRSETBYNAME)) == NULL)
>>              goto abort; /* errno set */
>>      as->as_run = getrrsetbyname_async_run;
>> 
>> IIUC this means that we modify the thread-local resolver options used by
>> subsequent queries.  Cleaning up by resetting the flag before returning
>> doesn't work in all cases because you could have overlap between two
>> active getrrsetbyname_async and eg getaddrinfo_async contexts.
>
> Right. It has to be set a the query level.
>
>> The diff below instead adds an as_flags member to struct asr_query, and
>> merges the flags of the various union members.  struct rrset and struct
>> ni keep their flags member, as they are a different kind of flags.
>> A subset of as_flags is passed down to the child ASR_SEND subq, the only
>> flag that is inherited right now is ASYNC_DNSSEC, which allows
>> getrrsetbyname_async to communicate its intent.
>> 
>> That's a bit of churn for a small improvement, maybe there is a simpler
>> diff?
>>
>> Comments welcome.
>> 
>
> Well, I like the as_flags cleanup part of the diff. Internal flags should
> indeed be on the asr_query structure directly, so they are not confused
> with query-specific parameters.
>
> For the flags inheritance, I'm not so sure.  I would rather keep the current
> internal API for now, and set the flags explicitely for this specific case.

Fine with me, here's a diff to introduce as_flags only, still on top of
the RES_USE_DNSSEC diff.


diff -x CVS -pruN asr.1/asr.c asr/asr.c
--- asr.1/asr.c Sat Feb 25 17:57:40 2017
+++ asr/asr.c   Sun Feb 26 22:43:02 2017
@@ -244,7 +244,7 @@ _asr_async_free(struct asr_query *as)
        case ASR_SEND:
                if (as->as_fd != -1)
                        close(as->as_fd);
-               if (as->as.dns.obuf && !(as->as.dns.flags & ASYNC_EXTOBUF))
+               if (as->as.dns.obuf && !(as->as_flags & ASYNC_EXTOBUF))
                        free(as->as.dns.obuf);
                if (as->as.dns.ibuf)
                        free(as->as.dns.ibuf);
diff -x CVS -pruN asr.1/asr_private.h asr/asr_private.h
--- asr.1/asr_private.h Sat Feb 25 17:57:40 2017
+++ asr/asr_private.h   Sun Feb 26 22:44:06 2017
@@ -165,6 +165,7 @@ struct asr_query {
        int             (*as_run)(struct asr_query *, struct asr_result *);
        struct asr_ctx  *as_ctx;
        int              as_type;
+       int              as_flags;
        int              as_state;
 
        /* cond */
@@ -183,7 +184,6 @@ struct asr_query {
 
        union {
                struct {
-                       int              flags;
                        uint16_t         reqid;
                        int              class;
                        int              type;
@@ -206,7 +206,6 @@ struct asr_query {
                } dns;
 
                struct {
-                       int              flags;
                        int              class;
                        int              type;
                        char            *name;
@@ -249,7 +248,6 @@ struct asr_query {
                        char            *fqdn;
                        struct addrinfo *aifirst;
                        struct addrinfo *ailast;
-                       int              flags;
                } ai;
 
                struct {
diff -x CVS -pruN asr.1/getaddrinfo_async.c asr/getaddrinfo_async.c
--- asr.1/getaddrinfo_async.c   Sat Feb 25 17:57:40 2017
+++ asr/getaddrinfo_async.c     Sun Feb 26 22:43:02 2017
@@ -356,11 +356,11 @@ getaddrinfo_async_run(struct asr_query *as, struct asr
                            AS_FAMILY(as) : as->as.ai.hints.ai_family;
 
                        if (family == AF_INET &&
-                           as->as.ai.flags & ASYNC_NO_INET) {
+                           as->as_flags & ASYNC_NO_INET) {
                                async_set_state(as, ASR_STATE_NEXT_FAMILY);
                                break;
                        } else if (family == AF_INET6 &&
-                           as->as.ai.flags & ASYNC_NO_INET6) {
+                           as->as_flags & ASYNC_NO_INET6) {
                                async_set_state(as, ASR_STATE_NEXT_FAMILY);
                                break;
                        }
@@ -431,7 +431,7 @@ getaddrinfo_async_run(struct asr_query *as, struct asr
 
        case ASR_STATE_NOT_FOUND:
                /* No result found. Maybe we can try again. */
-               if (as->as.ai.flags & ASYNC_AGAIN)
+               if (as->as_flags & ASYNC_AGAIN)
                        ar->ar_gai_errno = EAI_AGAIN;
                else
                        ar->ar_gai_errno = EAI_NODATA;
@@ -684,7 +684,7 @@ addrconfig_setup(struct asr_query *as)
        if (getifaddrs(&ifa0) == -1)
                return (-1);
 
-       as->as.ai.flags |= ASYNC_NO_INET | ASYNC_NO_INET6;
+       as->as_flags |= ASYNC_NO_INET | ASYNC_NO_INET6;
 
        for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) {
                if (ifa->ifa_addr == NULL)
@@ -697,7 +697,7 @@ addrconfig_setup(struct asr_query *as)
                        if (sinp->sin_addr.s_addr == htonl(INADDR_LOOPBACK))
                                continue;
 
-                       as->as.ai.flags &= ~ASYNC_NO_INET;
+                       as->as_flags &= ~ASYNC_NO_INET;
                        break;
                case PF_INET6:
                        sin6p = (struct sockaddr_in6 *)ifa->ifa_addr;
@@ -708,7 +708,7 @@ addrconfig_setup(struct asr_query *as)
                        if (IN6_IS_ADDR_LINKLOCAL(&sin6p->sin6_addr))
                                continue;
 
-                       as->as.ai.flags &= ~ASYNC_NO_INET6;
+                       as->as_flags &= ~ASYNC_NO_INET6;
                        break;
                }
        }
diff -x CVS -pruN asr.1/res_search_async.c asr/res_search_async.c
--- asr.1/res_search_async.c    Sat Feb 25 17:57:40 2017
+++ asr/res_search_async.c      Sun Feb 26 22:43:02 2017
@@ -169,9 +169,9 @@ res_search_async_run(struct asr_query *as, struct asr_
 
                if (as->as_dom_flags & ASYNC_DOM_DOMAIN) {
                        if (ar->ar_h_errno == NO_DATA)
-                               as->as.search.flags |= ASYNC_NODATA;
+                               as->as_flags |= ASYNC_NODATA;
                        else if (ar->ar_h_errno == TRY_AGAIN)
-                               as->as.search.flags |= ASYNC_AGAIN;
+                               as->as_flags |= ASYNC_AGAIN;
                }
 
                async_set_state(as, ASR_STATE_NEXT_DOMAIN);
@@ -181,9 +181,9 @@ res_search_async_run(struct asr_query *as, struct asr_
 
                if (as->as.search.saved_h_errno != HERRNO_UNSET)
                        ar->ar_h_errno = as->as.search.saved_h_errno;
-               else if (as->as.search.flags & ASYNC_NODATA)
+               else if (as->as_flags & ASYNC_NODATA)
                        ar->ar_h_errno = NO_DATA;
-               else if (as->as.search.flags & ASYNC_AGAIN)
+               else if (as->as_flags & ASYNC_AGAIN)
                        ar->ar_h_errno = TRY_AGAIN;
                /*
                 * Else, we got the ar_h_errno value set by res_query_async()
diff -x CVS -pruN asr.1/res_send_async.c asr/res_send_async.c
--- asr.1/res_send_async.c      Sat Feb 25 17:57:40 2017
+++ asr/res_send_async.c        Sun Feb 26 22:48:50 2017
@@ -67,7 +67,7 @@ res_send_async(const unsigned char *buf, int buflen, v
        }
        as->as_run = res_send_async_run;
 
-       as->as.dns.flags |= ASYNC_EXTOBUF;
+       as->as_flags |= ASYNC_EXTOBUF;
        as->as.dns.obuf = (unsigned char *)buf;
        as->as.dns.obuflen = buflen;
        as->as.dns.obufsize = buflen;
@@ -346,7 +346,7 @@ setup_query(struct asr_query *as, const char *name, co
        char                    fqdn[MAXDNAME];
        char                    dname[MAXDNAME];
 
-       if (as->as.dns.flags & ASYNC_EXTOBUF) {
+       if (as->as_flags & ASYNC_EXTOBUF) {
                errno = EINVAL;
                DPRINT("attempting to write in user packet");
                return (-1);


-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to