Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(637)

Unified Diff: net/spdy/spdy_session.cc

Issue 6800009: Attn: Mike Belshe Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/spdy/spdy_session.cc
===================================================================
--- net/spdy/spdy_session.cc (revision 80449)
+++ net/spdy/spdy_session.cc (working copy)
@@ -246,6 +246,8 @@
initial_recv_window_size_(spdy::kSpdyStreamInitialWindowSize),
net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)) {
DCHECK(HttpStreamFactory::spdy_enabled());
+ // TODO(jtl): Do we need to set kMaxSpdyFrameChunkSize here based on which
+ // transport protocol we're using?
net_log_.BeginEvent(
NetLog::TYPE_SPDY_SESSION,
make_scoped_refptr(
@@ -764,7 +766,8 @@
DCHECK_GT(size, 0u);
// TODO(mbelshe): We have too much copying of data here.
- IOBufferWithSize* buffer = new IOBufferWithSize(size);
+ // TODO(jtl): Why is this "WithSize"?
+ IOBuffer* buffer = new IOBufferWithSize(size);
memcpy(buffer->data(), compressed_frame->data(), size);
// Attempt to send the frame.
@@ -773,11 +776,26 @@
size = uncompressed_frame.length() + spdy::SpdyFrame::size();
in_flight_write_ = next_buffer;
}
+ // SCTP stream ID assignment is delayed until now, rather than done in
+ // QueueFrame, to be sure the association (connection) has been
+ // established. SCTP stream ID numbers can't be assigned until
+ // g_max_sctp_streams is set, and that can't happen until the association
+ // is established.
+ // TODO(jtl): In order to support piggy-backing DATA on the COOKIE_ECHO,
+ // as is allowed in FreeBSD and Mac OS X, we need to find a way to allow
+ // at least sctp stream ID 1 to be used prior to g_max_sctp_streams being
+ // set.
+ //
+ if (using_sctp()) {
+ spdy::SpdyFrame frame(in_flight_write_.buffer()->data(), false);
+ in_flight_write_.set_sctp_stream_id(GetSctpStreamID(frame));
+ }
} else {
DCHECK(in_flight_write_.buffer()->BytesRemaining());
}
write_pending_ = true;
+
int rv = connection_->socket()->Write(in_flight_write_.buffer(),
in_flight_write_.buffer()->BytesRemaining(), &write_callback_);
if (rv == net::ERR_IO_PENDING)
@@ -836,12 +854,54 @@
return id;
}
+uint16 SpdySession::GetSctpStreamID(const spdy::SpdyFrame& frame) {
+ uint32 stream_id = 0;
+ if (!frame.is_control_frame()) {
+ stream_id = reinterpret_cast<const spdy::SpdyDataFrame&>(frame).stream_id();
+ } else if (!using_sctp_control_stream()) {
+ spdy::SpdyControlType type =
+ reinterpret_cast<const spdy::SpdyControlFrame&>(frame).type();
+ // n.b. When not using an SCTP control stream, SETTINGS, NOOP, PING
+ // and GOAWAY control frames are still sent on SCTP stream 0 because
+ // they are not associated with a specific SPDY stream.
+ switch (type) {
+ case spdy::SYN_STREAM:
+ stream_id = static_cast<const spdy::SpdySynStreamControlFrame&>
+ (frame).stream_id();
+ break;
+ case spdy::SYN_REPLY:
+ stream_id = static_cast<const spdy::SpdySynReplyControlFrame&>
+ (frame).stream_id();
+ break;
+ case spdy::RST_STREAM:
+ stream_id = static_cast<const spdy::SpdyRstStreamControlFrame&>
+ (frame).stream_id();
+ break;
+ case spdy::HEADERS:
+ stream_id = static_cast<const spdy::SpdyHeadersControlFrame&>
+ (frame).stream_id();
+ break;
+ case spdy::WINDOW_UPDATE:
+ stream_id = static_cast<const spdy::SpdyWindowUpdateControlFrame&>
+ (frame).stream_id();
+ break;
+ default:
+ break;
+ }
+ }
+
+ return stream_id ? MapSpdyToSctp(stream_id) : 0;
+}
+
void SpdySession::QueueFrame(spdy::SpdyFrame* frame,
spdy::SpdyPriority priority,
SpdyStream* stream) {
int length = spdy::SpdyFrame::size() + frame->length();
- IOBuffer* buffer = new IOBuffer(length);
+ IOBuffer* buffer;
+ buffer = new IOBuffer(length);
memcpy(buffer->data(), frame->data(), length);
+ // can't assign IOBuffer::sctp_stream_id_ here because the association may not
+ // be established yet. See comments in SpdySession::WriteSocket()
queue_.push(SpdyIOBuffer(buffer, length, priority, stream));
WriteSocketLater();
@@ -1124,6 +1184,8 @@
}
scoped_refptr<SpdyStream> stream = active_streams_[stream_id];
+ if (using_sctp() && using_sctp_control_stream())
+ stream->set_syn_reply_received();
CHECK_EQ(stream->stream_id(), stream_id);
CHECK(!stream->cancelled());
@@ -1143,6 +1205,14 @@
}
Respond(*headers, stream);
+
+ // When using SCTP with a control stream, loss can result in the SYN_REPLY
+ // arriving after all the data. In this case close_pending() will be true
+ // and we need to call OnDataReceived to shutdown the metrics and close the
+ // stream.
+ if (using_sctp() && using_sctp_control_stream() &&
+ stream->close_pending())
+ stream->OnDataReceived(NULL, 0);
}
void SpdySession::OnHeaders(const spdy::SpdyHeadersControlFrame& frame,
« net/spdy/spdy_framer.cc ('K') | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698