summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.socket.xml9
-rw-r--r--src/core/load-fragment-gperf.gperf.m41
-rw-r--r--src/core/load-fragment.c31
-rw-r--r--src/core/load-fragment.h1
-rw-r--r--src/core/socket.c13
-rw-r--r--src/core/socket.h2
6 files changed, 57 insertions, 0 deletions
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index beac053bf0..43841c2399 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -311,6 +311,15 @@
</varlistentry>
<varlistentry>
+ <term><varname>SocketProtocol=</varname></term>
+ <listitem><para>Takes a one of <option>udplite</option>
+ or <option>sctp</option>. Specifies a socket protocol
+ (<constant>IPPROTO_UDPLITE</constant>) UDP-Lite
+ (<constant>IPPROTO_SCTP</constant>) SCTP socket respectively. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>BindIPv6Only=</varname></term>
<listitem><para>Takes a one of <option>default</option>,
<option>both</option> or <option>ipv6-only</option>. Controls
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 799418033d..679d6dd81d 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -249,6 +249,7 @@ Socket.ListenNetlink, config_parse_socket_listen, SOCKET_SOCK
Socket.ListenSpecial, config_parse_socket_listen, SOCKET_SPECIAL, 0
Socket.ListenMessageQueue, config_parse_socket_listen, SOCKET_MQUEUE, 0
Socket.ListenUSBFunction, config_parse_socket_listen, SOCKET_USB_FUNCTION, 0
+Socket.SocketProtocol, config_parse_socket_protocol, 0, 0
Socket.BindIPv6Only, config_parse_socket_bind, 0, 0,
Socket.Backlog, config_parse_unsigned, 0, offsetof(Socket, backlog)
Socket.BindToDevice, config_parse_socket_bindtodevice, 0, 0
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index dda79267f7..d5cf476fda 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -421,6 +421,37 @@ int config_parse_socket_listen(const char *unit,
return 0;
}
+int config_parse_socket_protocol(const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+ Socket *s;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ s = SOCKET(data);
+
+ if (streq(rvalue, "udplite"))
+ s->socket_protocol = IPPROTO_UDPLITE;
+ else if (streq(rvalue, "sctp"))
+ s->socket_protocol = IPPROTO_SCTP;
+ else {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Socket protocol not supported, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ return 0;
+}
+
int config_parse_socket_bind(const char *unit,
const char *filename,
unsigned line,
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 62300c10f9..a451fc164a 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -38,6 +38,7 @@ int config_parse_unit_path_printf(const char *unit, const char *filename, unsign
int config_parse_unit_path_strv_printf(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_documentation(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_socket_listen(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_socket_protocol(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_socket_bind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_exec_nice(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_exec_oom_score_adjust(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/core/socket.c b/src/core/socket.c
index 5b9e32ce9d..687675b24e 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1266,6 +1266,19 @@ static int socket_open_fds(Socket *s) {
know_label = true;
}
+ /* Apply the socket protocol */
+ switch(p->address.type) {
+ case SOCK_STREAM:
+ case SOCK_SEQPACKET:
+ if (p->socket->socket_protocol == IPPROTO_SCTP)
+ p->address.protocol = p->socket->socket_protocol;
+ break;
+ case SOCK_DGRAM:
+ if (p->socket->socket_protocol == IPPROTO_UDPLITE)
+ p->address.protocol = p->socket->socket_protocol;
+ break;
+ }
+
r = socket_address_listen(
&p->address,
SOCK_CLOEXEC|SOCK_NONBLOCK,
diff --git a/src/core/socket.h b/src/core/socket.h
index 94cda8a90d..fb3948130f 100644
--- a/src/core/socket.h
+++ b/src/core/socket.h
@@ -120,6 +120,8 @@ struct Socket {
bool remove_on_stop;
bool writable;
+ int socket_protocol;
+
/* Socket options */
bool keep_alive;
bool no_delay;