quic_dispatcher.h revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/ip_endpoint.h"
153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/base/linked_hash_map.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_blocked_writer_interface.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/quic/quic_protocol.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/tools/epoll_server/epoll_server.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_packet_writer.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_server_session.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/tools/quic/quic_time_wait_list_manager.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(COMPILER_GCC)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace BASE_HASH_NAMESPACE {
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<>
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)struct hash<net::QuicBlockedWriterInterface*> {
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::size_t operator()(
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const net::QuicBlockedWriterInterface* ptr) const {
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return hash<size_t>()(reinterpret_cast<size_t>(ptr));
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net {
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class EpollServer;
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicConfig;
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicCryptoServerConfig;
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicSession;
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace tools {
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace test {
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicDispatcherPeer;
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace test
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DeleteSessionsAlarm;
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class QuicDispatcher : public QuicPacketWriter, public QuicSessionOwner {
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Ideally we'd have a linked_hash_set: the  boolean is unused.
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  typedef linked_hash_map<QuicBlockedWriterInterface*, bool> WriteBlockedList;
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Due to the way delete_sessions_closure_ is registered, the Dispatcher
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // must live until epoll_server Shutdown.
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  QuicDispatcher(const QuicConfig& config,
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 const QuicCryptoServerConfig& crypto_config,
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 int fd,
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 EpollServer* epoll_server);
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~QuicDispatcher();
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // QuicPacketWriter
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual WriteResult WritePacket(
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const char* buffer, size_t buf_len,
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const IPAddressNumber& self_address,
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const IPEndPoint& peer_address,
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      QuicBlockedWriterInterface* writer) OVERRIDE;
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ProcessPacket(const IPEndPoint& server_address,
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const IPEndPoint& client_address,
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             QuicGuid guid,
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             const QuicEncryptedPacket& packet);
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Called when the underyling connection becomes writable to allow
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // queued writes to happen.
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Returns true if more writes are possible, false otherwise.
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool OnCanWrite();
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Sends ConnectionClose frames to all connected clients.
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Shutdown();
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Ensure that the closed connection is cleaned up asynchronously.
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnConnectionClose(QuicGuid guid, QuicErrorCode error) OVERRIDE;
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_fd(int fd) { fd_ = fd; }
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  typedef base::hash_map<QuicGuid, QuicSession*> SessionMap;
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual QuicSession* CreateQuicSession(
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      QuicGuid guid,
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const IPEndPoint& client_address,
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      int fd,
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      EpollServer* epoll_server);
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Deletes all sessions on the closed session list and clears the list.
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DeleteSessions();
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const SessionMap& session_map() const { return session_map_; }
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WriteBlockedList* write_blocked_list() { return &write_blocked_list_; }
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const QuicConfig& config_;
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const QuicCryptoServerConfig& crypto_config_;
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
107558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  QuicTimeWaitListManager* time_wait_list_manager() {
108558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return time_wait_list_manager_.get();
109558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
110558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  friend class net::tools::test::QuicDispatcherPeer;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Removes the session from the session map and write blocked list, and
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // adds the GUID to the time-wait list.
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CleanUpSession(SessionMap::iterator it);
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The list of connections waiting to write.
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WriteBlockedList write_blocked_list_;
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SessionMap session_map_;
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Entity that manages guids in time wait state.
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // An alarm which deletes closed sessions.
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeleteSessionsAlarm> delete_sessions_alarm_;
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The list of closed but not-yet-deleted sessions.
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::list<QuicSession*> closed_session_list_;
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EpollServer* epoll_server_;  // Owned by the server.
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The connection for client-server communication
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int fd_;
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // True if the session is write blocked due to the socket returning EAGAIN.
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // False if we have gotten a call to OnCanWrite after the last failed write.
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool write_blocked_;
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QuicDispatcher);
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace tools
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace net
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // NET_TOOLS_QUIC_QUIC_DISPATCHER_H_
148