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