Home | History | Annotate | Download | only in ril
      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 
     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 
     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:
     71     InterfaceMonitor() : mSocketFd(-1) {
     72         mControlSocket[kControlServer] = -1;
     73         mControlSocket[kControlClient] = -1;
     74     }
     75 
     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 
     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 
    127     void setCallback(ifMonitorCallback callback) {
    128         mOnAddressChangeCallback = callback;
    129     }
    130 
    131     void runAsync() {
    132         std::unique_lock<std::mutex> lock(mThreadMutex);
    133         mThread = std::make_unique<std::thread>([this]() { run(); });
    134     }
    135 
    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 
    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 
    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:
    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 
    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"
    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"
    327 void ifMonitorFree(struct ifMonitor* ifMonitor) {
    328     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
    329     delete monitor;
    330 }
    331 
    332 extern "C"
    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"
    340 void ifMonitorRunAsync(struct ifMonitor* ifMonitor) {
    341     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
    342 
    343     monitor->runAsync();
    344 }
    345 
    346 extern "C"
    347 void ifMonitorStop(struct ifMonitor* ifMonitor) {
    348     InterfaceMonitor* monitor = reinterpret_cast<InterfaceMonitor*>(ifMonitor);
    349 
    350     monitor->stop();
    351 }
    352 
    353