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