blob: ba7298d055f3aaffb59817370146f5fad83f7885 [file] [log] [blame]
sergeyucb90397c2015-08-04 18:14:411// 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 "net/quic/p2p/quic_p2p_session.h"
6
dchengc7eeda422015-12-26 03:56:487#include <utility>
8
sergeyucb90397c2015-08-04 18:14:419#include "base/callback_helpers.h"
10#include "net/base/io_buffer.h"
martijncc5402d2016-02-16 19:08:5811#include "net/base/ip_address.h"
sergeyucb90397c2015-08-04 18:14:4112#include "net/base/net_errors.h"
13#include "net/quic/p2p/quic_p2p_crypto_stream.h"
14#include "net/quic/p2p/quic_p2p_stream.h"
15#include "net/quic/quic_connection.h"
16#include "net/socket/socket.h"
17
18namespace net {
19
20QuicP2PSession::QuicP2PSession(const QuicConfig& config,
21 const QuicP2PCryptoConfig& crypto_config,
22 scoped_ptr<QuicConnection> connection,
tfarinaa3dd7aa2016-02-25 08:15:4423 scoped_ptr<Socket> socket)
sergeyucb90397c2015-08-04 18:14:4124 : QuicSession(connection.release(), config),
dchengc7eeda422015-12-26 03:56:4825 socket_(std::move(socket)),
sergeyucb90397c2015-08-04 18:14:4126 crypto_stream_(new QuicP2PCryptoStream(this, crypto_config)),
tfarinaa3dd7aa2016-02-25 08:15:4427 read_buffer_(new IOBuffer(static_cast<size_t>(kMaxPacketSize))) {
sergeyucb90397c2015-08-04 18:14:4128 DCHECK(config.negotiated());
29
30 // Non-null IP address needs to be passed here because QuicConnection uses
31 // ToString() to format addresses for logging and ToString() is not allowed
32 // for empty addresses.
33 // TODO(sergeyu): Fix QuicConnection and remove SetSelfAddress() call below.
tfarinaa3dd7aa2016-02-25 08:15:4434 this->connection()->SetSelfAddress(IPEndPoint(IPAddress(0, 0, 0, 0), 0));
sergeyucb90397c2015-08-04 18:14:4135}
36
37QuicP2PSession::~QuicP2PSession() {}
38
39void QuicP2PSession::Initialize() {
40 QuicSession::Initialize();
41 crypto_stream_->Connect();
42 DoReadLoop(OK);
43}
44
45void QuicP2PSession::SetDelegate(Delegate* delegate) {
46 delegate_ = delegate;
47}
48
49QuicCryptoStream* QuicP2PSession::GetCryptoStream() {
50 return crypto_stream_.get();
51}
52
53QuicP2PStream* QuicP2PSession::CreateIncomingDynamicStream(QuicStreamId id) {
54 QuicP2PStream* stream = new QuicP2PStream(id, this);
55 if (delegate_) {
56 delegate_->OnIncomingStream(stream);
57 }
danzh33407f12016-03-04 21:58:1658 ActivateStream(stream);
sergeyucb90397c2015-08-04 18:14:4159 return stream;
60}
61
jri86a3c602015-12-15 06:01:0362QuicP2PStream* QuicP2PSession::CreateOutgoingDynamicStream(
tfarinaa3dd7aa2016-02-25 08:15:4463 SpdyPriority priority) {
alyssarc39b80f2015-10-22 17:13:5864 QuicP2PStream* stream = new QuicP2PStream(GetNextOutgoingStreamId(), this);
sergeyucb90397c2015-08-04 18:14:4165 if (stream) {
66 ActivateStream(stream);
67 }
68 return stream;
69}
70
fayanga64c1a92016-02-13 01:55:5871void QuicP2PSession::OnConnectionClosed(QuicErrorCode error,
72 ConnectionCloseSource source) {
73 QuicSession::OnConnectionClosed(error, source);
sergeyucb90397c2015-08-04 18:14:4174
sergeyu1c98349632015-08-14 18:38:1775 socket_.reset();
76
sergeyucb90397c2015-08-04 18:14:4177 if (delegate_) {
78 Delegate* delegate = delegate_;
79 delegate_ = nullptr;
80 delegate->OnConnectionClosed(error);
81 }
82}
83
84void QuicP2PSession::DoReadLoop(int result) {
tfarinaa3dd7aa2016-02-25 08:15:4485 while (error() == QUIC_NO_ERROR) {
sergeyucb90397c2015-08-04 18:14:4186 switch (read_state_) {
87 case READ_STATE_DO_READ:
88 CHECK_EQ(result, OK);
89 result = DoRead();
90 break;
91 case READ_STATE_DO_READ_COMPLETE:
92 result = DoReadComplete(result);
93 break;
94 default:
95 NOTREACHED() << "read_state_: " << read_state_;
96 break;
97 }
98
99 if (result < 0)
100 break;
101 }
102}
103
104int QuicP2PSession::DoRead() {
105 DCHECK_EQ(read_state_, READ_STATE_DO_READ);
106 read_state_ = READ_STATE_DO_READ_COMPLETE;
107
sergeyu1c98349632015-08-14 18:38:17108 if (!socket_) {
tfarinaa3dd7aa2016-02-25 08:15:44109 return ERR_SOCKET_NOT_CONNECTED;
sergeyu1c98349632015-08-14 18:38:17110 }
111
sergeyucb90397c2015-08-04 18:14:41112 return socket_->Read(
113 read_buffer_.get(), kMaxPacketSize,
114 base::Bind(&QuicP2PSession::DoReadLoop, base::Unretained(this)));
115}
116
117int QuicP2PSession::DoReadComplete(int result) {
118 DCHECK_EQ(read_state_, READ_STATE_DO_READ_COMPLETE);
119 read_state_ = READ_STATE_DO_READ;
120
121 if (result <= 0) {
tfarinaa3dd7aa2016-02-25 08:15:44122 connection()->CloseConnection(QUIC_PACKET_READ_ERROR,
fayanga64c1a92016-02-13 01:55:58123 ConnectionCloseSource::FROM_SELF);
sergeyucb90397c2015-08-04 18:14:41124 return result;
125 }
126
127 QuicEncryptedPacket packet(read_buffer_->data(), result);
128 connection()->ProcessUdpPacket(connection()->self_address(),
129 connection()->peer_address(), packet);
130 return OK;
131}
132
133} // namespace net