]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: pass the socket cookie to invoked per-connection service instances as $SO_COOKI...
authorLennart Poettering <lennart@poettering.net>
Thu, 15 May 2025 07:15:46 +0000 (09:15 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 15 May 2025 07:45:32 +0000 (09:45 +0200)
The socket cookie is just too useful for identifying connections, let's
emphasize this a bit and pass it as environment variable.

man/systemd.exec.xml
man/systemd.socket.xml
src/core/service.c

index 829149f561cc7009ebed7305765e5f6c9d5da7f6..a63700afb3313059ad58c8d38942ea4061b938b9 100644 (file)
@@ -4412,6 +4412,17 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
           <xi:include href="version-info.xml" xpointer="v220"/></listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><varname>$SO_COOKIE</varname></term>
+
+          <listitem><para>If this is a unit started via per-connection socket activation (i.e. via a socket
+          unit with <varname>Accept=yes</varname>), this environment variable contains the Linux socket
+          cookie, formatted as decimal integer. The socket cookie can otherwise be acquired via <citerefentry
+          project='man-pages'><refentrytitle>getsockopt</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+
+          <xi:include href="version-info.xml" xpointer="v258"/></listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><varname>$TRIGGER_UNIT</varname></term>
           <term><varname>$TRIGGER_PATH</varname></term>
index acec1f1047f105902391a74e0622d9c3c56adcde..39bd0dd62625bdbdaeb0fda47f153c8e96e7c3f9 100644 (file)
         above for a more detailed discussion of the naming rules of triggered services.</para>
 
         <para>For IPv4 and IPv6 connections, the <varname>$REMOTE_ADDR</varname> environment variable will
-        contain the remote IP address, and <varname>$REMOTE_PORT</varname> will contain the remote port. This
-        is the same as the format used by CGI.</para>
+        contain the remote IP address, and <varname>$REMOTE_PORT</varname> will contain the remote port
+        number. These two variables correspond to those defined by the CGI interface for web services (see
+        <ulink url="https://datatracker.ietf.org/doc/html/rfc3875">RFC 3875</ulink>).</para>
 
         <para>For <constant>AF_UNIX</constant> socket connections, the <varname>$REMOTE_ADDR</varname>
         environment variable will contain either the remote socket's file system path starting with a slash
         (<literal>/</literal>) or its address in the abstract namespace starting with an at symbol
-        (<literal>@</literal>). If the socket is unnamed, <varname>$REMOTE_ADDR</varname> will not be set.</para>
+        (<literal>@</literal>). If the socket is unnamed, <varname>$REMOTE_ADDR</varname> will not be
+        set.</para>
+
+        <para>The <varname>$SO_COOKIE</varname> environment variable is set to the Linux socket cookie,
+        formatted as decimal integer. The socket cookie can otherwise be acquired via <citerefentry
+        project='man-pages'><refentrytitle>getsockopt</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
 
         <para>It is recommended to set <varname>CollectMode=inactive-or-failed</varname> for service
         instances activated via <varname>Accept=yes</varname>, to ensure that failed connection services are
index 141c85745a19e0667515c49468f55ebcca647430..46e8ff6239ea22d8c29b6fc00f6e0a324b1ca72c 100644 (file)
@@ -1749,7 +1749,7 @@ static int service_spawn_internal(
         if (r < 0)
                 return r;
 
-        our_env = new0(char*, 15);
+        our_env = new0(char*, 16);
         if (!our_env)
                 return -ENOMEM;
 
@@ -1821,6 +1821,14 @@ static int service_spawn_internal(
                                 our_env[n_env++] = t;
                         }
                 }
+
+                uint64_t cookie;
+                if (socket_get_cookie(s->socket_fd, &cookie) >= 0) {
+                        char *t;
+                        if (asprintf(&t, "SO_COOKIE=%" PRIu64, cookie) < 0)
+                                return -ENOMEM;
+                        our_env[n_env++] = t;
+                }
         }
 
         Service *env_source = NULL;