]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: sock: start to move some generic socket code to sock.c
authorWilly Tarreau <w@1wt.eu>
Fri, 28 Aug 2020 10:07:22 +0000 (12:07 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 28 Aug 2020 16:51:36 +0000 (18:51 +0200)
The new file sock.c will contain generic code for standard sockets
relying on file descriptors. We currently have way too much duplication
between proto_uxst, proto_tcp, proto_sockpair and proto_udp.

For now only get_src, get_dst and sock_create_server_socket were moved,
and are used where appropriate.

Makefile
include/haproxy/proto_tcp.h
include/haproxy/proto_udp.h
include/haproxy/sock.h [new file with mode: 0644]
src/proto_tcp.c
src/proto_udp.c
src/proto_uxst.c
src/sock.c [new file with mode: 0644]

index 2372af21dcb86a95d304debcf2c56bf570c239b2..7649998df3b3aef07e7618b531da1a65f95f7d26 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -820,7 +820,7 @@ OBJS = src/mux_fcgi.o src/mux_h1.o src/mux_h2.o src/backend.o                 \
        src/eb64tree.o src/dict.o src/shctx.o src/ebimtree.o                   \
        src/eb32tree.o src/ebtree.o src/dgram.o src/proto_udp.o                \
        src/hpack-huff.o src/cfgparse-tcp.o src/base64.o src/version.o         \
-       src/cfgparse-unix.o
+       src/cfgparse-unix.o src/sock.o
 
 ifneq ($(TRACE),)
 OBJS += src/calltrace.o
index 38c02c73df00e5e09c4ac813d03fa61e4289df81..2e20309116050db479ba3cdac85154f870f02255 100644 (file)
@@ -31,7 +31,6 @@
 int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
 int tcp_pause_listener(struct listener *l);
 int tcp_connect_server(struct connection *conn, int flags);
-int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
 int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
 int tcp_is_foreign(int fd, sa_family_t family);
 
index 5e2516621833e238440c4197e52e0f59693b6091..31e6a90523779094e6e2b6bcc6b0dc8086476087 100644 (file)
@@ -27,6 +27,7 @@
 int udp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
 int udp_pause_listener(struct listener *l);
 int udp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
+int udp6_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
 int udp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
 
 #endif /* _PROTO_PROTO_UDP_H */
diff --git a/include/haproxy/sock.h b/include/haproxy/sock.h
new file mode 100644 (file)
index 0000000..79904e2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * include/haproxy/sock.h
+ * This file contains declarations for native (BSD-compatible) sockets.
+ *
+ * Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
+ *
+ * This library 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, version 2.1
+ * exclusively.
+ *
+ * This library 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 this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef _HAPROXY_SOCK_H
+#define _HAPROXY_SOCK_H
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <haproxy/api.h>
+#include <haproxy/connection-t.h>
+
+int sock_create_server_socket(struct connection *conn);
+int sock_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
+int sock_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
+
+#endif /* _HAPROXY_SOCK_H */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
index 7ab6b50ecdb866540fcd7b8a5ef6c84b76348926..5d1bc1ec7808ae11554aed60876fc5bb9272882e 100644 (file)
@@ -39,6 +39,7 @@
 #include <haproxy/proto_tcp.h>
 #include <haproxy/protocol.h>
 #include <haproxy/proxy-t.h>
+#include <haproxy/sock.h>
 #include <haproxy/tools.h>
 
 
@@ -62,7 +63,7 @@ static struct protocol proto_tcpv4 = {
        .bind_all = tcp_bind_listeners,
        .unbind_all = unbind_all_listeners,
        .enable_all = enable_all_listeners,
-       .get_src = tcp_get_src,
+       .get_src = sock_get_src,
        .get_dst = tcp_get_dst,
        .pause = tcp_pause_listener,
        .add = tcpv4_add_listener,
@@ -87,7 +88,7 @@ static struct protocol proto_tcpv6 = {
        .bind_all = tcp_bind_listeners,
        .unbind_all = unbind_all_listeners,
        .enable_all = enable_all_listeners,
-       .get_src = tcp_get_src,
+       .get_src = sock_get_src,
        .get_dst = tcp_get_dst,
        .pause = tcp_pause_listener,
        .add = tcpv6_add_listener,
@@ -226,22 +227,6 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
        return 0;
 }
 
-/* conn->dst MUST be valid */
-static int create_server_socket(struct connection *conn)
-{
-       const struct netns_entry *ns = NULL;
-
-#ifdef USE_NS
-       if (objt_server(conn->target)) {
-               if (__objt_server(conn->target)->flags & SRV_F_USE_NS_FROM_PP)
-                       ns = conn->proxy_netns;
-               else
-                       ns = __objt_server(conn->target)->netns;
-       }
-#endif
-       return my_socketat(ns, conn->dst->ss_family, SOCK_STREAM, IPPROTO_TCP);
-}
-
 /*
  * This function initiates a TCP connection establishment to the target assigned
  * to connection <conn> using (si->{target,dst}). A source address may be
@@ -310,7 +295,7 @@ int tcp_connect_server(struct connection *conn, int flags)
                return SF_ERR_INTERNAL;
        }
 
-       fd = conn->handle.fd = create_server_socket(conn);
+       fd = conn->handle.fd = sock_create_server_socket(conn);
 
        if (fd == -1) {
                qfprintf(stderr, "Cannot get a server socket.\n");
@@ -594,21 +579,6 @@ int tcp_connect_server(struct connection *conn, int flags)
 }
 
 
-/*
- * Retrieves the source address for the socket <fd>, with <dir> indicating
- * if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
- * success, -1 in case of error. The socket's source address is stored in
- * <sa> for <salen> bytes.
- */
-int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
-{
-       if (dir)
-               return getsockname(fd, sa, &salen);
-       else
-               return getpeername(fd, sa, &salen);
-}
-
-
 /*
  * Retrieves the original destination address for the socket <fd>, with <dir>
  * indicating if we're a listener (=0) or an initiator (!=0). In the case of a
index e2a854d2107a4bed62767db16982b84cb09e4aac..0c14817f5d7aa8db257ae808e3e3cb8515130245 100644 (file)
@@ -36,6 +36,7 @@
 #include <haproxy/proto_udp.h>
 #include <haproxy/proxy.h>
 #include <haproxy/server.h>
+#include <haproxy/sock.h>
 #include <haproxy/task.h>
 
 static int udp_bind_listeners(struct protocol *proto, char *errmsg, int errlen);
@@ -83,7 +84,7 @@ static struct protocol proto_udp6 = {
        .bind_all = udp_bind_listeners,
        .unbind_all = unbind_all_listeners,
        .enable_all = enable_all_listeners,
-       .get_src = udp_get_src,
+       .get_src = udp6_get_src,
        .get_dst = udp_get_dst,
        .pause = udp_pause_listener,
        .add = udp6_add_listener,
@@ -103,21 +104,29 @@ int udp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
 {
        int ret;
 
-       if (dir)
-               ret = getsockname(fd, sa, &salen);
-       else
-               ret = getpeername(fd, sa, &salen);
-
-       if (!ret) {
-               if (sa->sa_family == AF_INET)
-                       sa->sa_family = AF_CUST_UDP4;
-               else if (sa->sa_family == AF_INET6)
-                       sa->sa_family = AF_CUST_UDP6;
-       }
+       ret = sock_get_src(fd, sa, salen, dir);
+       if (!ret)
+               sa->sa_family = AF_CUST_UDP4;
 
        return ret;
 }
 
+/*
+ * Retrieves the source address for the socket <fd>, with <dir> indicating
+ * if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
+ * success, -1 in case of error. The socket's source address is stored in
+ * <sa> for <salen> bytes.
+ */
+int udp6_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
+{
+       int ret;
+
+       ret = sock_get_src(fd, sa, salen, dir);
+       if (!ret)
+               sa->sa_family = AF_CUST_UDP6;
+
+       return ret;
+}
 
 /*
  * Retrieves the original destination address for the socket <fd>, with <dir>
index f64c890ab28b510ead526861ff6df1842ab102d6..0e1cfc62a25b5b69d41207af8827a9e51eb8b9ad 100644 (file)
@@ -33,6 +33,7 @@
 #include <haproxy/listener.h>
 #include <haproxy/log.h>
 #include <haproxy/protocol.h>
+#include <haproxy/sock.h>
 #include <haproxy/time.h>
 #include <haproxy/tools.h>
 #include <haproxy/version.h>
@@ -44,8 +45,6 @@ static int uxst_unbind_listeners(struct protocol *proto);
 static int uxst_connect_server(struct connection *conn, int flags);
 static void uxst_add_listener(struct listener *listener, int port);
 static int uxst_pause_listener(struct listener *l);
-static int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
-static int uxst_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
 
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct protocol proto_unix = {
@@ -63,8 +62,8 @@ static struct protocol proto_unix = {
        .unbind_all = uxst_unbind_listeners,
        .enable_all = enable_all_listeners,
        .disable_all = disable_all_listeners,
-       .get_src = uxst_get_src,
-       .get_dst = uxst_get_dst,
+       .get_src = sock_get_src,
+       .get_dst = sock_get_dst,
        .pause = uxst_pause_listener,
        .add = uxst_add_listener,
        .listeners = LIST_HEAD_INIT(proto_unix.listeners),
@@ -77,35 +76,6 @@ INITCALL1(STG_REGISTER, protocol_register, &proto_unix);
  * 1) low-level socket functions
  ********************************/
 
-/*
- * Retrieves the source address for the socket <fd>, with <dir> indicating
- * if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
- * success, -1 in case of error. The socket's source address is stored in
- * <sa> for <salen> bytes.
- */
-static int uxst_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
-{
-       if (dir)
-               return getsockname(fd, sa, &salen);
-       else
-               return getpeername(fd, sa, &salen);
-}
-
-
-/*
- * Retrieves the original destination address for the socket <fd>, with <dir>
- * indicating if we're a listener (=0) or an initiator (!=0). It returns 0 in
- * case of success, -1 in case of error. The socket's source address is stored
- * in <sa> for <salen> bytes.
- */
-static int uxst_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
-{
-       if (dir)
-               return getpeername(fd, sa, &salen);
-       else
-               return getsockname(fd, sa, &salen);
-}
-
 
 /********************************
  * 2) listener-oriented functions
diff --git a/src/sock.c b/src/sock.c
new file mode 100644 (file)
index 0000000..2eb4b6f
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Generic code for native (BSD-compatible) sockets
+ *
+ * Copyright 2000-2020 Willy Tarreau <w@1wt.eu>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <haproxy/api.h>
+#include <haproxy/connection.h>
+#include <haproxy/namespace.h>
+#include <haproxy/sock.h>
+#include <haproxy/tools.h>
+
+
+/* Create a socket to connect to the server in conn->dst (which MUST be valid),
+ * using the configured namespace if needed, or the one passed by the proxy
+ * protocol if required to do so. It ultimately calls socket() or socketat()
+ * and returns the FD or error code.
+ */
+int sock_create_server_socket(struct connection *conn)
+{
+       const struct netns_entry *ns = NULL;
+
+#ifdef USE_NS
+       if (objt_server(conn->target)) {
+               if (__objt_server(conn->target)->flags & SRV_F_USE_NS_FROM_PP)
+                       ns = conn->proxy_netns;
+               else
+                       ns = __objt_server(conn->target)->netns;
+       }
+#endif
+       return my_socketat(ns, conn->dst->ss_family, SOCK_STREAM, 0);
+}
+
+/*
+ * Retrieves the source address for the socket <fd>, with <dir> indicating
+ * if we're a listener (=0) or an initiator (!=0). It returns 0 in case of
+ * success, -1 in case of error. The socket's source address is stored in
+ * <sa> for <salen> bytes.
+ */
+int sock_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir)
+{
+       if (dir)
+               return getsockname(fd, sa, &salen);
+       else
+               return getpeername(fd, sa, &salen);
+}
+
+/*
+ * Retrieves the original destination address for the socket <fd>, with <dir>
+ * indicating if we're a listener (=0) or an initiator (!=0). It returns 0 in
+ * case of success, -1 in case of error. The socket's source address is stored
+ * in <sa> for <salen> bytes.
+ */
+int sock_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir)
+{
+       if (dir)
+               return getpeername(fd, sa, &salen);
+       else
+               return getsockname(fd, sa, &salen);
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */