quic_dispatcher.h revision f2477e01787aa58f445919b809d89e252beef54f
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)// A server side dispatcher which dispatches a given client's data to their
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// stream.
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifndef NET_TOOLS_QUIC_QUIC_DISPATCHER_H_
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define NET_TOOLS_QUIC_QUIC_DISPATCHER_H_
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <list>
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/ip_endpoint.h"
163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/base/linked_hash_map.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_blocked_writer_interface.h"
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/quic/quic_packet_writer.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_protocol.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/tools/epoll_server/epoll_server.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_server_session.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_time_wait_list_manager.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(COMPILER_GCC)
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace BASE_HASH_NAMESPACE {
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<>
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct hash<net::QuicBlockedWriterInterface*> {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::size_t operator()(
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const net::QuicBlockedWriterInterface* ptr) const {
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return hash<size_t>()(reinterpret_cast<size_t>(ptr));
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net {
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class EpollServer;
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicConfig;
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicCryptoServerConfig;
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicSession;
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace tools {
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace test {
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicDispatcherPeer;
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace test
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DeleteSessionsAlarm;
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class QuicEpollConnectionHelper;
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicDispatcher : public QuicPacketWriter, public QuicSessionOwner {
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Ideally we'd have a linked_hash_set: the  boolean is unused.
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  typedef linked_hash_map<QuicBlockedWriterInterface*, bool> WriteBlockedList;
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Due to the way delete_sessions_closure_ is registered, the Dispatcher
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // must live until epoll_server Shutdown. |supported_versions| specifies the
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // list of supported QUIC versions.
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicDispatcher(const QuicConfig& config,
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 const QuicCryptoServerConfig& crypto_config,
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                 const QuicVersionVector& supported_versions,
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 int fd,
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 EpollServer* epoll_server);
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~QuicDispatcher();
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // QuicPacketWriter
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual WriteResult WritePacket(
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const char* buffer, size_t buf_len,
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const IPAddressNumber& self_address,
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const IPEndPoint& peer_address,
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      QuicBlockedWriterInterface* writer) OVERRIDE;
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual bool IsWriteBlockedDataBuffered() const OVERRIDE;
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Process the incoming packet by creating a new session, passing it to
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // an existing session, or passing it to the TimeWaitListManager.
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ProcessPacket(const IPEndPoint& server_address,
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const IPEndPoint& client_address,
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             QuicGuid guid,
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             bool has_version_flag,
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const QuicEncryptedPacket& packet);
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called when the underyling connection becomes writable to allow
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // queued writes to happen.
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns true if more writes are possible, false otherwise.
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnCanWrite();
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Sends ConnectionClose frames to all connected clients.
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Shutdown();
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Ensure that the closed connection is cleaned up asynchronously.
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void OnConnectionClosed(QuicGuid guid, QuicErrorCode error) OVERRIDE;
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Sets the fd and creates a default packet writer with that fd.
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void set_fd(int fd);
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typedef base::hash_map<QuicGuid, QuicSession*> SessionMap;
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual QuicSession* CreateQuicSession(
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      QuicGuid guid,
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const IPEndPoint& client_address);
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Deletes all sessions on the closed session list and clears the list.
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DeleteSessions();
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const SessionMap& session_map() const { return session_map_; }
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Uses the specified |writer| instead of QuicSocketUtils and takes ownership
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // of writer.
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void UseWriter(QuicPacketWriter* writer);
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WriteBlockedList* write_blocked_list() { return &write_blocked_list_; }
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const QuicConfig& config_;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const QuicCryptoServerConfig& crypto_config_;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
119558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  QuicTimeWaitListManager* time_wait_list_manager() {
120558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return time_wait_list_manager_.get();
121558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
122558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  QuicEpollConnectionHelper* helper() { return helper_.get(); }
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EpollServer* epoll_server() { return epoll_server_; }
1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const QuicVersionVector& supported_versions() const {
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return supported_versions_;
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  friend class net::tools::test::QuicDispatcherPeer;
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Removes the session from the session map and write blocked list, and
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // adds the GUID to the time-wait list.
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CleanUpSession(SessionMap::iterator it);
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The list of connections waiting to write.
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WriteBlockedList write_blocked_list_;
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SessionMap session_map_;
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Entity that manages guids in time wait state.
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // An alarm which deletes closed sessions.
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeleteSessionsAlarm> delete_sessions_alarm_;
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The list of closed but not-yet-deleted sessions.
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::list<QuicSession*> closed_session_list_;
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EpollServer* epoll_server_;  // Owned by the server.
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The connection for client-server communication
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int fd_;
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // True if the session is write blocked due to the socket returning EAGAIN.
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // False if we have gotten a call to OnCanWrite after the last failed write.
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool write_blocked_;
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The helper used for all connections.
1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<QuicEpollConnectionHelper> helper_;
1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The writer to write to the socket with.
1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<QuicPacketWriter> writer_;
1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // This vector contains QUIC versions which we currently support.
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // This should be ordered such that the highest supported version is the first
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // element, with subsequent elements in descending order (versions can be
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // skipped as necessary).
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const QuicVersionVector supported_versions_;
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QuicDispatcher);
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace tools
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace net
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // NET_TOOLS_QUIC_QUIC_DISPATCHER_H_
179