aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-28 20:03:20 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-28 20:03:20 +0000
commit6c84df37e5e6ebfda8c61321975614ac45a24d98 (patch)
tree5ff76d5f95c9a35ff08186eb7a22d9ec0c1d0a07
parent5df76e3c888e17e93a055697e9196108f83589d4 (diff)
parent6eeb5c843f9f5e9feed501345bfb94f3451e61c6 (diff)
downloadmdnsresponder-android13-mainline-go-adservices-release.tar.gz
Snap for 8505378 from 6eeb5c843f9f5e9feed501345bfb94f3451e61c6 to mainline-go-adservices-releaseaml_go_ads_330915100aml_go_ads_330915000aml_go_ads_330913000android13-mainline-go-adservices-release
Change-Id: Ief2cdd74a1227c9cdb8e353dbace200ace0e516d
-rw-r--r--mDNSPosix/mDNSPosix.c100
1 files changed, 76 insertions, 24 deletions
diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c
index 64658b3..8960c93 100644
--- a/mDNSPosix/mDNSPosix.c
+++ b/mDNSPosix/mDNSPosix.c
@@ -581,42 +581,88 @@ mDNSexport mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(mDNS *const m, mDNS
return intf ? intf->index : 0;
}
-// Frees the specified PosixNetworkInterface structure. The underlying
+// Remove an interface identified by its index from the provided list, and return it.
+// This takes a pointer to a list of interfaces, where NULL represents the empty list.
+mDNSlocal PosixNetworkInterface *RemoveInterfaceFromListByIndex(PosixNetworkInterface **list, int index)
+ {
+ while (list && *list)
+ {
+ PosixNetworkInterface *current = *list;
+ if (current->index == index)
+ {
+ *list = (PosixNetworkInterface*)current->coreIntf.next;
+ current->coreIntf.next = NULL;
+ return current;
+ }
+ list = (PosixNetworkInterface**)&(current->coreIntf.next);
+ }
+ return NULL;
+ }
+
+// Close sockets on the specified PosixNetworkInterface structure. The underlying
// interface must have already been deregistered with the mDNS core.
-mDNSlocal void FreePosixNetworkInterface(PosixNetworkInterface *intf)
+mDNSlocal void ClosePosixNetworkInterface(PosixNetworkInterface *intf)
{
assert(intf != NULL);
- if (intf->intfName != NULL) free((void *)intf->intfName);
if (intf->multicastSocket4 != -1)
{
int ipv4_closed = close(intf->multicastSocket4);
assert(ipv4_closed == 0);
+ intf->multicastSocket4 = -1;
}
#if HAVE_IPV6
if (intf->multicastSocket6 != -1)
{
int ipv6_closed = close(intf->multicastSocket6);
assert(ipv6_closed == 0);
+ intf->multicastSocket6 = -1;
}
#endif
+ }
+
+// Free the specified PosixNetworkInterface structure. The underlying
+// interface must have already been deregistered with the mDNS core.
+mDNSlocal void FreePosixNetworkInterface(PosixNetworkInterface *intf)
+ {
+ assert(intf != NULL);
+ assert(intf->coreIntf.next == NULL);
+ ClosePosixNetworkInterface(intf);
+ free((void *)intf->intfName);
free(intf);
}
-// Grab the first interface, deregister it, free it, and repeat until done.
-mDNSlocal void ClearInterfaceList(mDNS *const m)
+// Frees a list of PosixNetworkInterfaces
+mDNSlocal void FreePosixNetworkInterfaceList(PosixNetworkInterface *intfList)
{
- assert(m != NULL);
+ while (intfList)
+ {
+ PosixNetworkInterface *next = (PosixNetworkInterface*)(intfList->coreIntf.next);
+ intfList->coreIntf.next = NULL;
+ FreePosixNetworkInterface(intfList);
+ intfList = next;
+ }
+ }
+// Grab the first interface, deregister it, close it, and repeat until done.
+// Returns the list of deregistered interfaces, or NULL if none.
+mDNSlocal PosixNetworkInterface *CloseInterfaceList(mDNS *const m)
+ {
+ assert(m != NULL);
+ PosixNetworkInterface *ret = NULL;
while (m->HostInterfaces)
{
PosixNetworkInterface *intf = (PosixNetworkInterface*)(m->HostInterfaces);
mDNS_DeregisterInterface(m, &intf->coreIntf, mDNSfalse);
if (gMDNSPlatformPosixVerboseLevel > 0) fprintf(stderr, "Deregistered interface %s\n", intf->intfName);
- FreePosixNetworkInterface(intf);
+ ClosePosixNetworkInterface(intf);
+ assert(intf->coreIntf.next == NULL);
+ intf->coreIntf.next = (NetworkInterfaceInfo*)ret;
+ ret = intf;
}
num_registered_interfaces = 0;
num_pkts_accepted = 0;
num_pkts_rejected = 0;
+ return ret;
}
// Sets up a send/receive socket.
@@ -848,10 +894,10 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
// Creates a PosixNetworkInterface for the interface whose IP address is
// intfAddr and whose name is intfName and registers it with mDNS core.
-mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct sockaddr *intfMask, const char *intfName, int intfIndex)
+mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct sockaddr *intfMask, const char *intfName, int intfIndex, PosixNetworkInterface **cachedList)
{
int err = 0;
- PosixNetworkInterface *intf;
+ PosixNetworkInterface *intf = NULL;
PosixNetworkInterface *alias = NULL;
assert(m != NULL);
@@ -859,15 +905,18 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct
assert(intfName != NULL);
assert(intfMask != NULL);
- // Allocate the interface structure itself.
- intf = (PosixNetworkInterface*)malloc(sizeof(*intf));
- if (intf == NULL) { assert(0); err = ENOMEM; }
-
- // And make a copy of the intfName.
- if (err == 0)
+ intf = RemoveInterfaceFromListByIndex(cachedList, intfIndex);
+ if (intf == NULL)
{
- intf->intfName = strdup(intfName);
- if (intf->intfName == NULL) { assert(0); err = ENOMEM; }
+ // Allocate the interface structure itself.
+ intf = (PosixNetworkInterface*)malloc(sizeof(*intf));
+ if (intf == NULL) { assert(0); err = ENOMEM; }
+ // And make a copy of the intfName.
+ if (err == 0)
+ {
+ intf->intfName = strdup(intfName);
+ if (intf->intfName == NULL) { assert(0); err = ENOMEM; }
+ }
}
if (err == 0)
@@ -933,7 +982,7 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct
}
// Call get_ifi_info() to obtain a list of active interfaces and call SetupOneInterface() on each one.
-mDNSlocal int SetupInterfaceList(mDNS *const m)
+mDNSlocal int SetupInterfaceList(mDNS *const m, PosixNetworkInterface **cachedList)
{
mDNSBool foundav4 = mDNSfalse;
int err = 0;
@@ -972,7 +1021,7 @@ mDNSlocal int SetupInterfaceList(mDNS *const m)
}
else if (i->ifi_flags & (IFF_MULTICAST | IFF_BROADCAST)) // http://b/25669326
{
- if (SetupOneInterface(m, i->ifi_addr, i->ifi_netmask, i->ifi_name, i->ifi_index) == 0)
+ if (SetupOneInterface(m, i->ifi_addr, i->ifi_netmask, i->ifi_name, i->ifi_index, cachedList) == 0)
if (i->ifi_addr->sa_family == AF_INET)
foundav4 = mDNStrue;
}
@@ -986,7 +1035,7 @@ mDNSlocal int SetupInterfaceList(mDNS *const m)
// In the interim, we skip loopback interface only if we found at least one v4 interface to use
// if ((m->HostInterfaces == NULL) && (firstLoopback != NULL))
if (!foundav4 && firstLoopback)
- (void) SetupOneInterface(m, firstLoopback->ifi_addr, firstLoopback->ifi_netmask, firstLoopback->ifi_name, firstLoopback->ifi_index);
+ (void) SetupOneInterface(m, firstLoopback->ifi_addr, firstLoopback->ifi_netmask, firstLoopback->ifi_name, firstLoopback->ifi_index, cachedList);
}
// Clean up.
@@ -1270,7 +1319,7 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
#endif
// Tell mDNS core about the network interfaces on this machine.
- if (err == mStatus_NoError) err = SetupInterfaceList(m);
+ if (err == mStatus_NoError) err = SetupInterfaceList(m, NULL);
// Tell mDNS core about DNS Servers
mDNS_Lock(m);
@@ -1302,7 +1351,9 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
mDNSexport void mDNSPlatformClose(mDNS *const m)
{
assert(m != NULL);
- ClearInterfaceList(m);
+ PosixNetworkInterface *closedList = CloseInterfaceList(m);
+ FreePosixNetworkInterfaceList(closedList);
+
if (m->p->unicastSocket4 != -1)
{
int ipv4_closed = close(m->p->unicastSocket4);
@@ -1320,8 +1371,9 @@ mDNSexport void mDNSPlatformClose(mDNS *const m)
mDNSexport mStatus mDNSPlatformPosixRefreshInterfaceList(mDNS *const m)
{
int err;
- ClearInterfaceList(m);
- err = SetupInterfaceList(m);
+ PosixNetworkInterface *closedList = CloseInterfaceList(m);
+ err = SetupInterfaceList(m, &closedList);
+ FreePosixNetworkInterfaceList(closedList);
return PosixErrorToStatus(err);
}