I think the socket stuff could be rewritten in a way that we also have a pool for socket descriptors in the same way as for TCP/UDP/RAW PCBs etc. The active descriptors are kept in a linked list, which would add two fields to the descriptors: int socketFd, void* next. -> each descriptor increases in size 8 bytes on a 32 bit system. Not ideal for "small systems", but when sockets are used, the systems are not really _that_ small any more, so I'd consider this overhead to be OK.
Yes, for many sockets a linked list may become slow, but usually every socket implies a netconn and a PCB -> PCBs are iterated for every incoming packet, too.
The advantage is that people not wanting any restrictions can simply switch from pool allocation to heap allocation globally (MEMP_MEM_MALLOC = 1) which automatically satisfies that requirement for sockets, PCBs, netconns...