Compare commits

..

No commits in common. "2ac4d1d45b952b9d675ae7911de3fef0874d65a8" and "f8bff7805ea1252c2421d07a92bf5b19f4f16aa7" have entirely different histories.

12 changed files with 156 additions and 270 deletions

View File

@ -448,27 +448,37 @@
<refsect2> <refsect2>
<title>Other Forms of Activation</title> <title>Other Forms of Activation</title>
<para>Other forms of activation have been suggested and implemented in some systems. However, there are <para>Other forms of activation have been suggested and
often simpler or better alternatives, or they can be put together of combinations of the schemes implemented in some systems. However, there are often simpler or
above. Example: Sometimes, it appears useful to start daemons or <filename>.socket</filename> units better alternatives, or they can be put together of combinations
when a specific IP address is configured on a network interface, because network sockets shall be bound of the schemes above. Example: Sometimes, it appears useful to
to the address. However, an alternative to implement this is by utilizing the Linux start daemons or <filename>.socket</filename> units when a
<constant>IP_FREEBIND</constant>/<constant>IPV6_FREEBIND</constant> socket option, as accessible via specific IP address is configured on a network interface,
<varname>FreeBind=yes</varname> in systemd socket files (see because network sockets shall be bound to the address. However,
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> for an alternative to implement this is by utilizing the Linux
details). This option, when enabled, allows sockets to be bound to a non-local, not configured IP <constant>IP_FREEBIND</constant> socket option, as accessible
address, and hence allows bindings to a particular IP address before it actually becomes available, via <varname>FreeBind=yes</varname> in systemd socket files (see
making such an explicit dependency to the configured address redundant. Another often suggested trigger <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for service activation is low system load. However, here too, a more convincing approach might be to for details). This option, when enabled, allows sockets to be
make proper use of features of the operating system, in particular, the CPU or I/O scheduler of bound to a non-local, not configured IP address, and hence
Linux. Instead of scheduling jobs from userspace based on monitoring the OS scheduler, it is advisable allows bindings to a particular IP address before it actually
to leave the scheduling of processes to the OS scheduler itself. systemd provides fine-grained access becomes available, making such an explicit dependency to the
to the CPU and I/O schedulers. If a process executed by the init system shall not negatively impact the configured address redundant. Another often suggested trigger
amount of CPU or I/O bandwidth available to other processes, it should be configured with for service activation is low system load. However, here too, a
more convincing approach might be to make proper use of features
of the operating system, in particular, the CPU or I/O scheduler
of Linux. Instead of scheduling jobs from userspace based on
monitoring the OS scheduler, it is advisable to leave the
scheduling of processes to the OS scheduler itself. systemd
provides fine-grained access to the CPU and I/O schedulers. If a
process executed by the init system shall not negatively impact
the amount of CPU or I/O bandwidth available to other processes,
it should be configured with
<varname>CPUSchedulingPolicy=idle</varname> and/or <varname>CPUSchedulingPolicy=idle</varname> and/or
<varname>IOSchedulingClass=idle</varname>. Optionally, this may be combined with timer-based activation <varname>IOSchedulingClass=idle</varname>. Optionally, this may
to schedule background jobs during runtime and with minimal impact on the system, and remove it from be combined with timer-based activation to schedule background
the boot phase itself.</para> jobs during runtime and with minimal impact on the system, and
remove it from the boot phase itself.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>

View File

@ -568,23 +568,26 @@
<varlistentry> <varlistentry>
<term><varname>IPTOS=</varname></term> <term><varname>IPTOS=</varname></term>
<listitem><para>Takes an integer argument controlling the IP Type-Of-Service field for packets <listitem><para>Takes an integer argument controlling the IP
generated from this socket. This controls the <constant>IP_TOS</constant> socket option (see Type-Of-Service field for packets generated from this socket.
<citerefentry This controls the IP_TOS socket option (see
project='die-net'><refentrytitle>ip</refentrytitle><manvolnum>7</manvolnum></citerefentry> for <citerefentry project='die-net'><refentrytitle>ip</refentrytitle><manvolnum>7</manvolnum></citerefentry>
details.). Either a numeric string or one of <option>low-delay</option>, <option>throughput</option>, for details.). Either a numeric string or one of
<option>reliability</option> or <option>low-cost</option> may be specified.</para></listitem> <option>low-delay</option>, <option>throughput</option>,
<option>reliability</option> or <option>low-cost</option> may
be specified.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>IPTTL=</varname></term> <term><varname>IPTTL=</varname></term>
<listitem><para>Takes an integer argument controlling the IPv4 Time-To-Live/IPv6 Hop-Count field for <listitem><para>Takes an integer argument controlling the IPv4
packets generated from this socket. This sets the Time-To-Live/IPv6 Hop-Count field for packets generated from
<constant>IP_TTL</constant>/<constant>IPV6_UNICAST_HOPS</constant> socket options (see <citerefentry this socket. This sets the IP_TTL/IPV6_UNICAST_HOPS socket
project='die-net'><refentrytitle>ip</refentrytitle><manvolnum>7</manvolnum></citerefentry> and options (see
<citerefentry <citerefentry project='die-net'><refentrytitle>ip</refentrytitle><manvolnum>7</manvolnum></citerefentry>
project='die-net'><refentrytitle>ipv6</refentrytitle><manvolnum>7</manvolnum></citerefentry> for and
details.)</para></listitem> <citerefentry project='die-net'><refentrytitle>ipv6</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for details.)</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -659,18 +662,20 @@
<varlistentry> <varlistentry>
<term><varname>FreeBind=</varname></term> <term><varname>FreeBind=</varname></term>
<listitem><para>Takes a boolean value. Controls whether the socket can be bound to non-local IP <listitem><para>Takes a boolean value. Controls whether the
addresses. This is useful to configure sockets listening on specific IP addresses before those IP socket can be bound to non-local IP addresses. This is useful
addresses are successfully configured on a network interface. This sets the to configure sockets listening on specific IP addresses before
<constant>IP_FREEBIND</constant>/<constant>IPV6_FREEBIND</constant> socket option. For robustness those IP addresses are successfully configured on a network
reasons it is recommended to use this option whenever you bind a socket to a specific IP interface. This sets the IP_FREEBIND socket option. For
address. Defaults to <option>false</option>.</para></listitem> robustness reasons it is recommended to use this option
whenever you bind a socket to a specific IP address. Defaults
to <option>false</option>.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>Transparent=</varname></term> <term><varname>Transparent=</varname></term>
<listitem><para>Takes a boolean value. Controls the <listitem><para>Takes a boolean value. Controls the
<constant>IP_TRANSPARENT</constant>/<constant>IPV6_TRANSPARENT</constant> socket option. Defaults to IP_TRANSPARENT socket option. Defaults to
<option>false</option>.</para></listitem> <option>false</option>.</para></listitem>
</varlistentry> </varlistentry>

View File

@ -6,11 +6,6 @@
#define IPV6_UNICAST_IF 76 #define IPV6_UNICAST_IF 76
#endif #endif
/* linux/in6.h or netinet/in.h */
#ifndef IPV6_TRANSPARENT
#define IPV6_TRANSPARENT 75
#endif
/* Not exposed but defined at include/net/ip.h */ /* Not exposed but defined at include/net/ip.h */
#ifndef IPV4_MIN_MTU #ifndef IPV4_MIN_MTU
#define IPV4_MIN_MTU 68 #define IPV4_MIN_MTU 68

View File

@ -80,15 +80,15 @@ int socket_address_listen(
} }
if (free_bind) { if (free_bind) {
r = socket_set_freebind(fd, socket_address_family(a), true); r = setsockopt_int(fd, IPPROTO_IP, IP_FREEBIND, true);
if (r < 0) if (r < 0)
log_warning_errno(r, "IP_FREEBIND/IPV6_FREEBIND failed: %m"); log_warning_errno(r, "IP_FREEBIND failed: %m");
} }
if (transparent) { if (transparent) {
r = socket_set_transparent(fd, socket_address_family(a), true); r = setsockopt_int(fd, IPPROTO_IP, IP_TRANSPARENT, true);
if (r < 0) if (r < 0)
log_warning_errno(r, "IP_TRANSPARENT/IPV6_TRANSPARENT failed: %m"); log_warning_errno(r, "IP_TRANSPARENT failed: %m");
} }
} }

View File

@ -26,7 +26,6 @@
#include "macro.h" #include "macro.h"
#include "memory-util.h" #include "memory-util.h"
#include "missing_socket.h" #include "missing_socket.h"
#include "missing_network.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "process-util.h" #include "process-util.h"
@ -1205,28 +1204,13 @@ ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags) {
return n; return n;
} }
int socket_get_family(int fd, int *ret) { int socket_pass_pktinfo(int fd, bool b) {
int af; int af;
socklen_t sl = sizeof(af); socklen_t sl = sizeof(af);
if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &af, &sl) < 0) if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &af, &sl) < 0)
return -errno; return -errno;
if (sl != sizeof(af))
return -EINVAL;
return af;
}
int socket_set_recvpktinfo(int fd, int af, bool b) {
int r;
if (af == AF_UNSPEC) {
r = socket_get_family(fd, &af);
if (r < 0)
return r;
}
switch (af) { switch (af) {
case AF_INET: case AF_INET:
@ -1242,142 +1226,3 @@ int socket_set_recvpktinfo(int fd, int af, bool b) {
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
} }
} }
int socket_set_recverr(int fd, int af, bool b) {
int r;
if (af == AF_UNSPEC) {
r = socket_get_family(fd, &af);
if (r < 0)
return r;
}
switch (af) {
case AF_INET:
return setsockopt_int(fd, IPPROTO_IP, IP_RECVERR, b);
case AF_INET6:
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVERR, b);
default:
return -EAFNOSUPPORT;
}
}
int socket_set_recvttl(int fd, int af, bool b) {
int r;
if (af == AF_UNSPEC) {
r = socket_get_family(fd, &af);
if (r < 0)
return r;
}
switch (af) {
case AF_INET:
return setsockopt_int(fd, IPPROTO_IP, IP_RECVTTL, b);
case AF_INET6:
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, b);
default:
return -EAFNOSUPPORT;
}
}
int socket_set_ttl(int fd, int af, int ttl) {
int r;
if (af == AF_UNSPEC) {
r = socket_get_family(fd, &af);
if (r < 0)
return r;
}
switch (af) {
case AF_INET:
return setsockopt_int(fd, IPPROTO_IP, IP_TTL, ttl);
case AF_INET6:
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, ttl);
default:
return -EAFNOSUPPORT;
}
}
int socket_set_unicast_if(int fd, int af, int ifi) {
be32_t ifindex_be = htobe32(ifi);
int r;
if (af == AF_UNSPEC) {
r = socket_get_family(fd, &af);
if (r < 0)
return r;
}
switch (af) {
case AF_INET:
if (setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex_be, sizeof(ifindex_be)) < 0)
return -errno;
return 0;
case AF_INET6:
if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex_be, sizeof(ifindex_be)) < 0)
return -errno;
return 0;
default:
return -EAFNOSUPPORT;
}
}
int socket_set_freebind(int fd, int af, bool b) {
int r;
if (af == AF_UNSPEC) {
r = socket_get_family(fd, &af);
if (r < 0)
return r;
}
switch (af) {
case AF_INET:
return setsockopt_int(fd, IPPROTO_IP, IP_FREEBIND, b);
case AF_INET6:
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_FREEBIND, b);
default:
return -EAFNOSUPPORT;
}
}
int socket_set_transparent(int fd, int af, bool b) {
int r;
if (af == AF_UNSPEC) {
r = socket_get_family(fd, &af);
if (r < 0)
return r;
}
switch (af) {
case AF_INET:
return setsockopt_int(fd, IPPROTO_IP, IP_TRANSPARENT, b);
case AF_INET6:
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_TRANSPARENT, b);
default:
return -EAFNOSUPPORT;
}
}

View File

@ -261,11 +261,4 @@ int socket_bind_to_ifindex(int fd, int ifindex);
ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags); ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);
int socket_get_family(int fd, int *ret); int socket_pass_pktinfo(int fd, bool b);
int socket_set_recvpktinfo(int fd, int af, bool b);
int socket_set_recverr(int fd, int af, bool b);
int socket_set_recvttl(int fd, int af, bool b);
int socket_set_ttl(int fd, int af, int ttl);
int socket_set_unicast_if(int fd, int af, int ifi);
int socket_set_freebind(int fd, int af, bool b);
int socket_set_transparent(int fd, int af, bool b);

View File

@ -979,11 +979,10 @@ static void socket_close_fds(Socket *s) {
(void) unlink(*i); (void) unlink(*i);
} }
static void socket_apply_socket_options(Socket *s, SocketPort *p, int fd) { static void socket_apply_socket_options(Socket *s, int fd) {
int r; int r;
assert(s); assert(s);
assert(p);
assert(fd >= 0); assert(fd >= 0);
if (s->keep_alive) { if (s->keep_alive) {
@ -1047,7 +1046,7 @@ static void socket_apply_socket_options(Socket *s, SocketPort *p, int fd) {
} }
if (s->pass_pktinfo) { if (s->pass_pktinfo) {
r = socket_set_recvpktinfo(fd, socket_address_family(&p->address), true); r = socket_pass_pktinfo(fd, true);
if (r < 0) if (r < 0)
log_unit_warning_errno(UNIT(s), r, "Failed to enable packet info socket option: %m"); log_unit_warning_errno(UNIT(s), r, "Failed to enable packet info socket option: %m");
} }
@ -1083,8 +1082,16 @@ static void socket_apply_socket_options(Socket *s, SocketPort *p, int fd) {
} }
if (s->ip_ttl >= 0) { if (s->ip_ttl >= 0) {
r = socket_set_ttl(fd, socket_address_family(&p->address), s->ip_ttl); int x;
if (r < 0)
r = setsockopt_int(fd, IPPROTO_IP, IP_TTL, s->ip_ttl);
if (socket_ipv6_is_supported())
x = setsockopt_int(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, s->ip_ttl);
else
x = -EAFNOSUPPORT;
if (r < 0 && x < 0)
log_unit_warning_errno(UNIT(s), r, "IP_TTL/IPV6_UNICAST_HOPS failed: %m"); log_unit_warning_errno(UNIT(s), r, "IP_TTL/IPV6_UNICAST_HOPS failed: %m");
} }
@ -1657,7 +1664,7 @@ static int socket_open_fds(Socket *_s) {
if (p->fd < 0) if (p->fd < 0)
return p->fd; return p->fd;
socket_apply_socket_options(s, p, p->fd); socket_apply_socket_options(s, p->fd);
socket_symlink(s); socket_symlink(s);
break; break;
@ -2997,7 +3004,7 @@ static int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
if (cfd < 0) if (cfd < 0)
goto fail; goto fail;
socket_apply_socket_options(p->socket, p, cfd); socket_apply_socket_options(p->socket, cfd);
} }
socket_enter_running(p->socket, cfd); socket_enter_running(p->socket, cfd);

View File

@ -189,25 +189,19 @@ static const char* fallback_chassis(void) {
int v, r; int v, r;
v = detect_virtualization(); v = detect_virtualization();
if (v < 0) if (VIRTUALIZATION_IS_VM(v))
log_debug_errno(v, "Failed to detect virtualization, ignoring: %m");
else if (VIRTUALIZATION_IS_VM(v))
return "vm"; return "vm";
else if (VIRTUALIZATION_IS_CONTAINER(v)) if (VIRTUALIZATION_IS_CONTAINER(v))
return "container"; return "container";
r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type); r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type);
if (r < 0) { if (r < 0)
log_debug_errno(v, "Failed to read DMI chassis type, ignoring: %m");
goto try_acpi; goto try_acpi;
}
r = safe_atou(type, &t); r = safe_atou(type, &t);
free(type); free(type);
if (r < 0) { if (r < 0)
log_debug_errno(v, "Failed to parse DMI chassis type, ignoring: %m");
goto try_acpi; goto try_acpi;
}
/* We only list the really obvious cases here. The DMI data is unreliable enough, so let's not do any /* We only list the really obvious cases here. The DMI data is unreliable enough, so let's not do any
additional guesswork on top of that. additional guesswork on top of that.
@ -223,7 +217,6 @@ static const char* fallback_chassis(void) {
case 0x4: /* Low Profile Desktop */ case 0x4: /* Low Profile Desktop */
case 0x6: /* Mini Tower */ case 0x6: /* Mini Tower */
case 0x7: /* Tower */ case 0x7: /* Tower */
case 0xD: /* All in one (i.e. PC built into monitor) */
return "desktop"; return "desktop";
case 0x8: /* Portable */ case 0x8: /* Portable */
@ -246,24 +239,17 @@ static const char* fallback_chassis(void) {
case 0x1F: /* Convertible */ case 0x1F: /* Convertible */
case 0x20: /* Detachable */ case 0x20: /* Detachable */
return "convertible"; return "convertible";
default:
log_debug("Unhandled DMI chassis type 0x%02x, ignoring.", t);
} }
try_acpi: try_acpi:
r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type); r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type);
if (r < 0) { if (r < 0)
log_debug_errno(v, "Failed read ACPI PM profile, ignoring: %m");
return NULL; return NULL;
}
r = safe_atou(type, &t); r = safe_atou(type, &t);
free(type); free(type);
if (r < 0) { if (r < 0)
log_debug_errno(v, "Failed parse ACPI PM profile, ignoring: %m");
return NULL; return NULL;
}
/* We only list the really obvious cases here as the ACPI data is not really super reliable. /* We only list the really obvious cases here as the ACPI data is not really super reliable.
* *
@ -289,9 +275,6 @@ try_acpi:
case 8: /* Tablet */ case 8: /* Tablet */
return "tablet"; return "tablet";
default:
log_debug("Unhandled ACPI PM profile 0x%02x, ignoring.", t);
} }
return NULL; return NULL;
@ -927,13 +910,13 @@ static const BusObjectImplementation manager_object = {
.vtables = BUS_VTABLES(hostname_vtable), .vtables = BUS_VTABLES(hostname_vtable),
}; };
static int connect_bus(Context *c, sd_event *event, sd_bus **ret) { static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r; int r;
assert(c); assert(c);
assert(event); assert(event);
assert(ret); assert(_bus);
r = sd_bus_default_system(&bus); r = sd_bus_default_system(&bus);
if (r < 0) if (r < 0)
@ -955,7 +938,8 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **ret) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to attach bus to event loop: %m"); return log_error_errno(r, "Failed to attach bus to event loop: %m");
*ret = TAKE_PTR(bus); *_bus = TAKE_PTR(bus);
return 0; return 0;
} }

View File

@ -386,27 +386,54 @@ static int dns_scope_socket(
} }
if (s->link) { if (s->link) {
r = socket_set_unicast_if(fd, sa.sa.sa_family, ifindex); be32_t ifindex_be = htobe32(ifindex);
if (sa.sa.sa_family == AF_INET) {
r = setsockopt(fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex_be, sizeof(ifindex_be));
if (r < 0) if (r < 0)
return r; return -errno;
} else if (sa.sa.sa_family == AF_INET6) {
r = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex_be, sizeof(ifindex_be));
if (r < 0)
return -errno;
}
} }
if (s->protocol == DNS_PROTOCOL_LLMNR) { if (s->protocol == DNS_PROTOCOL_LLMNR) {
/* RFC 4795, section 2.5 requires the TTL to be set to 1 */ /* RFC 4795, section 2.5 requires the TTL to be set to 1 */
r = socket_set_ttl(fd, sa.sa.sa_family, 1);
if (sa.sa.sa_family == AF_INET) {
r = setsockopt_int(fd, IPPROTO_IP, IP_TTL, 1);
if (r < 0) if (r < 0)
return r; return r;
} else if (sa.sa.sa_family == AF_INET6) {
r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, 1);
if (r < 0)
return r;
}
} }
if (type == SOCK_DGRAM) { if (type == SOCK_DGRAM) {
/* Set IP_RECVERR or IPV6_RECVERR to get ICMP error feedback. See discussion in #10345. */ /* Set IP_RECVERR or IPV6_RECVERR to get ICMP error feedback. See discussion in #10345. */
r = socket_set_recverr(fd, sa.sa.sa_family, true);
if (sa.sa.sa_family == AF_INET) {
r = setsockopt_int(fd, IPPROTO_IP, IP_RECVERR, true);
if (r < 0) if (r < 0)
return r; return r;
r = socket_set_recvpktinfo(fd, sa.sa.sa_family, true); r = setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, true);
if (r < 0) if (r < 0)
return r; return r;
} else if (sa.sa.sa_family == AF_INET6) {
r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVERR, true);
if (r < 0)
return r;
r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, true);
if (r < 0)
return r;
}
} }
if (ret_socket_address) if (ret_socket_address)

View File

@ -190,10 +190,18 @@ static int dns_stream_identify(DnsStream *s) {
s->ifindex = manager_find_ifindex(s->manager, s->local.sa.sa_family, s->local.sa.sa_family == AF_INET ? (union in_addr_union*) &s->local.in.sin_addr : (union in_addr_union*) &s->local.in6.sin6_addr); s->ifindex = manager_find_ifindex(s->manager, s->local.sa.sa_family, s->local.sa.sa_family == AF_INET ? (union in_addr_union*) &s->local.in.sin_addr : (union in_addr_union*) &s->local.in6.sin6_addr);
if (s->protocol == DNS_PROTOCOL_LLMNR && s->ifindex > 0) { if (s->protocol == DNS_PROTOCOL_LLMNR && s->ifindex > 0) {
be32_t ifindex = htobe32(s->ifindex);
/* Make sure all packets for this connection are sent on the same interface */ /* Make sure all packets for this connection are sent on the same interface */
r = socket_set_unicast_if(s->fd, s->local.sa.sa_family, s->ifindex); if (s->local.sa.sa_family == AF_INET) {
r = setsockopt(s->fd, IPPROTO_IP, IP_UNICAST_IF, &ifindex, sizeof(ifindex));
if (r < 0) if (r < 0)
log_debug_errno(errno, "Failed to invoke IP_UNICAST_IF/IPV6_UNICAST_IF: %m"); log_debug_errno(errno, "Failed to invoke IP_UNICAST_IF: %m");
} else if (s->local.sa.sa_family == AF_INET6) {
r = setsockopt(s->fd, IPPROTO_IPV6, IPV6_UNICAST_IF, &ifindex, sizeof(ifindex));
if (r < 0)
log_debug_errno(errno, "Failed to invoke IPV6_UNICAST_IF: %m");
}
} }
s->identified = true; s->identified = true;

View File

@ -543,13 +543,23 @@ static int set_dns_stub_common_socket_options(int fd, int family) {
if (r < 0) if (r < 0)
return r; return r;
r = socket_set_recvpktinfo(fd, family, true); if (family == AF_INET) {
r = setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, true);
if (r < 0) if (r < 0)
return r; return r;
r = socket_set_recvttl(fd, family, true); r = setsockopt_int(fd, IPPROTO_IP, IP_RECVTTL, true);
if (r < 0) if (r < 0)
return r; return r;
} else {
r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, true);
if (r < 0)
return r;
r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, true);
if (r < 0)
return r;
}
return 0; return 0;
} }
@ -651,7 +661,10 @@ static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int ty
/* Do not set IP_TTL for extra DNS stub listners, as the address may not be local and in that case /* Do not set IP_TTL for extra DNS stub listners, as the address may not be local and in that case
* people may want ttl > 1. */ * people may want ttl > 1. */
r = socket_set_freebind(fd, l->family, true); if (l->family == AF_INET)
r = setsockopt_int(fd, IPPROTO_IP, IP_FREEBIND, true);
else
r = setsockopt_int(fd, IPPROTO_IPV6, IPV6_FREEBIND, true);
if (r < 0) if (r < 0)
goto fail; goto fail;

View File

@ -647,7 +647,6 @@ static int manager_listen_setup(Manager *m) {
if (r < 0) if (r < 0)
return r; return r;
if (addr.sa.sa_family == AF_INET)
(void) setsockopt_int(m->server_socket, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); (void) setsockopt_int(m->server_socket, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY);
return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m); return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m);