1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/renderer_host/p2p/socket_host_tcp.h"
6
7#include "base/sys_byteorder.h"
8#include "content/common/p2p_messages.h"
9#include "ipc/ipc_sender.h"
10#include "jingle/glue/fake_ssl_client_socket.h"
11#include "jingle/glue/proxy_resolving_client_socket.h"
12#include "net/base/io_buffer.h"
13#include "net/base/net_errors.h"
14#include "net/base/net_util.h"
15#include "net/socket/client_socket_factory.h"
16#include "net/socket/client_socket_handle.h"
17#include "net/socket/ssl_client_socket.h"
18#include "net/socket/tcp_client_socket.h"
19#include "net/url_request/url_request_context.h"
20#include "net/url_request/url_request_context_getter.h"
21#include "third_party/libjingle/source/talk/base/asyncpacketsocket.h"
22
23namespace {
24
25typedef uint16 PacketLength;
26const int kPacketHeaderSize = sizeof(PacketLength);
27const int kReadBufferSize = 4096;
28const int kPacketLengthOffset = 2;
29const int kTurnChannelDataHeaderSize = 4;
30const int kRecvSocketBufferSize = 128 * 1024;
31const int kSendSocketBufferSize = 128 * 1024;
32
33bool IsTlsClientSocket(content::P2PSocketType type) {
34  return (type == content::P2P_SOCKET_STUN_TLS_CLIENT ||
35          type == content::P2P_SOCKET_TLS_CLIENT);
36}
37
38bool IsPseudoTlsClientSocket(content::P2PSocketType type) {
39  return (type == content::P2P_SOCKET_SSLTCP_CLIENT ||
40          type == content::P2P_SOCKET_STUN_SSLTCP_CLIENT);
41}
42
43}  // namespace
44
45namespace content {
46
47P2PSocketHostTcpBase::P2PSocketHostTcpBase(
48    IPC::Sender* message_sender,
49    int socket_id,
50    P2PSocketType type,
51    net::URLRequestContextGetter* url_context)
52    : P2PSocketHost(message_sender, socket_id),
53      write_pending_(false),
54      connected_(false),
55      type_(type),
56      url_context_(url_context) {
57}
58
59P2PSocketHostTcpBase::~P2PSocketHostTcpBase() {
60  if (state_ == STATE_OPEN) {
61    DCHECK(socket_.get());
62    socket_.reset();
63  }
64}
65
66bool P2PSocketHostTcpBase::InitAccepted(const net::IPEndPoint& remote_address,
67                                        net::StreamSocket* socket) {
68  DCHECK(socket);
69  DCHECK_EQ(state_, STATE_UNINITIALIZED);
70
71  remote_address_.ip_address = remote_address;
72  // TODO(ronghuawu): Add FakeSSLServerSocket.
73  socket_.reset(socket);
74  state_ = STATE_OPEN;
75  DoRead();
76  return state_ != STATE_ERROR;
77}
78
79bool P2PSocketHostTcpBase::Init(const net::IPEndPoint& local_address,
80                                const P2PHostAndIPEndPoint& remote_address) {
81  DCHECK_EQ(state_, STATE_UNINITIALIZED);
82
83  remote_address_ = remote_address;
84  state_ = STATE_CONNECTING;
85
86  net::HostPortPair dest_host_port_pair =
87      net::HostPortPair::FromIPEndPoint(remote_address.ip_address);
88  // TODO(mallinath) - We are ignoring local_address altogether. We should
89  // find a way to inject this into ProxyResolvingClientSocket. This could be
90  // a problem on multi-homed host.
91
92  // The default SSLConfig is good enough for us for now.
93  const net::SSLConfig ssl_config;
94  socket_.reset(new jingle_glue::ProxyResolvingClientSocket(
95                    NULL,     // Default socket pool provided by the net::Proxy.
96                    url_context_,
97                    ssl_config,
98                    dest_host_port_pair));
99
100  int status = socket_->Connect(
101      base::Bind(&P2PSocketHostTcpBase::OnConnected,
102                 base::Unretained(this)));
103  if (status != net::ERR_IO_PENDING) {
104    // We defer execution of ProcessConnectDone instead of calling it
105    // directly here as the caller may not expect an error/close to
106    // happen here.  This is okay, as from the caller's point of view,
107    // the connect always happens asynchronously.
108    base::MessageLoop* message_loop = base::MessageLoop::current();
109    CHECK(message_loop);
110    message_loop->PostTask(
111        FROM_HERE,
112        base::Bind(&P2PSocketHostTcpBase::OnConnected,
113                   base::Unretained(this), status));
114  }
115
116  return state_ != STATE_ERROR;
117}
118
119void P2PSocketHostTcpBase::OnError() {
120  socket_.reset();
121
122  if (state_ == STATE_UNINITIALIZED || state_ == STATE_CONNECTING ||
123      state_ == STATE_TLS_CONNECTING || state_ == STATE_OPEN) {
124    message_sender_->Send(new P2PMsg_OnError(id_));
125  }
126
127  state_ = STATE_ERROR;
128}
129
130void P2PSocketHostTcpBase::OnConnected(int result) {
131  DCHECK_EQ(state_, STATE_CONNECTING);
132  DCHECK_NE(result, net::ERR_IO_PENDING);
133
134  if (result != net::OK) {
135    OnError();
136    return;
137  }
138
139  if (IsTlsClientSocket(type_)) {
140    state_ = STATE_TLS_CONNECTING;
141    StartTls();
142  } else if (IsPseudoTlsClientSocket(type_)) {
143    scoped_ptr<net::StreamSocket> transport_socket = socket_.Pass();
144    socket_.reset(
145        new jingle_glue::FakeSSLClientSocket(transport_socket.Pass()));
146    state_ = STATE_TLS_CONNECTING;
147    int status = socket_->Connect(
148        base::Bind(&P2PSocketHostTcpBase::ProcessTlsSslConnectDone,
149                   base::Unretained(this)));
150    if (status != net::ERR_IO_PENDING) {
151      ProcessTlsSslConnectDone(status);
152    }
153  } else {
154    // If we are not doing TLS, we are ready to send data now.
155    // In case of TLS, SignalConnect will be sent only after TLS handshake is
156    // successfull. So no buffering will be done at socket handlers if any
157    // packets sent before that by the application.
158    OnOpen();
159  }
160}
161
162void P2PSocketHostTcpBase::StartTls() {
163  DCHECK_EQ(state_, STATE_TLS_CONNECTING);
164  DCHECK(socket_.get());
165
166  scoped_ptr<net::ClientSocketHandle> socket_handle(
167      new net::ClientSocketHandle());
168  socket_handle->SetSocket(socket_.Pass());
169
170  net::SSLClientSocketContext context;
171  context.cert_verifier = url_context_->GetURLRequestContext()->cert_verifier();
172  context.transport_security_state =
173      url_context_->GetURLRequestContext()->transport_security_state();
174  DCHECK(context.transport_security_state);
175
176  // Default ssl config.
177  const net::SSLConfig ssl_config;
178  net::HostPortPair dest_host_port_pair =
179      net::HostPortPair::FromIPEndPoint(remote_address_.ip_address);
180  if (!remote_address_.hostname.empty())
181    dest_host_port_pair.set_host(remote_address_.hostname);
182
183  net::ClientSocketFactory* socket_factory =
184      net::ClientSocketFactory::GetDefaultFactory();
185  DCHECK(socket_factory);
186
187  socket_ = socket_factory->CreateSSLClientSocket(
188      socket_handle.Pass(), dest_host_port_pair, ssl_config, context);
189  int status = socket_->Connect(
190      base::Bind(&P2PSocketHostTcpBase::ProcessTlsSslConnectDone,
191                 base::Unretained(this)));
192  if (status != net::ERR_IO_PENDING) {
193    ProcessTlsSslConnectDone(status);
194  }
195}
196
197void P2PSocketHostTcpBase::ProcessTlsSslConnectDone(int status) {
198  DCHECK_NE(status, net::ERR_IO_PENDING);
199  DCHECK_EQ(state_, STATE_TLS_CONNECTING);
200  if (status != net::OK) {
201    OnError();
202    return;
203  }
204  OnOpen();
205}
206
207void P2PSocketHostTcpBase::OnOpen() {
208  state_ = STATE_OPEN;
209  // Setting socket send and receive buffer size.
210  if (net::OK != socket_->SetReceiveBufferSize(kRecvSocketBufferSize)) {
211    LOG(WARNING) << "Failed to set socket receive buffer size to "
212                 << kRecvSocketBufferSize;
213  }
214
215  if (net::OK != socket_->SetSendBufferSize(kSendSocketBufferSize)) {
216    LOG(WARNING) << "Failed to set socket send buffer size to "
217                 << kSendSocketBufferSize;
218  }
219
220  DoSendSocketCreateMsg();
221  DoRead();
222}
223
224void P2PSocketHostTcpBase::DoSendSocketCreateMsg() {
225  DCHECK(socket_.get());
226
227  net::IPEndPoint address;
228  int result = socket_->GetLocalAddress(&address);
229  if (result < 0) {
230    LOG(ERROR) << "P2PSocketHostTcpBase::OnConnected: unable to get local"
231               << " address: " << result;
232    OnError();
233    return;
234  }
235
236  VLOG(1) << "Local address: " << address.ToString();
237
238  // If we are not doing TLS, we are ready to send data now.
239  // In case of TLS SignalConnect will be sent only after TLS handshake is
240  // successfull. So no buffering will be done at socket handlers if any
241  // packets sent before that by the application.
242  message_sender_->Send(new P2PMsg_OnSocketCreated(id_, address));
243}
244
245void P2PSocketHostTcpBase::DoRead() {
246  int result;
247  do {
248    if (!read_buffer_.get()) {
249      read_buffer_ = new net::GrowableIOBuffer();
250      read_buffer_->SetCapacity(kReadBufferSize);
251    } else if (read_buffer_->RemainingCapacity() < kReadBufferSize) {
252      // Make sure that we always have at least kReadBufferSize of
253      // remaining capacity in the read buffer. Normally all packets
254      // are smaller than kReadBufferSize, so this is not really
255      // required.
256      read_buffer_->SetCapacity(read_buffer_->capacity() + kReadBufferSize -
257                                read_buffer_->RemainingCapacity());
258    }
259    result = socket_->Read(
260        read_buffer_.get(),
261        read_buffer_->RemainingCapacity(),
262        base::Bind(&P2PSocketHostTcp::OnRead, base::Unretained(this)));
263    DidCompleteRead(result);
264  } while (result > 0);
265}
266
267void P2PSocketHostTcpBase::OnRead(int result) {
268  DidCompleteRead(result);
269  if (state_ == STATE_OPEN) {
270    DoRead();
271  }
272}
273
274void P2PSocketHostTcpBase::OnPacket(const std::vector<char>& data) {
275  if (!connected_) {
276    P2PSocketHost::StunMessageType type;
277    bool stun = GetStunPacketType(&*data.begin(), data.size(), &type);
278    if (stun && IsRequestOrResponse(type)) {
279      connected_ = true;
280    } else if (!stun || type == STUN_DATA_INDICATION) {
281      LOG(ERROR) << "Received unexpected data packet from "
282                 << remote_address_.ip_address.ToString()
283                 << " before STUN binding is finished. "
284                 << "Terminating connection.";
285      OnError();
286      return;
287    }
288  }
289
290  message_sender_->Send(new P2PMsg_OnDataReceived(
291      id_, remote_address_.ip_address, data, base::TimeTicks::Now()));
292
293  if (dump_incoming_rtp_packet_)
294    DumpRtpPacket(&data[0], data.size(), true);
295}
296
297// Note: dscp is not actually used on TCP sockets as this point,
298// but may be honored in the future.
299void P2PSocketHostTcpBase::Send(const net::IPEndPoint& to,
300                                const std::vector<char>& data,
301                                const talk_base::PacketOptions& options,
302                                uint64 packet_id) {
303  if (!socket_) {
304    // The Send message may be sent after the an OnError message was
305    // sent by hasn't been processed the renderer.
306    return;
307  }
308
309  if (!(to == remote_address_.ip_address)) {
310    // Renderer should use this socket only to send data to |remote_address_|.
311    NOTREACHED();
312    OnError();
313    return;
314  }
315
316  if (!connected_) {
317    P2PSocketHost::StunMessageType type = P2PSocketHost::StunMessageType();
318    bool stun = GetStunPacketType(&*data.begin(), data.size(), &type);
319    if (!stun || type == STUN_DATA_INDICATION) {
320      LOG(ERROR) << "Page tried to send a data packet to " << to.ToString()
321                 << " before STUN binding is finished.";
322      OnError();
323      return;
324    }
325  }
326
327  DoSend(to, data, options);
328}
329
330void P2PSocketHostTcpBase::WriteOrQueue(
331    scoped_refptr<net::DrainableIOBuffer>& buffer) {
332  if (write_buffer_.get()) {
333    write_queue_.push(buffer);
334    return;
335  }
336
337  write_buffer_ = buffer;
338  DoWrite();
339}
340
341void P2PSocketHostTcpBase::DoWrite() {
342  while (write_buffer_.get() && state_ == STATE_OPEN && !write_pending_) {
343    int result = socket_->Write(
344        write_buffer_.get(),
345        write_buffer_->BytesRemaining(),
346        base::Bind(&P2PSocketHostTcp::OnWritten, base::Unretained(this)));
347    HandleWriteResult(result);
348  }
349}
350
351void P2PSocketHostTcpBase::OnWritten(int result) {
352  DCHECK(write_pending_);
353  DCHECK_NE(result, net::ERR_IO_PENDING);
354
355  write_pending_ = false;
356  HandleWriteResult(result);
357  DoWrite();
358}
359
360void P2PSocketHostTcpBase::HandleWriteResult(int result) {
361  DCHECK(write_buffer_.get());
362  if (result >= 0) {
363    write_buffer_->DidConsume(result);
364    if (write_buffer_->BytesRemaining() == 0) {
365      message_sender_->Send(new P2PMsg_OnSendComplete(id_));
366      if (write_queue_.empty()) {
367        write_buffer_ = NULL;
368      } else {
369        write_buffer_ = write_queue_.front();
370        write_queue_.pop();
371      }
372    }
373  } else if (result == net::ERR_IO_PENDING) {
374    write_pending_ = true;
375  } else {
376    LOG(ERROR) << "Error when sending data in TCP socket: " << result;
377    OnError();
378  }
379}
380
381P2PSocketHost* P2PSocketHostTcpBase::AcceptIncomingTcpConnection(
382    const net::IPEndPoint& remote_address, int id) {
383  NOTREACHED();
384  OnError();
385  return NULL;
386}
387
388void P2PSocketHostTcpBase::DidCompleteRead(int result) {
389  DCHECK_EQ(state_, STATE_OPEN);
390
391  if (result == net::ERR_IO_PENDING) {
392    return;
393  } else if (result < 0) {
394    LOG(ERROR) << "Error when reading from TCP socket: " << result;
395    OnError();
396    return;
397  }
398
399  read_buffer_->set_offset(read_buffer_->offset() + result);
400  char* head = read_buffer_->StartOfBuffer();  // Purely a convenience.
401  int pos = 0;
402  while (pos <= read_buffer_->offset() && state_ == STATE_OPEN) {
403    int consumed = ProcessInput(head + pos, read_buffer_->offset() - pos);
404    if (!consumed)
405      break;
406    pos += consumed;
407  }
408  // We've consumed all complete packets from the buffer; now move any remaining
409  // bytes to the head of the buffer and set offset to reflect this.
410  if (pos && pos <= read_buffer_->offset()) {
411    memmove(head, head + pos, read_buffer_->offset() - pos);
412    read_buffer_->set_offset(read_buffer_->offset() - pos);
413  }
414}
415
416bool P2PSocketHostTcpBase::SetOption(P2PSocketOption option, int value) {
417  DCHECK_EQ(STATE_OPEN, state_);
418  switch (option) {
419    case P2P_SOCKET_OPT_RCVBUF:
420      return socket_->SetReceiveBufferSize(value) == net::OK;
421    case P2P_SOCKET_OPT_SNDBUF:
422      return socket_->SetSendBufferSize(value) == net::OK;
423    case P2P_SOCKET_OPT_DSCP:
424      return false;  // For TCP sockets DSCP setting is not available.
425    default:
426      NOTREACHED();
427      return false;
428  }
429}
430
431P2PSocketHostTcp::P2PSocketHostTcp(IPC::Sender* message_sender,
432                                   int socket_id,
433                                   P2PSocketType type,
434                                   net::URLRequestContextGetter* url_context)
435    : P2PSocketHostTcpBase(message_sender, socket_id, type, url_context) {
436  DCHECK(type == P2P_SOCKET_TCP_CLIENT ||
437         type == P2P_SOCKET_SSLTCP_CLIENT ||
438         type == P2P_SOCKET_TLS_CLIENT);
439}
440
441P2PSocketHostTcp::~P2PSocketHostTcp() {
442}
443
444int P2PSocketHostTcp::ProcessInput(char* input, int input_len) {
445  if (input_len < kPacketHeaderSize)
446    return 0;
447  int packet_size = base::NetToHost16(*reinterpret_cast<uint16*>(input));
448  if (input_len < packet_size + kPacketHeaderSize)
449    return 0;
450
451  int consumed = kPacketHeaderSize;
452  char* cur = input + consumed;
453  std::vector<char> data(cur, cur + packet_size);
454  OnPacket(data);
455  consumed += packet_size;
456  return consumed;
457}
458
459void P2PSocketHostTcp::DoSend(const net::IPEndPoint& to,
460                              const std::vector<char>& data,
461                              const talk_base::PacketOptions& options) {
462  int size = kPacketHeaderSize + data.size();
463  scoped_refptr<net::DrainableIOBuffer> buffer =
464      new net::DrainableIOBuffer(new net::IOBuffer(size), size);
465  *reinterpret_cast<uint16*>(buffer->data()) = base::HostToNet16(data.size());
466  memcpy(buffer->data() + kPacketHeaderSize, &data[0], data.size());
467
468  packet_processing_helpers::ApplyPacketOptions(
469      buffer->data() + kPacketHeaderSize,
470      buffer->BytesRemaining() - kPacketHeaderSize,
471      options, 0);
472
473  WriteOrQueue(buffer);
474}
475
476// P2PSocketHostStunTcp
477P2PSocketHostStunTcp::P2PSocketHostStunTcp(
478    IPC::Sender* message_sender,
479    int socket_id,
480    P2PSocketType type,
481    net::URLRequestContextGetter* url_context)
482    : P2PSocketHostTcpBase(message_sender, socket_id, type, url_context) {
483  DCHECK(type == P2P_SOCKET_STUN_TCP_CLIENT ||
484         type == P2P_SOCKET_STUN_SSLTCP_CLIENT ||
485         type == P2P_SOCKET_STUN_TLS_CLIENT);
486}
487
488P2PSocketHostStunTcp::~P2PSocketHostStunTcp() {
489}
490
491int P2PSocketHostStunTcp::ProcessInput(char* input, int input_len) {
492  if (input_len < kPacketHeaderSize + kPacketLengthOffset)
493    return 0;
494
495  int pad_bytes;
496  int packet_size = GetExpectedPacketSize(
497      input, input_len, &pad_bytes);
498
499  if (input_len < packet_size + pad_bytes)
500    return 0;
501
502  // We have a complete packet. Read through it.
503  int consumed = 0;
504  char* cur = input;
505  std::vector<char> data(cur, cur + packet_size);
506  OnPacket(data);
507  consumed += packet_size;
508  consumed += pad_bytes;
509  return consumed;
510}
511
512void P2PSocketHostStunTcp::DoSend(const net::IPEndPoint& to,
513                                  const std::vector<char>& data,
514                                  const talk_base::PacketOptions& options) {
515  // Each packet is expected to have header (STUN/TURN ChannelData), where
516  // header contains message type and and length of message.
517  if (data.size() < kPacketHeaderSize + kPacketLengthOffset) {
518    NOTREACHED();
519    OnError();
520    return;
521  }
522
523  int pad_bytes;
524  size_t expected_len = GetExpectedPacketSize(
525      &data[0], data.size(), &pad_bytes);
526
527  // Accepts only complete STUN/TURN packets.
528  if (data.size() != expected_len) {
529    NOTREACHED();
530    OnError();
531    return;
532  }
533
534  // Add any pad bytes to the total size.
535  int size = data.size() + pad_bytes;
536
537  scoped_refptr<net::DrainableIOBuffer> buffer =
538      new net::DrainableIOBuffer(new net::IOBuffer(size), size);
539  memcpy(buffer->data(), &data[0], data.size());
540
541  packet_processing_helpers::ApplyPacketOptions(
542      buffer->data(), data.size(), options, 0);
543
544  if (pad_bytes) {
545    char padding[4] = {0};
546    DCHECK_LE(pad_bytes, 4);
547    memcpy(buffer->data() + data.size(), padding, pad_bytes);
548  }
549  WriteOrQueue(buffer);
550
551  if (dump_outgoing_rtp_packet_)
552    DumpRtpPacket(buffer->data(), data.size(), false);
553}
554
555int P2PSocketHostStunTcp::GetExpectedPacketSize(
556    const char* data, int len, int* pad_bytes) {
557  DCHECK_LE(kTurnChannelDataHeaderSize, len);
558  // Both stun and turn had length at offset 2.
559  int packet_size = base::NetToHost16(*reinterpret_cast<const uint16*>(
560      data + kPacketLengthOffset));
561
562  // Get packet type (STUN or TURN).
563  uint16 msg_type = base::NetToHost16(*reinterpret_cast<const uint16*>(data));
564
565  *pad_bytes = 0;
566  // Add heder length to packet length.
567  if ((msg_type & 0xC000) == 0) {
568    packet_size += kStunHeaderSize;
569  } else {
570    packet_size += kTurnChannelDataHeaderSize;
571    // Calculate any padding if present.
572    if (packet_size % 4)
573      *pad_bytes = 4 - packet_size % 4;
574  }
575  return packet_size;
576}
577
578}  // namespace content
579