Since --dns settings overrule DNS related --dhcp-options,
remove the latter when values were defined via --dns.
To stay as backward compatible as possible, we add foreign_options to
the script hook environment from the --dns values when a --up script
is defined. In that case the default --dns-updown is not run, even
when --dns values are present, to prevent double DNS configuration.
This way an existing --up script that deals with DNS can run, without
the immediate need to change after an openvpn upgrade and a server
pushing --dns options.
If you specify a custom --dns-updown, or force running the default
dns-updown that comes with openvpn, those compat env vars are not set
for --up scripts and the dns-updown command is run, even when there's
an --up script present.
Since Android uses the DNS values from tuntap_options, we always
override those with --dns stuff unconditionally. Also on Windows when
--ip-win32 is dynamic or adaptive, since DHCP relies on these as well.
Change-Id: I635c4018fb43b5976a39b6a90cb2e9cb2570cd6a
Signed-off-by: Heiko Hund <heiko@ist.eigentlich.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20250618124835.24737-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg31922.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
| ... | ... |
@@ -691,7 +691,8 @@ run_updown_runner(bool up, struct options *o, const struct tuntap *tt, struct dn |
| 691 | 691 |
static void |
| 692 | 692 |
run_up_down_command(bool up, struct options *o, const struct tuntap *tt, struct dns_updown_runner_info *updown_runner) |
| 693 | 693 |
{
|
| 694 |
- if (!o->dns_options.updown) |
|
| 694 |
+ struct dns_options *dns = &o->dns_options; |
|
| 695 |
+ if (!dns->updown || (o->up_script && !dns->user_set_updown)) |
|
| 695 | 696 |
{
|
| 696 | 697 |
return; |
| 697 | 698 |
} |
| ... | ... |
@@ -701,7 +702,7 @@ run_up_down_command(bool up, struct options *o, const struct tuntap *tt, struct |
| 701 | 701 |
if (!updown_runner->required) |
| 702 | 702 |
{
|
| 703 | 703 |
/* Run dns updown directly */ |
| 704 |
- status = do_run_up_down_command(up, NULL, &o->dns_options, tt); |
|
| 704 |
+ status = do_run_up_down_command(up, NULL, dns, tt); |
|
| 705 | 705 |
} |
| 706 | 706 |
else |
| 707 | 707 |
{
|
| ... | ... |
@@ -852,6 +853,14 @@ run_dns_up_down(bool up, struct options *o, const struct tuntap *tt, struct dns_ |
| 852 | 852 |
{
|
| 853 | 853 |
return; |
| 854 | 854 |
} |
| 855 |
+#ifdef _WIN32 |
|
| 856 |
+ /* Don't use iservice in DHCP mode */ |
|
| 857 |
+ struct tuntap_options *tto = &o->tuntap_options; |
|
| 858 |
+ if (tto->ip_win32_type == IPW32_SET_DHCP_MASQ || tto->ip_win32_type == IPW32_SET_ADAPTIVE) |
|
| 859 |
+ {
|
|
| 860 |
+ return; |
|
| 861 |
+ } |
|
| 862 |
+#endif |
|
| 855 | 863 |
|
| 856 | 864 |
/* Warn about adding servers of unsupported AF */ |
| 857 | 865 |
const struct dns_server *s = o->dns_options.servers; |
| ... | ... |
@@ -76,7 +76,28 @@ struct dns_updown_runner_info {
|
| 76 | 76 |
#endif |
| 77 | 77 |
}; |
| 78 | 78 |
|
| 79 |
+#ifndef N_DHCP_ADDR |
|
| 80 |
+#define N_DHCP_ADDR 4 |
|
| 81 |
+#endif |
|
| 82 |
+ |
|
| 83 |
+#ifndef N_SEARCH_LIST_LEN |
|
| 84 |
+#define N_SEARCH_LIST_LEN 10 |
|
| 85 |
+#endif |
|
| 86 |
+ |
|
| 87 |
+struct dhcp_options {
|
|
| 88 |
+ in_addr_t dns[N_DHCP_ADDR]; |
|
| 89 |
+ int dns_len; |
|
| 90 |
+ |
|
| 91 |
+ struct in6_addr dns6[N_DHCP_ADDR]; |
|
| 92 |
+ int dns6_len; |
|
| 93 |
+ |
|
| 94 |
+ const char *domain; |
|
| 95 |
+ const char *domain_search_list[N_SEARCH_LIST_LEN]; |
|
| 96 |
+ int domain_search_list_len; |
|
| 97 |
+}; |
|
| 98 |
+ |
|
| 79 | 99 |
struct dns_options {
|
| 100 |
+ struct dhcp_options from_dhcp; |
|
| 80 | 101 |
struct dns_domain *search_domains; |
| 81 | 102 |
struct dns_server *servers_prepull; |
| 82 | 103 |
struct dns_server *servers; |
| ... | ... |
@@ -1328,7 +1328,6 @@ show_tuntap_options(const struct tuntap_options *o) |
| 1328 | 1328 |
#endif /* ifndef ENABLE_SMALL */ |
| 1329 | 1329 |
#endif /* ifdef _WIN32 */ |
| 1330 | 1330 |
|
| 1331 |
-#if defined(_WIN32) || defined(TARGET_ANDROID) |
|
| 1332 | 1331 |
static void |
| 1333 | 1332 |
dhcp_option_dns6_parse(const char *parm, struct in6_addr *dns6_list, int *len, int msglevel) |
| 1334 | 1333 |
{
|
| ... | ... |
@@ -1371,150 +1370,6 @@ dhcp_option_address_parse(const char *name, const char *parm, in_addr_t *array, |
| 1371 | 1371 |
} |
| 1372 | 1372 |
} |
| 1373 | 1373 |
|
| 1374 |
-/* |
|
| 1375 |
- * If DNS options are set use these for TUN/TAP options as well. |
|
| 1376 |
- * Applies to DNS, DNS6 and DOMAIN-SEARCH. |
|
| 1377 |
- * Existing options will be discarded. |
|
| 1378 |
- */ |
|
| 1379 |
-static void |
|
| 1380 |
-tuntap_options_copy_dns(struct options *o) |
|
| 1381 |
-{
|
|
| 1382 |
- struct tuntap_options *tt = &o->tuntap_options; |
|
| 1383 |
- struct dns_options *dns = &o->dns_options; |
|
| 1384 |
- |
|
| 1385 |
- if (dns->search_domains) |
|
| 1386 |
- {
|
|
| 1387 |
- tt->domain_search_list_len = 0; |
|
| 1388 |
- const struct dns_domain *domain = dns->search_domains; |
|
| 1389 |
- while (domain && tt->domain_search_list_len < N_SEARCH_LIST_LEN) |
|
| 1390 |
- {
|
|
| 1391 |
- tt->domain_search_list[tt->domain_search_list_len++] = domain->name; |
|
| 1392 |
- domain = domain->next; |
|
| 1393 |
- } |
|
| 1394 |
- if (domain) |
|
| 1395 |
- {
|
|
| 1396 |
- msg(M_WARN, "WARNING: couldn't copy all --dns search-domains to --dhcp-option"); |
|
| 1397 |
- } |
|
| 1398 |
- tt->dhcp_options |= DHCP_OPTIONS_DHCP_REQUIRED; |
|
| 1399 |
- } |
|
| 1400 |
- |
|
| 1401 |
- if (dns->servers) |
|
| 1402 |
- {
|
|
| 1403 |
- tt->dns_len = 0; |
|
| 1404 |
- tt->dns6_len = 0; |
|
| 1405 |
- bool overflow = false; |
|
| 1406 |
- const struct dns_server *server = dns->servers; |
|
| 1407 |
- while (server) |
|
| 1408 |
- {
|
|
| 1409 |
- for (int i = 0; i < server->addr_count; ++i) |
|
| 1410 |
- {
|
|
| 1411 |
- if (server->addr[i].family == AF_INET) |
|
| 1412 |
- {
|
|
| 1413 |
- if (tt->dns_len >= N_DHCP_ADDR) |
|
| 1414 |
- {
|
|
| 1415 |
- overflow = true; |
|
| 1416 |
- continue; |
|
| 1417 |
- } |
|
| 1418 |
- tt->dns[tt->dns_len++] = ntohl(server->addr[i].in.a4.s_addr); |
|
| 1419 |
- } |
|
| 1420 |
- else |
|
| 1421 |
- {
|
|
| 1422 |
- if (tt->dns6_len >= N_DHCP_ADDR) |
|
| 1423 |
- {
|
|
| 1424 |
- overflow = true; |
|
| 1425 |
- continue; |
|
| 1426 |
- } |
|
| 1427 |
- tt->dns6[tt->dns6_len++] = server->addr[i].in.a6; |
|
| 1428 |
- } |
|
| 1429 |
- } |
|
| 1430 |
- server = server->next; |
|
| 1431 |
- } |
|
| 1432 |
- if (overflow) |
|
| 1433 |
- {
|
|
| 1434 |
- msg(M_WARN, "WARNING: couldn't copy all --dns server addresses to --dhcp-option"); |
|
| 1435 |
- } |
|
| 1436 |
- tt->dhcp_options |= DHCP_OPTIONS_DHCP_OPTIONAL; |
|
| 1437 |
- } |
|
| 1438 |
-} |
|
| 1439 |
-#else /* if defined(_WIN32) || defined(TARGET_ANDROID) */ |
|
| 1440 |
-static void |
|
| 1441 |
-foreign_options_copy_dns(struct options *o, struct env_set *es) |
|
| 1442 |
-{
|
|
| 1443 |
- const struct dns_domain *domain = o->dns_options.search_domains; |
|
| 1444 |
- const struct dns_server *server = o->dns_options.servers; |
|
| 1445 |
- if (!domain && !server) |
|
| 1446 |
- {
|
|
| 1447 |
- return; |
|
| 1448 |
- } |
|
| 1449 |
- |
|
| 1450 |
- /* reset the index since we're starting all over again */ |
|
| 1451 |
- int opt_max = o->foreign_option_index; |
|
| 1452 |
- o->foreign_option_index = 0; |
|
| 1453 |
- |
|
| 1454 |
- for (int i = 1; i <= opt_max; ++i) |
|
| 1455 |
- {
|
|
| 1456 |
- char name[32]; |
|
| 1457 |
- snprintf(name, sizeof(name), "foreign_option_%d", i); |
|
| 1458 |
- |
|
| 1459 |
- const char *env_str = env_set_get(es, name); |
|
| 1460 |
- const char *value = strchr(env_str, '=') + 1; |
|
| 1461 |
- if ((domain && strstr(value, "dhcp-option DOMAIN-SEARCH") == value) |
|
| 1462 |
- || (server && strstr(value, "dhcp-option DNS") == value)) |
|
| 1463 |
- {
|
|
| 1464 |
- setenv_del(es, name); |
|
| 1465 |
- } |
|
| 1466 |
- else |
|
| 1467 |
- {
|
|
| 1468 |
- setenv_foreign_option(o, &value, 1, es); |
|
| 1469 |
- } |
|
| 1470 |
- } |
|
| 1471 |
- |
|
| 1472 |
- struct gc_arena gc = gc_new(); |
|
| 1473 |
- |
|
| 1474 |
- while (server) |
|
| 1475 |
- {
|
|
| 1476 |
- for (size_t i = 0; i < server->addr_count; ++i) |
|
| 1477 |
- {
|
|
| 1478 |
- if (server->addr[i].family == AF_INET) |
|
| 1479 |
- {
|
|
| 1480 |
- const char *argv[] = {
|
|
| 1481 |
- "dhcp-option", |
|
| 1482 |
- "DNS", |
|
| 1483 |
- print_in_addr_t(server->addr[i].in.a4.s_addr, 0, &gc) |
|
| 1484 |
- }; |
|
| 1485 |
- setenv_foreign_option(o, argv, 3, es); |
|
| 1486 |
- } |
|
| 1487 |
- else |
|
| 1488 |
- {
|
|
| 1489 |
- const char *argv[] = {
|
|
| 1490 |
- "dhcp-option", |
|
| 1491 |
- "DNS6", |
|
| 1492 |
- print_in6_addr(server->addr[i].in.a6, 0, &gc) |
|
| 1493 |
- }; |
|
| 1494 |
- setenv_foreign_option(o, argv, 3, es); |
|
| 1495 |
- } |
|
| 1496 |
- } |
|
| 1497 |
- server = server->next; |
|
| 1498 |
- } |
|
| 1499 |
- while (domain) |
|
| 1500 |
- {
|
|
| 1501 |
- const char *argv[] = { "dhcp-option", "DOMAIN-SEARCH", domain->name };
|
|
| 1502 |
- setenv_foreign_option(o, argv, 3, es); |
|
| 1503 |
- domain = domain->next; |
|
| 1504 |
- } |
|
| 1505 |
- |
|
| 1506 |
- gc_free(&gc); |
|
| 1507 |
- |
|
| 1508 |
- /* remove old leftover entries */ |
|
| 1509 |
- while (o->foreign_option_index < opt_max) |
|
| 1510 |
- {
|
|
| 1511 |
- char name[32]; |
|
| 1512 |
- snprintf(name, sizeof(name), "foreign_option_%d", opt_max--); |
|
| 1513 |
- setenv_del(es, name); |
|
| 1514 |
- } |
|
| 1515 |
-} |
|
| 1516 |
-#endif /* if defined(_WIN32) || defined(TARGET_ANDROID) */ |
|
| 1517 |
- |
|
| 1518 | 1374 |
#ifndef ENABLE_SMALL |
| 1519 | 1375 |
static const char * |
| 1520 | 1376 |
print_vlan_accept(enum vlan_acceptable_frames mode) |
| ... | ... |
@@ -3603,6 +3458,260 @@ options_process_mutate_prf(struct options *o) |
| 3603 | 3603 |
} |
| 3604 | 3604 |
} |
| 3605 | 3605 |
|
| 3606 |
+#if defined(_WIN32) || defined(TARGET_ANDROID) |
|
| 3607 |
+/** |
|
| 3608 |
+ * @brief Postprocess DNS related settings |
|
| 3609 |
+ * |
|
| 3610 |
+ * Set TUN/TAP DNS options with values from either --dns |
|
| 3611 |
+ * or --dhcp-option. |
|
| 3612 |
+ * |
|
| 3613 |
+ * @param o pointer to the options struct |
|
| 3614 |
+ */ |
|
| 3615 |
+static void |
|
| 3616 |
+tuntap_options_postprocess_dns(struct options *o) |
|
| 3617 |
+{
|
|
| 3618 |
+ struct dns_options *dns = &o->dns_options; |
|
| 3619 |
+ struct tuntap_options *tt = &o->tuntap_options; |
|
| 3620 |
+ if (!dns->servers) |
|
| 3621 |
+ {
|
|
| 3622 |
+ /* Copy --dhcp-options to tuntap_options */ |
|
| 3623 |
+ struct dhcp_options *dhcp = &dns->from_dhcp; |
|
| 3624 |
+ assert(sizeof(dhcp->dns) == sizeof(tt->dns)); |
|
| 3625 |
+ assert(sizeof(dhcp->dns6) == sizeof(tt->dns6)); |
|
| 3626 |
+ assert(sizeof(dhcp->domain_search_list) == sizeof(tt->domain_search_list)); |
|
| 3627 |
+ |
|
| 3628 |
+ tt->domain = dhcp->domain; |
|
| 3629 |
+ tt->dns_len = dhcp->dns_len; |
|
| 3630 |
+ tt->dns6_len = dhcp->dns6_len; |
|
| 3631 |
+ |
|
| 3632 |
+ memcpy(tt->dns, dhcp->dns, sizeof(tt->dns)); |
|
| 3633 |
+ memcpy(tt->dns6, dhcp->dns6, sizeof(tt->dns6)); |
|
| 3634 |
+ |
|
| 3635 |
+ tt->domain_search_list_len = dhcp->domain_search_list_len; |
|
| 3636 |
+ for (size_t i = 0; i < SIZE(tt->domain_search_list); ++i) |
|
| 3637 |
+ {
|
|
| 3638 |
+ tt->domain_search_list[i] = dhcp->domain_search_list[i]; |
|
| 3639 |
+ } |
|
| 3640 |
+ |
|
| 3641 |
+ return; |
|
| 3642 |
+ } |
|
| 3643 |
+ |
|
| 3644 |
+#if defined(_WIN32) |
|
| 3645 |
+ if (tt->ip_win32_type != IPW32_SET_DHCP_MASQ && tt->ip_win32_type != IPW32_SET_ADAPTIVE) |
|
| 3646 |
+ {
|
|
| 3647 |
+ return; /* Not in DHCP mode */ |
|
| 3648 |
+ } |
|
| 3649 |
+#endif /* if defined(_WIN32) */ |
|
| 3650 |
+ |
|
| 3651 |
+ /* Copy --dns options to tuntap_options */ |
|
| 3652 |
+ const struct dns_domain *d = dns->search_domains; |
|
| 3653 |
+ while (d && tt->domain_search_list_len + 1 < N_SEARCH_LIST_LEN) |
|
| 3654 |
+ {
|
|
| 3655 |
+ tt->domain_search_list[tt->domain_search_list_len++] = d->name; |
|
| 3656 |
+ d = d->next; |
|
| 3657 |
+ } |
|
| 3658 |
+ if (d) |
|
| 3659 |
+ {
|
|
| 3660 |
+ msg(M_WARN, "WARNING: couldn't copy all --dns search-domains to TUN/TAP"); |
|
| 3661 |
+ } |
|
| 3662 |
+ |
|
| 3663 |
+ const struct dns_server *s = dns->servers; |
|
| 3664 |
+ while (s) |
|
| 3665 |
+ {
|
|
| 3666 |
+ bool non_standard_server_port = false; |
|
| 3667 |
+ for (int i = 0; i < s->addr_count; ++i) |
|
| 3668 |
+ {
|
|
| 3669 |
+ if (s->addr[i].port && s->addr[i].port != 53) |
|
| 3670 |
+ {
|
|
| 3671 |
+ non_standard_server_port = true; |
|
| 3672 |
+ break; |
|
| 3673 |
+ } |
|
| 3674 |
+ } |
|
| 3675 |
+ if ((s->transport && s->transport != DNS_TRANSPORT_PLAIN) |
|
| 3676 |
+ || (s->dnssec && s->dnssec != DNS_SECURITY_NO) |
|
| 3677 |
+ || non_standard_server_port) |
|
| 3678 |
+ {
|
|
| 3679 |
+ /* Skip servers requiring unsupported config to be set */ |
|
| 3680 |
+ s = s->next; |
|
| 3681 |
+ } |
|
| 3682 |
+ else |
|
| 3683 |
+ {
|
|
| 3684 |
+ bool overflow = false; |
|
| 3685 |
+ for (int i = 0; i < s->addr_count; ++i) |
|
| 3686 |
+ {
|
|
| 3687 |
+ if (s->addr[i].family == AF_INET && tt->dns_len + 1 < N_DHCP_ADDR) |
|
| 3688 |
+ {
|
|
| 3689 |
+ tt->dns[tt->dns_len++] = s->addr[i].in.a4.s_addr; |
|
| 3690 |
+ } |
|
| 3691 |
+ else if (tt->dns6_len + 1 < N_DHCP_ADDR) |
|
| 3692 |
+ {
|
|
| 3693 |
+ tt->dns6[tt->dns6_len++] = s->addr[i].in.a6; |
|
| 3694 |
+ } |
|
| 3695 |
+ else |
|
| 3696 |
+ {
|
|
| 3697 |
+ overflow = true; |
|
| 3698 |
+ } |
|
| 3699 |
+ } |
|
| 3700 |
+ if (overflow) |
|
| 3701 |
+ {
|
|
| 3702 |
+ msg(M_WARN, "WARNING: couldn't copy all --dns server addresses to TUN/TAP"); |
|
| 3703 |
+ } |
|
| 3704 |
+ return; |
|
| 3705 |
+ } |
|
| 3706 |
+ } |
|
| 3707 |
+} |
|
| 3708 |
+ |
|
| 3709 |
+#else /* if defined(_WIN32) || defined(TARGET_ANDROID) */ |
|
| 3710 |
+ |
|
| 3711 |
+/** |
|
| 3712 |
+ * @brief Postprocess DNS related settings |
|
| 3713 |
+ * |
|
| 3714 |
+ * Discard existing --dhcp-options from the env if needed and possibly |
|
| 3715 |
+ * replace them with values from --dns. If no --dns servers are set copy |
|
| 3716 |
+ * the --dhcp-option values over for --dns-updown runs. |
|
| 3717 |
+ * |
|
| 3718 |
+ * @param o pointer to the options struct |
|
| 3719 |
+ * @param es env set to modify potentially |
|
| 3720 |
+ */ |
|
| 3721 |
+static void |
|
| 3722 |
+dhcp_options_postprocess_dns(struct options *o, struct env_set *es) |
|
| 3723 |
+{
|
|
| 3724 |
+ struct gc_arena gc = gc_new(); |
|
| 3725 |
+ struct dns_options *dns = &o->dns_options; |
|
| 3726 |
+ |
|
| 3727 |
+ if (dns->servers || dns->user_set_updown) |
|
| 3728 |
+ {
|
|
| 3729 |
+ /* Clean up env from --dhcp-option DNS config */ |
|
| 3730 |
+ struct buffer name = alloc_buf_gc(OPTION_PARM_SIZE, &gc); |
|
| 3731 |
+ struct buffer value = alloc_buf_gc(OPTION_PARM_SIZE, &gc); |
|
| 3732 |
+ |
|
| 3733 |
+ const int fo_count = o->foreign_option_index; |
|
| 3734 |
+ o->foreign_option_index = 0; |
|
| 3735 |
+ |
|
| 3736 |
+ for (int i = 1; i <= fo_count; ++i) |
|
| 3737 |
+ {
|
|
| 3738 |
+ buf_clear(&name); |
|
| 3739 |
+ buf_printf(&name, "foreign_option_%d", i); |
|
| 3740 |
+ const char *env_str = env_set_get(es, BSTR(&name)); |
|
| 3741 |
+ const char *item_val = strchr(env_str, '=') + 1; |
|
| 3742 |
+ buf_clear(&value); |
|
| 3743 |
+ buf_printf(&value, "%s", item_val); |
|
| 3744 |
+ |
|
| 3745 |
+ /* Remove foreign option item from env set */ |
|
| 3746 |
+ env_set_del(es, BSTR(&name)); |
|
| 3747 |
+ |
|
| 3748 |
+ item_val = BSTR(&value); |
|
| 3749 |
+ if (strncmp(item_val, "dhcp-option ", 12) != 0 |
|
| 3750 |
+ || (strncmp(item_val + 12, "ADAPTER-DOMAIN-SUFFIX ", 22) != 0 |
|
| 3751 |
+ && strncmp(item_val + 12, "DOMAIN-SEARCH ", 14) != 0 |
|
| 3752 |
+ && strncmp(item_val + 12, "DOMAIN ", 7) != 0 |
|
| 3753 |
+ && strncmp(item_val + 12, "DNS6 ", 5) != 0 |
|
| 3754 |
+ && strncmp(item_val + 12, "DNS ", 4) != 0)) |
|
| 3755 |
+ {
|
|
| 3756 |
+ /* Re-set the item with potentially updated name */ |
|
| 3757 |
+ buf_clear(&name); |
|
| 3758 |
+ buf_printf(&name, "foreign_option_%d", ++o->foreign_option_index); |
|
| 3759 |
+ setenv_str(es, BSTR(&name), BSTR(&value)); |
|
| 3760 |
+ } |
|
| 3761 |
+ } |
|
| 3762 |
+ } |
|
| 3763 |
+ |
|
| 3764 |
+ if (!dns->servers) |
|
| 3765 |
+ {
|
|
| 3766 |
+ /* Copy --dhcp-options to dns_options */ |
|
| 3767 |
+ struct dhcp_options *dhcp = &dns->from_dhcp; |
|
| 3768 |
+ |
|
| 3769 |
+ if (dhcp->dns_len || dhcp->dns6_len) |
|
| 3770 |
+ {
|
|
| 3771 |
+ struct dns_domain **entry = &dns->search_domains; |
|
| 3772 |
+ ALLOC_OBJ_CLEAR_GC(*entry, struct dns_domain, &dns->gc); |
|
| 3773 |
+ struct dns_domain *new = *entry; |
|
| 3774 |
+ new->name = dhcp->domain; |
|
| 3775 |
+ entry = &new->next; |
|
| 3776 |
+ |
|
| 3777 |
+ for (size_t i = 0; i < dhcp->domain_search_list_len; ++i) |
|
| 3778 |
+ {
|
|
| 3779 |
+ ALLOC_OBJ_CLEAR_GC(*entry, struct dns_domain, &dns->gc); |
|
| 3780 |
+ struct dns_domain *new = *entry; |
|
| 3781 |
+ new->name = dhcp->domain_search_list[i]; |
|
| 3782 |
+ entry = &new->next; |
|
| 3783 |
+ } |
|
| 3784 |
+ |
|
| 3785 |
+ struct dns_server *server = dns_server_get(&dns->servers, 0, &dns->gc); |
|
| 3786 |
+ const size_t max_addrs = SIZE(server->addr); |
|
| 3787 |
+ for (size_t i = 0; i < dhcp->dns_len && server->addr_count < max_addrs; ++i) |
|
| 3788 |
+ {
|
|
| 3789 |
+ server->addr[server->addr_count].in.a4.s_addr = htonl(dhcp->dns[i]); |
|
| 3790 |
+ server->addr[server->addr_count].family = AF_INET; |
|
| 3791 |
+ server->addr_count += 1; |
|
| 3792 |
+ } |
|
| 3793 |
+ for (size_t i = 0; i < dhcp->dns6_len && server->addr_count < max_addrs; ++i) |
|
| 3794 |
+ {
|
|
| 3795 |
+ server->addr[server->addr_count].in.a6 = dhcp->dns6[i]; |
|
| 3796 |
+ server->addr[server->addr_count].family = AF_INET6; |
|
| 3797 |
+ server->addr_count += 1; |
|
| 3798 |
+ } |
|
| 3799 |
+ } |
|
| 3800 |
+ } |
|
| 3801 |
+ else if (o->up_script && !dns->user_set_updown) |
|
| 3802 |
+ {
|
|
| 3803 |
+ /* Set foreign option env vars from --dns config */ |
|
| 3804 |
+ const char *p[] = { "dhcp-option", NULL, NULL };
|
|
| 3805 |
+ size_t p_len = sizeof(p) / sizeof(p[0]); |
|
| 3806 |
+ |
|
| 3807 |
+ p[1] = "DOMAIN"; |
|
| 3808 |
+ const struct dns_domain *d = dns->search_domains; |
|
| 3809 |
+ while (d) |
|
| 3810 |
+ {
|
|
| 3811 |
+ p[2] = d->name; |
|
| 3812 |
+ setenv_foreign_option(o, (const char **)p, p_len, es); |
|
| 3813 |
+ d = d->next; |
|
| 3814 |
+ } |
|
| 3815 |
+ |
|
| 3816 |
+ const struct dns_server *s = dns->servers; |
|
| 3817 |
+ while (s) |
|
| 3818 |
+ {
|
|
| 3819 |
+ bool non_standard_server_port = false; |
|
| 3820 |
+ for (int i = 0; i < s->addr_count; ++i) |
|
| 3821 |
+ {
|
|
| 3822 |
+ if (s->addr[i].port && s->addr[i].port != 53) |
|
| 3823 |
+ {
|
|
| 3824 |
+ non_standard_server_port = true; |
|
| 3825 |
+ break; |
|
| 3826 |
+ } |
|
| 3827 |
+ } |
|
| 3828 |
+ if ((s->transport && s->transport != DNS_TRANSPORT_PLAIN) |
|
| 3829 |
+ || (s->dnssec && s->dnssec != DNS_SECURITY_NO) |
|
| 3830 |
+ || non_standard_server_port) |
|
| 3831 |
+ {
|
|
| 3832 |
+ /* Skip servers requiring unsupported config to be set */ |
|
| 3833 |
+ s = s->next; |
|
| 3834 |
+ } |
|
| 3835 |
+ else |
|
| 3836 |
+ {
|
|
| 3837 |
+ for (int i = 0; i < s->addr_count; ++i) |
|
| 3838 |
+ {
|
|
| 3839 |
+ if (s->addr[i].family == AF_INET) |
|
| 3840 |
+ {
|
|
| 3841 |
+ p[1] = "DNS"; |
|
| 3842 |
+ p[2] = print_in_addr_t(s->addr[i].in.a4.s_addr, IA_NET_ORDER, &gc); |
|
| 3843 |
+ } |
|
| 3844 |
+ else |
|
| 3845 |
+ {
|
|
| 3846 |
+ p[1] = "DNS6"; |
|
| 3847 |
+ p[2] = print_in6_addr(s->addr[i].in.a6, 0, &gc); |
|
| 3848 |
+ } |
|
| 3849 |
+ setenv_foreign_option(o, (const char **)p, p_len, es); |
|
| 3850 |
+ } |
|
| 3851 |
+ break; |
|
| 3852 |
+ } |
|
| 3853 |
+ } |
|
| 3854 |
+ } |
|
| 3855 |
+ |
|
| 3856 |
+ gc_free(&gc); |
|
| 3857 |
+} |
|
| 3858 |
+#endif /* if defined(_WIN32) || defined(TARGET_ANDROID) */ |
|
| 3859 |
+ |
|
| 3606 | 3860 |
static void |
| 3607 | 3861 |
options_postprocess_mutate(struct options *o, struct env_set *es) |
| 3608 | 3862 |
{
|
| ... | ... |
@@ -3786,9 +3895,9 @@ options_postprocess_mutate(struct options *o, struct env_set *es) |
| 3786 | 3786 |
else |
| 3787 | 3787 |
{
|
| 3788 | 3788 |
#if defined(_WIN32) || defined(TARGET_ANDROID) |
| 3789 |
- tuntap_options_copy_dns(o); |
|
| 3789 |
+ tuntap_options_postprocess_dns(o); |
|
| 3790 | 3790 |
#else |
| 3791 |
- foreign_options_copy_dns(o, es); |
|
| 3791 |
+ dhcp_options_postprocess_dns(o, es); |
|
| 3792 | 3792 |
#endif |
| 3793 | 3793 |
} |
| 3794 | 3794 |
if (o->auth_token_generate && !o->auth_token_renewal) |
| ... | ... |
@@ -4171,9 +4280,9 @@ options_postprocess_pull(struct options *o, struct env_set *es) |
| 4171 | 4171 |
{
|
| 4172 | 4172 |
dns_options_postprocess_pull(&o->dns_options); |
| 4173 | 4173 |
#if defined(_WIN32) || defined(TARGET_ANDROID) |
| 4174 |
- tuntap_options_copy_dns(o); |
|
| 4174 |
+ tuntap_options_postprocess_dns(o); |
|
| 4175 | 4175 |
#else |
| 4176 |
- foreign_options_copy_dns(o, es); |
|
| 4176 |
+ dhcp_options_postprocess_dns(o, es); |
|
| 4177 | 4177 |
#endif |
| 4178 | 4178 |
} |
| 4179 | 4179 |
return success; |
| ... | ... |
@@ -8162,18 +8271,43 @@ add_option(struct options *options, |
| 8162 | 8162 |
goto err; |
| 8163 | 8163 |
} |
| 8164 | 8164 |
} |
| 8165 |
-#if defined(_WIN32) || defined(TARGET_ANDROID) |
|
| 8166 | 8165 |
else if (streq(p[0], "dhcp-option") && p[1]) |
| 8167 | 8166 |
{
|
| 8167 |
+ struct dhcp_options *dhcp = &options->dns_options.from_dhcp; |
|
| 8168 |
+#if defined(_WIN32) || defined(TARGET_ANDROID) |
|
| 8168 | 8169 |
struct tuntap_options *o = &options->tuntap_options; |
| 8170 |
+#endif |
|
| 8169 | 8171 |
VERIFY_PERMISSION(OPT_P_DHCPDNS); |
| 8170 | 8172 |
|
| 8171 |
- if ((streq(p[1], "DOMAIN") || streq(p[1], "ADAPTER_DOMAIN_SUFFIX")) |
|
| 8172 |
- && p[2] && !p[3]) |
|
| 8173 |
+ if ((streq(p[1], "DOMAIN") || streq(p[1], "ADAPTER_DOMAIN_SUFFIX")) && p[2] && !p[3]) |
|
| 8173 | 8174 |
{
|
| 8174 |
- o->domain = p[2]; |
|
| 8175 |
- o->dhcp_options |= DHCP_OPTIONS_DHCP_OPTIONAL; |
|
| 8175 |
+ dhcp->domain = p[2]; |
|
| 8176 |
+ } |
|
| 8177 |
+ else if (streq(p[1], "DOMAIN-SEARCH") && p[2] && !p[3]) |
|
| 8178 |
+ {
|
|
| 8179 |
+ if (dhcp->domain_search_list_len < N_SEARCH_LIST_LEN) |
|
| 8180 |
+ {
|
|
| 8181 |
+ dhcp->domain_search_list[dhcp->domain_search_list_len++] = p[2]; |
|
| 8182 |
+ } |
|
| 8183 |
+ else |
|
| 8184 |
+ {
|
|
| 8185 |
+ msg(msglevel, "--dhcp-option %s: maximum of %d search entries can be specified", |
|
| 8186 |
+ p[1], N_SEARCH_LIST_LEN); |
|
| 8187 |
+ } |
|
| 8188 |
+ } |
|
| 8189 |
+ else if ((streq(p[1], "DNS") || streq(p[1], "DNS6")) && p[2] && !p[3] |
|
| 8190 |
+ && (!strstr(p[2], ":") || ipv6_addr_safe(p[2]))) |
|
| 8191 |
+ {
|
|
| 8192 |
+ if (strstr(p[2], ":")) |
|
| 8193 |
+ {
|
|
| 8194 |
+ dhcp_option_dns6_parse(p[2], dhcp->dns6, &dhcp->dns6_len, msglevel); |
|
| 8195 |
+ } |
|
| 8196 |
+ else |
|
| 8197 |
+ {
|
|
| 8198 |
+ dhcp_option_address_parse("DNS", p[2], dhcp->dns, &dhcp->dns_len, msglevel);
|
|
| 8199 |
+ } |
|
| 8176 | 8200 |
} |
| 8201 |
+#if defined(_WIN32) || defined(TARGET_ANDROID) |
|
| 8177 | 8202 |
else if (streq(p[1], "NBS") && p[2] && !p[3]) |
| 8178 | 8203 |
{
|
| 8179 | 8204 |
o->netbios_scope = p[2]; |
| ... | ... |
@@ -8191,23 +8325,9 @@ add_option(struct options *options, |
| 8191 | 8191 |
o->netbios_node_type = t; |
| 8192 | 8192 |
o->dhcp_options |= DHCP_OPTIONS_DHCP_REQUIRED; |
| 8193 | 8193 |
} |
| 8194 |
- else if ((streq(p[1], "DNS") || streq(p[1], "DNS6")) && p[2] && !p[3] |
|
| 8195 |
- && (!strstr(p[2], ":") || ipv6_addr_safe(p[2]))) |
|
| 8196 |
- {
|
|
| 8197 |
- if (strstr(p[2], ":")) |
|
| 8198 |
- {
|
|
| 8199 |
- dhcp_option_dns6_parse(p[2], o->dns6, &o->dns6_len, msglevel); |
|
| 8200 |
- } |
|
| 8201 |
- else |
|
| 8202 |
- {
|
|
| 8203 |
- dhcp_option_address_parse("DNS", p[2], o->dns, &o->dns_len, msglevel);
|
|
| 8204 |
- o->dhcp_options |= DHCP_OPTIONS_DHCP_OPTIONAL; |
|
| 8205 |
- } |
|
| 8206 |
- } |
|
| 8207 | 8194 |
else if (streq(p[1], "WINS") && p[2] && !p[3]) |
| 8208 | 8195 |
{
|
| 8209 | 8196 |
dhcp_option_address_parse("WINS", p[2], o->wins, &o->wins_len, msglevel);
|
| 8210 |
- o->dhcp_options |= DHCP_OPTIONS_DHCP_OPTIONAL; |
|
| 8211 | 8197 |
} |
| 8212 | 8198 |
else if (streq(p[1], "NTP") && p[2] && !p[3]) |
| 8213 | 8199 |
{
|
| ... | ... |
@@ -8219,19 +8339,6 @@ add_option(struct options *options, |
| 8219 | 8219 |
dhcp_option_address_parse("NBDD", p[2], o->nbdd, &o->nbdd_len, msglevel);
|
| 8220 | 8220 |
o->dhcp_options |= DHCP_OPTIONS_DHCP_REQUIRED; |
| 8221 | 8221 |
} |
| 8222 |
- else if (streq(p[1], "DOMAIN-SEARCH") && p[2] && !p[3]) |
|
| 8223 |
- {
|
|
| 8224 |
- if (o->domain_search_list_len < N_SEARCH_LIST_LEN) |
|
| 8225 |
- {
|
|
| 8226 |
- o->domain_search_list[o->domain_search_list_len++] = p[2]; |
|
| 8227 |
- } |
|
| 8228 |
- else |
|
| 8229 |
- {
|
|
| 8230 |
- msg(msglevel, "--dhcp-option %s: maximum of %d search entries can be specified", |
|
| 8231 |
- p[1], N_SEARCH_LIST_LEN); |
|
| 8232 |
- } |
|
| 8233 |
- o->dhcp_options |= DHCP_OPTIONS_DHCP_OPTIONAL; |
|
| 8234 |
- } |
|
| 8235 | 8222 |
else if (streq(p[1], "DISABLE-NBT") && !p[2]) |
| 8236 | 8223 |
{
|
| 8237 | 8224 |
o->disable_nbt = 1; |
| ... | ... |
@@ -8249,8 +8356,10 @@ add_option(struct options *options, |
| 8249 | 8249 |
msg(msglevel, "--dhcp-option: unknown option type '%s' or missing or unknown parameter", p[1]); |
| 8250 | 8250 |
goto err; |
| 8251 | 8251 |
} |
| 8252 |
- } |
|
| 8252 |
+#else /* if defined(_WIN32) || defined(TARGET_ANDROID) */ |
|
| 8253 |
+ setenv_foreign_option(options, (const char **)p, 3, es); |
|
| 8253 | 8254 |
#endif /* if defined(_WIN32) || defined(TARGET_ANDROID) */ |
| 8255 |
+ } |
|
| 8254 | 8256 |
#ifdef _WIN32 |
| 8255 | 8257 |
else if (streq(p[0], "show-adapters") && !p[1]) |
| 8256 | 8258 |
{
|