• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "if_monitor.h"
18 
19 #include <errno.h>
20 #include <linux/rtnetlink.h>
21 #include <net/if.h>
22 #include <poll.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 
29 #include <memory>
30 #include <mutex>
31 #include <thread>
32 #include <unordered_map>
33 #include <vector>
34 
35 #define LOG_TAG "RIL-IFMON"
36 #include <utils/Log.h>
37 
38 static const size_t kReadBufferSize = 32768;
39 
40 static const size_t kControlServer = 0;
41 static const size_t kControlClient = 1;
42 
43 // A list of commands that can be sent to the monitor. These should be one
44 // character long as that is all that the monitor will read and process.
45 static const char kMonitorStopCommand[] = "\1";
46 static const char kMonitorAckCommand[] = "\2";
47 
addrLength(int addrFamily)48 static size_t addrLength(int addrFamily) {
49     switch (addrFamily) {
50         case AF_INET:
51             return 4;
52         case AF_INET6:
53             return 16;
54         default:
55             return 0;
56     }
57 }
58 
operator ==(const struct ifAddress & left,const struct ifAddress & right)59 bool operator==(const struct ifAddress& left, const struct ifAddress& right) {
60     // The prefix length does not factor in to whether two addresses are the
61     // same or not. Only the family and the address data. This matches the
62     // kernel behavior when attempting to add the same address with different
63     // prefix lengths, those changes are rejected because the address already
64     // exists.
65     return left.family == right.family &&
66            memcmp(&left.addr, &right.addr, addrLength(left.family)) == 0;
67 }
68 
69 class InterfaceMonitor {
70 public:
InterfaceMonitor()71     InterfaceMonitor() : mSocketFd(-1) {
72         mControlSocket[kControlServer] = -1;
73         mControlSocket[kControlClient] = -1;
74     }
75 
~InterfaceMonitor()76     ~InterfaceMonitor() {
77         if (mControlSocket[kControlClient] != -1) {
78             ::close(mControlSocket[kControlClient]);
79             mControlSocket[kControlClient] = -1;
80         }
81         if (mControlSocket[kControlServer] != -1) {
82             ::close(mControlSocket[kControlServer]);
83             mControlSocket[kControlServer] = -1;
84         }
85 
86         if (mSocketFd != -1) {
87             ::close(mSocketFd);
88             mSocketFd = -1;
89         }
90     }
91 
init()92     bool init() {
93         if (mSocketFd != -1) {
94             RLOGE("InterfaceMonitor already initialized");
95             return false;
96         }
97 
98         mSocketFd = ::socket(AF_NETLINK,
99                              SOCK_DGRAM | SOCK_CLOEXEC,
100                              NETLINK_ROUTE);
101         if (mSocketFd == -1) {
102             RLOGE("InterfaceMonitor failed to open socket: %s", strerror(errno));
103             return false;
104         }
105 
106         if (::socketpair(AF_UNIX, SOCK_DGRAM, 0, mControlSocket) != 0) {
107             RLOGE("Unable to create control socket pair: %s", strerror(errno));
108             return false;
109         }
110 
111         struct sockaddr_nl addr;
112         memset(&addr, 0, sizeof(addr));
113         addr.nl_family = AF_NETLINK;
114         addr.nl_groups = (1 << (RTNLGRP_IPV4_IFADDR - 1)) |
115                          (1 << (RTNLGRP_IPV6_IFADDR - 1));
116 
117         struct sockaddr* sa = reinterpret_cast<struct sockaddr*>(&addr);
118         if (::bind(mSocketFd, sa, sizeof(addr)) != 0) {
119             RLOGE("InterfaceMonitor failed to bind socket: %s",
120                   strerror(errno));
121             return false;
122         }
123 
124         return true;
125     }
126 
setCallback(ifMonitorCallback callback)127     void setCallback(ifMonitorCallback callback) {
128         mOnAddressChangeCallback = callback;
129     }
130 
runAsync()131     void runAsync() {
132         std::unique_lock<std::mutex> lock(mThreadMutex);
133         mThread = std::make_unique<std::thread>([this]() { run(); });
134     }
135 
requestAddress()136     void requestAddress() {
137         struct {
138             struct nlmsghdr hdr;
139             struct ifaddrmsg msg;
140             char padding[16];
141         } request;
142 
143         memset(&request, 0, sizeof(request));
144         request.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(request.msg));
145         request.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
146         request.hdr.nlmsg_type = RTM_GETADDR;
147 
148         int status = ::send(mSocketFd, &request, request.hdr.nlmsg_len, 0);
149         if (status < 0 ||
150             static_cast<unsigned int>(status) != request.hdr.nlmsg_len) {
151             if (status < 0) {
152                 RLOGE("Failed to send netlink request: %s", strerror(errno));
153             } else {
154                 RLOGE("Short send only sent %d out of %d bytes",
155                       status, (int)request.hdr.nlmsg_len);
156             }
157         }
158     }
159 
run()160     void run() {
161         requestAddress();
162 
163         std::vector<struct pollfd> fds(2);
164         fds[0].events = POLLIN;
165         fds[0].fd = mControlSocket[kControlServer];
166         fds[1].events = POLLIN;
167         fds[1].fd = mSocketFd;
168         while (true) {
169             int status = ::poll(fds.data(), fds.size(), -1);
170             if (status < 0) {
171                 if (errno == EINTR) {
172                     // Interrupted, just keep going
173                     continue;
174                 }
175                 // Actual error, time to quit
176                 RLOGE("Polling failed: %s", strerror(errno));
177                 break;
178             } else if (status == 0) {
179                 // Timeout
180                 continue;
181             }
182 
183             if (fds[0].revents & POLLIN) {
184                 // Control message received
185                 char command = -1;
186                 if (::read(mControlSocket[kControlServer],
187                            &command,
188                            sizeof(command)) == 1) {
189                     if (command == kMonitorStopCommand[0]) {
190                         break;
191                     }
192                 }
193             } else if (fds[1].revents & POLLIN) {
194                 onReadAvailable();
195             }
196         }
197         ::write(mControlSocket[kControlServer], kMonitorAckCommand, 1);
198     }
199 
stop()200     void stop() {
201         std::unique_lock<std::mutex> lock(mThreadMutex);
202         if (mThread) {
203             ::write(mControlSocket[kControlClient], kMonitorStopCommand, 1);
204             char ack = -1;
205             while (ack != kMonitorAckCommand[0]) {
206                 ::read(mControlSocket[kControlClient], &ack, sizeof(ack));
207             }
208             mThread->join();
209             mThread.reset();
210         }
211     }
212 
213 private:
onReadAvailable()214     void onReadAvailable() {
215         char buffer[kReadBufferSize];
216         struct sockaddr_storage storage;
217 
218         while (true) {
219             socklen_t addrSize = sizeof(storage);
220             int status = ::recvfrom(mSocketFd,
221                                     buffer,
222                                     sizeof(buffer),
223                                     MSG_DONTWAIT,
224                                     reinterpret_cast<struct sockaddr*>(&storage),
225                                     &addrSize);
226             if (status < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
227                 // Nothing to receive, everything is fine
228                 return;
229             } else if (status < 0 && errno == EINTR) {
230                 // Caught interrupt, try again
231                 continue;
232             } else if (status < 0) {
233                 RLOGE("InterfaceMonitor receive failed: %s", strerror(errno));
234                 return;
235             } else if (addrSize < 0 ||
236                        static_cast<size_t>(addrSize) != sizeof(struct sockaddr_nl)) {
237                 RLOGE("InterfaceMonitor received invalid address size");
238                 return;
239             }
240 
241             size_t length = static_cast<size_t>(status);
242 
243             auto hdr = reinterpret_cast<struct nlmsghdr*>(buffer);
244             while (NLMSG_OK(hdr, length) && hdr->nlmsg_type != NLMSG_DONE) {
245                 switch (hdr->nlmsg_type) {
246                     case RTM_NEWADDR:
247                     case RTM_DELADDR:
248                         handleAddressChange(hdr);
249                         break;
250                     default:
251                         RLOGE("Received message type %d", (int)hdr->nlmsg_type);
252                         break;
253                 }
254                 NLMSG_NEXT(hdr, length);
255             }
256         }
257     }
258 
handleAddressChange(const struct nlmsghdr * hdr)259     void handleAddressChange(const struct nlmsghdr* hdr) {
260         if (!mOnAddressChangeCallback) {
261             return;
262         }
263 
264         auto msg = reinterpret_cast<const struct ifaddrmsg*>(NLMSG_DATA(hdr));
265         std::vector<ifAddress>& ifAddrs = mAddresses[msg->ifa_index];
266 
267         auto attr = reinterpret_cast<const struct rtattr*>(IFA_RTA(msg));
268         int attrLen = IFA_PAYLOAD(hdr);
269 
270         bool somethingChanged = false;
271         for (;attr && RTA_OK(attr, attrLen); attr = RTA_NEXT(attr, attrLen)) {
272             if (attr->rta_type != IFA_LOCAL && attr->rta_type != IFA_ADDRESS) {
273                 continue;
274             }
275 
276             ifAddress addr;
277             memset(&addr, 0, sizeof(addr));
278 
279             // Ensure that the payload matches the expected address length
280             if (RTA_PAYLOAD(attr) >= addrLength(msg->ifa_family)) {
281                 addr.family = msg->ifa_family;
282                 addr.prefix = msg->ifa_prefixlen;
283                 memcpy(&addr.addr, RTA_DATA(attr), addrLength(addr.family));
284             } else {
285                 RLOGE("Invalid address family (%d) and size (%d) combination",
286                       int(msg->ifa_family), int(RTA_PAYLOAD(attr)));
287                 continue;
288             }
289 
290             auto it = std::find(ifAddrs.begin(), ifAddrs.end(), addr);
291             if (hdr->nlmsg_type == RTM_NEWADDR && it == ifAddrs.end()) {
292                 // New address does not exist, add it
293                 ifAddrs.push_back(addr);
294                 somethingChanged = true;
295             } else if (hdr->nlmsg_type == RTM_DELADDR && it != ifAddrs.end()) {
296                 // Address was removed and it exists, remove it
297                 ifAddrs.erase(it);
298                 somethingChanged = true;
299             }
300         }
301 
302         if (somethingChanged) {
303             mOnAddressChangeCallback(msg->ifa_index,
304                                      ifAddrs.data(),
305                                      ifAddrs.size());
306         }
307     }
308 
309     ifMonitorCallback mOnAddressChangeCallback;
310     std::unordered_map<unsigned int, std::vector<ifAddress>> mAddresses;
311     std::unique_ptr<std::thread> mThread;
312     std::mutex mThreadMutex;
313     int mSocketFd;
314     int mControlSocket[2];
315 };
316 
317 extern "C"
ifMonitorCreate()318 struct ifMonitor* ifMonitorCreate() {
319     auto monitor = std::make_unique<InterfaceMonitor>();
320     if (!monitor || !monitor->init()) {
321         return nullptr;
322     }
323     return reinterpret_cast<struct ifMonitor*>(monitor.release());
324 }
325 
326 extern "C"
ifMonitorFree(struct ifMonitor * ifMonitor)327 void ifMonitorFree(struct ifMonitor* ifMonitor) {
328     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
329     delete monitor;
330 }
331 
332 extern "C"
ifMonitorSetCallback(struct ifMonitor * ifMonitor,ifMonitorCallback callback)333 void ifMonitorSetCallback(struct ifMonitor* ifMonitor,
334                           ifMonitorCallback callback) {
335     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
336     monitor->setCallback(callback);
337 }
338 
339 extern "C"
ifMonitorRunAsync(struct ifMonitor * ifMonitor)340 void ifMonitorRunAsync(struct ifMonitor* ifMonitor) {
341     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
342 
343     monitor->runAsync();
344 }
345 
346 extern "C"
ifMonitorStop(struct ifMonitor * ifMonitor)347 void ifMonitorStop(struct ifMonitor* ifMonitor) {
348     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
349 
350     monitor->stop();
351 }
352 
353