linux returns EAGAIN for closed ocserv interfaces

Nikos Mavrogiannopoulos n.mavrogiannopoulos at gmail.com
Fri Sep 19 06:59:13 PDT 2014


On Fri, Sep 19, 2014 at 2:54 PM, Niels Peen <niels at peen.ch> wrote:
> 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;
>>                 }
>>         }

Are these discussions public? Does that change solve the issue? Is the
loop on dnsmasq on tun or udp socket?

regards,
Nikos



More information about the openconnect-devel mailing list