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_common.h"
17
18 namespace OHOS {
19 namespace NetManagerStandard {
20
21 namespace {
22 constexpr const char *MDNS_TYPE_TCP = "_tcp";
23 constexpr const char *MDNS_TYPE_UDP = "_udp";
24 constexpr const char *MDNS_TYPE_PREFIX = "_";
25 constexpr size_t MDNS_TYPE_SEGMENT = 2;
26 constexpr size_t MDNS_INSTANCE_SEGMENT = 3;
27 constexpr size_t MDNS_NAME_IDX = 0;
28 constexpr size_t MDNS_TYPE1_IDX = 1;
29 constexpr size_t MDNS_TYPE2_IDX = 2;
30
31 } // namespace
32
EndsWith(const std::string_view & str,const std::string_view & pat)33 bool EndsWith(const std::string_view &str, const std::string_view &pat)
34 {
35 if (str.length() < pat.length()) {
36 return false;
37 }
38 return std::mismatch(pat.rbegin(), pat.rend(), str.rbegin()).first == pat.rend();
39 }
40
StartsWith(const std::string_view & str,const std::string_view & pat)41 bool StartsWith(const std::string_view &str, const std::string_view &pat)
42 {
43 if (str.length() < pat.length()) {
44 return false;
45 }
46 return std::mismatch(pat.begin(), pat.end(), str.begin()).first == pat.end();
47 }
48
Split(const std::string_view & s,char seperator)49 std::vector<std::string_view> Split(const std::string_view &s, char seperator)
50 {
51 std::vector<std::string_view> output;
52 std::string::size_type prev = 0;
53 std::string::size_type pos = 0;
54 while ((pos = s.find(seperator, pos)) != std::string::npos) {
55 if (pos - prev > 0) {
56 output.push_back(s.substr(prev, pos - prev));
57 }
58 prev = ++pos;
59 }
60 if (prev < s.size()) {
61 output.push_back(s.substr(prev));
62 }
63 return output;
64 }
65
IsNameValid(const std::string & name)66 bool IsNameValid(const std::string &name)
67 {
68 return 0 < name.size() && name.size() <= MDNS_MAX_DOMAIN_LABEL &&
69 name.find(MDNS_DOMAIN_SPLITER) == std::string::npos;
70 }
71
IsTypeValid(const std::string & type)72 bool IsTypeValid(const std::string &type)
73 {
74 auto views = Split(type, MDNS_DOMAIN_SPLITER);
75 return views.size() == MDNS_TYPE_SEGMENT && views[0].size() <= MDNS_MAX_DOMAIN_LABEL &&
76 StartsWith(views[0], MDNS_TYPE_PREFIX) && (views[1] == MDNS_TYPE_UDP || views[1] == MDNS_TYPE_TCP);
77 }
78
IsPortValid(int port)79 bool IsPortValid(int port)
80 {
81 return 0 <= port && port <= UINT16_MAX;
82 }
83
IsInstanceValid(const std::string & instance)84 bool IsInstanceValid(const std::string &instance)
85 {
86 auto views = Split(instance, MDNS_DOMAIN_SPLITER);
87 return views.size() == MDNS_INSTANCE_SEGMENT && views[MDNS_NAME_IDX].size() <= MDNS_MAX_DOMAIN_LABEL &&
88 views[MDNS_TYPE1_IDX].size() <= MDNS_MAX_DOMAIN_LABEL &&
89 StartsWith(views[MDNS_TYPE1_IDX], MDNS_TYPE_PREFIX) &&
90 (views[MDNS_TYPE2_IDX] == MDNS_TYPE_UDP || views[MDNS_TYPE2_IDX] == MDNS_TYPE_TCP);
91 }
92
IsDomainValid(const std::string & domain)93 bool IsDomainValid(const std::string &domain)
94 {
95 return domain.size() + static_cast<size_t>(!EndsWith(domain, MDNS_DOMAIN_SPLITER_STR)) <= MDNS_MAX_DOMAIN;
96 }
97
ExtractNameAndType(const std::string & instance,std::string & name,std::string & type)98 void ExtractNameAndType(const std::string &instance, std::string &name, std::string &type)
99 {
100 auto views = Split(instance, MDNS_DOMAIN_SPLITER);
101 if (views.size() == MDNS_INSTANCE_SEGMENT || views.size() == MDNS_INSTANCE_SEGMENT + 1) {
102 name = std::string(views[MDNS_NAME_IDX].begin(), views[MDNS_NAME_IDX].end());
103 type = std::string(views[MDNS_TYPE1_IDX].begin(), views[MDNS_TYPE2_IDX].end());
104 }
105 }
106
107 } // namespace NetManagerStandard
108 } // namespace OHOS
109