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