diff options
Diffstat (limited to 'meta-networking/recipes-protocols/mdns/mdns/0004-Use-list-for-changed-interfaces.patch')
-rw-r--r-- | meta-networking/recipes-protocols/mdns/mdns/0004-Use-list-for-changed-interfaces.patch | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/meta-networking/recipes-protocols/mdns/mdns/0004-Use-list-for-changed-interfaces.patch b/meta-networking/recipes-protocols/mdns/mdns/0004-Use-list-for-changed-interfaces.patch new file mode 100644 index 000000000..db3a63ea4 --- /dev/null +++ b/meta-networking/recipes-protocols/mdns/mdns/0004-Use-list-for-changed-interfaces.patch | |||
@@ -0,0 +1,177 @@ | |||
1 | From 798bfb5e984845a27874d1a244686db6e384d7b8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Nate Karstens <nate.karstens@garmin.com> | ||
3 | Date: Thu, 13 Jul 2017 09:00:00 -0500 | ||
4 | Subject: [PATCH 04/11] Use list for changed interfaces | ||
5 | |||
6 | Uses a linked list to store the index of changed network interfaces | ||
7 | instead of a bitfield. This allows for network interfaces with an | ||
8 | index greater than 31 (an index of 36 was seen on Android). | ||
9 | |||
10 | Upstream-Status: Submitted [dts@apple.com] | ||
11 | |||
12 | Signed-off-by: Nate Karstens <nate.karstens@garmin.com> | ||
13 | --- | ||
14 | mDNSPosix/mDNSPosix.c | 67 +++++++++++++++++++++++++++++++++---------- | ||
15 | 1 file changed, 52 insertions(+), 15 deletions(-) | ||
16 | |||
17 | diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c | ||
18 | index 195d04b..bb883c1 100755 | ||
19 | --- a/mDNSPosix/mDNSPosix.c | ||
20 | +++ b/mDNSPosix/mDNSPosix.c | ||
21 | @@ -67,6 +67,14 @@ struct IfChangeRec | ||
22 | }; | ||
23 | typedef struct IfChangeRec IfChangeRec; | ||
24 | |||
25 | +// Used to build a list of network interface indices | ||
26 | +struct NetworkInterfaceIndex | ||
27 | +{ | ||
28 | + int if_index; | ||
29 | + struct NetworkInterfaceIndex *Next; | ||
30 | +}; | ||
31 | +typedef struct NetworkInterfaceIndex NetworkInterfaceIndex; | ||
32 | + | ||
33 | // Note that static data is initialized to zero in (modern) C. | ||
34 | static PosixEventSource *gEventSources; // linked list of PosixEventSource's | ||
35 | static sigset_t gEventSignalSet; // Signals which event loop listens for | ||
36 | @@ -1458,6 +1466,32 @@ mDNSlocal mStatus OpenIfNotifySocket(int *pFD) | ||
37 | return err; | ||
38 | } | ||
39 | |||
40 | +mDNSlocal mDNSBool ListContainsInterfaceIndex(GenLinkedList *list, int if_index) | ||
41 | +{ | ||
42 | + NetworkInterfaceIndex *item; | ||
43 | + | ||
44 | + for (item = (NetworkInterfaceIndex*)list->Head; item != NULL; item = item->Next) | ||
45 | + { | ||
46 | + if (if_index == item->if_index) return mDNStrue; | ||
47 | + } | ||
48 | + | ||
49 | + return mDNSfalse; | ||
50 | +} | ||
51 | + | ||
52 | +mDNSlocal void AddInterfaceIndexToList(GenLinkedList *list, int if_index) | ||
53 | +{ | ||
54 | + NetworkInterfaceIndex *item; | ||
55 | + | ||
56 | + if (ListContainsInterfaceIndex(list, if_index)) return; | ||
57 | + | ||
58 | + item = malloc(sizeof *item); | ||
59 | + if (item == NULL) return; | ||
60 | + | ||
61 | + item->if_index = if_index; | ||
62 | + item->Next = NULL; | ||
63 | + AddToTail(list, item); | ||
64 | +} | ||
65 | + | ||
66 | #if MDNS_DEBUGMSGS | ||
67 | mDNSlocal void PrintNetLinkMsg(const struct nlmsghdr *pNLMsg) | ||
68 | { | ||
69 | @@ -1485,14 +1519,13 @@ mDNSlocal void PrintNetLinkMsg(const struct nlmsghdr *pNLMsg) | ||
70 | } | ||
71 | #endif | ||
72 | |||
73 | -mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) | ||
74 | +mDNSlocal void ProcessRoutingNotification(int sd, GenLinkedList *changedInterfaces) | ||
75 | // Read through the messages on sd and if any indicate that any interface records should | ||
76 | // be torn down and rebuilt, return affected indices as a bitmask. Otherwise return 0. | ||
77 | { | ||
78 | ssize_t readCount; | ||
79 | char buff[4096]; | ||
80 | struct nlmsghdr *pNLMsg = (struct nlmsghdr*) buff; | ||
81 | - mDNSu32 result = 0; | ||
82 | |||
83 | // The structure here is more complex than it really ought to be because, | ||
84 | // unfortunately, there's no good way to size a buffer in advance large | ||
85 | @@ -1528,9 +1561,9 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) | ||
86 | |||
87 | // Process the NetLink message | ||
88 | if (pNLMsg->nlmsg_type == RTM_GETLINK || pNLMsg->nlmsg_type == RTM_NEWLINK) | ||
89 | - result |= 1 << ((struct ifinfomsg*) NLMSG_DATA(pNLMsg))->ifi_index; | ||
90 | + AddInterfaceIndexToList(changedInterfaces, ((struct ifinfomsg*) NLMSG_DATA(pNLMsg))->ifi_index); | ||
91 | else if (pNLMsg->nlmsg_type == RTM_DELADDR || pNLMsg->nlmsg_type == RTM_NEWADDR) | ||
92 | - result |= 1 << ((struct ifaddrmsg*) NLMSG_DATA(pNLMsg))->ifa_index; | ||
93 | + AddInterfaceIndexToList(changedInterfaces, ((struct ifaddrmsg*) NLMSG_DATA(pNLMsg))->ifa_index); | ||
94 | |||
95 | // Advance pNLMsg to the next message in the buffer | ||
96 | if ((pNLMsg->nlmsg_flags & NLM_F_MULTI) != 0 && pNLMsg->nlmsg_type != NLMSG_DONE) | ||
97 | @@ -1541,8 +1574,6 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) | ||
98 | else | ||
99 | break; // all done! | ||
100 | } | ||
101 | - | ||
102 | - return result; | ||
103 | } | ||
104 | |||
105 | #else // USES_NETLINK | ||
106 | @@ -1574,14 +1605,13 @@ mDNSlocal void PrintRoutingSocketMsg(const struct ifa_msghdr *pRSMsg) | ||
107 | } | ||
108 | #endif | ||
109 | |||
110 | -mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) | ||
111 | +mDNSlocal void ProcessRoutingNotification(int sd, GenLinkedList *changedInterfaces) | ||
112 | // Read through the messages on sd and if any indicate that any interface records should | ||
113 | // be torn down and rebuilt, return affected indices as a bitmask. Otherwise return 0. | ||
114 | { | ||
115 | ssize_t readCount; | ||
116 | char buff[4096]; | ||
117 | struct ifa_msghdr *pRSMsg = (struct ifa_msghdr*) buff; | ||
118 | - mDNSu32 result = 0; | ||
119 | |||
120 | readCount = read(sd, buff, sizeof buff); | ||
121 | if (readCount < (ssize_t) sizeof(struct ifa_msghdr)) | ||
122 | @@ -1596,12 +1626,10 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) | ||
123 | pRSMsg->ifam_type == RTM_IFINFO) | ||
124 | { | ||
125 | if (pRSMsg->ifam_type == RTM_IFINFO) | ||
126 | - result |= 1 << ((struct if_msghdr*) pRSMsg)->ifm_index; | ||
127 | + AddInterfaceIndexToList(changedInterfaces, ((struct if_msghdr*) pRSMsg)->ifm_index); | ||
128 | else | ||
129 | - result |= 1 << pRSMsg->ifam_index; | ||
130 | + AddInterfaceIndexToList(changedInterfaces, pRSMsg->ifam_index); | ||
131 | } | ||
132 | - | ||
133 | - return result; | ||
134 | } | ||
135 | |||
136 | #endif // USES_NETLINK | ||
137 | @@ -1611,7 +1639,8 @@ mDNSlocal void InterfaceChangeCallback(int fd, void *context) | ||
138 | { | ||
139 | IfChangeRec *pChgRec = (IfChangeRec*) context; | ||
140 | fd_set readFDs; | ||
141 | - mDNSu32 changedInterfaces = 0; | ||
142 | + GenLinkedList changedInterfaces; | ||
143 | + NetworkInterfaceIndex *changedInterface; | ||
144 | struct timeval zeroTimeout = { 0, 0 }; | ||
145 | |||
146 | (void)fd; // Unused | ||
147 | @@ -1619,17 +1648,25 @@ mDNSlocal void InterfaceChangeCallback(int fd, void *context) | ||
148 | FD_ZERO(&readFDs); | ||
149 | FD_SET(pChgRec->NotifySD, &readFDs); | ||
150 | |||
151 | + InitLinkedList(&changedInterfaces, offsetof(NetworkInterfaceIndex, Next)); | ||
152 | + | ||
153 | do | ||
154 | { | ||
155 | - changedInterfaces |= ProcessRoutingNotification(pChgRec->NotifySD); | ||
156 | + ProcessRoutingNotification(pChgRec->NotifySD, &changedInterfaces); | ||
157 | } | ||
158 | while (0 < select(pChgRec->NotifySD + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &zeroTimeout)); | ||
159 | |||
160 | // Currently we rebuild the entire interface list whenever any interface change is | ||
161 | // detected. If this ever proves to be a performance issue in a multi-homed | ||
162 | // configuration, more care should be paid to changedInterfaces. | ||
163 | - if (changedInterfaces) | ||
164 | + if (changedInterfaces.Head != NULL) | ||
165 | mDNSPlatformPosixRefreshInterfaceList(pChgRec->mDNS); | ||
166 | + | ||
167 | + while ((changedInterface = (NetworkInterfaceIndex*)changedInterfaces.Head) != NULL) | ||
168 | + { | ||
169 | + RemoveFromList(&changedInterfaces, changedInterface); | ||
170 | + free(changedInterface); | ||
171 | + } | ||
172 | } | ||
173 | |||
174 | // Register with either a Routing Socket or RtNetLink to listen for interface changes. | ||
175 | -- | ||
176 | 2.20.1 | ||
177 | |||