Index: net/web2socket_proxy/web2socket_conn.h |
diff --git a/net/web2socket_proxy/web2socket_conn.h b/net/web2socket_proxy/web2socket_conn.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d1105474c8ee009b54b385584fd6e716c556ec42 |
--- /dev/null |
+++ b/net/web2socket_proxy/web2socket_conn.h |
@@ -0,0 +1,125 @@ |
+// Copyright (c) 2010 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 CHROME_WEB2SOCKET_PROXY_WEB2SOCKET_CONN_H_ |
+#define CHROME_WEB2SOCKET_PROXY_WEB2SOCKET_CONN_H_ |
+ |
+#include <sys/socket.h> |
+ |
+#include "base/md5.h" |
+#include "net/web2socket_proxy/web2socket_serv.h" |
+#include "third_party/libevent/event.h" |
+ |
+class Conn { |
+ public: |
+ Web2SocketServ* master_; |
+ |
+ enum Phase { |
+ // Initial stage of connection. |
+ PHASE_WAIT_HANDSHAKE, |
+ PHASE_WAIT_DESTFRAME, |
+ PHASE_WAIT_DESTCONNECT, |
+ |
+ // Operational stage of connection. |
+ PHASE_OUTSIDE_FRAME, |
+ PHASE_INSIDE_FRAME_BASE64, |
+ PHASE_INSIDE_FRAME_SKIP, |
+ |
+ // Terminal stage of connection. |
+ PHASE_SHUT, // Closing handshake was emitted, buffers may pending. |
+ PHASE_DEFUNCT // Connection was nuked. |
+ } phase_; |
+ |
+ // We maintain two channels per Conn: |
+ // primary channel is websocket connection, |
+ // destination channel is a proxied connection. |
+ class Chan { |
+ public: |
+ int sock_; |
+ struct bufferevent* bev_; |
+ |
+ Chan() : sock_(-1), bev_(NULL) {} |
+ |
+ ~Chan() { |
+ if (bev_) { |
+ bufferevent_disable(bev_, EV_READ | EV_WRITE); |
+ bufferevent_free(bev_); |
+ bev_ = NULL; |
+ } |
+ if (sock_ >= 0) { |
+ shutdown(sock_, SHUT_RDWR); |
+ close(sock_); |
+ sock_ = -1; |
+ } |
+ } |
+ } primchan_, destchan_; |
+ |
+ // Unfortunately evdns callbacks are uncancellable, |
+ // so potentially we can receive callback for a deleted Conn. |
+ // Even worse, storage of deleted Conn may be reused |
+ // for a new connection and new connection can receive callback |
+ // destined for deleted Conn. |
+ // Conn::Token is introduced in order to prevent that. |
+ typedef void* Token; |
+ Token token_; |
+ typedef std::map<Token, Conn*> TokenMap; |
+ static TokenMap token_map_; |
+ static Token last_token_; |
+ static Conn* Get(Token token); |
+ |
+ // Header fields supplied by client at initial websocket handshake. |
+ std::map<std::string, std::string> header_fields_; |
+ |
+ // Cryptohashed answer for websocket handshake. |
+ MD5Digest handshake_response_; |
+ |
+ // Hostname and port of destination socket. |
+ // Websocket client supplies them in first data frame (destframe). |
+ std::string destname_; |
+ uint32_t destport_; |
+ |
+ // We try to DNS resolve hostname in both IPv4 and IPv6 domains. |
+ // Track resolution failures here. |
+ bool destresolution_ipv4_failure_; |
+ bool destresolution_ipv6_failure_; |
+ |
+ // Used to schedule a timeout for an initial phase of connection. |
+ struct event destconnect_timeout_event_; |
+ |
+ explicit Conn(Web2SocketServ* master); |
+ ~Conn(); |
+ |
+ enum Status { |
+ STATUS_OK, |
+ STATUS_INCOMPLETE, |
+ STATUS_SKIP, |
+ STATUS_ABORT |
+ }; |
+ |
+ void Shut(); |
+ Status ConsumeHeader(struct evbuffer*); |
+ Status ConsumeDestframe(struct evbuffer*); |
+ Status ConsumeFrameHeader(struct evbuffer*); |
+ Status ProcessFrameData(struct evbuffer*); |
+ |
+ // return true on success. |
+ bool EmitHandshake(struct bufferevent*); |
+ bool TryConnectDest(const struct sockaddr*, socklen_t); |
+ |
+ static void OnDestConnectTimeout(int, short, Token); |
+ static void OnPrimchanRead(struct bufferevent*, Token); |
+ static void OnPrimchanWrite(struct bufferevent*, Token); |
+ static void OnPrimchanError(struct bufferevent*, short what, Token); |
+ static void OnDestResolutionIPv4(int result, char type, int count, |
+ int ttl, void* addr_list, Token); |
+ static void OnDestResolutionIPv6(int result, char type, int count, |
+ int ttl, void* addr_list, Token); |
+ static void OnDestchanRead(struct bufferevent*, Token); |
+ static void OnDestchanWrite(struct bufferevent*, Token); |
+ static void OnDestchanError(struct bufferevent*, short what, Token); |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Conn); |
+}; |
+ |
+#endif // CHROME_WEB2SOCKET_PROXY_WEB2SOCKET_CONN_H_ |