blob: 94777b307d5a69edb548716eb1110b02c5b1c8ba [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,
danakjad1777e2016-04-16 00:56:4222 std::unique_ptr<QuicConnection> connection,
23 std::unique_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.
eroman36d84e54432016-03-17 03:23:0234 this->connection()->SetSelfAddress(IPEndPoint(IPAddress::IPv4AllZeros(), 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,
bnc614a92d32016-04-04 13:56:0772 const std::string& error_details,
fayanga64c1a92016-02-13 01:55:5873 ConnectionCloseSource source) {
jri78ec06a2016-03-31 18:19:4074 QuicSession::OnConnectionClosed(error, error_details, source);
sergeyucb90397c2015-08-04 18:14:4175
sergeyu1c98349632015-08-14 18:38:1776 socket_.reset();
77
sergeyucb90397c2015-08-04 18:14:4178 if (delegate_) {
79 Delegate* delegate = delegate_;
80 delegate_ = nullptr;
81 delegate->OnConnectionClosed(error);
82 }
83}
84
85void QuicP2PSession::DoReadLoop(int result) {
tfarinaa3dd7aa2016-02-25 08:15:4486 while (error() == QUIC_NO_ERROR) {
sergeyucb90397c2015-08-04 18:14:4187 switch (read_state_) {
88 case READ_STATE_DO_READ:
89 CHECK_EQ(result, OK);
90 result = DoRead();
91 break;
92 case READ_STATE_DO_READ_COMPLETE:
93 result = DoReadComplete(result);
94 break;
95 default:
96 NOTREACHED() << "read_state_: " << read_state_;
97 break;
98 }
99
100 if (result < 0)
101 break;
102 }
103}
104
105int QuicP2PSession::DoRead() {
106 DCHECK_EQ(read_state_, READ_STATE_DO_READ);
107 read_state_ = READ_STATE_DO_READ_COMPLETE;
108
sergeyu1c98349632015-08-14 18:38:17109 if (!socket_) {
tfarinaa3dd7aa2016-02-25 08:15:44110 return ERR_SOCKET_NOT_CONNECTED;
sergeyu1c98349632015-08-14 18:38:17111 }
112
sergeyucb90397c2015-08-04 18:14:41113 return socket_->Read(
114 read_buffer_.get(), kMaxPacketSize,
115 base::Bind(&QuicP2PSession::DoReadLoop, base::Unretained(this)));
116}
117
118int QuicP2PSession::DoReadComplete(int result) {
119 DCHECK_EQ(read_state_, READ_STATE_DO_READ_COMPLETE);
120 read_state_ = READ_STATE_DO_READ;
121
122 if (result <= 0) {
jri78ec06a2016-03-31 18:19:40123 connection()->CloseConnection(QUIC_PACKET_READ_ERROR, "packet read error",
124 ConnectionCloseBehavior::SILENT_CLOSE);
sergeyucb90397c2015-08-04 18:14:41125 return result;
126 }
127
jokulikf2bd55c52016-03-24 22:35:30128 QuicReceivedPacket packet(read_buffer_->data(), result, clock_.Now());
sergeyucb90397c2015-08-04 18:14:41129 connection()->ProcessUdpPacket(connection()->self_address(),
130 connection()->peer_address(), packet);
131 return OK;
132}
133
134} // namespace net