168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/quic/quic_ack_notifier_manager.h"
668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <stddef.h>
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <list>
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <map>
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <utility>
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <vector>
1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/stl_util.h"
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/quic/quic_ack_notifier.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/quic/quic_protocol.h"
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace net {
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)AckNotifierManager::AckNotifierManager() {}
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)AckNotifierManager::~AckNotifierManager() {
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  STLDeleteElements(&ack_notifiers_);
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AckNotifierManager::OnPacketAcked(
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    QuicPacketSequenceNumber sequence_number,
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    QuicTime::Delta delta_largest_observed) {
284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Inform all the registered AckNotifiers of the new ACK.
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AckNotifierMap::iterator map_it = ack_notifier_map_.find(sequence_number);
304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (map_it == ack_notifier_map_.end()) {
314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // No AckNotifier is interested in this sequence number.
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // One or more AckNotifiers are registered as interested in this sequence
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // number. Iterate through them and call OnAck on each.
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (AckNotifierSet::iterator set_it = map_it->second.begin();
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       set_it != map_it->second.end(); ++set_it) {
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    QuicAckNotifier* ack_notifier = *set_it;
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ack_notifier->OnAck(sequence_number, delta_largest_observed);
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // If this has resulted in an empty AckNotifer, erase it.
434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (ack_notifier->IsEmpty()) {
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      delete ack_notifier;
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ack_notifiers_.erase(ack_notifier);
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Remove the sequence number from the map as we have notified all the
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // registered AckNotifiers, and we won't see it again.
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ack_notifier_map_.erase(map_it);
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AckNotifierManager::UpdateSequenceNumber(
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    QuicPacketSequenceNumber old_sequence_number,
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    QuicPacketSequenceNumber new_sequence_number) {
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  AckNotifierMap::iterator map_it = ack_notifier_map_.find(old_sequence_number);
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (map_it != ack_notifier_map_.end()) {
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // We will add an entry to the map for the new sequence number, and move
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // the
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // list of AckNotifiers over.
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    AckNotifierSet new_set;
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    for (AckNotifierSet::iterator notifier_it = map_it->second.begin();
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         notifier_it != map_it->second.end(); ++notifier_it) {
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      (*notifier_it)
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          ->UpdateSequenceNumber(old_sequence_number, new_sequence_number);
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      new_set.insert(*notifier_it);
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ack_notifier_map_[new_sequence_number] = new_set;
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ack_notifier_map_.erase(map_it);
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AckNotifierManager::OnSerializedPacket(
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const SerializedPacket& serialized_packet) {
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Run through all the frames and if any of them are stream frames and have
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // an AckNotifier registered, then inform the AckNotifier that it should be
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // interested in this packet's sequence number.
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RetransmittableFrames* frames = serialized_packet.retransmittable_frames;
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // AckNotifiers can only be attached to retransmittable frames.
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!frames) {
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  for (QuicFrames::const_iterator it = frames->frames().begin();
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)       it != frames->frames().end(); ++it) {
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (it->type == STREAM_FRAME && it->stream_frame->notifier != NULL) {
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      QuicAckNotifier* notifier = it->stream_frame->notifier;
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // The AckNotifier needs to know it is tracking this packet's sequence
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // number.
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      notifier->AddSequenceNumber(serialized_packet.sequence_number,
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                  serialized_packet.packet->length());
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Update the mapping in the other direction, from sequence
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // number to AckNotifier.
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ack_notifier_map_[serialized_packet.sequence_number].insert(notifier);
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Take ownership of the AckNotifier.
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ack_notifiers_.insert(notifier);
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace net
108