Home | History | Annotate | Download | only in quic
      1 // Copyright (c) 2012 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 #include "net/tools/quic/quic_epoll_connection_helper.h"
      6 
      7 #include <errno.h>
      8 #include <sys/socket.h>
      9 
     10 #include "base/logging.h"
     11 #include "base/stl_util.h"
     12 #include "net/base/ip_endpoint.h"
     13 #include "net/quic/crypto/quic_random.h"
     14 #include "net/tools/flip_server/epoll_server.h"
     15 #include "net/tools/quic/quic_socket_utils.h"
     16 
     17 namespace net {
     18 namespace tools {
     19 
     20 namespace {
     21 
     22 class QuicEpollAlarm : public QuicAlarm {
     23  public:
     24   QuicEpollAlarm(EpollServer* epoll_server,
     25                  QuicAlarm::Delegate* delegate)
     26       : QuicAlarm(delegate),
     27         epoll_server_(epoll_server),
     28         epoll_alarm_impl_(this) {}
     29 
     30  protected:
     31   virtual void SetImpl() OVERRIDE {
     32     DCHECK(deadline().IsInitialized());
     33     epoll_server_->RegisterAlarm(
     34         deadline().Subtract(QuicTime::Zero()).ToMicroseconds(),
     35         &epoll_alarm_impl_);
     36   }
     37 
     38   virtual void CancelImpl() OVERRIDE {
     39     DCHECK(!deadline().IsInitialized());
     40     epoll_alarm_impl_.UnregisterIfRegistered();
     41   }
     42 
     43  private:
     44   class EpollAlarmImpl : public EpollAlarm {
     45    public:
     46     explicit EpollAlarmImpl(QuicEpollAlarm* alarm) : alarm_(alarm) {}
     47 
     48     virtual int64 OnAlarm() OVERRIDE {
     49       EpollAlarm::OnAlarm();
     50       alarm_->Fire();
     51       // Fire will take care of registering the alarm, if needed.
     52       return 0;
     53     }
     54 
     55    private:
     56     QuicEpollAlarm* alarm_;
     57   };
     58 
     59   EpollServer* epoll_server_;
     60   EpollAlarmImpl epoll_alarm_impl_;
     61 };
     62 
     63 }  // namespace
     64 
     65 QuicEpollConnectionHelper::QuicEpollConnectionHelper(
     66   int fd, EpollServer* epoll_server)
     67     : writer_(NULL),
     68       epoll_server_(epoll_server),
     69       fd_(fd),
     70       connection_(NULL),
     71       clock_(epoll_server),
     72       random_generator_(QuicRandom::GetInstance()) {
     73 }
     74 
     75 QuicEpollConnectionHelper::QuicEpollConnectionHelper(QuicPacketWriter* writer,
     76                                                      EpollServer* epoll_server)
     77     : writer_(writer),
     78       epoll_server_(epoll_server),
     79       fd_(-1),
     80       connection_(NULL),
     81       clock_(epoll_server),
     82       random_generator_(QuicRandom::GetInstance()) {
     83 }
     84 
     85 QuicEpollConnectionHelper::~QuicEpollConnectionHelper() {
     86 }
     87 
     88 void QuicEpollConnectionHelper::SetConnection(QuicConnection* connection) {
     89   DCHECK(!connection_);
     90   connection_ = connection;
     91 }
     92 
     93 const QuicClock* QuicEpollConnectionHelper::GetClock() const {
     94   return &clock_;
     95 }
     96 
     97 QuicRandom* QuicEpollConnectionHelper::GetRandomGenerator() {
     98   return random_generator_;
     99 }
    100 
    101 int QuicEpollConnectionHelper::WritePacketToWire(
    102     const QuicEncryptedPacket& packet,
    103     int* error) {
    104   if (connection_->ShouldSimulateLostPacket()) {
    105     DLOG(INFO) << "Dropping packet due to fake packet loss.";
    106     *error = 0;
    107     return packet.length();
    108   }
    109 
    110   // If we have a writer, delgate the write to it.
    111   if (writer_) {
    112     return writer_->WritePacket(packet.data(), packet.length(),
    113                                 connection_->self_address().address(),
    114                                 connection_->peer_address(),
    115                                 connection_,
    116                                 error);
    117   } else {
    118     return QuicSocketUtils::WritePacket(
    119         fd_, packet.data(), packet.length(),
    120         connection_->self_address().address(),
    121         connection_->peer_address(),
    122         error);
    123   }
    124 }
    125 
    126 bool QuicEpollConnectionHelper::IsWriteBlockedDataBuffered() {
    127   return false;
    128 }
    129 
    130 bool QuicEpollConnectionHelper::IsWriteBlocked(int error) {
    131   return error == EAGAIN || error == EWOULDBLOCK;
    132 }
    133 
    134 QuicAlarm* QuicEpollConnectionHelper::CreateAlarm(
    135     QuicAlarm::Delegate* delegate) {
    136   return new QuicEpollAlarm(epoll_server_, delegate);
    137 }
    138 
    139 }  // namespace tools
    140 }  // namespace net
    141