quic Client Connect

第一个问题,客户端什么时候发送CHLO消息?

void QuicClientBase::StartConnect(){
InitializeSession();//这个被子类覆盖
}
void QuicSpdyClientBase::InitializeSession() {
  client_session()->Initialize();//create crypto_stream_
  client_session()->CryptoConnect();
}
void QuicSpdyClientSession::CryptoConnect() {
  DCHECK(flow_controller());
  crypto_stream_->CryptoConnect();
}
bool QuicCryptoClientStream::CryptoConnect() {
  return handshaker_->CryptoConnect();
}
bool QuicCryptoClientHandshaker::CryptoConnect() {
  next_state_ = STATE_INITIALIZE;
  DoHandshakeLoop(nullptr);
  return session()->connection()->connected();
}
void QuicCryptoClientHandshaker::DoHandshakeLoop(
    const CryptoHandshakeMessage* in) {
  QuicCryptoClientConfig::CachedState* cached =
      crypto_config_->LookupOrCreate(server_id_);

  QuicAsyncStatus rv = QUIC_SUCCESS;
  do {
    CHECK_NE(STATE_NONE, next_state_);
    const State state = next_state_;
    next_state_ = STATE_IDLE;
    rv = QUIC_SUCCESS;
    switch (state) {
      case STATE_INITIALIZE:
        DoInitialize(cached);
        break;
      case STATE_SEND_CHLO:
        DoSendCHLO(cached);
        return;  // return waiting to hear from server.
      case STATE_RECV_REJ:
        DoReceiveREJ(in, cached);
        break;
      case STATE_VERIFY_PROOF:
        rv = DoVerifyProof(cached);
        break;
      case STATE_VERIFY_PROOF_COMPLETE:
        DoVerifyProofComplete(cached);
        break;
      case STATE_GET_CHANNEL_ID:
        rv = DoGetChannelID(cached);
        break;
      case STATE_GET_CHANNEL_ID_COMPLETE:
        DoGetChannelIDComplete();
        break;
      case STATE_RECV_SHLO:
        DoReceiveSHLO(in, cached);
        break;
      case STATE_IDLE:
        // This means that the peer sent us a message that we weren't expecting.
        stream_->CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
                                            "Handshake in idle state");
        return;
      case STATE_INITIALIZE_SCUP:
        DoInitializeServerConfigUpdate(cached);
        break;
      case STATE_NONE:
        QUIC_NOTREACHED();
        return;  // We are done.
    }
  } while (rv != QUIC_PENDING && next_state_ != STATE_NONE);
}
void QuicCryptoClientHandshaker::DoSendCHLO(
    QuicCryptoClientConfig::CachedState* cached) {
SendHandshakeMessage(out);    
    }
void QuicCryptoHandshaker::SendHandshakeMessage(
    const CryptoHandshakeMessage& message) {
    const QuicData& data = message.GetSerialized(session()->perspective());
    stream_->WriteOrBufferData(QuicStringPiece(data.data(), data.length()), false,
                             nullptr);
    }

2第二个问题,写入buffer中的数据何时被发送出去。

QuicConsumedData QuicSession::WritevData(QuicStream* stream,
                                         QuicStreamId id,
                                         size_t write_length,
                                         QuicStreamOffset offset,
                                         StreamSendingState state) 
{
 QuicConsumedData data =
      connection_->SendStreamData(id, write_length, offset, state);
}
QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
                                                size_t write_length,
                                                QuicStreamOffset offset,
                                                StreamSendingState state)
{
return packet_generator_.ConsumeData(id, write_length, offset, state);
}  
QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id,
                                                  size_t write_length,
                                                  QuicStreamOffset offset,
                                                  StreamSendingState state)
{
 packet_creator_.Flush();
}  
void QuicPacketCreator::Flush()
{
SerializePacket(serialized_packet_buffer, kMaxPacketSize);
OnSerializedPacket();
}                                                                                           
void QuicPacketCreator::OnSerializedPacket()
{
SerializedPacket packet(std::move(packet_));//? why move 
delegate_->OnSerializedPacket(&packet);
} 
//serialized_packet包含了序列化之后的数据
void QuicConnection::OnSerializedPacket(SerializedPacket* serialized_packet)
{
SendOrQueuePacket(serialized_packet);
}
void QuicConnection::SendOrQueuePacket(SerializedPacket* packet)
{
if (!queued_packets_.empty() || !WritePacket(packet)){}
}
bool QuicConnection::WritePacket(SerializedPacket* packet)
{
  WriteResult result = writer_->WritePacket(
      packet->encrypted_buffer, encrypted_length, self_address().host(),
      peer_address(), per_packet_options_);
} 
//writer_->WritePacket 会调用最终的socket接口,将数据发送出去。例如下面这个子类
WriteResult QuicDefaultPacketWriter::WritePacket(
    const char* buffer,
    size_t buf_len,
    const QuicIpAddress& self_address,
    const QuicSocketAddress& peer_address,
    PerPacketOptions* options) {
  WriteResult result = QuicSocketUtils::WritePacket(fd_, buffer, buf_len,
                                                    self_address, peer_address);
  if (result.status == WRITE_STATUS_BLOCKED) {
    write_blocked_ = true;
  }
  return result;
}

 到这里依然有个疑问,buffer的数据被谁读取?再次看了下代码,stream_->WriteOrBufferData会将数据写入到QuicStream对象中的send_buffer_中。send_buffer_中数据是被哪个函数读取呢?是WriteStreamData。按图索骥,这次反过来分析代码,分析被调用关系。正常的调用关系则是1-2-3-4-5。

//5
//https://cs.chromium.org/chromium/src/net/third_party/quic/core/quic_stream.cc?q=WriteOrBufferData&dr=CSs&l=709
bool QuicStream::WriteStreamData(QuicStreamOffset offset,
                                 QuicByteCount data_length,
                                 QuicDataWriter* writer) {
  return send_buffer_.WriteStreamData(offset, data_length, writer);
}
//4
//QuicStream::WriteStreamData is called in QuicSession
//
bool QuicSession::WriteStreamData(QuicStreamId id,
                                  QuicStreamOffset offset,
                                  QuicByteCount data_length,
                                  QuicDataWriter* writer) {
  QuicStream* stream = GetStream(id);
  return stream->WriteStreamData(offset, data_length, writer);
}
//3
//QuicSession::WriteStreamData is called in QuicFramer
bool QuicFramer::AppendStreamFrame(const QuicStreamFrame& frame,
                                   bool no_stream_frame_length,
                                   QuicDataWriter* writer)
{
    if (!data_producer_->WriteStreamData(frame.stream_id, frame.offset,
                                         frame.data_length, writer)){}
}
//2
size_t QuicFramer::BuildDataPacket(const QuicPacketHeader& header,
                                   const QuicFrames& frames,
                                   char* buffer,
                                   size_t packet_length) {
  QuicDataWriter writer(packet_length, buffer, endianness());                                  
      case STREAM_FRAME:
        if (!AppendStreamFrame(*frame.stream_frame, no_stream_frame_length,
                               &writer)) {}                                    
                                   }
//1
void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
                                        size_t encrypted_buffer_len) {
  size_t length = framer_->BuildDataPacket(header, queued_frames_,
                                           encrypted_buffer, packet_size_);                                         
                                        }                               

 但是,QuicFramer是QuicConnection中的一个对象,那么QuicSession是怎么传递给data_producer_的。

void QuicSession::Initialize() {
  connection_->set_visitor(this);
  connection_->SetSessionNotifier(this);
  connection_->SetDataProducer(this);
  connection_->SetFromConfig(config_);
  DCHECK_EQ(kCryptoStreamId, GetMutableCryptoStream()->id());
  static_stream_map_[kCryptoStreamId] = GetMutableCryptoStream();
}
void QuicConnection::SetDataProducer(
    QuicStreamFrameDataProducer* data_producer) {
  framer_.set_data_producer(data_producer);
}
//in quic_framer.h
  void set_data_producer(QuicStreamFrameDataProducer* data_producer) {
    data_producer_ = data_producer;
  }

你可能感兴趣的:(QUIC)