]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
socket: add support for opening socket pairs
authorMiroslav Lichvar <mlichvar@redhat.com>
Mon, 18 Nov 2019 17:08:47 +0000 (18:08 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 12 Dec 2019 12:03:31 +0000 (13:03 +0100)
socket.c
socket.h

index 7126fab9410612f9a9be407c618191b35abe16ba..acbc2c40e3fa45ed2b831d21dfaa7671dcd076a2 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -243,6 +243,30 @@ open_socket(int domain, int type, int flags)
 
 /* ================================================== */
 
+static int
+open_socket_pair(int domain, int type, int flags, int *other_fd)
+{
+  int sock_fds[2];
+
+  if (socketpair(domain, type | get_open_flags(flags), 0, sock_fds) < 0) {
+    DEBUG_LOG("Could not open %s socket : %s",
+              domain_to_string(domain), strerror(errno));
+    return INVALID_SOCK_FD;
+  }
+
+  if (!set_socket_flags(sock_fds[0], flags) || !set_socket_flags(sock_fds[1], flags)) {
+    close(sock_fds[0]);
+    close(sock_fds[1]);
+    return INVALID_SOCK_FD;
+  }
+
+  *other_fd = sock_fds[1];
+
+  return sock_fds[0];
+}
+
+/* ================================================== */
+
 static int
 set_socket_options(int sock_fd, int flags)
 {
@@ -520,6 +544,22 @@ error:
 
 /* ================================================== */
 
+static int
+open_unix_socket_pair(int type, int flags, int *other_fd)
+{
+  int sock_fd;
+
+  sock_fd = open_socket_pair(AF_UNIX, type, flags, other_fd);
+  if (sock_fd < 0)
+    return INVALID_SOCK_FD;
+
+  DEBUG_LOG("Opened Unix socket pair fd1=%d fd2=%d", sock_fd, *other_fd);
+
+  return sock_fd;
+}
+
+/* ================================================== */
+
 static int
 get_recv_flags(int flags)
 {
@@ -1159,6 +1199,25 @@ SCK_OpenUnixStreamSocket(const char *remote_addr, const char *local_addr, int fl
 
 /* ================================================== */
 
+int
+SCK_OpenUnixSocketPair(int flags, int *other_fd)
+{
+  int sock_fd;
+
+  /* Prefer SEQPACKET sockets over DGRAM in order to receive a zero-length
+     message (end of file) when the other end is unexpectedly closed */
+  if (
+#ifdef SOCK_SEQPACKET
+      (sock_fd = open_unix_socket_pair(SOCK_SEQPACKET, flags, other_fd)) < 0 &&
+#endif
+      (sock_fd = open_unix_socket_pair(SOCK_DGRAM, flags, other_fd)) < 0)
+    return INVALID_SOCK_FD;
+
+  return sock_fd;
+}
+
+/* ================================================== */
+
 int
 SCK_SetIntOption(int sock_fd, int level, int name, int value)
 {
index 47b9b5b5cad5dfc8ee9a2ab6436280bf2307dee6..9d4a38e3ecc1f452e0bdcdcb1b38c7ed7a96eac6 100644 (file)
--- a/socket.h
+++ b/socket.h
@@ -98,6 +98,7 @@ extern int SCK_OpenUnixDatagramSocket(const char *remote_addr, const char *local
                                       int flags);
 extern int SCK_OpenUnixStreamSocket(const char *remote_addr, const char *local_addr,
                                     int flags);
+extern int SCK_OpenUnixSocketPair(int flags, int *other_fd);
 
 /* Set and get a socket option of int size */
 extern int SCK_SetIntOption(int sock_fd, int level, int name, int value);