• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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_packet_reader.h"
6 
7 #include "absl/base/macros.h"
8 #include "quiche/quic/core/quic_packets.h"
9 #include "quiche/quic/core/quic_process_packet_interface.h"
10 #include "quiche/quic/core/quic_udp_socket.h"
11 #include "quiche/quic/core/quic_utils.h"
12 #include "quiche/quic/platform/api/quic_bug_tracker.h"
13 #include "quiche/quic/platform/api/quic_flag_utils.h"
14 #include "quiche/quic/platform/api/quic_flags.h"
15 #include "quiche/quic/platform/api/quic_ip_address.h"
16 #include "quiche/quic/platform/api/quic_logging.h"
17 #include "quiche/quic/platform/api/quic_server_stats.h"
18 #include "quiche/quic/platform/api/quic_socket_address.h"
19 
20 namespace quic {
21 
QuicPacketReader()22 QuicPacketReader::QuicPacketReader()
23     : read_buffers_(kNumPacketsPerReadMmsgCall),
24       read_results_(kNumPacketsPerReadMmsgCall) {
25   QUICHE_DCHECK_EQ(read_buffers_.size(), read_results_.size());
26   for (size_t i = 0; i < read_results_.size(); ++i) {
27     read_results_[i].packet_buffer.buffer = read_buffers_[i].packet_buffer;
28     read_results_[i].packet_buffer.buffer_len =
29         sizeof(read_buffers_[i].packet_buffer);
30 
31     read_results_[i].control_buffer.buffer = read_buffers_[i].control_buffer;
32     read_results_[i].control_buffer.buffer_len =
33         sizeof(read_buffers_[i].control_buffer);
34   }
35 }
36 
37 QuicPacketReader::~QuicPacketReader() = default;
38 
ReadAndDispatchPackets(int fd,int port,const QuicClock & clock,ProcessPacketInterface * processor,QuicPacketCount *)39 bool QuicPacketReader::ReadAndDispatchPackets(
40     int fd, int port, const QuicClock& clock, ProcessPacketInterface* processor,
41     QuicPacketCount* /*packets_dropped*/) {
42   // Reset all read_results for reuse.
43   for (size_t i = 0; i < read_results_.size(); ++i) {
44     read_results_[i].Reset(
45         /*packet_buffer_length=*/sizeof(read_buffers_[i].packet_buffer));
46   }
47 
48   // Use clock.Now() as the packet receipt time, the time between packet
49   // arriving at the host and now is considered part of the network delay.
50   QuicTime now = clock.Now();
51 
52   BitMask64 info_bits{QuicUdpPacketInfoBit::DROPPED_PACKETS,
53                       QuicUdpPacketInfoBit::PEER_ADDRESS,
54                       QuicUdpPacketInfoBit::V4_SELF_IP,
55                       QuicUdpPacketInfoBit::V6_SELF_IP,
56                       QuicUdpPacketInfoBit::RECV_TIMESTAMP,
57                       QuicUdpPacketInfoBit::TTL,
58                       QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER};
59   if (GetQuicRestartFlag(quic_receive_ecn)) {
60     QUIC_RESTART_FLAG_COUNT_N(quic_receive_ecn, 3, 3);
61     info_bits.Set(QuicUdpPacketInfoBit::ECN);
62   }
63   size_t packets_read =
64       socket_api_.ReadMultiplePackets(fd, info_bits, &read_results_);
65   for (size_t i = 0; i < packets_read; ++i) {
66     auto& result = read_results_[i];
67     if (!result.ok) {
68       QUIC_CODE_COUNT(quic_packet_reader_read_failure);
69       continue;
70     }
71 
72     if (!result.packet_info.HasValue(QuicUdpPacketInfoBit::PEER_ADDRESS)) {
73       QUIC_BUG(quic_bug_10329_1) << "Unable to get peer socket address.";
74       continue;
75     }
76 
77     QuicSocketAddress peer_address =
78         result.packet_info.peer_address().Normalized();
79 
80     QuicIpAddress self_ip = GetSelfIpFromPacketInfo(
81         result.packet_info, peer_address.host().IsIPv6());
82     if (!self_ip.IsInitialized()) {
83       QUIC_BUG(quic_bug_10329_2) << "Unable to get self IP address.";
84       continue;
85     }
86 
87     bool has_ttl = result.packet_info.HasValue(QuicUdpPacketInfoBit::TTL);
88     int ttl = has_ttl ? result.packet_info.ttl() : 0;
89     if (!has_ttl) {
90       QUIC_CODE_COUNT(quic_packet_reader_no_ttl);
91     }
92 
93     char* headers = nullptr;
94     size_t headers_length = 0;
95     if (result.packet_info.HasValue(
96             QuicUdpPacketInfoBit::GOOGLE_PACKET_HEADER)) {
97       headers = result.packet_info.google_packet_headers().buffer;
98       headers_length = result.packet_info.google_packet_headers().buffer_len;
99     } else {
100       QUIC_CODE_COUNT(quic_packet_reader_no_google_packet_header);
101     }
102 
103     QuicReceivedPacket packet(
104         result.packet_buffer.buffer, result.packet_buffer.buffer_len, now,
105         /*owns_buffer=*/false, ttl, has_ttl, headers, headers_length,
106         /*owns_header_buffer=*/false, result.packet_info.ecn_codepoint());
107     QuicSocketAddress self_address(self_ip, port);
108     processor->ProcessPacket(self_address, peer_address, packet);
109   }
110 
111   // We may not have read all of the packets available on the socket.
112   return packets_read == kNumPacketsPerReadMmsgCall;
113 }
114 
115 // static
GetSelfIpFromPacketInfo(const QuicUdpPacketInfo & packet_info,bool prefer_v6_ip)116 QuicIpAddress QuicPacketReader::GetSelfIpFromPacketInfo(
117     const QuicUdpPacketInfo& packet_info, bool prefer_v6_ip) {
118   if (prefer_v6_ip) {
119     if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP)) {
120       return packet_info.self_v6_ip();
121     }
122     if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP)) {
123       return packet_info.self_v4_ip();
124     }
125   } else {
126     if (packet_info.HasValue(QuicUdpPacketInfoBit::V4_SELF_IP)) {
127       return packet_info.self_v4_ip();
128     }
129     if (packet_info.HasValue(QuicUdpPacketInfoBit::V6_SELF_IP)) {
130       return packet_info.self_v6_ip();
131     }
132   }
133   return QuicIpAddress();
134 }
135 
136 }  // namespace quic
137