tevent: fd events do not work correctly for UDP socket?

Pavel Březina pbrezina at redhat.com
Wed Aug 19 17:15:13 UTC 2020


On 8/18/20 6:31 PM, Jeremy Allison wrote:
> On Tue, Aug 18, 2020 at 01:46:09PM +0200, Pavel Březina via samba-technical wrote:
>> When I connect to a port over UDP and nobody listens on the port tevent
>> fires immediately read fd event even though there is no data available.
>>
>> Simple reproducer is attached. Just run 'make && ./client' and see that
>> read_handler is executed immediately. When there is a process listening (nc
>> -ul 3333) the handler is fired only when data is available.
>>
>> This probably boils down to epoll_wait but not being an epoll export, I'd
>> like to ask if there is something that can be done about it or if it is an
>> expected behavior.
> 
> Do strace ./client to see why this is:
> 
> The key is here:
> 
> write(1, "File descriptor is readable!\n", 29File descriptor is readable!
> ) = 29
> read(4, 0x7fffeee02750, 254)            = -1 ECONNREFUSED (Connection refused)
> 
> Your connect call succeeds, as it's setting up the local
> binding to the remote address, but as it hasn't sent any
> data yet the client hasn't noticed there's no one listening.
> 
> Once you do the:
> 
>       const char *msg = "I AM CONNECTED\n";
>       write(fd, msg, strlen(msg));
> 
> call then the kernel tries to send the data, notices
> there's nothing listening and so the read fd becomes
> ready via EPOLL - it needs to return the error
> ECONNREFUSED (we select for EPOLLIN|EPOLLERR|EPOLLHUP).
> 
> So when you call the read() in the tevent handler,
> that's when you'd pick up the errno = ECONNREFUSED
> error.

I see. If I understand it correctly epoll returns EPOLLERR and the code 
hits this [1] line?

> I don't think this is tevent specific behavior.

If the above is true then tevent should provide way for the handler to 
check for errors or don't call a read handler on an error so read does 
not get called.

My use case is that I'm trying to implement a CLDAP ping over UDP in 
SSSD and when a Domain Controller is unreachable the read handler is 
fired, then ldap tries to receive a reply and blocks until network 
timeout is reached which is undesirable.

[1] 
https://github.com/samba-team/samba/blob/master/lib/tevent/tevent_epoll.c#L707




More information about the samba-technical mailing list