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