| 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_
|
|
|