diff options
author | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-02 22:15:38 +0000 |
---|---|---|
committer | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-02 22:15:38 +0000 |
commit | 4e6f0edd6c424ce6ae754e07910a869e8ef358b4 (patch) | |
tree | 84c37bd0116e012244ce806f4f934ff6983256fb /net/quic/quic_connection.h | |
parent | 896584f40469394ec27e52e7c10b9dca9f12bd33 (diff) | |
download | chromium_src-4e6f0edd6c424ce6ae754e07910a869e8ef358b4.zip chromium_src-4e6f0edd6c424ce6ae754e07910a869e8ef358b4.tar.gz chromium_src-4e6f0edd6c424ce6ae754e07910a869e8ef358b4.tar.bz2 |
Add QuicConnection and MockQuicConnectionHelper.
Review URL: https://chromiumcodereview.appspot.com/11276011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@165766 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic/quic_connection.h')
-rw-r--r-- | net/quic/quic_connection.h | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h new file mode 100644 index 0000000..51604db --- /dev/null +++ b/net/quic/quic_connection.h @@ -0,0 +1,311 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// The entity that handles framing writes for a Quic client or server. +// Each QuicSession will have a connection associated with it. +// +// On the server side, the Dispatcher handles the raw reads, and hands off +// packets via ProcessUdpPacket for framing and processing. +// +// On the client side, the Connection handles the raw reads, as well as the +// processing. +// +// Note: this class is not thread-safe. + +#ifndef NET_QUIC_QUIC_CONNECTION_H_ +#define NET_QUIC_QUIC_CONNECTION_H_ + +#include <list> +#include <set> +#include <vector> + +#include "base/hash_tables.h" +#include "net/base/ip_endpoint.h" +#include "net/quic/quic_fec_group.h" +#include "net/quic/quic_framer.h" +#include "net/quic/quic_packet_creator.h" +#include "net/quic/quic_protocol.h" + +namespace net { + +class QuicClock; +class QuicConnection; +class QuicEncrypter; +class QuicReceiptMetricsCollector; +class QuicSendScheduler; + +class NET_EXPORT_PRIVATE QuicConnectionVisitorInterface { + public: + typedef std::set<QuicPacketSequenceNumber> AckedPackets; + + virtual ~QuicConnectionVisitorInterface() {} + // A simple visitor interface for dealing with data frames. The session + // should determine if all frames will be accepted, and return true if so. + // If any frames can't be processed or buffered, none of the data should + // be used, and the callee should return false. + virtual bool OnPacket(const IPEndPoint& self_address, + const IPEndPoint& peer_address, + const QuicPacketHeader& header, + const std::vector<QuicStreamFrame>& frame) = 0; + // Called when the stream is reset by the peer. + virtual void OnRstStream(const QuicRstStreamFrame& frame) = 0; + // Called when the connection is closed either locally by the framer, or + // remotely by the peer. + virtual void ConnectionClose(QuicErrorCode error, bool from_peer) = 0; + // Called when packets are acked by the peer. + virtual void OnAck(AckedPackets acked_packets) = 0; +}; + +class NET_EXPORT_PRIVATE QuicConnectionHelperInterface { + public: + virtual ~QuicConnectionHelperInterface() {} + + // Sets the QuicConnection to be used by this helper. This method + // must only be called once. + virtual void SetConnection(QuicConnection* connection) = 0; + + // Returns a QuicClock to be used for all time related functions. + virtual QuicClock* GetClock() = 0; + + // Sends the packet out to the peer, possibly simulating packet + // loss if FLAGS_fake_packet_loss_percentage is set. If the write failed + // errno will be copied to |*error|. + virtual int WritePacketToWire(QuicPacketSequenceNumber number, + const QuicEncryptedPacket& packet, + bool resend, + int* error) = 0; + + // Sets up an alarm to resend the packet with the given sequence number if we + // haven't gotten an ack in the expected time frame. Implementations must + // invoke MaybeResendPacket when the alarm fires. Implementations must also + // handle the case where |this| is deleted before the alarm fires. + virtual void SetResendAlarm(QuicPacketSequenceNumber sequence_number, + uint64 delay_in_us) = 0; + + // Sets an alarm to send packets after |delay_in_us|. Implementations must + // invoke OnCanWrite when the alarm fires. Implementations must also + // handle the case where |this| is deleted before the alarm fires. + virtual void SetSendAlarm(uint64 delay_in_us) = 0; + + // Sets An alarm which fires when the connection may have timed out. + // Implementations must call CheckForTimeout() and then reregister the alarm + // if the connection has not yet timed out. + virtual void SetTimeoutAlarm(uint64 delay_in_us) = 0; + + // Returns true if a send alarm is currently set. + virtual bool IsSendAlarmSet() = 0; + + // If a send alarm is currently set, this method unregisters it. If + // no send alarm is set, it does nothing. + virtual void UnregisterSendAlarmIfRegistered() = 0; +}; + +class NET_EXPORT_PRIVATE QuicConnection : public QuicFramerVisitorInterface { + public: + // Constructs a new QuicConnection for the specified |guid| and |address|. + // |helper| will be owned by this connection. + QuicConnection(QuicGuid guid, + IPEndPoint address, + QuicConnectionHelperInterface* helper); + virtual ~QuicConnection(); + + // Send the data payload to the peer. + size_t SendStreamData(QuicStreamId id, + base::StringPiece data, + QuicStreamOffset offset, + bool fin, + QuicPacketSequenceNumber* last_packet); + // Send a stream reset frame to the peer. + virtual void SendRstStream(QuicStreamId id, + QuicErrorCode error, + QuicStreamOffset offset); + // Sends a connection close frame to the peer, and notifies the visitor of + // the close. + virtual void SendConnectionClose(QuicErrorCode error); + + // Processes an incoming UDP packet (consisting of a QuicEncryptedPacket) from + // the peer. If processing this packet permits a packet to be revived from + // its FEC group that packet will be revived and processed. + virtual void ProcessUdpPacket(const IPEndPoint& self_address, + const IPEndPoint& peer_address, + const QuicEncryptedPacket& packet); + + // Called when the underlying connection becomes writable to allow + // queued writes to happen. Returns false if the socket has become blocked. + virtual bool OnCanWrite(); + + // From QuicFramerVisitorInterface + virtual void OnError(QuicFramer* framer) OVERRIDE; + virtual void OnPacket(const IPEndPoint& self_address, + const IPEndPoint& peer_address) OVERRIDE; + virtual void OnRevivedPacket() OVERRIDE; + virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE; + virtual void OnFecProtectedPayload(base::StringPiece payload) OVERRIDE; + virtual void OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE; + virtual void OnAckFrame(const QuicAckFrame& frame) OVERRIDE; + virtual void OnRstStreamFrame(const QuicRstStreamFrame& frame) OVERRIDE; + virtual void OnConnectionCloseFrame( + const QuicConnectionCloseFrame& frame) OVERRIDE; + virtual void OnFecData(const QuicFecData& fec) OVERRIDE; + virtual void OnPacketComplete() OVERRIDE; + + // Accessors + void set_visitor(QuicConnectionVisitorInterface* visitor) { + visitor_ = visitor; + } + const IPEndPoint& self_address() const { return self_address_; } + const IPEndPoint& peer_address() const { return peer_address_; } + QuicGuid guid() const { return guid_; } + + // Updates the internal state concerning which packets have been acked, and + // sends an ack if new data frames have been received. + void AckPacket(const QuicPacketHeader& header); + + // Called by a ResendAlarm when the timer goes off. If the packet has been + // acked it's a no op, otherwise the packet is resent and another alarm is + // scheduled. + void MaybeResendPacket(QuicPacketSequenceNumber sequence_number); + + QuicGuid guid() { return guid_; } + + QuicPacketCreator::Options* options() { return packet_creator_.options(); } + + bool connected() { return connected_; } + + size_t NumFecGroups() const { return group_map_.size(); } + + size_t NumQueuedPackets() const { return queued_packets_.size(); } + + // If the connection has timed out, this will close the connection and return + // true. Otherwise, it will return false and will reset the timeout alarm. + bool CheckForTimeout(); + + // Returns true of the next packet to be sent should be "lost" by + // not actually writing it to the wire. + bool ShouldSimulateLostPacket(); + + protected: + // Send a packet to the peer. If resend is true, this packet contains data, + // and will be resent if we don't get an ack. If force is true, then the + // packet will be sent immediately and the send scheduler will not be + // consulted. + virtual bool SendPacket(QuicPacketSequenceNumber number, + QuicPacket* packet, + bool resend, + bool force); + + // Make sure an ack we got from our peer is sane. + bool ValidateAckFrame(const QuicAckFrame& incoming_ack); + + // These two are called by OnAckFrame to update the appropriate internal + // state. + // + // Updates internal state based on incoming_ack.received_info + void UpdatePacketInformationReceivedByPeer( + const QuicAckFrame& incoming_ack); + // Updates internal state based in incoming_ack.sent_info + void UpdatePacketInformationSentByPeer(const QuicAckFrame& incoming_ack); + + private: + friend class QuicConnectionPeer; + typedef base::hash_set<QuicPacketSequenceNumber> SequenceSet; + + // Sets up a packet with an QuicAckFrame and sends it out. + void SendAck(); + + // If a packet can be revived from the current FEC group, then + // revive and process the packet. + void MaybeProcessRevivedPacket(); + + // Get the FEC group associate with the last processed packet. + QuicFecGroup* GetFecGroup(); + + // Fills the ack frame with the appropriate latched information. + void FillAckFrame(QuicAckFrame* ack); + + // Closes any FEC groups protecting packets before |sequence_number|. + void CloseFecGroupsBefore(QuicPacketSequenceNumber sequence_number); + + scoped_ptr<QuicConnectionHelperInterface> helper_; + QuicFramer framer_; + QuicClock* clock_; + + QuicGuid guid_; + IPEndPoint self_address_; + IPEndPoint peer_address_; + + bool last_packet_revived_; // true if the last packet was revived from FEC. + size_t last_size_; // size of the last received packet. + QuicPacketHeader last_header_; + std::vector<QuicStreamFrame> frames_; + + QuicAckFrame outgoing_ack_; + + // Track some client state so we can do less bookkeeping + // + // The largest packet we've seen which contained an ack frame. + QuicPacketSequenceNumber largest_seen_packet_with_ack_; + // The largest seen value for least_packet_awaiting_ack from the client. + QuicPacketSequenceNumber largest_seen_least_packet_awaiting_ack_; + + typedef base::hash_map<QuicPacketSequenceNumber, + QuicPacket*> UnackedPacketMap; + // When new packets are created which may be resent, they are added + // to this map, which contains owning pointers. + UnackedPacketMap unacked_packets_; + + // Packets which have not been written to the wire. + struct QueuedPacket { + QuicPacketSequenceNumber sequence_number; + QuicPacket* packet; + bool resend; + + QueuedPacket(QuicPacketSequenceNumber sequence_number, + QuicPacket* packet, + bool resend) { + this->sequence_number = sequence_number; + this->packet = packet; + this->resend = resend; + } + }; + typedef std::list<QueuedPacket> QueuedPacketList; + // When packets could not be sent because the socket was not writable, + // they are added to this list. For packets that are not resendable, this + // list contains owning pointers, since they are not added to + // unacked_packets_. + QueuedPacketList queued_packets_; + + // True when the socket becomes unwritable. + bool write_blocked_; + + typedef std::map<QuicFecGroupNumber, QuicFecGroup*> FecGroupMap; + FecGroupMap group_map_; + QuicPacketHeader revived_header_; + scoped_array<char> revived_payload_; + + // Only set if we configure fake packet loss. + //scoped_ptr<MTRandom> random_; + + QuicConnectionVisitorInterface* visitor_; + QuicPacketCreator packet_creator_; + + // The number of usec of idle network before we kill of this connection. + uint64 timeout_us_; + // The time (since the epoch) that we got or tried to send a packet for this + // connection. + uint64 time_of_last_packet_us_; + + scoped_ptr<QuicReceiptMetricsCollector> collector_; + + // Scheduler which drives packet send rate. + scoped_ptr<QuicSendScheduler> scheduler_; + + // True by default. False if we've received or sent an explicit connection + // close. + bool connected_; +}; + +} // namespace net + +#endif // NET_QUIC_QUIC_CONNECTION_H_ |