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// TCP/IP server that handles IO asynchronously in the specified MessageLoop.
6// These objects are NOT thread safe.  They use WSAEVENT handles to monitor
7// activity in a given MessageLoop.  This means that callbacks will
8// happen in that loop's thread always and that all other methods (including
9// constructors and destructors) should also be called from the same thread.
10
11#ifndef NET_BASE_LISTEN_SOCKET_H_
12#define NET_BASE_LISTEN_SOCKET_H_
13#pragma once
14
15#include "build/build_config.h"
16
17#if defined(OS_WIN)
18#include <winsock2.h>
19#endif
20#include <string>
21#if defined(OS_WIN)
22#include "base/win/object_watcher.h"
23#elif defined(OS_POSIX)
24#include "base/message_loop.h"
25#endif
26
27#include "base/basictypes.h"
28#include "base/memory/ref_counted.h"
29
30#if defined(OS_POSIX)
31struct event;  // From libevent
32typedef int SOCKET;
33#endif
34
35// Implements a raw socket interface
36class ListenSocket : public base::RefCountedThreadSafe<ListenSocket>,
37#if defined(OS_WIN)
38                     public base::win::ObjectWatcher::Delegate
39#elif defined(OS_POSIX)
40                     public MessageLoopForIO::Watcher
41#endif
42{
43 public:
44  // TODO(erikkay): this delegate should really be split into two parts
45  // to split up the listener from the connected socket.  Perhaps this class
46  // should be split up similarly.
47  class ListenSocketDelegate {
48   public:
49    virtual ~ListenSocketDelegate() {}
50
51    // server is the original listening Socket, connection is the new
52    // Socket that was created.  Ownership of connection is transferred
53    // to the delegate with this call.
54    virtual void DidAccept(ListenSocket *server, ListenSocket *connection) = 0;
55    virtual void DidRead(ListenSocket *connection,
56                         const char* data,
57                         int len) = 0;
58    virtual void DidClose(ListenSocket *sock) = 0;
59  };
60
61  // Listen on port for the specified IP address.  Use 127.0.0.1 to only
62  // accept local connections.
63  static ListenSocket* Listen(std::string ip, int port,
64                              ListenSocketDelegate* del);
65
66  // Send data to the socket.
67  void Send(const char* bytes, int len, bool append_linefeed = false);
68  void Send(const std::string& str, bool append_linefeed = false);
69
70  // NOTE: This is for unit test use only!
71  // Pause/Resume calling Read().  Note that ResumeReads() will also call
72  // Read() if there is anything to read.
73  void PauseReads();
74  void ResumeReads();
75
76 protected:
77  friend class base::RefCountedThreadSafe<ListenSocket>;
78
79  enum WaitState {
80    NOT_WAITING      = 0,
81    WAITING_ACCEPT   = 1,
82    WAITING_READ     = 3,
83    WAITING_CLOSE    = 4
84  };
85
86  static const SOCKET kInvalidSocket;
87  static const int kSocketError;
88
89  ListenSocket(SOCKET s, ListenSocketDelegate* del);
90  virtual ~ListenSocket();
91  static SOCKET Listen(std::string ip, int port);
92  // if valid, returned SOCKET is non-blocking
93  static SOCKET Accept(SOCKET s);
94
95  virtual void SendInternal(const char* bytes, int len);
96
97  virtual void Listen();
98  virtual void Accept();
99  virtual void Read();
100  virtual void Close();
101  virtual void CloseSocket(SOCKET s);
102
103  // Pass any value in case of Windows, because in Windows
104  // we are not using state.
105  void WatchSocket(WaitState state);
106  void UnwatchSocket();
107
108#if defined(OS_WIN)
109  // ObjectWatcher delegate
110  virtual void OnObjectSignaled(HANDLE object);
111  base::win::ObjectWatcher watcher_;
112  HANDLE socket_event_;
113#elif defined(OS_POSIX)
114  // Called by MessagePumpLibevent when the socket is ready to do I/O
115  virtual void OnFileCanReadWithoutBlocking(int fd);
116  virtual void OnFileCanWriteWithoutBlocking(int fd);
117  WaitState wait_state_;
118  // The socket's libevent wrapper
119  MessageLoopForIO::FileDescriptorWatcher watcher_;
120#endif
121
122  SOCKET socket_;
123  ListenSocketDelegate *socket_delegate_;
124
125 private:
126  bool reads_paused_;
127  bool has_pending_reads_;
128
129  DISALLOW_COPY_AND_ASSIGN(ListenSocket);
130};
131
132#endif  // NET_BASE_LISTEN_SOCKET_H_
133