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