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// A server side dispatcher which dispatches a given client's data to their
6// stream.
7
8#ifndef NET_TOOLS_QUIC_QUIC_DISPATCHER_H_
9#define NET_TOOLS_QUIC_QUIC_DISPATCHER_H_
10
11#include <list>
12
13#include "base/basictypes.h"
14#include "base/containers/hash_tables.h"
15#include "base/memory/scoped_ptr.h"
16#include "net/base/ip_endpoint.h"
17#include "net/base/linked_hash_map.h"
18#include "net/quic/quic_blocked_writer_interface.h"
19#include "net/quic/quic_protocol.h"
20#include "net/tools/quic/quic_server_session.h"
21#include "net/tools/quic/quic_time_wait_list_manager.h"
22
23namespace net {
24
25class EpollServer;
26class QuicConfig;
27class QuicCryptoServerConfig;
28class QuicSession;
29
30namespace tools {
31
32class DeleteSessionsAlarm;
33class QuicEpollConnectionHelper;
34class QuicPacketWriterWrapper;
35
36namespace test {
37class QuicDispatcherPeer;
38}  // namespace test
39
40class ProcessPacketInterface {
41 public:
42  virtual ~ProcessPacketInterface() {}
43  virtual void ProcessPacket(const IPEndPoint& server_address,
44                             const IPEndPoint& client_address,
45                             const QuicEncryptedPacket& packet) = 0;
46};
47
48class QuicDispatcher : public QuicServerSessionVisitor,
49                       public ProcessPacketInterface {
50 public:
51  // Creates per-connection packet writers out of the QuicDispatcher's shared
52  // QuicPacketWriter. The per-connection writers' IsWriteBlocked() state must
53  // always be the same as the shared writer's IsWriteBlocked(), or else the
54  // QuicDispatcher::OnCanWrite logic will not work. (This will hopefully be
55  // cleaned up for bug 16950226.)
56  class PacketWriterFactory {
57   public:
58    virtual ~PacketWriterFactory() {}
59
60    virtual QuicPacketWriter* Create(QuicPacketWriter* writer,
61                                     QuicConnection* connection) = 0;
62  };
63
64  // Creates ordinary QuicPerConnectionPacketWriter instances.
65  class DefaultPacketWriterFactory : public PacketWriterFactory {
66   public:
67    virtual ~DefaultPacketWriterFactory() {}
68
69    virtual QuicPacketWriter* Create(
70        QuicPacketWriter* writer,
71        QuicConnection* connection) OVERRIDE;
72  };
73
74  // Ideally we'd have a linked_hash_set: the  boolean is unused.
75  typedef linked_hash_map<QuicBlockedWriterInterface*, bool> WriteBlockedList;
76
77  // Due to the way delete_sessions_closure_ is registered, the Dispatcher must
78  // live until epoll_server Shutdown. |supported_versions| specifies the list
79  // of supported QUIC versions. Takes ownership of |packet_writer_factory|,
80  // which is used to create per-connection writers.
81  QuicDispatcher(const QuicConfig& config,
82                 const QuicCryptoServerConfig& crypto_config,
83                 const QuicVersionVector& supported_versions,
84                 PacketWriterFactory* packet_writer_factory,
85                 EpollServer* epoll_server);
86
87  virtual ~QuicDispatcher();
88
89  virtual void Initialize(int fd);
90
91  // Process the incoming packet by creating a new session, passing it to
92  // an existing session, or passing it to the TimeWaitListManager.
93  virtual void ProcessPacket(const IPEndPoint& server_address,
94                             const IPEndPoint& client_address,
95                             const QuicEncryptedPacket& packet) OVERRIDE;
96
97  // Called when the socket becomes writable to allow queued writes to happen.
98  virtual void OnCanWrite();
99
100  // Returns true if there's anything in the blocked writer list.
101  virtual bool HasPendingWrites() const;
102
103  // Sends ConnectionClose frames to all connected clients.
104  void Shutdown();
105
106  // QuicServerSessionVisitor interface implementation:
107  // Ensure that the closed connection is cleaned up asynchronously.
108  virtual void OnConnectionClosed(QuicConnectionId connection_id,
109                                  QuicErrorCode error) OVERRIDE;
110
111  // Queues the blocked writer for later resumption.
112  virtual void OnWriteBlocked(
113      QuicBlockedWriterInterface* blocked_writer) OVERRIDE;
114
115  typedef base::hash_map<QuicConnectionId, QuicSession*> SessionMap;
116
117  // Deletes all sessions on the closed session list and clears the list.
118  void DeleteSessions();
119
120  const SessionMap& session_map() const { return session_map_; }
121
122 protected:
123  // Instantiates a new low-level packet writer. Caller takes ownership of the
124  // returned object.
125  virtual QuicPacketWriter* CreateWriter(int fd);
126
127  virtual QuicSession* CreateQuicSession(QuicConnectionId connection_id,
128                                         const IPEndPoint& server_address,
129                                         const IPEndPoint& client_address);
130
131  virtual QuicConnection* CreateQuicConnection(
132      QuicConnectionId connection_id,
133      const IPEndPoint& server_address,
134      const IPEndPoint& client_address);
135
136  // Called by |framer_visitor_| when the public header has been parsed.
137  virtual bool OnUnauthenticatedPublicHeader(
138      const QuicPacketPublicHeader& header);
139
140  // Create and return the time wait list manager for this dispatcher, which
141  // will be owned by the dispatcher as time_wait_list_manager_
142  virtual QuicTimeWaitListManager* CreateQuicTimeWaitListManager();
143
144  // Replaces the packet writer with |writer|. Takes ownership of |writer|.
145  void set_writer(QuicPacketWriter* writer) {
146    writer_.reset(writer);
147  }
148
149  QuicTimeWaitListManager* time_wait_list_manager() {
150    return time_wait_list_manager_.get();
151  }
152
153  EpollServer* epoll_server() { return epoll_server_; }
154
155  const QuicVersionVector& supported_versions() const {
156    return supported_versions_;
157  }
158
159  const IPEndPoint& current_server_address() {
160    return current_server_address_;
161  }
162  const IPEndPoint& current_client_address() {
163    return current_client_address_;
164  }
165  const QuicEncryptedPacket& current_packet() {
166    return *current_packet_;
167  }
168
169  const QuicConfig& config() const { return config_; }
170
171  const QuicCryptoServerConfig& crypto_config() const { return crypto_config_; }
172
173  QuicFramer* framer() { return &framer_; }
174
175  QuicEpollConnectionHelper* helper() { return helper_.get(); }
176
177  QuicPacketWriter* writer() { return writer_.get(); }
178
179  const QuicConnection::PacketWriterFactory& connection_writer_factory() {
180    return connection_writer_factory_;
181  }
182
183 private:
184  class QuicFramerVisitor;
185  friend class net::tools::test::QuicDispatcherPeer;
186
187  // An adapter that creates packet writers using the dispatcher's
188  // PacketWriterFactory and shared writer. Essentially, it just curries the
189  // writer argument away from QuicDispatcher::PacketWriterFactory.
190  class PacketWriterFactoryAdapter :
191    public QuicConnection::PacketWriterFactory {
192   public:
193    PacketWriterFactoryAdapter(QuicDispatcher* dispatcher);
194    virtual ~PacketWriterFactoryAdapter ();
195
196    virtual QuicPacketWriter* Create(QuicConnection* connection) const OVERRIDE;
197
198   private:
199    QuicDispatcher* dispatcher_;
200  };
201
202  // Called by |framer_visitor_| when the private header has been parsed
203  // of a data packet that is destined for the time wait manager.
204  void OnUnauthenticatedHeader(const QuicPacketHeader& header);
205
206  // Removes the session from the session map and write blocked list, and
207  // adds the ConnectionId to the time-wait list.
208  void CleanUpSession(SessionMap::iterator it);
209
210  bool HandlePacketForTimeWait(const QuicPacketPublicHeader& header);
211
212  const QuicConfig& config_;
213
214  const QuicCryptoServerConfig& crypto_config_;
215
216  // The list of connections waiting to write.
217  WriteBlockedList write_blocked_list_;
218
219  SessionMap session_map_;
220
221  // Entity that manages connection_ids in time wait state.
222  scoped_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
223
224  // An alarm which deletes closed sessions.
225  scoped_ptr<DeleteSessionsAlarm> delete_sessions_alarm_;
226
227  // The list of closed but not-yet-deleted sessions.
228  std::list<QuicSession*> closed_session_list_;
229
230  EpollServer* epoll_server_;  // Owned by the server.
231
232  // The helper used for all connections.
233  scoped_ptr<QuicEpollConnectionHelper> helper_;
234
235  // The writer to write to the socket with.
236  scoped_ptr<QuicPacketWriter> writer_;
237
238  // Used to create per-connection packet writers, not |writer_| itself.
239  scoped_ptr<PacketWriterFactory> packet_writer_factory_;
240
241  // Passed in to QuicConnection for it to create the per-connection writers
242  PacketWriterFactoryAdapter connection_writer_factory_;
243
244  // This vector contains QUIC versions which we currently support.
245  // This should be ordered such that the highest supported version is the first
246  // element, with subsequent elements in descending order (versions can be
247  // skipped as necessary).
248  const QuicVersionVector supported_versions_;
249
250  // Information about the packet currently being handled.
251  IPEndPoint current_client_address_;
252  IPEndPoint current_server_address_;
253  const QuicEncryptedPacket* current_packet_;
254
255  QuicFramer framer_;
256  scoped_ptr<QuicFramerVisitor> framer_visitor_;
257
258  DISALLOW_COPY_AND_ASSIGN(QuicDispatcher);
259};
260
261}  // namespace tools
262}  // namespace net
263
264#endif  // NET_TOOLS_QUIC_QUIC_DISPATCHER_H_
265