From e045e325df676108a5689231259bd6ecdae72909 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 23 Dec 2017 19:32:04 +0900 Subject: [PATCH] basic: introduce socket_protocol_{from,to}_name() And use them where they can be applicable. --- src/basic/generate-socket-protocol-list.sh | 5 ++ src/basic/meson.build | 12 ++++- src/basic/socket-protocol-list.c | 57 ++++++++++++++++++++++ src/basic/socket-protocol-list.h | 26 ++++++++++ src/basic/socket-protocol-to-name.awk | 9 ++++ src/core/dbus-socket.c | 12 +++-- src/core/load-fragment.c | 14 ++++-- src/core/socket.c | 21 ++++---- src/shared/bus-unit-util.c | 18 ++----- 9 files changed, 141 insertions(+), 33 deletions(-) create mode 100755 src/basic/generate-socket-protocol-list.sh create mode 100644 src/basic/socket-protocol-list.c create mode 100644 src/basic/socket-protocol-list.h create mode 100644 src/basic/socket-protocol-to-name.awk diff --git a/src/basic/generate-socket-protocol-list.sh b/src/basic/generate-socket-protocol-list.sh new file mode 100755 index 0000000000..18a540f32b --- /dev/null +++ b/src/basic/generate-socket-protocol-list.sh @@ -0,0 +1,5 @@ +#!/bin/sh -eu + +$1 -dM -include netinet/in.h - . +***/ + +#include +#include + +#include "socket-protocol-list.h" +#include "macro.h" + +static const struct socket_protocol_name* lookup_socket_protocol(register const char *str, register GPERF_LEN_TYPE len); + +#include "socket-protocol-from-name.h" +#include "socket-protocol-to-name.h" + +const char *socket_protocol_to_name(int id) { + + if (id < 0) + return NULL; + + if (id >= (int) ELEMENTSOF(socket_protocol_names)) + return NULL; + + return socket_protocol_names[id]; +} + +int socket_protocol_from_name(const char *name) { + const struct socket_protocol_name *sc; + + assert(name); + + sc = lookup_socket_protocol(name, strlen(name)); + if (!sc) + return 0; + + return sc->id; +} + +int socket_protocol_max(void) { + return ELEMENTSOF(socket_protocol_names); +} diff --git a/src/basic/socket-protocol-list.h b/src/basic/socket-protocol-list.h new file mode 100644 index 0000000000..12fd053382 --- /dev/null +++ b/src/basic/socket-protocol-list.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2014 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +const char *socket_protocol_to_name(int id); +int socket_protocol_from_name(const char *name); + +int socket_protocol_max(void); diff --git a/src/basic/socket-protocol-to-name.awk b/src/basic/socket-protocol-to-name.awk new file mode 100644 index 0000000000..4848a7631a --- /dev/null +++ b/src/basic/socket-protocol-to-name.awk @@ -0,0 +1,9 @@ +BEGIN{ + print "static const char* const socket_protocol_names[] = { " +} +!/HOPOPTS/ { + printf " [IPPROTO_%s] = \"%s\",\n", $1, tolower($1) +} +END{ + print "};" +} diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 6c5d5944fc..26ab6b9ea5 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -28,6 +28,7 @@ #include "parse-util.h" #include "path-util.h" #include "socket.h" +#include "socket-protocol-list.h" #include "socket-util.h" #include "string-util.h" #include "unit.h" @@ -268,18 +269,23 @@ static int bus_socket_set_transient_property( return 1; } else if (streq(name, "SocketProtocol")) { + const char *p; int32_t i; r = sd_bus_message_read(message, "i", &i); if (r < 0) return r; - if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP)) + p = socket_protocol_to_name(i); + if (!p) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %i", name, i); + if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported socket protocol: %s", p); + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { s->socket_protocol = i; - unit_write_settingf(u, flags, name, "%s=%s", name, i == IPPROTO_UDPLITE ? "udplite" : "sctp"); + unit_write_settingf(u, flags, name, "%s=%s", name, p); } return 1; @@ -557,7 +563,7 @@ static int bus_socket_set_transient_property( if (!p) return log_oom(); - p->type = socket_type_from_string(t); + p->type = socket_port_type_from_string(t); if (p->type < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown Socket type: %s", t); diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 469b2fc2b4..28920e4a4f 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -64,6 +64,7 @@ #include "securebits.h" #include "securebits-util.h" #include "signal-util.h" +#include "socket-protocol-list.h" #include "stat-util.h" #include "string-util.h" #include "strv.h" @@ -454,6 +455,7 @@ int config_parse_socket_protocol(const char *unit, void *data, void *userdata) { Socket *s; + int r; assert(filename); assert(lvalue); @@ -462,15 +464,17 @@ int config_parse_socket_protocol(const char *unit, s = SOCKET(data); - if (streq(rvalue, "udplite")) - s->socket_protocol = IPPROTO_UDPLITE; - else if (streq(rvalue, "sctp")) - s->socket_protocol = IPPROTO_SCTP; - else { + r = socket_protocol_from_name(rvalue); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid socket protocol, ignoring: %s", rvalue); + return 0; + } else if (!IN_SET(r, IPPROTO_UDPLITE, IPPROTO_SCTP)) { log_syntax(unit, LOG_ERR, filename, line, 0, "Socket protocol not supported, ignoring: %s", rvalue); return 0; } + s->socket_protocol = r; + return 0; } diff --git a/src/core/socket.c b/src/core/socket.c index 553bbe9f76..d45b528985 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -53,6 +53,7 @@ #include "signal-util.h" #include "smack-util.h" #include "socket.h" +#include "socket-protocol-list.h" #include "special.h" #include "string-table.h" #include "string-util.h" @@ -2783,16 +2784,16 @@ const char* socket_port_type_to_string(SocketPort *p) { SocketType socket_port_type_from_string(const char *s) { assert(s); - if (STR_IN_SET(t, "Stream", "Datagram", "SequentialPacket", "Netlink")) - return = SOCKET_SOCKET; - else if (streq(t, "Special")) - return = SOCKET_SPECIAL; - else if (streq(t, "MessageQueue")) - return = SOCKET_MQUEUE; - else if (streq(t, "FIFO")) - return = SOCKET_FIFO; - else if (streq(t, "USBFunction")) - return = SOCKET_USB_FUNCTION; + if (STR_IN_SET(s, "Stream", "Datagram", "SequentialPacket", "Netlink")) + return SOCKET_SOCKET; + else if (streq(s, "Special")) + return SOCKET_SPECIAL; + else if (streq(s, "MessageQueue")) + return SOCKET_MQUEUE; + else if (streq(s, "FIFO")) + return SOCKET_FIFO; + else if (streq(s, "USBFunction")) + return SOCKET_USB_FUNCTION; else return _SOCKET_TYPE_INVALID; } diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index 805ad30c7a..b9224bb23c 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -42,6 +42,7 @@ #include "rlimit-util.h" #include "securebits-util.h" #include "signal-util.h" +#include "socket-protocol-list.h" #include "string-util.h" #include "syslog-util.h" #include "terminal-util.h" @@ -113,6 +114,7 @@ DEFINE_BUS_APPEND_PARSE("i", parse_errno) DEFINE_BUS_APPEND_PARSE("i", sched_policy_from_string) DEFINE_BUS_APPEND_PARSE("i", secure_bits_from_string) DEFINE_BUS_APPEND_PARSE("i", signal_from_string_try_harder) +DEFINE_BUS_APPEND_PARSE("i", socket_protocol_from_name) DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, ioprio_parse_priority) DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, parse_nice) DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, safe_atoi) @@ -1250,21 +1252,9 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons return bus_append_strv(m, field, eq, EXTRACT_QUOTES); - if (streq(field, "SocketProtocol")) { + if (streq(field, "SocketProtocol")) - if (streq(eq, "udplite")) - r = sd_bus_message_append(m, "(sv)", field, "i", IPPROTO_UDPLITE); - else if (streq(eq, "sctp")) - r = sd_bus_message_append(m, "(sv)", field, "i", IPPROTO_SCTP); - else { - log_error("Unsupported Socket protocol: %s", eq); - return -EINVAL; - } - if (r < 0) - return bus_log_create_error(r); - - return 1; - } + return bus_append_socket_protocol_from_name(m, field, eq); if (STR_IN_SET(field, "ListenStream", "ListenDatagram", "ListenSequentialPacket", "ListenNetlink",