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