nscd vs NSS ERANGE protocol
Florian Weimer
fweimer@redhat.com
Tue Nov 18 20:10:30 GMT 2025
I've been reading NSS and nscd sources a lot lately. I was trying to
find a way to avoid the ERANGE protocol, by allocating the required
memory directly (similar to what getaddrinfo already does, although not
internally).
The nscd wire protocol does not contain information about the response
size, although the server knows that when it starts sending the
response. The current clients (at least the protocol handlers in glibc
that I looked at) use the size fields and progressively read more and
more data from the socket. However, the nscd socket service is
one-shot: client sends request, server sends response, server closes
socket. (The connection is not reused for multiple requests.) So the
client could read data until it hits end of stream (at which point
read/recv returns zero, it won't block due to the server close).
Relying on this would simplify some aspects of the client code.
If the data is accessed through the mapping, then we have size
information in the header of each in-cache allocation. We'd need to fix
concurrent reads from the cache before we can use the size information
directly, though. Right now, we might see a bad value there, but I
suspect it's generally it's okay because we just send an extra ERANGE
error down to the application, which retries, and then next concurrent
read doesn't reproduce the race condition (or the one after that).
Maybe we can check the allocation size against the map size or something
like that, to avoid really large allocation attempts even if the cache
synchronization is not fully fixed yet.
I still hope I find a way to simplify this. My goal is to reverse the
direction if implementation: use allocating functions as the baseline,
and implement the _r variants on top of that, with a one-entry
per-thread cache that prevents the ERANGE retries from hitting the
underlying service.
Thanks,
Florian
More information about the Libc-alpha
mailing list