quic_server_session.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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 "net/quic/quic_server_session.h"
6
7#include "base/logging.h"
8#include "net/quic/quic_connection.h"
9#include "net/quic/quic_flags.h"
10#include "net/quic/quic_spdy_server_stream.h"
11#include "net/quic/reliable_quic_stream.h"
12
13namespace net {
14
15QuicServerSession::QuicServerSession(
16    const QuicConfig& config,
17    QuicConnection* connection,
18    QuicPerConnectionPacketWriter* connection_packet_writer,
19    QuicServerSessionVisitor* visitor)
20    : QuicSession(connection, config),
21      connection_packet_writer_(connection_packet_writer),
22      visitor_(visitor) {}
23
24QuicServerSession::~QuicServerSession() {}
25
26void QuicServerSession::InitializeSession(
27    const QuicCryptoServerConfig& crypto_config) {
28  QuicSession::InitializeSession();
29  crypto_stream_.reset(CreateQuicCryptoServerStream(crypto_config));
30}
31
32QuicCryptoServerStream* QuicServerSession::CreateQuicCryptoServerStream(
33    const QuicCryptoServerConfig& crypto_config) {
34  return new QuicCryptoServerStream(crypto_config, this);
35}
36
37void QuicServerSession::OnConfigNegotiated() {
38  QuicSession::OnConfigNegotiated();
39  if (!FLAGS_enable_quic_fec ||
40      !config()->HasReceivedConnectionOptions() ||
41      !ContainsQuicTag(config()->ReceivedConnectionOptions(), kFHDR)) {
42    return;
43  }
44  // kFHDR config maps to FEC protection always for headers stream.
45  // TODO(jri): Add crypto stream in addition to headers for kHDR.
46  headers_stream_->set_fec_policy(FEC_PROTECT_ALWAYS);
47}
48
49void QuicServerSession::OnConnectionClosed(QuicErrorCode error,
50                                           bool from_peer) {
51  QuicSession::OnConnectionClosed(error, from_peer);
52  // In the unlikely event we get a connection close while doing an asynchronous
53  // crypto event, make sure we cancel the callback.
54  if (crypto_stream_.get() != NULL) {
55    crypto_stream_->CancelOutstandingCallbacks();
56  }
57  visitor_->OnConnectionClosed(connection()->connection_id(), error);
58}
59
60void QuicServerSession::OnWriteBlocked() {
61  QuicSession::OnWriteBlocked();
62  visitor_->OnWriteBlocked(connection());
63}
64
65bool QuicServerSession::ShouldCreateIncomingDataStream(QuicStreamId id) {
66  if (id % 2 == 0) {
67    DVLOG(1) << "Invalid incoming even stream_id:" << id;
68    connection()->SendConnectionClose(QUIC_INVALID_STREAM_ID);
69    return false;
70  }
71  if (GetNumOpenStreams() >= get_max_open_streams()) {
72    DVLOG(1) << "Failed to create a new incoming stream with id:" << id
73             << " Already " << GetNumOpenStreams() << " open.";
74    connection()->SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS);
75    return false;
76  }
77  return true;
78}
79
80QuicDataStream* QuicServerSession::CreateIncomingDataStream(
81    QuicStreamId id) {
82  if (!ShouldCreateIncomingDataStream(id)) {
83    return NULL;
84  }
85
86  return new QuicSpdyServerStream(id, this);
87}
88
89QuicDataStream* QuicServerSession::CreateOutgoingDataStream() {
90  DLOG(ERROR) << "Server push not yet supported";
91  return NULL;
92}
93
94QuicCryptoServerStream* QuicServerSession::GetCryptoStream() {
95  return crypto_stream_.get();
96}
97
98}  // namespace net
99