Index: chrome/browser/chromeos/net/webproxy/conn.h |
diff --git a/chrome/browser/chromeos/net/webproxy/conn.h b/chrome/browser/chromeos/net/webproxy/conn.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..450fe38f4c19a171897294d6dfc03ef7402ab6a8 |
--- /dev/null |
+++ b/chrome/browser/chromeos/net/webproxy/conn.h |
@@ -0,0 +1,148 @@ |
+// Copyright (c) 2011 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_BROWSER_CHROMEOS_NET_WEBPROXY_CONN_H_ |
+#define CHROME_BROWSER_CHROMEOS_NET_WEBPROXY_CONN_H_ |
+ |
+#include <sys/socket.h> |
+ |
+#include "base/md5.h" |
+#include "chrome/browser/chromeos/net/webproxy/serv.h" |
+#include "third_party/libevent/event.h" |
+ |
+namespace chromeos { |
+namespace webproxy { |
+ |
+class Conn { |
zel
2011/04/07 16:54:12
comments please - what does this class do?
Denis Lagno
2011/04/11 23:21:27
Done.
|
+ public: |
+ 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. |
+ }; |
+ |
+ // Channel structure. |
+ struct Chan { |
+ 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; |
+ } |
+ } |
+ }; |
+ |
+ // Status of processing incoming data. |
+ enum Status { |
+ STATUS_OK, |
+ STATUS_INCOMPLETE, // Not all required data is present in buffer yet. |
+ STATUS_SKIP, |
+ STATUS_ABORT // Data is invalid. We must shut connection. |
+ }; |
+ |
+ // 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; |
+ typedef std::map<Token, Conn*> TokenMap; |
+ |
+ explicit Conn(Serv* master); |
+ ~Conn(); |
+ |
+ static Conn* Get(Token token); |
+ |
+ void Shut(); |
+ |
+ Status ConsumeHeader(struct evbuffer*); |
+ Status ConsumeDestframe(struct evbuffer*); |
+ Status ConsumeFrameHeader(struct evbuffer*); |
+ Status ProcessFrameData(struct evbuffer*); |
+ |
+ // Returns true on success. |
+ bool EmitHandshake(struct bufferevent*); |
+ |
+ // Attempts to establish second connection (to remote TCP service). |
+ // Returns true on success. |
+ bool TryConnectDest(const struct sockaddr*, socklen_t); |
+ |
+ // Used as libevent callbacks. |
+ 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); |
+ |
+ Chan& primchan() { return primchan_; } |
+ Token token() const { return token_; } |
+ |
+ private: |
+ Serv* master_; |
+ Phase phase_; |
+ |
+ // We maintain two channels per Conn: |
+ // primary channel is websocket connection. |
+ Chan primchan_; |
+ // Destination channel is a proxied connection. |
+ Chan destchan_; |
+ |
+ 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 destport_; |
+ |
+ // We try to DNS resolve hostname in both IPv4 and IPv6 domains. |
+ // Track resolution failures here. |
+ bool destresolution_ipv4_failed_; |
+ bool destresolution_ipv6_failed_; |
+ |
+ // Used to schedule a timeout for an initial phase of connection. |
+ struct event destconnect_timeout_event_; |
+ |
+ static TokenMap token_map_; |
+ static Token last_token_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Conn); |
+}; |
+ |
+} // namespace chromeos |
+} // namespace webproxy |
+ |
+#endif // CHROME_BROWSER_CHROMEOS_NET_WEBPROXY_CONN_H_ |