595694ed20dff1ddf61fa29b827043ea01651984
[oweals/openwrt.git] /
1 From a0088e83640d7d1544127dd668660462e9f78e52 Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Thu, 10 May 2018 21:43:14 +0100
4 Subject: [PATCH 06/17] Handle query retry on REFUSED or SERVFAIL for
5  DNSSEC-generated queries.
6
7 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
8 ---
9  src/forward.c | 46 ++++++++++++++++++++++++++++++++++++++++------
10  1 file changed, 40 insertions(+), 6 deletions(-)
11
12 --- a/src/forward.c
13 +++ b/src/forward.c
14 @@ -298,9 +298,9 @@ static int forward_query(int udpfd, unio
15                 fd = forward->rfd4->fd;
16             }
17           
18 -         while (retry_send( sendto(fd, (char *)header, plen, 0,
19 -                                   &forward->sentto->addr.sa,
20 -                                   sa_len(&forward->sentto->addr))));
21 +         while (retry_send(sendto(fd, (char *)header, plen, 0,
22 +                                  &forward->sentto->addr.sa,
23 +                                  sa_len(&forward->sentto->addr))));
24           
25           return 1;
26         }
27 @@ -804,8 +804,7 @@ void reply_query(int fd, int family, tim
28    dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY,
29               (void *)header, n, &serveraddr, NULL);
30  #endif
31 -  
32 -  
33 +
34    /* log_query gets called indirectly all over the place, so 
35       pass these in global variables - sorry. */
36    daemon->log_display_id = forward->log_id;
37 @@ -826,6 +825,40 @@ void reply_query(int fd, int family, tim
38        size_t plen;
39        int is_sign;
40  
41 +      /* For DNSSEC originated queries, just retry the query to the same server. */
42 +      if (forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY))
43 +       {
44 +         blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
45 +         plen = forward->stash_len;
46 +
47 +         forward->forwardall = 2; /* only retry once */
48 +         
49 +         if (forward->sentto->addr.sa.sa_family == AF_INET) 
50 +           log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec");
51 +#ifdef HAVE_IPV6
52 +         else
53 +           log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec");
54 +#endif
55 +  
56 +         if (forward->sentto->sfd)
57 +           fd = forward->sentto->sfd->fd;
58 +         else
59 +           {
60 +#ifdef HAVE_IPV6
61 +             if (forward->sentto->addr.sa.sa_family == AF_INET6)
62 +               fd = forward->rfd6->fd;
63 +             else
64 +#endif
65 +               fd = forward->rfd4->fd;
66 +           }
67 +         
68 +         while (retry_send(sendto(fd, (char *)header, plen, 0,
69 +                                  &forward->sentto->addr.sa,
70 +                                  sa_len(&forward->sentto->addr))));
71 +         
72 +         return;
73 +       }
74 +         
75        /* In strict order mode, there must be a server later in the chain
76          left to send to, otherwise without the forwardall mechanism,
77          code further on will cycle around the list forwever if they
78 @@ -1017,7 +1050,8 @@ void reply_query(int fd, int family, tim
79  #ifdef HAVE_IPV6
80                       new->rfd6 = NULL;
81  #endif
82 -                     new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY);
83 +                     new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY | FREC_HAS_EXTRADATA);
84 +                     new->forwardall = 0;
85                       
86                       new->dependent = forward; /* to find query awaiting new one. */
87                       forward->blocking_query = new; /* for garbage cleaning */