/*
 * libjingle
 * Copyright 2004--2005, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef TALK_P2P_BASE_STUN_H_
#define TALK_P2P_BASE_STUN_H_

// This file contains classes for dealing with the STUN and TURN protocols.
// Both protocols use the same wire format.

#include <string>
#include <vector>

#include "talk/base/basictypes.h"
#include "talk/base/bytebuffer.h"
#include "talk/base/ipaddress.h"

namespace cricket {

// These are the types of STUN & TURN messages as of last check.
enum StunMessageType {
  STUN_BINDING_REQUEST              = 0x0001,
  STUN_BINDING_RESPONSE             = 0x0101,
  STUN_BINDING_ERROR_RESPONSE       = 0x0111,
  STUN_SHARED_SECRET_REQUEST        = 0x0002,
  STUN_SHARED_SECRET_RESPONSE       = 0x0102,
  STUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112,
  STUN_ALLOCATE_REQUEST             = 0x0003,
  STUN_ALLOCATE_RESPONSE            = 0x0103,
  STUN_ALLOCATE_ERROR_RESPONSE      = 0x0113,
  STUN_SEND_REQUEST                 = 0x0004,
  STUN_SEND_RESPONSE                = 0x0104,
  STUN_SEND_ERROR_RESPONSE          = 0x0114,
  STUN_DATA_INDICATION              = 0x0115
};

// These are the types of attributes defined in STUN & TURN.  Next to each is
// the name of the class (T is StunTAttribute) that implements that type.
//
// TODO: Some attributes defined in RFC5389 are not
// implemented yet, particularly REALM, NONCE, SOFTWARE,
// ALTERNATE-SERVE and FINGEPRINT. Implement them.
enum StunAttributeType {
  STUN_ATTR_MAPPED_ADDRESS        = 0x0001, // Address
  STUN_ATTR_USERNAME              = 0x0006, // ByteString, multiple of 4 bytes
  STUN_ATTR_MESSAGE_INTEGRITY     = 0x0008, // ByteString, 20 bytes
  STUN_ATTR_ERROR_CODE            = 0x0009, // ErrorCode
  STUN_ATTR_UNKNOWN_ATTRIBUTES    = 0x000a, // UInt16List
  STUN_ATTR_LIFETIME              = 0x000d, // UInt32
  STUN_ATTR_MAGIC_COOKIE          = 0x000f, // ByteString, 4 bytes
  STUN_ATTR_BANDWIDTH             = 0x0010, // UInt32
  STUN_ATTR_DESTINATION_ADDRESS   = 0x0011, // Address
  STUN_ATTR_SOURCE_ADDRESS2       = 0x0012, // Address
  STUN_ATTR_DATA                  = 0x0013, // ByteString
  STUN_ATTR_XOR_MAPPED_ADDRESS    = 0x0020, // XorAddress
  STUN_ATTR_OPTIONS               = 0x8001  // UInt32
};

enum StunErrorCodes {
  STUN_ERROR_BAD_REQUEST          = 400,
  STUN_ERROR_UNAUTHORIZED         = 401,
  STUN_ERROR_UNKNOWN_ATTRIBUTE    = 420,
  STUN_ERROR_STALE_CREDENTIALS    = 430,
  STUN_ERROR_INTEGRITY_CHECK_FAILURE = 431,
  STUN_ERROR_MISSING_USERNAME     = 432,
  STUN_ERROR_USE_TLS              = 433,
  STUN_ERROR_SERVER_ERROR         = 500,
  STUN_ERROR_GLOBAL_FAILURE       = 600
};

enum StunAddressFamily {
  STUN_ADDRESS_IPV4 = 1,
  STUN_ADDRESS_IPV6 = 2
};

extern const char STUN_ERROR_REASON_BAD_REQUEST[];
extern const char STUN_ERROR_REASON_STALE_CREDENTIALS[];
extern const char STUN_ERROR_REASON_SERVER_ERROR[];

// Following values correspond to RFC5389.
const size_t kStunTransactionIdOffset = 8;
const size_t kStunTransactionIdLength = 12;
const uint32 kStunMagicCookie = 0x2112A442;
const size_t kStunMagicCookieLength = sizeof(kStunMagicCookie);

// Following value corresponds to an earlier version of STUN from
// RFC3489.
const size_t kStunLegacyTransactionIdLength = 16;

class StunAttribute;
class StunAddressAttribute;
class StunUInt32Attribute;
class StunByteStringAttribute;
class StunErrorCodeAttribute;
class StunUInt16ListAttribute;
class StunTransportPrefsAttribute;

// Records a complete STUN/TURN message.  Each message consists of a type and
// any number of attributes.  Each attribute is parsed into an instance of an
// appropriate class (see above).  The Get* methods will return instances of
// that attribute class.
class StunMessage {
public:
  StunMessage();
  ~StunMessage();
  StunMessageType type() const { return static_cast<StunMessageType>(type_); }
  uint16 length() const { return length_; }
  const std::string& transaction_id() const { return transaction_id_; }

  // Returns true if the message confirms to RFC3489 rather than
  // RFC5389. The main difference between two version of the STUN
  // protocol is the presence of the magic cookie and different length
  // of transaction ID. For outgoing packets version of the protocol
  // is determined by the lengths of the transaction ID.
  bool IsLegacy() const;

  void SetType(StunMessageType type) { type_ = type; }
  void SetTransactionID(const std::string& str);

  const StunAddressAttribute* GetAddress(StunAttributeType type) const;
  const StunUInt32Attribute* GetUInt32(StunAttributeType type) const;
  const StunByteStringAttribute* GetByteString(StunAttributeType type) const;
  const StunErrorCodeAttribute* GetErrorCode() const;
  const StunUInt16ListAttribute* GetUnknownAttributes() const;
  const StunTransportPrefsAttribute* GetTransportPrefs() const;

  void AddAttribute(StunAttribute* attr);

  // Parses the STUN/TURN packet in the given buffer and records it here.  The
  // return value indicates whether this was successful.
  bool Read(talk_base::ByteBuffer* buf);

  // Writes this object into a STUN/TURN packet. Return value is true if
  // successful.
  void Write(talk_base::ByteBuffer* buf) const;

private:
  uint16 type_;
  uint16 length_;
  std::string transaction_id_;
  std::vector<StunAttribute*>* attrs_;

  const StunAttribute* GetAttribute(StunAttributeType type) const;
  static bool IsValidTransactionId(const std::string& transaction_id);
};

// Base class for all STUN/TURN attributes.
class StunAttribute {
public:
  virtual ~StunAttribute() {}

  StunAttributeType type() const {
    return static_cast<StunAttributeType>(type_);
  }
  uint16 length() const { return length_; }

  // Reads the body (not the type or length) for this type of attribute from
  // the given buffer.  Return value is true if successful.
  virtual bool Read(talk_base::ByteBuffer* buf) = 0;

  // Writes the body (not the type or length) to the given buffer.  Return
  // value is true if successful.
  virtual void Write(talk_base::ByteBuffer* buf) const = 0;

  // Creates an attribute object with the given type and len.
  static StunAttribute* Create(uint16 type, uint16 length);

  // Creates an attribute object with the given type and smallest length.
  static StunAddressAttribute* CreateAddress(uint16 type);
  static StunUInt32Attribute* CreateUInt32(uint16 type);
  static StunByteStringAttribute* CreateByteString(uint16 type);
  static StunErrorCodeAttribute* CreateErrorCode();
  static StunUInt16ListAttribute* CreateUnknownAttributes();
  static StunTransportPrefsAttribute* CreateTransportPrefs();

protected:
  StunAttribute(uint16 type, uint16 length);

  void SetLength(uint16 length) { length_ = length; }

private:
  uint16 type_;
  uint16 length_;
};

// Implements STUN/TURN attributes that record an Internet address.
// TODO: IPv6 support, and use the SocketAddress class.
class StunAddressAttribute : public StunAttribute {
public:
  explicit StunAddressAttribute(uint16 type);

  static const uint16 SIZE = 8;

  StunAddressFamily family() const { return family_; }
  uint16 port() const { return port_; }
  talk_base::IPAddress ipaddr() const { return ip_; }

  void SetFamily(StunAddressFamily family);
  void SetIP(const talk_base::IPAddress& ip) { ip_ = ip; }
  void SetPort(uint16 port) { port_ = port; }

  virtual bool Read(talk_base::ByteBuffer* buf);
  virtual void Write(talk_base::ByteBuffer* buf) const;

private:
  StunAddressFamily family_;
  uint16 port_;
  talk_base::IPAddress ip_;
};

// Implements STUN/TURN attributes that record an Internet address.
class StunXorAddressAttribute : public StunAddressAttribute {
public:
  explicit StunXorAddressAttribute(uint16 type);

  virtual bool Read(talk_base::ByteBuffer* buf);
  virtual void Write(talk_base::ByteBuffer* buf) const;
};

// Implements STUN/TURN attributs that record a 32-bit integer.
class StunUInt32Attribute : public StunAttribute {
public:
  explicit StunUInt32Attribute(uint16 type);

  static const uint16 SIZE = 4;

  uint32 value() const { return bits_; }

  void SetValue(uint32 bits) { bits_ = bits; }

  bool GetBit(int index) const;
  void SetBit(int index, bool value);

  bool Read(talk_base::ByteBuffer* buf);
  void Write(talk_base::ByteBuffer* buf) const;

private:
  uint32 bits_;
};

// Implements STUN/TURN attributs that record an arbitrary byte string
class StunByteStringAttribute : public StunAttribute {
public:
  StunByteStringAttribute(uint16 type, uint16 length);
  ~StunByteStringAttribute();

  const char* bytes() const { return bytes_; }

  void SetBytes(char* bytes, uint16 length);

  void CopyBytes(const char* bytes); // uses strlen
  void CopyBytes(const void* bytes, uint16 length);

  uint8 GetByte(int index) const;
  void SetByte(int index, uint8 value);

  bool Read(talk_base::ByteBuffer* buf);
  void Write(talk_base::ByteBuffer* buf) const;

private:
  char* bytes_;
};

// Implements STUN/TURN attributs that record an error code.
class StunErrorCodeAttribute : public StunAttribute {
public:
  StunErrorCodeAttribute(uint16 type, uint16 length);
  ~StunErrorCodeAttribute();

  static const uint16 MIN_SIZE = 4;

  uint32 error_code() const { return (class_ << 8) | number_; }
  uint8 error_class() const { return class_; }
  uint8 number() const { return number_; }
  const std::string& reason() const { return reason_; }

  void SetErrorCode(uint32 code);
  void SetErrorClass(uint8 eclass) { class_ = eclass; }
  void SetNumber(uint8 number) { number_ = number; }
  void SetReason(const std::string& reason);

  bool Read(talk_base::ByteBuffer* buf);
  void Write(talk_base::ByteBuffer* buf) const;

private:
  uint8 class_;
  uint8 number_;
  std::string reason_;
};

// Implements STUN/TURN attributs that record a list of attribute names.
class StunUInt16ListAttribute : public StunAttribute {
public:
  StunUInt16ListAttribute(uint16 type, uint16 length);
  ~StunUInt16ListAttribute();

  size_t Size() const;
  uint16 GetType(int index) const;
  void SetType(int index, uint16 value);
  void AddType(uint16 value);

  bool Read(talk_base::ByteBuffer* buf);
  void Write(talk_base::ByteBuffer* buf) const;

private:
  std::vector<uint16>* attr_types_;
};

// The special MAGIC-COOKIE attribute is used to distinguish TURN packets from
// other kinds of traffic.
// TODO: This value has nothing to do with STUN. Move it to a
// separate file.
extern const char TURN_MAGIC_COOKIE_VALUE[4];

// Returns the (successful) response type for the given request type.
StunMessageType GetStunResponseType(StunMessageType request_type);

// Returns the error response type for the given request type.
StunMessageType GetStunErrorResponseType(StunMessageType request_type);

} // namespace cricket

#endif  // TALK_P2P_BASE_STUN_H_
