1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 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#ifndef NET_SOCKET_TCP_CLIENT_SOCKET_WIN_H_ 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NET_SOCKET_TCP_CLIENT_SOCKET_WIN_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <winsock2.h> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/non_thread_safe.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/address_list.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/completion_callback.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_log.h" 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/socket/client_socket.h" 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net { 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BoundNetLog; 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass TCPClientSocketWin : public ClientSocket, base::NonThreadSafe { 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The IP address(es) and port number to connect to. The TCP socket will try 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // each IP address in the list until it succeeds in establishing a 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // connection. 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TCPClientSocketWin(const AddressList& addresses, 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick net::NetLog* net_log, 283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const net::NetLog::Source& source); 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual ~TCPClientSocketWin(); 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // AdoptSocket causes the given, connected socket to be adopted as a TCP 334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // socket. This object must not be connected. This object takes ownership of 344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // the given socket and then acts as if Connect() had been called. This 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // function is used by TCPServerSocket() to adopt accepted connections 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // and for testing. 374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch void AdoptSocket(SOCKET socket); 384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ClientSocket methods: 407b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen virtual int Connect(CompletionCallback* callback 417b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID 427b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen , bool wait_for_connect 437b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif 447b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen ); 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Disconnect(); 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool IsConnected() const; 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool IsConnectedAndIdle() const; 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual int GetPeerAddress(AddressList* address) const; 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual int GetLocalAddress(IPEndPoint* address) const; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual const BoundNetLog& NetLog() const { return net_log_; } 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void SetSubresourceSpeculation(); 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual void SetOmniboxSpeculation(); 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick virtual bool WasEverUsed() const; 54513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch virtual bool UsingTCPFastOpen() const; 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Socket methods: 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Multiple outstanding requests are not supported. 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Full duplex mode (reading and writing at the same time) is supported 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback); 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback); 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool SetReceiveBufferSize(int32 size); 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool SetSendBufferSize(int32 size); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // State machine for connecting the socket. 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch enum ConnectState { 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CONNECT_STATE_CONNECT, 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CONNECT_STATE_CONNECT_COMPLETE, 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CONNECT_STATE_NONE, 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott class Core; 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // State machine used by Connect(). 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int DoConnectLoop(int result); 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int DoConnect(); 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int DoConnectComplete(int result); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Helper used by Disconnect(), which disconnects minus the logging and 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // resetting of current_ai_. 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void DoDisconnect(); 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns true if a Connect() is in progress. 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool waiting_connect() const { 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return next_connect_state_ != CONNECT_STATE_NONE; 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns the OS error code (or 0 on success). 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int CreateSocket(const struct addrinfo* ai); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Returns the OS error code (or 0 on success). 934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int SetupSocket(); 944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Called after Connect() has completed with |net_error|. 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void LogConnectCompletion(int net_error); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoReadCallback(int rv); 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoWriteCallback(int rv); 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DidCompleteConnect(); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DidCompleteRead(); 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DidCompleteWrite(); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SOCKET socket_; 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The list of addresses we should try in order to establish a connection. 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddressList addresses_; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Where we are in above list, or NULL if all addrinfos have been tried. 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const struct addrinfo* current_ai_; 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The various states that the socket could be in. 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool waiting_read_; 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool waiting_write_; 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The core of the socket that can live longer than the socket itself. We pass 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // resources to the Windows async IO functions and we have to make sure that 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // they are not destroyed while the OS still references them. 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<Core> core_; 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // External callback; called when connect or read is complete. 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* read_callback_; 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // External callback; called when write is complete. 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompletionCallback* write_callback_; 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The next state for the Connect() state machine. 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ConnectState next_connect_state_; 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The OS error that CONNECT_STATE_CONNECT last completed with. 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int connect_os_error_; 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BoundNetLog net_log_; 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 135513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // This socket was previously disconnected and has not been re-connected. 136513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch bool previously_disconnected_; 137513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Record of connectivity and transmissions, for use in speculative connection 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // histograms. 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UseHistory use_history_; 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(TCPClientSocketWin); 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace net 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // NET_SOCKET_TCP_CLIENT_SOCKET_WIN_H_ 148