1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_dispatcher.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <errno.h> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/logging.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/stl_util.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_blocked_writer_interface.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_utils.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_epoll_connection_helper.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_socket_utils.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net { 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace tools { 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using std::make_pair; 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DeleteSessionsAlarm : public EpollAlarm { 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) explicit DeleteSessionsAlarm(QuicDispatcher* dispatcher) 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : dispatcher_(dispatcher) { 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual int64 OnAlarm() OVERRIDE { 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollAlarm::OnAlarm(); 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dispatcher_->DeleteSessions(); 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 0; 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicDispatcher* dispatcher_; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicDispatcher::QuicDispatcher(const QuicConfig& config, 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const QuicCryptoServerConfig& crypto_config, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int fd, 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer* epoll_server) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : config_(config), 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) crypto_config_(crypto_config), 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) time_wait_list_manager_( 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new QuicTimeWaitListManager(this, epoll_server)), 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delete_sessions_alarm_(new DeleteSessionsAlarm(this)), 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) epoll_server_(epoll_server), 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd_(fd), 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) write_blocked_(false) { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicDispatcher::~QuicDispatcher() { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) STLDeleteValues(&session_map_); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) STLDeleteElements(&closed_session_list_); 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int QuicDispatcher::WritePacket(const char* buffer, size_t buf_len, 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IPAddressNumber& self_address, 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IPEndPoint& peer_address, 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicBlockedWriterInterface* writer, 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int* error) { 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (write_blocked_) { 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) write_blocked_list_.AddBlockedObject(writer); 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *error = EAGAIN; 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int rc = QuicSocketUtils::WritePacket(fd_, buffer, buf_len, 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self_address, peer_address, 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rc == -1 && (*error == EWOULDBLOCK || *error == EAGAIN)) { 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) write_blocked_list_.AddBlockedObject(writer); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) write_blocked_ = true; 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return rc; 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicDispatcher::ProcessPacket(const IPEndPoint& server_address, 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IPEndPoint& client_address, 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicGuid guid, 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const QuicEncryptedPacket& packet) { 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicSession* session; 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SessionMap::iterator it = session_map_.find(guid); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (it == session_map_.end()) { 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (time_wait_list_manager_->IsGuidInTimeWait(guid)) { 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) time_wait_list_manager_->ProcessPacket(server_address, 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_address, 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) guid, 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session = CreateQuicSession(guid, client_address, fd_, epoll_server_); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (session == NULL) { 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG(INFO) << "Failed to create session for " << guid; 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add this guid fo the time-wait state, to safely nack future packets. 97558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // We don't know the version here, so assume latest. 98558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch time_wait_list_manager_->AddGuidToTimeWait(guid, QuicVersionMax()); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) time_wait_list_manager_->ProcessPacket(server_address, 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_address, 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) guid, 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) packet); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG(INFO) << "Created new session for " << guid; 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_map_.insert(make_pair(guid, session)); 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session = it->second; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session->connection()->ProcessUdpPacket( 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) server_address, client_address, packet); 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicDispatcher::CleanUpSession(SessionMap::iterator it) { 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicSession* session = it->second; 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) write_blocked_list_.RemoveBlockedObject(session->connection()); 118558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch time_wait_list_manager_->AddGuidToTimeWait(it->first, 119558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch session->connection()->version()); 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_map_.erase(it); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicDispatcher::DeleteSessions() { 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) STLDeleteElements(&closed_session_list_); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool QuicDispatcher::OnCanWrite() { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We got an EPOLLOUT: the socket should not be blocked. 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) write_blocked_ = false; 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Give each writer one attempt to write. 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int num_writers = write_blocked_list_.NumObjects(); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int i = 0; i < num_writers; ++i) { 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (write_blocked_list_.IsEmpty()) { 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicBlockedWriterInterface* writer = 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) write_blocked_list_.GetNextBlockedObject(); 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool can_write_more = writer->OnCanWrite(); 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (write_blocked_) { 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We were unable to write. Wait for the next EPOLLOUT. 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // In this case, the session would have been added to the blocked list 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // up in WritePacket. 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The socket is not blocked but the writer has ceded work. Add it to the 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // end of the list. 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (can_write_more) { 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) write_blocked_list_.AddBlockedObject(writer); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We're not write blocked. Return true if there's more work to do. 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return !write_blocked_list_.IsEmpty(); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicDispatcher::Shutdown() { 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (!session_map_.empty()) { 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicSession* session = session_map_.begin()->second; 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session->connection()->SendConnectionClose(QUIC_PEER_GOING_AWAY); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Validate that the session removes itself from the session map on close. 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(session_map_.empty() || session_map_.begin()->second != session); 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeleteSessions(); 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void QuicDispatcher::OnConnectionClose(QuicGuid guid, QuicErrorCode error) { 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SessionMap::iterator it = session_map_.find(guid); 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (it == session_map_.end()) { 1702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch LOG(DFATAL) << "GUID " << guid << " does not exist in the session map. " 1712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch << "Error: " << QuicUtils::ErrorToString(error); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DLOG_IF(INFO, error != QUIC_NO_ERROR) << "Closing connection due to error: " 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << QuicUtils::ErrorToString(error); 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (closed_session_list_.empty()) { 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) epoll_server_->RegisterAlarmApproximateDelta( 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, delete_sessions_alarm_.get()); 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closed_session_list_.push_back(it->second); 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CleanUpSession(it); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)QuicSession* QuicDispatcher::CreateQuicSession( 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicGuid guid, 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IPEndPoint& client_address, 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int fd, 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EpollServer* epoll_server) { 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) QuicConnectionHelperInterface* helper = 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new QuicEpollConnectionHelper(this, epoll_server); 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) QuicServerSession* session = new QuicServerSession( 194558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch config_, new QuicConnection(guid, client_address, helper, true, 195558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch QuicVersionMax()), this); 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) session->InitializeSession(crypto_config_); 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return session; 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace tools 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace net 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 204