Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(411)

Unified Diff: net/tools/quic/quic_dispatcher.cc

Issue 123303003: Move all the packet parsing logic into QuicDispatcher from the (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/tools/quic/quic_dispatcher.h ('k') | net/tools/quic/quic_dispatcher_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/tools/quic/quic_dispatcher.cc
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc
index 297234d9755b176210acaa50cb2b3a75fe315c8c..21070169a979d8e1f082f78bdddc1637be4db411 100644
--- a/net/tools/quic/quic_dispatcher.cc
+++ b/net/tools/quic/quic_dispatcher.cc
@@ -17,6 +17,7 @@
namespace net {
namespace tools {
+using base::StringPiece;
using std::make_pair;
class DeleteSessionsAlarm : public EpollAlarm {
@@ -35,6 +36,90 @@ class DeleteSessionsAlarm : public EpollAlarm {
QuicDispatcher* dispatcher_;
};
+class QuicDispatcher::QuicFramerVisitor : public QuicFramerVisitorInterface {
+ public:
+ explicit QuicFramerVisitor(QuicDispatcher* dispatcher)
+ : dispatcher_(dispatcher) {
+ }
+
+ // QuicFramerVisitorInterface implementation
+ virtual void OnPacket() OVERRIDE {}
+ virtual bool OnUnauthenticatedPublicHeader(
+ const QuicPacketPublicHeader& header) OVERRIDE {
+ return dispatcher_->OnUnauthenticatedPublicHeader(header);
+ }
+ virtual bool OnUnauthenticatedHeader(
+ const QuicPacketHeader& header) OVERRIDE {
+ dispatcher_->OnUnauthenticatedHeader(header);
+ return false;
+ }
+ virtual void OnError(QuicFramer* framer) OVERRIDE {
+ DLOG(INFO) << QuicUtils::ErrorToString(framer->error());
+ }
+
+ // The following methods should never get called because we always return
+ // false from OnUnauthenticatedHeader(). As a result, we never process the
+ // payload of the packet.
+ virtual bool OnProtocolVersionMismatch(
+ QuicVersion /*received_version*/) OVERRIDE {
+ DCHECK(false);
+ return false;
+ }
+ virtual void OnPublicResetPacket(
+ const QuicPublicResetPacket& /*packet*/) OVERRIDE {
+ DCHECK(false);
+ }
+ virtual void OnVersionNegotiationPacket(
+ const QuicVersionNegotiationPacket& /*packet*/) OVERRIDE {
+ DCHECK(false);
+ }
+ virtual void OnPacketComplete() OVERRIDE {
+ DCHECK(false);
+ }
+ virtual bool OnPacketHeader(const QuicPacketHeader& /*header*/) OVERRIDE {
+ DCHECK(false);
+ return false;
+ }
+ virtual void OnRevivedPacket() OVERRIDE {
+ DCHECK(false);
+ }
+ virtual void OnFecProtectedPayload(StringPiece /*payload*/) OVERRIDE {
+ DCHECK(false);
+ }
+ virtual bool OnStreamFrame(const QuicStreamFrame& /*frame*/) OVERRIDE {
+ DCHECK(false);
+ return false;
+ }
+ virtual bool OnAckFrame(const QuicAckFrame& /*frame*/) OVERRIDE {
+ DCHECK(false);
+ return false;
+ }
+ virtual bool OnCongestionFeedbackFrame(
+ const QuicCongestionFeedbackFrame& /*frame*/) OVERRIDE {
+ DCHECK(false);
+ return false;
+ }
+ virtual bool OnRstStreamFrame(const QuicRstStreamFrame& /*frame*/) OVERRIDE {
+ DCHECK(false);
+ return false;
+ }
+ virtual bool OnConnectionCloseFrame(
+ const QuicConnectionCloseFrame & /*frame*/) OVERRIDE {
+ DCHECK(false);
+ return false;
+ }
+ virtual bool OnGoAwayFrame(const QuicGoAwayFrame& /*frame*/) OVERRIDE {
+ DCHECK(false);
+ return false;
+ }
+ virtual void OnFecData(const QuicFecData& /*fec*/) OVERRIDE {
+ DCHECK(false);
+ }
+
+ private:
+ QuicDispatcher* dispatcher_;
+};
+
QuicDispatcher::QuicDispatcher(const QuicConfig& config,
const QuicCryptoServerConfig& crypto_config,
const QuicVersionVector& supported_versions,
@@ -50,7 +135,11 @@ QuicDispatcher::QuicDispatcher(const QuicConfig& config,
write_blocked_(false),
helper_(new QuicEpollConnectionHelper(epoll_server_)),
writer_(new QuicDefaultPacketWriter(fd)),
- supported_versions_(supported_versions) {
+ supported_versions_(supported_versions),
+ current_packet_(NULL),
+ framer_(supported_versions, /*unused*/ QuicTime::Zero(), true),
+ framer_visitor_(new QuicFramerVisitor(this)) {
+ framer_.set_visitor(framer_visitor_.get());
}
QuicDispatcher::~QuicDispatcher() {
@@ -87,41 +176,56 @@ bool QuicDispatcher::IsWriteBlockedDataBuffered() const {
void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address,
const IPEndPoint& client_address,
- QuicGuid guid,
- bool has_version_flag,
const QuicEncryptedPacket& packet) {
+ current_server_address_ = server_address;
+ current_client_address_ = client_address;
+ current_packet_ = &packet;
+ // ProcessPacket will cause the packet to be dispatched in
+ // OnUnauthenticatedPublicHeader, or sent to the time wait list manager
+ // in OnAuthenticatedHeader.
+ framer_.ProcessPacket(packet);
+ // TODO(rjshade): Return a status describing if/why a packet was dropped,
+ // and log somehow. Maybe expose as a varz.
+}
+
+bool QuicDispatcher::OnUnauthenticatedPublicHeader(
+ const QuicPacketPublicHeader& header) {
QuicSession* session = NULL;
+ QuicGuid guid = header.guid;
SessionMap::iterator it = session_map_.find(guid);
if (it == session_map_.end()) {
+ if (header.reset_flag) {
+ return false;
+ }
if (time_wait_list_manager_->IsGuidInTimeWait(guid)) {
- time_wait_list_manager_->ProcessPacket(server_address,
- client_address,
- guid,
- packet);
- return;
+ return HandlePacketForTimeWait(header);
}
// Ensure the packet has a version negotiation bit set before creating a new
// session for it. All initial packets for a new connection are required to
// have the flag set. Otherwise it may be a stray packet.
- if (has_version_flag) {
- session = CreateQuicSession(guid, server_address, client_address);
+ if (header.version_flag) {
+ session = CreateQuicSession(guid, current_server_address_,
+ current_client_address_);
}
if (session == NULL) {
DLOG(INFO) << "Failed to create session for " << guid;
// Add this guid fo the time-wait state, to safely reject future packets.
- // We don't know the version here, so assume latest.
- // TODO(ianswett): Produce a no-version version negotiation packet.
- time_wait_list_manager_->AddGuidToTimeWait(guid,
- supported_versions_.front(),
- NULL);
- time_wait_list_manager_->ProcessPacket(server_address,
- client_address,
- guid,
- packet);
- return;
+
+ if (header.version_flag &&
+ !framer_.IsSupportedVersion(header.versions.front())) {
+ // TODO(ianswett): Produce a no-version version negotiation packet.
+ return false;
+ }
+
+ // Use the version in the packet if possible, otherwise assume the latest.
+ QuicVersion version = header.version_flag ? header.versions.front() :
+ supported_versions_.front();
+ time_wait_list_manager_->AddGuidToTimeWait(guid, version, NULL);
+ DCHECK(time_wait_list_manager_->IsGuidInTimeWait(guid));
+ return HandlePacketForTimeWait(header);
}
DLOG(INFO) << "Created new session for " << guid;
session_map_.insert(make_pair(guid, session));
@@ -130,7 +234,18 @@ void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address,
}
session->connection()->ProcessUdpPacket(
- server_address, client_address, packet);
+ current_server_address_, current_client_address_, *current_packet_);
+
+ // Do not parse the packet further. The session will process it completely.
+ return false;
+}
+
+void QuicDispatcher::OnUnauthenticatedHeader(const QuicPacketHeader& header) {
+ DCHECK(time_wait_list_manager_->IsGuidInTimeWait(header.public_header.guid));
+ time_wait_list_manager_->ProcessPacket(current_server_address_,
+ current_client_address_,
+ header.public_header.guid,
+ header.packet_sequence_number);
}
void QuicDispatcher::CleanUpSession(SessionMap::iterator it) {
@@ -223,5 +338,22 @@ QuicSession* QuicDispatcher::CreateQuicSession(
return session;
}
+bool QuicDispatcher::HandlePacketForTimeWait(
+ const QuicPacketPublicHeader& header) {
+ if (header.reset_flag) {
+ // Public reset packets do not have sequence numbers, so ignore the packet.
+ return false;
+ }
+
+ // Switch the framer to the correct version, so that the sequence number can
+ // be parsed correctly.
+ framer_.set_version(time_wait_list_manager_->GetQuicVersionFromGuid(
+ header.guid));
+
+ // Continue parsing the packet to extract the sequence number. Then
+ // send it to the time wait manager in OnUnathenticatedHeader.
+ return true;
+}
+
} // namespace tools
} // namespace net
« no previous file with comments | « net/tools/quic/quic_dispatcher.h ('k') | net/tools/quic/quic_dispatcher_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698