/Users/deen/code/yugabyte-db/src/yb/util/net/sockaddr.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // |
18 | | // The following only applies to changes made to this file as part of YugaByte development. |
19 | | // |
20 | | // Portions Copyright (c) YugaByte, Inc. |
21 | | // |
22 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
23 | | // in compliance with the License. You may obtain a copy of the License at |
24 | | // |
25 | | // http://www.apache.org/licenses/LICENSE-2.0 |
26 | | // |
27 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
28 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
29 | | // or implied. See the License for the specific language governing permissions and limitations |
30 | | // under the License. |
31 | | // |
32 | | #include "yb/util/net/sockaddr.h" |
33 | | |
34 | | #include <stdio.h> |
35 | | #include <string.h> |
36 | | |
37 | | #include <string> |
38 | | |
39 | | #include <boost/functional/hash.hpp> |
40 | | #include <boost/lexical_cast.hpp> |
41 | | |
42 | | #include "yb/gutil/macros.h" |
43 | | #include "yb/gutil/stringprintf.h" |
44 | | #include "yb/util/result.h" |
45 | | #include "yb/util/status_format.h" |
46 | | |
47 | | namespace yb { |
48 | | |
49 | | using strings::Substitute; |
50 | | |
51 | 27.8M | std::string ToString(const Endpoint& endpoint) { |
52 | 27.8M | return boost::lexical_cast<std::string>(endpoint); |
53 | 27.8M | } |
54 | | |
55 | 181M | std::size_t hash_value(const IpAddress& address) { |
56 | 181M | size_t seed = 0; |
57 | | |
58 | 181M | if (address.is_v4()) { |
59 | 181M | boost::hash_combine(seed, address.to_v4().to_ulong()); |
60 | 181M | } else { |
61 | 24.6k | boost::hash_combine(seed, address.to_v6().to_bytes()); |
62 | 24.6k | } |
63 | | |
64 | 181M | return seed; |
65 | 181M | } |
66 | | |
67 | 181M | std::size_t hash_value(const Endpoint& endpoint) { |
68 | 181M | size_t seed = 0; |
69 | | |
70 | 181M | boost::hash_combine(seed, hash_value(endpoint.address())); |
71 | 181M | boost::hash_combine(seed, endpoint.port()); |
72 | | |
73 | 181M | return seed; |
74 | 181M | } |
75 | | |
76 | 1.93k | Result<Endpoint> ParseEndpoint(const std::string& input, uint16_t default_port) { |
77 | 1.93k | boost::system::error_code ec; |
78 | | // First of all we try to parse whole string as address w/o port. |
79 | | // Important for IPv6 addesses like fe80::1:1. |
80 | 1.93k | auto address = IpAddress::from_string(input, ec); |
81 | 1.93k | if (!ec) { |
82 | 3 | return Endpoint(address, default_port); |
83 | 3 | } |
84 | | |
85 | 1.93k | std::string::size_type pos = 0; |
86 | 1.93k | std::string::size_type address_begin, address_end; |
87 | | |
88 | 1.93k | if (!input.empty() && input[0] == '[') { |
89 | 7 | pos = input.find(']'); |
90 | 7 | if (pos != std::string::npos) { |
91 | 6 | address_begin = 1; |
92 | 6 | address_end = pos; |
93 | 6 | if (++pos >= input.size()) { |
94 | 2 | pos = std::string::npos; |
95 | 2 | } |
96 | 6 | } else { |
97 | 1 | return STATUS_SUBSTITUTE(NetworkError, "']' missing in $0", input); |
98 | 1 | } |
99 | 1.92k | } else { |
100 | 1.92k | address_begin = 0; |
101 | 1.92k | pos = input.find(':'); |
102 | 1.92k | address_end = pos != std::string::npos ? pos : input.size()0 ; |
103 | 1.92k | } |
104 | 1.93k | auto address_str = input.substr(address_begin, address_end - address_begin); |
105 | 1.93k | address = IpAddress::from_string(address_str, ec); |
106 | 1.93k | if (ec) { |
107 | 1 | return STATUS_FORMAT(NetworkError, "Failed to parse $0: $1", input, ec); |
108 | 1 | } |
109 | 1.93k | if (pos == std::string::npos) { |
110 | 2 | return Endpoint(address, default_port); |
111 | 2 | } |
112 | 1.92k | if (input[pos] != ':') { |
113 | 0 | return STATUS_SUBSTITUTE(NetworkError, "':' missing after ']' in $0", input); |
114 | 0 | } |
115 | 1.92k | ++pos; |
116 | 1.92k | if (pos == input.size()) { |
117 | 1 | return STATUS_SUBSTITUTE(NetworkError, "Port not specified in $0", input); |
118 | 1 | } |
119 | 1.92k | char *end = nullptr; |
120 | 1.92k | auto port = strtoul(input.c_str() + pos, &end, 10); |
121 | 1.92k | if (port > 0xffff || end != input.c_str() + input.size()) { |
122 | 0 | return STATUS_SUBSTITUTE(NetworkError, "Invalid port in $0", input); |
123 | 0 | } |
124 | 1.92k | return Endpoint(address, port); |
125 | 1.92k | } |
126 | | |
127 | | } // namespace yb |