ngtcp2: avoid supplying 0 length `msg_control` to sendmsg()
Testing on macOS 12.4, sendmsg() fails with EINVAL when a msg_control buffer is provided in sengmsg(), even though msg_controllen was set to 0. Initialize msg.msg_controllen just as needed and also perform the size assertion only when needed. Closes #9039
This commit is contained in:
Родитель
71bbabb167
Коммит
8135d420ee
|
@ -1653,25 +1653,22 @@ static CURLcode do_sendmsg(size_t *psent, struct Curl_easy *data, int sockfd,
|
||||||
struct iovec msg_iov = {(void *)pkt, pktlen};
|
struct iovec msg_iov = {(void *)pkt, pktlen};
|
||||||
struct msghdr msg = {0};
|
struct msghdr msg = {0};
|
||||||
uint8_t msg_ctrl[32];
|
uint8_t msg_ctrl[32];
|
||||||
size_t ctrllen = 0;
|
|
||||||
ssize_t sent;
|
ssize_t sent;
|
||||||
#if defined(__linux__) && defined(UDP_SEGMENT)
|
#if defined(__linux__) && defined(UDP_SEGMENT)
|
||||||
struct cmsghdr *cm;
|
struct cmsghdr *cm;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*psent = 0;
|
*psent = 0;
|
||||||
|
|
||||||
assert(sizeof(msg_ctrl) >= CMSG_SPACE(sizeof(uint16_t)));
|
|
||||||
|
|
||||||
msg.msg_iov = &msg_iov;
|
msg.msg_iov = &msg_iov;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
|
|
||||||
msg.msg_control = msg_ctrl;
|
|
||||||
msg.msg_controllen = sizeof(msg_ctrl);
|
|
||||||
|
|
||||||
#if defined(__linux__) && defined(UDP_SEGMENT)
|
#if defined(__linux__) && defined(UDP_SEGMENT)
|
||||||
if(pktlen > gsolen) {
|
if(pktlen > gsolen) {
|
||||||
ctrllen += CMSG_SPACE(sizeof(uint16_t));
|
/* Only set this, when we need it. macOS, for example,
|
||||||
|
* does not seem to like a msg_control of length 0. */
|
||||||
|
msg.msg_control = msg_ctrl;
|
||||||
|
assert(sizeof(msg_ctrl) >= CMSG_SPACE(sizeof(uint16_t)));
|
||||||
|
msg.msg_controllen = CMSG_SPACE(sizeof(uint16_t));
|
||||||
cm = CMSG_FIRSTHDR(&msg);
|
cm = CMSG_FIRSTHDR(&msg);
|
||||||
cm->cmsg_level = SOL_UDP;
|
cm->cmsg_level = SOL_UDP;
|
||||||
cm->cmsg_type = UDP_SEGMENT;
|
cm->cmsg_type = UDP_SEGMENT;
|
||||||
|
@ -1680,7 +1677,6 @@ static CURLcode do_sendmsg(size_t *psent, struct Curl_easy *data, int sockfd,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
msg.msg_controllen = ctrllen;
|
|
||||||
|
|
||||||
while((sent = sendmsg(sockfd, &msg, 0)) == -1 && SOCKERRNO == EINTR)
|
while((sent = sendmsg(sockfd, &msg, 0)) == -1 && SOCKERRNO == EINTR)
|
||||||
;
|
;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче