Re: unwind and split-horizon DNS

2019-12-01 Thread Otto Moerbeek
On Sat, Nov 30, 2019 at 08:39:36AM +0100, Otto Moerbeek wrote:

> On Fri, Nov 29, 2019 at 11:37:40PM +0100, Björn Ketelaars wrote:
> 
> > On Fri 29/11/2019 21:35, Otto Moerbeek wrote:
> > > On Fri, Nov 29, 2019 at 10:27:57AM +0100, Florian Obser wrote:
> > > 
> > > > On Fri, Nov 29, 2019 at 07:28:20AM +0100, Otto Moerbeek wrote:
> > > > > On Fri, Nov 29, 2019 at 07:02:27AM +0100, Björn Ketelaars wrote:
> > > > > > I experienced no regression while using the free wifi service of the
> > > > > > Dutch railways, which is known to do strange things with DNS.
> > > > > 
> > > > > Thanks for testing. The Dutch railways have been a great inspiration
> > > > > to unwind work, as florian@ can telll you :-)
> > > > 
> > > > They have got to be good at *something*. Not sure if it's their core
> > > > business to annoy the hell out of me, but hey...
> > > > 
> > > > Only joking, overall I'm quite happy with the Dutch railway. I use
> > > > them every work day and they get me where I need to go most of the
> > > > time.
> > > > 
> > > > -- 
> > > > I'm not entirely sure you are real.
> > > > 
> > > 
> > > And here's a rebased diff for your convenience,
> > 
> > The rebased diff results in a different behaviour than the first diff.
> > More precise, 'force acceptbogus forwarder' is not respected any more
> > resulting in issues with DNSSEC.
> > 
> > I compared the old- and the rebased diff and noticed that some bits have
> > been left out. Functionality is restored after applying the diff below.
> > 
> > 
> > diff --git sbin/unwind/unwind.c sbin/unwind/unwind.c
> > index 5a97dcccec4..4687a7cc122 100644
> > --- sbin/unwind/unwind.c
> > +++ sbin/unwind/unwind.c
> > @@ -675,6 +675,12 @@ merge_config(struct uw_conf *conf, struct uw_conf 
> > *xconf)
> > uw_forwarder, entry);
> > }
> >  
> > +   for (n = RB_MIN(force_tree, >force); n != NULL; n = nxt) {
> > +   nxt = RB_NEXT(force_tree, >force, n);
> > +   RB_REMOVE(force_tree, >force, n);
> > +   RB_INSERT(force_tree, >force, n);
> > +   }
> > +
> > free(xconf);
> >  }
> >  
> 
> Thanks for spottting that. I did myself as well, but sent the wrong
> version... Below the full corrected diff.

Diff has been committed with one grammar change: acceptbogus is now
two words.

Thanks to the testers,

-Otto



Re: unwind and split-horizon DNS

2019-11-29 Thread Otto Moerbeek
On Fri, Nov 29, 2019 at 11:37:40PM +0100, Björn Ketelaars wrote:

> On Fri 29/11/2019 21:35, Otto Moerbeek wrote:
> > On Fri, Nov 29, 2019 at 10:27:57AM +0100, Florian Obser wrote:
> > 
> > > On Fri, Nov 29, 2019 at 07:28:20AM +0100, Otto Moerbeek wrote:
> > > > On Fri, Nov 29, 2019 at 07:02:27AM +0100, Björn Ketelaars wrote:
> > > > > I experienced no regression while using the free wifi service of the
> > > > > Dutch railways, which is known to do strange things with DNS.
> > > > 
> > > > Thanks for testing. The Dutch railways have been a great inspiration
> > > > to unwind work, as florian@ can telll you :-)
> > > 
> > > They have got to be good at *something*. Not sure if it's their core
> > > business to annoy the hell out of me, but hey...
> > > 
> > > Only joking, overall I'm quite happy with the Dutch railway. I use
> > > them every work day and they get me where I need to go most of the
> > > time.
> > > 
> > > -- 
> > > I'm not entirely sure you are real.
> > > 
> > 
> > And here's a rebased diff for your convenience,
> 
> The rebased diff results in a different behaviour than the first diff.
> More precise, 'force acceptbogus forwarder' is not respected any more
> resulting in issues with DNSSEC.
> 
> I compared the old- and the rebased diff and noticed that some bits have
> been left out. Functionality is restored after applying the diff below.
> 
> 
> diff --git sbin/unwind/unwind.c sbin/unwind/unwind.c
> index 5a97dcccec4..4687a7cc122 100644
> --- sbin/unwind/unwind.c
> +++ sbin/unwind/unwind.c
> @@ -675,6 +675,12 @@ merge_config(struct uw_conf *conf, struct uw_conf *xconf)
>   uw_forwarder, entry);
>   }
>  
> + for (n = RB_MIN(force_tree, >force); n != NULL; n = nxt) {
> + nxt = RB_NEXT(force_tree, >force, n);
> + RB_REMOVE(force_tree, >force, n);
> + RB_INSERT(force_tree, >force, n);
> + }
> +
>   free(xconf);
>  }
>  

Thanks for spottting that. I did myself as well, but sent the wrong
version... Below the full corrected diff.

-Otto

Index: frontend.c
===
RCS file: /cvs/src/sbin/unwind/frontend.c,v
retrieving revision 1.41
diff -u -p -r1.41 frontend.c
--- frontend.c  29 Nov 2019 15:22:02 -  1.41
+++ frontend.c  29 Nov 2019 20:32:43 -
@@ -336,6 +336,7 @@ frontend_dispatch_main(int fd, short eve
case IMSG_RECONF_BLOCKLIST_FILE:
case IMSG_RECONF_FORWARDER:
case IMSG_RECONF_DOT_FORWARDER:
+   case IMSG_RECONF_FORCE:
imsg_receive_config(, );
break;
case IMSG_RECONF_END:
Index: parse.y
===
RCS file: /cvs/src/sbin/unwind/parse.y,v
retrieving revision 1.20
diff -u -p -r1.20 parse.y
--- parse.y 28 Nov 2019 10:02:44 -  1.20
+++ parse.y 29 Nov 2019 20:32:43 -
@@ -90,8 +90,9 @@ struct sockaddr_storage   *host_ip(const c
 
 typedef struct {
union {
-   int64_t  number;
-   char*string;
+   int64_t  number;
+   char*string;
+   struct force_treeforce;
} v;
int lineno;
 } YYSTYPE;
@@ -101,12 +102,13 @@ typedef struct {
 %token INCLUDE ERROR
 %token FORWARDER DOT PORT 
 %token AUTHENTICATION NAME PREFERENCE RECURSOR DHCP STUB
-%token BLOCK LIST LOG
+%token BLOCK LIST LOG FORCE ACCEPTBOGUS
 
 %token   STRING
 %token   NUMBER
-%typeyesno port dot prefopt log
+%typeyesno port dot prefopt log acceptbogus
 %typestring authname
+%type force_list
 
 %%
 
@@ -117,6 +119,7 @@ grammar : /* empty */
| grammar uw_pref '\n'
| grammar uw_forwarder '\n'
| grammar block_list '\n'
+   | grammar force '\n'
| grammar error '\n'{ file->errors++; }
;
 
@@ -311,6 +314,63 @@ dot:   DOT { $$ = 
DOT; }
 log:   LOG { $$ = 1; }
|   /* empty */ { $$ = 0; }
;
+
+force  :   FORCE acceptbogus prefopt '{' force_list optnl '}' {
+   struct force_tree_entry *n, *nxt;
+   int error = 0;
+
+   for (n = RB_MIN(force_tree, &$5); n != NULL;
+   n = nxt) {
+   nxt = RB_NEXT(force_tree, >force, n);
+   n->acceptbogus = $2;
+   n->type = $3;
+   RB_REMOVE(force_tree, &$5, n);
+   if (RB_INSERT(force_tree, >force,
+   n)) {
+   yyerror("%s already in an force "

Re: unwind and split-horizon DNS

2019-11-29 Thread Björn Ketelaars
On Fri 29/11/2019 21:35, Otto Moerbeek wrote:
> On Fri, Nov 29, 2019 at 10:27:57AM +0100, Florian Obser wrote:
> 
> > On Fri, Nov 29, 2019 at 07:28:20AM +0100, Otto Moerbeek wrote:
> > > On Fri, Nov 29, 2019 at 07:02:27AM +0100, Björn Ketelaars wrote:
> > > > I experienced no regression while using the free wifi service of the
> > > > Dutch railways, which is known to do strange things with DNS.
> > > 
> > > Thanks for testing. The Dutch railways have been a great inspiration
> > > to unwind work, as florian@ can telll you :-)
> > 
> > They have got to be good at *something*. Not sure if it's their core
> > business to annoy the hell out of me, but hey...
> > 
> > Only joking, overall I'm quite happy with the Dutch railway. I use
> > them every work day and they get me where I need to go most of the
> > time.
> > 
> > -- 
> > I'm not entirely sure you are real.
> > 
> 
> And here's a rebased diff for your convenience,

The rebased diff results in a different behaviour than the first diff.
More precise, 'force acceptbogus forwarder' is not respected any more
resulting in issues with DNSSEC.

I compared the old- and the rebased diff and noticed that some bits have
been left out. Functionality is restored after applying the diff below.


diff --git sbin/unwind/unwind.c sbin/unwind/unwind.c
index 5a97dcccec4..4687a7cc122 100644
--- sbin/unwind/unwind.c
+++ sbin/unwind/unwind.c
@@ -675,6 +675,12 @@ merge_config(struct uw_conf *conf, struct uw_conf *xconf)
uw_forwarder, entry);
}
 
+   for (n = RB_MIN(force_tree, >force); n != NULL; n = nxt) {
+   nxt = RB_NEXT(force_tree, >force, n);
+   RB_REMOVE(force_tree, >force, n);
+   RB_INSERT(force_tree, >force, n);
+   }
+
free(xconf);
 }
 



Re: unwind and split-horizon DNS

2019-11-29 Thread Otto Moerbeek
On Fri, Nov 29, 2019 at 10:27:57AM +0100, Florian Obser wrote:

> On Fri, Nov 29, 2019 at 07:28:20AM +0100, Otto Moerbeek wrote:
> > On Fri, Nov 29, 2019 at 07:02:27AM +0100, Björn Ketelaars wrote:
> > > I experienced no regression while using the free wifi service of the
> > > Dutch railways, which is known to do strange things with DNS.
> > 
> > Thanks for testing. The Dutch railways have been a great inspiration
> > to unwind work, as florian@ can telll you :-)
> 
> They have got to be good at *something*. Not sure if it's their core
> business to annoy the hell out of me, but hey...
> 
> Only joking, overall I'm quite happy with the Dutch railway. I use
> them every work day and they get me where I need to go most of the
> time.
> 
> -- 
> I'm not entirely sure you are real.
> 

And here's a rebased diff for your convenience,

-Otto

Index: frontend.c
===
RCS file: /cvs/src/sbin/unwind/frontend.c,v
retrieving revision 1.41
diff -u -p -r1.41 frontend.c
--- frontend.c  29 Nov 2019 15:22:02 -  1.41
+++ frontend.c  29 Nov 2019 20:30:19 -
@@ -336,6 +336,7 @@ frontend_dispatch_main(int fd, short eve
case IMSG_RECONF_BLOCKLIST_FILE:
case IMSG_RECONF_FORWARDER:
case IMSG_RECONF_DOT_FORWARDER:
+   case IMSG_RECONF_FORCE:
imsg_receive_config(, );
break;
case IMSG_RECONF_END:
Index: parse.y
===
RCS file: /cvs/src/sbin/unwind/parse.y,v
retrieving revision 1.20
diff -u -p -r1.20 parse.y
--- parse.y 28 Nov 2019 10:02:44 -  1.20
+++ parse.y 29 Nov 2019 20:30:19 -
@@ -90,8 +90,9 @@ struct sockaddr_storage   *host_ip(const c
 
 typedef struct {
union {
-   int64_t  number;
-   char*string;
+   int64_t  number;
+   char*string;
+   struct force_treeforce;
} v;
int lineno;
 } YYSTYPE;
@@ -101,12 +102,13 @@ typedef struct {
 %token INCLUDE ERROR
 %token FORWARDER DOT PORT 
 %token AUTHENTICATION NAME PREFERENCE RECURSOR DHCP STUB
-%token BLOCK LIST LOG
+%token BLOCK LIST LOG FORCE ACCEPTBOGUS
 
 %token   STRING
 %token   NUMBER
-%typeyesno port dot prefopt log
+%typeyesno port dot prefopt log acceptbogus
 %typestring authname
+%type force_list
 
 %%
 
@@ -117,6 +119,7 @@ grammar : /* empty */
| grammar uw_pref '\n'
| grammar uw_forwarder '\n'
| grammar block_list '\n'
+   | grammar force '\n'
| grammar error '\n'{ file->errors++; }
;
 
@@ -311,6 +314,63 @@ dot:   DOT { $$ = 
DOT; }
 log:   LOG { $$ = 1; }
|   /* empty */ { $$ = 0; }
;
+
+force  :   FORCE acceptbogus prefopt '{' force_list optnl '}' {
+   struct force_tree_entry *n, *nxt;
+   int error = 0;
+
+   for (n = RB_MIN(force_tree, &$5); n != NULL;
+   n = nxt) {
+   nxt = RB_NEXT(force_tree, >force, n);
+   n->acceptbogus = $2;
+   n->type = $3;
+   RB_REMOVE(force_tree, &$5, n);
+   if (RB_INSERT(force_tree, >force,
+   n)) {
+   yyerror("%s already in an force "
+   "list", n->domain);
+   error = 1;
+   }
+   }
+   if (error)
+   YYERROR;
+   }
+   ;
+
+acceptbogus:   ACCEPTBOGUS { $$ = 1; }
+   |   /* empty */ { $$ = 0; }
+   ;
+
+force_list:force_list optnl STRING {
+   struct force_tree_entry *e;
+   size_t   len;
+
+   len = strlen($3);
+   e = malloc(sizeof(*e));
+   if (e == NULL)
+   err(1, NULL);
+   if (strlcpy(e->domain, $3, sizeof(e->domain)) >=
+   sizeof(e->domain)) {
+   yyerror("force %s too long", $3);
+   free($3);
+   YYERROR;
+   }
+   free($3);
+   if (len == 0 || e->domain[len-1] != '.') {
+   if (strlcat(e->domain, ".",
+   

Re: unwind and split-horizon DNS

2019-11-29 Thread Florian Obser
On Fri, Nov 29, 2019 at 07:28:20AM +0100, Otto Moerbeek wrote:
> On Fri, Nov 29, 2019 at 07:02:27AM +0100, Björn Ketelaars wrote:
> > I experienced no regression while using the free wifi service of the
> > Dutch railways, which is known to do strange things with DNS.
> 
> Thanks for testing. The Dutch railways have been a great inspiration
> to unwind work, as florian@ can telll you :-)

They have got to be good at *something*. Not sure if it's their core
business to annoy the hell out of me, but hey...

Only joking, overall I'm quite happy with the Dutch railway. I use
them every work day and they get me where I need to go most of the
time.

-- 
I'm not entirely sure you are real.



Re: unwind and split-horizon DNS

2019-11-28 Thread Otto Moerbeek
On Fri, Nov 29, 2019 at 07:02:27AM +0100, Björn Ketelaars wrote:

> On Thu 28/11/2019 16:16, Otto Moerbeek wrote:
> > On Thu, Nov 28, 2019 at 03:26:34PM +0100, Otto Moerbeek wrote:
> > 
> > > Hi,
> > > 
> > > In many offices, split horizon DNS is used. This means that if you are
> > > in the office you are supposed to use a specific resolver that will
> > > hand out different results than when asking for the same name on the
> > > rest of the internet.
> > > 
> > > Until now unwind could not really handle that, e.g. in recursing mode,
> > > it would produce the view as from outside of the office. 
> > > 
> > > With this diff, it becomes possible to force using a specific resolver
> > > when resolving names in specific domains.
> > > 
> > > For example, with this unwind.conf:
> > > 
> > > # Office forwarder
> > > forwarder 1.2.3.4 
> > > force forwarder {
> > >   myoffice.com
> > >   dmz.colocation.com
> > > }
> > > 
> > > This will make unwind always use the mentioned forwarder for anything
> > > under office.com or dmz.colocation.com. If the forwarder is dead,
> > > regular resolving is done for these names and www.office.com will
> > > likely return the external address.
> > > 
> > > Often split-horizon DNS breaks DNSSEC for these specific domains. If
> > > that is the case, you can use
> > > 
> > > force acceptbogus forwarder { 
> > >   ... 
> > > }
> > > 
> > > please test this,
> > > 
> > >   -Otto
> > > 
> > > OAIndex: frontend.c
> > 
> > Dont know hwre that OA is comming from.  But it confuses patch, making
> > it skip first part of the diff. Proper diff below:
> 
> @Home I'm redirecting all DNS requests to a machine with unbound serving
> a couple of local-zones. unwind didn't work for me as these local-zones
> would not resolve because of DNSSEC. With your diff, and the config
> below unwind works perfect.
> 
> forwarder 10.0.0.1
> force acceptbogus forwarder {
>   lan
> }
> 
> I experienced no regression while using the free wifi service of the
> Dutch railways, which is known to do strange things with DNS.

Thanks for testing. The Dutch railways have been a great inspiration
to unwind work, as florian@ can telll you :-)

-Otto



Re: unwind and split-horizon DNS

2019-11-28 Thread Björn Ketelaars
On Thu 28/11/2019 16:16, Otto Moerbeek wrote:
> On Thu, Nov 28, 2019 at 03:26:34PM +0100, Otto Moerbeek wrote:
> 
> > Hi,
> > 
> > In many offices, split horizon DNS is used. This means that if you are
> > in the office you are supposed to use a specific resolver that will
> > hand out different results than when asking for the same name on the
> > rest of the internet.
> > 
> > Until now unwind could not really handle that, e.g. in recursing mode,
> > it would produce the view as from outside of the office. 
> > 
> > With this diff, it becomes possible to force using a specific resolver
> > when resolving names in specific domains.
> > 
> > For example, with this unwind.conf:
> > 
> > # Office forwarder
> > forwarder 1.2.3.4 
> > force forwarder {
> > myoffice.com
> > dmz.colocation.com
> > }
> > 
> > This will make unwind always use the mentioned forwarder for anything
> > under office.com or dmz.colocation.com. If the forwarder is dead,
> > regular resolving is done for these names and www.office.com will
> > likely return the external address.
> > 
> > Often split-horizon DNS breaks DNSSEC for these specific domains. If
> > that is the case, you can use
> > 
> > force acceptbogus forwarder { 
> > ... 
> > }
> > 
> > please test this,
> > 
> > -Otto
> > 
> > OAIndex: frontend.c
> 
> Dont know hwre that OA is comming from.  But it confuses patch, making
> it skip first part of the diff. Proper diff below:

@Home I'm redirecting all DNS requests to a machine with unbound serving
a couple of local-zones. unwind didn't work for me as these local-zones
would not resolve because of DNSSEC. With your diff, and the config
below unwind works perfect.

forwarder 10.0.0.1
force acceptbogus forwarder {
lan
}

I experienced no regression while using the free wifi service of the
Dutch railways, which is known to do strange things with DNS.



Re: unwind and split-horizon DNS

2019-11-28 Thread Otto Moerbeek
On Thu, Nov 28, 2019 at 03:26:34PM +0100, Otto Moerbeek wrote:

> Hi,
> 
> In many offices, split horizon DNS is used. This means that if you are
> in the office you are supposed to use a specific resolver that will
> hand out different results than when asking for the same name on the
> rest of the internet.
> 
> Until now unwind could not really handle that, e.g. in recursing mode,
> it would produce the view as from outside of the office. 
> 
> With this diff, it becomes possible to force using a specific resolver
> when resolving names in specific domains.
> 
> For example, with this unwind.conf:
> 
> # Office forwarder
> forwarder 1.2.3.4 
> force forwarder {
>   myoffice.com
>   dmz.colocation.com
> }
> 
> This will make unwind always use the mentioned forwarder for anything
> under office.com or dmz.colocation.com. If the forwarder is dead,
> regular resolving is done for these names and www.office.com will
> likely return the external address.
> 
> Often split-horizon DNS breaks DNSSEC for these specific domains. If
> that is the case, you can use
> 
> force acceptbogus forwarder { 
>   ... 
> }
> 
> please test this,
> 
>   -Otto
> 
> OAIndex: frontend.c

Dont know hwre that OA is comming from.  But it confuses patch, making
it skip first part of the diff. Proper diff below:

-Otto

Index: frontend.c
===
RCS file: /cvs/src/sbin/unwind/frontend.c,v
retrieving revision 1.40
diff -u -p -r1.40 frontend.c
--- frontend.c  27 Nov 2019 17:09:12 -  1.40
+++ frontend.c  28 Nov 2019 14:24:17 -
@@ -336,6 +336,7 @@ frontend_dispatch_main(int fd, short eve
case IMSG_RECONF_BLOCKLIST_FILE:
case IMSG_RECONF_FORWARDER:
case IMSG_RECONF_DOT_FORWARDER:
+   case IMSG_RECONF_FORCE:
imsg_receive_config(, );
break;
case IMSG_RECONF_END:
Index: parse.y
===
RCS file: /cvs/src/sbin/unwind/parse.y,v
retrieving revision 1.20
diff -u -p -r1.20 parse.y
--- parse.y 28 Nov 2019 10:02:44 -  1.20
+++ parse.y 28 Nov 2019 14:24:17 -
@@ -90,8 +90,9 @@ struct sockaddr_storage   *host_ip(const c
 
 typedef struct {
union {
-   int64_t  number;
-   char*string;
+   int64_t  number;
+   char*string;
+   struct force_treeforce;
} v;
int lineno;
 } YYSTYPE;
@@ -101,12 +102,13 @@ typedef struct {
 %token INCLUDE ERROR
 %token FORWARDER DOT PORT 
 %token AUTHENTICATION NAME PREFERENCE RECURSOR DHCP STUB
-%token BLOCK LIST LOG
+%token BLOCK LIST LOG FORCE ACCEPTBOGUS
 
 %token   STRING
 %token   NUMBER
-%typeyesno port dot prefopt log
+%typeyesno port dot prefopt log acceptbogus
 %typestring authname
+%type force_list
 
 %%
 
@@ -117,6 +119,7 @@ grammar : /* empty */
| grammar uw_pref '\n'
| grammar uw_forwarder '\n'
| grammar block_list '\n'
+   | grammar force '\n'
| grammar error '\n'{ file->errors++; }
;
 
@@ -311,6 +314,63 @@ dot:   DOT { $$ = 
DOT; }
 log:   LOG { $$ = 1; }
|   /* empty */ { $$ = 0; }
;
+
+force  :   FORCE acceptbogus prefopt '{' force_list optnl '}' {
+   struct force_tree_entry *n, *nxt;
+   int error = 0;
+
+   for (n = RB_MIN(force_tree, &$5); n != NULL;
+   n = nxt) {
+   nxt = RB_NEXT(force_tree, >force, n);
+   n->acceptbogus = $2;
+   n->type = $3;
+   RB_REMOVE(force_tree, &$5, n);
+   if (RB_INSERT(force_tree, >force,
+   n)) {
+   yyerror("%s already in an force "
+   "list", n->domain);
+   error = 1;
+   }
+   }
+   if (error)
+   YYERROR;
+   }
+   ;
+
+acceptbogus:   ACCEPTBOGUS { $$ = 1; }
+   |   /* empty */ { $$ = 0; }
+   ;
+
+force_list:force_list optnl STRING {
+   struct force_tree_entry *e;
+   size_t   len;
+
+   len = strlen($3);
+   e = malloc(sizeof(*e));
+   if (e == NULL)
+   err(1, NULL);
+

unwind and split-horizon DNS

2019-11-28 Thread Otto Moerbeek
Hi,

In many offices, split horizon DNS is used. This means that if you are
in the office you are supposed to use a specific resolver that will
hand out different results than when asking for the same name on the
rest of the internet.

Until now unwind could not really handle that, e.g. in recursing mode,
it would produce the view as from outside of the office. 

With this diff, it becomes possible to force using a specific resolver
when resolving names in specific domains.

For example, with this unwind.conf:

# Office forwarder
forwarder 1.2.3.4 
force forwarder {
myoffice.com
dmz.colocation.com
}

This will make unwind always use the mentioned forwarder for anything
under office.com or dmz.colocation.com. If the forwarder is dead,
regular resolving is done for these names and www.office.com will
likely return the external address.

Often split-horizon DNS breaks DNSSEC for these specific domains. If
that is the case, you can use

force acceptbogus forwarder { 
... 
}

please test this,

-Otto

OAIndex: frontend.c
===
RCS file: /cvs/src/sbin/unwind/frontend.c,v
retrieving revision 1.40
diff -u -p -r1.40 frontend.c
--- frontend.c  27 Nov 2019 17:09:12 -  1.40
+++ frontend.c  28 Nov 2019 14:24:17 -
@@ -336,6 +336,7 @@ frontend_dispatch_main(int fd, short eve
case IMSG_RECONF_BLOCKLIST_FILE:
case IMSG_RECONF_FORWARDER:
case IMSG_RECONF_DOT_FORWARDER:
+   case IMSG_RECONF_FORCE:
imsg_receive_config(, );
break;
case IMSG_RECONF_END:
Index: parse.y
===
RCS file: /cvs/src/sbin/unwind/parse.y,v
retrieving revision 1.20
diff -u -p -r1.20 parse.y
--- parse.y 28 Nov 2019 10:02:44 -  1.20
+++ parse.y 28 Nov 2019 14:24:17 -
@@ -90,8 +90,9 @@ struct sockaddr_storage   *host_ip(const c
 
 typedef struct {
union {
-   int64_t  number;
-   char*string;
+   int64_t  number;
+   char*string;
+   struct force_treeforce;
} v;
int lineno;
 } YYSTYPE;
@@ -101,12 +102,13 @@ typedef struct {
 %token INCLUDE ERROR
 %token FORWARDER DOT PORT 
 %token AUTHENTICATION NAME PREFERENCE RECURSOR DHCP STUB
-%token BLOCK LIST LOG
+%token BLOCK LIST LOG FORCE ACCEPTBOGUS
 
 %token   STRING
 %token   NUMBER
-%typeyesno port dot prefopt log
+%typeyesno port dot prefopt log acceptbogus
 %typestring authname
+%type force_list
 
 %%
 
@@ -117,6 +119,7 @@ grammar : /* empty */
| grammar uw_pref '\n'
| grammar uw_forwarder '\n'
| grammar block_list '\n'
+   | grammar force '\n'
| grammar error '\n'{ file->errors++; }
;
 
@@ -311,6 +314,63 @@ dot:   DOT { $$ = 
DOT; }
 log:   LOG { $$ = 1; }
|   /* empty */ { $$ = 0; }
;
+
+force  :   FORCE acceptbogus prefopt '{' force_list optnl '}' {
+   struct force_tree_entry *n, *nxt;
+   int error = 0;
+
+   for (n = RB_MIN(force_tree, &$5); n != NULL;
+   n = nxt) {
+   nxt = RB_NEXT(force_tree, >force, n);
+   n->acceptbogus = $2;
+   n->type = $3;
+   RB_REMOVE(force_tree, &$5, n);
+   if (RB_INSERT(force_tree, >force,
+   n)) {
+   yyerror("%s already in an force "
+   "list", n->domain);
+   error = 1;
+   }
+   }
+   if (error)
+   YYERROR;
+   }
+   ;
+
+acceptbogus:   ACCEPTBOGUS { $$ = 1; }
+   |   /* empty */ { $$ = 0; }
+   ;
+
+force_list:force_list optnl STRING {
+   struct force_tree_entry *e;
+   size_t   len;
+
+   len = strlen($3);
+   e = malloc(sizeof(*e));
+   if (e == NULL)
+   err(1, NULL);
+   if (strlcpy(e->domain, $3, sizeof(e->domain)) >=
+   sizeof(e->domain)) {
+   yyerror("force %s too long", $3);
+   free($3);
+   YYERROR;
+   }
+