1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "quiche/quic/core/quic_server_id.h"
6
7 #include <string>
8 #include <tuple>
9 #include <utility>
10
11 #include "absl/strings/match.h"
12 #include "absl/strings/str_cat.h"
13 #include "absl/strings/string_view.h"
14 #include "absl/types/optional.h"
15 #include "url/third_party/mozilla/url_parse.h"
16 #include "quiche/common/platform/api/quiche_logging.h"
17
18 namespace quic {
19
20 // static
ParseFromHostPortString(absl::string_view host_port_string)21 absl::optional<QuicServerId> QuicServerId::ParseFromHostPortString(
22 absl::string_view host_port_string) {
23 url::Component username_component;
24 url::Component password_component;
25 url::Component host_component;
26 url::Component port_component;
27
28 url::ParseAuthority(host_port_string.data(),
29 url::Component(0, host_port_string.size()),
30 &username_component, &password_component, &host_component,
31 &port_component);
32
33 // Only support "host:port" and nothing more or less.
34 if (username_component.is_valid() || password_component.is_valid() ||
35 !host_component.is_nonempty() || !port_component.is_nonempty()) {
36 QUICHE_DVLOG(1) << "QuicServerId could not be parsed: " << host_port_string;
37 return absl::nullopt;
38 }
39
40 std::string hostname(host_port_string.data() + host_component.begin,
41 host_component.len);
42
43 int parsed_port_number =
44 url::ParsePort(host_port_string.data(), port_component);
45 // Negative result is either invalid or unspecified, either of which is
46 // disallowed for this parse. Port 0 is technically valid but reserved and not
47 // really usable in practice, so easiest to just disallow it here.
48 if (parsed_port_number <= 0) {
49 QUICHE_DVLOG(1)
50 << "Port could not be parsed while parsing QuicServerId from: "
51 << host_port_string;
52 return absl::nullopt;
53 }
54 QUICHE_DCHECK_LE(parsed_port_number, std::numeric_limits<uint16_t>::max());
55
56 return QuicServerId(std::move(hostname),
57 static_cast<uint16_t>(parsed_port_number));
58 }
59
QuicServerId()60 QuicServerId::QuicServerId() : QuicServerId("", 0, false) {}
61
QuicServerId(std::string host,uint16_t port)62 QuicServerId::QuicServerId(std::string host, uint16_t port)
63 : QuicServerId(std::move(host), port, false) {}
64
QuicServerId(std::string host,uint16_t port,bool privacy_mode_enabled)65 QuicServerId::QuicServerId(std::string host, uint16_t port,
66 bool privacy_mode_enabled)
67 : host_(std::move(host)),
68 port_(port),
69 privacy_mode_enabled_(privacy_mode_enabled) {}
70
~QuicServerId()71 QuicServerId::~QuicServerId() {}
72
operator <(const QuicServerId & other) const73 bool QuicServerId::operator<(const QuicServerId& other) const {
74 return std::tie(port_, host_, privacy_mode_enabled_) <
75 std::tie(other.port_, other.host_, other.privacy_mode_enabled_);
76 }
77
operator ==(const QuicServerId & other) const78 bool QuicServerId::operator==(const QuicServerId& other) const {
79 return privacy_mode_enabled_ == other.privacy_mode_enabled_ &&
80 host_ == other.host_ && port_ == other.port_;
81 }
82
operator !=(const QuicServerId & other) const83 bool QuicServerId::operator!=(const QuicServerId& other) const {
84 return !(*this == other);
85 }
86
ToHostPortString() const87 std::string QuicServerId::ToHostPortString() const {
88 return absl::StrCat(GetHostWithIpv6Brackets(), ":", port_);
89 }
90
GetHostWithoutIpv6Brackets() const91 absl::string_view QuicServerId::GetHostWithoutIpv6Brackets() const {
92 if (host_.length() > 2 && host_.front() == '[' && host_.back() == ']') {
93 return absl::string_view(host_.data() + 1, host_.length() - 2);
94 } else {
95 return host_;
96 }
97 }
98
GetHostWithIpv6Brackets() const99 std::string QuicServerId::GetHostWithIpv6Brackets() const {
100 if (!absl::StrContains(host_, ':') || host_.length() <= 2 ||
101 (host_.front() == '[' && host_.back() == ']')) {
102 return host_;
103 } else {
104 return absl::StrCat("[", host_, "]");
105 }
106 }
107
108 } // namespace quic
109