root/trunk/whisperlib/net/base/connection.h

Revision 7, 27.7 kB (checked in by whispercastorg, 2 years ago)

version 0.2.0

Line 
1 // Copyright (c) 2009, Whispersoft s.r.l.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Whispersoft s.r.l. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Authors: Cosmin Tudorache & Catalin Popescu
31 //
32
33 #ifndef __NET_BASE_CONNECTION_H__
34 #define __NET_BASE_CONNECTION_H__
35
36 #include <string>
37 #include <whisperlib/common/base/types.h>
38 #include <whisperlib/common/base/log.h>
39
40 #include <whisperlib/common/io/buffer/memory_stream.h>
41
42 #include <whisperlib/net/base/address.h>
43 #include <whisperlib/net/base/selectable.h>
44 #include <whisperlib/net/base/timeouter.h>
45
46 #include <openssl/ssl.h>
47 #include <openssl/err.h>
48
49 // TcpConnection
50 // -------------
51 // Encapsulates a socket file descriptor of the underneath connection.
52 // This class provides the basic mechanisms for handling events received
53 // from the selector. It implements reading and writing methods for
54 // reading/writing from/to the fd. It also uses read/write buffers ,
55 // so you don't have to re-buffer.
56 // To use this class:
57 // - obtain an instance, either by direct constructor, or by factory
58 // - set appropriate handlers (connect, read, write, close)
59 // - call Connect to connect to open connection to desired address.
60 // You will be notified on "connect" handler when connection is
61 // fully established, or connect failed.
62 // In fully connected mode, you will be notified on "read" handler when new data
63 // arrives (read it from inbuf() stream), and on "close" handler when
64 // the connection got closed (either because you or your party closed it).
65 // NOTE possible pitfalls:
66 //  -- all handlers should return as fast as possible, selector's asynchronous
67 //     execution efficiency depends on it.
68 //  -- to implement timeouts, use net::Timeouter class w/ the selector
69 //  -- to implement flow-control you should check the size of inbuf(),
70 //     and/or outbuf() and enable/disable reading or writing as required
71 //     for your protocol.
72
73 // TcpAcceptor
74 // -----------
75 // Encapsulates a listening socket file descriptor.
76 // To use this class:
77 // - obtain an instance, either by direct constructor, or by factory
78 // - set appropriate handlers (accept, filter)
79 // - call Listen to open local address in listen mode
80 // You will be notified on "filter" handler when someone wants to connect
81 // and on "accept" handler when someone connected.
82
83 //
84 // TODO(cpopescu): Include a DNS lookup feature and the corresponding
85 //                 Connect form
86 //
87
88 namespace net {
89
90 ////////////////////////////////////////////////////////////////////////////
91
92 struct NetConnectionParams {
93   NetConnectionParams(common::ByteOrder byte_order = common::kByteOrder,
94                       int block_size = io::DataBlock::kDefaultBufferSize)
95     : byte_order_(byte_order),
96       block_size_(block_size) {
97   }
98   common::ByteOrder byte_order_;
99   int block_size_;
100 };
101
102 struct NetAcceptorParams {
103   NetAcceptorParams()
104       : next_client_thread_(0),
105         client_threads_(NULL) {
106   }
107   NetAcceptorParams(const NetAcceptorParams& params)
108       : next_client_thread_(0),
109         client_threads_(params.client_threads_) {
110   }
111   void set_client_threads(const vector<SelectorThread*>* client_threads) {
112     CHECK(client_threads_ == NULL);
113     client_threads_ = client_threads;
114   }
115   Selector* GetNextSelector() {
116     if ( client_threads_ == NULL ) return NULL;
117     if ( next_client_thread_ >= client_threads_->size() ) {
118       next_client_thread_ = 0;
119     }
120     Selector* const chosen =
121         (*client_threads_)[next_client_thread_]->mutable_selector();
122     next_client_thread_++;
123     return chosen;
124   }
125   private:
126   int next_client_thread_;
127   const vector<SelectorThread*>* client_threads_;
128 };
129
130 ////////////////////////////////////////////////////////////////////////////
131
132 class Selector;
133 class NetConnection;
134
135 class NetAcceptor {
136  public:
137   enum State {
138     DISCONNECTED,
139     LISTENING,
140   };
141   static const char* StateName(State s) {
142     switch (s) {
143       CONSIDER(DISCONNECTED);
144       CONSIDER(LISTENING);
145       default: return "UNKNOWN";
146     }
147   }
148
149  public:
150   NetAcceptor(const NetAcceptorParams& params = NetAcceptorParams())
151     : state_(DISCONNECTED),
152       local_address_(),
153       last_error_code_(0),
154       count_clients_accepted_(0),
155       filter_handler_(NULL),
156       own_filter_handler_(false),
157       accept_handler_(NULL),
158       own_accept_handler_(false) {
159   }
160   virtual ~NetAcceptor() {
161     // The SUPER class should call Close() in destructor;
162     // we cannot call it, because Close is virtual.
163     CHECK_EQ(state(), DISCONNECTED);
164     DetachAllHandlers();
165   }
166
167   // opens acceptor in listen mode
168   virtual bool Listen(const net::HostPort& local_addr) = 0;
169
170   // closes acceptor
171   virtual void Close() = 0;
172
173   // returns a description of this acceptor, useful as log line header
174   // Usage example:
175   //  LOG_INFO << acceptor.PrefixInfo() << "foo";
176   // yields a log line like:
177   //  "LISTENING : [0.0.0.0:5665 (fd: 7)] foo"
178   virtual string PrefixInfo() const = 0;
179
180   const HostPort& local_address() const {
181     return local_address_;
182   }
183   State state() const {
184     return state_;
185   }
186   const char* StateName() const {
187     return StateName(state_);
188   }
189
190   int last_error_code() const {
191     return last_error_code_;
192   }
193
194  protected:
195   void set_state(State state) {
196     state_ = state;
197   }
198   void set_local_address(const net::HostPort& local_address) {
199     local_address_ = local_address;
200   }
201   void set_last_error_code(int last_error_code) {
202     last_error_code_ = last_error_code;
203   }
204
205  public:
206   typedef ResultCallback1<bool, const net::HostPort&> FilterHandler;
207   typedef Callback1<NetConnection*> AcceptHandler;
208
209   void SetFilterHandler(FilterHandler* filter_handler, bool own);
210   void DetachFilterHandler();
211   void SetAcceptHandler(AcceptHandler* accept_handler, bool own);
212   void DetachAcceptHandler();
213   void DetachAllHandlers();
214
215  protected:
216   bool InvokeFilterHandler(const net::HostPort& incoming_peer_address);
217   void InvokeAcceptHandler(NetConnection* new_connection);
218
219  private:
220   // The state we are in
221   State state_;
222
223   // socket local address
224   HostPort local_address_;
225
226   // the code of the last error. Just for log & debug.
227   int last_error_code_;
228
229   // Statistics
230   int64 count_clients_accepted_;
231
232   // We call this handler to notify the application that a new client wants
233   //  to connect.
234   // If the application returns true -> we proceed with connection setup
235   // else -> we reject this guy.
236   FilterHandler* filter_handler_;
237   bool own_filter_handler_;
238   // We call this handler to deliver a fully connected client to application.
239   AcceptHandler* accept_handler_;
240   bool own_accept_handler_;
241 };
242
243 class NetConnection {
244  public:
245   enum State {
246     DISCONNECTED,
247     CONNECTING,
248     CONNECTED,
249     FLUSHING,
250   };
251   static const char* StateName(State s) {
252     switch (s) {
253       CONSIDER(DISCONNECTED);
254       CONSIDER(CONNECTING);
255       CONSIDER(CONNECTED);
256       CONSIDER(FLUSHING);
257     }
258     return "UNKNOWN";
259   }
260
261   enum CloseWhat {
262     CLOSE_READ,        // close read half of the connection
263     CLOSE_WRITE,       // close write half of the connection
264     CLOSE_READ_WRITE,  // close both read & write
265   };
266   static const char* CloseWhatName(CloseWhat what) {
267     switch ( what ) {
268       CONSIDER(CLOSE_READ);
269       CONSIDER(CLOSE_WRITE);
270       CONSIDER(CLOSE_READ_WRITE);
271     }
272     return "UNKNOWN";
273   }
274
275  public:
276   NetConnection(const NetConnectionParams& params)
277     : state_(DISCONNECTED),
278       last_error_code_(0),
279       connect_handler_(NULL),
280       read_handler_(NULL),
281       write_handler_(NULL),
282       close_handler_(NULL),
283       own_connect_handler_(false),
284       own_read_handler_(false),
285       own_write_handler_(false),
286       own_close_handler_(false),
287       count_bytes_written_(0),
288       count_bytes_read_(0),
289       inbuf_(params.byte_order_, params.block_size_),
290       outbuf_(params.byte_order_, params.block_size_) {
291   }
292   virtual ~NetConnection() {
293     DetachAllHandlers();
294   }
295
296   // connect to remote address.
297   // returns: false -> connect failed.
298   //          true -> connect pending.
299   //                  Later on: if the connect procedure succeeds,
300   //                            the ConnectHandler will be called.
301   //                            If it fails, the CloseHandler will be called.
302   virtual bool Connect(const net::HostPort& addr) = 0;
303   virtual void FlushAndClose() = 0;
304   virtual void ForceClose() = 0;
305   // tune connection
306   virtual bool SetSendBufferSize(int size) = 0;
307   virtual bool SetRecvBufferSize(int size) = 0;
308   // These functions registers/unregisters the connection for read/write
309   // events with the selector.
310   virtual void RequestReadEvents(bool enable) = 0;
311   virtual void RequestWriteEvents(bool enable) = 0;
312   // Return local/remote connection address.
313   virtual const HostPort& local_address() const = 0;
314   virtual const HostPort& remote_address() const = 0;
315   // returns a description of this acceptor, useful as log line header
316   // Usage example:
317   //  LOG_INFO << connection.PrefixInfo() << "foo";
318   // yields a log line like:
319   //  "CONNECTED : [12.34.56.78:5665 -> 87.65.43.21:6556 (fd: 7)] foo"
320   virtual string PrefixInfo() const = 0;
321
322
323   typedef Closure ConnectHandler;
324   typedef ResultClosure<bool> ReadHandler;
325   typedef ResultClosure<bool> WriteHandler;
326   typedef Callback2<int, CloseWhat> CloseHandler;
327
328   // Means of communication with the outside world.
329   // Applications should set this handlers to receive connection notifications.
330   // own: true = the handler is automatically deleted.
331   //      false = the caller still owns the handler.
332   void SetConnectHandler(ConnectHandler* connect_handler, bool own);
333   void DetachConnectHandler();
334   void SetReadHandler(ReadHandler* read_handler, bool own);
335   void DetachReadHandler();
336   void SetWriteHandler(WriteHandler* write_handler, bool own);
337   void DetachWriteHandler();
338   void SetCloseHandler(CloseHandler* close_handler, bool own);
339   void DetachCloseHandler();
340   void DetachAllHandlers();
341
342  protected:
343   void InvokeConnectHandler();
344   bool InvokeReadHandler();
345   bool InvokeWriteHandler();
346   void InvokeCloseHandler(int err, CloseWhat what);
347
348  public:
349   State state() const {
350     return state_;
351   }
352   const char* StateName() const {
353     return StateName(state_);
354   }
355
356   // Write basics: copies data to oubuf & enables write requests.
357   void Write(const void* buf, int32 size) {
358     outbuf()->Write(buf, size);
359     RequestWriteEvents(true);
360   }
361   void Write(io::MemoryStream* ms) {
362     outbuf()->AppendStream(ms);
363     RequestWriteEvents(true);
364   }
365   void Write(const string& str) {
366     Write(str.c_str(), str.size());
367   }
368   void Write(const char * sz_str) {
369     Write(sz_str, ::strlen(sz_str));
370   }
371
372   int64 count_bytes_written() const { return count_bytes_written_; }
373   int64 count_bytes_read() const { return count_bytes_read_; }
374
375   io::MemoryStream* inbuf() { return &inbuf_; }
376   io::MemoryStream* outbuf() { return &outbuf_; }
377
378   int last_error_code() const { return last_error_code_; }
379
380  protected:
381   void set_state(State state) {
382     state_ = state;
383   }
384   void set_last_error_code(int err) {
385     last_error_code_ = err;
386   }
387   void inc_bytes_written(int64 value) {
388     count_bytes_written_ += value;
389   }
390   void inc_bytes_read(int64 value) {
391     count_bytes_read_ += value;
392   }
393
394  private:
395   // connection state
396   State state_;
397
398   int last_error_code_;
399
400   ConnectHandler* connect_handler_;
401   ReadHandler* read_handler_;
402   WriteHandler* write_handler_;
403   CloseHandler* close_handler_;
404
405   bool own_connect_handler_;
406   bool own_read_handler_;
407   bool own_write_handler_;
408   bool own_close_handler_;
409
410   // Statistics
411   int64 count_bytes_written_;
412   int64 count_bytes_read_;
413
414   // Buffered connection
415   io::MemoryStream inbuf_;
416   io::MemoryStream outbuf_;
417 };
418
419 /////////////////////////////////////////////////////////////////////////////
420
421 struct TcpConnectionParams : public NetConnectionParams {
422   TcpConnectionParams(common::ByteOrder byte_order = common::kByteOrder,
423                       int block_size = io::DataBlock::kDefaultBufferSize,
424                       int send_buffer_size = -1,
425                       int recv_buffer_size = -1,
426                       int64 shutdown_linger_timeout_ms = 5000)
427     : NetConnectionParams(byte_order, block_size),
428       send_buffer_size_(send_buffer_size),
429       recv_buffer_size_(recv_buffer_size),
430       shutdown_linger_timeout_ms_(shutdown_linger_timeout_ms) {
431   }
432   int send_buffer_size_; // if -1 the system default is used
433   int recv_buffer_size_; // if -1 the system default is used
434   int64 shutdown_linger_timeout_ms_;
435 };
436
437 struct TcpAcceptorParams : public NetAcceptorParams {
438   TcpAcceptorParams(
439       // insert NetAcceptorParams here, with default values
440       const TcpConnectionParams& tcp_connection_params = TcpConnectionParams(),
441       int backlog = 100)
442         : NetAcceptorParams(),
443           tcp_connection_params_(tcp_connection_params),
444           backlog_(backlog) {
445   }
446   // parameter for spawned connections
447   TcpConnectionParams tcp_connection_params_;
448   int backlog_;
449
450 };
451
452 /////////////////////////////////////////////////////////////////////////////
453
454 class TcpConnection;
455
456 class TcpAcceptor : public NetAcceptor, private Selectable {
457  public:
458   TcpAcceptor(Selector* selector,
459               const TcpAcceptorParams& tcp_params = TcpAcceptorParams());
460   virtual ~TcpAcceptor();
461
462   //////////////////////////////////////////////////////////////////////
463   //
464   // NetAcceptor methods
465   //
466  public:
467   virtual bool Listen(const HostPort& local_addr);
468   virtual void Close(); // for both NetAcceptor and Selectable interfaces
469   virtual string PrefixInfo() const;
470
471   //////////////////////////////////////////////////////////////////////
472   //
473   // Overridden selectable interface
474   //
475  private:
476   virtual bool HandleReadEvent(int events);
477   virtual bool HandleWriteEvent(int events);
478   virtual bool HandleErrorEvent(int events);
479   virtual int GetFd() const { return fd_; }
480   //virtual void Close(); // already defined above
481   //////////////////////////////////////////////////////////////////////
482
483  private:
484   // Initializes a new connection in the provided selector
485   void InitializeAceptedConnection(Selector* selector, int client_fd);
486
487   // Sets normal socket options for our purposes:
488   //  non-blocking, fast bind reusing
489   bool SetSocketOptions();
490
491   // returns the errno associated with local fd_
492   int ExtractSocketErrno();
493
494   // close internal socket
495   void InternalClose(int err);
496
497  private:
498   TcpAcceptorParams tcp_params_;
499
500   // The fd of the socket
501   int fd_;
502 };
503
504 ////////////////////////////////////////////////////////////////////////
505 ////////////////////////////////////////////////////////////////////////
506 ////////////////////////////////////////////////////////////////////////
507
508 class TcpConnection : public NetConnection, private Selectable {
509  private:
510   static const int64 kShutdownTimeoutId = -100;
511
512  public:
513   TcpConnection(Selector* selector,
514                 const TcpConnectionParams& tcp_params = TcpConnectionParams());
515   virtual ~TcpConnection();
516
517   // make Selectable::selector() public
518   using net::Selectable::selector;
519
520   void Close(CloseWhat what);
521
522  private:
523   // Use an already connected fd. Usually obtained by an acceptor.
524   // The local and peer addresses are obtained from fd.
525   bool Wrap(int fd);
526   friend class TcpAcceptor;
527
528   //////////////////////////////////////////////////////////////////////
529   //
530   // NetConnection interface methods
531   //
532  public:
533   virtual bool Connect(const HostPort& remote_addr);
534   virtual void FlushAndClose();
535   virtual void ForceClose();
536   virtual bool SetSendBufferSize(int size);
537   virtual bool SetRecvBufferSize(int size);
538   virtual void RequestReadEvents(bool enable);
539   virtual void RequestWriteEvents(bool enable);
540   virtual const HostPort& local_address() const;
541   virtual const HostPort& remote_address() const;
542   virtual string PrefixInfo() const;
543   //////////////////////////////////////////////////////////////////////
544
545   //////////////////////////////////////////////////////////////////////
546   //
547   // Selectable interface methods
548   //
549  private:
550   virtual bool HandleReadEvent(int events);
551   virtual bool HandleWriteEvent(int events);
552   virtual bool HandleErrorEvent(int events);
553   virtual void Close();
554   virtual int GetFd() const { return fd_; }
555   //////////////////////////////////////////////////////////////////////
556
557  private:
558   bool read_closed() const { return read_closed_; }
559   bool write_closed() const { return write_closed_; }
560   void set_read_closed(bool read_closed) { read_closed_ = read_closed; }
561   void set_write_closed(bool write_closed) { write_closed_ = write_closed; }
562
563   // sets socket options for our purposes
564   //  - non-blocking
565   //  - disable Nagel algorithm
566   //  - apply tcp parameters
567   bool SetSocketOptions();
568
569   // returns the errno associated with the given socket
570   static int ExtractSocketErrno(int fd);
571   int ExtractSocketErrno() {
572     return ExtractSocketErrno(fd_);
573   }
574
575   // This function reads the local address from the socket and sets
576   // it into local_address_
577   void InitializeLocalAddress();
578   // This function reads the remote address from the socket and sets
579   // it into remote_address_
580   void InitializeRemoteAddress();
581
582   // because NetConnection::InvokeConnectHandler is protected we wrap it here.
583   void InvokeConnectHandler() {
584     NetConnection::InvokeConnectHandler();
585   }
586   // because NetConnection::InvokeCloseHandler is protected we wrap it here.
587   void InvokeCloseHandler(int err, CloseWhat what) {
588     if ( what == CLOSE_READ || what == CLOSE_READ_WRITE ) {
589       CHECK(read_closed()) << " what=" << what;
590     }
591     if ( what == CLOSE_WRITE || what == CLOSE_READ_WRITE ) {
592       CHECK(write_closed()) << " what=" << what;
593     }
594     NetConnection::InvokeCloseHandler(err, what);
595   }
596
597   // immediate close fd
598   void InternalClose(int err, bool call_close_handler);
599
600   // The timeouter handler
601   void HandleTimeoutEvent(int64 timeout_id);
602
603  private:
604   // parameters for this connection
605   TcpConnectionParams tcp_params_;
606
607   // The fd of the socket
608   int fd_;
609
610   net::HostPort local_address_;
611   net::HostPort remote_address_;
612
613   // true = the write half of the connection is closed; no more transmissions.
614   bool write_closed_;
615   // true = the read half of the connection is closed; no more receptions.
616   bool read_closed_;
617
618   Timeouter timeouter_;
619 };
620
621 ////////////////////////////////////////////////////////////////////////
622 ////////////////////////////////////////////////////////////////////////
623 ////////////////////////////////////////////////////////////////////////
624
625 struct SslConnectionParams : public NetConnectionParams {
626   SslConnectionParams(
627       common::ByteOrder byte_order = common::kByteOrder,
628       int block_size = io::DataBlock::kDefaultBufferSize,
629       SSL_CTX* ssl_context = NULL)
630         : NetConnectionParams(byte_order, block_size),
631           ssl_context_(ssl_context) {
632   }
633   SSL_CTX* ssl_context_;
634 };
635
636 struct SslAcceptorParams : public NetAcceptorParams {
637   SslAcceptorParams(
638       // insert NetAcceptorParams params here
639       const SslConnectionParams& ssl_connection_params = SslConnectionParams()
640       // insert specific SslAcceptorParams params here
641       )
642         : ssl_connection_params_(ssl_connection_params) {
643   }
644   // parameter for spawned connections
645   SslConnectionParams ssl_connection_params_;
646 };
647
648 /////////////////////////////////////////////////////////////////////////
649
650 class SslConnection;
651
652 class SslAcceptor : public NetAcceptor {
653  public:
654   SslAcceptor(Selector* selector,
655               const SslAcceptorParams& ssl_params = SslAcceptorParams());
656   virtual ~SslAcceptor();
657
658   bool TcpAcceptorFilterHandler(const net::HostPort& peer_addr);
659   void TcpAcceptorAcceptHandler(NetConnection* tcp_connection);
660
661   void SslConnectionConnectHandler(SslConnection* ssl_connection);
662   void SslConnectionCloseHandler(SslConnection* ssl_connection,
663       int err, NetConnection::CloseWhat what);
664
665   //////////////////////////////////////////////////////////////////////
666   //
667   // NetAcceptor interface methods
668   //
669   virtual bool Listen(const net::HostPort& local_addr);
670   virtual void Close();
671   virtual string PrefixInfo() const;
672
673  private:
674   // Initialize SSL members
675   bool SslInitialize();
676   // Cleanup SSL members
677   void SslClear();
678
679   // Initializes a new connection in the provided selector
680   void InitializeAceptedConnection(Selector* selector, int client_fd);
681  private:
682   net::Selector* selector_;
683   // parameters for this acceptor
684   const SslAcceptorParams params_;
685
686   // the TCP acceptor
687   TcpAcceptor tcp_acceptor_;
688 };
689
690 class SslConnection : public NetConnection {
691  public:
692   SslConnection(Selector* selector,
693                 const SslConnectionParams& ssl_params = SslConnectionParams());
694   virtual ~SslConnection();
695
696   Selector* selector() const {
697     return selector_;
698   }
699  private:
700   // Use an already established tcp connection. Usually obtained by an acceptor.
701   // We take ownership of tcp_connection.
702   void Wrap(TcpConnection* tcp_connection);
703   friend class SslAcceptor;
704
705   //////////////////////////////////////////////////////////////////////
706   //
707   // NetConnection interface methods
708   //
709  public:
710   virtual bool Connect(const HostPort& remote_addr);
711   virtual void FlushAndClose();
712   virtual void ForceClose();
713   virtual bool SetSendBufferSize(int size);
714   virtual bool SetRecvBufferSize(int size);
715   virtual void RequestReadEvents(bool enable);
716   virtual void RequestWriteEvents(bool enable);
717   virtual const HostPort& local_address() const;
718   virtual const HostPort& remote_address() const;
719   virtual string PrefixInfo() const;
720   //////////////////////////////////////////////////////////////////////
721
722   //////////////////////////////////////////////////////////////////////
723   //
724   // Selectable interface methods
725   //
726  private:
727   virtual bool HandleReadEvent(int events);
728   virtual bool HandleWriteEvent(int events);
729   virtual bool HandleErrorEvent(int events);
730   virtual void Close();
731   virtual int GetFd() const;
732   //////////////////////////////////////////////////////////////////////
733
734  private:
735   // Working with the underlying tcp_connection
736   void TcpConnectionConnectHandler();
737   bool TcpConnectionReadHandler();
738   bool TcpConnectionWriteHandler();
739   void TcpConnectionCloseHandler(int err, CloseWhat what);
740
741   // The timeouter handler
742   void HandleTimeoutEvent(int64 timeout_id);
743
744   // because NetConnection::InvokeConnectHandler is protected we wrap it here.
745   void InvokeConnectHandler() {
746     NetConnection::InvokeConnectHandler();
747   }
748
749  public:
750   static const std::string& SslErrorName(int err);
751   static const std::string& SslWantName(int want);
752   // Returns a description of the last SSL error. This function pops error
753   // values from SSL stack, so don't call it twice.
754   static std::string SslLastError();
755
756   // Globally initialize SSL library.
757   static const void SslLibraryInit();
758
759   // Returns a new X509 structure, or NULL on failure.
760   // You have to call X509_free(..) on the valid result.
761   static X509* SslLoadCertificateFile(const string& filename);
762   // Returns a new EVP_PKEY structure, or NULL on failure.
763   // You have to call EVP_PKEY_free(..) on the valid result.
764   static EVP_PKEY* SslLoadPrivateKeyFile(const string& filename);
765
766   // Clone X509. Never fail. Use X509_free(..).
767   static X509* SslDuplicateX509(const X509& src);
768   // Clone EVP_PKEY. Never fail. Use EVP_PKEY_free(..).
769   static EVP_PKEY* SslDuplicateEVP_PKEY(const EVP_PKEY& src);
770
771   // returns a description of all data buffered in "bio"
772   static string SslPrintableBio(BIO* bio);
773
774   // Returns a new SSL_CTX structure, or NULL on failure.
775   // It also loads SSL certificate and key if non-empty strings.
776   // You have to call SslDeleteContext(..) on the valid result.
777   static SSL_CTX* SslCreateContext(const string& certificate_filename = "",
778                                    const string& key_filename = "");
779   // Free SSL context. This is the reverse of SslCreateContext(..).
780   static void SslDeleteContext(SSL_CTX* ssl_ctx);
781
782  private:
783   bool SslInitialize(bool is_server);
784   void SslClear();
785
786   // do SSL handshake
787   void SslHandshake();
788   // do SSL shutdown
789   void SslShutdown();
790
791  private:
792   net::Selector* selector_;
793   // parameters for this connection
794   const SslConnectionParams ssl_params_;
795
796   // The TCP connection
797   TcpConnection* tcp_connection_;
798
799   static const uint32 kSslBufferSize = 10000; //The maximum size of BIO buffers
800   bool is_server_side_; // true = this is a server side connection
801                         // false = this is a client side connection
802
803   // The OpenSSL structures
804   SSL_CTX* p_ctx_;    // also contains the certificate and key
805   BIO* p_bio_read_;   // Network --> SSL , use BIO_write(p_bio_read_, ...)
806   BIO* p_bio_write_;  // Network <-- SSL , use BIO_read(p_bio_write_, ...)
807   SSL* p_ssl_;
808
809   bool handshake_finished_;
810
811   // helpers for sequencing reads/writes of complete SSL packets.
812   bool read_blocked_;
813   bool read_blocked_on_write_;
814   bool write_blocked_on_read_;
815
816   // for debug, count output/input bytes
817   uint64 ssl_out_count_;
818   uint64 ssl_in_count_;
819
820   Timeouter timeouter_;
821 };
822
823 enum PROTOCOL {
824   PROTOCOL_TCP,
825   PROTOCOL_SSL,
826 };
827 class NetFactory {
828 public:
829   NetFactory(net::Selector* selector)
830     : selector_(selector),
831       tcp_acceptor_params_(),
832       tcp_connection_params_(),
833       ssl_acceptor_params_(),
834       ssl_connection_params_() {
835   }
836   ~NetFactory() {
837   }
838   void SetTcpParams(const TcpAcceptorParams&
839                       tcp_acceptor_params = TcpAcceptorParams(),
840                     const TcpConnectionParams&
841                       tcp_connection_params = TcpConnectionParams()) {
842     tcp_acceptor_params_ = tcp_acceptor_params;
843     tcp_connection_params_ = tcp_connection_params;
844   }
845   void SetSslParams(const SslAcceptorParams&
846                       ssl_acceptor_params = SslAcceptorParams(),
847                     const SslConnectionParams&
848                       ssl_connection_params = SslConnectionParams()) {
849     ssl_acceptor_params_ = ssl_acceptor_params;
850     ssl_connection_params_ = ssl_connection_params;
851   }
852   NetConnection* CreateConnection(PROTOCOL protocol) {
853     switch(protocol) {
854       case PROTOCOL_TCP:
855         return new TcpConnection(selector_, tcp_connection_params_);
856       case PROTOCOL_SSL:
857         return new SslConnection(selector_, ssl_connection_params_);
858       default:
859         LOG_FATAL << "Illegal protocol: " << protocol;
860         return NULL;
861     }
862   }
863   NetAcceptor* CreateAcceptor(PROTOCOL protocol) {
864     switch(protocol) {
865       case PROTOCOL_TCP:
866         return new TcpAcceptor(selector_, tcp_acceptor_params_);
867       case PROTOCOL_SSL:
868         return new SslAcceptor(selector_, ssl_acceptor_params_);
869       default:
870         LOG_FATAL << "Illegal protocol: " << protocol;
871         return NULL;
872     }
873   }
874 private:
875   net::Selector* selector_;
876
877   TcpAcceptorParams tcp_acceptor_params_;
878   TcpConnectionParams tcp_connection_params_;
879
880   SslAcceptorParams ssl_acceptor_params_;
881   SslConnectionParams ssl_connection_params_;
882 };
883 }
884
885 #endif  // __NET_BASE_CONNECTION_H__
Note: See TracBrowser for help on using the browser.