<term><varname>$REMOTE_PORT</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>), these environment variables contain the IP address and
- port number of the remote peer of the socket connection.</para>
+ unit with <varname>Accept=yes</varname>), these environment variables contain information about the
+ remote peer of the socket connection.</para>
+
+ <para>For IPv4 and IPv6 connections, <varname>$REMOTE_ADDR</varname> contains the IP address, and
+ <varname>$REMOTE_PORT</varname> contains the port number of the remote peer.</para>
+
+ <para>For <constant>AF_UNIX</constant> socket connections, <varname>$REMOTE_ADDR</varname> contains
+ either the remote socket's file system path starting with a slash (<literal>/</literal>), its
+ address in the abstract namespace starting with an at symbol (<literal>@</literal>), or is unset
+ in case of an unnamed socket. <varname>$REMOTE_PORT</varname> is not set for <constant>AF_UNIX</constant>
+ sockets.</para>
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
</varlistentry>
services (in case of <varname>Accept=</varname><option>yes</option>). See the Description section
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
+ <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. For <constant>SOCK_RAW</constant>, the port is the IP
protocol.</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> won't be set.</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
cleaned up and released from memory, and do not accumulate.</para></listitem>
* in ENOTCONN), and just use whate we can use. */
if (getpeername(s->socket_fd, &sa.sa, &salen) >= 0 &&
- IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
+ IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK, AF_UNIX)) {
_cleanup_free_ char *addr = NULL;
char *t;
- unsigned port;
- r = sockaddr_pretty(&sa.sa, salen, true, false, &addr);
+ r = sockaddr_pretty(&sa.sa, salen, /* translate_ipv6= */ true, /* include_port= */ false, &addr);
if (r < 0)
return r;
- t = strjoin("REMOTE_ADDR=", addr);
- if (!t)
- return -ENOMEM;
- our_env[n_env++] = t;
+ if (sa.sa.sa_family != AF_UNIX || IN_SET(addr[0], '/', '@')) {
+ t = strjoin("REMOTE_ADDR=", addr);
+ if (!t)
+ return -ENOMEM;
+ our_env[n_env++] = t;
+ }
- r = sockaddr_port(&sa.sa, &port);
- if (r < 0)
- return r;
+ if (IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
+ unsigned port;
- if (asprintf(&t, "REMOTE_PORT=%u", port) < 0)
- return -ENOMEM;
- our_env[n_env++] = t;
+ r = sockaddr_port(&sa.sa, &port);
+ if (r < 0)
+ return r;
+
+ if (asprintf(&t, "REMOTE_PORT=%u", port) < 0)
+ return -ENOMEM;
+ our_env[n_env++] = t;
+ }
}
}