Chromium Code Reviews| 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_ |