This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: TCP_CORK (aka TCP_NOPUSH) does not work

On 2019-07-30 15:30, Lavrentiev, Anton (NIH/NLM/NCBI) [C] via cygwin wrote:
> Consider the following code:
> $ cat cork.c
> #include <arpa/inet.h>
> #include <netinet/in.h>
> #include <netinet/tcp.h>
> #include <unistd.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/socket.h>
> #include <sys/types.h>
> #if defined(TCP_NOPUSH)  &&  !defined(TCP_CORK)
> #  define TCP_CORK  TCP_NOPUSH
> #endif

For POSIX only non-Nagle TCP_NODELAY is required:
and even then says:
"The implementation need not allow the value of the option to be set via
setsockopt() or retrieved via getsockopt()."

TCP_CORK is Linux only; TCP_NOPUSH is BSD only; Windows does its own thing:

Regular SO options on Windows:

You can abuse Nagle to get similar behaviour cross-platform:

> int main(int argc, const char* argv[])
> {
>     union {
>         struct sockaddr_in in;
>         struct sockaddr    sa;
>     } addr;
>     int sock, cork = 1;
>     memset(&addr, 0, sizeof(addr));
>     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
>         perror("socket");
> = AF_INET;
> = inet_addr(argv[1]);
> = htons((unsigned short) atoi(argv[2]));
>     if (connect(sock, &, sizeof( < 0)
>         perror("connect");
>     if (setsockopt(sock, IPPROTO_TCP, TCP_CORK, (char*) &cork, sizeof(cork)) != 0)
>         perror("cork");
>     return 0;
> }
> When compiled and run under Cygwin, the last syscall, setsockopt(), returns
> an error, Protocol not available:
> gcc cork.c
> ./a.exe 443
> cork: Protocol not available

This is error ENOPROTOOPT, where the message is misleading, but as suggested by
the name, means that the socket option is not supported for that protocol;
getsockopt(3p/3posix) says: "The option is not supported by the protocol."
getsockopt(2) for Linux and FreeBSD say: "The option is unknown at the level
indicated." and given the POSIX statement above, that error should be treated as
a warning to do something different.

> The same code works under Linux just fine.  I straced both.
> gcc cork.c
> ./a.out 443
> Any ideas?  Is TCP_NOPUSH (which is a BSDism, BTW) not actually usable on
Cygwin?  If not, why is it in the header file <netinet/tcp.h>?

If a socket option is defined, perhaps for compatibility, it should either be
used or ignored, rather than giving an error.
If you are not going to support a socket option, and generate an error, it would
be better to not define the option and generate the error at compile time,
instead of failing at run time.

Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada

This email may be disturbing to some readers as it contains
too much technical detail. Reader discretion is advised.

Problem reports:
Unsubscribe info:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]