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