mirror of
https://github.com/systemd/systemd.git
synced 2024-10-27 01:55:22 +03:00
Allow interface scopes to be specified in ListenStream=
Closes #12624. The formatting in systemd.socket.xml is updated a bit. Currently in_addr_port_ifindex_name_to_string() always prints the ifindex numerically. This is not super useful since the interface numbers are semi-random. Should we use interface names in preference?
This commit is contained in:
parent
c4c6ee3a95
commit
a07ab56a49
@ -200,22 +200,24 @@
|
||||
</para>
|
||||
|
||||
<para>If the address string is a string in the format
|
||||
v.w.x.y:z, it is read as IPv4 specifier for listening on an
|
||||
address v.w.x.y on a port z.</para>
|
||||
|
||||
<para>If the address string is a string in the format [x]:y,
|
||||
it is read as IPv6 address x on a port y. Note that this might
|
||||
make the service available via IPv4, too, depending on the
|
||||
<varname>BindIPv6Only=</varname> setting (see below).
|
||||
</para>
|
||||
<literal><replaceable>v.w.x.y</replaceable>:<replaceable>z</replaceable></literal>, it is interpeted
|
||||
as IPv4 address <replaceable>v.w.x.y</replaceable> and port <replaceable>z</replaceable>.</para>
|
||||
|
||||
<para>If the address string is a string in the format
|
||||
<literal>vsock:x:y</literal>, it is read as CID <literal>x</literal> on
|
||||
a port <literal>y</literal> address in the
|
||||
<constant>AF_VSOCK</constant> family. The CID is a unique 32-bit
|
||||
integer identifier in <constant>AF_VSOCK</constant> analogous to an IP
|
||||
address. Specifying the CID is optional, and may be set to the empty
|
||||
string.</para>
|
||||
<literal>[<replaceable>x</replaceable>]:<replaceable>y</replaceable></literal>, it is interpreted as
|
||||
IPv6 address <replaceable>x</replaceable> and port <replaceable>y</replaceable>. An optional
|
||||
interface scope (interface name or number) may be specifed after a <literal>%</literal> symbol:
|
||||
<literal>[<replaceable>x</replaceable>]:<replaceable>y</replaceable>%<replaceable>dev</replaceable></literal>.
|
||||
Interface scopes are only useful with link-local addresses, because the kernel ignores them in other
|
||||
cases. Note that if an address is specified as IPv6, it might still make the service available via
|
||||
IPv4 too, depending on the <varname>BindIPv6Only=</varname> setting (see below).</para>
|
||||
|
||||
<para>If the address string is a string in the format
|
||||
<literal>vsock:<replaceable>x</replaceable>:<replaceable>y</replaceable></literal>, it is read as CID
|
||||
<replaceable>x</replaceable> on a port <replaceable>y</replaceable> address in the
|
||||
<constant>AF_VSOCK</constant> family. The CID is a unique 32-bit integer identifier in
|
||||
<constant>AF_VSOCK</constant> analogous to an IP address. Specifying the CID is optional, and may be
|
||||
set to the empty string.</para>
|
||||
|
||||
<para>Note that <constant>SOCK_SEQPACKET</constant> (i.e.
|
||||
<varname>ListenSequentialPacket=</varname>) is only available
|
||||
|
@ -157,9 +157,9 @@ int socket_address_parse(SocketAddress *a, const char *s) {
|
||||
|
||||
} else {
|
||||
union in_addr_union address;
|
||||
int family;
|
||||
int family, ifindex;
|
||||
|
||||
r = in_addr_port_ifindex_name_from_string_auto(s, &family, &address, &port, NULL, NULL);
|
||||
r = in_addr_port_ifindex_name_from_string_auto(s, &family, &address, &port, &ifindex, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -181,6 +181,7 @@ int socket_address_parse(SocketAddress *a, const char *s) {
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_addr = address.in6,
|
||||
.sin6_port = htobe16(port),
|
||||
.sin6_scope_id = ifindex,
|
||||
},
|
||||
.size = sizeof(struct sockaddr_in6),
|
||||
};
|
||||
|
@ -59,11 +59,21 @@ static void test_socket_address_parse(void) {
|
||||
test_socket_address_parse_one("[::1]:0", -EINVAL, 0, NULL);
|
||||
test_socket_address_parse_one("[::1]:65536", -ERANGE, 0, NULL);
|
||||
test_socket_address_parse_one("[a:b:1]:8888", -EINVAL, 0, NULL);
|
||||
test_socket_address_parse_one("[::1]%lo:1234", -EINVAL, 0, NULL);
|
||||
test_socket_address_parse_one("[::1]%lo:0", -EINVAL, 0, NULL);
|
||||
test_socket_address_parse_one("[::1]%lo", -EINVAL, 0, NULL);
|
||||
test_socket_address_parse_one("[::1]%lo%lo:1234", -EINVAL, 0, NULL);
|
||||
test_socket_address_parse_one("[::1]% lo:1234", -EINVAL, 0, NULL);
|
||||
|
||||
test_socket_address_parse_one("8888", 0, default_family, "[::]:8888");
|
||||
test_socket_address_parse_one("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888", 0, AF_INET6,
|
||||
"[2001:db8:0:85a3::ac1f:8001]:8888");
|
||||
test_socket_address_parse_one("[::1]:8888", 0, AF_INET6, NULL);
|
||||
test_socket_address_parse_one("[::1]:1234%lo", 0, AF_INET6, NULL);
|
||||
test_socket_address_parse_one("[::1]:0%lo", -EINVAL, 0, NULL);
|
||||
test_socket_address_parse_one("[::1]%lo", -EINVAL, 0, NULL);
|
||||
test_socket_address_parse_one("[::1]:1234%lo%lo", -ENODEV, 0, NULL);
|
||||
test_socket_address_parse_one("[::1]:1234%xxxxasdf", -ENODEV, 0, NULL);
|
||||
test_socket_address_parse_one("192.168.1.254:8888", 0, AF_INET, NULL);
|
||||
test_socket_address_parse_one("/foo/bar", 0, AF_UNIX, NULL);
|
||||
test_socket_address_parse_one("/", 0, AF_UNIX, NULL);
|
||||
@ -297,7 +307,8 @@ static void test_in_addr_ifindex_name_from_string_auto(void) {
|
||||
test_in_addr_ifindex_name_from_string_auto_one("fe80::18%19#another.test.com", "another.test.com");
|
||||
}
|
||||
|
||||
static void test_in_addr_port_ifindex_name_from_string_auto_one(const char *str, int family, uint16_t port, int ifindex, const char *server_name) {
|
||||
static void test_in_addr_port_ifindex_name_from_string_auto_one(const char *str, int family, uint16_t port, int ifindex,
|
||||
const char *server_name, const char *str_repr) {
|
||||
union in_addr_union a;
|
||||
uint16_t p;
|
||||
int f, i;
|
||||
@ -313,7 +324,7 @@ static void test_in_addr_port_ifindex_name_from_string_auto_one(const char *str,
|
||||
assert_se(ifindex == i);
|
||||
assert_se(streq_ptr(server_name, name));
|
||||
assert_se(in_addr_port_ifindex_name_to_string(f, &a, p, i, name, &x) >= 0);
|
||||
assert_se(streq(str, x));
|
||||
assert_se(streq(str_repr ?: str, x));
|
||||
}
|
||||
|
||||
if (port > 0)
|
||||
@ -325,7 +336,7 @@ static void test_in_addr_port_ifindex_name_from_string_auto_one(const char *str,
|
||||
assert_se(ifindex == i);
|
||||
assert_se(streq_ptr(server_name, name));
|
||||
assert_se(in_addr_port_ifindex_name_to_string(f, &a, 0, i, name, &x) >= 0);
|
||||
assert_se(streq(str, x));
|
||||
assert_se(streq(str_repr ?: str, x));
|
||||
}
|
||||
|
||||
if (ifindex > 0)
|
||||
@ -337,7 +348,7 @@ static void test_in_addr_port_ifindex_name_from_string_auto_one(const char *str,
|
||||
assert_se(port == p);
|
||||
assert_se(streq_ptr(server_name, name));
|
||||
assert_se(in_addr_port_ifindex_name_to_string(f, &a, p, 0, name, &x) >= 0);
|
||||
assert_se(streq(str, x));
|
||||
assert_se(streq(str_repr ?: str, x));
|
||||
}
|
||||
|
||||
if (server_name)
|
||||
@ -349,25 +360,30 @@ static void test_in_addr_port_ifindex_name_from_string_auto_one(const char *str,
|
||||
assert_se(port == p);
|
||||
assert_se(ifindex == i);
|
||||
assert_se(in_addr_port_ifindex_name_to_string(f, &a, p, i, NULL, &x) >= 0);
|
||||
assert_se(streq(str, x));
|
||||
assert_se(streq(str_repr ?: str, x));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_in_addr_port_ifindex_name_from_string_auto(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1", AF_INET, 0, 0, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1#test.com", AF_INET, 0, 0, "test.com");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1:53", AF_INET, 53, 0, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1:53#example.com", AF_INET, 53, 0, "example.com");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18", AF_INET6, 0, 0, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18#hoge.com", AF_INET6, 0, 0, "hoge.com");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%19", AF_INET6, 0, 19, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53", AF_INET6, 53, 0, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%19#hoge.com", AF_INET6, 0, 19, "hoge.com");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53#hoge.com", AF_INET6, 53, 0, "hoge.com");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19", AF_INET6, 53, 19, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19#hoge.com", AF_INET6, 53, 19, "hoge.com");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1", AF_INET, 0, 0, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1#test.com", AF_INET, 0, 0, "test.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1:53", AF_INET, 53, 0, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("192.168.0.1:53#example.com", AF_INET, 53, 0, "example.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18", AF_INET6, 0, 0, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18#hoge.com", AF_INET6, 0, 0, "hoge.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%19", AF_INET6, 0, 19, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%lo", AF_INET6, 0, 1, NULL, "fe80::18%1");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53", AF_INET6, 53, 0, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19", AF_INET6, 53, 19, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%lo", AF_INET6, 53, 1, NULL, "[fe80::18]:53%1");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("fe80::18%19#hoge.com", AF_INET6, 0, 19, "hoge.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53#hoge.com", AF_INET6, 53, 0, "hoge.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19", AF_INET6, 53, 19, NULL, NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%19#hoge.com", AF_INET6, 53, 19, "hoge.com", NULL);
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%lo", AF_INET6, 53, 1, NULL, "[fe80::18]:53%1");
|
||||
test_in_addr_port_ifindex_name_from_string_auto_one("[fe80::18]:53%lo#hoge.com", AF_INET6, 53, 1, "hoge.com", "[fe80::18]:53%1#hoge.com");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
Loading…
Reference in New Issue
Block a user