mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-12-01 09:46:09 +03:00
168 lines
5.3 KiB
C++
168 lines
5.3 KiB
C++
|
// Copyright (c) 2016 The Chromium Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#include "net/tools/quic/chlo_extractor.h"
|
||
|
|
||
|
#include "net/quic/core/crypto/crypto_framer.h"
|
||
|
#include "net/quic/core/crypto/crypto_handshake_message.h"
|
||
|
#include "net/quic/core/crypto/crypto_protocol.h"
|
||
|
#include "net/quic/core/crypto/quic_decrypter.h"
|
||
|
#include "net/quic/core/crypto/quic_encrypter.h"
|
||
|
#include "net/quic/core/quic_framer.h"
|
||
|
#include "net/quic/platform/api/quic_string_piece.h"
|
||
|
#include "net/quic/platform/api/quic_text_utils.h"
|
||
|
|
||
|
namespace net {
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
class ChloFramerVisitor : public QuicFramerVisitorInterface,
|
||
|
public CryptoFramerVisitorInterface {
|
||
|
public:
|
||
|
ChloFramerVisitor(QuicFramer* framer, ChloExtractor::Delegate* delegate);
|
||
|
|
||
|
~ChloFramerVisitor() override = default;
|
||
|
|
||
|
// QuicFramerVisitorInterface implementation
|
||
|
void OnError(QuicFramer* framer) override {}
|
||
|
bool OnProtocolVersionMismatch(QuicTransportVersion version) override;
|
||
|
void OnPacket() override {}
|
||
|
void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {}
|
||
|
void OnVersionNegotiationPacket(
|
||
|
const QuicVersionNegotiationPacket& packet) override {}
|
||
|
bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override;
|
||
|
bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
|
||
|
void OnDecryptedPacket(EncryptionLevel level) override {}
|
||
|
bool OnPacketHeader(const QuicPacketHeader& header) override;
|
||
|
bool OnStreamFrame(const QuicStreamFrame& frame) override;
|
||
|
bool OnAckFrame(const QuicAckFrame& frame) override;
|
||
|
bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
|
||
|
bool OnPingFrame(const QuicPingFrame& frame) override;
|
||
|
bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
|
||
|
bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
|
||
|
bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
|
||
|
bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
|
||
|
bool OnBlockedFrame(const QuicBlockedFrame& frame) override;
|
||
|
bool OnPaddingFrame(const QuicPaddingFrame& frame) override;
|
||
|
void OnPacketComplete() override {}
|
||
|
|
||
|
// CryptoFramerVisitorInterface implementation.
|
||
|
void OnError(CryptoFramer* framer) override;
|
||
|
void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
|
||
|
|
||
|
bool found_chlo() { return found_chlo_; }
|
||
|
|
||
|
private:
|
||
|
QuicFramer* framer_;
|
||
|
ChloExtractor::Delegate* delegate_;
|
||
|
bool found_chlo_;
|
||
|
QuicConnectionId connection_id_;
|
||
|
};
|
||
|
|
||
|
ChloFramerVisitor::ChloFramerVisitor(QuicFramer* framer,
|
||
|
ChloExtractor::Delegate* delegate)
|
||
|
: framer_(framer),
|
||
|
delegate_(delegate),
|
||
|
found_chlo_(false),
|
||
|
connection_id_(0) {}
|
||
|
|
||
|
bool ChloFramerVisitor::OnProtocolVersionMismatch(
|
||
|
QuicTransportVersion version) {
|
||
|
if (!framer_->IsSupportedVersion(version)) {
|
||
|
return false;
|
||
|
}
|
||
|
framer_->set_version(version);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ChloFramerVisitor::OnUnauthenticatedPublicHeader(
|
||
|
const QuicPacketHeader& header) {
|
||
|
connection_id_ = header.connection_id;
|
||
|
return true;
|
||
|
}
|
||
|
bool ChloFramerVisitor::OnUnauthenticatedHeader(
|
||
|
const QuicPacketHeader& header) {
|
||
|
return true;
|
||
|
}
|
||
|
bool ChloFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) {
|
||
|
return true;
|
||
|
}
|
||
|
bool ChloFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
|
||
|
QuicStringPiece data(frame.data_buffer, frame.data_length);
|
||
|
if (frame.stream_id == kCryptoStreamId && frame.offset == 0 &&
|
||
|
QuicTextUtils::StartsWith(data, "CHLO")) {
|
||
|
CryptoFramer crypto_framer;
|
||
|
crypto_framer.set_visitor(this);
|
||
|
if (!crypto_framer.ProcessInput(data, Perspective::IS_SERVER)) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ChloFramerVisitor::OnAckFrame(const QuicAckFrame& frame) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ChloFramerVisitor::OnStopWaitingFrame(const QuicStopWaitingFrame& frame) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ChloFramerVisitor::OnPingFrame(const QuicPingFrame& frame) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ChloFramerVisitor::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ChloFramerVisitor::OnConnectionCloseFrame(
|
||
|
const QuicConnectionCloseFrame& frame) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ChloFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ChloFramerVisitor::OnWindowUpdateFrame(
|
||
|
const QuicWindowUpdateFrame& frame) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ChloFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& frame) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool ChloFramerVisitor::OnPaddingFrame(const QuicPaddingFrame& frame) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void ChloFramerVisitor::OnError(CryptoFramer* framer) {}
|
||
|
|
||
|
void ChloFramerVisitor::OnHandshakeMessage(
|
||
|
const CryptoHandshakeMessage& message) {
|
||
|
if (delegate_ != nullptr) {
|
||
|
delegate_->OnChlo(framer_->transport_version(), connection_id_, message);
|
||
|
}
|
||
|
found_chlo_ = true;
|
||
|
}
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
// static
|
||
|
bool ChloExtractor::Extract(const QuicEncryptedPacket& packet,
|
||
|
const QuicTransportVersionVector& versions,
|
||
|
Delegate* delegate) {
|
||
|
QuicFramer framer(versions, QuicTime::Zero(), Perspective::IS_SERVER);
|
||
|
ChloFramerVisitor visitor(&framer, delegate);
|
||
|
framer.set_visitor(&visitor);
|
||
|
if (!framer.ProcessPacket(packet)) {
|
||
|
return false;
|
||
|
}
|
||
|
return visitor.found_chlo();
|
||
|
}
|
||
|
|
||
|
} // namespace net
|