/*
 *  Copyright 2013 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/p2p/base/asyncstuntcpsocket.h"

#include <string.h>

#include "webrtc/p2p/base/stun.h"
#include "webrtc/base/common.h"
#include "webrtc/base/logging.h"

namespace cricket {

static const size_t kMaxPacketSize = 64 * 1024;

typedef uint16 PacketLength;
static const size_t kPacketLenSize = sizeof(PacketLength);
static const size_t kPacketLenOffset = 2;
static const size_t kBufSize = kMaxPacketSize + kStunHeaderSize;
static const size_t kTurnChannelDataHdrSize = 4;

inline bool IsStunMessage(uint16 msg_type) {
  // The first two bits of a channel data message are 0b01.
  return (msg_type & 0xC000) ? false : true;
}

// AsyncStunTCPSocket
// Binds and connects |socket| and creates AsyncTCPSocket for
// it. Takes ownership of |socket|. Returns NULL if bind() or
// connect() fail (|socket| is destroyed in that case).
AsyncStunTCPSocket* AsyncStunTCPSocket::Create(
    rtc::AsyncSocket* socket,
    const rtc::SocketAddress& bind_address,
    const rtc::SocketAddress& remote_address) {
  return new AsyncStunTCPSocket(AsyncTCPSocketBase::ConnectSocket(
      socket, bind_address, remote_address), false);
}

AsyncStunTCPSocket::AsyncStunTCPSocket(
    rtc::AsyncSocket* socket, bool listen)
    : rtc::AsyncTCPSocketBase(socket, listen, kBufSize) {
}

int AsyncStunTCPSocket::Send(const void *pv, size_t cb,
                             const rtc::PacketOptions& options) {
  if (cb > kBufSize || cb < kPacketLenSize + kPacketLenOffset) {
    SetError(EMSGSIZE);
    return -1;
  }

  // If we are blocking on send, then silently drop this packet
  if (!IsOutBufferEmpty())
    return static_cast<int>(cb);

  int pad_bytes;
  size_t expected_pkt_len = GetExpectedLength(pv, cb, &pad_bytes);

  // Accepts only complete STUN/ChannelData packets.
  if (cb != expected_pkt_len)
    return -1;

  AppendToOutBuffer(pv, cb);

  ASSERT(pad_bytes < 4);
  char padding[4] = {0};
  AppendToOutBuffer(padding, pad_bytes);

  int res = FlushOutBuffer();
  if (res <= 0) {
    // drop packet if we made no progress
    ClearOutBuffer();
    return res;
  }

  // We claim to have sent the whole thing, even if we only sent partial
  return static_cast<int>(cb);
}

void AsyncStunTCPSocket::ProcessInput(char* data, size_t* len) {
  rtc::SocketAddress remote_addr(GetRemoteAddress());
  // STUN packet - First 4 bytes. Total header size is 20 bytes.
  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  // |0 0|     STUN Message Type     |         Message Length        |
  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  // TURN ChannelData
  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  // |         Channel Number        |            Length             |
  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

  while (true) {
    // We need at least 4 bytes to read the STUN or ChannelData packet length.
    if (*len < kPacketLenOffset + kPacketLenSize)
      return;

    int pad_bytes;
    size_t expected_pkt_len = GetExpectedLength(data, *len, &pad_bytes);
    size_t actual_length = expected_pkt_len + pad_bytes;

    if (*len < actual_length) {
      return;
    }

    SignalReadPacket(this, data, expected_pkt_len, remote_addr,
                     rtc::CreatePacketTime(0));

    *len -= actual_length;
    if (*len > 0) {
      memmove(data, data + actual_length, *len);
    }
  }
}

void AsyncStunTCPSocket::HandleIncomingConnection(
    rtc::AsyncSocket* socket) {
  SignalNewConnection(this, new AsyncStunTCPSocket(socket, false));
}

size_t AsyncStunTCPSocket::GetExpectedLength(const void* data, size_t len,
                                             int* pad_bytes) {
  *pad_bytes = 0;
  PacketLength pkt_len =
      rtc::GetBE16(static_cast<const char*>(data) + kPacketLenOffset);
  size_t expected_pkt_len;
  uint16 msg_type = rtc::GetBE16(data);
  if (IsStunMessage(msg_type)) {
    // STUN message.
    expected_pkt_len = kStunHeaderSize + pkt_len;
  } else {
    // TURN ChannelData message.
    expected_pkt_len = kTurnChannelDataHdrSize + pkt_len;
    // From RFC 5766 section 11.5
    // Over TCP and TLS-over-TCP, the ChannelData message MUST be padded to
    // a multiple of four bytes in order to ensure the alignment of
    // subsequent messages.  The padding is not reflected in the length
    // field of the ChannelData message, so the actual size of a ChannelData
    // message (including padding) is (4 + Length) rounded up to the nearest
    // multiple of 4.  Over UDP, the padding is not required but MAY be
    // included.
    if (expected_pkt_len % 4)
      *pad_bytes = 4 - (expected_pkt_len % 4);
  }
  return expected_pkt_len;
}

}  // namespace cricket
