Chromium Code Reviews| Index: webrtc/p2p/quic/quictransportchannel.cc |
| diff --git a/webrtc/p2p/quic/quictransportchannel.cc b/webrtc/p2p/quic/quictransportchannel.cc |
| index 7e68612388b85e85b5ca522a64c0a91f3b354375..e366e83501f20450e115b1954d511e175a67c716 100644 |
| --- a/webrtc/p2p/quic/quictransportchannel.cc |
| +++ b/webrtc/p2p/quic/quictransportchannel.cc |
| @@ -123,6 +123,7 @@ namespace cricket { |
| QuicTransportChannel::QuicTransportChannel(TransportChannelImpl* channel) |
| : TransportChannelImpl(channel->transport_name(), channel->component()), |
| + Transport("", nullptr), |
|
pthatcher1
2016/03/30 20:34:50
Why not use channel->transport_name() for the tran
mikescarlett
2016/04/05 19:58:53
Transport isn't subclassed anymore
|
| worker_thread_(rtc::Thread::Current()), |
| channel_(channel), |
| helper_(worker_thread_) { |
| @@ -153,9 +154,15 @@ QuicTransportChannel::QuicTransportChannel(TransportChannelImpl* channel) |
| net::QuicTime::Delta::FromSeconds(kIdleConnectionStateLifetime)); |
| // Set the bytes reserved for the QUIC connection ID to zero. |
| config_.SetBytesForConnectionIdToSend(0); |
| + // Provide the Transport base class with a pointer to this channel by |
| + // implicitly triggering Transport::CreateTransportChannel. |
| + Transport::CreateChannel(0); |
| } |
| -QuicTransportChannel::~QuicTransportChannel() {} |
| +QuicTransportChannel::~QuicTransportChannel() { |
| + // Required to avoid assertion error in Transport::~Transport(). |
| + Transport::DestroyAllChannels(); |
| +} |
| bool QuicTransportChannel::SetLocalCertificate( |
| const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
| @@ -441,6 +448,8 @@ bool QuicTransportChannel::CreateQuicSession() { |
| this, &QuicTransportChannel::OnHandshakeComplete); |
| quic_->SignalConnectionClosed.connect( |
| this, &QuicTransportChannel::OnConnectionClosed); |
| + quic_->SignalIncomingStream.connect(this, |
| + &QuicTransportChannel::OnIncomingStream); |
| return true; |
| } |
| @@ -539,6 +548,7 @@ void QuicTransportChannel::OnConnectionClosed(net::QuicErrorCode error, |
| // does not close due to failure. |
| set_quic_state(QUIC_TRANSPORT_CLOSED); |
| set_writable(false); |
| + SignalClosed(); |
| } |
| void QuicTransportChannel::OnProofValid( |
| @@ -567,4 +577,116 @@ void QuicTransportChannel::set_quic_state(QuicTransportState state) { |
| quic_state_ = state; |
| } |
| +bool QuicTransportChannel::NegotiateTransportDescription( |
| + ContentAction local_role, |
| + std::string* error_desc) { |
| + if (!local_description() || !remote_description()) { |
| + const std::string msg = |
| + "Local and Remote description must be set before " |
| + "transport descriptions are negotiated"; |
| + return BadTransportDescription(msg, error_desc); |
| + } |
| + |
| + rtc::SSLFingerprint* remote_fp = |
| + remote_description()->identity_fingerprint.get(); |
| + |
| + if (remote_fp) { |
| + if (!SetRemoteFingerprint( |
| + remote_fp->algorithm, |
| + reinterpret_cast<const uint8_t*>(remote_fp->digest.data()), |
| + remote_fp->digest.size())) { |
| + return BadTransportDescription("Failed to apply remote fingerprint.", |
| + error_desc); |
| + } |
| + } else { |
| + return BadTransportDescription( |
| + "Local fingerprint supplied when caller didn't offer DTLS.", |
| + error_desc); |
| + } |
| + |
| + // From RFC 4145, section-4.1, The following are the values that the |
| + // 'setup' attribute can take in an offer/answer exchange: |
| + // Offer Answer |
| + // ________________ |
| + // active passive / holdconn |
| + // passive active / holdconn |
| + // actpass active / passive / holdconn |
| + // holdconn holdconn |
| + // |
| + // Set the role that is most conformant with RFC 5763, Section 5, bullet 1 |
| + // The endpoint MUST use the setup attribute defined in [RFC4145]. |
| + // The endpoint that is the offerer MUST use the setup attribute |
| + // value of setup:actpass and be prepared to receive a client_hello |
| + // before it receives the answer. The answerer MUST use either a |
| + // setup attribute value of setup:active or setup:passive. Note that |
| + // if the answerer uses setup:passive, then the DTLS handshake will |
| + // not begin until the answerer is received, which adds additional |
| + // latency. setup:active allows the answer and the DTLS handshake to |
| + // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever |
| + // party is active MUST initiate a DTLS handshake by sending a |
| + // ClientHello over each flow (host/port quartet). |
| + // IOW - actpass and passive modes should be treated as server and |
| + // active as client. |
|
pthatcher1
2016/03/30 20:34:50
Can you just delete this whole comment and write t
mikescarlett
2016/04/05 19:58:53
Done. See QuicTransport in https://codereview.webr
|
| + ConnectionRole local_connection_role = local_description()->connection_role; |
| + ConnectionRole remote_connection_role = remote_description()->connection_role; |
| + |
| + bool is_remote_server = false; |
| + if (local_role == CA_OFFER) { |
| + if (local_connection_role != CONNECTIONROLE_ACTPASS) { |
| + return BadTransportDescription( |
| + "Offerer must use actpass value for setup attribute.", error_desc); |
| + } |
| + |
| + if (remote_connection_role == CONNECTIONROLE_ACTIVE || |
| + remote_connection_role == CONNECTIONROLE_PASSIVE || |
| + remote_connection_role == CONNECTIONROLE_NONE) { |
| + is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE); |
| + } else { |
| + const std::string msg = |
| + "Answerer must use either active or passive value " |
| + "for setup attribute."; |
| + return BadTransportDescription(msg, error_desc); |
| + } |
| + // If remote is NONE or ACTIVE it will act as client. |
| + } else { |
| + if (remote_connection_role != CONNECTIONROLE_ACTPASS && |
| + remote_connection_role != CONNECTIONROLE_NONE) { |
| + return BadTransportDescription( |
| + "Offerer must use actpass value for setup attribute.", error_desc); |
| + } |
| + |
| + if (local_connection_role == CONNECTIONROLE_ACTIVE || |
| + local_connection_role == CONNECTIONROLE_PASSIVE) { |
| + is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE); |
| + } else { |
| + const std::string msg = |
| + "Answerer must use either active or passive value " |
| + "for setup attribute."; |
| + return BadTransportDescription(msg, error_desc); |
| + } |
| + |
| + // If local is passive, local will act as server. |
| + } |
| + |
| + rtc::SSLRole ssl_role = is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER; |
| + if (!SetSslRole(ssl_role)) { |
| + return BadTransportDescription("Failed to set ssl role for the channel.", |
| + error_desc); |
| + } |
| + |
| + // Now run the negotiation for the base class. |
| + return Transport::NegotiateTransportDescription(local_role, error_desc); |
| +} |
| + |
| +ReliableQuicStream* QuicTransportChannel::CreateQuicStream() { |
|
pthatcher1
2016/03/30 20:34:50
Can you make it clear that the 0 here is the prior
mikescarlett
2016/04/05 19:58:53
Done.
|
| + if (quic_) { |
| + return quic_->CreateOutgoingDynamicStream(0); |
| + } |
| + return nullptr; |
| +} |
| + |
| +void QuicTransportChannel::OnIncomingStream(ReliableQuicStream* stream) { |
| + SignalIncomingStream(stream); |
| +} |
| + |
| } // namespace cricket |