Skip to content
Advertisement

recv() skipping UDP packets

I wrote simple program to handle incoming UDP packets. I send 60000 UDP packets to and this programm is losing packets. Bandwith about 60-70 Mbit/s. If I wun tcpdump in parallel, then I see that all packages are received by the kernel. Also I tried recvmsg and recvmmsg with same result.

Program source code:

#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h> 
#include <signal.h>

#include <string.h>
#include <unistd.h>
sig_atomic_t exit_cond = 0;
int sock;
void signal_handler(int signum)
{
    exit_cond = 1;
    shutdown(sock,SHUT_RDWR);
    close(sock);
}

char buff[10240];
int main(int argc,char **argv)
{
    int len;
    unsigned long long overal;
    sock = socket(AF_INET,SOCK_DGRAM,0);
    signal(SIGTERM,signal_handler);
    signal(SIGINT,signal_handler);
    if(sock == -1)
    {
        printf("Error in socket()n");
        return -1;
    }
    struct sockaddr_in rcv_addr;
    memset(&rcv_addr, 0, sizeof(rcv_addr)); 

    rcv_addr.sin_family    = AF_INET;
    rcv_addr.sin_addr.s_addr = INADDR_ANY; 
    rcv_addr.sin_port = htons(1024); 
    if(bind(sock, (const struct sockaddr *)&rcv_addr,sizeof(rcv_addr)) < 0)
    { 
        printf("Error in bind()n");
        return -1;
    }
    
    while(!exit_cond)
    {
        
        len = recv(sock, (char *)buff, 10240,
                MSG_WAITALL);
        if(len > 0)
        {
            overal++;
        }
        
    }
    printf("Overal: %lldn",overal);    
}

Advertisement

Answer

The problem was solved. I was wrong about tcpdump, not all packets delivers to kernel. Also I did not describe the problem in detail. Program runs on single core ARM procesor, payload of UDP packets is 256 bytes, so CPU keep up with data stream, and the result kernel UDP queue owerflows, and I see packet loss. iperf3 have 1448 bytes payload, and works fine. If I decrfease iperf3 payload package to 256 bytes, it starts dropping packets as well. To fix the problem I increased payload to 512 bytes, increased net.core.rmem_max, net.core.rmem_default and NICs ring buffers and all works fine.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement