]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Redefine control layer callbacks which are QUIC specific.
authorFrédéric Lécaille <flecaille@haproxy.com>
Fri, 6 Nov 2020 14:49:49 +0000 (15:49 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 23 Dec 2020 10:57:26 +0000 (11:57 +0100)
We add src/quic_sock.c QUIC specific socket management functions as callbacks
for the control layer: ->accept_conn, ->default_iocb and ->rx_listening.
accept_conn() will have to be defined. The default I/O handler only recvfrom()
the datagrams received. Furthermore, ->rx_listening callback always returns 1 at
this time but should returns 0 when reloading the processus.

include/haproxy/quic_sock.h [new file with mode: 0644]
src/proto_quic.c
src/quic_sock.c [new file with mode: 0644]

diff --git a/include/haproxy/quic_sock.h b/include/haproxy/quic_sock.h
new file mode 100644 (file)
index 0000000..78623e8
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * include/haproxy/quic_sock.h
+ * This file contains declarations for QUIC sockets.
+ *
+ * Copyright 2020 Frédéric Lécaille <flecaille@haproxy.com>
+ *
+ * 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_QUIC_SOCK_H
+#define _HAPROXY_QUIC_SOCK_H
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <haproxy/api.h>
+#include <haproxy/connection-t.h>
+#include <haproxy/listener-t.h>
+
+int quic_sock_accepting_conn(const struct receiver *rx);
+struct connection *quic_sock_accept_conn(struct listener *l, int *status);
+void quic_sock_fd_iocb(int fd);
+
+#endif /* _HAPROXY_QUIC_SOCK_H */
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ * End:
+ */
index bde3e4859a120cb26ca5d7f628312295210b73ea..751fc49aac625c4ae6c0e1e763d60b2d042aaca4 100644 (file)
@@ -41,6 +41,7 @@
 #include <haproxy/proto_udp.h>
 #include <haproxy/proxy-t.h>
 #include <haproxy/sock.h>
+#include <haproxy/quic_sock.h>
 #include <haproxy/sock_inet.h>
 #include <haproxy/tools.h>
 
@@ -63,7 +64,7 @@ struct protocol proto_quic4 = {
        .unbind         = default_unbind_listener,
        .suspend        = default_suspend_listener,
        .resume         = default_resume_listener,
-       .accept_conn    = sock_accept_conn,
+       .accept_conn    = quic_sock_accept_conn,
        .connect        = quic_connect_server,
 
        /* binding layer */
@@ -79,8 +80,8 @@ struct protocol proto_quic4 = {
        .rx_enable      = sock_enable,
        .rx_disable     = sock_disable,
        .rx_unbind      = sock_unbind,
-       .rx_listening   = sock_accepting_conn,
-       .default_iocb   = sock_accept_iocb,
+       .rx_listening   = quic_sock_accepting_conn,
+       .default_iocb   = quic_sock_fd_iocb,
        .receivers      = LIST_HEAD_INIT(proto_quic4.receivers),
        .nb_receivers   = 0,
 };
@@ -100,7 +101,7 @@ struct protocol proto_quic6 = {
        .unbind         = default_unbind_listener,
        .suspend        = default_suspend_listener,
        .resume         = default_resume_listener,
-       .accept_conn    = sock_accept_conn,
+       .accept_conn    = quic_sock_accept_conn,
        .connect        = quic_connect_server,
 
        /* binding layer */
@@ -116,8 +117,8 @@ struct protocol proto_quic6 = {
        .rx_enable      = sock_enable,
        .rx_disable     = sock_disable,
        .rx_unbind      = sock_unbind,
-       .rx_listening   = sock_accepting_conn,
-       .default_iocb   = sock_accept_iocb,
+       .rx_listening   = quic_sock_accepting_conn,
+       .default_iocb   = quic_sock_fd_iocb,
        .receivers      = LIST_HEAD_INIT(proto_quic6.receivers),
        .nb_receivers   = 0,
 };
diff --git a/src/quic_sock.c b/src/quic_sock.c
new file mode 100644 (file)
index 0000000..374e97b
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * QUIC socket management.
+ *
+ * Copyright 2020 HAProxy Technologies, Frédéric Lécaille <flecaille@haproxy.com>
+ *
+ * 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 <errno.h>
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <haproxy/connection.h>
+#include <haproxy/listener.h>
+
+/* Tests if the receiver supports accepting connections. Returns positive on
+ * success, 0 if not possible
+ */
+int quic_sock_accepting_conn(const struct receiver *rx)
+{
+       return 1;
+}
+
+/* Accept an incoming connection from listener <l>, and return it, as well as
+ * a CO_AC_* status code into <status> if not null. Null is returned on error.
+ * <l> must be a valid listener with a valid frontend.
+ */
+struct connection *quic_sock_accept_conn(struct listener *l, int *status)
+{
+       /* TO DO */
+       return NULL;
+}
+
+/* Function called on a read event from a listening socket. It tries
+ * to handle as many connections as possible.
+ */
+void quic_sock_fd_iocb(int fd)
+{
+       ssize_t ret;
+       struct buffer *buf;
+       struct listener *l = objt_listener(fdtab[fd].owner);
+       /* Source address */
+       struct sockaddr_storage saddr = {0};
+       socklen_t saddrlen;
+
+       if (!l)
+               ABORT_NOW();
+
+       if (!(fdtab[fd].ev & FD_POLL_IN) || !fd_recv_ready(fd))
+               return;
+
+       buf = get_trash_chunk();
+       saddrlen = sizeof saddr;
+       do {
+               ret = recvfrom(fd, buf->area, buf->size, 0,
+                              (struct sockaddr *)&saddr, &saddrlen);
+               if (ret < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       if (errno == EAGAIN)
+                               fd_cant_recv(fd);
+                       return;
+               }
+       } while (0);
+
+       buf->data = ret;
+}