15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_TOOLS_FLIP_SERVER_SM_CONNECTION_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_TOOLS_FLIP_SERVER_SM_CONNECTION_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <arpa/inet.h>  // in_addr_t
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/create_listener.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/epoll_server.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/mem_cache.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/ring_buffer.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/sm_interface.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "openssl/ssl.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FlipAcceptor;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MemoryCache;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SSLState;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A frame of data to be sent.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DataFrame {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* data;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t size;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool delete_when_done;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t index;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DataFrame() : data(NULL), size(0), delete_when_done(false), index(0) {}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~DataFrame();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::list<DataFrame*> OutputList;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SMConnection : public SMConnectionInterface,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     public EpollCallbackInterface,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     public NotifierInterface {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SMConnection();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static SMConnection* NewSMConnection(EpollServer* epoll_server,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       SSLState *ssl_state,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       MemoryCache* memory_cache,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       FlipAcceptor *acceptor,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       std::string log_prefix);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(mbelshe): Make these private.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  time_t last_read_time_;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string server_ip_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string server_port_;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual EpollServer* epoll_server() OVERRIDE;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OutputList* output_list() { return &output_list_; }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MemoryCache* memory_cache() { return memory_cache_; }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReadyToSend() OVERRIDE;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EnqueueDataFrame(DataFrame* df);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int fd() const { return fd_; }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool initialized() const { return initialized_; }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string client_ip() const { return client_ip_; }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitSMConnection(SMConnectionPoolInterface* connection_pool,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        SMInterface* sm_interface,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        EpollServer* epoll_server,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int fd,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        std::string server_ip,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        std::string server_port,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        std::string remote_ip,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        bool use_ssl);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CorkSocket();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UncorkSocket();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Send(const char* data, int len, int flags);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // EpollCallbackInterface interface.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnRegistration(EpollServer* eps,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              int fd,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              int event_mask) OVERRIDE;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnModification(int fd, int event_mask) OVERRIDE {}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnEvent(int fd, EpollEvent* event) OVERRIDE;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnUnregistration(int fd, bool replaced) OVERRIDE;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnShutdown(EpollServer* eps, int fd) OVERRIDE;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NotifierInterface interface.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Notify() OVERRIDE {}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Cleanup(const char* cleanup);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flag indicating if we should force spdy on all connections.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool force_spdy() { return force_spdy_; }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void set_force_spdy(bool value) { force_spdy_ = value; }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Decide if SPDY was negotiated.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool WasSpdyNegotiated();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the protocol interfaces we'll need for this connection.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if successful, false otherwise.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SetupProtocolInterfaces();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool DoRead();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool DoWrite();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool DoConsumeReadData();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleEvents();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleResponseFullyRead();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend std::ostream& operator<<(std::ostream& os, const SMConnection& c) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    os << &c << "\n";
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return os;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SMConnection(EpollServer* epoll_server,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               SSLState* ssl_state,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               MemoryCache* memory_cache,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               FlipAcceptor* acceptor,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::string log_prefix);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int fd_;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int events_;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool registered_in_epoll_server_;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool initialized_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool protocol_detected_;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool connection_complete_;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SMConnectionPoolInterface* connection_pool_;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EpollServer *epoll_server_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLState *ssl_state_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MemoryCache* memory_cache_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FlipAcceptor *acceptor_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string client_ip_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RingBuffer read_buffer_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OutputList output_list_;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SMInterface* sm_spdy_interface_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SMInterface* sm_http_interface_;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SMInterface* sm_streamer_interface_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SMInterface* sm_interface_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string log_prefix_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t max_bytes_sent_per_dowrite_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSL* ssl_;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool force_spdy_;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NET_TOOLS_FLIP_SERVER_SM_CONNECTION_H_
163