Compare commits
6 Commits
b8bc23d241
...
4c39482e38
Author | SHA1 | Date |
---|---|---|
Raul Cheleguini | 4c39482e38 | |
Yu Watanabe | 5261c521e3 | |
Franck Bui | 514d9e1665 | |
Lennart Poettering | b480a4c15e | |
Lennart Poettering | af3baf174a | |
Raul Cheleguini | 9173c11fe4 |
25
TODO
25
TODO
|
@ -129,6 +129,10 @@ Deprecations and removals:
|
|||
|
||||
Features:
|
||||
|
||||
* format-table: introduce new cell type for strings with ansi sequences in
|
||||
them. display them in regular output mode (via strip_tab_ansi()), but
|
||||
suppress them in json mode.
|
||||
|
||||
* machined: when registering a machine, also take a relative cgroup path,
|
||||
relative to the machine's unit. This is useful when registering unpriv
|
||||
machines, as they might sit down the cgroup tree, below a cgroup delegation
|
||||
|
@ -217,12 +221,8 @@ Features:
|
|||
services where mount propagation from the root fs is off, an still have
|
||||
confext/sysext propagated in.
|
||||
|
||||
* support F_DUDFD_QUERY for comparing fds in same_fd (requires kernel 6.10)
|
||||
|
||||
* generic interface for varlink for setting log level and stuff that all our daemons can implement
|
||||
|
||||
* use pty ioctl to get peer wherever possible (TIOCGPTPEER)
|
||||
|
||||
* maybe teach repart.d/ dropins a new setting MakeMountNodes= or so, which is
|
||||
just like MakeDirectories=, but uses an access mode of 0000 and sets the +i
|
||||
chattr bit. This is useful as protection against early uses of /var/ or /tmp/
|
||||
|
@ -253,8 +253,6 @@ Features:
|
|||
* initrd: when transitioning from initrd to host, validate that
|
||||
/lib/modules/`uname -r` exists, refuse otherwise
|
||||
|
||||
* tmpfiles: add "owning" flag for lines that limits effect of --purge
|
||||
|
||||
* signed bpf loading: to address need for signature verification for bpf
|
||||
programs when they are loaded, and given the bpf folks don't think this is
|
||||
realistic in kernel space, maybe add small daemon that facilitates this
|
||||
|
@ -458,9 +456,6 @@ Features:
|
|||
* introduce mntid_t, and make it 64bit, as apparently the kernel switched to
|
||||
64bit mount ids
|
||||
|
||||
* use udev rule networkd ownership property to take ownership of network
|
||||
interfaces nspawn creates
|
||||
|
||||
* mountfsd/nsresourced
|
||||
- userdb: maybe allow callers to map one uid to their own uid
|
||||
- bpflsm: allow writes if resulting UID on disk would be userns' owner UID
|
||||
|
@ -647,6 +642,7 @@ Features:
|
|||
- openpt_allocate_in_namespace()
|
||||
- unit_attach_pid_to_cgroup_via_bus()
|
||||
- cg_attach() – requires new kernel feature
|
||||
- journald's process cache
|
||||
|
||||
* ddi must be listed as block device fstype
|
||||
|
||||
|
@ -1470,9 +1466,6 @@ Features:
|
|||
|
||||
* in sd-id128: also parse UUIDs in RFC4122 URN syntax (i.e. chop off urn:uuid: prefix)
|
||||
|
||||
* DynamicUser= + StateDirectory= → use uid mapping mounts, too, in order to
|
||||
make dirs appear under right UID.
|
||||
|
||||
* systemd-sysext: optionally, run it in initrd already, before transitioning
|
||||
into host, to open up possibility for services shipped like that.
|
||||
|
||||
|
@ -1644,14 +1637,6 @@ Features:
|
|||
|
||||
* maybe add kernel cmdline params: to force random seed crediting
|
||||
|
||||
* introduce a new per-process uuid, similar to the boot id, the machine id, the
|
||||
invocation id, that is derived from process creds, specifically a hashed
|
||||
combination of AT_RANDOM + getpid() + the starttime from
|
||||
/proc/self/status. Then add these ids implicitly when logging. Deriving this
|
||||
uuid from these three things has the benefit that it can be derived easily
|
||||
from /proc/$PID/ in a stable, and unique way that changes on both fork() and
|
||||
exec().
|
||||
|
||||
* let's not GC a unit while its ratelimits are still pending
|
||||
|
||||
* when killing due to service watchdog timeout maybe detect whether target
|
||||
|
|
24
meson.build
24
meson.build
|
@ -1579,6 +1579,29 @@ conf.set('DEFAULT_DNS_OVER_TLS_MODE',
|
|||
'DNS_OVER_TLS_' + default_dns_over_tls.underscorify().to_upper())
|
||||
conf.set_quoted('DEFAULT_DNS_OVER_TLS_MODE_STR', default_dns_over_tls)
|
||||
|
||||
dns_over_https = get_option('dns-over-https')
|
||||
if dns_over_https != 'false'
|
||||
have = true
|
||||
if conf.get('HAVE_LIBCURL') == 0
|
||||
message('DNS-over-HTTPS support depends on libcurl, but dependencies are not available')
|
||||
have = false
|
||||
endif
|
||||
if conf.get('HAVE_OPENSSL') == 0
|
||||
message('openssl required, but not available')
|
||||
have = false
|
||||
endif
|
||||
endif
|
||||
conf.set10('ENABLE_DNS_OVER_HTTPS', have)
|
||||
|
||||
default_dns_over_https = get_option('default-dns-over-https')
|
||||
if default_dns_over_https != 'no' and conf.get('ENABLE_DNS_OVER_HTTPS') == 0
|
||||
message('default-dns-over-https cannot be enabled. Setting default-dns-over-https to no.')
|
||||
default_dns_over_https = 'no'
|
||||
endif
|
||||
conf.set('DEFAULT_DNS_OVER_HTTPS_MODE',
|
||||
'DNS_OVER_HTTPS_' + default_dns_over_https.underscorify().to_upper())
|
||||
conf.set_quoted('DEFAULT_DNS_OVER_HTTPS_MODE_STR', default_dns_over_https)
|
||||
|
||||
default_mdns = get_option('default-mdns')
|
||||
conf.set('DEFAULT_MDNS_MODE',
|
||||
'RESOLVE_SUPPORT_' + default_mdns.to_upper())
|
||||
|
@ -2991,6 +3014,7 @@ summary({
|
|||
'default compression method' : compression,
|
||||
'default DNSSEC mode' : default_dnssec,
|
||||
'default DNS-over-TLS mode' : default_dns_over_tls,
|
||||
'default DNS-over-HTTPS mode' : default_dns_over_https,
|
||||
'default mDNS mode' : default_mdns,
|
||||
'default LLMNR mode' : default_llmnr,
|
||||
'default DNS servers' : dns_servers.split(' '),
|
||||
|
|
|
@ -353,6 +353,10 @@ option('default-dns-over-tls', type : 'combo',
|
|||
description : 'default DNS-over-TLS mode',
|
||||
choices : ['yes', 'opportunistic', 'no'],
|
||||
value : 'no')
|
||||
option('default-dns-over-https', type : 'combo',
|
||||
description : 'default DNS-over-HTTPS mode',
|
||||
choices : ['yes', 'no'],
|
||||
value : 'no')
|
||||
option('default-mdns', type : 'combo',
|
||||
choices : ['yes', 'resolve', 'no'],
|
||||
description : 'default MulticastDNS mode',
|
||||
|
@ -363,6 +367,8 @@ option('default-llmnr', type : 'combo',
|
|||
value : 'yes')
|
||||
option('dns-over-tls', type : 'combo', choices : ['auto', 'gnutls', 'openssl', 'true', 'false'],
|
||||
description : 'DNS-over-TLS support')
|
||||
option('dns-over-https', type : 'combo', choices : ['true', 'false'],
|
||||
description : 'DNS-over-HTTPS support')
|
||||
option('dns-servers', type : 'string',
|
||||
description : 'space-separated list of default DNS servers',
|
||||
value : '1.1.1.1#cloudflare-dns.com 8.8.8.8#dns.google 1.0.0.1#cloudflare-dns.com 8.8.4.4#dns.google 2606:4700:4700::1111#cloudflare-dns.com 2001:4860:4860::8888#dns.google 2606:4700:4700::1001#cloudflare-dns.com 2001:4860:4860::8844#dns.google')
|
||||
|
|
|
@ -1131,6 +1131,8 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
|
|||
* • If O_CREAT is used with XO_LABEL, any created file will be immediately relabelled.
|
||||
*
|
||||
* • If the path is specified NULL or empty, behaves like fd_reopen().
|
||||
*
|
||||
* • If XO_NOCOW is specified will turn on the NOCOW btrfs flag on the file, if available.
|
||||
*/
|
||||
|
||||
if (isempty(path)) {
|
||||
|
|
|
@ -14,7 +14,6 @@ systemd_pull_sources = files(
|
|||
'pull-tar.c',
|
||||
'pull-job.c',
|
||||
'pull-common.c',
|
||||
'curl-util.c',
|
||||
)
|
||||
|
||||
systemd_import_sources = files(
|
||||
|
|
|
@ -117,6 +117,10 @@ if conf.get('ENABLE_DNS_OVER_TLS') == 1
|
|||
endif
|
||||
endif
|
||||
|
||||
if conf.get('ENABLE_DNS_OVER_HTTPS') == 1
|
||||
systemd_resolved_dependencies += libcurl
|
||||
endif
|
||||
|
||||
link_with = [
|
||||
libshared,
|
||||
libsystemd_resolve_core,
|
||||
|
|
|
@ -422,10 +422,17 @@ DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
|
|||
|
||||
/* Determine the best feature level we care about. If DNSSEC mode is off there's no point in using anything
|
||||
* better than EDNS0, hence don't even try. */
|
||||
if (dns_server_get_dnssec_mode(s) != DNSSEC_NO)
|
||||
if (dns_server_get_dnssec_mode(s) != DNSSEC_NO) {
|
||||
best = dns_server_get_dns_over_tls_mode(s) == DNS_OVER_TLS_NO ?
|
||||
DNS_SERVER_FEATURE_LEVEL_DO :
|
||||
DNS_SERVER_FEATURE_LEVEL_TLS_DO;
|
||||
/* TODO: Add HTTPS_PLAIN_DO too? */
|
||||
#if ENABLE_DNS_OVER_HTTPS
|
||||
best = dns_server_get_dns_over_https_mode(s) == DNS_OVER_HTTPS_NO ?
|
||||
DNS_SERVER_FEATURE_LEVEL_DO :
|
||||
DNS_SERVER_FEATURE_LEVEL_HTTPS_PLAIN;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
best = dns_server_get_dns_over_tls_mode(s) == DNS_OVER_TLS_NO ?
|
||||
DNS_SERVER_FEATURE_LEVEL_EDNS0 :
|
||||
|
@ -493,7 +500,8 @@ DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
|
|||
} else if (s->packet_bad_opt &&
|
||||
DNS_SERVER_FEATURE_LEVEL_IS_EDNS0(s->possible_feature_level) &&
|
||||
dns_server_get_dnssec_mode(s) != DNSSEC_YES &&
|
||||
dns_server_get_dns_over_tls_mode(s) != DNS_OVER_TLS_YES) {
|
||||
dns_server_get_dns_over_tls_mode(s) != DNS_OVER_TLS_YES &&
|
||||
dns_server_get_dns_over_https_mode(s) != DNS_OVER_HTTPS_YES) {
|
||||
|
||||
/* A reply to one of our EDNS0 queries didn't carry a valid OPT RR, then downgrade to
|
||||
* below EDNS0 levels. After all, some servers generate different responses with and
|
||||
|
@ -962,6 +970,12 @@ DnsOverTlsMode dns_server_get_dns_over_tls_mode(DnsServer *s) {
|
|||
return manager_get_dns_over_tls_mode(s->manager);
|
||||
}
|
||||
|
||||
DnsOverHttpsMode dns_server_get_dns_over_https_mode(DnsServer *s) {
|
||||
assert(s);
|
||||
|
||||
return manager_get_dns_over_https_mode(s->manager);
|
||||
}
|
||||
|
||||
void dns_server_flush_cache(DnsServer *s) {
|
||||
DnsServer *current;
|
||||
DnsScope *scope;
|
||||
|
@ -1095,12 +1109,13 @@ static const char* const dns_server_type_table[_DNS_SERVER_TYPE_MAX] = {
|
|||
DEFINE_STRING_TABLE_LOOKUP(dns_server_type, DnsServerType);
|
||||
|
||||
static const char* const dns_server_feature_level_table[_DNS_SERVER_FEATURE_LEVEL_MAX] = {
|
||||
[DNS_SERVER_FEATURE_LEVEL_TCP] = "TCP",
|
||||
[DNS_SERVER_FEATURE_LEVEL_UDP] = "UDP",
|
||||
[DNS_SERVER_FEATURE_LEVEL_EDNS0] = "UDP+EDNS0",
|
||||
[DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN] = "TLS+EDNS0",
|
||||
[DNS_SERVER_FEATURE_LEVEL_DO] = "UDP+EDNS0+DO",
|
||||
[DNS_SERVER_FEATURE_LEVEL_TLS_DO] = "TLS+EDNS0+DO",
|
||||
[DNS_SERVER_FEATURE_LEVEL_TCP] = "TCP",
|
||||
[DNS_SERVER_FEATURE_LEVEL_UDP] = "UDP",
|
||||
[DNS_SERVER_FEATURE_LEVEL_EDNS0] = "UDP+EDNS0",
|
||||
[DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN] = "TLS+EDNS0",
|
||||
[DNS_SERVER_FEATURE_LEVEL_HTTPS_PLAIN] = "HTTPS+EDNS0",
|
||||
[DNS_SERVER_FEATURE_LEVEL_DO] = "UDP+EDNS0+DO",
|
||||
[DNS_SERVER_FEATURE_LEVEL_TLS_DO] = "TLS+EDNS0+DO",
|
||||
};
|
||||
DEFINE_STRING_TABLE_LOOKUP(dns_server_feature_level, DnsServerFeatureLevel);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ typedef enum DnsServerFeatureLevel {
|
|||
DNS_SERVER_FEATURE_LEVEL_UDP,
|
||||
DNS_SERVER_FEATURE_LEVEL_EDNS0,
|
||||
DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN,
|
||||
DNS_SERVER_FEATURE_LEVEL_HTTPS_PLAIN,
|
||||
DNS_SERVER_FEATURE_LEVEL_DO,
|
||||
DNS_SERVER_FEATURE_LEVEL_TLS_DO,
|
||||
_DNS_SERVER_FEATURE_LEVEL_MAX,
|
||||
|
@ -46,6 +47,7 @@ typedef enum DnsServerFeatureLevel {
|
|||
#define DNS_SERVER_FEATURE_LEVEL_IS_EDNS0(x) ((x) >= DNS_SERVER_FEATURE_LEVEL_EDNS0)
|
||||
#define DNS_SERVER_FEATURE_LEVEL_IS_TLS(x) IN_SET(x, DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN, DNS_SERVER_FEATURE_LEVEL_TLS_DO)
|
||||
#define DNS_SERVER_FEATURE_LEVEL_IS_DNSSEC(x) ((x) >= DNS_SERVER_FEATURE_LEVEL_DO)
|
||||
#define DNS_SERVER_FEATURE_LEVEL_IS_HTTPS(x) ((x) == DNS_SERVER_FEATURE_LEVEL_HTTPS_PLAIN)
|
||||
#define DNS_SERVER_FEATURE_LEVEL_IS_UDP(x) IN_SET(x, DNS_SERVER_FEATURE_LEVEL_UDP, DNS_SERVER_FEATURE_LEVEL_EDNS0, DNS_SERVER_FEATURE_LEVEL_DO)
|
||||
|
||||
const char* dns_server_feature_level_to_string(DnsServerFeatureLevel i) _const_;
|
||||
|
@ -164,6 +166,7 @@ void manager_next_dns_server(Manager *m, DnsServer *if_current);
|
|||
|
||||
DnssecMode dns_server_get_dnssec_mode(DnsServer *s);
|
||||
DnsOverTlsMode dns_server_get_dns_over_tls_mode(DnsServer *s);
|
||||
DnsOverHttpsMode dns_server_get_dns_over_https_mode(DnsServer *s);
|
||||
|
||||
size_t dns_server_get_mtu(DnsServer *s);
|
||||
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
|
||||
#include "af-list.h"
|
||||
#include "alloc-util.h"
|
||||
|
||||
#include "dns-domain.h"
|
||||
#include "errno-list.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "glyph-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "random-util.h"
|
||||
#include "resolved-dns-cache.h"
|
||||
#include "resolved-dns-transaction.h"
|
||||
|
@ -16,6 +18,10 @@
|
|||
#include "resolved-llmnr.h"
|
||||
#include "string-table.h"
|
||||
|
||||
#if ENABLE_DNS_OVER_HTTPS
|
||||
#include "curl-util.h"
|
||||
#endif
|
||||
|
||||
#define TRANSACTIONS_MAX 4096
|
||||
#define TRANSACTION_TCP_TIMEOUT_USEC (10U*USEC_PER_SEC)
|
||||
|
||||
|
@ -682,7 +688,13 @@ static uint16_t dns_transaction_port(DnsTransaction *t) {
|
|||
if (t->server->port > 0)
|
||||
return t->server->port;
|
||||
|
||||
return DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level) ? 853 : 53;
|
||||
if (DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level))
|
||||
return 853;
|
||||
|
||||
if (DNS_SERVER_FEATURE_LEVEL_IS_HTTPS(t->current_feature_level))
|
||||
return 443;
|
||||
|
||||
return 53;
|
||||
}
|
||||
|
||||
static int dns_transaction_emit_tcp(DnsTransaction *t) {
|
||||
|
@ -1518,6 +1530,9 @@ static int dns_transaction_emit_udp(DnsTransaction *t) {
|
|||
if (t->current_feature_level < DNS_SERVER_FEATURE_LEVEL_UDP || DNS_SERVER_FEATURE_LEVEL_IS_TLS(t->current_feature_level))
|
||||
return -EAGAIN; /* Sorry, can't do UDP, try TCP! */
|
||||
|
||||
if (DNS_SERVER_FEATURE_LEVEL_IS_HTTPS(t->current_feature_level))
|
||||
return -EAGAIN; /* Direct request logic to HTTPS */
|
||||
|
||||
if (!t->bypass && !dns_server_dnssec_supported(t->server) && dns_type_is_dnssec(dns_transaction_key(t)->type))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
|
@ -1984,6 +1999,223 @@ static int mdns_make_dummy_packet(DnsTransaction *t, DnsPacket **ret_packet, Set
|
|||
return add_known_answers;
|
||||
}
|
||||
|
||||
#if ENABLE_DNS_OVER_HTTPS
|
||||
static size_t dns_transaction_curl_header_callback(void *contents, size_t size, size_t nmemb, void *userdata) {
|
||||
_cleanup_free_ char *content_header = NULL;
|
||||
DnsTransaction *t = ASSERT_PTR(userdata);
|
||||
size_t sz = size * nmemb;
|
||||
CURLcode code;
|
||||
long status;
|
||||
int r;
|
||||
|
||||
assert(contents);
|
||||
|
||||
code = curl_easy_getinfo(t->curl, CURLINFO_RESPONSE_CODE, &status);
|
||||
if (code != CURLE_OK)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve response code: %s", curl_easy_strerror(code));
|
||||
|
||||
if (status >= 200 && status <= 299) {
|
||||
r = curl_header_strdup(contents, sz, "Content-Type:", &content_header);
|
||||
if (r < 0) {
|
||||
log_oom();
|
||||
return 0;
|
||||
}
|
||||
if (r > 0) {
|
||||
r = strcmp("application/dns-message", content_header);
|
||||
if (r == 0)
|
||||
t->valid_dns_message = true;
|
||||
return sz;
|
||||
}
|
||||
}
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
static size_t dns_transaction_curl_write_callback(void *contents, size_t size, size_t nmemb, void *userdata) {
|
||||
DnsTransaction *t = ASSERT_PTR(userdata);
|
||||
size_t sz = size * nmemb;
|
||||
int r;
|
||||
|
||||
t->payload = memdup(contents, sz);
|
||||
if (!t->payload) {
|
||||
log_debug("Failed to extract HTTP payload to further processing");
|
||||
r = log_oom();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
t->payload_size += sz;
|
||||
|
||||
return sz;
|
||||
|
||||
fail:
|
||||
dns_transaction_complete(t, DNS_TRANSACTION_INVALID_REPLY);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int dns_transaction_curl_recv(DnsTransaction *t, DnsPacket **p) {
|
||||
size_t ms;
|
||||
int r;
|
||||
|
||||
ms = t->payload_size;
|
||||
|
||||
if (t->payload_size < 1) {
|
||||
log_debug("Received HTTP payload unexpected size %zu", t->payload_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = dns_packet_new(p, DNS_PROTOCOL_DNS, ms, DNS_PACKET_SIZE_MAX);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
log_debug("Received HTTP payload of size %zu", t->payload_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dns_transaction_curl_make_url(DnsTransaction *t, char **url) {
|
||||
_cleanup_free_ char *base64_string = NULL;
|
||||
uint8_t *packet_to_send = DNS_PACKET_DATA(t->sent);
|
||||
int r;
|
||||
|
||||
/* Let's zero the query ID according to the RFC */
|
||||
packet_to_send[0] = 0;
|
||||
packet_to_send[1] = 0;
|
||||
|
||||
r = base64mem_full(packet_to_send, t->sent->size, MAX_URL_LENGTH, &base64_string);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to encode DNS packet to base64");
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Remove base64 trailing characters */
|
||||
delete_trailing_chars(base64_string, "=");
|
||||
|
||||
/* Build the DoH's wire format request URL */
|
||||
r = asprintf(url, "https://%s/dns-query?dns=%s", t->server->server_string, base64_string);
|
||||
if (r < 0) {
|
||||
log_debug("Failed to allocate and set the url for transaction %" PRIu16 ".", t->id);
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dns_transaction_curl_on_response(CurlGlue *g, CURL *curl, CURLcode result) {
|
||||
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
|
||||
DnsTransaction *t = NULL;
|
||||
int status;
|
||||
int r;
|
||||
|
||||
assert(g);
|
||||
assert(curl);
|
||||
|
||||
curl_easy_getinfo(curl, CURLINFO_PRIVATE, &t);
|
||||
|
||||
if (result != CURLE_OK) {
|
||||
log_error_errno(SYNTHETIC_ERRNO(EIO), "HTTP request failed: %s", curl_easy_strerror(result));
|
||||
status = DNS_TRANSACTION_INVALID_REPLY;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!t->valid_dns_message) {
|
||||
log_debug("Received invalid HTTP payload, expected content type of application/dns-message");
|
||||
status = DNS_TRANSACTION_INVALID_REPLY;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = dns_transaction_curl_recv(t, &p);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "HTTP payload receive failure");
|
||||
dns_transaction_complete_errno(t, r);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Transfer the received payload to transaction/packet struct */
|
||||
uint8_t *p_data = DNS_PACKET_DATA(p);
|
||||
memcpy(p_data, t->payload, t->payload_size);
|
||||
|
||||
p->size = t->payload_size;
|
||||
|
||||
r = dns_packet_validate_reply(p);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Received invalid DNS packet as response, ignoring: %m");
|
||||
|
||||
if (r == 0)
|
||||
log_debug("Received inappropriate DNS packet as response, ignoring");
|
||||
|
||||
dns_transaction_process_reply(t, p, false);
|
||||
|
||||
return;
|
||||
finish:
|
||||
dns_transaction_complete(t, status);
|
||||
}
|
||||
|
||||
static int dns_transaction_emit_curl(DnsTransaction *t) {
|
||||
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
|
||||
_cleanup_free_ char *rule = NULL;
|
||||
int r;
|
||||
|
||||
assert(t);
|
||||
assert(t->sent);
|
||||
|
||||
dns_transaction_close_connection(t, true);
|
||||
|
||||
if (t->scope->protocol == DNS_PROTOCOL_DNS) {
|
||||
r = dns_transaction_pick_server(t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (manager_server_is_stub(t->scope->manager, t->server))
|
||||
return -ELOOP;
|
||||
|
||||
r = curl_glue_new(&t->glue, e);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
t->glue->on_finished = dns_transaction_curl_on_response;
|
||||
|
||||
r = dns_transaction_curl_make_url(t, &t->url);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = curl_glue_make(&t->curl, t->url, t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (curl_easy_setopt(t->curl, CURLOPT_HEADERFUNCTION, dns_transaction_curl_header_callback) != CURLE_OK)
|
||||
return -EIO;
|
||||
|
||||
if (curl_easy_setopt(t->curl, CURLOPT_HEADERDATA, t) != CURLE_OK)
|
||||
return -EIO;
|
||||
|
||||
if (curl_easy_setopt(t->curl, CURLOPT_WRITEFUNCTION, dns_transaction_curl_write_callback) != CURLE_OK)
|
||||
return -EIO;
|
||||
|
||||
if (curl_easy_setopt(t->curl, CURLOPT_WRITEDATA, t) != CURLE_OK)
|
||||
return -EIO;
|
||||
|
||||
// Prevents libcurl's native name lookups
|
||||
r = asprintf(&rule, "%s:443:%s", t->server->server_string, t->server->server_string);
|
||||
if (r < 0) {
|
||||
log_debug("Failed to compound IP resolution to CURLOPT_RESOLVE parameter");
|
||||
return r;
|
||||
}
|
||||
|
||||
t->glue->resolve_rules = curl_slist_append(NULL, rule);
|
||||
if (curl_easy_setopt(t->curl, CURLOPT_RESOLVE, t->glue->resolve_rules) != CURLE_OK)
|
||||
return -EIO;
|
||||
|
||||
|
||||
log_debug("Emitting HTTPS request via curl for transaction %" PRIu16, t->id);
|
||||
r = curl_glue_add(t->glue, t->curl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else
|
||||
/* TODO: Is this the right error code here? */
|
||||
return -ELOOP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
|
||||
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL, *dummy = NULL;
|
||||
_cleanup_set_free_ Set *keys = NULL;
|
||||
|
@ -2172,10 +2404,20 @@ int dns_transaction_go(DnsTransaction *t) {
|
|||
r = dns_transaction_emit_udp(t);
|
||||
if (r == -EMSGSIZE)
|
||||
log_debug("Sending query via TCP since it is too large.");
|
||||
#if ENABLE_DNS_OVER_HTTPS
|
||||
else if ((r == -EAGAIN &&
|
||||
(DNS_SERVER_FEATURE_LEVEL_IS_HTTPS(t->current_feature_level))))
|
||||
log_debug("Sending query via HTTPS.");
|
||||
#endif
|
||||
else if (r == -EAGAIN)
|
||||
log_debug("Sending query via TCP since UDP isn't supported or DNS-over-TLS is selected.");
|
||||
else if (r == -EPERM)
|
||||
log_debug("Sending query via TCP since UDP is blocked.");
|
||||
#if ENABLE_DNS_OVER_HTTPS
|
||||
if ((r == -EAGAIN &&
|
||||
(DNS_SERVER_FEATURE_LEVEL_IS_HTTPS(t->current_feature_level))))
|
||||
r = dns_transaction_emit_curl(t);
|
||||
#endif
|
||||
if (IN_SET(r, -EMSGSIZE, -EAGAIN, -EPERM))
|
||||
r = dns_transaction_emit_tcp(t);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
#include "sd-event.h"
|
||||
#include "in-addr-util.h"
|
||||
|
||||
#if ENABLE_DNS_OVER_HTTPS
|
||||
#include <curl/curl.h>
|
||||
#include "curl-util.h"
|
||||
#endif
|
||||
|
||||
typedef struct DnsTransaction DnsTransaction;
|
||||
typedef struct DnsTransactionFinder DnsTransactionFinder;
|
||||
typedef enum DnsTransactionState DnsTransactionState;
|
||||
|
@ -92,7 +97,15 @@ struct DnsTransaction {
|
|||
|
||||
/* TCP connection logic, if we need it */
|
||||
DnsStream *stream;
|
||||
|
||||
#if ENABLE_DNS_OVER_HTTPS
|
||||
/* HTTPS connection logic, if we need it */
|
||||
CurlGlue *glue;
|
||||
CURL *curl;
|
||||
char *url;
|
||||
uint8_t *payload;
|
||||
size_t payload_size;
|
||||
bool valid_dns_message;
|
||||
#endif
|
||||
/* The active server */
|
||||
DnsServer *server;
|
||||
|
||||
|
@ -219,6 +232,9 @@ DnsTransactionSource dns_transaction_source_from_string(const char *s) _pure_;
|
|||
/* Maximum attempts to send MDNS requests, see RFC 6762 Section 8.1 */
|
||||
#define MDNS_TRANSACTION_ATTEMPTS_MAX 3
|
||||
|
||||
/* Maximum URL length for HTTP GET request, see RFC ... */
|
||||
#define MAX_URL_LENGTH 2048
|
||||
|
||||
#define TRANSACTION_ATTEMPTS_MAX(p) ((p) == DNS_PROTOCOL_LLMNR ? \
|
||||
LLMNR_TRANSACTION_ATTEMPTS_MAX : \
|
||||
(p) == DNS_PROTOCOL_MDNS ? \
|
||||
|
|
|
@ -26,6 +26,7 @@ Resolve.LLMNR, config_parse_resolve_support, 0,
|
|||
Resolve.MulticastDNS, config_parse_resolve_support, 0, offsetof(Manager, mdns_support)
|
||||
Resolve.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Manager, dnssec_mode)
|
||||
Resolve.DNSOverTLS, config_parse_dns_over_tls_mode, 0, offsetof(Manager, dns_over_tls_mode)
|
||||
Resolve.DNSOverHTTPS, config_parse_dns_over_https_mode, 0, offsetof(Manager, dns_over_https_mode)
|
||||
Resolve.Cache, config_parse_dns_cache_mode, DNS_CACHE_MODE_YES, offsetof(Manager, enable_cache)
|
||||
Resolve.DNSStubListener, config_parse_dns_stub_listener_mode, 0, offsetof(Manager, dns_stub_listener_mode)
|
||||
Resolve.ReadEtcHosts, config_parse_bool, 0, offsetof(Manager, read_etc_hosts)
|
||||
|
|
|
@ -1670,6 +1670,15 @@ DnsOverTlsMode manager_get_dns_over_tls_mode(Manager *m) {
|
|||
return DNS_OVER_TLS_NO;
|
||||
}
|
||||
|
||||
DnsOverHttpsMode manager_get_dns_over_https_mode(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
if (m->dns_over_https_mode != _DNS_OVER_HTTPS_MODE_INVALID)
|
||||
return m->dns_over_https_mode;
|
||||
|
||||
return DNS_OVER_HTTPS_NO;
|
||||
}
|
||||
|
||||
void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResourceKey *key) {
|
||||
|
||||
assert(verdict >= 0);
|
||||
|
|
|
@ -40,6 +40,7 @@ struct Manager {
|
|||
ResolveSupport mdns_support;
|
||||
DnssecMode dnssec_mode;
|
||||
DnsOverTlsMode dns_over_tls_mode;
|
||||
DnsOverHttpsMode dns_over_https_mode;
|
||||
DnsCacheMode enable_cache;
|
||||
bool cache_from_localhost;
|
||||
DnsStubListenerMode dns_stub_listener_mode;
|
||||
|
@ -207,6 +208,8 @@ bool manager_dnssec_supported(Manager *m);
|
|||
|
||||
DnsOverTlsMode manager_get_dns_over_tls_mode(Manager *m);
|
||||
|
||||
DnsOverHttpsMode manager_get_dns_over_https_mode(Manager *m);
|
||||
|
||||
void manager_dnssec_verdict(Manager *m, DnssecVerdict verdict, const DnsResourceKey *key);
|
||||
|
||||
bool manager_routable(Manager *m);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#Domains=
|
||||
#DNSSEC={{DEFAULT_DNSSEC_MODE_STR}}
|
||||
#DNSOverTLS={{DEFAULT_DNS_OVER_TLS_MODE_STR}}
|
||||
#DNSOverHTTPS={{DEFAULT_DNS_OVER_HTTPS_MODE_STR}}
|
||||
#MulticastDNS={{DEFAULT_MDNS_MODE_STR}}
|
||||
#LLMNR={{DEFAULT_LLMNR_MODE_STR}}
|
||||
#Cache=yes
|
||||
|
|
|
@ -311,6 +311,9 @@ void curl_glue_remove_and_free(CurlGlue *g, CURL *c) {
|
|||
if (g->curl)
|
||||
curl_multi_remove_handle(g->curl, c);
|
||||
|
||||
if (g->resolve_rules)
|
||||
curl_slist_free_all(g->resolve_rules);
|
||||
|
||||
curl_easy_cleanup(c);
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ struct CurlGlue {
|
|||
|
||||
void (*on_finished)(CurlGlue *g, CURL *curl, CURLcode code);
|
||||
void *userdata;
|
||||
struct curl_slist *resolve_rules;;
|
||||
};
|
||||
|
||||
int curl_glue_new(CurlGlue **glue, sd_event *event);
|
|
@ -256,6 +256,10 @@ if conf.get('HAVE_TPM2') == 1 and conf.get('HAVE_LIBCRYPTSETUP') == 1
|
|||
shared_sources += files('cryptsetup-tpm2.c')
|
||||
endif
|
||||
|
||||
if conf.get('HAVE_LIBCURL') == 1
|
||||
shared_sources += files('curl-util.c')
|
||||
endif
|
||||
|
||||
generate_ip_protocol_list = find_program('generate-ip-protocol-list.sh')
|
||||
ip_protocol_list_txt = custom_target(
|
||||
'ip-protocol-list.txt',
|
||||
|
@ -337,6 +341,11 @@ libshared_deps = [threads,
|
|||
libxz_cflags,
|
||||
libzstd_cflags]
|
||||
|
||||
# Is this correct?
|
||||
if conf.get('HAVE_LIBCURL') == 1
|
||||
libshared_deps += [libcurl]
|
||||
endif
|
||||
|
||||
libshared_sym_path = meson.current_source_dir() / 'libshared.sym'
|
||||
libshared_build_dir = meson.current_build_dir()
|
||||
|
||||
|
|
|
@ -1808,63 +1808,81 @@ char* umount_and_unlink_and_free(char *p) {
|
|||
return mfree(p);
|
||||
}
|
||||
|
||||
static int path_get_mount_info(
|
||||
static int path_get_mount_info_at(
|
||||
int dir_fd,
|
||||
const char *path,
|
||||
char **ret_fstype,
|
||||
char **ret_options) {
|
||||
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
_cleanup_free_ char *fstype = NULL, *options = NULL;
|
||||
struct libmnt_fs *fs;
|
||||
int r;
|
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
||||
int r, mnt_id;
|
||||
|
||||
assert(path);
|
||||
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
||||
|
||||
table = mnt_new_table();
|
||||
if (!table)
|
||||
return -ENOMEM;
|
||||
|
||||
r = mnt_table_parse_mtab(table, /* filename = */ NULL);
|
||||
r = path_get_mnt_id_at(dir_fd, path, &mnt_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return log_debug_errno(r, "Failed to get mount ID: %m");
|
||||
|
||||
fs = mnt_table_find_mountpoint(table, path, MNT_ITER_FORWARD);
|
||||
if (!fs)
|
||||
return -EINVAL;
|
||||
r = libmount_parse("/proc/self/mountinfo", NULL, &table, &iter);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
|
||||
|
||||
if (ret_fstype) {
|
||||
fstype = strdup(strempty(mnt_fs_get_fstype(fs)));
|
||||
if (!fstype)
|
||||
return -ENOMEM;
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r == 1)
|
||||
break; /* EOF */
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
|
||||
|
||||
if (mnt_fs_get_id(fs) != mnt_id)
|
||||
continue;
|
||||
|
||||
_cleanup_free_ char *fstype = NULL, *options = NULL;
|
||||
|
||||
if (ret_fstype) {
|
||||
fstype = strdup(strempty(mnt_fs_get_fstype(fs)));
|
||||
if (!fstype)
|
||||
return log_oom_debug();
|
||||
}
|
||||
|
||||
if (ret_options) {
|
||||
options = strdup(strempty(mnt_fs_get_options(fs)));
|
||||
if (!options)
|
||||
return log_oom_debug();
|
||||
}
|
||||
|
||||
if (ret_fstype)
|
||||
*ret_fstype = TAKE_PTR(fstype);
|
||||
if (ret_options)
|
||||
*ret_options = TAKE_PTR(options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ret_options) {
|
||||
options = strdup(strempty(mnt_fs_get_options(fs)));
|
||||
if (!options)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (ret_fstype)
|
||||
*ret_fstype = TAKE_PTR(fstype);
|
||||
if (ret_options)
|
||||
*ret_options = TAKE_PTR(options);
|
||||
|
||||
return 0;
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Cannot find mount ID %i from /proc/self/mountinfo.", mnt_id);
|
||||
}
|
||||
|
||||
int path_is_network_fs_harder(const char *path) {
|
||||
int path_is_network_fs_harder_at(int dir_fd, const char *path) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int r;
|
||||
|
||||
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
||||
|
||||
fd = xopenat(dir_fd, path, O_PATH | O_CLOEXEC | O_NOFOLLOW);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
r = fd_is_network_fs(fd);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
_cleanup_free_ char *fstype = NULL, *options = NULL;
|
||||
int r, ret;
|
||||
|
||||
assert(path);
|
||||
|
||||
ret = path_is_network_fs(path);
|
||||
if (ret > 0)
|
||||
return true;
|
||||
|
||||
r = path_get_mount_info(path, &fstype, &options);
|
||||
r = path_get_mount_info_at(fd, /* path = */ NULL, &fstype, &options);
|
||||
if (r < 0)
|
||||
return RET_GATHER(ret, r);
|
||||
return r;
|
||||
|
||||
if (fstype_is_network(fstype))
|
||||
return true;
|
||||
|
|
|
@ -181,4 +181,7 @@ int mount_credentials_fs(const char *path, size_t size, bool ro);
|
|||
|
||||
int make_fsmount(int error_log_level, const char *what, const char *type, unsigned long flags, const char *options, int userns_fd);
|
||||
|
||||
int path_is_network_fs_harder(const char *path);
|
||||
int path_is_network_fs_harder_at(int dir_fd, const char *path);
|
||||
static inline int path_is_network_fs_harder(const char *path) {
|
||||
return path_is_network_fs_harder_at(AT_FDCWD, path);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
DEFINE_CONFIG_PARSE_ENUM(config_parse_resolve_support, resolve_support, ResolveSupport);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_dnssec_mode, dnssec_mode, DnssecMode);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_dns_over_tls_mode, dns_over_tls_mode, DnsOverTlsMode);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_dns_over_https_mode, dns_over_https_mode, DnsOverHttpsMode);
|
||||
|
||||
static const char* const resolve_support_table[_RESOLVE_SUPPORT_MAX] = {
|
||||
[RESOLVE_SUPPORT_NO] = "no",
|
||||
|
@ -29,6 +30,12 @@ static const char* const dns_over_tls_mode_table[_DNS_OVER_TLS_MODE_MAX] = {
|
|||
};
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dns_over_tls_mode, DnsOverTlsMode, DNS_OVER_TLS_YES);
|
||||
|
||||
static const char* const dns_over_https_mode_table[_DNS_OVER_HTTPS_MODE_MAX] = {
|
||||
[DNS_OVER_HTTPS_NO] = "no",
|
||||
[DNS_OVER_HTTPS_YES] = "yes",
|
||||
};
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dns_over_https_mode, DnsOverHttpsMode, DNS_OVER_HTTPS_YES);
|
||||
|
||||
bool dns_server_address_valid(int family, const union in_addr_union *sa) {
|
||||
|
||||
/* Refuses the 0 IP addresses as well as 127.0.0.53/127.0.0.54 (which is our own DNS stub) */
|
||||
|
|
|
@ -27,6 +27,7 @@ enum DnsCacheMode {
|
|||
typedef enum ResolveSupport ResolveSupport;
|
||||
typedef enum DnssecMode DnssecMode;
|
||||
typedef enum DnsOverTlsMode DnsOverTlsMode;
|
||||
typedef enum DnsOverHttpsMode DnsOverHttpsMode;
|
||||
|
||||
/* Do not change the order, see link_get_llmnr_support() or link_get_mdns_support(). */
|
||||
enum ResolveSupport {
|
||||
|
@ -70,9 +71,21 @@ enum DnsOverTlsMode {
|
|||
_DNS_OVER_TLS_MODE_INVALID = -EINVAL,
|
||||
};
|
||||
|
||||
enum DnsOverHttpsMode {
|
||||
/* No connection is made for DNS-over-HTTPS */
|
||||
DNS_OVER_HTTPS_NO,
|
||||
|
||||
/* Enforce DNS-over-HTTPS */
|
||||
DNS_OVER_HTTPS_YES,
|
||||
|
||||
_DNS_OVER_HTTPS_MODE_MAX,
|
||||
_DNS_OVER_HTTPS_MODE_INVALID = -EINVAL,
|
||||
};
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_resolve_support);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dnssec_mode);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dns_over_tls_mode);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dns_over_https_mode);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dns_cache_mode);
|
||||
|
||||
const char* resolve_support_to_string(ResolveSupport p) _const_;
|
||||
|
@ -84,6 +97,9 @@ DnssecMode dnssec_mode_from_string(const char *s) _pure_;
|
|||
const char* dns_over_tls_mode_to_string(DnsOverTlsMode p) _const_;
|
||||
DnsOverTlsMode dns_over_tls_mode_from_string(const char *s) _pure_;
|
||||
|
||||
const char* dns_over_https_mode_to_string(DnsOverHttpsMode p) _const_;
|
||||
DnsOverHttpsMode dns_over_https_mode_from_string(const char *s) _pure_;
|
||||
|
||||
bool dns_server_address_valid(int family, const union in_addr_union *sa);
|
||||
|
||||
const char* dns_cache_mode_to_string(DnsCacheMode p) _const_;
|
||||
|
|
|
@ -538,9 +538,53 @@ TEST(bind_mount_submounts) {
|
|||
}
|
||||
|
||||
TEST(path_is_network_fs_harder) {
|
||||
ASSERT_OK_ZERO(path_is_network_fs_harder("/dev"));
|
||||
ASSERT_OK_ZERO(path_is_network_fs_harder("/sys"));
|
||||
ASSERT_OK_ZERO(path_is_network_fs_harder("/run"));
|
||||
_cleanup_close_ int dir_fd = -EBADF;
|
||||
int r;
|
||||
|
||||
ASSERT_OK(dir_fd = open("/", O_PATH | O_CLOEXEC));
|
||||
FOREACH_STRING(s,
|
||||
"/", "/dev/", "/proc/", "/run/", "/sys/", "/tmp/", "/usr/", "/var/tmp/",
|
||||
"", ".", "../../../", "/this/path/should/not/exist/for/test-mount-util/") {
|
||||
|
||||
r = path_is_network_fs_harder(s);
|
||||
log_debug("path_is_network_fs_harder(%s) → %i: %s", s, r, r < 0 ? STRERROR(r) : yes_no(r));
|
||||
|
||||
const char *q = path_startswith(s, "/") ?: s;
|
||||
r = path_is_network_fs_harder_at(dir_fd, q);
|
||||
log_debug("path_is_network_fs_harder_at(root, %s) → %i: %s", q, r, r < 0 ? STRERROR(r) : yes_no(r));
|
||||
}
|
||||
|
||||
if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) {
|
||||
(void) log_tests_skipped("not running privileged");
|
||||
return;
|
||||
}
|
||||
|
||||
_cleanup_(rm_rf_physical_and_freep) char *t = NULL;
|
||||
assert_se(mkdtemp_malloc("/tmp/test-mount-util.path_is_network_fs_harder.XXXXXXX", &t) >= 0);
|
||||
|
||||
r = safe_fork("(make_mount-point)",
|
||||
FORK_RESET_SIGNALS |
|
||||
FORK_CLOSE_ALL_FDS |
|
||||
FORK_DEATHSIG_SIGTERM |
|
||||
FORK_WAIT |
|
||||
FORK_REOPEN_LOG |
|
||||
FORK_LOG |
|
||||
FORK_NEW_MOUNTNS |
|
||||
FORK_MOUNTNS_SLAVE,
|
||||
NULL);
|
||||
ASSERT_OK(r);
|
||||
|
||||
if (r == 0) {
|
||||
ASSERT_OK(mount_nofollow_verbose(LOG_INFO, "tmpfs", t, "tmpfs", 0, NULL));
|
||||
ASSERT_OK_ZERO(path_is_network_fs_harder(t));
|
||||
ASSERT_OK_ERRNO(umount(t));
|
||||
|
||||
ASSERT_OK(mount_nofollow_verbose(LOG_INFO, "tmpfs", t, "tmpfs", 0, "x-systemd-growfs,x-systemd-automount"));
|
||||
ASSERT_OK_ZERO(path_is_network_fs_harder(t));
|
||||
ASSERT_OK_ERRNO(umount(t));
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_DEBUG);
|
||||
|
|
|
@ -142,11 +142,13 @@ endif
|
|||
############################################################
|
||||
|
||||
if install_tests
|
||||
foreach script : ['integration-test-setup.sh', 'run-unit-tests.py']
|
||||
install_data(script,
|
||||
install_mode : 'rwxr-xr-x',
|
||||
install_dir : testsdir)
|
||||
endforeach
|
||||
install_data('run-unit-tests.py',
|
||||
install_mode : 'rwxr-xr-x',
|
||||
install_dir : testsdir)
|
||||
|
||||
install_data('integration-test-setup.sh',
|
||||
install_mode : 'rwxr-xr-x',
|
||||
install_dir : testdata_dir)
|
||||
endif
|
||||
|
||||
############################################################
|
||||
|
|
|
@ -7,9 +7,9 @@ Before=getty-pre.target
|
|||
|
||||
[Service]
|
||||
ExecStartPre=rm -f /failed /testok
|
||||
ExecStartPre=/usr/lib/systemd/tests/integration-test-setup.sh setup
|
||||
ExecStartPre=/usr/lib/systemd/tests/testdata/integration-test-setup.sh setup
|
||||
ExecStart=@command@
|
||||
ExecStopPost=/usr/lib/systemd/tests/integration-test-setup.sh finalize
|
||||
ExecStopPost=/usr/lib/systemd/tests/testdata/integration-test-setup.sh finalize
|
||||
Type=oneshot
|
||||
MemoryAccounting=@memory-accounting@
|
||||
StateDirectory=%N
|
||||
|
|
Loading…
Reference in New Issue