OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef NET_SOCKET_SCTP_CLIENT_SOCKET_LIBEVENT_H_ |
| 6 #define NET_SOCKET_SCTP_CLIENT_SOCKET_LIBEVENT_H_ |
| 7 #pragma once |
| 8 |
| 9 #include <netinet/in.h> |
| 10 |
| 11 #include "base/message_loop.h" |
| 12 #include "base/memory/ref_counted.h" |
| 13 #include "base/memory/scoped_ptr.h" |
| 14 #include "base/threading/non_thread_safe.h" |
| 15 #include "net/base/address_list.h" |
| 16 #include "net/base/completion_callback.h" |
| 17 #include "net/base/net_log.h" |
| 18 #include "net/socket/client_socket.h" |
| 19 |
| 20 struct event; // From libevent |
| 21 |
| 22 namespace net { |
| 23 |
| 24 class BoundNetLog; |
| 25 |
| 26 // A client socket that uses SCTP as the transport layer. |
| 27 class SCTPClientSocketLibevent : public ClientSocket, base::NonThreadSafe { |
| 28 public: |
| 29 // The IP address(es) and port number to connect to. The SCTP socket will try |
| 30 // each IP address in the list until it succeeds in establishing a |
| 31 // connection. |
| 32 SCTPClientSocketLibevent(const AddressList& addresses, |
| 33 net::NetLog* net_log, |
| 34 const net::NetLog::Source& source); |
| 35 |
| 36 virtual ~SCTPClientSocketLibevent(); |
| 37 |
| 38 // AdoptSocket causes the given, connected socket to be adopted as an SCTP |
| 39 // socket. This object must not be connected. This object takes ownership of |
| 40 // the given socket and then acts as if Connect() had been called. This |
| 41 // function is intended for testing only. |
| 42 void AdoptSocket(int socket); |
| 43 |
| 44 // ClientSocket methods: |
| 45 virtual int Connect(CompletionCallback* callback); |
| 46 virtual void Disconnect(); |
| 47 virtual bool IsConnected() const; |
| 48 virtual bool IsConnectedAndIdle() const; |
| 49 virtual int GetPeerAddress(AddressList* address) const; |
| 50 virtual const BoundNetLog& NetLog() const; |
| 51 virtual void SetSubresourceSpeculation() {} |
| 52 virtual void SetOmniboxSpeculation() {} |
| 53 virtual bool WasEverUsed() const { return false; } |
| 54 virtual bool UsingTCPFastOpen() const { return false; } |
| 55 virtual int protocol() { return IPPROTO_SCTP; } |
| 56 virtual bool using_sctp_control_stream() { |
| 57 return using_sctp_control_stream_ ? true : false; |
| 58 } |
| 59 virtual void set_using_sctp_control_stream() { |
| 60 using_sctp_control_stream_ = true; |
| 61 return; |
| 62 } |
| 63 |
| 64 // Map a SPDY stream number to an SCTP stream ID. |
| 65 virtual uint16 MapSpdyToSctp(uint32 stream_id); |
| 66 |
| 67 // Socket methods: |
| 68 // Multiple outstanding requests are not supported. |
| 69 // Full duplex mode (reading and writing at the same time) is supported |
| 70 virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback); |
| 71 virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback); |
| 72 virtual bool SetReceiveBufferSize(int32 size); |
| 73 virtual bool SetSendBufferSize(int32 size); |
| 74 |
| 75 private: |
| 76 // State machine for connecting the socket. |
| 77 enum ConnectState { |
| 78 CONNECT_STATE_CONNECT, |
| 79 CONNECT_STATE_CONNECT_COMPLETE, |
| 80 CONNECT_STATE_NONE, |
| 81 }; |
| 82 |
| 83 // State of SCTP association for the socket. |
| 84 enum AssociationState { |
| 85 SCTP_EMPTY, |
| 86 SCTP_CLOSED, |
| 87 SCTP_COOKIE_WAIT, |
| 88 SCTP_COOKIE_ECHOED, |
| 89 SCTP_ESTABLISHED, |
| 90 SCTP_SHUTDOWN_PENDING, |
| 91 SCTP_SHUTDOWN_SENT, |
| 92 SCTP_SHUTDOWN_RECEIVED, |
| 93 SCTP_SHUTDOWN_ACK_SENT, |
| 94 }; |
| 95 |
| 96 class ReadWatcher : public MessageLoopForIO::Watcher { |
| 97 public: |
| 98 explicit ReadWatcher(SCTPClientSocketLibevent* socket) : socket_(socket) {} |
| 99 |
| 100 // MessageLoopForIO::Watcher methods |
| 101 |
| 102 virtual void OnFileCanReadWithoutBlocking(int /* fd */) { |
| 103 if (socket_->read_callback_) |
| 104 socket_->DidCompleteRead(); |
| 105 } |
| 106 |
| 107 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) {} |
| 108 |
| 109 private: |
| 110 SCTPClientSocketLibevent* const socket_; |
| 111 |
| 112 DISALLOW_COPY_AND_ASSIGN(ReadWatcher); |
| 113 }; |
| 114 |
| 115 class WriteWatcher : public MessageLoopForIO::Watcher { |
| 116 public: |
| 117 explicit WriteWatcher(SCTPClientSocketLibevent* socket) : socket_(socket) {} |
| 118 |
| 119 // MessageLoopForIO::Watcher methods |
| 120 |
| 121 virtual void OnFileCanReadWithoutBlocking(int /* fd */) {} |
| 122 |
| 123 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) { |
| 124 if (socket_->waiting_connect()) { |
| 125 socket_->DidCompleteConnect(); |
| 126 } else if (socket_->write_callback_) { |
| 127 socket_->DidCompleteWrite(); |
| 128 } |
| 129 } |
| 130 |
| 131 private: |
| 132 SCTPClientSocketLibevent* const socket_; |
| 133 |
| 134 DISALLOW_COPY_AND_ASSIGN(WriteWatcher); |
| 135 }; |
| 136 |
| 137 // State machine used by Connect(). |
| 138 int DoConnectLoop(int result); |
| 139 int DoConnect(); |
| 140 int DoConnectComplete(int result); |
| 141 |
| 142 // Helper used by Disconnect(), which disconnects minus the logging and |
| 143 // resetting of current_ai_. |
| 144 void DoDisconnect(); |
| 145 |
| 146 void DoReadCallback(int rv); |
| 147 void DoWriteCallback(int rv); |
| 148 void DidCompleteRead(); |
| 149 void DidCompleteWrite(); |
| 150 void DidCompleteConnect(); |
| 151 |
| 152 // Returns true if a Connect() is in progress. |
| 153 bool waiting_connect() const { |
| 154 return next_connect_state_ != CONNECT_STATE_NONE; |
| 155 } |
| 156 |
| 157 // Returns the OS error code (or 0 on success). |
| 158 int CreateSocket(const struct addrinfo* ai); |
| 159 |
| 160 // Returns the OS error code (or 0 on success). |
| 161 int SetupSocket(); |
| 162 |
| 163 // Helper to add an SCTP_CONNECT (end) event to the NetLog. |
| 164 void LogConnectCompletion(int net_error); |
| 165 |
| 166 // Internal function to write to a socket. |
| 167 int InternalWrite(IOBuffer* buf, int buf_len); |
| 168 int InternalWrite(IOBuffer* buf, int buf_len, int sctp_stream_id); |
| 169 |
| 170 int socket_; |
| 171 |
| 172 // The list of addresses we should try in order to establish a connection. |
| 173 AddressList addresses_; |
| 174 |
| 175 // Where we are in above list, or NULL if all addrinfos have been tried. |
| 176 const struct addrinfo* current_ai_; |
| 177 |
| 178 // Flag to indicate whether or not we are sending SPDY control frames on SCTP |
| 179 // stream 0. |
| 180 bool using_sctp_control_stream_; |
| 181 |
| 182 // Number of outgoing SCTP streams negotiated during association setup. |
| 183 uint16 max_sctp_streams_; |
| 184 |
| 185 // The socket's libevent wrappers |
| 186 MessageLoopForIO::FileDescriptorWatcher read_socket_watcher_; |
| 187 MessageLoopForIO::FileDescriptorWatcher write_socket_watcher_; |
| 188 |
| 189 // The corresponding watchers for reads and writes. |
| 190 ReadWatcher read_watcher_; |
| 191 WriteWatcher write_watcher_; |
| 192 |
| 193 // The buffer used by OnSocketReady to retry Read requests |
| 194 scoped_refptr<IOBuffer> read_buf_; |
| 195 int read_buf_len_; |
| 196 |
| 197 // The buffer used by OnSocketReady to retry Write requests |
| 198 scoped_refptr<IOBuffer> write_buf_; |
| 199 int write_buf_len_; |
| 200 |
| 201 // External callback; called when read is complete. |
| 202 CompletionCallback* read_callback_; |
| 203 |
| 204 // External callback; called when write is complete. |
| 205 CompletionCallback* write_callback_; |
| 206 |
| 207 // The next state for the Connect() state machine. |
| 208 ConnectState next_connect_state_; |
| 209 |
| 210 // The OS error that CONNECT_STATE_CONNECT last completed with. |
| 211 int connect_os_error_; |
| 212 |
| 213 BoundNetLog net_log_; |
| 214 |
| 215 // This socket was previously disconnected and has not been re-connected. |
| 216 bool previously_disconnected_; |
| 217 |
| 218 // Record of connectivity and transmissions, for use in speculative connection |
| 219 // histograms. |
| 220 UseHistory use_history_; |
| 221 |
| 222 DISALLOW_COPY_AND_ASSIGN(SCTPClientSocketLibevent); |
| 223 }; |
| 224 |
| 225 } // namespace net |
| 226 |
| 227 #endif // NET_SOCKET_SCTP_CLIENT_SOCKET_LIBEVENT_H_ |
OLD | NEW |