-
Notifications
You must be signed in to change notification settings - Fork 128
Open
Description
Hi,
I'm trying to send 5 packets, each of size 3KB, using Generic Segmentation Offload (GSO) in a UDP socket. However, I'm encountering an error: "Message too long". I suspect there might be an issue with how I'm using GSO. Here is a simplified version of my client code:
#ifdef __linux__
#ifndef UDP_SEGMENT
#define UDP_SEGMENT 103
#endif
static void send_packets_gso(int fd, quicly_address_t *dest, quicly_address_t *src, struct iovec *packets, size_t num_packets,
uint8_t ecn)
{
struct iovec vec = {.iov_base = (void *)packets[0].iov_base,
.iov_len = packets[num_packets - 1].iov_base + packets[num_packets - 1].iov_len - packets[0].iov_base};
char cmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(uint16_t)) /* UDP_SEGMENT */ +
CMSG_SPACE(sizeof(int)) /* IP_TOS */];
struct msghdr mess = {
.msg_name = dest,
.msg_namelen = quicly_get_socklen(&dest->sa),
.msg_iov = &vec,
.msg_iovlen = 1,
.msg_control = cmsgbuf,
};
if (src != NULL && src->sa.sa_family != AF_UNSPEC)
set_srcaddr(&mess, src);
if (num_packets != 1) {
struct cmsghdr *cmsg = (struct cmsghdr *)((char *)mess.msg_control + mess.msg_controllen);
cmsg->cmsg_level = SOL_UDP;
cmsg->cmsg_type = UDP_SEGMENT;
cmsg->cmsg_len = CMSG_LEN(sizeof(uint16_t));
*(uint16_t *)CMSG_DATA(cmsg) = packets[0].iov_len;
mess.msg_controllen += CMSG_SPACE(sizeof(uint16_t));
}
set_ecn(&mess, ecn);
assert(mess.msg_controllen <= sizeof(cmsgbuf));
if (mess.msg_controllen == 0)
mess.msg_control = NULL;
int ret;
while ((ret = sendmsg(fd, &mess, 0)) == -1 && errno == EINTR)
;
if (ret == -1)
perror("sendmsg failed");
if (ret > 0) {
printf("send successfully. ret = %d\n", ret);
}
}
#endif
static int send_pending(int fd, quicly_conn_t *conn)
{
quicly_address_t dest, src;
struct iovec packets[MAX_BURST_PACKETS];
uint8_t buf[MAX_BURST_PACKETS * quicly_get_context(conn)->transport_params.max_udp_payload_size];
size_t num_packets = MAX_BURST_PACKETS;
int ret;
if ((ret = quicly_send(conn, &dest, &src, packets, &num_packets, buf, sizeof(buf))) == 0 && num_packets != 0) {
num_packets = 5;
struct iovec new_packets[num_packets];
size_t packet_size = 3072; // 3 KB per packet
char *packet_data = malloc(packet_size * num_packets);
for (size_t i = 0; i < num_packets; i++) {
new_packets[i].iov_base = packet_data + (i * packet_size);
new_packets[i].iov_len = packet_size;
memset(new_packets[i].iov_base, 'A' + i, packet_size); // fill the buffer with different data
}
send_packets_gso(fd, &dest, &src, new_packets, num_packets, quicly_send_get_ecn_bits(conn));
}
return ret;
}
Metadata
Metadata
Assignees
Labels
No labels