1 // 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.
5 #include "net/quic/p2p/quic_p2p_session.h"
7 #include "base/callback_helpers.h"
8 #include "net/base/io_buffer.h"
9 #include "net/base/net_errors.h"
10 #include "net/quic/p2p/quic_p2p_crypto_stream.h"
11 #include "net/quic/p2p/quic_p2p_stream.h"
12 #include "net/quic/quic_connection.h"
13 #include "net/socket/socket.h"
17 QuicP2PSession::QuicP2PSession(const QuicConfig
& config
,
18 const QuicP2PCryptoConfig
& crypto_config
,
19 scoped_ptr
<QuicConnection
> connection
,
20 scoped_ptr
<net::Socket
> socket
)
21 : QuicSession(connection
.release(), config
),
22 socket_(socket
.Pass()),
23 crypto_stream_(new QuicP2PCryptoStream(this, crypto_config
)),
24 read_buffer_(new net::IOBuffer(static_cast<size_t>(kMaxPacketSize
))) {
25 DCHECK(config
.negotiated());
27 // Non-null IP address needs to be passed here because QuicConnection uses
28 // ToString() to format addresses for logging and ToString() is not allowed
29 // for empty addresses.
30 // TODO(sergeyu): Fix QuicConnection and remove SetSelfAddress() call below.
31 net::IPAddressNumber
ip(net::kIPv4AddressSize
, 0);
32 this->connection()->SetSelfAddress(net::IPEndPoint(ip
, 0));
35 QuicP2PSession::~QuicP2PSession() {}
37 void QuicP2PSession::Initialize() {
38 QuicSession::Initialize();
39 crypto_stream_
->Connect();
43 void QuicP2PSession::SetDelegate(Delegate
* delegate
) {
47 QuicCryptoStream
* QuicP2PSession::GetCryptoStream() {
48 return crypto_stream_
.get();
51 QuicP2PStream
* QuicP2PSession::CreateIncomingDynamicStream(QuicStreamId id
) {
52 QuicP2PStream
* stream
= new QuicP2PStream(id
, this);
54 delegate_
->OnIncomingStream(stream
);
59 QuicP2PStream
* QuicP2PSession::CreateOutgoingDynamicStream() {
60 QuicP2PStream
* stream
= new QuicP2PStream(GetNextStreamId(), this);
62 ActivateStream(stream
);
67 void QuicP2PSession::OnConnectionClosed(QuicErrorCode error
, bool from_peer
) {
68 QuicSession::OnConnectionClosed(error
, from_peer
);
73 Delegate
* delegate
= delegate_
;
75 delegate
->OnConnectionClosed(error
);
79 void QuicP2PSession::DoReadLoop(int result
) {
80 while (error() == net::QUIC_NO_ERROR
) {
81 switch (read_state_
) {
82 case READ_STATE_DO_READ
:
86 case READ_STATE_DO_READ_COMPLETE
:
87 result
= DoReadComplete(result
);
90 NOTREACHED() << "read_state_: " << read_state_
;
99 int QuicP2PSession::DoRead() {
100 DCHECK_EQ(read_state_
, READ_STATE_DO_READ
);
101 read_state_
= READ_STATE_DO_READ_COMPLETE
;
104 return net::ERR_SOCKET_NOT_CONNECTED
;
107 return socket_
->Read(
108 read_buffer_
.get(), kMaxPacketSize
,
109 base::Bind(&QuicP2PSession::DoReadLoop
, base::Unretained(this)));
112 int QuicP2PSession::DoReadComplete(int result
) {
113 DCHECK_EQ(read_state_
, READ_STATE_DO_READ_COMPLETE
);
114 read_state_
= READ_STATE_DO_READ
;
117 connection()->CloseConnection(net::QUIC_PACKET_READ_ERROR
, false);
121 QuicEncryptedPacket
packet(read_buffer_
->data(), result
);
122 connection()->ProcessUdpPacket(connection()->self_address(),
123 connection()->peer_address(), packet
);