1// Copyright 2013 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#ifndef NET_QUIC_QUIC_ACK_NOTIFIER_H_
6#define NET_QUIC_QUIC_ACK_NOTIFIER_H_
7
8#include "base/memory/ref_counted.h"
9#include "net/quic/quic_protocol.h"
10
11namespace net {
12
13// Used to register with a QuicConnection for notification once a set of packets
14// have all been ACKed.
15// The connection informs this class of newly ACKed sequence numbers, and once
16// we have seen ACKs for all the sequence numbers we are interested in, we
17// trigger a call to a provided Closure.
18class NET_EXPORT_PRIVATE QuicAckNotifier {
19 public:
20 class NET_EXPORT_PRIVATE DelegateInterface
21     : public base::RefCounted<DelegateInterface> {
22   public:
23    DelegateInterface();
24    // Args:
25    //  num_original_packets - Number of packets in the original transmission.
26    //  num_original_bytes - Number of packets in the original transmission.
27    //  num_retransmitted_packets - Number of packets that had to be
28    //                              retransmitted.
29    //  num_retransmitted_bytes - Number of bytes that had to be retransmitted.
30    virtual void OnAckNotification(int num_original_packets,
31                                   int num_original_bytes,
32                                   int num_retransmitted_packets,
33                                   int num_retransmitted_bytes,
34                                   QuicTime::Delta delta_largest_observed) = 0;
35   protected:
36    friend class base::RefCounted<DelegateInterface>;
37
38    // Delegates are ref counted.
39    virtual ~DelegateInterface();
40  };
41
42  // QuicAckNotifier is expected to keep its own reference to the delegate.
43  explicit QuicAckNotifier(DelegateInterface* delegate);
44  virtual ~QuicAckNotifier();
45
46  // Register a sequence number that this AckNotifier should be interested in.
47  void AddSequenceNumber(const QuicPacketSequenceNumber& sequence_number,
48                         int packet_payload_size);
49
50  // Called by the QuicConnection on receipt of new ACK frame, with the sequence
51  // number referenced by the ACK frame.
52  // Deletes the matching sequence number from the stored set of sequence
53  // numbers. If this set is now empty, call the stored delegate's
54  // OnAckNotification method.
55  //
56  // Returns true if the provided sequence_number caused the delegate to be
57  // called, false otherwise.
58  bool OnAck(QuicPacketSequenceNumber sequence_number,
59             QuicTime::Delta delta_largest_observed);
60
61  bool IsEmpty() { return sequence_numbers_.empty(); }
62
63  // If a packet is retransmitted by the connection it will be sent with a
64  // different sequence number. Updates our internal set of sequence_numbers to
65  // track the latest number.
66  void UpdateSequenceNumber(QuicPacketSequenceNumber old_sequence_number,
67                            QuicPacketSequenceNumber new_sequence_number);
68
69 private:
70  struct PacketInfo {
71    PacketInfo();
72    explicit PacketInfo(int payload_size);
73
74    int packet_payload_size;
75  };
76
77  // The delegate's OnAckNotification() method will be called once we have been
78  // notified of ACKs for all the sequence numbers we are tracking.
79  // This is not owned by OnAckNotifier and must outlive it.
80  scoped_refptr<DelegateInterface> delegate_;
81
82  // Sequence numbers this notifier is waiting to hear about. The
83  // delegate will not be called until this is empty.
84  base::hash_map<QuicPacketSequenceNumber, PacketInfo> sequence_numbers_;
85
86  // Transmission and retransmission stats.
87  // Number of packets in the original transmission.
88  int original_packet_count_;
89  // Number of packets in the original transmission.
90  int original_byte_count_;
91  // Number of packets that had to be retransmitted.
92  int retransmitted_packet_count_;
93  // Number of bytes that had to be retransmitted.
94  int retransmitted_byte_count_;
95
96  DISALLOW_COPY_AND_ASSIGN(QuicAckNotifier);
97};
98
99};  // namespace net
100
101#endif  // NET_QUIC_QUIC_ACK_NOTIFIER_H_
102