]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
OPTIM: quic: improve slightly qc_snd_buf() internal
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 20 Feb 2024 10:23:17 +0000 (11:23 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 20 Feb 2024 15:42:05 +0000 (16:42 +0100)
qc_snd_buf() is a wrapper for sendmsg() syscall (or its derivatives)
used for all QUIC emissions. This patch aims at removing several
non-optimal code sections :

* fd_send_ready() for connected sockets is only checked on the function
  preambule instead of inside the emission loop

* zero-ing msghdr structure for unconnected sockets is removed. This is
  unnecessary as all fields are properly initialized then.

* extra memcpy/memset invocations when using IP_PKTINFO/IPV6_RECVPKTINFO
  are removed by setting directly the address value into cmsg buffer

src/quic_sock.c

index f79651334b81ddd14370c4d2941f4b37b680ba51..47534beb3236c3ce337c114bd95b702e1d96de7e 100644 (file)
@@ -582,31 +582,31 @@ int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t sz,
 {
        ssize_t ret;
 
+       if (qc_test_fd(qc) && !fd_send_ready(qc->fd))
+               return 0;
+
        do {
                if (qc_test_fd(qc)) {
-                       if (!fd_send_ready(qc->fd))
-                               return 0;
-
                        ret = send(qc->fd, b_peek(buf, b_head_ofs(buf)), sz,
                                   MSG_DONTWAIT | MSG_NOSIGNAL);
                }
 #if defined(IP_PKTINFO) || defined(IP_RECVDSTADDR) || defined(IPV6_RECVPKTINFO)
                else if (is_addr(&qc->local_addr)) {
-                       struct msghdr msg = { 0 };
+                       struct msghdr msg;
                        struct iovec vec;
                        struct cmsghdr *cmsg;
 #ifdef IP_PKTINFO
-                       struct in_pktinfo in;
+                       struct in_pktinfo *in;
 #endif /* IP_PKTINFO */
 #ifdef IPV6_RECVPKTINFO
-                       struct in6_pktinfo in6;
+                       struct in6_pktinfo *in6;
 #endif /* IPV6_RECVPKTINFO */
                        union {
 #ifdef IP_PKTINFO
-                               char buf[CMSG_SPACE(sizeof(in))];
+                               char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
 #endif /* IP_PKTINFO */
 #ifdef IPV6_RECVPKTINFO
-                               char buf6[CMSG_SPACE(sizeof(in6))];
+                               char buf6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
 #endif /* IPV6_RECVPKTINFO */
                                char bufaddr[CMSG_SPACE(sizeof(struct in_addr))];
                                struct cmsghdr align;
@@ -622,19 +622,20 @@ int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t sz,
                        switch (qc->local_addr.ss_family) {
                        case AF_INET:
 #if defined(IP_PKTINFO)
-                               memset(&in, 0, sizeof(in));
-                               memcpy(&in.ipi_spec_dst,
-                                      &((struct sockaddr_in *)&qc->local_addr)->sin_addr,
-                                      sizeof(struct in_addr));
-
                                msg.msg_control = u.buf;
                                msg.msg_controllen = sizeof(u.buf);
 
                                cmsg = CMSG_FIRSTHDR(&msg);
+                               in = (struct in_pktinfo *)CMSG_DATA(cmsg);
+                               in->ipi_ifindex = 0;
+                               in->ipi_addr.s_addr = 0;
+                               memcpy(&in->ipi_spec_dst,
+                                      &((struct sockaddr_in *)&qc->local_addr)->sin_addr,
+                                      sizeof(struct in_addr));
+
                                cmsg->cmsg_level = IPPROTO_IP;
                                cmsg->cmsg_type = IP_PKTINFO;
                                cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
-                               memcpy(CMSG_DATA(cmsg), &in, sizeof(in));
 #elif defined(IP_RECVDSTADDR)
                                msg.msg_control = u.bufaddr;
                                msg.msg_controllen = sizeof(u.bufaddr);
@@ -651,19 +652,19 @@ int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t sz,
 
                        case AF_INET6:
 #ifdef IPV6_RECVPKTINFO
-                               memset(&in6, 0, sizeof(in6));
-                               memcpy(&in6.ipi6_addr,
-                                      &((struct sockaddr_in6 *)&qc->local_addr)->sin6_addr,
-                                      sizeof(struct in6_addr));
-
                                msg.msg_control = u.buf6;
                                msg.msg_controllen = sizeof(u.buf6);
 
                                cmsg = CMSG_FIRSTHDR(&msg);
+                               in6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
+                               in6->ipi6_ifindex = 0;
+                               memcpy(&in6->ipi6_addr,
+                                      &((struct sockaddr_in6 *)&qc->local_addr)->sin6_addr,
+                                      sizeof(struct in6_addr));
+
                                cmsg->cmsg_level = IPPROTO_IPV6;
                                cmsg->cmsg_type = IPV6_PKTINFO;
                                cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
-                               memcpy(CMSG_DATA(cmsg), &in6, sizeof(in6));
 #endif /* IPV6_RECVPKTINFO */
                                break;