• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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