Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sending 5 x 3KB Packets via GSO - "Message too long/Invalid argument" Error #582

Open
xs-411 opened this issue May 22, 2024 · 0 comments
Open

Comments

@xs-411
Copy link

xs-411 commented May 22, 2024

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;
}

@xs-411 xs-411 changed the title Sending 5 x 3KB Packets via GSO - "Message too long" Error Sending 5 x 3KB Packets via GSO - "Message too long/Invalid argument" Error May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant