summaryrefslogtreecommitdiffstats
path: root/net/socket/websocket_transport_connect_sub_job.h
blob: 36a4e943eb01184bdb224e0fd2e36a7da8aed533 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_SOCKET_WEBSOCKET_TRANSPORT_CONNECT_SUB_JOB_H_
#define NET_SOCKET_WEBSOCKET_TRANSPORT_CONNECT_SUB_JOB_H_

#include <stddef.h>
#include <utility>

#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/address_list.h"
#include "net/base/load_states.h"
#include "net/socket/websocket_endpoint_lock_manager.h"
#include "net/socket/websocket_transport_client_socket_pool.h"

namespace net {

class BoundNetLog;
class ClientSocketFactory;
class IPEndPoint;
class StreamSocket;

// Attempts to connect to a subset of the addresses required by a
// WebSocketTransportConnectJob, specifically either the IPv4 or IPv6
// addresses. Each address is tried in turn, and parent_job->OnSubJobComplete()
// is called when the first address succeeds or the last address fails.
class WebSocketTransportConnectSubJob
    : public WebSocketEndpointLockManager::Waiter {
 public:
  typedef WebSocketTransportConnectJob::SubJobType SubJobType;

  WebSocketTransportConnectSubJob(const AddressList& addresses,
                                  WebSocketTransportConnectJob* parent_job,
                                  SubJobType type);

  ~WebSocketTransportConnectSubJob() override;

  // Start connecting.
  int Start();

  bool started() { return next_state_ != STATE_NONE; }

  LoadState GetLoadState() const;

  SubJobType type() const { return type_; }

  scoped_ptr<StreamSocket> PassSocket() { return std::move(transport_socket_); }

  // Implementation of WebSocketEndpointLockManager::EndpointWaiter.
  void GotEndpointLock() override;

 private:
  enum State {
    STATE_NONE,
    STATE_OBTAIN_LOCK,
    STATE_OBTAIN_LOCK_COMPLETE,
    STATE_TRANSPORT_CONNECT,
    STATE_TRANSPORT_CONNECT_COMPLETE,
    STATE_DONE,
  };

  ClientSocketFactory* client_socket_factory() const;

  const BoundNetLog& net_log() const;

  const IPEndPoint& CurrentAddress() const;

  void OnIOComplete(int result);
  int DoLoop(int result);
  int DoEndpointLock();
  int DoEndpointLockComplete();
  int DoTransportConnect();
  int DoTransportConnectComplete(int result);

  WebSocketTransportConnectJob* const parent_job_;

  const AddressList addresses_;
  size_t current_address_index_;

  State next_state_;
  const SubJobType type_;

  scoped_ptr<StreamSocket> transport_socket_;

  DISALLOW_COPY_AND_ASSIGN(WebSocketTransportConnectSubJob);
};

}  // namespace net

#endif  // NET_SOCKET_WEBSOCKET_TRANSPORT_CONNECT_SUB_JOB_H_