private-octopus / picoquic

Minimal implementation of the QUIC protocol
MIT License
523 stars 153 forks source link

Sending ECN flags broken on Windows #1640

Closed huitema closed 4 months ago

huitema commented 4 months ago

The code in picoquic in Picoquic by setting the ECN option at the socket level. Calls like:

            /* Request setting ECN_ECT_1 in outgoing packets */
            DWORD ecn = PICOQUIC_ECN_ECT_1;
            if (setsockopt(sd, IPPROTO_IP, IPV6_ECN, (const char *)&ecn, sizeof(ecn)) < 0) {
                ...
            }

I also set the "receive ECN" option at the socket level, and then get the ECN value as part of overlapped recvmsg. that code is wrong. In linux, the call would use IPV6_TCLASS to set the ECN byte in outgoing packets. There is no equivalent of setting TCLASS in Windows. Apparently, the msquic code uses a CMSG option in sendmsg with the same option code IP_ECN to set the ECN data on the specific packet. Just the symmetric of the CMSG option in recvmsg.

Instead, the code should be setting CMSG IP_ECN=ECT_1. It may also requires IP_PKTINFO, but picoquic uses that already. The part of the documentation that isn't really clear is that the control_buffer in WSAMSG length has to be sized to the actual number of CMSGs rather than the total size of the allocated buffer...