ElkeAusBerlin
ElkeAusBerlin

Reputation: 575

Zero copy networking not working on Linux

I try to test zero copy networking on Ubuntu 20.04. I set the corresponding socket option and pass MSG_ZEROCOPY as parameter to the send call. Problem is that I never receive the response from the kernel. recvmsg is always EAGAIN. Is there something wrong how I setup the socket? Full server code can be found here. What I am doing is more or less this:

sockfd = socket(AF_INET, SOCK_STREAM, 0);
bind(sockfd, (SA*)&servaddr, sizeof(servaddr);
listen(sockfd, 5);
setsockopt(sockfd, SOL_SOCKET, SO_ZEROCOPY, &optValue, sizeof(one));
connfd = accept(sockfd, (SA*)&cli, &len);

send(connfd, buff, MAX, MSG_DONTWAIT | MSG_ZEROCOPY)
ret = recvmsg(sockfd, &msg, MSG_ERRQUEUE);

if (ret == -1 && errno == EAGAIN)
{
    // it's always here
}

[Edit]

I realised that recvmsg actually returns but the counter is wrong. In my understanding each send increments the counter by 1. But after one send serr->ee_data is zero. After the second send serr->ee_data is 1. I certainly do misunderstand something here.

The fixed code is here.

Thanks!

Upvotes: 0

Views: 706

Answers (1)

kzsnyk
kzsnyk

Reputation: 2211

From https://www.kernel.org/doc/html/v4.15/networking/msg_zerocopy.html :

Setting the socket option only works when the socket is in its initial (TCP_CLOSED) state

In your example, the socket is in the LISTEN state. So, i would suggest to try the following :

sockfd = socket(AF_INET, SOCK_STREAM, 0);
/* try to set the option before listen is called */
if (setsockopt(sockfd, SOL_SOCKET, SO_ZEROCOPY, &optValue, sizeof(one)))
    perror("setsocketopt");

bind(sockfd, (SA*)&servaddr, sizeof(servaddr);
listen(sockfd, 5);

Upvotes: 1

Related Questions