OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 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 CHROME_WEB2SOCKET_PROXY_WEB2SOCKET_CONN_H_ |
| 6 #define CHROME_WEB2SOCKET_PROXY_WEB2SOCKET_CONN_H_ |
| 7 |
| 8 #include <sys/socket.h> |
| 9 |
| 10 #include "base/md5.h" |
| 11 #include "net/web2socket_proxy/web2socket_serv.h" |
| 12 #include "third_party/libevent/event.h" |
| 13 |
| 14 class Conn { |
| 15 public: |
| 16 Web2SocketServ* master_; |
| 17 |
| 18 enum Phase { |
| 19 // Initial stage of connection. |
| 20 PHASE_WAIT_HANDSHAKE, |
| 21 PHASE_WAIT_DESTFRAME, |
| 22 PHASE_WAIT_DESTCONNECT, |
| 23 |
| 24 // Operational stage of connection. |
| 25 PHASE_OUTSIDE_FRAME, |
| 26 PHASE_INSIDE_FRAME_BASE64, |
| 27 PHASE_INSIDE_FRAME_SKIP, |
| 28 |
| 29 // Terminal stage of connection. |
| 30 PHASE_SHUT, // Closing handshake was emitted, buffers may pending. |
| 31 PHASE_DEFUNCT // Connection was nuked. |
| 32 } phase_; |
| 33 |
| 34 // We maintain two channels per Conn: |
| 35 // primary channel is websocket connection, |
| 36 // destination channel is a proxied connection. |
| 37 class Chan { |
| 38 public: |
| 39 int sock_; |
| 40 struct bufferevent* bev_; |
| 41 |
| 42 Chan() : sock_(-1), bev_(NULL) {} |
| 43 |
| 44 ~Chan() { |
| 45 if (bev_) { |
| 46 bufferevent_disable(bev_, EV_READ | EV_WRITE); |
| 47 bufferevent_free(bev_); |
| 48 bev_ = NULL; |
| 49 } |
| 50 if (sock_ >= 0) { |
| 51 shutdown(sock_, SHUT_RDWR); |
| 52 close(sock_); |
| 53 sock_ = -1; |
| 54 } |
| 55 } |
| 56 } primchan_, destchan_; |
| 57 |
| 58 // Unfortunately evdns callbacks are uncancellable, |
| 59 // so potentially we can receive callback for a deleted Conn. |
| 60 // Even worse, storage of deleted Conn may be reused |
| 61 // for a new connection and new connection can receive callback |
| 62 // destined for deleted Conn. |
| 63 // Conn::Token is introduced in order to prevent that. |
| 64 typedef void* Token; |
| 65 Token token_; |
| 66 typedef std::map<Token, Conn*> TokenMap; |
| 67 static TokenMap token_map_; |
| 68 static Token last_token_; |
| 69 static Conn* Get(Token token); |
| 70 |
| 71 // Header fields supplied by client at initial websocket handshake. |
| 72 std::map<std::string, std::string> header_fields_; |
| 73 |
| 74 // Cryptohashed answer for websocket handshake. |
| 75 MD5Digest handshake_response_; |
| 76 |
| 77 // Hostname and port of destination socket. |
| 78 // Websocket client supplies them in first data frame (destframe). |
| 79 std::string destname_; |
| 80 uint32_t destport_; |
| 81 |
| 82 // We try to DNS resolve hostname in both IPv4 and IPv6 domains. |
| 83 // Track resolution failures here. |
| 84 bool destresolution_ipv4_failure_; |
| 85 bool destresolution_ipv6_failure_; |
| 86 |
| 87 // Used to schedule a timeout for an initial phase of connection. |
| 88 struct event destconnect_timeout_event_; |
| 89 |
| 90 explicit Conn(Web2SocketServ* master); |
| 91 ~Conn(); |
| 92 |
| 93 enum Status { |
| 94 STATUS_OK, |
| 95 STATUS_INCOMPLETE, |
| 96 STATUS_SKIP, |
| 97 STATUS_ABORT |
| 98 }; |
| 99 |
| 100 void Shut(); |
| 101 Status ConsumeHeader(struct evbuffer*); |
| 102 Status ConsumeDestframe(struct evbuffer*); |
| 103 Status ConsumeFrameHeader(struct evbuffer*); |
| 104 Status ProcessFrameData(struct evbuffer*); |
| 105 |
| 106 // return true on success. |
| 107 bool EmitHandshake(struct bufferevent*); |
| 108 bool TryConnectDest(const struct sockaddr*, socklen_t); |
| 109 |
| 110 static void OnDestConnectTimeout(int, short, Token); |
| 111 static void OnPrimchanRead(struct bufferevent*, Token); |
| 112 static void OnPrimchanWrite(struct bufferevent*, Token); |
| 113 static void OnPrimchanError(struct bufferevent*, short what, Token); |
| 114 static void OnDestResolutionIPv4(int result, char type, int count, |
| 115 int ttl, void* addr_list, Token); |
| 116 static void OnDestResolutionIPv6(int result, char type, int count, |
| 117 int ttl, void* addr_list, Token); |
| 118 static void OnDestchanRead(struct bufferevent*, Token); |
| 119 static void OnDestchanWrite(struct bufferevent*, Token); |
| 120 static void OnDestchanError(struct bufferevent*, short what, Token); |
| 121 |
| 122 DISALLOW_COPY_AND_ASSIGN(Conn); |
| 123 }; |
| 124 |
| 125 #endif // CHROME_WEB2SOCKET_PROXY_WEB2SOCKET_CONN_H_ |
OLD | NEW |