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