c - Hvorfor kan jeg ikke deaktivere MTU-opdagelse på Windows-stikket? IP\_PMTUDISC\_DONT undlader at indstille

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at bygge uftp på Windows. Det er en UDP overførselsklient/server.


Jeg kunne i sidste ende gøre statiske binære filer med OpenSSL forbundet. Men jeg har stadig et problem med en smule kode. Det undlader at sætte IP\_PMTUDISC\_DONT flag på stikket.


Når jeg kører koden Windows fejl:


> uftpd.exe -D C:xfertest -p 1044 -d -T c:	mp

Error disabling MTU discovery: (10042) An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call.
Error leaving multicast group: (10038) An operation was attempted on something that is not a socket.


Dette er den kode, der forsøger at sætte flagget på stikket i client\_init.c:


#ifdef IP\_MTU\_DISCOVER
{
    int mtuflag = IP\_PMTUDISC\_DONT;
    if (setsockopt(listener, IPPROTO\_IP, IP\_MTU\_DISCOVER, &mtuflag, sizeof(mtuflag)) == SOCKET\_ERROR) {
        sockerror(0, 0, 0, "Error disabling MTU discovery");
        closesocket(listener);
        exit(ERR\_SOCKET);
    }
}
#endif


Dette er bygget på Windows Server 2016 med VS2017 community udgave.


Jeg har prøvet testbygninger, der ikke inkluderer dette flag, men de synes at have langt dårligere præstation (tons NAK'er), hvilket måske ikke er en overraskelse, hvis dette medfører fragmentering.


Kan nogen tænke på, hvorfor jeg ikke kan sætte op på dette? Lytteren er faktisk en stikkontakt, der er oprettet i samme fil af listener = socket(family, SOCK\_DGRAM, 0). Jeg ser andre tilbagemeldinger på internettet, der hævder, at nogle af disse API'er kan have ændret sig gennem tiden. Jeg vil se, om jeg kan bygge videre på tidligere versioner af VS og OS, men jeg håber, at nogen der har ramt dette før, kan påpege en klar vej til en løsning hurtigere end jeg kan.

Bedste reference


Støtte til IP\_MTU\_DISCOVER eksisterede simpelthen ikke i Windows Server 2016.


IP\_MTU\_DISCOVER blev implementeret i WSL (Windows Subsystem for Linux) til UDP-stik i Windows 10 build 15002 (se WSL-problemer # 69, # 170, # 717 og # 720 på GitHub): [13] [14] [15] [16]


https://docs.microsoft.com/en-us/windows/wsl/release-notes#build-15002[17]



  Implementeret IP\_MTU\_DISCOVER INET socket option (GH # 720, 717, 170, 69)



IP\_MTU\_DISCOVER blev implementeret i WSL til TCP sockets i Windows 10 build 16215 (se WSL-problemer # 1639, # 2115 og # 2205 på GitHub): [18] [19] [20]


https://docs.microsoft.com/en-us/windows/wsl/release-notes#build-16215[21]



  Tilføjet support til IP\_MTU\_DISCOVER til TCP sockets. [[GH 1639, 2115, 2205]]



Bare fordi præprocessoren har #define 'da-værdien for IP\_MTU\_DISCOVER garanterer ikke mål OS , at din kode ender med at køre, rent faktisk understøtter [[IP\_MTU\_DISCOVER. Du skal køre koden og ignorere fejlen WSAENOPROTOOPT fra setsockopt(), hvis den forekommer, fx:


#ifdef IP\_MTU\_DISCOVER
{
    int mtuflag = IP\_PMTUDISC\_DONT;
    if (setsockopt(listener, IPPROTO\_IP, IP\_MTU\_DISCOVER, &mtuflag, sizeof(mtuflag)) == SOCKET\_ERROR) {
        if (WSAGetLastError() != WSAENOPROTOOPT) {
            sockerror(0, 0, 0, "Error disabling MTU discovery");
            closesocket(listener);
            exit(ERR\_SOCKET);
        }
        // IP\_MTU\_DISCOVER is NOT supported on this OS!
        // Do something else, or just move on...
    }
}
#endif