tech-userlevel archive

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

PROPOSAL: new libc function allocaddrinfo()

Writing a nsswitch plugin for getaddrinfo turns out to be rather annoying, because there is no good mechanism to safely allocate the "struct addrinfo" objects to be returned. The naive implementation would be to malloc a struct addrinfo, and then malloc separately for the ai_addr field. However, this results in a leak, because our freeaddrinfo() does not free ai_addr.

Looking at the libc source, one can see that the addrinfo and sockaddr are allocated together, and copy that approach, however depending on undocumented implementation details like that is a recipe for trouble. There is nothing to say that NetBSD cannot switch to using separate allocations in the future, or that it even has to use malloc at all, for that matter.

The only safe way for a nss getaddrinfo plugin to obtain new addrinfos seems to be to recursively call getaddrinfo again in such a way as to cause it to return a addrinfo with the appropriate sockaddr allocted (eg inet_ntop the address back to text, and look up with AI_NUMERICHOST) and then fiddle with the result. This is non-obvious, needlessly cumbersome, and inefficient.

I propose to solve this by introducing a new libc function:

        struct addrinfo *allocaddrinfo(socklen_t addrlen)

Which guarantees to allocate a struct addrinfo and associated ai_addr memory of the given size in a way that is compatible with freeaddrinfo. We should also document that ai_canonname is managed with malloc/free and that it is safe for nss plugins to depend on that fact.

Internally, libc/net/getaddrinfo.c:get_ai() can also be changed to use allocaddrinfo().

Home | Main Index | Thread Index | Old Index