Hi, On Fri, Jul 10, 2020 at 06:42:18PM +0200, Jan Just Keijser wrote: > On 08/07/20 10:24, Gert Doering wrote: > > Can I have a v4, please? :-) > V4:
Okay, here we go...
Generally speaking, it works now :-)
In the "ipconfig /all" output, I can now see a long list of DNS suffixes.
Together with a DNS search list on the LAN *and* block-outside-dns, this
seems to have interesting effects on Win10 - namely, it tries all the
search domains it has (on all interfaces), but it will try the "LAN"
search domains only via the "LAN" nameservers - and these are blocked,
so there might be interesting side effects if both are used togehter -
*or* it might be a way to get Win10 DNS to behave better even without
block-outside-DNS (by configuring a search domain on the TAP side).
Codewise, a few remarks...
> @@ -1145,6 +1146,19 @@ parse_hash_fingerprint(const char *str, int nbytes,
> int msglevel, struct gc_aren
> #ifndef ENABLE_SMALL
>
> static void
> +show_dhcp_option_list(const char *name, const char * const*array, int len)
> +{
> + int i;
> + for (i = 0; i < len; ++i)
> + {
> + msg(D_SHOW_PARMS, " %s[%d] = %s",
> + name,
> + i,
> + array[i] );
> + }
> +}
This is not "forbidden" by the style guide, but I think a more compact
form would increase readability - the old openvpn style of having
individual function calls spread over 10+ lines because each parameter
is getting its own line is not really something we do anymore. So:
> + msg(D_SHOW_PARMS, " %s[%d] = %s", name, i, array[i] );
... which is well below the 80 character limit and which I find more
readable, tbh.
> +/*
> + * RFC3397 states that multiple searchdomains are encoded as follows:
> + * - at start the length of the entire option is given
> + * - each subdomain is preceded by its length
> + * - each searchdomain is separated by a NUL character
> + * e.g. if you want "openvpn.net" and "duckduckgo.com" then you end up with
> + * 0x13 0x7 openvpn 0x3 net 0x00 0x0A duckduckgo 0x3 com 0x00
While at it, 0x1D :-)
> + */
> +static void
> +write_dhcp_search_str(struct buffer *buf, const int type, const char * const
> *str_array,
> + int array_len, bool *error)
> +{
> + char tmp_buf[256];
> + int i;
> + int len = 0;
> +
> + for (i=0; i < array_len; i++)
> + {
> + const char *ptr = str_array[i], *dotptr = str_array[i];
> + int j, k;
> +
> + msg(M_INFO, "Processing '%s'", ptr);
This line should not stay as it is - if you see it in the log, it's
mostly unclear "it's processing 'domain' - what for?", and M_INFO is
too high for unspecific info.
Most other DHCP activities do not log anything (unless error), so for
consistency I would just remove it. But if we keep it, it needs to
be more clear, like
> + msg(D_DHCP_OPT, "dhcp search domain '%s'", ptr);
or something like that.
> + if (strlen(ptr) + len + 1 > sizeof(tmp_buf))
> + {
> + *error = true;
> + msg(M_WARN, "write_dhcp_search_str: temp buffer overflow
> building DHCP options");
> + return;
> + }
> + /* Loop over all subdomains separated by a dot and replace the dot
> + with the length of the subdomain */
> + while ((dotptr = strchr(ptr, '.')) != NULL)
> + {
> + j = dotptr - ptr;
> + tmp_buf[len++] = j;
> + for (k=0; k < j; k++) tmp_buf[len++] = ptr[k];
Side note: this violate coding style - for(), as if(), mandates brackets.
> + for (k=0; k < j; k++)
{
tmp_buf[len++] = ptr[k];
}
> + ptr = dotptr + 1;
> + }
> +
> + /* Now do the remainder after the last dot */
> + j = strlen(ptr);
> + tmp_buf[len++] = j;
> + for (k=0; k < j; k++) tmp_buf[len++] = ptr[k];
same here.
> +
> + /* And close off with an extra NUL char */
> + tmp_buf[len++] = 0;
> + }
With these required brackets, the nested loops get long - and I do not
find them overly elegant anyway (one could do a memcpy(), which would
make more clear what is done, but it's still double-looping).
For this, I had the idea to code it as follows (mentioned yesterday, but
now actually written down) - single pass, no nested loops:
/* Loop over all subdomains separated by a dot and replace the dot
with the length of the subdomain */
/* label_length_pos points to the byte to be replaced by the length
* of the following domain label */
int label_length_pos = len++;
while(true)
{
if (*ptr == '.' || *ptr == '\0' )
{
tmp_buf[label_length_pos] = (len-label_length_pos)-1;
label_length_pos = len;
if (*ptr == '\0')
{
break;
}
}
tmp_buf[len++] = *ptr++;
}
/* And close off with an extra NUL char */
tmp_buf[len++] = '\0';
(I've actually tested this and it works :-) - wireshark and Win10 confirms
that the result is good - so if you want it, just use it for v5, if not,
leave it)
> +
> + if (!buf_safe(buf, 2 + len))
> + {
> + *error = true;
> + msg(M_WARN, "write_search_dhcp_str: buffer overflow building DHCP
> options");
> + return;
> + }
> + if (len > 255)
> + {
> + *error = true;
> + msg(M_WARN, "write_dhcp_search_str: search domain string must be <=
> 255 bytes");
> + return;
> + }
> +
> + buf_write_u8(buf, type);
> + buf_write_u8(buf, len);
> + for (i=0; i < len; i++) buf_write_u8(buf, tmp_buf[i]);
> +}
There's another set of brackets needed here... { buf_write_u8() }
But why use buf_write_u8() and another for() loop at all?
buf_write(buf, tmp_buf, len);
should do the job just fine...
So - getting close. Technological issues solved, now style issues
(which are much harder at times :-) ).
gert
--
"If was one thing all people took for granted, was conviction that if you
feed honest figures into a computer, honest figures come out. Never doubted
it myself till I met a computer with a sense of humor."
Robert A. Heinlein, The Moon is a Harsh Mistress
Gert Doering - Munich, Germany [email protected]
signature.asc
Description: PGP signature
_______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel
