15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/protocol/channel_multiplexer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/single_thread_task_runner.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/thread_task_runner_handle.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/stream_socket.h" 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "remoting/protocol/message_serialization.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protocol { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kChannelIdUnknown = -1; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxPacketSize = 1024; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PendingPacket { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingPacket(scoped_ptr<MultiplexPacket> packet, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done_task) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : packet(packet.Pass()), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_task(done_task), 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos(0U) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~PendingPacket() { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_task.Run(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_empty() { return pos >= packet->data().size(); } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Read(char* buffer, size_t size) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = std::min(size, packet->data().size() - pos); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer, packet->data().data() + pos, size); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos += size; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MultiplexPacket> packet; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Closure done_task; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t pos; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PendingPacket); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char ChannelMultiplexer::kMuxChannelName[] = "mux"; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ChannelMultiplexer::PendingChannel { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingChannel(const std::string& name, 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ChannelCreatedCallback& callback) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : name(name), callback(callback) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name; 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ChannelCreatedCallback callback; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChannelMultiplexer::MuxChannel { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MuxChannel(ChannelMultiplexer* multiplexer, const std::string& name, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int send_id); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~MuxChannel(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name() { return name_; } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int receive_id() { return receive_id_; } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_receive_id(int id) { receive_id_ = id; } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by ChannelMultiplexer. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::StreamSocket> CreateSocket(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnIncomingPacket(scoped_ptr<MultiplexPacket> packet, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done_task); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnWriteFailed(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by MuxSocket. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnSocketDestroyed(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool DoWrite(scoped_ptr<MultiplexPacket> packet, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done_task); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int DoRead(net::IOBuffer* buffer, int buffer_len); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelMultiplexer* multiplexer_; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name_; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int send_id_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool id_sent_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int receive_id_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MuxSocket* socket_; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<PendingPacket*> pending_packets_; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MuxChannel); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChannelMultiplexer::MuxSocket : public net::StreamSocket, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::NonThreadSafe, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::SupportsWeakPtr<MuxSocket> { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MuxSocket(MuxChannel* channel); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~MuxSocket(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnWriteComplete(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnWriteFailed(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnPacketReceived(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // net::StreamSocket interface. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int Read(net::IOBuffer* buffer, int buffer_len, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) OVERRIDE; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int Write(net::IOBuffer* buffer, int buffer_len, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) OVERRIDE; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual int SetReceiveBufferSize(int32 size) OVERRIDE { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return net::ERR_NOT_IMPLEMENTED; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual int SetSendBufferSize(int32 size) OVERRIDE { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return net::ERR_NOT_IMPLEMENTED; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int Connect(const net::CompletionCallback& callback) OVERRIDE { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return net::ERR_NOT_IMPLEMENTED; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Disconnect() OVERRIDE { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsConnected() const OVERRIDE { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool IsConnectedAndIdle() const OVERRIDE { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetPeerAddress(net::IPEndPoint* address) const OVERRIDE { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return net::ERR_NOT_IMPLEMENTED; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetLocalAddress(net::IPEndPoint* address) const OVERRIDE { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return net::ERR_NOT_IMPLEMENTED; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual const net::BoundNetLog& NetLog() const OVERRIDE { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_log_; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetSubresourceSpeculation() OVERRIDE { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetOmniboxSpeculation() OVERRIDE { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool WasEverUsed() const OVERRIDE { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool UsingTCPFastOpen() const OVERRIDE { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool WasNpnNegotiated() const OVERRIDE { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual net::NextProto GetNegotiatedProtocol() const OVERRIDE { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::kProtoUnknown; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetSSLInfo(net::SSLInfo* ssl_info) OVERRIDE { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MuxChannel* channel_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback read_callback_; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBuffer> read_buffer_; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int read_buffer_size_; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool write_pending_; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int write_result_; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback write_callback_; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::BoundNetLog net_log_; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MuxSocket); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelMultiplexer::MuxChannel::MuxChannel( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChannelMultiplexer* multiplexer, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int send_id) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : multiplexer_(multiplexer), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name_(name), 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) send_id_(send_id), 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_sent_(false), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) receive_id_(kChannelIdUnknown), 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_(NULL) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelMultiplexer::MuxChannel::~MuxChannel() { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Socket must be destroyed before the channel. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!socket_); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&pending_packets_); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<net::StreamSocket> ChannelMultiplexer::MuxChannel::CreateSocket() { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!socket_); // Can't create more than one socket per channel. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MuxSocket> result(new MuxSocket(this)); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = result.get(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.PassAs<net::StreamSocket>(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::MuxChannel::OnIncomingPacket( 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MultiplexPacket> packet, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done_task) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(packet->channel_id(), receive_id_); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (packet->data().size() > 0) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_packets_.push_back(new PendingPacket(packet.Pass(), done_task)); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (socket_) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notify the socket that we have more data. 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_->OnPacketReceived(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::MuxChannel::OnWriteFailed() { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (socket_) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_->OnWriteFailed(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::MuxChannel::OnSocketDestroyed() { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(socket_); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_ = NULL; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelMultiplexer::MuxChannel::DoWrite( 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MultiplexPacket> packet, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done_task) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet->set_channel_id(send_id_); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!id_sent_) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet->set_channel_name(name_); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_sent_ = true; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return multiplexer_->DoWrite(packet.Pass(), done_task); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChannelMultiplexer::MuxChannel::DoRead(net::IOBuffer* buffer, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer_len) { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pos = 0; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (buffer_len > 0 && !pending_packets_.empty()) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!pending_packets_.front()->is_empty()); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = pending_packets_.front()->Read( 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer->data() + pos, buffer_len); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(result, buffer_len); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos += result; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_len -= pos; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_packets_.front()->is_empty()) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete pending_packets_.front(); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_packets_.erase(pending_packets_.begin()); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pos; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelMultiplexer::MuxSocket::MuxSocket(MuxChannel* channel) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : channel_(channel), 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_buffer_size_(0), 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_pending_(false), 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_result_(0) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelMultiplexer::MuxSocket::~MuxSocket() { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->OnSocketDestroyed(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChannelMultiplexer::MuxSocket::Read( 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IOBuffer* buffer, int buffer_len, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(read_callback_.is_null()); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = channel_->DoRead(buffer, buffer_len); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == 0) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_buffer_ = buffer; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_buffer_size_ = buffer_len; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_callback_ = callback; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_IO_PENDING; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ChannelMultiplexer::MuxSocket::Write( 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IOBuffer* buffer, int buffer_len, 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MultiplexPacket> packet(new MultiplexPacket()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t size = std::min(kMaxPacketSize, buffer_len); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet->mutable_data()->assign(buffer->data(), size); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_pending_ = true; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = channel_->DoWrite(packet.Pass(), base::Bind( 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ChannelMultiplexer::MuxSocket::OnWriteComplete, AsWeakPtr())); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cannot complete the write, e.g. if the connection has been terminated. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_FAILED; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnWriteComplete() might be called above synchronously. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_pending_) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(write_callback_.is_null()); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_callback_ = callback; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_result_ = size; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_IO_PENDING; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::MuxSocket::OnWriteComplete() { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_pending_ = false; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!write_callback_.is_null()) { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback cb; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::swap(cb, write_callback_); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cb.Run(write_result_); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::MuxSocket::OnWriteFailed() { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!write_callback_.is_null()) { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback cb; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::swap(cb, write_callback_); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cb.Run(net::ERR_FAILED); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::MuxSocket::OnPacketReceived() { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_callback_.is_null()) { 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int result = channel_->DoRead(read_buffer_.get(), read_buffer_size_); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_buffer_ = NULL; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(result, 0); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback cb; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::swap(cb, read_callback_); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cb.Run(result); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciChannelMultiplexer::ChannelMultiplexer(StreamChannelFactory* factory, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& base_channel_name) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : base_channel_factory_(factory), 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_channel_name_(base_channel_name), 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_channel_id_(0), 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelMultiplexer::~ChannelMultiplexer() { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pending_channels_.empty()); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteValues(&channels_); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cancel creation of the base channel if it hasn't finished. 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base_channel_factory_) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_channel_factory_->CancelChannelCreation(base_channel_name_); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ChannelMultiplexer::CreateChannel(const std::string& name, 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ChannelCreatedCallback& callback) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base_channel_.get()) { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Already have |base_channel_|. Create new multiplexed channel 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // synchronously. 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(GetOrCreateChannel(name)->CreateSocket()); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!base_channel_.get() && !base_channel_factory_) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fail synchronously if we failed to create |base_channel_|. 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(scoped_ptr<net::StreamSocket>()); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Still waiting for the |base_channel_|. 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_channels_.push_back(PendingChannel(name, callback)); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is the first multiplexed channel then create the base channel. 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_channels_.size() == 1U) { 3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base_channel_factory_->CreateChannel( 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_channel_name_, 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ChannelMultiplexer::OnBaseChannelReady, 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::CancelChannelCreation(const std::string& name) { 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::list<PendingChannel>::iterator it = pending_channels_.begin(); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != pending_channels_.end(); ++it) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->name == name) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_channels_.erase(it); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::OnBaseChannelReady( 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::StreamSocket> socket) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_channel_factory_ = NULL; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_channel_ = socket.Pass(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base_channel_.get()) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize reader and writer. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reader_.Init(base_channel_.get(), 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ChannelMultiplexer::OnIncomingPacket, 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) writer_.Init(base_channel_.get(), 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ChannelMultiplexer::OnWriteFailed, 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoCreatePendingChannels(); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::DoCreatePendingChannels() { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_channels_.empty()) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Every time this function is called it connects a single channel and posts a 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // separate task to connect other channels. This is necessary because the 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback may destroy the multiplexer or somehow else modify 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |pending_channels_| list (e.g. call CancelChannelCreation()). 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadTaskRunnerHandle::Get()->PostTask( 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&ChannelMultiplexer::DoCreatePendingChannels, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingChannel c = pending_channels_.front(); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_channels_.erase(pending_channels_.begin()); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::StreamSocket> socket; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base_channel_.get()) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket = GetOrCreateChannel(c.name)->CreateSocket(); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) c.callback.Run(socket.Pass()); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelMultiplexer::MuxChannel* ChannelMultiplexer::GetOrCreateChannel( 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we already have a channel with the requested name. 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, MuxChannel*>::iterator it = channels_.find(name); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != channels_.end()) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return it->second; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a new channel if we haven't found existing one. 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MuxChannel* channel = new MuxChannel(this, name, next_channel_id_); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++next_channel_id_; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels_[channel->name()] = channel; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel; 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::OnWriteFailed(int error) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<std::string, MuxChannel*>::iterator it = channels_.begin(); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != channels_.end(); ++it) { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadTaskRunnerHandle::Get()->PostTask( 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&ChannelMultiplexer::NotifyWriteFailed, 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), it->second->name())); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::NotifyWriteFailed(const std::string& name) { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, MuxChannel*>::iterator it = channels_.find(name); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != channels_.end()) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it->second->OnWriteFailed(); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChannelMultiplexer::OnIncomingPacket(scoped_ptr<MultiplexPacket> packet, 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done_task) { 4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(packet->has_channel_id()); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!packet->has_channel_id()) { 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Received packet without channel_id."; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_task.Run(); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int receive_id = packet->channel_id(); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MuxChannel* channel = NULL; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<int, MuxChannel*>::iterator it = 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels_by_receive_id_.find(receive_id); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != channels_by_receive_id_.end()) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel = it->second; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a new |channel_id| we haven't seen before. Look it up by name. 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!packet->has_channel_name()) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Received packet with unknown channel_id and " 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "without channel_name."; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_task.Run(); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel = GetOrCreateChannel(packet->channel_name()); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel->set_receive_id(receive_id); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channels_by_receive_id_[receive_id] = channel; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel->OnIncomingPacket(packet.Pass(), done_task); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelMultiplexer::DoWrite(scoped_ptr<MultiplexPacket> packet, 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& done_task) { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return writer_.Write(SerializeAndFrameMessage(*packet), done_task); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protocol 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 513