Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: chrome/browser/chromeos/web_socket_proxy.cc

Issue 21115004: extensions: Remove chrome.webSocketProxyPrivate API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 #include "chrome/browser/chromeos/web_socket_proxy.h"
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include <algorithm>
12 #include <limits>
13 #include <list>
14 #include <map>
15 #include <vector>
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <netinet/in.h>
20 #include <signal.h>
21 #include <sys/socket.h>
22 #include <sys/types.h>
23 #include <sys/wait.h>
24
25 #include "base/base64.h"
26 #include "base/basictypes.h"
27 #include "base/bind.h"
28 #include "base/bind_helpers.h"
29 #include "base/lazy_instance.h"
30 #include "base/logging.h"
31 #include "base/memory/ref_counted.h"
32 #include "base/memory/scoped_ptr.h"
33 #include "base/memory/weak_ptr.h"
34 #include "base/message_loop/message_loop.h"
35 #include "base/sequenced_task_runner_helpers.h"
36 #include "base/sha1.h"
37 #include "base/stl_util.h"
38 #include "base/strings/string_number_conversions.h"
39 #include "base/strings/string_util.h"
40 #include "base/sys_byteorder.h"
41 #include "chrome/browser/chrome_notification_types.h"
42 #include "chrome/browser/chromeos/web_socket_proxy_helper.h"
43 #include "chrome/browser/internal_auth.h"
44 #include "content/public/browser/browser_thread.h"
45 #include "content/public/browser/notification_details.h"
46 #include "content/public/browser/notification_service.h"
47 #include "content/public/browser/notification_types.h"
48 #include "content/public/common/url_constants.h"
49 #include "extensions/common/constants.h"
50 #include "net/base/address_list.h"
51 #include "net/base/host_port_pair.h"
52 #include "net/base/io_buffer.h"
53 #include "net/base/net_errors.h"
54 #include "net/cert/cert_verifier.h"
55 #include "net/http/transport_security_state.h"
56 #include "net/socket/client_socket_factory.h"
57 #include "net/socket/client_socket_handle.h"
58 #include "net/socket/ssl_client_socket.h"
59 #include "net/socket/stream_socket.h"
60 #include "net/ssl/ssl_config_service.h"
61 #include "third_party/libevent/evdns.h"
62 #include "third_party/libevent/event.h"
63 #include "url/gurl.h"
64 #include "url/url_parse.h"
65
66 using content::BrowserThread;
67
68 namespace chromeos {
69
70 namespace {
71
72 const uint8 kCRLF[] = "\r\n";
73 const uint8 kCRLFCRLF[] = "\r\n\r\n";
74
75 // Not a constant but preprocessor definition for easy concatenation.
76 #define kProxyPath "/tcpproxy"
77
78 enum WebSocketStatusCode {
79 WS_CLOSE_NORMAL = 1000,
80 WS_CLOSE_GOING_AWAY = 1001,
81 WS_CLOSE_PROTOCOL_ERROR = 1002,
82 WS_CLOSE_UNACCEPTABLE_DATA = 1003,
83
84 WS_CLOSE_DESTINATION_ERROR = 4000,
85 WS_CLOSE_LIMIT_VIOLATION = 4001,
86 WS_CLOSE_RESOLUTION_FAILED = 4002,
87 WS_CLOSE_UNEXPECTED = 4003
88 };
89
90 enum WebSocketFrameOpcode {
91 WS_OPCODE_TEXT = 1,
92 WS_OPCODE_CLOSE = 8
93 };
94
95 // Fixed-size (one-byte) messages communicated via control pipe.
96 const char kControlMessageShutdown[] = { '.' };
97 const char kControlMessageNetworkChange[] = { ':' };
98
99 // Returns true on success.
100 bool SetNonBlock(int fd) {
101 int flags = fcntl(fd, F_GETFL, 0);
102 return flags >= 0 && fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0;
103 }
104
105 // Returns true on success.
106 bool IgnoreSigPipe() {
107 struct sigaction sa;
108 sa.sa_handler = SIG_IGN;
109 sa.sa_flags = 0;
110 if (sigemptyset(&sa.sa_mask) || sigaction(SIGPIPE, &sa, 0)) {
111 LOG(ERROR) << "WebSocketProxy: Failed to disable sigpipe";
112 return false;
113 }
114 return true;
115 }
116
117 uint64 ReadNetworkInteger(uint8* buf, int num_bytes) {
118 uint64 rv = 0;
119 DCHECK_GE(num_bytes, 0);
120 DCHECK_LE(num_bytes, 8);
121 while (num_bytes--) {
122 rv <<= 8;
123 rv += *buf++;
124 }
125 return rv;
126 }
127
128 void WriteNetworkInteger(int64 n, uint8* buf, int num_bytes) {
129 DCHECK_GE(num_bytes, 0);
130 DCHECK_LE(num_bytes, 8);
131 while (num_bytes--) {
132 buf[num_bytes] = n % (1 << 8);
133 n >>= 8;
134 }
135 }
136
137 typedef uint8 (*AsciiFilter)(uint8);
138
139 uint8 AsciiFilterVerbatim(uint8 c) {
140 return c;
141 }
142
143 uint8 AsciiFilterLower(uint8 c) {
144 return base::ToLowerASCII(c);
145 }
146
147 std::string FetchAsciiSnippet(uint8* begin, uint8* end, AsciiFilter filter) {
148 std::string rv;
149 for (; begin < end; ++begin) {
150 if (!isascii(*begin))
151 return rv;
152 rv += filter(*begin);
153 }
154 return rv;
155 }
156
157 std::string FetchExtensionIdFromOrigin(const std::string &origin) {
158 GURL url(origin);
159 if (url.SchemeIs(extensions::kExtensionScheme))
160 return url.host();
161 else
162 return std::string();
163 }
164
165 inline size_t strlen(const void* s) {
166 return ::strlen(static_cast<const char*>(s));
167 }
168
169 void SendNotification(int port) {
170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
171 content::NotificationService::current()->Notify(
172 chrome::NOTIFICATION_WEB_SOCKET_PROXY_STARTED,
173 content::NotificationService::AllSources(), content::Details<int>(&port));
174 }
175
176 class Conn;
177
178 // Websocket to TCP proxy server.
179 class Serv {
180 public:
181 Serv();
182 ~Serv();
183
184 // Do not call it twice.
185 void Run();
186
187 // Terminates running server (should be called on a different thread).
188 void Shutdown();
189 // Called on network change. Reinitializes DNS resolution service.
190 void OnNetworkChange();
191
192 void ZapConn(Conn*);
193 void MarkConnImportance(Conn*, bool important);
194 Conn* GetFreshConn();
195 bool IsConnSane(Conn*);
196 void CloseAll();
197
198 static void OnConnect(int listening_sock, short event, void*);
199 static void OnControlRequest(int fd, short event, void*);
200
201 struct event_base* evbase() { return evbase_; }
202
203 // Libevent base.
204 struct event_base* evbase_;
205
206 // Socket to listen incoming websocket connections.
207 int listening_sock_;
208
209 // TODO(dilmah): remove this extra socket as soon as obsolete
210 // getPassportForTCP function is removed from webSocketProxyPrivate API.
211 // Additional socket to listen incoming connections on fixed port 10101.
212 int extra_listening_sock_;
213
214 // Used to communicate control requests: either shutdown request or network
215 // change notification.
216 int control_descriptor_[2];
217
218 // Flag whether shutdown has been requested.
219 bool shutdown_requested_;
220
221 // List of pending connections; We are trying to keep size of this list
222 // below kConnPoolLimit in LRU fashion.
223 typedef std::list<Conn*> ConnPool;
224 ConnPool conn_pool_;
225
226 // Reverse map to look up a connection in a conn_pool.
227 typedef std::map<Conn*, ConnPool::iterator> RevMap;
228 RevMap rev_map_;
229
230 scoped_ptr<struct event> connection_event_;
231 scoped_ptr<struct event> control_event_;
232 // TODO(dilmah): remove this extra event as soon as obsolete
233 // getPassportForTCP function is removed from webSocketProxyPrivate API.
234 scoped_ptr<struct event> extra_connection_event_;
235
236 DISALLOW_COPY_AND_ASSIGN(Serv);
237 };
238
239 // Connection (amalgamates both channels between proxy and javascript and
240 // between proxy and destination).
241 class Conn {
242 public:
243 enum Phase {
244 // Initial stage of connection.
245 PHASE_WAIT_HANDSHAKE,
246 PHASE_WAIT_DESTFRAME,
247 PHASE_WAIT_DESTCONNECT,
248
249 // Operational stage of connection.
250 PHASE_OUTSIDE_FRAME,
251 PHASE_INSIDE_FRAME_BASE64,
252 PHASE_INSIDE_FRAME_SKIP,
253
254 // Terminal stage of connection.
255 PHASE_SHUT, // Closing handshake was emitted, buffers may be pending.
256 PHASE_DEFUNCT // Connection was nuked.
257 };
258
259 // Channel structure (either proxy<->browser or proxy<->destination).
260 class Chan {
261 public:
262 explicit Chan(Conn* master)
263 : master_(master),
264 write_pending_(false),
265 read_bev_(NULL),
266 write_bev_(NULL),
267 read_fd_(-1),
268 write_fd_(-1) {
269 }
270
271 ~Chan() {
272 Zap();
273 }
274
275 // Returns true on success.
276 bool Write(const void* data, size_t size) {
277 if (write_bev_ == NULL)
278 return false;
279 write_pending_ = true;
280 return (0 == bufferevent_write(write_bev_, data, size));
281 }
282
283 void Zap() {
284 if (read_bev_) {
285 bufferevent_disable(read_bev_, EV_READ);
286 bufferevent_free(read_bev_);
287 }
288 if (write_bev_ && write_bev_ != read_bev_) {
289 bufferevent_disable(write_bev_, EV_READ);
290 bufferevent_free(write_bev_);
291 }
292 read_bev_ = NULL;
293 write_bev_ = NULL;
294 if (write_fd_ && read_fd_ == write_fd_)
295 shutdown(write_fd_, SHUT_RDWR);
296 if (write_fd_ >= 0) {
297 close(write_fd_);
298 DCHECK_GE(read_fd_, 0);
299 }
300 if (read_fd_ && read_fd_ != write_fd_)
301 close(read_fd_);
302 read_fd_ = -1;
303 write_fd_ = -1;
304 write_pending_ = false;
305 master_->ConsiderSuicide();
306 }
307
308 void Shut() {
309 if (!write_pending_)
310 Zap();
311 }
312
313 int read_fd() const { return read_fd_; }
314 void set_read_fd(int fd) { read_fd_ = fd; }
315 int write_fd() const { return write_fd_; }
316 void set_write_fd(int fd) { write_fd_ = fd; }
317 bool write_pending() const { return write_pending_; }
318 void set_write_pending(bool pending) { write_pending_ = pending; }
319 struct bufferevent* read_bev() const { return read_bev_; }
320 void set_read_bev(struct bufferevent* bev) { read_bev_ = bev; }
321 struct bufferevent* write_bev() const { return write_bev_; }
322 void set_write_bev(struct bufferevent* bev) { write_bev_ = bev; }
323
324 private:
325 Conn* master_;
326 bool write_pending_; // Whether write buffer is not flushed yet.
327 struct bufferevent* read_bev_;
328 struct bufferevent* write_bev_;
329 // UNIX descriptors.
330 int read_fd_;
331 int write_fd_;
332
333 DISALLOW_COPY_AND_ASSIGN(Chan);
334 };
335
336 // Status of processing incoming data.
337 enum Status {
338 STATUS_OK,
339 STATUS_INCOMPLETE, // Not all required data is present in buffer yet.
340 STATUS_SKIP,
341 STATUS_ABORT // Data is invalid. We must shut connection.
342 };
343
344 // Unfortunately evdns callbacks are uncancellable,
345 // so potentially we can receive callback for a deleted Conn.
346 // Even worse, storage of deleted Conn may be reused
347 // for a new connection and new connection can receive callback
348 // destined for deleted Conn.
349 // EventKey is introduced in order to prevent that.
350 typedef void* EventKey;
351 typedef std::map<EventKey, Conn*> EventKeyMap;
352
353 explicit Conn(Serv* master);
354 ~Conn();
355
356 static Conn* Get(EventKey evkey);
357
358 void Shut(int status, const void* reason);
359
360 void ConsiderSuicide();
361
362 Status ConsumeHeader(struct evbuffer*);
363 Status ConsumeDestframe(struct evbuffer*);
364 Status ConsumeFrameHeader(struct evbuffer*);
365 Status ProcessFrameData(struct evbuffer*);
366
367 // Return true on success.
368 bool EmitHandshake(Chan*);
369 bool EmitFrame(
370 Chan*, WebSocketFrameOpcode opcode, const void* buf, size_t size);
371
372 // Attempts to establish second connection (to remote TCP service).
373 // Returns true on success.
374 bool TryConnectDest(const struct sockaddr*, socklen_t);
375
376 // Return security origin associated with this connection.
377 const std::string& GetOrigin();
378
379 // Used as libevent callbacks.
380 static void OnDestConnectTimeout(int, short, EventKey);
381 static void OnPrimchanRead(struct bufferevent*, EventKey);
382 static void OnPrimchanWrite(struct bufferevent*, EventKey);
383 static void OnPrimchanError(struct bufferevent*, short what, EventKey);
384 static void OnDestResolutionIPv4(int result, char type, int count,
385 int ttl, void* addr_list, EventKey);
386 static void OnDestResolutionIPv6(int result, char type, int count,
387 int ttl, void* addr_list, EventKey);
388 static void OnDestchanRead(struct bufferevent*, EventKey);
389 static void OnDestchanWrite(struct bufferevent*, EventKey);
390 static void OnDestchanError(struct bufferevent*, short what, EventKey);
391
392 Chan& primchan() { return primchan_; }
393 EventKey evkey() const { return evkey_; }
394
395 private:
396 Serv* master_;
397 Phase phase_;
398 uint64 frame_bytes_remaining_;
399 uint8 frame_mask_[4];
400 int frame_mask_index_;
401
402 // We maintain two channels per Conn:
403 // primary channel is websocket connection.
404 Chan primchan_;
405 // Destination channel is a proxied connection.
406 Chan destchan_;
407
408 EventKey evkey_;
409
410 // Header fields supplied by client at initial websocket handshake.
411 std::map<std::string, std::string> header_fields_;
412
413 // Parameters requested via query component of GET resource.
414 std::map<std::string, std::string> requested_parameters_;
415
416 // Hostname and port of destination socket.
417 // Websocket client supplies them in first data frame (destframe).
418 std::string destname_;
419 int destport_;
420
421 // Preresolved |destname_| (empty if not pre-resolved).
422 std::string destaddr_;
423
424 // Whether TLS over TCP requested.
425 bool do_tls_;
426
427 // We try to DNS resolve hostname in both IPv4 and IPv6 domains.
428 // Track resolution failures here.
429 bool destresolution_ipv4_failed_;
430 bool destresolution_ipv6_failed_;
431
432 // Used to schedule a timeout for initial phase of connection.
433 scoped_ptr<struct event> destconnect_timeout_event_;
434
435 static base::LazyInstance<EventKeyMap>::Leaky evkey_map_;
436 static EventKey last_evkey_;
437
438 DISALLOW_COPY_AND_ASSIGN(Conn);
439 };
440
441 class SSLChan : public base::MessageLoopForIO::Watcher {
442 public:
443 static void Start(const net::AddressList& address_list,
444 const net::HostPortPair& host_port_pair,
445 int read_pipe,
446 int write_pipe) {
447 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
448 SSLChan* ALLOW_UNUSED chan = new SSLChan(
449 address_list, host_port_pair, read_pipe, write_pipe);
450 }
451
452 private:
453 enum Phase {
454 PHASE_CONNECTING,
455 PHASE_RUNNING,
456 PHASE_CLOSING,
457 PHASE_CLOSED
458 };
459
460 class DerivedIOBufferWithSize : public net::IOBufferWithSize {
461 public:
462 DerivedIOBufferWithSize(net::IOBuffer* host, int size)
463 : IOBufferWithSize(host->data(), size), host_(host) {
464 DCHECK(host_.get());
465 DCHECK(host_->data());
466 }
467
468 protected:
469 virtual ~DerivedIOBufferWithSize() {
470 data_ = NULL; // We do not own memory, bypass base class destructor.
471 }
472
473 scoped_refptr<net::IOBuffer> host_;
474 };
475
476 // Provides queue of data represented as IOBuffers.
477 class IOBufferQueue {
478 public:
479 // We do not allocate all capacity at once but lazily in |buf_size_| chunks.
480 explicit IOBufferQueue(int capacity)
481 : buf_size_(1 + capacity / kNumBuffersLimit) {
482 }
483
484 // Obtains IOBuffer to add new data to back.
485 net::IOBufferWithSize* GetIOBufferToFill() {
486 if (back_.get() == NULL) {
487 if (storage_.size() >= kNumBuffersLimit)
488 return NULL;
489 storage_.push_back(new net::IOBufferWithSize(buf_size_));
490 back_ = new net::DrainableIOBuffer(storage_.back().get(), buf_size_);
491 }
492 return new DerivedIOBufferWithSize(
493 back_.get(), back_->BytesRemaining());
494 }
495
496 // Obtains IOBuffer with some data from front.
497 net::IOBufferWithSize* GetIOBufferToProcess() {
498 if (front_.get() == NULL) {
499 if (storage_.empty())
500 return NULL;
501 front_ = new net::DrainableIOBuffer(storage_.front().get(), buf_size_);
502 }
503 int front_capacity =
504 (storage_.size() == 1 && back_.get()) ? back_->BytesConsumed()
505 : buf_size_;
506 return new DerivedIOBufferWithSize(
507 front_.get(), front_capacity - front_->BytesConsumed());
508 }
509
510 // Records number of bytes as added to back.
511 void DidFill(int bytes) {
512 DCHECK(back_.get());
513 back_->DidConsume(bytes);
514 if (back_->BytesRemaining() == 0)
515 back_ = NULL;
516 }
517
518 // Pops number of bytes from front.
519 void DidProcess(int bytes) {
520 DCHECK(front_.get());
521 front_->DidConsume(bytes);
522 if (front_->BytesRemaining() == 0) {
523 storage_.pop_front();
524 front_ = NULL;
525 }
526 }
527
528 void Clear() {
529 front_ = NULL;
530 back_ = NULL;
531 storage_.clear();
532 }
533
534 private:
535 static const unsigned kNumBuffersLimit = 12;
536 const int buf_size_;
537 std::list< scoped_refptr<net::IOBufferWithSize> > storage_;
538 scoped_refptr<net::DrainableIOBuffer> front_;
539 scoped_refptr<net::DrainableIOBuffer> back_;
540
541 DISALLOW_COPY_AND_ASSIGN(IOBufferQueue);
542 };
543
544 SSLChan(const net::AddressList address_list,
545 const net::HostPortPair host_port_pair,
546 int read_pipe,
547 int write_pipe)
548 : phase_(PHASE_CONNECTING),
549 host_port_pair_(host_port_pair),
550 inbound_stream_(WebSocketProxy::kBufferLimit),
551 outbound_stream_(WebSocketProxy::kBufferLimit),
552 read_pipe_(read_pipe),
553 write_pipe_(write_pipe),
554 weak_factory_(this) {
555 if (!SetNonBlock(read_pipe_) || !SetNonBlock(write_pipe_)) {
556 Shut(net::ERR_UNEXPECTED);
557 return;
558 }
559 net::ClientSocketFactory* factory =
560 net::ClientSocketFactory::GetDefaultFactory();
561 socket_.reset(factory->CreateTransportClientSocket(
562 address_list, NULL, net::NetLog::Source()));
563 if (socket_ == NULL) {
564 Shut(net::ERR_FAILED);
565 return;
566 }
567 int result = socket_->Connect(base::Bind(&SSLChan::OnSocketConnect,
568 base::Unretained(this)));
569 if (result != net::ERR_IO_PENDING)
570 OnSocketConnect(result);
571 }
572
573 virtual ~SSLChan() {
574 phase_ = PHASE_CLOSED;
575 write_pipe_controller_.StopWatchingFileDescriptor();
576 read_pipe_controller_.StopWatchingFileDescriptor();
577 close(write_pipe_);
578 close(read_pipe_);
579 }
580
581 void Shut(int ALLOW_UNUSED net_error_code) {
582 if (phase_ != PHASE_CLOSED) {
583 phase_ = PHASE_CLOSING;
584 scoped_refptr<net::IOBufferWithSize> buf[] = {
585 outbound_stream_.GetIOBufferToProcess(),
586 inbound_stream_.GetIOBufferToProcess()
587 };
588 for (int i = arraysize(buf); i--;) {
589 if (buf[i].get() && buf[i]->size() > 0) {
590 base::MessageLoop::current()->PostTask(
591 FROM_HERE,
592 base::Bind(&SSLChan::Proceed, weak_factory_.GetWeakPtr()));
593 return;
594 }
595 }
596 phase_ = PHASE_CLOSED;
597 if (socket_ != NULL) {
598 socket_->Disconnect();
599 socket_.reset();
600 }
601 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
602 }
603 }
604
605 void OnSocketConnect(int result) {
606 if (phase_ != PHASE_CONNECTING) {
607 NOTREACHED();
608 return;
609 }
610 if (result) {
611 Shut(result);
612 return;
613 }
614 net::ClientSocketHandle* handle = new net::ClientSocketHandle();
615 handle->set_socket(socket_.release());
616 net::ClientSocketFactory* factory =
617 net::ClientSocketFactory::GetDefaultFactory();
618 net::SSLClientSocketContext ssl_context;
619 if (!cert_verifier_.get())
620 cert_verifier_.reset(net::CertVerifier::CreateDefault());
621 ssl_context.cert_verifier = cert_verifier_.get();
622 if (!transport_security_state_.get())
623 transport_security_state_.reset(new net::TransportSecurityState);
624 ssl_context.transport_security_state = transport_security_state_.get();
625 socket_.reset(factory->CreateSSLClientSocket(
626 handle, host_port_pair_, ssl_config_, ssl_context));
627 if (!socket_.get()) {
628 LOG(WARNING) << "Failed to create an SSL client socket.";
629 OnSSLHandshakeCompleted(net::ERR_UNEXPECTED);
630 return;
631 }
632 result = socket_->Connect(base::Bind(&SSLChan::OnSSLHandshakeCompleted,
633 base::Unretained(this)));
634 if (result != net::ERR_IO_PENDING)
635 OnSSLHandshakeCompleted(result);
636 }
637
638 void OnSSLHandshakeCompleted(int result) {
639 if (result) {
640 Shut(result);
641 return;
642 }
643 is_socket_read_pending_ = false;
644 is_socket_write_pending_ = false;
645 is_read_pipe_blocked_ = false;
646 is_write_pipe_blocked_ = false;
647 base::MessageLoopForIO::current()->WatchFileDescriptor(
648 read_pipe_, false, base::MessageLoopForIO::WATCH_READ,
649 &read_pipe_controller_, this);
650 base::MessageLoopForIO::current()->WatchFileDescriptor(
651 write_pipe_, false, base::MessageLoopForIO::WATCH_WRITE,
652 &write_pipe_controller_, this);
653 phase_ = PHASE_RUNNING;
654 Proceed();
655 }
656
657 void OnSocketRead(int result) {
658 DCHECK(is_socket_read_pending_);
659 is_socket_read_pending_ = false;
660 if (result <= 0) {
661 Shut(result);
662 return;
663 }
664 inbound_stream_.DidFill(result);
665 Proceed();
666 }
667
668 void OnSocketWrite(int result) {
669 DCHECK(is_socket_write_pending_);
670 is_socket_write_pending_ = false;
671 if (result < 0) {
672 outbound_stream_.Clear();
673 Shut(result);
674 return;
675 }
676 outbound_stream_.DidProcess(result);
677 Proceed();
678 }
679
680 // MessageLoopForIO::Watcher overrides.
681 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE {
682 if (fd != read_pipe_) {
683 NOTREACHED();
684 return;
685 }
686 is_read_pipe_blocked_ = false;
687 Proceed();
688 }
689
690 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {
691 if (fd != write_pipe_) {
692 NOTREACHED();
693 return;
694 }
695 is_write_pipe_blocked_ = false;
696 Proceed();
697 }
698
699 private:
700 void Proceed() {
701 if (phase_ != PHASE_RUNNING && phase_ != PHASE_CLOSING)
702 return;
703 for (bool proceed = true; proceed;) {
704 proceed = false;
705 if (!is_read_pipe_blocked_ && phase_ == PHASE_RUNNING) {
706 scoped_refptr<net::IOBufferWithSize> buf =
707 outbound_stream_.GetIOBufferToFill();
708 if (buf.get() && buf->size() > 0) {
709 int rv = read(read_pipe_, buf->data(), buf->size());
710 if (rv > 0) {
711 outbound_stream_.DidFill(rv);
712 proceed = true;
713 } else if (rv == -1 && errno == EAGAIN) {
714 is_read_pipe_blocked_ = true;
715 base::MessageLoopForIO::current()->WatchFileDescriptor(
716 read_pipe_, false, base::MessageLoopForIO::WATCH_READ,
717 &read_pipe_controller_, this);
718 } else if (rv == 0) {
719 Shut(0);
720 } else {
721 DCHECK_LT(rv, 0);
722 Shut(net::ERR_UNEXPECTED);
723 return;
724 }
725 }
726 }
727 if (!is_socket_read_pending_ && phase_ == PHASE_RUNNING) {
728 scoped_refptr<net::IOBufferWithSize> buf =
729 inbound_stream_.GetIOBufferToFill();
730 if (buf.get() && buf->size() > 0) {
731 int rv = socket_->Read(
732 buf.get(),
733 buf->size(),
734 base::Bind(&SSLChan::OnSocketRead, base::Unretained(this)));
735 is_socket_read_pending_ = true;
736 if (rv != net::ERR_IO_PENDING) {
737 base::MessageLoop::current()->PostTask(
738 FROM_HERE, base::Bind(&SSLChan::OnSocketRead,
739 weak_factory_.GetWeakPtr(), rv));
740 }
741 }
742 }
743 if (!is_socket_write_pending_) {
744 scoped_refptr<net::IOBufferWithSize> buf =
745 outbound_stream_.GetIOBufferToProcess();
746 if (buf.get() && buf->size() > 0) {
747 int rv = socket_->Write(
748 buf.get(),
749 buf->size(),
750 base::Bind(&SSLChan::OnSocketWrite, base::Unretained(this)));
751 is_socket_write_pending_ = true;
752 if (rv != net::ERR_IO_PENDING) {
753 base::MessageLoop::current()->PostTask(
754 FROM_HERE, base::Bind(&SSLChan::OnSocketWrite,
755 weak_factory_.GetWeakPtr(), rv));
756 }
757 } else if (phase_ == PHASE_CLOSING) {
758 Shut(0);
759 }
760 }
761 if (!is_write_pipe_blocked_) {
762 scoped_refptr<net::IOBufferWithSize> buf =
763 inbound_stream_.GetIOBufferToProcess();
764 if (buf.get() && buf->size() > 0) {
765 int rv = write(write_pipe_, buf->data(), buf->size());
766 if (rv > 0) {
767 inbound_stream_.DidProcess(rv);
768 proceed = true;
769 } else if (rv == -1 && errno == EAGAIN) {
770 is_write_pipe_blocked_ = true;
771 base::MessageLoopForIO::current()->WatchFileDescriptor(
772 write_pipe_, false, base::MessageLoopForIO::WATCH_WRITE,
773 &write_pipe_controller_, this);
774 } else {
775 DCHECK_LE(rv, 0);
776 inbound_stream_.Clear();
777 Shut(net::ERR_UNEXPECTED);
778 return;
779 }
780 } else if (phase_ == PHASE_CLOSING) {
781 Shut(0);
782 }
783 }
784 }
785 }
786
787 Phase phase_;
788 scoped_ptr<net::StreamSocket> socket_;
789 net::HostPortPair host_port_pair_;
790 scoped_ptr<net::CertVerifier> cert_verifier_;
791 scoped_ptr<net::TransportSecurityState> transport_security_state_;
792 net::SSLConfig ssl_config_;
793 IOBufferQueue inbound_stream_;
794 IOBufferQueue outbound_stream_;
795 int read_pipe_;
796 int write_pipe_;
797 bool is_socket_read_pending_;
798 bool is_socket_write_pending_;
799 bool is_read_pipe_blocked_;
800 bool is_write_pipe_blocked_;
801 base::WeakPtrFactory<SSLChan> weak_factory_;
802 base::MessageLoopForIO::FileDescriptorWatcher read_pipe_controller_;
803 base::MessageLoopForIO::FileDescriptorWatcher write_pipe_controller_;
804
805 friend class base::DeleteHelper<SSLChan>;
806 DISALLOW_COPY_AND_ASSIGN(SSLChan);
807 };
808
809 Serv::Serv()
810 : evbase_(NULL),
811 listening_sock_(-1),
812 extra_listening_sock_(-1),
813 shutdown_requested_(false) {
814 control_descriptor_[0] = -1;
815 control_descriptor_[1] = -1;
816 }
817
818 Serv::~Serv() {
819 CloseAll();
820 }
821
822 void Serv::Run() {
823 if (evbase_ || shutdown_requested_)
824 return;
825
826 evbase_ = event_init();
827 if (!evbase_) {
828 LOG(ERROR) << "WebSocketProxy: Couldn't create libevent base";
829 return;
830 }
831
832 if (pipe(control_descriptor_) ||
833 !SetNonBlock(control_descriptor_[0]) ||
834 !SetNonBlock(control_descriptor_[1])) {
835 LOG(ERROR) << "WebSocketProxy: Failed to create control pipe";
836 return;
837 }
838
839 listening_sock_ = socket(AF_INET, SOCK_STREAM, 0);
840 if (listening_sock_ < 0) {
841 LOG(ERROR) << "WebSocketProxy: Failed to create socket";
842 return;
843 }
844 {
845 int on = 1;
846 setsockopt(listening_sock_, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
847 }
848
849 struct sockaddr_in addr;
850 memset(&addr, 0, sizeof(addr));
851 addr.sin_family = AF_INET;
852 // Let the OS allocate a port number.
853 addr.sin_port = base::HostToNet16(0);
854 addr.sin_addr.s_addr = base::HostToNet32(INADDR_LOOPBACK);
855 if (bind(listening_sock_,
856 reinterpret_cast<struct sockaddr*>(&addr),
857 sizeof(addr))) {
858 LOG(ERROR) << "WebSocketProxy: Failed to bind server socket";
859 return;
860 }
861 if (listen(listening_sock_, 12)) {
862 LOG(ERROR) << "WebSocketProxy: Failed to listen server socket";
863 return;
864 }
865 if (!SetNonBlock(listening_sock_)) {
866 LOG(ERROR) << "WebSocketProxy: Failed to go non block";
867 return;
868 }
869
870 connection_event_.reset(new struct event);
871 event_set(connection_event_.get(), listening_sock_, EV_READ | EV_PERSIST,
872 &OnConnect, this);
873 event_base_set(evbase_, connection_event_.get());
874 if (event_add(connection_event_.get(), NULL)) {
875 LOG(ERROR) << "WebSocketProxy: Failed to add listening event";
876 return;
877 }
878
879 {
880 // TODO(dilmah): remove this control block as soon as obsolete
881 // getPassportForTCP function is removed from webSocketProxyPrivate API.
882 // Following block adds extra listening socket on fixed port 10101.
883 extra_listening_sock_ = socket(AF_INET, SOCK_STREAM, 0);
884 if (extra_listening_sock_ < 0) {
885 LOG(ERROR) << "WebSocketProxy: Failed to create socket";
886 return;
887 }
888 {
889 int on = 1;
890 setsockopt(listening_sock_, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
891 }
892 const int kPort = 10101;
893 memset(&addr, 0, sizeof(addr));
894 addr.sin_family = AF_INET;
895 addr.sin_port = base::HostToNet16(kPort);
896 addr.sin_addr.s_addr = base::HostToNet32(INADDR_LOOPBACK);
897 if (bind(extra_listening_sock_,
898 reinterpret_cast<struct sockaddr*>(&addr),
899 sizeof(addr))) {
900 LOG(ERROR) << "WebSocketProxy: Failed to bind server socket";
901 return;
902 }
903 if (listen(extra_listening_sock_, 12)) {
904 LOG(ERROR) << "WebSocketProxy: Failed to listen server socket";
905 return;
906 }
907 if (!SetNonBlock(extra_listening_sock_)) {
908 LOG(ERROR) << "WebSocketProxy: Failed to go non block";
909 return;
910 }
911 extra_connection_event_.reset(new struct event);
912 event_set(extra_connection_event_.get(), extra_listening_sock_,
913 EV_READ | EV_PERSIST, &OnConnect, this);
914 event_base_set(evbase_, extra_connection_event_.get());
915 if (event_add(extra_connection_event_.get(), NULL)) {
916 LOG(ERROR) << "WebSocketProxy: Failed to add listening event";
917 return;
918 }
919 }
920
921 control_event_.reset(new struct event);
922 event_set(control_event_.get(), control_descriptor_[0], EV_READ | EV_PERSIST,
923 &OnControlRequest, this);
924 event_base_set(evbase_, control_event_.get());
925 if (event_add(control_event_.get(), NULL)) {
926 LOG(ERROR) << "WebSocketProxy: Failed to add control event";
927 return;
928 }
929
930 if (evdns_init())
931 LOG(WARNING) << "WebSocketProxy: Failed to initialize evDNS";
932 if (!IgnoreSigPipe()) {
933 LOG(ERROR) << "WebSocketProxy: Failed to ignore SIGPIPE";
934 return;
935 }
936
937 memset(&addr, 0, sizeof(addr));
938 socklen_t addr_len = sizeof(addr);
939 if (getsockname(
940 listening_sock_, reinterpret_cast<struct sockaddr*>(&addr), &addr_len)) {
941 LOG(ERROR) << "Failed to determine listening port";
942 return;
943 }
944 BrowserThread::PostTask(
945 BrowserThread::UI, FROM_HERE,
946 base::Bind(&SendNotification, base::NetToHost16(addr.sin_port)));
947
948 LOG(INFO) << "WebSocketProxy: Starting event dispatch loop.";
949 event_base_dispatch(evbase_);
950 if (shutdown_requested_)
951 LOG(INFO) << "WebSocketProxy: Event dispatch loop terminated upon request";
952 else
953 LOG(ERROR) << "WebSocketProxy: Event dispatch loop terminated unexpectedly";
954 CloseAll();
955 }
956
957 void Serv::Shutdown() {
958 int r ALLOW_UNUSED =
959 write(control_descriptor_[1], kControlMessageShutdown, 1);
960 }
961
962 void Serv::OnNetworkChange() {
963 int r ALLOW_UNUSED =
964 write(control_descriptor_[1], kControlMessageNetworkChange, 1);
965 }
966
967 void Serv::CloseAll() {
968 while (!conn_pool_.empty())
969 ZapConn(conn_pool_.back());
970 if (listening_sock_ >= 0) {
971 shutdown(listening_sock_, SHUT_RDWR);
972 close(listening_sock_);
973 }
974 for (int i = 0; i < 2; ++i) {
975 if (control_descriptor_[i] >= 0) {
976 control_descriptor_[i] = -1;
977 close(control_descriptor_[i]);
978 }
979 }
980 if (control_event_.get()) {
981 event_del(control_event_.get());
982 control_event_.reset();
983 }
984 if (extra_connection_event_.get()) {
985 event_del(extra_connection_event_.get());
986 extra_connection_event_.reset();
987 }
988 if (connection_event_.get()) {
989 event_del(connection_event_.get());
990 connection_event_.reset();
991 }
992 if (evbase_) {
993 event_base_free(evbase_);
994 evbase_ = NULL;
995 }
996 }
997
998 void Serv::ZapConn(Conn* cs) {
999 RevMap::iterator rit = rev_map_.find(cs);
1000 if (rit != rev_map_.end()) {
1001 conn_pool_.erase(rit->second);
1002 rev_map_.erase(rit);
1003 delete cs;
1004 }
1005 }
1006
1007 void Serv::MarkConnImportance(Conn* cs, bool important) {
1008 if (conn_pool_.size() < WebSocketProxy::kConnPoolLimit / 4) {
1009 // Fast common path.
1010 return;
1011 }
1012 RevMap::iterator rit = rev_map_.find(cs);
1013 if (rit != rev_map_.end()) {
1014 ConnPool::iterator it = rit->second;
1015 CHECK(*it == cs);
1016 if (important && it == conn_pool_.begin()) {
1017 // Already at the top. Shortcut.
1018 return;
1019 }
1020 conn_pool_.erase(it);
1021 }
1022 if (important) {
1023 conn_pool_.push_front(cs);
1024 rev_map_[cs] = conn_pool_.begin();
1025 } else {
1026 conn_pool_.push_back(cs);
1027 rev_map_[cs] = conn_pool_.end();
1028 --rev_map_[cs];
1029 }
1030 }
1031
1032 Conn* Serv::GetFreshConn() {
1033 if (conn_pool_.size() > WebSocketProxy::kConnPoolLimit) {
1034 // Connections overflow. Shut those oldest not active.
1035 ConnPool::iterator it = conn_pool_.end();
1036 --it;
1037 for (int i = conn_pool_.size() - WebSocketProxy::kConnPoolLimit; i-- > 0;) {
1038 // Shut may invalidate an iterator; hence postdecrement.
1039 (*it--)->Shut(WS_CLOSE_GOING_AWAY,
1040 "Flood of new connections, getting rid of old ones");
1041 }
1042 if (conn_pool_.size() > WebSocketProxy::kConnPoolLimit + 12) {
1043 // Connections overflow. Zap the oldest not active.
1044 ZapConn(conn_pool_.back());
1045 }
1046 }
1047 Conn* cs = new Conn(this);
1048 conn_pool_.push_front(cs);
1049 rev_map_[cs] = conn_pool_.begin();
1050 return cs;
1051 }
1052
1053 bool Serv::IsConnSane(Conn* cs) {
1054 return rev_map_.find(cs) != rev_map_.end();
1055 }
1056
1057 // static
1058 void Serv::OnConnect(int listening_sock, short event, void* ctx) {
1059 Serv* self = static_cast<Serv*>(ctx);
1060 Conn* cs = self->GetFreshConn();
1061 int sock = accept(listening_sock, NULL, NULL);
1062 if (sock < 0 || !SetNonBlock(sock)) {
1063 // Read readiness was triggered on listening socket
1064 // yet we failed to accept a connection; definitely weird.
1065 NOTREACHED();
1066 self->ZapConn(cs);
1067 return;
1068 }
1069 cs->primchan().set_read_fd(sock);
1070 cs->primchan().set_write_fd(sock);
1071
1072 struct bufferevent* bev = bufferevent_new(
1073 sock,
1074 &Conn::OnPrimchanRead, &Conn::OnPrimchanWrite, &Conn::OnPrimchanError,
1075 cs->evkey());
1076 if (bev == NULL) {
1077 self->ZapConn(cs);
1078 return;
1079 }
1080 cs->primchan().set_read_bev(bev);
1081 cs->primchan().set_write_bev(bev);
1082 bufferevent_base_set(self->evbase_, bev);
1083 bufferevent_setwatermark(bev, EV_READ, 0, WebSocketProxy::kBufferLimit);
1084 if (bufferevent_enable(bev, EV_READ | EV_WRITE)) {
1085 self->ZapConn(cs);
1086 return;
1087 }
1088 }
1089
1090 // static
1091 void Serv::OnControlRequest(int fd, short event, void* ctx) {
1092 Serv* self = static_cast<Serv*>(ctx);
1093
1094 char c;
1095 if (1 == read(fd, &c, 1) && c == *kControlMessageNetworkChange) {
1096 // OnNetworkChange request.
1097 evdns_clear_nameservers_and_suspend();
1098 evdns_init();
1099 evdns_resume();
1100 } else if (c == *kControlMessageShutdown) {
1101 self->shutdown_requested_ = true;
1102 event_base_loopbreak(self->evbase_);
1103 }
1104 }
1105
1106 Conn::Conn(Serv* master)
1107 : master_(master),
1108 phase_(PHASE_WAIT_HANDSHAKE),
1109 frame_bytes_remaining_(0),
1110 frame_mask_index_(0),
1111 primchan_(this),
1112 destchan_(this),
1113 do_tls_(false),
1114 destresolution_ipv4_failed_(false),
1115 destresolution_ipv6_failed_(false) {
1116 while (evkey_map_.Get().find(last_evkey_) != evkey_map_.Get().end()) {
1117 last_evkey_ = reinterpret_cast<EventKey>(reinterpret_cast<size_t>(
1118 last_evkey_) + 1);
1119 }
1120 evkey_ = last_evkey_;
1121 evkey_map_.Get()[evkey_] = this;
1122 // Schedule timeout for initial phase of connection.
1123 destconnect_timeout_event_.reset(new struct event);
1124 evtimer_set(destconnect_timeout_event_.get(),
1125 &OnDestConnectTimeout, evkey_);
1126 event_base_set(master_->evbase(),
1127 destconnect_timeout_event_.get());
1128
1129 struct timeval tv;
1130 tv.tv_sec = 20;
1131 tv.tv_usec = 0;
1132 evtimer_add(destconnect_timeout_event_.get(), &tv);
1133 }
1134
1135 Conn::~Conn() {
1136 phase_ = PHASE_DEFUNCT;
1137 event_del(destconnect_timeout_event_.get());
1138 if (evkey_map_.Get()[evkey_] == this)
1139 evkey_map_.Get().erase(evkey_);
1140 else
1141 NOTREACHED();
1142 }
1143
1144 Conn* Conn::Get(EventKey evkey) {
1145 EventKeyMap::iterator it = evkey_map_.Get().find(evkey);
1146 if (it == evkey_map_.Get().end())
1147 return NULL;
1148 Conn* cs = it->second;
1149 if (cs == NULL ||
1150 cs->evkey_ != evkey ||
1151 cs->master_ == NULL ||
1152 cs->phase_ < 0 ||
1153 cs->phase_ > PHASE_SHUT ||
1154 !cs->master_->IsConnSane(cs)) {
1155 return NULL;
1156 }
1157 return cs;
1158 }
1159
1160 void Conn::Shut(int status, const void* reason) {
1161 if (phase_ >= PHASE_SHUT)
1162 return;
1163 master_->MarkConnImportance(this, false);
1164
1165 std::vector<uint8> payload(2 + strlen(reason));
1166 WriteNetworkInteger(status, vector_as_array(&payload), 2);
1167 memcpy(vector_as_array(&payload) + 2, reason, strlen(reason));
1168
1169 EmitFrame(
1170 &primchan_, WS_OPCODE_CLOSE, vector_as_array(&payload), payload.size());
1171 primchan_.Shut();
1172 destchan_.Shut();
1173 phase_ = PHASE_SHUT;
1174 }
1175
1176 void Conn::ConsiderSuicide() {
1177 if (!primchan_.write_pending() && !destchan_.write_pending())
1178 master_->ZapConn(this);
1179 }
1180
1181 Conn::Status Conn::ConsumeHeader(struct evbuffer* evb) {
1182 uint8* buf = EVBUFFER_DATA(evb);
1183 size_t buf_size = EVBUFFER_LENGTH(evb);
1184
1185 static const uint8 kGetPrefix[] = "GET " kProxyPath;
1186 static const uint8 kKeyValueDelimiter[] = ": ";
1187
1188 if (buf_size <= 0)
1189 return STATUS_INCOMPLETE;
1190 if (!buf)
1191 return STATUS_ABORT;
1192 if (!std::equal(buf, buf + std::min(buf_size, strlen(kGetPrefix)),
1193 kGetPrefix)) {
1194 // Data head does not match what is expected.
1195 return STATUS_ABORT;
1196 }
1197
1198 if (buf_size >= WebSocketProxy::kHeaderLimit)
1199 return STATUS_ABORT;
1200 uint8* buf_end = buf + buf_size;
1201 // Handshake request must end with double CRLF.
1202 uint8* term_pos = std::search(buf, buf_end, kCRLFCRLF,
1203 kCRLFCRLF + strlen(kCRLFCRLF));
1204 if (term_pos == buf_end)
1205 return STATUS_INCOMPLETE;
1206 term_pos += strlen(kCRLFCRLF);
1207 // First line is "GET path?query protocol" line. If query is empty then we
1208 // fall back to (obsolete) way of obtaining parameters from first websocket
1209 // frame. Otherwise query contains all required parameters (host, port etc).
1210 uint8* get_request_end = std::search(
1211 buf, term_pos, kCRLF, kCRLF + strlen(kCRLF));
1212 DCHECK(get_request_end != term_pos);
1213 uint8* resource_end = std::find(
1214 buf + strlen(kGetPrefix), get_request_end, ' ');
1215 if (*resource_end != ' ')
1216 return STATUS_ABORT;
1217 if (resource_end != buf + strlen(kGetPrefix)) {
1218 char* piece = reinterpret_cast<char*>(buf) + strlen(kGetPrefix) + 1;
1219 url_parse::Component query(
1220 0, resource_end - reinterpret_cast<uint8*>(piece));
1221 for (url_parse::Component key, value;
1222 url_parse::ExtractQueryKeyValue(piece, &query, &key, &value);) {
1223 if (key.len > 0) {
1224 requested_parameters_[std::string(piece + key.begin, key.len)] =
1225 net::UnescapeURLComponent(std::string(piece + value.begin,
1226 value.len), net::UnescapeRule::URL_SPECIAL_CHARS);
1227 }
1228 }
1229 }
1230 for (uint8* pos = get_request_end;;) {
1231 pos += strlen(kCRLF);
1232 if (term_pos - pos < static_cast<ptrdiff_t>(strlen(kCRLF)))
1233 return STATUS_ABORT;
1234 if (term_pos - pos == static_cast<ptrdiff_t>(strlen(kCRLF)))
1235 break;
1236 uint8* npos = std::search(pos, term_pos, kKeyValueDelimiter,
1237 kKeyValueDelimiter + strlen(kKeyValueDelimiter));
1238 if (npos == term_pos)
1239 return STATUS_ABORT;
1240 std::string key = FetchAsciiSnippet(pos, npos, AsciiFilterLower);
1241 pos = std::search(npos += strlen(kKeyValueDelimiter), term_pos,
1242 kCRLF, kCRLF + strlen(kCRLF));
1243 if (pos == term_pos)
1244 return STATUS_ABORT;
1245 if (!key.empty()) {
1246 header_fields_[key] = FetchAsciiSnippet(npos, pos,
1247 key == "sec-websocket-key" ? AsciiFilterVerbatim : AsciiFilterLower);
1248 }
1249 }
1250
1251 // Values of Upgrade and Connection fields are hardcoded in the protocol.
1252 if (header_fields_["upgrade"] != "websocket" ||
1253 header_fields_["connection"] != "upgrade" ||
1254 header_fields_["sec-websocket-key"].size() != 24) {
1255 return STATUS_ABORT;
1256 }
1257 if (header_fields_["sec-websocket-version"] != "8" &&
1258 header_fields_["sec-websocket-version"] != "13") {
1259 return STATUS_ABORT;
1260 }
1261 // Normalize origin (e.g. leading slash).
1262 GURL origin = GURL(GetOrigin()).GetOrigin();
1263 if (!origin.is_valid())
1264 return STATUS_ABORT;
1265
1266 if (!requested_parameters_.empty()) {
1267 destname_ = requested_parameters_["hostname"];
1268 int port;
1269 if (!base::StringToInt(requested_parameters_["port"], &port) ||
1270 port < 0 || port >= 1 << 16) {
1271 return STATUS_ABORT;
1272 }
1273 destport_ = port;
1274 destaddr_ = requested_parameters_["addr"];
1275 do_tls_ = (requested_parameters_["tls"] == "true");
1276
1277 requested_parameters_["extension_id"] =
1278 FetchExtensionIdFromOrigin(GetOrigin());
1279 std::string passport(requested_parameters_["passport"]);
1280 requested_parameters_.erase("passport");
1281 if (!chrome::InternalAuthVerification::VerifyPassport(
1282 passport, "web_socket_proxy", requested_parameters_)) {
1283 return STATUS_ABORT;
1284 }
1285 }
1286
1287 evbuffer_drain(evb, term_pos - buf);
1288 return STATUS_OK;
1289 }
1290
1291 bool Conn::EmitHandshake(Chan* chan) {
1292 std::vector<std::string> boilerplate;
1293 boilerplate.push_back("HTTP/1.1 101 WebSocket Protocol Handshake");
1294 boilerplate.push_back("Upgrade: websocket");
1295 boilerplate.push_back("Connection: Upgrade");
1296
1297 {
1298 // Take care of Accept field.
1299 std::string word = header_fields_["sec-websocket-key"];
1300 word += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
1301 std::string accept_token;
1302 base::Base64Encode(base::SHA1HashString(word), &accept_token);
1303 boilerplate.push_back("Sec-WebSocket-Accept: " + accept_token);
1304 }
1305
1306 boilerplate.push_back("");
1307 for (size_t i = 0; i < boilerplate.size(); ++i) {
1308 if (!chan->Write(boilerplate[i].c_str(), boilerplate[i].size()) ||
1309 !chan->Write(kCRLF, strlen(kCRLF))) {
1310 return false;
1311 }
1312 }
1313 return true;
1314 }
1315
1316 bool Conn::EmitFrame(
1317 Chan* chan, WebSocketFrameOpcode opcode, const void* buf, size_t size) {
1318 uint8 header[10];
1319 int header_size = 2;
1320 DCHECK(chan);
1321 DCHECK(opcode >= 0 && static_cast<int>(opcode) < 16);
1322 header[0] = opcode | 0x80; // FIN bit set.
1323 if (size < 126) {
1324 header[1] = size;
1325 } else if (size < (1 << 16)) {
1326 header[1] = 126;
1327 WriteNetworkInteger(size, header + 2, 2);
1328 header_size += 2;
1329 } else {
1330 header[1] = 127;
1331 WriteNetworkInteger(size, header + 2, 8);
1332 header_size += 8;
1333 }
1334 return chan->Write(header, header_size) && chan->Write(buf, size);
1335 }
1336
1337 Conn::Status Conn::ConsumeDestframe(struct evbuffer* evb) {
1338 if (!requested_parameters_.empty()) {
1339 // Parameters were already provided (and verified) in query component of
1340 // websocket URL.
1341 return STATUS_OK;
1342 }
1343 if (frame_bytes_remaining_ == 0) {
1344 Conn::Status rv = ConsumeFrameHeader(evb);
1345 if (rv != STATUS_OK)
1346 return rv;
1347 if (frame_bytes_remaining_ == 0 ||
1348 frame_bytes_remaining_ >= WebSocketProxy::kHeaderLimit) {
1349 return STATUS_ABORT;
1350 }
1351 }
1352
1353 uint8* buf = EVBUFFER_DATA(evb);
1354 size_t buf_size = EVBUFFER_LENGTH(evb);
1355 if (buf_size < frame_bytes_remaining_)
1356 return STATUS_INCOMPLETE;
1357 for (size_t i = 0; i < buf_size; ++i) {
1358 buf[i] ^= frame_mask_[frame_mask_index_];
1359 frame_mask_index_ = (frame_mask_index_ + 1) % 4;
1360 }
1361 std::string passport;
1362 if (!WebSocketProxyHelper::FetchPassportAddrNamePort(
1363 buf, buf + frame_bytes_remaining_,
1364 &passport, &destaddr_, &destname_, &destport_)) {
1365 return STATUS_ABORT;
1366 }
1367 std::map<std::string, std::string> map;
1368 map["hostname"] = destname_;
1369 map["port"] = base::IntToString(destport_);
1370 map["extension_id"] = FetchExtensionIdFromOrigin(GetOrigin());
1371 if (!destaddr_.empty())
1372 map["addr"] = destaddr_;
1373 if (!chrome::InternalAuthVerification::VerifyPassport(
1374 passport, "web_socket_proxy", map)) {
1375 return STATUS_ABORT;
1376 }
1377
1378 evbuffer_drain(evb, frame_bytes_remaining_);
1379 frame_bytes_remaining_ = 0;
1380 return STATUS_OK;
1381 }
1382
1383 Conn::Status Conn::ConsumeFrameHeader(struct evbuffer* evb) {
1384 uint8* buf = EVBUFFER_DATA(evb);
1385 size_t buf_size = EVBUFFER_LENGTH(evb);
1386 size_t header_size = 2;
1387
1388 if (buf_size < header_size)
1389 return STATUS_INCOMPLETE;
1390 if (buf[0] & 0x70) {
1391 // We are not able to handle non-zero reserved bits.
1392 NOTIMPLEMENTED();
1393 return STATUS_ABORT;
1394 }
1395 bool fin_flag = buf[0] & 0x80;
1396 if (!fin_flag) {
1397 NOTIMPLEMENTED();
1398 return STATUS_ABORT;
1399 }
1400 int opcode = buf[0] & 0x0f;
1401 switch (opcode) {
1402 case WS_OPCODE_TEXT:
1403 break;
1404 case WS_OPCODE_CLOSE:
1405 return STATUS_ABORT;
1406 default:
1407 NOTIMPLEMENTED();
1408 return STATUS_ABORT;
1409 }
1410
1411 bool mask_flag = buf[1] & 0x80;
1412 if (!mask_flag) {
1413 // Client-to-server frames must be masked.
1414 return STATUS_ABORT;
1415 }
1416 frame_bytes_remaining_ = buf[1] & 0x7f;
1417 int extra_size = 0;
1418 if (frame_bytes_remaining_ == 126)
1419 extra_size = 2;
1420 else if (frame_bytes_remaining_ == 127)
1421 extra_size = 8;
1422 if (buf_size < header_size + extra_size + sizeof(frame_mask_))
1423 return STATUS_INCOMPLETE;
1424 if (extra_size)
1425 frame_bytes_remaining_ = ReadNetworkInteger(buf + header_size, extra_size);
1426 header_size += extra_size;
1427 memcpy(frame_mask_, buf + header_size, sizeof(frame_mask_));
1428 header_size += sizeof(frame_mask_);
1429 frame_mask_index_ = 0;
1430 evbuffer_drain(evb, header_size);
1431 return STATUS_OK;
1432 }
1433
1434 Conn::Status Conn::ProcessFrameData(struct evbuffer* evb) {
1435 uint8* buf = EVBUFFER_DATA(evb);
1436 size_t buf_size = EVBUFFER_LENGTH(evb);
1437
1438 DCHECK_GE(frame_bytes_remaining_, 1u);
1439 if (frame_bytes_remaining_ < buf_size)
1440 buf_size = frame_bytes_remaining_;
1441 // base64 is encoded in chunks of 4 bytes.
1442 buf_size = buf_size / 4 * 4;
1443 if (buf_size < 1)
1444 return STATUS_INCOMPLETE;
1445 switch (phase_) {
1446 case PHASE_INSIDE_FRAME_BASE64: {
1447 for (size_t i = 0; i < buf_size; ++i) {
1448 buf[i] ^= frame_mask_[frame_mask_index_];
1449 frame_mask_index_ = (frame_mask_index_ + 1) % 4;
1450 }
1451 std::string out_bytes;
1452 base::Base64Decode(std::string(buf, buf + buf_size), &out_bytes);
1453 evbuffer_drain(evb, buf_size);
1454 DCHECK(destchan_.write_bev());
1455 if (!destchan_.Write(out_bytes.c_str(), out_bytes.size()))
1456 return STATUS_ABORT;
1457 break;
1458 }
1459 case PHASE_INSIDE_FRAME_SKIP: {
1460 evbuffer_drain(evb, buf_size);
1461 break;
1462 }
1463 default: {
1464 return STATUS_ABORT;
1465 }
1466 }
1467 frame_bytes_remaining_ -= buf_size;
1468 return frame_bytes_remaining_ ? STATUS_INCOMPLETE : STATUS_OK;
1469 }
1470
1471 bool Conn::TryConnectDest(const struct sockaddr* addr, socklen_t addrlen) {
1472 if (destchan_.read_fd() >= 0 || destchan_.read_bev() != NULL)
1473 return false;
1474 if (do_tls_) {
1475 int fd[4];
1476 if (pipe(fd) || pipe(fd + 2))
1477 return false;
1478 destchan_.set_read_fd(fd[0]);
1479 destchan_.set_write_fd(fd[3]);
1480 for (int i = arraysize(fd); i--;) {
1481 if (!SetNonBlock(fd[i]))
1482 return false;
1483 }
1484 destchan_.set_read_bev(bufferevent_new(
1485 destchan_.read_fd(),
1486 &OnDestchanRead, NULL, &OnDestchanError,
1487 evkey_));
1488 destchan_.set_write_bev(bufferevent_new(
1489 destchan_.write_fd(),
1490 NULL, &OnDestchanWrite, &OnDestchanError,
1491 evkey_));
1492 net::IPEndPoint endpoint;
1493 if (!endpoint.FromSockAddr(addr, addrlen))
1494 return false;
1495 net::AddressList addrlist(endpoint);
1496 net::HostPortPair host_port_pair(destname_, destport_);
1497 BrowserThread::PostTask(
1498 BrowserThread::IO, FROM_HERE, base::Bind(
1499 &SSLChan::Start, addrlist, host_port_pair, fd[2], fd[1]));
1500 } else {
1501 int sock = socket(addr->sa_family, SOCK_STREAM, 0);
1502 if (sock < 0)
1503 return false;
1504 destchan_.set_read_fd(sock);
1505 destchan_.set_write_fd(sock);
1506 if (!SetNonBlock(sock))
1507 return false;
1508 if (connect(sock, addr, addrlen)) {
1509 if (errno != EINPROGRESS)
1510 return false;
1511 }
1512 destchan_.set_read_bev(bufferevent_new(
1513 sock,
1514 &OnDestchanRead, &OnDestchanWrite, &OnDestchanError,
1515 evkey_));
1516 destchan_.set_write_bev(destchan_.read_bev());
1517 }
1518 if (destchan_.read_bev() == NULL || destchan_.write_bev() == NULL)
1519 return false;
1520 if (bufferevent_base_set(master_->evbase(), destchan_.read_bev()) ||
1521 bufferevent_base_set(master_->evbase(), destchan_.write_bev())) {
1522 return false;
1523 }
1524 bufferevent_setwatermark(
1525 destchan_.read_bev(), EV_READ, 0, WebSocketProxy::kBufferLimit);
1526 if (bufferevent_enable(destchan_.read_bev(), EV_READ) ||
1527 bufferevent_enable(destchan_.write_bev(), EV_WRITE)) {
1528 return false;
1529 }
1530 return true;
1531 }
1532
1533 const std::string& Conn::GetOrigin() {
1534 return header_fields_[header_fields_["sec-websocket-version"] == "8" ?
1535 "sec-websocket-origin" : "origin"];
1536 }
1537
1538 // static
1539 void Conn::OnPrimchanRead(struct bufferevent* bev, EventKey evkey) {
1540 Conn* cs = Conn::Get(evkey);
1541 if (bev == NULL ||
1542 cs == NULL ||
1543 bev != cs->primchan_.read_bev()) {
1544 NOTREACHED();
1545 return;
1546 }
1547 if (EVBUFFER_LENGTH(EVBUFFER_INPUT(bev)) <= 0)
1548 return;
1549 cs->master_->MarkConnImportance(cs, true);
1550 for (;;) {
1551 switch (cs->phase_) {
1552 case PHASE_WAIT_HANDSHAKE: {
1553 switch (cs->ConsumeHeader(EVBUFFER_INPUT(bev))) {
1554 case STATUS_OK: {
1555 break;
1556 }
1557 case STATUS_INCOMPLETE: {
1558 return;
1559 }
1560 case STATUS_ABORT:
1561 default: {
1562 cs->master_->ZapConn(cs);
1563 return;
1564 }
1565 }
1566 // Header consumed OK. Do respond.
1567 if (!cs->EmitHandshake(&cs->primchan_)) {
1568 cs->master_->ZapConn(cs);
1569 return;
1570 }
1571 cs->phase_ = PHASE_WAIT_DESTFRAME;
1572 }
1573 case PHASE_WAIT_DESTFRAME: {
1574 switch (cs->ConsumeDestframe(EVBUFFER_INPUT(bev))) {
1575 case STATUS_OK: {
1576 {
1577 // Unfortunately libevent as of 1.4 does not look into /etc/hosts.
1578 // There seems to be no easy API to perform only "local" part of
1579 // getaddrinfo resolution. Hence this hack for "localhost".
1580 if (cs->destname_ == "localhost")
1581 cs->destname_ = "127.0.0.1";
1582 }
1583 if (cs->destaddr_.empty())
1584 cs->destaddr_ = cs->destname_;
1585 {
1586 struct sockaddr_in sa;
1587 memset(&sa, 0, sizeof(sa));
1588 sa.sin_port = base::HostToNet16(cs->destport_);
1589 if (inet_pton(sa.sin_family = AF_INET,
1590 cs->destaddr_.c_str(),
1591 &sa.sin_addr) == 1) {
1592 // valid IPv4 address supplied.
1593 if (cs->TryConnectDest((struct sockaddr*)&sa, sizeof(sa))) {
1594 cs->phase_ = PHASE_WAIT_DESTCONNECT;
1595 return;
1596 }
1597 }
1598 }
1599 {
1600 if (cs->destaddr_.size() >= 2 &&
1601 cs->destaddr_[0] == '[' &&
1602 cs->destaddr_[cs->destaddr_.size() - 1] == ']') {
1603 // Literal IPv6 address in brackets.
1604 cs->destaddr_ =
1605 cs->destaddr_.substr(1, cs->destaddr_.size() - 2);
1606 }
1607 struct sockaddr_in6 sa;
1608 memset(&sa, 0, sizeof(sa));
1609 sa.sin6_port = base::HostToNet16(cs->destport_);
1610 if (inet_pton(sa.sin6_family = AF_INET6,
1611 cs->destaddr_.c_str(),
1612 &sa.sin6_addr) == 1) {
1613 // valid IPv6 address supplied.
1614 if (cs->TryConnectDest((struct sockaddr*)&sa, sizeof(sa))) {
1615 cs->phase_ = PHASE_WAIT_DESTCONNECT;
1616 return;
1617 }
1618 }
1619 }
1620 // Asynchronous DNS resolution.
1621 if (evdns_count_nameservers() < 1) {
1622 evdns_clear_nameservers_and_suspend();
1623 evdns_init();
1624 evdns_resume();
1625 }
1626 evdns_resolve_ipv4(cs->destname_.c_str(), 0,
1627 &OnDestResolutionIPv4, evkey);
1628 evdns_resolve_ipv6(cs->destname_.c_str(), 0,
1629 &OnDestResolutionIPv6, evkey);
1630 cs->phase_ = PHASE_WAIT_DESTCONNECT;
1631 return;
1632 }
1633 case STATUS_INCOMPLETE: {
1634 return;
1635 }
1636 case STATUS_ABORT:
1637 default: {
1638 cs->Shut(WS_CLOSE_DESTINATION_ERROR,
1639 "Incorrect destination specification in first frame");
1640 return;
1641 }
1642 }
1643 }
1644 case PHASE_WAIT_DESTCONNECT: {
1645 if (EVBUFFER_LENGTH(EVBUFFER_INPUT(bev)) >=
1646 WebSocketProxy::kBufferLimit) {
1647 cs->Shut(WS_CLOSE_LIMIT_VIOLATION, "Read buffer overflow");
1648 }
1649 return;
1650 }
1651 case PHASE_OUTSIDE_FRAME: {
1652 switch (cs->ConsumeFrameHeader(EVBUFFER_INPUT(bev))) {
1653 case STATUS_OK: {
1654 if (cs->frame_bytes_remaining_ % 4) {
1655 // We expect base64 encoded data (encoded in 4-bytes chunks).
1656 cs->Shut(WS_CLOSE_UNACCEPTABLE_DATA,
1657 "Frame payload size is not multiple of 4");
1658 return;
1659 }
1660 cs->phase_ = PHASE_INSIDE_FRAME_BASE64;
1661 // Process remaining data if any.
1662 break;
1663 }
1664 case STATUS_SKIP: {
1665 cs->phase_ = PHASE_INSIDE_FRAME_SKIP;
1666 // Process remaining data if any.
1667 break;
1668 }
1669 case STATUS_INCOMPLETE: {
1670 return;
1671 }
1672 case STATUS_ABORT:
1673 default: {
1674 cs->Shut(WS_CLOSE_PROTOCOL_ERROR, "Invalid frame header");
1675 return;
1676 }
1677 }
1678 break;
1679 }
1680 case PHASE_INSIDE_FRAME_BASE64:
1681 case PHASE_INSIDE_FRAME_SKIP: {
1682 switch (cs->ProcessFrameData(EVBUFFER_INPUT(bev))) {
1683 case STATUS_OK: {
1684 cs->phase_ = PHASE_OUTSIDE_FRAME;
1685 // Handle remaining data if any.
1686 break;
1687 }
1688 case STATUS_INCOMPLETE: {
1689 return;
1690 }
1691 case STATUS_ABORT:
1692 default: {
1693 cs->Shut(WS_CLOSE_UNACCEPTABLE_DATA, "Invalid frame data");
1694 return;
1695 }
1696 }
1697 break;
1698 }
1699 case PHASE_SHUT: {
1700 evbuffer_drain(EVBUFFER_INPUT(bev),
1701 EVBUFFER_LENGTH(EVBUFFER_INPUT(bev)));
1702 return;
1703 }
1704 case PHASE_DEFUNCT:
1705 default: {
1706 NOTREACHED();
1707 cs->master_->ZapConn(cs);
1708 return;
1709 }
1710 }
1711 }
1712 }
1713
1714 // static
1715 void Conn::OnPrimchanWrite(struct bufferevent* bev, EventKey evkey) {
1716 Conn* cs = Conn::Get(evkey);
1717 if (bev == NULL ||
1718 cs == NULL ||
1719 bev != cs->primchan_.write_bev()) {
1720 NOTREACHED();
1721 return;
1722 }
1723 // Write callback is called when low watermark is reached, 0 by default.
1724 cs->primchan_.set_write_pending(false);
1725 if (cs->phase_ >= PHASE_SHUT) {
1726 cs->master_->ZapConn(cs);
1727 return;
1728 }
1729 if (cs->phase_ > PHASE_WAIT_DESTCONNECT)
1730 OnDestchanRead(cs->destchan_.read_bev(), evkey);
1731 if (cs->phase_ >= PHASE_SHUT)
1732 cs->primchan_.Zap();
1733 }
1734
1735 // static
1736 void Conn::OnPrimchanError(struct bufferevent* bev,
1737 short what, EventKey evkey) {
1738 Conn* cs = Conn::Get(evkey);
1739 if (bev == NULL ||
1740 cs == NULL ||
1741 (bev != cs->primchan_.read_bev() && bev != cs->primchan_.write_bev())) {
1742 return;
1743 }
1744 cs->primchan_.set_write_pending(false);
1745 if (cs->phase_ >= PHASE_SHUT)
1746 cs->master_->ZapConn(cs);
1747 else
1748 cs->Shut(WS_CLOSE_NORMAL, "Error reported on websocket channel");
1749 }
1750
1751 // static
1752 void Conn::OnDestResolutionIPv4(int result, char type,
1753 int count, int ttl,
1754 void* addr_list, EventKey evkey) {
1755 Conn* cs = Conn::Get(evkey);
1756 if (cs == NULL)
1757 return;
1758 if (cs->phase_ != PHASE_WAIT_DESTCONNECT)
1759 return;
1760 if (result == DNS_ERR_NONE &&
1761 count >= 1 &&
1762 addr_list != NULL &&
1763 type == DNS_IPv4_A) {
1764 for (int i = 0; i < count; ++i) {
1765 struct sockaddr_in sa;
1766 memset(&sa, 0, sizeof(sa));
1767 sa.sin_family = AF_INET;
1768 sa.sin_port = base::HostToNet16(cs->destport_);
1769 DCHECK(sizeof(sa.sin_addr) == sizeof(struct in_addr));
1770 memcpy(&sa.sin_addr,
1771 static_cast<struct in_addr*>(addr_list) + i,
1772 sizeof(sa.sin_addr));
1773 if (cs->TryConnectDest((struct sockaddr*)&sa, sizeof(sa)))
1774 return;
1775 }
1776 }
1777 cs->destresolution_ipv4_failed_ = true;
1778 if (cs->destresolution_ipv4_failed_ && cs->destresolution_ipv6_failed_)
1779 cs->Shut(WS_CLOSE_RESOLUTION_FAILED, "DNS resolution failed");
1780 }
1781
1782 // static
1783 void Conn::OnDestResolutionIPv6(int result, char type,
1784 int count, int ttl,
1785 void* addr_list, EventKey evkey) {
1786 Conn* cs = Conn::Get(evkey);
1787 if (cs == NULL)
1788 return;
1789 if (cs->phase_ != PHASE_WAIT_DESTCONNECT)
1790 return;
1791 if (result == DNS_ERR_NONE &&
1792 count >= 1 &&
1793 addr_list != NULL &&
1794 type == DNS_IPv6_AAAA) {
1795 for (int i = 0; i < count; ++i) {
1796 struct sockaddr_in6 sa;
1797 memset(&sa, 0, sizeof(sa));
1798 sa.sin6_family = AF_INET6;
1799 sa.sin6_port = base::HostToNet16(cs->destport_);
1800 DCHECK(sizeof(sa.sin6_addr) == sizeof(struct in6_addr));
1801 memcpy(&sa.sin6_addr,
1802 static_cast<struct in6_addr*>(addr_list) + i,
1803 sizeof(sa.sin6_addr));
1804 if (cs->TryConnectDest((struct sockaddr*)&sa, sizeof(sa)))
1805 return;
1806 }
1807 }
1808 cs->destresolution_ipv6_failed_ = true;
1809 if (cs->destresolution_ipv4_failed_ && cs->destresolution_ipv6_failed_)
1810 cs->Shut(WS_CLOSE_RESOLUTION_FAILED, "DNS resolution failed");
1811 }
1812
1813 // static
1814 void Conn::OnDestConnectTimeout(int, short, EventKey evkey) {
1815 Conn* cs = Conn::Get(evkey);
1816 if (cs == NULL)
1817 return;
1818 if (cs->phase_ > PHASE_WAIT_DESTCONNECT)
1819 return;
1820 cs->Shut(WS_CLOSE_RESOLUTION_FAILED, "DNS resolution timeout");
1821 }
1822
1823 // static
1824 void Conn::OnDestchanRead(struct bufferevent* bev, EventKey evkey) {
1825 Conn* cs = Conn::Get(evkey);
1826 if (bev == NULL ||
1827 cs == NULL ||
1828 bev != cs->destchan_.read_bev()) {
1829 NOTREACHED();
1830 return;
1831 }
1832 if (EVBUFFER_LENGTH(EVBUFFER_INPUT(bev)) <= 0)
1833 return;
1834 if (cs->primchan_.write_bev() == NULL) {
1835 cs->master_->ZapConn(cs);
1836 return;
1837 }
1838 cs->master_->MarkConnImportance(cs, true);
1839 std::string out_bytes;
1840 base::Base64Encode(
1841 std::string(
1842 static_cast<const char*>(static_cast<void*>(
1843 EVBUFFER_DATA(EVBUFFER_INPUT(bev)))),
1844 EVBUFFER_LENGTH(EVBUFFER_INPUT(bev))),
1845 &out_bytes);
1846 evbuffer_drain(EVBUFFER_INPUT(bev), EVBUFFER_LENGTH(EVBUFFER_INPUT(bev)));
1847 if (!cs->EmitFrame(&cs->primchan_, WS_OPCODE_TEXT,
1848 out_bytes.c_str(), out_bytes.size())) {
1849 cs->Shut(WS_CLOSE_UNEXPECTED, "Failed to write websocket frame");
1850 }
1851 }
1852
1853 // static
1854 void Conn::OnDestchanWrite(struct bufferevent* bev, EventKey evkey) {
1855 Conn* cs = Conn::Get(evkey);
1856 if (bev == NULL ||
1857 cs == NULL ||
1858 bev != cs->destchan_.write_bev()) {
1859 NOTREACHED();
1860 return;
1861 }
1862 // Write callback is called when low watermark is reached, 0 by default.
1863 cs->destchan_.set_write_pending(false);
1864 if (cs->phase_ == PHASE_WAIT_DESTCONNECT)
1865 cs->phase_ = PHASE_OUTSIDE_FRAME;
1866 if (cs->phase_ < PHASE_SHUT)
1867 OnPrimchanRead(cs->primchan_.read_bev(), evkey);
1868 else
1869 cs->destchan_.Zap();
1870 }
1871
1872 // static
1873 void Conn::OnDestchanError(struct bufferevent* bev,
1874 short what, EventKey evkey) {
1875 Conn* cs = Conn::Get(evkey);
1876 if (bev == NULL ||
1877 cs == NULL ||
1878 (bev != cs->destchan_.read_bev() && bev != cs->destchan_.write_bev())) {
1879 return;
1880 }
1881 cs->destchan_.set_write_pending(false);
1882 if (cs->phase_ >= PHASE_SHUT)
1883 cs->master_->ZapConn(cs);
1884 else
1885 cs->Shut(WS_CLOSE_DESTINATION_ERROR,
1886 "Failure reported on destination channel");
1887 }
1888
1889 // static
1890 Conn::EventKey Conn::last_evkey_ = 0;
1891
1892 // static
1893 base::LazyInstance<Conn::EventKeyMap>::Leaky
1894 Conn::evkey_map_ = LAZY_INSTANCE_INITIALIZER;
1895
1896 } // namespace
1897
1898 WebSocketProxy::WebSocketProxy() : impl_(new Serv()) {
1899 }
1900
1901 WebSocketProxy::~WebSocketProxy() {
1902 delete static_cast<Serv*>(impl_);
1903 impl_ = NULL;
1904 }
1905
1906 void WebSocketProxy::Run() {
1907 static_cast<Serv*>(impl_)->Run();
1908 }
1909
1910 void WebSocketProxy::Shutdown() {
1911 static_cast<Serv*>(impl_)->Shutdown();
1912 }
1913
1914 void WebSocketProxy::OnNetworkChange() {
1915 static_cast<Serv*>(impl_)->OnNetworkChange();
1916 }
1917
1918 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/web_socket_proxy.h ('k') | chrome/browser/chromeos/web_socket_proxy_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698