From 8de9f8f193c35acc2322abd846bfe79af2fdc85d Mon Sep 17 00:00:00 2001 From: Amaury Denoyelle Date: Mon, 19 Feb 2024 15:29:48 +0100 Subject: [PATCH] MINOR: quic: remove sendto() usage variant qc_snd_buf() is a wrapper around emission syscalls. Given QUIC configuration, a different variant is used. When using connection socket, send() is the only used. For listener sockets, sendmsg() and sendto() are possible. The first one is used only if local address has been retrieved prior. This allows to fix it on sending to guarantee the source address selection. Finally, sendto() is used for systems which do not support local address retrieval. All of these variants render the code too complex. As such, this patch simplifies this by removing sendto() alternative. Now, sendmsg() is always used for listener sockets. Source address is then specified only if supported by the system. This patch should not exhibit functional behavior changes. It will be useful when implementing GSO as the code is now simpler. --- src/quic_sock.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/quic_sock.c b/src/quic_sock.c index 14db339f5..45f6bb85c 100644 --- a/src/quic_sock.c +++ b/src/quic_sock.c @@ -670,11 +670,11 @@ int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t sz, 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)) { + else { struct msghdr msg; struct iovec vec; - struct cmsghdr *cmsg = NULL; + struct cmsghdr *cmsg __maybe_unused = NULL; + union { #ifdef IP_PKTINFO char buf[CMSG_SPACE(sizeof(struct in_pktinfo))]; @@ -684,27 +684,25 @@ int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t sz, #endif /* IPV6_RECVPKTINFO */ char bufaddr[CMSG_SPACE(sizeof(struct in_addr))]; struct cmsghdr align; - } u; + } ancillary_data; vec.iov_base = b_peek(buf, b_head_ofs(buf)); vec.iov_len = sz; + msg.msg_name = &qc->peer_addr; msg.msg_namelen = get_addr_len(&qc->peer_addr); msg.msg_iov = &vec; msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; - msg.msg_control = u.bufaddr; - cmsg_set_saddr(&msg, &cmsg, &qc->local_addr); + /* Set source address for listener socket if known. */ + if (is_addr(&qc->local_addr)) { + msg.msg_control = ancillary_data.bufaddr; + cmsg_set_saddr(&msg, &cmsg, &qc->local_addr); + } - ret = sendmsg(qc->li->rx.fd, &msg, - MSG_DONTWAIT|MSG_NOSIGNAL); - } -#endif /* IP_PKTINFO || IP_RECVDSTADDR || IPV6_RECVPKTINFO */ - else { - ret = sendto(qc->li->rx.fd, b_peek(buf, b_head_ofs(buf)), sz, - MSG_DONTWAIT|MSG_NOSIGNAL, - (struct sockaddr *)&qc->peer_addr, - get_addr_len(&qc->peer_addr)); + ret = sendmsg(qc->li->rx.fd, &msg, MSG_DONTWAIT|MSG_NOSIGNAL); } } while (ret < 0 && errno == EINTR);