1// Copyright (c) 2011 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#ifndef NET_TOOLS_FLIP_SERVER_SM_CONNECTION_H_
6#define NET_TOOLS_FLIP_SERVER_SM_CONNECTION_H_
7
8#include <arpa/inet.h>  // in_addr_t
9#include <time.h>
10
11#include <list>
12#include <string>
13
14#include "base/compiler_specific.h"
15#include "net/spdy/spdy_protocol.h"
16#include "net/tools/epoll_server/epoll_server.h"
17#include "net/tools/flip_server/create_listener.h"
18#include "net/tools/flip_server/mem_cache.h"
19#include "net/tools/flip_server/ring_buffer.h"
20#include "net/tools/flip_server/sm_interface.h"
21#include "openssl/ssl.h"
22
23namespace net {
24
25class FlipAcceptor;
26class MemoryCache;
27struct SSLState;
28class SpdySM;
29
30// A frame of data to be sent.
31class DataFrame {
32 public:
33  const char* data;
34  size_t size;
35  bool delete_when_done;
36  size_t index;
37  DataFrame() : data(NULL), size(0), delete_when_done(false), index(0) {}
38  virtual ~DataFrame();
39};
40
41typedef std::list<DataFrame*> OutputList;
42
43class SMConnection : public SMConnectionInterface,
44                     public EpollCallbackInterface,
45                     public NotifierInterface {
46 public:
47  virtual ~SMConnection();
48
49  static SMConnection* NewSMConnection(EpollServer* epoll_server,
50                                       SSLState* ssl_state,
51                                       MemoryCache* memory_cache,
52                                       FlipAcceptor* acceptor,
53                                       std::string log_prefix);
54
55  // TODO(mbelshe): Make these private.
56  time_t last_read_time_;
57  std::string server_ip_;
58  std::string server_port_;
59
60  virtual EpollServer* epoll_server() OVERRIDE;
61  OutputList* output_list() { return &output_list_; }
62  MemoryCache* memory_cache() { return memory_cache_; }
63  virtual void ReadyToSend() OVERRIDE;
64  void EnqueueDataFrame(DataFrame* df);
65
66  int fd() const { return fd_; }
67  bool initialized() const { return initialized_; }
68  std::string client_ip() const { return client_ip_; }
69
70  virtual void InitSMConnection(SMConnectionPoolInterface* connection_pool,
71                                SMInterface* sm_interface,
72                                EpollServer* epoll_server,
73                                int fd,
74                                std::string server_ip,
75                                std::string server_port,
76                                std::string remote_ip,
77                                bool use_ssl);
78
79  void CorkSocket();
80  void UncorkSocket();
81
82  int Send(const char* data, int len, int flags);
83
84  // EpollCallbackInterface interface.
85  virtual void OnRegistration(EpollServer* eps,
86                              int fd,
87                              int event_mask) OVERRIDE;
88  virtual void OnModification(int fd, int event_mask) OVERRIDE {}
89  virtual void OnEvent(int fd, EpollEvent* event) OVERRIDE;
90  virtual void OnUnregistration(int fd, bool replaced) OVERRIDE;
91  virtual void OnShutdown(EpollServer* eps, int fd) OVERRIDE;
92
93  // NotifierInterface interface.
94  virtual void Notify() OVERRIDE {}
95
96  void Cleanup(const char* cleanup);
97
98  // Flag indicating if we should force spdy on all connections.
99  static bool force_spdy() { return force_spdy_; }
100  static void set_force_spdy(bool value) { force_spdy_ = value; }
101
102 private:
103  // Decide if SPDY was negotiated.
104  bool WasSpdyNegotiated(SpdyMajorVersion* version_negotiated);
105
106  // Initialize the protocol interfaces we'll need for this connection.
107  // Returns true if successful, false otherwise.
108  bool SetupProtocolInterfaces();
109
110  bool DoRead();
111  bool DoWrite();
112  bool DoConsumeReadData();
113  void Reset();
114
115  void HandleEvents();
116  void HandleResponseFullyRead();
117
118 protected:
119  friend std::ostream& operator<<(std::ostream& os, const SMConnection& c) {
120    os << &c << "\n";
121    return os;
122  }
123
124  SMConnection(EpollServer* epoll_server,
125               SSLState* ssl_state,
126               MemoryCache* memory_cache,
127               FlipAcceptor* acceptor,
128               std::string log_prefix);
129
130 private:
131  int fd_;
132  int events_;
133
134  bool registered_in_epoll_server_;
135  bool initialized_;
136  bool protocol_detected_;
137  bool connection_complete_;
138
139  SMConnectionPoolInterface* connection_pool_;
140
141  EpollServer* epoll_server_;
142  SSLState* ssl_state_;
143  MemoryCache* memory_cache_;
144  FlipAcceptor* acceptor_;
145  std::string client_ip_;
146
147  RingBuffer read_buffer_;
148
149  OutputList output_list_;
150  SpdySM* sm_spdy_interface_;
151  SMInterface* sm_http_interface_;
152  SMInterface* sm_streamer_interface_;
153  SMInterface* sm_interface_;
154  std::string log_prefix_;
155
156  size_t max_bytes_sent_per_dowrite_;
157
158  SSL* ssl_;
159
160  static bool force_spdy_;
161};
162
163}  // namespace net
164
165#endif  // NET_TOOLS_FLIP_SERVER_SM_CONNECTION_H_
166