linux returns EAGAIN for closed ocserv interfaces

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I ran into an issue where dnsmasq would become unresponsive on a very busy VPN server. Dnsmasq would be looping endlessly like this:

sendmsg(6, {msg_name(16)={sa_family=AF_INET, sin_port=htons(59990), sin_addr=inet_addr("10.255.232.69")}, msg_iov(1)=[{"F\253\201\200\0\1\0\3\0\0\0\0\5b-api\10facebook\3com\0\0\1\0\1\300\f\0\5\0\1\0\0\6r\0\6\3z-m\300\22\3000\0\5\0\1\0\0\6n\0\v\3z-m\4c10r\300\22\300B\0\1\0\1\0\0\0\3\0\4\37\rF\6", 93}], msg_controllen=0, msg_flags=0}, 0) = -1 EAGAIN (Resource temporarily unavailable)
nanosleep({0, 10000}, NULL)             = 0
sendmsg(6, {msg_name(16)={sa_family=AF_INET, sin_port=htons(59990), sin_addr=inet_addr("10.255.232.69")}, msg_iov(1)=[{"F\253\201\200\0\1\0\3\0\0\0\0\5b-api\10facebook\3com\0\0\1\0\1\300\f\0\5\0\1\0\0\6r\0\6\3z-m\300\22\3000\0\5\0\1\0\0\6n\0\v\3z-m\4c10r\300\22\300B\0\1\0\1\0\0\0\3\0\4\37\rF\6", 93}], msg_controllen=0, msg_flags=0}, 0) = -1 EAGAIN (Resource temporarily unavailable)
nanosleep({0, 10000}, NULL)       

10.255.232.69 is a client of ocserv that disconnected prior to dnsmasq returning the result. Removing ocserv from the server (but letting people connect with other VPN methods) prevents the problem from occurring. 

Simon Kelley of dnsmasq provided me a work-around which I?m testing at the moment. That doesn?t solve the underlying problem though. When I swap dnsmasq for BIND it runs into a similar problem: it fills up the send queue and becomes unresponsive.

I suspect the problem is with how ocserv closes the tun interfaces. Thomas Veerman suggested that closing the interfaces may simply be failing occasionally and provided me with the patch below, which I?m testing as well.

# diff main-misc.c.old main-misc.c
131,136c131,137
<       if (proc->tun_lease.name[0] != 0) {
<               if (proc->tun_lease.fd >= 0)
<                       close(proc->tun_lease.fd);
<               proc->tun_lease.fd = -1;
<       }
< 
---
>       while (proc->tun_lease.fd >= 0) {
>               int r = close(proc->tun_lease.fd);
>               if (r == 0 || errno == EBADF) {
>                       proc->tun_lease.fd = -1;
>                 }
>         }
>                     

Appreciate any comments you may have.

Cheers,
Niels




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux