Re: [patch] update unbound forwards with dhclient nameservers
On Sun, Jul 19, 2015 at 08:53:04PM +0200, Gregor Best wrote: > On Sun, Jul 19, 2015 at 07:03:59PM +0100, Stuart Henderson wrote: > > [...] > > I'm uncertain about whether dhclient should do this at all, it seems > > to be the opposite of the direction dhclient has been going in > > recently, > > [...] > > I've had a similar intuition at first, but it's one less thing to run > versus the "monitor lease file" approach and it only calls one static > external command with relatively fixed parameters instead of what the > removed `script' option did. In the end, it's a matter of personal > taste, I think. Indeed, I prodded krw@ to have a look / final say. If it's inaproriate for dhclient we might re-consider this for the magical "manage-network-daemon" if/when it shows up. As far as I'm concerned having unbound run on localhost is a sensible setup. Btw. my use case is for stupid networks that require that you use their resolvers. -- I'm not entirely sure you are real.
Re: [patch] update unbound forwards with dhclient nameservers
On Sun, Jul 19, 2015 at 07:03:59PM +0100, Stuart Henderson wrote: > [...] > I'm uncertain about whether dhclient should do this at all, it seems > to be the opposite of the direction dhclient has been going in > recently, > [...] I've had a similar intuition at first, but it's one less thing to run versus the "monitor lease file" approach and it only calls one static external command with relatively fixed parameters instead of what the removed `script' option did. In the end, it's a matter of personal taste, I think. > [...] > but if it is added, it probably wants to be disabled for the ramdisk. > [...] I've attached an updated patch, in case this is still interesting to someone. Do I need to add anything other than `#ifdef SMALL' in the appropriate places? -- Gregor Best -- Index: clparse.c === RCS file: /mnt/media/cvs/src/sbin/dhclient/clparse.c,v retrieving revision 1.92 diff -u -p -r1.92 clparse.c --- clparse.c 18 May 2015 17:51:21 - 1.92 +++ clparse.c 19 Jul 2015 18:44:12 - @@ -75,6 +75,9 @@ read_client_conf(void) config->backoff_cutoff = 15; config->initial_interval = 3; config->bootp_policy = ACCEPT; +#ifndef SMALL + config->update_unbound = 0; +#endif config->requested_options [config->requested_option_count++] = DHO_SUBNET_MASK; config->requested_options @@ -270,6 +273,12 @@ parse_client_statement(FILE *cfile) if (parse_ip_addr(cfile, &config->next_server)) parse_semi(cfile); break; +#ifndef SMALL + case TOK_UPDATE_UNBOUND: + config->update_unbound = 1; + parse_semi(cfile); + break; +#endif default: parse_warn("expecting a statement."); if (token != ';') Index: conflex.c === RCS file: /mnt/media/cvs/src/sbin/dhclient/conflex.c,v retrieving revision 1.32 diff -u -p -r1.32 conflex.c --- conflex.c 18 May 2015 17:51:21 - 1.32 +++ conflex.c 19 Jul 2015 18:48:00 - @@ -341,7 +341,10 @@ static const struct keywords { { "send", TOK_SEND }, { "server-name",TOK_SERVER_NAME }, { "supersede", TOK_SUPERSEDE }, - { "timeout",TOK_TIMEOUT } + { "timeout",TOK_TIMEOUT }, +#ifndef SMALL + { "update-unbound", TOK_UPDATE_UNBOUND } +#endif }; intkw_cmp(const void *k, const void *e); Index: dhclient.c === RCS file: /mnt/media/cvs/src/sbin/dhclient/dhclient.c,v retrieving revision 1.361 diff -u -p -r1.361 dhclient.c --- dhclient.c 18 May 2015 14:59:42 - 1.361 +++ dhclient.c 19 Jul 2015 18:45:28 - @@ -97,6 +97,9 @@ intres_hnok(const char *dn); voidfork_privchld(int, int); voidget_ifname(char *); +#ifndef SMALL +voidupdate_unbound_forwards(struct option_data *); +#endif char *resolv_conf_contents(struct option_data *, struct option_data *); voidwrite_resolv_conf(u_int8_t *, size_t); @@ -903,8 +906,15 @@ bind_lease(void) goto newlease; } - client->new->resolv_conf = resolv_conf_contents( - &options[DHO_DOMAIN_NAME], &options[DHO_DOMAIN_NAME_SERVERS]); +#ifndef SMALL + if (config->update_unbound) { + update_unbound_forwards(&options[DHO_DOMAIN_NAME_SERVERS]); + } else +#endif + { + client->new->resolv_conf = resolv_conf_contents( + &options[DHO_DOMAIN_NAME], &options[DHO_DOMAIN_NAME_SERVERS]); + } /* Replace the old active lease with the new one. */ client->active = client->new; @@ -2043,6 +2053,91 @@ get_ifname(char *arg) } else if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ) error("Interface name too long"); } + +#ifndef SMALL +/* + * Update unbound forwarder list + */ +void +update_unbound_forwards(struct option_data *nameservers) +{ + char *ns; + int rslt; + + if (!nameservers->len) { + return; + } + + ns = pretty_print_option(DHO_DOMAIN_NAME_SERVERS, nameservers, 0); + + rslt = imsg_compose(unpriv_ibuf, IMSG_UPDATE_UNBOUND_FORWARDS, + 0, 0, -1, ns, strlen(ns) + 1); + + if (rslt == -1) { + warning("update_unbound_forwards: imsg_compose: %s", + strerror(errno)); + } + + flush_unpriv_ibuf("update_unbound_forwards"); +} + +void +priv_update_unbound_forwards(struct imsg *imsg) +{ + char *args[MAXNS + 3]; /* `unbound-control', `forward', final NULL */ + char *ns, *p, **srv; + int rslt, i = 0; +
Re: [patch] update unbound forwards with dhclient nameservers
On 2015/07/19 19:53, Gregor Best wrote: > On Sun, Jul 19, 2015 at 03:31:33PM +, Florian Obser wrote: > > [...] > > Oh god, yes please. I always wanted to write this diff myself ;) > > More comments in the diff below. > > [...] > > Great to read. I've attached an updated patch. I'm uncertain about whether dhclient should do this at all, it seems to be the opposite of the direction dhclient has been going in recently, but if it is added, it probably wants to be disabled for the ramdisk.
Re: [patch] update unbound forwards with dhclient nameservers
On Sun, Jul 19, 2015 at 03:31:33PM +, Florian Obser wrote: > [...] > Oh god, yes please. I always wanted to write this diff myself ;) > More comments in the diff below. > [...] Great to read. I've attached an updated patch. -- Gregor Best Index: clparse.c === RCS file: /mnt/media/cvs/src/sbin/dhclient/clparse.c,v retrieving revision 1.92 diff -u -p -r1.92 clparse.c --- clparse.c 18 May 2015 17:51:21 - 1.92 +++ clparse.c 9 Jul 2015 15:00:05 - @@ -75,6 +75,7 @@ read_client_conf(void) config->backoff_cutoff = 15; config->initial_interval = 3; config->bootp_policy = ACCEPT; + config->update_unbound = 0; config->requested_options [config->requested_option_count++] = DHO_SUBNET_MASK; config->requested_options @@ -269,6 +270,10 @@ parse_client_statement(FILE *cfile) case TOK_NEXT_SERVER: if (parse_ip_addr(cfile, &config->next_server)) parse_semi(cfile); + break; + case TOK_UPDATE_UNBOUND: + config->update_unbound = 1; + parse_semi(cfile); break; default: parse_warn("expecting a statement."); Index: conflex.c === RCS file: /mnt/media/cvs/src/sbin/dhclient/conflex.c,v retrieving revision 1.32 diff -u -p -r1.32 conflex.c --- conflex.c 18 May 2015 17:51:21 - 1.32 +++ conflex.c 19 Jul 2015 17:31:13 - @@ -341,7 +341,8 @@ static const struct keywords { { "send", TOK_SEND }, { "server-name",TOK_SERVER_NAME }, { "supersede", TOK_SUPERSEDE }, - { "timeout",TOK_TIMEOUT } + { "timeout",TOK_TIMEOUT }, + { "update-unbound", TOK_UPDATE_UNBOUND } }; intkw_cmp(const void *k, const void *e); Index: dhclient.c === RCS file: /mnt/media/cvs/src/sbin/dhclient/dhclient.c,v retrieving revision 1.361 diff -u -p -r1.361 dhclient.c --- dhclient.c 18 May 2015 14:59:42 - 1.361 +++ dhclient.c 19 Jul 2015 17:48:11 - @@ -97,6 +97,7 @@ intres_hnok(const char *dn); voidfork_privchld(int, int); voidget_ifname(char *); +voidupdate_unbound_forwards(struct option_data *); char *resolv_conf_contents(struct option_data *, struct option_data *); voidwrite_resolv_conf(u_int8_t *, size_t); @@ -903,8 +904,12 @@ bind_lease(void) goto newlease; } - client->new->resolv_conf = resolv_conf_contents( - &options[DHO_DOMAIN_NAME], &options[DHO_DOMAIN_NAME_SERVERS]); + if (config->update_unbound) { + update_unbound_forwards(&options[DHO_DOMAIN_NAME_SERVERS]); + } else { + client->new->resolv_conf = resolv_conf_contents( + &options[DHO_DOMAIN_NAME], &options[DHO_DOMAIN_NAME_SERVERS]); + } /* Replace the old active lease with the new one. */ client->active = client->new; @@ -2042,6 +2047,89 @@ get_ifname(char *arg) close(s); } else if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ) error("Interface name too long"); +} + +/* + * Update unbound forwarder list + */ +void +update_unbound_forwards(struct option_data *nameservers) +{ + char *ns; + int rslt; + + if (!nameservers->len) { + return; + } + + ns = pretty_print_option(DHO_DOMAIN_NAME_SERVERS, nameservers, 0); + + rslt = imsg_compose(unpriv_ibuf, IMSG_UPDATE_UNBOUND_FORWARDS, + 0, 0, -1, ns, strlen(ns) + 1); + + if (rslt == -1) { + warning("update_unbound_forwards: imsg_compose: %s", + strerror(errno)); + } + + flush_unpriv_ibuf("update_unbound_forwards"); +} + +void +priv_update_unbound_forwards(struct imsg *imsg) +{ + char *args[MAXNS + 3]; /* `unbound-control', `forward', final NULL */ + char *ns, *p, **srv; + int rslt, i = 0; + size_t sz; + pid_t child; + + if (imsg->hdr.len < IMSG_HEADER_SIZE) { + warning("short IMSG_UPDATE_UNBOUND_FORWARDS"); + return; + } + + ns = imsg->data; + sz = imsg->hdr.len - IMSG_HEADER_SIZE; + ns[sz] = '\0'; /* Make sure we're terminated properly */ + + /* Construct unbound-control arguments */ + memset(args, 0, sizeof(args)); + args[0] = "unbound-control"; + args[1] = "forward"; + srv = &args[2]; + while (i < MAXNS) { + p = strsep(&ns, " "); + if (p == NULL) + break; + if (*p == '\0')
Re: [patch] update unbound forwards with dhclient nameservers
I really like this idea, modulo the comments that Florian made. On 2015 Jul 19 (Sun) at 13:08:46 +0200 (+0200), Gregor Best wrote: :Hello, : :the following is a patch that adds an option called `update_unbound' to :dhclient.conf. With this option enabled, dhclient will call : : unbound-control forwards : :instead of rewriting /etc/resolv.conf. : :My usage scenario is that I'm running unbound on my laptop as a local :resolver. /etc/resolv.conf is configured to only use 127.0.0.1 as the :nameserver. : :I use this because I have a few VPN connections that have custom DNS :namespaces, which I manage with Unbound's forward zones. Since :sometimes I am in networks that have a split horizon DNS (e.g. :University, hackerspace, etc...), I can't use a statically configured :fallback forward zone for all my requests. Manually calling using :unbound-control to change the forward DNS became too annoying, so I :wrote this patch. : :Does the patch make sense in OpenBSD or should I keep it as a local :change? : :-- : Gregor Best :-- : :Index: clparse.c :=== :RCS file: /mnt/media/cvs/src/sbin/dhclient/clparse.c,v :retrieving revision 1.92 :diff -u -p -r1.92 clparse.c :--- clparse.c 18 May 2015 17:51:21 - 1.92 :+++ clparse.c 9 Jul 2015 15:00:05 - :@@ -75,6 +75,7 @@ read_client_conf(void) : config->backoff_cutoff = 15; : config->initial_interval = 3; : config->bootp_policy = ACCEPT; :+ config->update_unbound = 0; : config->requested_options : [config->requested_option_count++] = DHO_SUBNET_MASK; : config->requested_options :@@ -269,6 +270,10 @@ parse_client_statement(FILE *cfile) : case TOK_NEXT_SERVER: : if (parse_ip_addr(cfile, &config->next_server)) : parse_semi(cfile); :+ break; :+ case TOK_UPDATE_UNBOUND: :+ config->update_unbound = 1; :+ parse_semi(cfile); : break; : default: : parse_warn("expecting a statement."); :Index: conflex.c :=== :RCS file: /mnt/media/cvs/src/sbin/dhclient/conflex.c,v :retrieving revision 1.32 :diff -u -p -r1.32 conflex.c :--- conflex.c 18 May 2015 17:51:21 - 1.32 :+++ conflex.c 9 Jul 2015 14:54:56 - :@@ -341,7 +341,8 @@ static const struct keywords { : { "send", TOK_SEND }, : { "server-name",TOK_SERVER_NAME }, : { "supersede", TOK_SUPERSEDE }, :- { "timeout",TOK_TIMEOUT } :+ { "timeout",TOK_TIMEOUT }, :+ { "update_unbound", TOK_UPDATE_UNBOUND } : }; : : int kw_cmp(const void *k, const void *e); :Index: dhclient.c :=== :RCS file: /mnt/media/cvs/src/sbin/dhclient/dhclient.c,v :retrieving revision 1.361 :diff -u -p -r1.361 dhclient.c :--- dhclient.c 18 May 2015 14:59:42 - 1.361 :+++ dhclient.c 9 Jul 2015 15:52:41 - :@@ -97,6 +97,7 @@ int res_hnok(const char *dn); : : void fork_privchld(int, int); : void get_ifname(char *); :+void update_unbound_forwards(struct option_data *); : char *resolv_conf_contents(struct option_data *, :struct option_data *); : void write_resolv_conf(u_int8_t *, size_t); :@@ -903,8 +904,12 @@ bind_lease(void) : goto newlease; : } : :- client->new->resolv_conf = resolv_conf_contents( :- &options[DHO_DOMAIN_NAME], &options[DHO_DOMAIN_NAME_SERVERS]); :+ if (config->update_unbound) { :+ update_unbound_forwards(&options[DHO_DOMAIN_NAME_SERVERS]); :+ } else { :+ client->new->resolv_conf = resolv_conf_contents( :+ &options[DHO_DOMAIN_NAME], &options[DHO_DOMAIN_NAME_SERVERS]); :+ } : : /* Replace the old active lease with the new one. */ : client->active = client->new; :@@ -2042,6 +2047,88 @@ get_ifname(char *arg) : close(s); : } else if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ) : error("Interface name too long"); :+} :+ :+/* :+ * Update unbound forwarder list :+ */ :+void :+update_unbound_forwards(struct option_data *nameservers) :+{ :+ char *ns; :+ int rslt; :+ :+ if (!nameservers->len) { :+ return; :+ } :+ :+ ns = pretty_print_option(DHO_DOMAIN_NAME_SERVERS, nameservers, 0); :+ :+ rslt = imsg_compose(unpriv_ibuf, IMSG_UPDATE_UNBOUND_FORWARDS, :+ 0, 0, -1, ns, strlen(ns) + 1); :+ :+ if (rslt == -1) { :+ warning("update_unbound_forwards: imsg_compose: %s", :+ strerror(errno)); :+ } :+ :+ flush_unpriv_ibuf("update_unbound_forwards"); :+} :+ :+void :+priv_updat
Re: [patch] update unbound forwards with dhclient nameservers
On 2015/07/19 13:08, Gregor Best wrote: > Hello, > > the following is a patch that adds an option called `update_unbound' to > dhclient.conf. With this option enabled, dhclient will call > > unbound-control forwards > > instead of rewriting /etc/resolv.conf. > > My usage scenario is that I'm running unbound on my laptop as a local > resolver. /etc/resolv.conf is configured to only use 127.0.0.1 as the > nameserver. I'm doing this without patches, using a script run by entr (from packages) to watch the lease file (written with -L /etc/dhclient.lease., i.e. "!dhclient -L /etc/dhclient.lease.iwn0 iwn0" in /etc/hostname.iwn0). The code doing -L in dhclient takes care to keep the same inode for this file specifically to support doing this. $ cat dhcp-watcher #!/bin/sh gw=$(route -n get -inet 0.0.0.0 | awk '/interface/ {print $2}') dns=$(awk '/domain-name-servers/ {gsub("[;,]", " ", $3); print $3;}' /etc/dhclient.lease.$gw) unbound-control forward_add . $dns > /dev/null echo "default now on $gw: $(unbound-control list_forwards)" | logger -t dhcp-watcher $ cat dhcp-watcher.run #!/bin/sh /etc/dhcp-watcher echo /etc/dhclient.lease.* | tr ' ' '\n' | /usr/local/bin/entr /etc/dhcp-watcher
Re: [patch] update unbound forwards with dhclient nameservers
On Sun, Jul 19, 2015 at 01:08:46PM +0200, Gregor Best wrote: > Hello, > > the following is a patch that adds an option called `update_unbound' to > dhclient.conf. With this option enabled, dhclient will call > > unbound-control forwards > > instead of rewriting /etc/resolv.conf. > > My usage scenario is that I'm running unbound on my laptop as a local > resolver. /etc/resolv.conf is configured to only use 127.0.0.1 as the > nameserver. > Oh god, yes please. I always wanted to write this diff myself ;) More comments in the diff below. > I use this because I have a few VPN connections that have custom DNS > namespaces, which I manage with Unbound's forward zones. Since > sometimes I am in networks that have a split horizon DNS (e.g. > University, hackerspace, etc...), I can't use a statically configured > fallback forward zone for all my requests. Manually calling using > unbound-control to change the forward DNS became too annoying, so I > wrote this patch. > > Does the patch make sense in OpenBSD or should I keep it as a local > change? > > -- > Gregor Best > -- > > Index: clparse.c > === > RCS file: /mnt/media/cvs/src/sbin/dhclient/clparse.c,v > retrieving revision 1.92 > diff -u -p -r1.92 clparse.c > --- clparse.c 18 May 2015 17:51:21 - 1.92 > +++ clparse.c 9 Jul 2015 15:00:05 - > @@ -75,6 +75,7 @@ read_client_conf(void) > config->backoff_cutoff = 15; > config->initial_interval = 3; > config->bootp_policy = ACCEPT; > + config->update_unbound = 0; > config->requested_options > [config->requested_option_count++] = DHO_SUBNET_MASK; > config->requested_options > @@ -269,6 +270,10 @@ parse_client_statement(FILE *cfile) > case TOK_NEXT_SERVER: > if (parse_ip_addr(cfile, &config->next_server)) > parse_semi(cfile); > + break; > + case TOK_UPDATE_UNBOUND: > + config->update_unbound = 1; > + parse_semi(cfile); > break; > default: > parse_warn("expecting a statement."); > Index: conflex.c > === > RCS file: /mnt/media/cvs/src/sbin/dhclient/conflex.c,v > retrieving revision 1.32 > diff -u -p -r1.32 conflex.c > --- conflex.c 18 May 2015 17:51:21 - 1.32 > +++ conflex.c 9 Jul 2015 14:54:56 - > @@ -341,7 +341,8 @@ static const struct keywords { > { "send", TOK_SEND }, > { "server-name",TOK_SERVER_NAME }, > { "supersede", TOK_SUPERSEDE }, > - { "timeout",TOK_TIMEOUT } > + { "timeout",TOK_TIMEOUT }, > + { "update_unbound", TOK_UPDATE_UNBOUND } Use update-unbound (minus, not underscrore) for the keyword; also update the man page. > }; > > int kw_cmp(const void *k, const void *e); > Index: dhclient.c > === > RCS file: /mnt/media/cvs/src/sbin/dhclient/dhclient.c,v > retrieving revision 1.361 > diff -u -p -r1.361 dhclient.c > --- dhclient.c18 May 2015 14:59:42 - 1.361 > +++ dhclient.c9 Jul 2015 15:52:41 - > @@ -97,6 +97,7 @@ int res_hnok(const char *dn); > > void fork_privchld(int, int); > void get_ifname(char *); > +void update_unbound_forwards(struct option_data *); > char *resolv_conf_contents(struct option_data *, >struct option_data *); > void write_resolv_conf(u_int8_t *, size_t); > @@ -903,8 +904,12 @@ bind_lease(void) > goto newlease; > } > > - client->new->resolv_conf = resolv_conf_contents( > - &options[DHO_DOMAIN_NAME], &options[DHO_DOMAIN_NAME_SERVERS]); > + if (config->update_unbound) { > + update_unbound_forwards(&options[DHO_DOMAIN_NAME_SERVERS]); > + } else { > + client->new->resolv_conf = resolv_conf_contents( > + &options[DHO_DOMAIN_NAME], > &options[DHO_DOMAIN_NAME_SERVERS]); > + } > > /* Replace the old active lease with the new one. */ > client->active = client->new; > @@ -2042,6 +2047,88 @@ get_ifname(char *arg) > close(s); > } else if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ) > error("Interface name too long"); > +} > + > +/* > + * Update unbound forwarder list > + */ > +void > +update_unbound_forwards(struct option_data *nameservers) > +{ > + char *ns; > + int rslt; > + > + if (!nameservers->len) { > + return; > + } > + > + ns = pretty_print_option(DHO_DOMAIN_NAME_SERVERS, nameservers, 0); > + > + rslt = imsg_compose(unpriv_ibuf, IMSG_UPDATE_UNBOUND_FORWARDS, > + 0, 0, -1, ns, strlen(ns) + 1); > + > + if (rslt == -1) { > +
[patch] update unbound forwards with dhclient nameservers
Hello, the following is a patch that adds an option called `update_unbound' to dhclient.conf. With this option enabled, dhclient will call unbound-control forwards instead of rewriting /etc/resolv.conf. My usage scenario is that I'm running unbound on my laptop as a local resolver. /etc/resolv.conf is configured to only use 127.0.0.1 as the nameserver. I use this because I have a few VPN connections that have custom DNS namespaces, which I manage with Unbound's forward zones. Since sometimes I am in networks that have a split horizon DNS (e.g. University, hackerspace, etc...), I can't use a statically configured fallback forward zone for all my requests. Manually calling using unbound-control to change the forward DNS became too annoying, so I wrote this patch. Does the patch make sense in OpenBSD or should I keep it as a local change? -- Gregor Best -- Index: clparse.c === RCS file: /mnt/media/cvs/src/sbin/dhclient/clparse.c,v retrieving revision 1.92 diff -u -p -r1.92 clparse.c --- clparse.c 18 May 2015 17:51:21 - 1.92 +++ clparse.c 9 Jul 2015 15:00:05 - @@ -75,6 +75,7 @@ read_client_conf(void) config->backoff_cutoff = 15; config->initial_interval = 3; config->bootp_policy = ACCEPT; + config->update_unbound = 0; config->requested_options [config->requested_option_count++] = DHO_SUBNET_MASK; config->requested_options @@ -269,6 +270,10 @@ parse_client_statement(FILE *cfile) case TOK_NEXT_SERVER: if (parse_ip_addr(cfile, &config->next_server)) parse_semi(cfile); + break; + case TOK_UPDATE_UNBOUND: + config->update_unbound = 1; + parse_semi(cfile); break; default: parse_warn("expecting a statement."); Index: conflex.c === RCS file: /mnt/media/cvs/src/sbin/dhclient/conflex.c,v retrieving revision 1.32 diff -u -p -r1.32 conflex.c --- conflex.c 18 May 2015 17:51:21 - 1.32 +++ conflex.c 9 Jul 2015 14:54:56 - @@ -341,7 +341,8 @@ static const struct keywords { { "send", TOK_SEND }, { "server-name",TOK_SERVER_NAME }, { "supersede", TOK_SUPERSEDE }, - { "timeout",TOK_TIMEOUT } + { "timeout",TOK_TIMEOUT }, + { "update_unbound", TOK_UPDATE_UNBOUND } }; intkw_cmp(const void *k, const void *e); Index: dhclient.c === RCS file: /mnt/media/cvs/src/sbin/dhclient/dhclient.c,v retrieving revision 1.361 diff -u -p -r1.361 dhclient.c --- dhclient.c 18 May 2015 14:59:42 - 1.361 +++ dhclient.c 9 Jul 2015 15:52:41 - @@ -97,6 +97,7 @@ intres_hnok(const char *dn); voidfork_privchld(int, int); voidget_ifname(char *); +voidupdate_unbound_forwards(struct option_data *); char *resolv_conf_contents(struct option_data *, struct option_data *); voidwrite_resolv_conf(u_int8_t *, size_t); @@ -903,8 +904,12 @@ bind_lease(void) goto newlease; } - client->new->resolv_conf = resolv_conf_contents( - &options[DHO_DOMAIN_NAME], &options[DHO_DOMAIN_NAME_SERVERS]); + if (config->update_unbound) { + update_unbound_forwards(&options[DHO_DOMAIN_NAME_SERVERS]); + } else { + client->new->resolv_conf = resolv_conf_contents( + &options[DHO_DOMAIN_NAME], &options[DHO_DOMAIN_NAME_SERVERS]); + } /* Replace the old active lease with the new one. */ client->active = client->new; @@ -2042,6 +2047,88 @@ get_ifname(char *arg) close(s); } else if (strlcpy(ifi->name, arg, IFNAMSIZ) >= IFNAMSIZ) error("Interface name too long"); +} + +/* + * Update unbound forwarder list + */ +void +update_unbound_forwards(struct option_data *nameservers) +{ + char *ns; + int rslt; + + if (!nameservers->len) { + return; + } + + ns = pretty_print_option(DHO_DOMAIN_NAME_SERVERS, nameservers, 0); + + rslt = imsg_compose(unpriv_ibuf, IMSG_UPDATE_UNBOUND_FORWARDS, + 0, 0, -1, ns, strlen(ns) + 1); + + if (rslt == -1) { + warning("update_unbound_forwards: imsg_compose: %s", + strerror(errno)); + } + + flush_unpriv_ibuf("update_unbound_forwards"); +} + +void +priv_update_unbound_forwards(struct imsg *imsg) +{ + char *args[MAXNS + 3]; /* `unbound-control', `forward', final NULL */ + char *ns, *p; + int i, rslt; + size_t sz; + pid_t child;