• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "mdns_socket_listener.h"
17 
18 #include <arpa/inet.h>
19 #include <fcntl.h>
20 #include <ifaddrs.h>
21 #include <net/if.h>
22 #include <netinet/in.h>
23 #include <sys/select.h>
24 #include <sys/socket.h>
25 #include <sys/time.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <cassert>
29 #include <cerrno>
30 #include <cstdlib>
31 #include <cstring>
32 #include <pthread.h>
33 #include <iostream>
34 #include <algorithm>
35 
36 #include "netmgr_ext_log_wrapper.h"
37 
38 namespace OHOS {
39 namespace NetManagerStandard {
40 
41 namespace {
42 constexpr uint32_t MDNS_MULTICAST_INADDR = (224U << 24) | 251U;
43 constexpr in6_addr MDNS_MULTICAST_IN6ADDR = {
44     {{0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB}}};
45 
46 constexpr const char *CONTROL_TAG_REFRESH = "R";
47 
48 constexpr uint16_t MDNS_PORT = 5353;
49 constexpr size_t RECV_BUFFER = 2000;
50 constexpr int WAIT_THREAD_MS = 5;
51 constexpr size_t MDNS_MAX_SOCKET = 16;
52 constexpr size_t REFRESH_BUFFER_LEN = 2;
53 
IfaceIsSupported(ifaddrs * ifa)54 inline bool IfaceIsSupported(ifaddrs *ifa)
55 {
56     return ifa->ifa_addr && ((ifa->ifa_flags & IFF_UP) && (ifa->ifa_flags & IFF_MULTICAST)) &&
57            (!(ifa->ifa_flags & IFF_LOOPBACK) && !(ifa->ifa_flags & IFF_POINTOPOINT));
58 }
59 
InitFdFlags(int sock)60 int InitFdFlags(int sock)
61 {
62     const int flags = fcntl(sock, F_GETFL, 0);
63     if (flags == -1) {
64         return -1;
65     }
66     if (fcntl(sock, F_SETFL, static_cast<uint32_t>(flags) | O_NONBLOCK) == -1) {
67         return -1;
68     }
69     return 0;
70 }
71 
InitReusedSocket(int sock)72 int InitReusedSocket(int sock)
73 {
74     const int enable = 1;
75     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char *>(&enable), sizeof(enable)) != 0) {
76         return -1;
77     }
78     if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast<const char *>(&enable), sizeof(enable)) != 0) {
79         return -1;
80     }
81     return sock;
82 }
83 
InitSocketV4(int sock,ifaddrs * ifa,int port)84 int InitSocketV4(int sock, ifaddrs *ifa, int port)
85 {
86     const int one = 1;
87     const int maxtll = 255;
88 
89     if (sock < 0) {
90         NETMGR_EXT_LOG_E("mdns_log sock [%{public}d] error", sock);
91         return -1;
92     }
93     if (port != 0 && InitReusedSocket(sock) < 0) {
94         NETMGR_EXT_LOG_E("mdns_log InitReusedSocket error");
95         return -1;
96     }
97 
98     bool allOK =
99         (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, reinterpret_cast<const char *>(&one), sizeof(one)) == 0) &&
100         (setsockopt(sock, IPPROTO_IP, IP_PKTINFO, reinterpret_cast<const char *>(&one), sizeof(one)) == 0) &&
101         (setsockopt(sock, IPPROTO_IP, IP_TTL, reinterpret_cast<const char *>(&maxtll), sizeof(maxtll)) == 0) &&
102         (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, reinterpret_cast<const char *>(&maxtll), sizeof(maxtll)) == 0);
103     if (!allOK) {
104         NETMGR_EXT_LOG_E("mdns_log setsockopt IP_MULTICAST_LOOP|IP_PKTINFO|IP_TTL|IP_MULTICAST_TTL error");
105         return -1;
106     }
107 
108     sockaddr_in sockAddr{};
109 
110     ip_mreq mreq{};
111     mreq.imr_multiaddr.s_addr = htonl(MDNS_MULTICAST_INADDR);
112     mreq.imr_interface = ifa ? reinterpret_cast<sockaddr_in *>(ifa->ifa_addr)->sin_addr : in_addr{INADDR_ANY};
113     allOK =
114         (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, reinterpret_cast<const char *>(&mreq), sizeof(mreq)) == 0) &&
115         (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, reinterpret_cast<const char *>(&mreq.imr_interface),
116                     sizeof(in_addr)) == 0);
117     if (!allOK) {
118         NETMGR_EXT_LOG_E("mdns_log setsockopt IP_ADD_MEMBERSHIP|IP_MULTICAST_IF error");
119         return -1;
120     }
121 
122     sockAddr.sin_family = AF_INET;
123     sockAddr.sin_addr.s_addr = INADDR_ANY;
124     sockAddr.sin_port = htons(port);
125 
126     if (bind(sock, reinterpret_cast<sockaddr *>(&sockAddr), sizeof(sockaddr_in)) != 0) {
127         NETMGR_EXT_LOG_E("mdns_log bind failed, errno:[%{public}d]", errno);
128         return -1;
129     }
130 
131     return InitFdFlags(sock);
132 }
133 
InitSocketV6(int sock,ifaddrs * ifa,int port)134 int InitSocketV6(int sock, ifaddrs *ifa, int port)
135 {
136     const int one = 1;
137     const int max = 255;
138 
139     if (sock < 0) {
140         return -1;
141     }
142     if (port != 0 && InitReusedSocket(sock) < 0) {
143         return -1;
144     }
145 
146     bool allOK =
147         (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, reinterpret_cast<const char *>(&one), sizeof(one)) == 0) &&
148         (setsockopt(sock, IPPROTO_IPV6, IPV6_2292PKTINFO, reinterpret_cast<const char *>(&one), sizeof(one)) == 0) &&
149         (setsockopt(sock, IPPROTO_IPV6, IPV6_2292HOPLIMIT, reinterpret_cast<const char *>(&one), sizeof(one)) == 0) &&
150         (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<const char *>(&one), sizeof(one)) == 0) &&
151         (setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, reinterpret_cast<const char *>(&max), sizeof(max)) == 0) &&
152         (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, reinterpret_cast<const char *>(&max), sizeof(max)) == 0);
153     if (!allOK) {
154         return -1;
155     }
156 
157     sockaddr_in6 sockAddr{};
158 
159     unsigned int ifaceIndex = ifa ? if_nametoindex(ifa->ifa_name) : 0;
160     ipv6_mreq mreq{};
161     mreq.ipv6mr_multiaddr = MDNS_MULTICAST_IN6ADDR;
162     mreq.ipv6mr_interface = ifaceIndex;
163     allOK =
164         (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, reinterpret_cast<const char *>(&mreq), sizeof(mreq)) == 0) &&
165         (setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, reinterpret_cast<const char *>(&ifaceIndex),
166                     sizeof(ifaceIndex)) == 0);
167     if (!allOK) {
168         return -1;
169     }
170 
171     sockAddr.sin6_family = AF_INET6;
172     sockAddr.sin6_addr = in6addr_any;
173     sockAddr.sin6_port = htons(port);
174     sockAddr.sin6_flowinfo = 0;
175     sockAddr.sin6_scope_id = 0;
176 
177     if (bind(sock, reinterpret_cast<sockaddr *>(&sockAddr), sizeof(sockaddr_in6)) != 0) {
178         NETMGR_EXT_LOG_E("mdns_log bind failed, errno:[%{public}d]", errno);
179         return -1;
180     }
181 
182     return InitFdFlags(sock);
183 }
184 
185 } // namespace
186 
MDnsSocketListener()187 MDnsSocketListener::MDnsSocketListener()
188 {
189     if (socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, ctrlPair_) != 0) {
190         NETMGR_EXT_LOG_F("mdns_log bind failed, errno:[%{public}d]", errno);
191     }
192 }
193 
~MDnsSocketListener()194 MDnsSocketListener::~MDnsSocketListener()
195 {
196     Stop();
197 }
198 
Start()199 void MDnsSocketListener::Start()
200 {
201     if (std::this_thread::get_id() == thread_.get_id()) {
202         return;
203     }
204     if (!runningFlag_) {
205         runningFlag_ = true;
206         thread_ = std::thread([this]() { Run(); });
207         std::string threadName = "MDnsSockListen";
208         pthread_setname_np(thread_.native_handle(), threadName.c_str());
209         std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_THREAD_MS));
210     }
211 }
212 
Stop()213 void MDnsSocketListener::Stop()
214 {
215     if (std::this_thread::get_id() == thread_.get_id()) {
216         return;
217     }
218     if (runningFlag_) {
219         runningFlag_ = false;
220         TriggerRefresh();
221         if (thread_.joinable()) {
222             thread_.join();
223         }
224     }
225 }
226 
OpenSocketForEachIface(bool ipv6Support,bool lo)227 void MDnsSocketListener::OpenSocketForEachIface(bool ipv6Support, bool lo)
228 {
229     ifaddrs *ifaddr = nullptr;
230     ifaddrs *loaddr = nullptr;
231 
232     if (getifaddrs(&ifaddr) < 0) {
233         NETMGR_EXT_LOG_F("mdns_log getifaddrs failed, errno=[%{public}d]", errno);
234         return;
235     }
236 
237     for (ifaddrs *ifa = ifaddr; ifa != nullptr && socks_.size() < MDNS_MAX_SOCKET; ifa = ifa->ifa_next) {
238         if (ifa->ifa_addr == nullptr || (ifa->ifa_addr->sa_family != AF_INET && ifa->ifa_addr->sa_family != AF_INET6)) {
239             continue;
240         }
241 
242         std::string ifName(ifa->ifa_name);
243         std::transform(ifName.begin(), ifName.end(), ifName.begin(), ::tolower);
244         if (ifName.find("p2p") != std::string::npos) {
245             continue;
246         }
247 
248         if ((ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_addr->sa_family == AF_INET) {
249             loaddr = ifa;
250             continue;
251         }
252         if (!IfaceIsSupported(ifa)) {
253             NETMGR_EXT_LOG_I("mdns_log iface [%{public}s] is mismatch", ifa->ifa_name);
254             continue;
255         }
256         if (ifa->ifa_addr->sa_family == AF_INET) {
257             OpenSocketV4(ifa);
258         } else if (ifa->ifa_addr->sa_family == AF_INET6) {
259             OpenSocketV6(ifa, ipv6Support);
260         }
261     }
262 
263     if (lo && socks_.size() == 0 && loaddr && loaddr->ifa_addr) {
264         OpenSocketV4(loaddr);
265     }
266 
267     freeifaddrs(ifaddr);
268 
269     if (socks_.size() == 0) {
270         NETMGR_EXT_LOG_F("mdns_log no available iface found");
271     }
272 }
273 
OpenSocketV4(ifaddrs * ifa)274 void MDnsSocketListener::OpenSocketV4(ifaddrs *ifa)
275 {
276     sockaddr_in *saddr = reinterpret_cast<sockaddr_in *>(ifa->ifa_addr);
277     int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
278     if (sock < 0) {
279         NETMGR_EXT_LOG_E("mdns_log socket create failed, errno:[%{public}d]", errno);
280         return;
281     }
282     if (InitSocketV4(sock, ifa, MDNS_PORT)) {
283         NETMGR_EXT_LOG_E("mdns_log InitSocketV4 failed, errno=[%{public}d]", errno);
284         close(sock);
285     } else {
286         socks_.emplace_back(sock);
287         iface_[sock] = ifa->ifa_name;
288         reinterpret_cast<sockaddr_in *>(&saddr_[sock])->sin_family = AF_INET;
289         reinterpret_cast<sockaddr_in *>(&saddr_[sock])->sin_addr = saddr->sin_addr;
290     }
291     NETMGR_EXT_LOG_I("mdns_log iface found, ifa_name=[%{public}s]", ifa->ifa_name);
292 }
293 
InetAddrV6IsLoopback(const in6_addr * addr6)294 inline bool InetAddrV6IsLoopback(const in6_addr *addr6)
295 {
296     return IN6_IS_ADDR_LOOPBACK(addr6);
297 }
298 
OpenSocketV6(ifaddrs * ifa,bool ipv6Support)299 void MDnsSocketListener::OpenSocketV6(ifaddrs *ifa, bool ipv6Support)
300 {
301     if (!ipv6Support || IN6_IS_ADDR_LOOPBACK(&reinterpret_cast<sockaddr_in6 *>(ifa->ifa_addr)->sin6_addr) ||
302         (reinterpret_cast<sockaddr_in6 *>(ifa->ifa_addr)->sin6_scope_id != 0)) {
303         NETMGR_EXT_LOG_D("mdns_log ipv6 not supported");
304         return;
305     }
306     sockaddr_in6 *saddr = reinterpret_cast<sockaddr_in6 *>(ifa->ifa_addr);
307     int sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
308     if (sock < 0) {
309         NETMGR_EXT_LOG_E("mdns_log socket create failed, errno:[%{public}d]", errno);
310         return;
311     }
312     if (InitSocketV6(sock, ifa, MDNS_PORT)) {
313         NETMGR_EXT_LOG_E("mdns_log InitSocketV6 failed, errno=[%{public}d]", errno);
314         close(sock);
315     } else {
316         socks_.emplace_back(sock);
317         iface_[sock] = ifa->ifa_name;
318         reinterpret_cast<sockaddr_in6 *>(&saddr_[sock])->sin6_family = AF_INET6;
319         reinterpret_cast<sockaddr_in6 *>(&saddr_[sock])->sin6_addr = saddr->sin6_addr;
320     }
321     NETMGR_EXT_LOG_I("mdns_log iface found, ifa_name=[%{public}s]", ifa->ifa_name);
322 }
323 
OpenSocketForDefault(bool ipv6Support)324 void MDnsSocketListener::OpenSocketForDefault(bool ipv6Support)
325 {
326     int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
327     if (socks_.size() < MDNS_MAX_SOCKET && InitSocketV4(sock, nullptr, MDNS_PORT)) {
328         close(sock);
329     } else {
330         socks_.emplace_back(sock);
331     }
332     if (!ipv6Support) {
333         return;
334     }
335     int sock6 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
336     if (socks_.size() < MDNS_MAX_SOCKET && InitSocketV6(sock6, nullptr, MDNS_PORT)) {
337         close(sock6);
338     } else {
339         socks_.emplace_back(sock6);
340     }
341 }
342 
CloseAllSocket()343 void MDnsSocketListener::CloseAllSocket()
344 {
345     for (size_t i = 0; i < socks_.size() && i < MDNS_MAX_SOCKET; ++i) {
346         close(socks_[i]);
347     }
348     socks_.clear();
349     iface_.clear();
350 }
351 
Run()352 void MDnsSocketListener::Run()
353 {
354     while (runningFlag_) {
355         fd_set rfds;
356         FD_ZERO(&rfds);
357         FD_SET(ctrlPair_[0], &rfds);
358         int nfds = ctrlPair_[0] + 1;
359         for (size_t i = 0; i < socks_.size(); ++i) {
360             FD_SET(socks_[i], &rfds);
361             nfds = std::max(nfds, socks_[i] + 1);
362         }
363         timeval timeout{.tv_sec = 1, .tv_usec = 0};
364         int res = select(nfds, &rfds, 0, 0, &timeout);
365         if (res < 0) {
366             continue;
367         }
368         if (FD_ISSET(ctrlPair_[0], &rfds)) {
369             CanRefresh();
370         }
371         for (size_t i = 0; i < socks_.size() && i < MDNS_MAX_SOCKET; ++i) {
372             if (FD_ISSET(socks_[i], &rfds)) {
373                 ReceiveInSock(socks_[i]);
374             }
375         }
376         if (static_cast<bool>(finished_)) {
377             finished_(ctrlPair_[0]);
378         }
379     }
380     NETMGR_EXT_LOG_I("mdns_log listener stopped");
381 }
382 
ReceiveInSock(int sock)383 void MDnsSocketListener::ReceiveInSock(int sock)
384 {
385     sockaddr_storage addr{};
386     sockaddr *saddr = (sockaddr *)&addr;
387     socklen_t addrlen = sizeof(addr);
388     MDnsPayload payload(RECV_BUFFER);
389     msghdr msg{};
390     iovec iov[1];
391     cmsghdr *cmptr;
392     union {
393         cmsghdr cm;
394         char control[CMSG_SPACE(sizeof(in6_pktinfo))];
395     } control_un;
396     msg.msg_control = control_un.control;
397     msg.msg_controllen = sizeof(control_un.control);
398     msg.msg_flags = 0;
399     msg.msg_name = saddr;
400     msg.msg_namelen = addrlen;
401     iov[0].iov_base = payload.data();
402     iov[0].iov_len = payload.size();
403     msg.msg_iov = iov;
404     msg.msg_iovlen = 1;
405 
406     ssize_t recvLen = recvmsg(sock, &msg, 0);
407     if (recvLen <= 0) {
408         NETMGR_EXT_LOG_E("mdns_log recvmsg return: [%{public}zd], errno:[%{public}d]", recvLen, errno);
409         return;
410     }
411 
412     int ifIndex = -1;
413     for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != nullptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) {
414         if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO) {
415             ifIndex = reinterpret_cast<in_pktinfo *>(CMSG_DATA(cmptr))->ipi_ifindex;
416         }
417         if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == IPV6_2292PKTINFO) {
418             ifIndex = static_cast<int>(reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cmptr))->ipi6_ifindex);
419         }
420     }
421 
422     char ifName[IFNAMSIZ] = {0};
423     if (if_indextoname(static_cast<unsigned>(ifIndex), ifName) == nullptr) {
424         NETMGR_EXT_LOG_E("mdns_log if_indextoname failed, errno:[%{public}d]", errno);
425     }
426     if (ifName == iface_[sock] && recvLen > 0 && recv_) {
427         payload.resize(static_cast<size_t>(recvLen));
428         recv_(sock, payload);
429     }
430 }
431 
TriggerRefresh()432 void MDnsSocketListener::TriggerRefresh()
433 {
434     write(ctrlPair_[1], CONTROL_TAG_REFRESH, 1);
435 }
436 
CanRefresh()437 bool MDnsSocketListener::CanRefresh()
438 {
439     char buf[REFRESH_BUFFER_LEN] = {};
440     read(ctrlPair_[0], buf, 1);
441     return (std::string_view(buf) == CONTROL_TAG_REFRESH);
442 }
443 
Multicast(int sock,const MDnsPayload & payload)444 ssize_t MDnsSocketListener::Multicast(int sock, const MDnsPayload &payload)
445 {
446     NETMGR_EXT_LOG_I("mdns_log Multicast");
447     const sockaddr *saddrIf = GetSockAddr(sock);
448     if (saddrIf == nullptr) {
449         NETMGR_EXT_LOG_E("mdns_log GetSockAddr failed");
450         return -1;
451     }
452 
453     if (saddrIf->sa_family == AF_INET) {
454         in_addr addr;
455         addr.s_addr = htonl(MDNS_MULTICAST_INADDR);
456         sockaddr_in saddr{.sin_family = AF_INET, .sin_port = htons(MDNS_PORT), .sin_addr = addr};
457         return sendto(sock, payload.data(), payload.size(), 0, reinterpret_cast<const sockaddr *>(&saddr),
458                       sizeof(saddr));
459     }
460     if (saddrIf->sa_family == AF_INET6) {
461         sockaddr_in6 saddr{.sin6_family = AF_INET6, .sin6_port = htons(MDNS_PORT), .sin6_addr = MDNS_MULTICAST_IN6ADDR};
462         return sendto(sock, payload.data(), payload.size(), 0, reinterpret_cast<const sockaddr *>(&saddr),
463                       sizeof(saddr));
464     }
465     return -1;
466 }
467 
Unicast(int sock,sockaddr * saddr,const MDnsPayload & payload)468 ssize_t MDnsSocketListener::Unicast(int sock, sockaddr *saddr, const MDnsPayload &payload)
469 {
470     socklen_t saddrLen = 0;
471     if (saddr->sa_family == AF_INET) {
472         saddrLen = sizeof(sockaddr_in);
473     } else if (saddr->sa_family == AF_INET6) {
474         saddrLen = sizeof(sockaddr_in6);
475     } else {
476         return -1;
477     }
478     return sendto(sock, payload.data(), payload.size(), 0, saddr, saddrLen);
479 }
480 
MulticastAll(const MDnsPayload & payload)481 ssize_t MDnsSocketListener::MulticastAll(const MDnsPayload &payload)
482 {
483     ssize_t total = 0;
484     for (size_t i = 0; i < socks_.size() && i < MDNS_MAX_SOCKET; ++i) {
485         ssize_t sendLen = Multicast(socks_[i], payload);
486         if (sendLen == -1) {
487             return sendLen;
488         }
489         total += sendLen;
490     }
491     return total;
492 }
493 
GetSockets() const494 const std::vector<int> &MDnsSocketListener::GetSockets() const
495 {
496     return socks_;
497 }
498 
SetReceiveHandler(const ReceiveHandler & callback)499 void MDnsSocketListener::SetReceiveHandler(const ReceiveHandler &callback)
500 {
501     recv_ = callback;
502 }
503 
SetFinishedHandler(const FinishedHandler & callback)504 void MDnsSocketListener::SetFinishedHandler(const FinishedHandler &callback)
505 {
506     finished_ = callback;
507 }
508 
GetIface(int sock) const509 std::string_view MDnsSocketListener::GetIface(int sock) const
510 {
511     auto i = iface_.find(sock);
512     return i == iface_.end() ? std::string_view{} : i->second;
513 }
514 
GetSockAddr(int sock) const515 const sockaddr *MDnsSocketListener::GetSockAddr(int sock) const
516 {
517     auto i = saddr_.find(sock);
518     return i == saddr_.end() ? nullptr : reinterpret_cast<const sockaddr *>(&(i->second));
519 }
520 } // namespace NetManagerStandard
521 } // namespace OHOS
522