Keep interface ID stable when rebuilding list

mdnsresponder uses the pointer to the PosixNetworkInterface structure as
interfaceID. However it updates the interface list by freeing and
reallocating the whole list, which at best causes queries scheduled for
one interface to stop being sent as there is no matching interface
anymore, and at worst causes them to be sent on the wrong interface when
malloc() returns a pointer that belonged to a previous free()ed
interface.

This was not noticed previously because:
 - mdnsresponder usage on Android did not specify specific interfaces,
   so discovery / announcements would be done on all interfaces anyway
 - The list is free()ed and malloc()ed in the same order immediately,
   and most of the time malloc() would return the same pointer that was
   free()ed previously for the same interface. This only causes unwanted
   behavior when an interface is added or removed in the middle of the
   list.

To work around this issue, when rebuilding the list, do not deallocate
each interface structure but instead put them in a temporary list. Then
reuse the same structs from the temporary list when recreating
interfaces with the same index. This ensures that interfaces with the
same index keep the same interfaceID (the pointer to the struct) when
the interface list gets rebuilt.

Upstream mdnsresponder stopped deallocating interfaces immediately when
rebuilding the list too, putting them in a temporary list that is kept
for 1 minute, however it does not take interfaces from that temporary
list when rebuilding them. This should fix bugs where requests get sent
on the wrong interface since malloc() cannot return a pointer that
matches a previously free()ed interface, but likely causes them to just
stop being sent as the new list does not match interfaceIDs in requests
anymore.

Bug: 198253353
Test: atest --rerun-until-failure 50 CtsNetTestCases:NsdManagerTest
Change-Id: I1f9099964140722394d1feed7f2a8b9c77e70527
1 file changed