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 |