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