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