mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 05:41:26 +02:00
MINOR: quic: only use sendmsg() syscall variant
This patch is the direct followup of the previous one : MINOR: quic: remove sendto() usage variant This finalizes qc_snd_buf() simplification by removing send() syscall usage for quic-conn owned socket. Syscall invocation is merged in a single code location to the sendmsg() variant. The only difference for owned socket is that destination address for sendmsg() is set to NULL. This usage is documented in man 2 sendmsg as valid for connected sockets. This allows maximum performance by avoiding unnecessary lookups on kernel socket address tables. As the previous patch, no functional change should happen here. However, it will be simpler to extend qc_snd_buf() for GSO usage.
This commit is contained in:
parent
8de9f8f193
commit
8b950f40fa
@ -72,6 +72,14 @@ static inline char qc_test_fd(struct quic_conn *qc)
|
|||||||
return qc->fd >= 0;
|
return qc->fd >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns active socket for <qc> connection. This may be its owned connection
|
||||||
|
* socket or the listener one as a fallback.
|
||||||
|
*/
|
||||||
|
static inline int qc_fd(struct quic_conn *qc)
|
||||||
|
{
|
||||||
|
return qc_test_fd(qc) ? qc->fd : qc->li->rx.fd;
|
||||||
|
}
|
||||||
|
|
||||||
/* Try to increment <l> handshake current counter. If listener limit is
|
/* Try to increment <l> handshake current counter. If listener limit is
|
||||||
* reached, incrementation is rejected and 0 is returned.
|
* reached, incrementation is rejected and 0 is returned.
|
||||||
*/
|
*/
|
||||||
|
@ -661,16 +661,6 @@ int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t sz,
|
|||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
if (qc_test_fd(qc) && !fd_send_ready(qc->fd))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (qc_test_fd(qc)) {
|
|
||||||
ret = send(qc->fd, b_peek(buf, b_head_ofs(buf)), sz,
|
|
||||||
MSG_DONTWAIT | MSG_NOSIGNAL);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec vec;
|
struct iovec vec;
|
||||||
struct cmsghdr *cmsg __maybe_unused = NULL;
|
struct cmsghdr *cmsg __maybe_unused = NULL;
|
||||||
@ -689,21 +679,39 @@ int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t sz,
|
|||||||
vec.iov_base = b_peek(buf, b_head_ofs(buf));
|
vec.iov_base = b_peek(buf, b_head_ofs(buf));
|
||||||
vec.iov_len = sz;
|
vec.iov_len = sz;
|
||||||
|
|
||||||
|
/* man 2 sendmsg
|
||||||
|
*
|
||||||
|
* The msg_name field is used on an unconnected socket to specify the
|
||||||
|
* target address for a datagram. It points to a buffer containing the
|
||||||
|
* address; the msg_namelen field should be set to the size of the
|
||||||
|
* address. For a connected socket, these fields should be specified
|
||||||
|
* as NULL and 0, respectively.
|
||||||
|
*/
|
||||||
|
if (!qc_test_fd(qc)) {
|
||||||
msg.msg_name = &qc->peer_addr;
|
msg.msg_name = &qc->peer_addr;
|
||||||
msg.msg_namelen = get_addr_len(&qc->peer_addr);
|
msg.msg_namelen = get_addr_len(&qc->peer_addr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg.msg_name = NULL;
|
||||||
|
msg.msg_namelen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
msg.msg_iov = &vec;
|
msg.msg_iov = &vec;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
msg.msg_control = NULL;
|
msg.msg_control = NULL;
|
||||||
msg.msg_controllen = 0;
|
msg.msg_controllen = 0;
|
||||||
|
|
||||||
/* Set source address for listener socket if known. */
|
if (qc_test_fd(qc) && !fd_send_ready(qc->fd))
|
||||||
if (is_addr(&qc->local_addr)) {
|
return 0;
|
||||||
|
|
||||||
|
/* Set source address when using listener socket if possible. */
|
||||||
|
if (!qc_test_fd(qc) && is_addr(&qc->local_addr)) {
|
||||||
msg.msg_control = ancillary_data.bufaddr;
|
msg.msg_control = ancillary_data.bufaddr;
|
||||||
cmsg_set_saddr(&msg, &cmsg, &qc->local_addr);
|
cmsg_set_saddr(&msg, &cmsg, &qc->local_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sendmsg(qc->li->rx.fd, &msg, MSG_DONTWAIT|MSG_NOSIGNAL);
|
do {
|
||||||
}
|
ret = sendmsg(qc_fd(qc), &msg, MSG_DONTWAIT|MSG_NOSIGNAL);
|
||||||
} while (ret < 0 && errno == EINTR);
|
} while (ret < 0 && errno == EINTR);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user