TURN episode #1

This commit is contained in:
bossiel 2014-05-01 05:01:53 +00:00
parent f05c0705dd
commit 4a687f2b23
32 changed files with 4374 additions and 3039 deletions

View File

@ -126,8 +126,7 @@ tnet_stun_response_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO,
tsk_buffer_t *buffer = tnet_stun_message_serialize(message);
tnet_stun_response_t *response = tsk_null;
if(!buffer)
{
if(!buffer) {
goto bail;
}
@ -256,8 +255,7 @@ int tnet_stun_send_bind(const tnet_nat_context_t* context, tnet_stun_binding_t *
In other words, the very first request is sent as if there were no
authentication or message integrity applied.
*/
stun_phase0:
{
stun_phase0: {
if(!(request = tnet_stun_create_request(binding))) {
goto bail;
}
@ -431,8 +429,7 @@ static tsk_object_t* tnet_stun_binding_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_binding_def_s =
{
static const tsk_object_def_t tnet_stun_binding_def_s = {
sizeof(tnet_stun_binding_t),
tnet_stun_binding_ctor,
tnet_stun_binding_dtor,

View File

@ -77,8 +77,7 @@ typedef uint64_t tnet_stun_binding_id_t;
/**@ingroup tnet_stun_group
* STUN2 binding context.
**/
typedef struct tnet_stun_binding_s
{
typedef struct tnet_stun_binding_s {
TSK_DECLARE_OBJECT;
//! A unique id to identify this binding.

View File

@ -0,0 +1,406 @@
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#include "stun/tnet_stun_attr.h"
#include "stun/tnet_stun_utils.h"
#include "tnet_endianness.h"
#include "tsk_memory.h"
#include "tsk_debug.h"
#define kWithoutPadding tsk_false
#define kWithPadding tsk_true
#define ALIGN_ON_32BITS(size_in_octes) if (((size_in_octes) & 3)) (size_in_octes) += (4 - ((size_in_octes) & 3));
#define ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(p_buffer, size_in_octes) \
if (((size_in_octes) & 3)) { \
int c = (4 - ((size_in_octes) & 3)); \
memset(p_buffer, 0, c); \
(size_in_octes) += c; \
}
#define IS_XOR(e_type) \
(e_type == tnet_stun_attr_type_xor_mapped_address || e_type == tnet_stun_attr_type_xor_peer_address || e_type == tnet_stun_attr_type_xor_relayed_address)
static int _tnet_stun_attr_cmp(const tsk_object_t *_att1, const tsk_object_t *_att2)
{
const tnet_stun_attr_t *pc_att1 = (const tnet_stun_attr_t *)_att1;
const tnet_stun_attr_t *pc_att2 = (const tnet_stun_attr_t *)_att2;
return (int)(pc_att1 - pc_att2);
}
static int _tnet_stun_attr_get_size_in_octetunits(const tnet_stun_attr_t* pc_self, tsk_bool_t with_padding, tsk_size_t* p_size)
{
if (!pc_self || !p_size) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
switch (pc_self->hdr.e_type) {
case tnet_stun_attr_type_mapped_address:
case tnet_stun_attr_type_xor_mapped_address:
case tnet_stun_attr_type_xor_peer_address:
case tnet_stun_attr_type_xor_relayed_address: {
extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
const tnet_stun_attr_address_t* _pc_self = (const tnet_stun_attr_address_t*)pc_self;
if (pc_self->__def__ != tnet_stun_attr_address_def_t) {
TSK_DEBUG_ERROR("Invalid base type");
return -2;
}
*p_size = (kStunAttrHdrSizeInOctets + 1/*Ignored*/ + 1/*Family*/ + 2/*Port*/ + ((_pc_self->e_family == tnet_stun_address_family_ipv6) ? 16 : 4));
if (with_padding) {
ALIGN_ON_32BITS(*p_size);
}
return 0;
}
case tnet_stun_attr_type_username:
case tnet_stun_attr_type_password: {
extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
const tnet_stun_attr_vdata_t* _pc_self = (const tnet_stun_attr_vdata_t*)pc_self;
if (pc_self->__def__ != tnet_stun_attr_vdata_def_t) {
TSK_DEBUG_ERROR("Invalid base type");
return -2;
}
*p_size = (kStunAttrHdrSizeInOctets + _pc_self->u_data_size);
if (with_padding) {
ALIGN_ON_32BITS(*p_size);
}
return 0;
}
default: {
TSK_DEBUG_WARN("Attribute type=%d is unknown. Don't be surprised if something goes wrong.", pc_self->hdr.e_type);
*p_size = (kStunAttrHdrSizeInOctets + pc_self->hdr.u_length);
if (with_padding) {
ALIGN_ON_32BITS(*p_size);
}
return 0;
}
}
}
static int _tnet_stun_attr_write(const tnet_stun_transac_id_t* pc_transac_id, const tnet_stun_attr_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t with_padding, tsk_size_t *p_written)
{
tsk_size_t n_min_req_size;
int ret;
if (!pc_self || !p_buff_ptr || !n_buff_size || !p_written) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if ((ret = _tnet_stun_attr_get_size_in_octetunits(pc_self, with_padding, &n_min_req_size))) {
return ret;
}
if (n_min_req_size > n_buff_size) {
TSK_DEBUG_ERROR("Buffer too short %u<%u", n_buff_size, n_min_req_size);
return -2;
}
*((uint16_t*)&p_buff_ptr[0]) = tnet_htons((unsigned short)pc_self->hdr.e_type);
// *((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)pc_self->hdr.u_length);
*p_written = kStunAttrHdrSizeInOctets;
switch (pc_self->hdr.e_type) {
case tnet_stun_attr_type_mapped_address:
case tnet_stun_attr_type_xor_mapped_address:
case tnet_stun_attr_type_xor_peer_address:
case tnet_stun_attr_type_xor_relayed_address: {
tsk_size_t u_addr_size;
extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
const tnet_stun_attr_address_t* _pc_self = (const tnet_stun_attr_address_t*)pc_self;
tsk_bool_t b_xor = IS_XOR(pc_self->hdr.e_type);
if (pc_self->__def__ != tnet_stun_attr_address_def_t) {
TSK_DEBUG_ERROR("Invalid base type");
return -2;
}
p_buff_ptr[*p_written] = 0x00; // Reserved
p_buff_ptr[*p_written + 1] = _pc_self->e_family;
u_addr_size = (_pc_self->e_family == tnet_stun_address_family_ipv6 ? 16 : 4);
if (b_xor) {
tsk_size_t u;
*((uint16_t*)&p_buff_ptr[*p_written + 2]) = tnet_htons(_pc_self->u_port ^ kStunMagicCookieShort);
*((uint32_t*)&p_buff_ptr[*p_written + 4]) = tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[0])) ^ kStunMagicCookieLong);
for (u = 4; u < u_addr_size; u+=4) {
if (pc_transac_id) {
*((uint32_t*)&p_buff_ptr[*p_written + 4 + u]) = tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[u])) ^ tnet_ntohl(*((uint32_t*)(*pc_transac_id + u - 4))));
}
else {
*((uint32_t*)&p_buff_ptr[*p_written + 4 + u]) = tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[u])) ^ 0);
}
}
}
else {
*((uint16_t*)&p_buff_ptr[*p_written + 2]) = tnet_htons(_pc_self->u_port);
memcpy(&p_buff_ptr[*p_written + 4], _pc_self->address, u_addr_size);
}
*p_written += 4 + u_addr_size;
*((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)*p_written - kStunAttrHdrSizeInOctets);
if (with_padding) {
ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(&p_buff_ptr[*p_written], *p_written);
}
return 0;
}
case tnet_stun_attr_type_username:
case tnet_stun_attr_type_password: {
extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
const tnet_stun_attr_vdata_t* _pc_self = (const tnet_stun_attr_vdata_t*)pc_self;
if (pc_self->__def__ != tnet_stun_attr_vdata_def_t) {
TSK_DEBUG_ERROR("Invalid base type");
return -2;
}
if (_pc_self->p_data_ptr && _pc_self->u_data_size) {
memcpy(&p_buff_ptr[*p_written], _pc_self->p_data_ptr, _pc_self->u_data_size);
*p_written += _pc_self->u_data_size;
}
*((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)*p_written - kStunAttrHdrSizeInOctets);
if (with_padding) {
ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(&p_buff_ptr[*p_written], *p_written);
}
return 0;
}
default: {
TSK_DEBUG_ERROR("Attribute type=%d is unknown.", pc_self->hdr.e_type);
return -2;
}
}
}
int tnet_stun_attr_init(tnet_stun_attr_t* p_self, tnet_stun_attr_type_t e_type, uint16_t u_length)
{
if (!p_self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
p_self->hdr.e_type = e_type;
p_self->hdr.u_length = u_length;
return 0;
}
int tnet_stun_attr_get_size_in_octetunits_without_padding(const tnet_stun_attr_t* pc_self, tsk_size_t* p_size)
{
return _tnet_stun_attr_get_size_in_octetunits(pc_self, kWithoutPadding, p_size);
}
int tnet_stun_attr_get_size_in_octetunits_with_padding(const tnet_stun_attr_t* pc_self, tsk_size_t* p_size)
{
return _tnet_stun_attr_get_size_in_octetunits(pc_self, kWithPadding, p_size);
}
int tnet_stun_attr_write_without_padding(const tnet_stun_transac_id_t* pc_transac_id, const tnet_stun_attr_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written)
{
return _tnet_stun_attr_write(pc_transac_id, pc_self, p_buff_ptr, n_buff_size, kWithoutPadding, p_written);
}
int tnet_stun_attr_write_with_padding(const tnet_stun_transac_id_t* pc_transac_id, const tnet_stun_attr_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written)
{
return _tnet_stun_attr_write(pc_transac_id, pc_self, p_buff_ptr, n_buff_size, kWithPadding, p_written);
}
int tnet_stun_attr_read(const tnet_stun_transac_id_t* pc_transac_id, const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_consumed_octets, tnet_stun_attr_t** pp_attr)
{
tnet_stun_attr_type_t Type;
uint16_t Length, PadLength;
int ret = -1;
static const void* kNullBuffPtr = tsk_null;
static const tsk_size_t kNullBuffSize = 0;
if (!pc_buff_ptr || !n_buff_size || !pp_attr || !p_consumed_octets) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (n_buff_size < kStunAttrHdrSizeInOctets) {
TSK_DEBUG_ERROR("Buffer too short(%u)", n_buff_size);
return -2;
}
Type = tnet_ntohs_2(&pc_buff_ptr[0]);
Length = tnet_ntohs_2(&pc_buff_ptr[2]);
if (Length > n_buff_size) {
TSK_DEBUG_ERROR("Buffer too short(%u). Length=%u", n_buff_size, Length);
return -3;
}
PadLength = (Length & 0x03) ? (4 - (Length & 0x03)) : 0;
*pp_attr = tsk_null;
*p_consumed_octets = kStunAttrHdrSizeInOctets + Length + PadLength;
switch (Type) {
case tnet_stun_attr_type_mapped_address:
case tnet_stun_attr_type_xor_mapped_address:
case tnet_stun_attr_type_xor_peer_address:
case tnet_stun_attr_type_xor_relayed_address: {
// First 8bits must be ignored
tnet_stun_address_family_t e_family = pc_buff_ptr[5];
uint16_t u_port = tnet_ntohs_2(&pc_buff_ptr[6]);
tnet_stun_attr_address_t* p_attr;
tsk_bool_t b_xor = IS_XOR(Type);
uint16_t u, u_addr_size = (e_family == tnet_stun_address_family_ipv6) ? 16 : 4;
if (b_xor) {
u_port ^= kStunMagicCookieShort;
}
if ((ret = tnet_stun_attr_address_create(Type, e_family, u_port, kNullBuffPtr, &p_attr))) {
return ret;
}
if (b_xor) {
*((uint32_t*)&p_attr->address[0]) = tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8]) ^ kStunMagicCookieLong);
for (u = 4; u < u_addr_size; u+=4) {
if (pc_transac_id) {
*((uint32_t*)&p_attr->address[u]) = tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8 + u]) ^ tnet_ntohl_2(((uint32_t*)(*pc_transac_id + u - 4))));
}
else {
*((uint32_t*)&p_attr->address[u]) = tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8 + u]) ^ 0);
}
}
}
else {
memcpy(p_attr->address, &pc_buff_ptr[8], u_addr_size);
}
*pp_attr = TNET_STUN_ATTR(p_attr);
break;
}
case tnet_stun_attr_type_username:
case tnet_stun_attr_type_password:
default: {
tnet_stun_attr_vdata_t* p_attr;
if ((ret = tnet_stun_attr_vdata_create(Type, &pc_buff_ptr[4], Length, &p_attr))) {
return ret;
}
*pp_attr = TNET_STUN_ATTR(p_attr);
break;
}
}
return ret;
}
// ============== VDATA (USERNAME, MESSAGE-INTEGRITY, ...) ================ //
int tnet_stun_attr_vdata_create(tnet_stun_attr_type_t e_type, const uint8_t* pc_data_ptr, uint16_t u_data_size, tnet_stun_attr_vdata_t** pp_attr)
{
int ret = -1;
uint16_t u_length = pc_data_ptr ? u_data_size : 0;
tnet_stun_attr_vdata_t* p_attr = tsk_null;
extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
if (!pp_attr) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (!(p_attr = tsk_object_new(tnet_stun_attr_vdata_def_t))) {
ret = -2;
goto bail;
}
if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), e_type, u_length))) {
goto bail;
}
if (u_length) {
if (!(p_attr->p_data_ptr = tsk_malloc(u_length))) {
ret = -3;
goto bail;
}
memcpy(p_attr->p_data_ptr, pc_data_ptr, u_length);
p_attr->u_data_size = u_length;
}
bail:
if (ret) {
TSK_OBJECT_SAFE_FREE(p_attr);
}
return ret;
}
static tsk_object_t* tnet_stun_attr_vdata_ctor(tsk_object_t * self, va_list * app)
{
tnet_stun_attr_vdata_t *p_vdata = (tnet_stun_attr_vdata_t *)self;
if (p_vdata) {
}
return self;
}
static tsk_object_t* tnet_stun_attr_vdata_dtor(tsk_object_t * self)
{
tnet_stun_attr_vdata_t *p_vdata = (tnet_stun_attr_vdata_t *)self;
if (p_vdata) {
TSK_DEBUG_INFO("*** STUN Attribute(VDATA) destroyed ***");
TSK_FREE(p_vdata->p_data_ptr);
}
return self;
}
static const tsk_object_def_t tnet_stun_attr_vdata_def_s = {
sizeof(tnet_stun_attr_vdata_t),
tnet_stun_attr_vdata_ctor,
tnet_stun_attr_vdata_dtor,
_tnet_stun_attr_cmp,
};
const tsk_object_def_t *tnet_stun_attr_vdata_def_t = &tnet_stun_attr_vdata_def_s;
// ============== ADDRESS ================ //
int tnet_stun_attr_address_create(tnet_stun_attr_type_t e_type, tnet_stun_address_family_t e_family, uint16_t u_port, const tnet_stun_addr_t* pc_addr, tnet_stun_attr_address_t** pp_attr)
{
int ret = - 1;
extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
tnet_stun_attr_address_t* p_attr = tsk_null;
uint16_t u_length = (e_family == tnet_stun_address_family_ipv6) ? 16 : 4;
if (!pp_attr) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (!(p_attr = tsk_object_new(tnet_stun_attr_address_def_t))) {
ret = -2;
goto bail;
}
if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), e_type, u_length))) {
goto bail;
}
p_attr->e_family = e_family;
p_attr->u_port = u_port;
if (pc_addr) {
memcpy(p_attr->address, *pc_addr, u_length);
}
*pp_attr = p_attr;
bail:
if (ret) {
TSK_OBJECT_SAFE_FREE(p_attr);
}
return ret;
}
static tsk_object_t* tnet_stun_attr_address_ctor(tsk_object_t * self, va_list * app)
{
tnet_stun_attr_address_t *p_addr = (tnet_stun_attr_address_t *)self;
if (p_addr) {
}
return self;
}
static tsk_object_t* tnet_stun_attr_address_dtor(tsk_object_t * self)
{
tnet_stun_attr_address_t *p_addr = (tnet_stun_attr_address_t *)self;
if (p_addr) {
TSK_DEBUG_INFO("*** STUN Attribute(ADDRESS) destroyed ***");
}
return self;
}
static const tsk_object_def_t tnet_stun_attr_address_def_s = {
sizeof(tnet_stun_attr_address_t),
tnet_stun_attr_address_ctor,
tnet_stun_attr_address_dtor,
_tnet_stun_attr_cmp,
};
const tsk_object_def_t *tnet_stun_attr_address_def_t = &tnet_stun_attr_address_def_s;

View File

@ -0,0 +1,72 @@
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#ifndef TNET_STUN_ATTR_H
#define TNET_STUN_ATTR_H
#include "tinynet_config.h"
#include "stun/tnet_stun_types.h"
#include "tsk_object.h"
#include "tsk_list.h"
TNET_BEGIN_DECLS
// rfc5389 - 15. STUN Attributes
typedef struct tnet_stun_attr_hdr_xs {
enum tnet_stun_attr_type_e e_type; // 16bits
uint16_t u_length; // 16bits prior to padding, measured in bytes (WITHOUT header)
} tnet_stun_attr_hdr_xt;
typedef struct tnet_stun_attr_s {
TSK_DECLARE_OBJECT;
struct tnet_stun_attr_s* pc_base;
struct tnet_stun_attr_hdr_xs hdr;
} tnet_stun_attr_t;
#define TNET_STUN_DECLARE_ATTR struct tnet_stun_attr_s __base__
#define TNET_STUN_ATTR(p_self) ((struct tnet_stun_attr_s*)(p_self))
typedef tsk_list_t tnet_stun_attrs_L_t;
int tnet_stun_attr_init(struct tnet_stun_attr_s* p_self, enum tnet_stun_attr_type_e e_type, uint16_t u_length);
TINYNET_API int tnet_stun_attr_get_size_in_octetunits_without_padding(const struct tnet_stun_attr_s* pc_self, tsk_size_t* p_size);
TINYNET_API int tnet_stun_attr_get_size_in_octetunits_with_padding(const struct tnet_stun_attr_s* pc_self, tsk_size_t* p_size);
TINYNET_API int tnet_stun_attr_write_without_padding(const tnet_stun_transac_id_t* pc_transac_id, const struct tnet_stun_attr_s* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written);
TINYNET_API int tnet_stun_attr_write_with_padding(const tnet_stun_transac_id_t* pc_transac_id, const struct tnet_stun_attr_s* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written);
TINYNET_API int tnet_stun_attr_read(const tnet_stun_transac_id_t* pc_transac_id, const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_consumed_octets, struct tnet_stun_attr_s** pp_attr);
// ============== VDATA (USERNAME, MESSAGE-INTEGRITY, ...) ================ //
typedef struct tnet_stun_attr_vdata_s {
TNET_STUN_DECLARE_ATTR;
uint8_t *p_data_ptr;
uint16_t u_data_size;
} tnet_stun_attr_vdata_t;
int tnet_stun_attr_vdata_create(enum tnet_stun_attr_type_e e_type, const uint8_t* pc_data_ptr, uint16_t u_data_size, struct tnet_stun_attr_vdata_s** pp_attr);
// ============== ADDRESS ================ //
typedef struct tnet_stun_attr_address_s {
TNET_STUN_DECLARE_ATTR;
enum tnet_stun_address_family e_family; // 8bits
uint16_t u_port; // 16bits
tnet_stun_addr_t address; // always in network byte order. Use tnet_stun_utils_inet_pton()
} tnet_stun_attr_address_t;
int tnet_stun_attr_address_create(enum tnet_stun_attr_type_e e_type, enum tnet_stun_address_family e_family, uint16_t u_port, const tnet_stun_addr_t* pc_addr, struct tnet_stun_attr_address_s** pp_attr);
TNET_END_DECLS
#endif /* TNET_STUN_ATTR_H */

View File

@ -199,8 +199,7 @@ tnet_stun_attribute_t* tnet_stun_attribute_deserialize(const void* data, tsk_siz
uint16_t length = tnet_ntohs_2(&dataPtr[2]);
/* Check validity */
if(!data || size<=4/* Type(2-bytes) plus Length (2-bytes) */)
{
if(!data || size<=4/* Type(2-bytes) plus Length (2-bytes) */) {
return 0;
}
@ -209,33 +208,28 @@ tnet_stun_attribute_t* tnet_stun_attribute_deserialize(const void* data, tsk_siz
/* Attribute Value
*/
switch(type)
{
switch(type) {
/* RFC 5389 - 15.1. MAPPED-ADDRESS */
case stun_mapped_address:
{
case stun_mapped_address: {
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_mapped_address_create(dataPtr, length);
break;
}
/* RFC 5389 - 15.2. XOR-MAPPED-ADDRESS*/
case stun_xor_mapped_address:
{
case stun_xor_mapped_address: {
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_xmapped_address_create(dataPtr, length);
break;
}
/* RFC 5389 - 15.3. USERNAME*/
case stun_username:
{
case stun_username: {
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_username_create(dataPtr, length);
break;
}
/* RFC 5389 - MESSAGE-INTEGRITY*/
case stun_message_integrity:
{
case stun_message_integrity: {
if(length == TSK_SHA1_DIGEST_SIZE) {
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_integrity_create(dataPtr, length);
}
@ -243,52 +237,45 @@ tnet_stun_attribute_t* tnet_stun_attribute_deserialize(const void* data, tsk_siz
}
/* RFC 5389 - 15.5. FINGERPRINT*/
case stun_fingerprint:
{
case stun_fingerprint: {
uint32_t fingerprint = tnet_htonl_2(dataPtr);
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_fingerprint_create(fingerprint);
break;
}
/* RFC 5389 - 15.6. ERROR-CODE*/
case stun_error_code:
{
case stun_error_code: {
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_errorcode_create(dataPtr, length);
break;
}
/* RFC 5389 - 15.7. REALM*/
case stun_realm:
{
case stun_realm: {
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_realm_create(dataPtr, length);
break;
}
/* RFC 5389 - 15.8. NONCE*/
case stun_nonce:
{
case stun_nonce: {
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_nonce_create(dataPtr, length);
break;
}
/* RFC 5389 - 15.9. UNKNOWN-ATTRIBUTES*/
case stun_unknown_attributes:
{
case stun_unknown_attributes: {
TSK_DEBUG_ERROR("DESERIALIZE:UNKNOWN-ATTRIBUTES ==> NOT IMPLEMENTED");
attribute = tnet_stun_attribute_create();
break;
}
/* RFC 5389 - 15.10. SOFTWARE */
case stun_software:
{
case stun_software: {
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_software_create(dataPtr, length);
break;
}
/* RFC 5389 - 15.11. ALTERNATE-SERVER */
case stun_alternate_server:
{
case stun_alternate_server: {
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_altserver_create(dataPtr, length);
break;
}
@ -304,15 +291,13 @@ tnet_stun_attribute_t* tnet_stun_attribute_deserialize(const void* data, tsk_siz
case stun_requested_transport:
case stun_dont_fragment:
case stun_reserved3:
case stun_reservation_token:
{
case stun_reservation_token: {
attribute = tnet_turn_attribute_deserialize(type, length, dataPtr, length);
break;
}
/* RFC 5245 - 19.1. PRIORITY */
case stun_ice_priority:
{
case stun_ice_priority: {
if(length >= 4) {
uint32_t value = dataPtr[0] << 24 | dataPtr[1] << 16 | dataPtr[2] << 8 | dataPtr[3];
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_ice_priority_create(value);
@ -320,14 +305,12 @@ tnet_stun_attribute_t* tnet_stun_attribute_deserialize(const void* data, tsk_siz
break;
}
/* RFC 5245 - 19.1. USE_CANDIDATE */
case stun_ice_use_candidate:
{
case stun_ice_use_candidate: {
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_ice_use_candidate_create();
break;
}
/* RFC 5245 - 19.1. ICE_CONTROLLED*/
case stun_ice_controlled:
{
case stun_ice_controlled: {
if(length >= 8) {
uint64_t value = ((((uint64_t)dataPtr[0]) << 56) | (((uint64_t)dataPtr[1]) << 48) | (((uint64_t)dataPtr[2]) << 40) | (((uint64_t)dataPtr[3]) << 32) | (((uint64_t)dataPtr[4]) << 24) | (((uint64_t)dataPtr[5]) << 16) | ((uint64_t)dataPtr[6]) << 8 | ((uint64_t)dataPtr[7]));
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_ice_controlled_create(value);
@ -335,8 +318,7 @@ tnet_stun_attribute_t* tnet_stun_attribute_deserialize(const void* data, tsk_siz
break;
}
/* RFC 5245 - 19.1. ICE_CONTROLLING*/
case stun_ice_controlling:
{
case stun_ice_controlling: {
if(length >= 8) {
uint64_t value = ((((uint64_t)dataPtr[0]) << 56) | (((uint64_t)dataPtr[1]) << 48) | (((uint64_t)dataPtr[2]) << 40) | (((uint64_t)dataPtr[3]) << 32) | (((uint64_t)dataPtr[4]) << 24) | (((uint64_t)dataPtr[5]) << 16) | ((uint64_t)dataPtr[6]) << 8 | ((uint64_t)dataPtr[7]));
attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_ice_controlling_create(value);
@ -393,8 +375,7 @@ int tnet_stun_attribute_serialize(const tnet_stun_attribute_t* attribute, tsk_bu
switch(attribute->type) {
/* RFC 5389 - 15.1. MAPPED-ADDRESS */
case stun_mapped_address:
{
case stun_mapped_address: {
uint32_t u32 = 0;
tnet_stun_attribute_mapped_addr_t* ma = (tnet_stun_attribute_mapped_addr_t*)attribute;
tsk_size_t addr_size, i;
@ -415,8 +396,7 @@ int tnet_stun_attribute_serialize(const tnet_stun_attribute_t* attribute, tsk_bu
}
/* RFC 5389 - 15.2. XOR-MAPPED-ADDRESS*/
case stun_xor_mapped_address:
{
case stun_xor_mapped_address: {
uint32_t u32 = 0;
tnet_stun_attribute_xmapped_addr_t* xma = (tnet_stun_attribute_xmapped_addr_t*)attribute;
tsk_size_t addr_size, i;
@ -436,8 +416,7 @@ int tnet_stun_attribute_serialize(const tnet_stun_attribute_t* attribute, tsk_bu
}
/* RFC 5389 - 15.3. USERNAME*/
case stun_username:
{
case stun_username: {
tnet_stun_attribute_username_t *username = (tnet_stun_attribute_username_t*)attribute;
tsk_buffer_append(output, username->value, tsk_strlen(username->value));
return 0;
@ -445,24 +424,21 @@ int tnet_stun_attribute_serialize(const tnet_stun_attribute_t* attribute, tsk_bu
/* RFC 5389 - MESSAGE-INTEGRITY*/
case stun_message_integrity:
{
case stun_message_integrity: {
tnet_stun_attribute_integrity_t *integrity = (tnet_stun_attribute_integrity_t*)attribute;
tsk_buffer_append(output, integrity->sha1digest, TSK_SHA1_DIGEST_SIZE);
return 0;
}
/* RFC 5389 - 15.5. FINGERPRINT*/
case stun_fingerprint:
{
case stun_fingerprint: {
uint32_t fingerprint = /*tnet_htonl*/(((tnet_stun_attribute_fingerprint_t*)attribute)->value);
tsk_buffer_append(output, &fingerprint, 4);
return 0;
}
/* RFC 5389 - 15.6. ERROR-CODE*/
case stun_error_code:
{
case stun_error_code: {
uint32_t u32 = 0;
tnet_stun_attribute_errorcode_t *errorcode = (tnet_stun_attribute_errorcode_t*)attribute;
u32 |= (errorcode->_class & 0x07) << 8;
@ -474,39 +450,34 @@ int tnet_stun_attribute_serialize(const tnet_stun_attribute_t* attribute, tsk_bu
}
/* RFC 5389 - 15.7. REALM*/
case stun_realm:
{
case stun_realm: {
tnet_stun_attribute_realm_t *realm = (tnet_stun_attribute_realm_t*)attribute;
tsk_buffer_append(output, realm->value, tsk_strlen(realm->value));
return 0;
}
/* RFC 5389 - 15.8. NONCE*/
case stun_nonce:
{
case stun_nonce: {
tnet_stun_attribute_nonce_t *nonce = (tnet_stun_attribute_nonce_t*)attribute;
tsk_buffer_append(output, nonce->value, tsk_strlen(nonce->value));
return 0;
}
/* RFC 5389 - 15.9. UNKNOWN-ATTRIBUTES*/
case stun_unknown_attributes:
{
case stun_unknown_attributes: {
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
return -3;
}
/* RFC 5389 - 15.10. SOFTWARE */
case stun_software:
{
case stun_software: {
tnet_stun_attribute_software_t *software = (tnet_stun_attribute_software_t*)attribute;
tsk_buffer_append(output, software->value, tsk_strlen(software->value));
return 0;
}
/* RFC 5389 - 15.11. ALTERNATE-SERVER */
case stun_alternate_server:
{
case stun_alternate_server: {
TSK_DEBUG_ERROR("NOT IMPLEMENTED");
return -3;
}
@ -521,36 +492,31 @@ int tnet_stun_attribute_serialize(const tnet_stun_attribute_t* attribute, tsk_bu
case stun_requested_transport:
case stun_dont_fragment:
case stun_reserved3:
case stun_reservation_token:
{
case stun_reservation_token: {
return tnet_turn_attribute_serialize(attribute, output);
}
/* RFC 5245 - 19.1. PRIORITY */
case stun_ice_priority:
{
case stun_ice_priority: {
uint32_t value = tnet_htonl(((tnet_stun_attribute_ice_priority_t*)attribute)->value);
tsk_buffer_append(output, &value, 4);
return 0;
}
/* RFC 5245 - 19.1. USE_CANDIDATE */
case stun_ice_use_candidate:
{
case stun_ice_use_candidate: {
// no body
return 0;
}
/* RFC 5245 - 19.1. ICE_CONTROLLED */
case stun_ice_controlled:
{
case stun_ice_controlled: {
uint64_t value = ((tnet_stun_attribute_ice_controlled_t*)attribute)->value;
value = ((((uint64_t)tnet_htonl(value >> 32)) << 32) | ((uint64_t)tnet_htonl(value & 0xFFFFFFFF)));
tsk_buffer_append(output, &value, 8);
return 0;
}
/* RFC 5245 - 19.1. ICE_CONTROLLING */
case stun_ice_controlling:
{
case stun_ice_controlling: {
uint64_t value = ((tnet_stun_attribute_ice_controlling_t*)attribute)->value;
value = ((((uint64_t)tnet_htonl(value >> 32)) << 32) | ((uint64_t)tnet_htonl(value & 0xFFFFFFFF)));
tsk_buffer_append(output, &value, 8);
@ -597,8 +563,7 @@ static tsk_object_t* tnet_stun_attribute_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_def_s = {
sizeof(tnet_stun_attribute_t),
tnet_stun_attribute_ctor,
tnet_stun_attribute_dtor,
@ -659,8 +624,7 @@ static tsk_object_t* tnet_stun_attribute_mapped_addr_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_mapped_addr_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_mapped_addr_def_s = {
sizeof(tnet_stun_attribute_mapped_addr_t),
tnet_stun_attribute_mapped_addr_ctor,
tnet_stun_attribute_mapped_addr_dtor,
@ -733,8 +697,7 @@ static tsk_object_t* tnet_stun_attribute_xmapped_addr_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_xmapped_addr_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_xmapped_addr_def_s = {
sizeof(tnet_stun_attribute_xmapped_addr_t),
tnet_stun_attribute_xmapped_addr_ctor,
tnet_stun_attribute_xmapped_addr_dtor,
@ -770,8 +733,7 @@ static tsk_object_t* tnet_stun_attribute_username_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_username_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_username_def_s = {
sizeof(tnet_stun_attribute_username_t),
tnet_stun_attribute_username_ctor,
tnet_stun_attribute_username_dtor,
@ -808,8 +770,7 @@ static tsk_object_t* tnet_stun_attribute_integrity_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_integrity_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_integrity_def_s = {
sizeof(tnet_stun_attribute_integrity_t),
tnet_stun_attribute_integrity_ctor,
tnet_stun_attribute_integrity_dtor,
@ -841,8 +802,7 @@ static tsk_object_t* tnet_stun_attribute_fingerprint_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_fingerprint_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_fingerprint_def_s = {
sizeof(tnet_stun_attribute_fingerprint_t),
tnet_stun_attribute_fingerprint_ctor,
tnet_stun_attribute_fingerprint_dtor,
@ -886,8 +846,7 @@ static tsk_object_t* tnet_stun_attribute_errorcode_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_errorcode_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_errorcode_def_s = {
sizeof(tnet_stun_attribute_errorcode_t),
tnet_stun_attribute_errorcode_ctor,
tnet_stun_attribute_errorcode_dtor,
@ -923,8 +882,7 @@ static tsk_object_t* tnet_stun_attribute_realm_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_realm_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_realm_def_s = {
sizeof(tnet_stun_attribute_realm_t),
tnet_stun_attribute_realm_ctor,
tnet_stun_attribute_realm_dtor,
@ -960,8 +918,7 @@ static tsk_object_t* tnet_stun_attribute_nonce_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_nonce_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_nonce_def_s = {
sizeof(tnet_stun_attribute_nonce_t),
tnet_stun_attribute_nonce_ctor,
tnet_stun_attribute_nonce_dtor,
@ -995,8 +952,7 @@ static tsk_object_t* tnet_stun_attribute_unknowns_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_unknowns_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_unknowns_def_s = {
sizeof(tnet_stun_attribute_unknowns_t),
tnet_stun_attribute_unknowns_ctor,
tnet_stun_attribute_unknowns_dtor,
@ -1031,8 +987,7 @@ static tsk_object_t* tnet_stun_attribute_software_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_software_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_software_def_s = {
sizeof(tnet_stun_attribute_software_t),
tnet_stun_attribute_software_ctor,
tnet_stun_attribute_software_dtor,
@ -1083,8 +1038,7 @@ static tsk_object_t* tnet_stun_attribute_altserver_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_altserver_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_altserver_def_s = {
sizeof(tnet_stun_attribute_altserver_t),
tnet_stun_attribute_altserver_ctor,
tnet_stun_attribute_altserver_dtor,
@ -1116,8 +1070,7 @@ static tsk_object_t* tnet_stun_attribute_ice_priority_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_attribute_ice_priority_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_ice_priority_def_s = {
sizeof(tnet_stun_attribute_ice_priority_t),
tnet_stun_attribute_ice_priority_ctor,
tnet_stun_attribute_ice_priority_dtor,
@ -1147,8 +1100,7 @@ static tsk_object_t* tnet_stun_attribute_ice_use_candidate_dtor(tsk_object_t * s
return self;
}
static const tsk_object_def_t tnet_stun_attribute_ice_use_candidate_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_ice_use_candidate_def_s = {
sizeof(tnet_stun_attribute_ice_use_candidate_t),
tnet_stun_attribute_ice_use_candidate_ctor,
tnet_stun_attribute_ice_use_candidate_dtor,
@ -1180,8 +1132,7 @@ static tsk_object_t* tnet_stun_attribute_ice_controlled_dtor(tsk_object_t * self
return self;
}
static const tsk_object_def_t tnet_stun_attribute_ice_controlled_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_ice_controlled_def_s = {
sizeof(tnet_stun_attribute_ice_controlled_t),
tnet_stun_attribute_ice_controlled_ctor,
tnet_stun_attribute_ice_controlled_dtor,
@ -1214,8 +1165,7 @@ static tsk_object_t* tnet_stun_attribute_ice_controlling_dtor(tsk_object_t * sel
return self;
}
static const tsk_object_def_t tnet_stun_attribute_ice_controlling_def_s =
{
static const tsk_object_def_t tnet_stun_attribute_ice_controlling_def_s = {
sizeof(tnet_stun_attribute_ice_controlling_t),
tnet_stun_attribute_ice_controlling_ctor,
tnet_stun_attribute_ice_controlling_dtor,

View File

@ -51,8 +51,7 @@ TNET_BEGIN_DECLS
/**@ingroup tnet_stun_group
* STUN IP family as per RFC 5389 subclause 15.1.
**/
typedef enum tnet_stun_addr_family_e
{
typedef enum tnet_stun_addr_family_e {
stun_ipv4 = 0x01,
stun_ipv6 = 0x02
}
@ -61,8 +60,7 @@ tnet_stun_addr_family_t;
/**@ingroup tnet_stun_group
* STUN attribute types as per RFC 5389 subclause 18.2.
**/
typedef enum tnet_stun_attribute_type_e
{
typedef enum tnet_stun_attribute_type_e {
/* === RFC 5389 - Comprehension-required range (0x0000-0x7FFF) */
stun_reserved = 0x0000, /**< (Reserved) */
stun_mapped_address = 0x0001, /**< http://tools.ietf.org/html/rfc5389#page-32 */
@ -110,8 +108,7 @@ tnet_stun_attribute_type_t;
/**@ingroup tnet_stun_group
RFC 5389 - 15. STUN Attributes
*/
typedef struct tnet_stun_attribute_s
{
typedef struct tnet_stun_attribute_s {
TSK_DECLARE_OBJECT;
/*
0 1 2 3
@ -136,8 +133,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_def_t;
/**@ingroup tnet_stun_group
*RFC 5389 - 15.1. MAPPED-ADDRESS
*/
typedef struct tnet_stun_attribute_mapped_addr_s
{
typedef struct tnet_stun_attribute_mapped_addr_s {
TNET_STUN_DECLARE_ATTRIBUTE;
/*
@ -163,8 +159,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_mapped_addr_def_t;
/**@ingroup tnet_stun_group
* RFC 5389 - 15.2. XOR-MAPPED-ADDRESS
*/
typedef struct tnet_stun_attribute_xmapped_addr_s
{
typedef struct tnet_stun_attribute_xmapped_addr_s {
TNET_STUN_DECLARE_ATTRIBUTE;
/*
@ -187,8 +182,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_xmapped_addr_def_t;
/**@ingroup tnet_stun_group
* RFC 5389 - 15.3. USERNAME.
*/
typedef struct tnet_stun_attribute_username_s
{
typedef struct tnet_stun_attribute_username_s {
TNET_STUN_DECLARE_ATTRIBUTE;
char* value;
@ -200,8 +194,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_username_def_t;
/**@ingroup tnet_stun_group
* RFC 5389 - 15.4. MESSAGE-INTEGRITY.
*/
typedef struct tnet_stun_attribute_integrity_s
{
typedef struct tnet_stun_attribute_integrity_s {
TNET_STUN_DECLARE_ATTRIBUTE;
tsk_sha1digest_t sha1digest;
@ -213,8 +206,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_integrity_def_t;
/**@ingroup tnet_stun_group
* RFC 5389 - 15.5. FINGERPRINT.
*/
typedef struct tnet_stun_attribute_fingerprint_s
{
typedef struct tnet_stun_attribute_fingerprint_s {
TNET_STUN_DECLARE_ATTRIBUTE;
uint32_t value;
@ -225,8 +217,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_fingerprint_def_t;
/**@ingroup tnet_stun_group
*RFC 5389 - 15.6. ERROR-CODE
*/
typedef struct tnet_stun_attribute_errorcode_s
{
typedef struct tnet_stun_attribute_errorcode_s {
TNET_STUN_DECLARE_ATTRIBUTE;
/*
0 1 2 3
@ -248,8 +239,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_errorcode_def_t;
/**@ingroup tnet_stun_group
* RFC 5389 - 15.7. REALM. */
typedef struct tnet_stun_attribute_realm_s
{
typedef struct tnet_stun_attribute_realm_s {
TNET_STUN_DECLARE_ATTRIBUTE;
char* value;
@ -260,8 +250,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_realm_def_t;
/**@ingroup tnet_stun_group
* RFC 5389 - 15.8. NONCE. */
typedef struct tnet_stun_attribute_nonce_s
{
typedef struct tnet_stun_attribute_nonce_s {
TNET_STUN_DECLARE_ATTRIBUTE;
char* value;
@ -271,8 +260,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_nonce_def_t;
/**@ingroup tnet_stun_group
* RFC 5389 - 15.9. UNKNOWN-ATTRIBUTES. */
typedef struct tnet_stun_attribute_unknowns_s
{
typedef struct tnet_stun_attribute_unknowns_s {
TNET_STUN_DECLARE_ATTRIBUTE;
tsk_buffer_t *value;
@ -282,8 +270,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_unknowns_def_t;
/**@ingroup tnet_stun_group
* RFC 5389 - 15.10. SOFTWARE. */
typedef struct tnet_stun_attribute_software_s
{
typedef struct tnet_stun_attribute_software_s {
TNET_STUN_DECLARE_ATTRIBUTE;
char *value;
@ -293,8 +280,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_software_def_t;
/**@ingroup tnet_stun_group
* RFC 5389 - 15.11. ALTERNATE-SERVER. */
typedef struct tnet_stun_attribute_altserver_s
{
typedef struct tnet_stun_attribute_altserver_s {
TNET_STUN_DECLARE_ATTRIBUTE;
tnet_stun_addr_family_t family;
@ -306,8 +292,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_altserver_def_t;
/**@ingroup tnet_stun_group
* RFC 5245 - 19.1. New Attributes */
typedef struct tnet_stun_attribute_ice_priority_s
{
typedef struct tnet_stun_attribute_ice_priority_s {
TNET_STUN_DECLARE_ATTRIBUTE;
uint32_t value;
}
@ -316,8 +301,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_priority_def_t;
/**@ingroup tnet_stun_group
* RFC 5245 - 19.1. New Attributes */
typedef struct tnet_stun_attribute_ice_use_candidate_s
{
typedef struct tnet_stun_attribute_ice_use_candidate_s {
TNET_STUN_DECLARE_ATTRIBUTE;
}
tnet_stun_attribute_ice_use_candidate_t;
@ -325,8 +309,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_use_candidate_de
/**@ingroup tnet_stun_group
* RFC 5245 - 19.1. New Attributes */
typedef struct tnet_stun_attribute_ice_controlled_s
{
typedef struct tnet_stun_attribute_ice_controlled_s {
TNET_STUN_DECLARE_ATTRIBUTE;
uint64_t value;
}
@ -335,8 +318,7 @@ TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_ice_controlled_def_t
/**@ingroup tnet_stun_group
* RFC 5245 - 19.1. New Attributes */
typedef struct tnet_stun_attribute_ice_controlling_s
{
typedef struct tnet_stun_attribute_ice_controlling_s {
TNET_STUN_DECLARE_ATTRIBUTE;
uint64_t value;
}

View File

@ -161,8 +161,7 @@ tsk_buffer_t* tnet_stun_message_serialize(const tnet_stun_message_t *self)
/*=== Attributes === */
{
tsk_list_item_t *item;
tsk_list_foreach(item, self->attributes)
{
tsk_list_foreach(item, self->attributes) {
attribute = item->data;
tnet_stun_attribute_serialize(attribute, output);
tnet_stun_attribute_pad(attribute, output);
@ -177,12 +176,14 @@ tsk_buffer_t* tnet_stun_message_serialize(const tnet_stun_message_t *self)
// will be computed again to store the correct value
uint16_t length = (output->size) - TNET_STUN_HEADER_SIZE;
#if 0
if(self->fingerprint)
if(self->fingerprint) {
length += (2/* Type */ + 2 /* Length */+ 4 /* FINGERPRINT VALUE*/);
}
#endif
if(compute_integrity)
if(compute_integrity) {
length += (2/* Type */ + 2 /* Length */+ TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
}
*(((uint16_t*)output->data)+1) = tnet_htons(length);
}
@ -275,8 +276,7 @@ tnet_stun_message_t* tnet_stun_message_deserialize(const uint8_t *data, tsk_size
/* Check message validity
*/
if((message->length + TNET_STUN_HEADER_SIZE) != size)
{
if((message->length + TNET_STUN_HEADER_SIZE) != size) {
TSK_OBJECT_SAFE_FREE(message);
goto bail;
}
@ -458,7 +458,8 @@ static tsk_object_t* tnet_stun_message_ctor(tsk_object_t * self, va_list * app)
message->fingerprint = 1;
message->integrity = 0;
{ // Create random transaction id
{
// Create random transaction id
int i;
for(i = 0; i < sizeof(message->transaction_id)/sizeof(message->transaction_id[0]); ++i) {
message->transaction_id[i] = rand();
@ -483,8 +484,7 @@ static tsk_object_t* tnet_stun_message_dtor(tsk_object_t * self)
return self;
}
static const tsk_object_def_t tnet_stun_message_def_s =
{
static const tsk_object_def_t tnet_stun_message_def_s = {
sizeof(tnet_stun_message_t),
tnet_stun_message_ctor,
tnet_stun_message_dtor,

View File

@ -95,8 +95,7 @@ typedef uint8_t tnet_stun_transacid_t[TNET_STUN_TRANSACID_SIZE];
/**@ingroup tnet_stun_group
* List of all supported STUN classes as per RFC 5389 subcaluse 6.
**/
typedef enum tnet_stun_class_type_e
{
typedef enum tnet_stun_class_type_e {
stun_class_request = 0x00, /**< Request class: 0b00 */
stun_class_indication = 0x01, /**< Indication class: 0b01 */
stun_class_success_response = 0x02, /**< Success response class: 0b10 */
@ -109,8 +108,7 @@ tnet_stun_class_type_t;
* RFC 5389 only define one method(Bining). All other methods have been defined
* by TURN (draft-ietf-behave-turn-16 and draft-ietf-behave-turn-tcp-05).
**/
typedef enum tnet_stun_method_type_e
{
typedef enum tnet_stun_method_type_e {
stun_method_binding = 0x0001, /**< RFC 5389 - Binding method: 0b000000000001 */
stun_method_allocate = 0x0003, /**< draft-ietf-behave-turn-16 - Allocate (only request/response semantics defined) */
@ -125,8 +123,7 @@ tnet_stun_method_type_t;
/**@ingroup tnet_stun_group
* List of all supported STUN types.
*/
typedef enum tnet_stun_message_type_e
{
typedef enum tnet_stun_message_type_e {
/* RFC 5389 - 6. STUN Message Structure
The message type defines the message class (request, success
@ -184,8 +181,7 @@ tnet_stun_message_type_t;
* STUN Message structure as per RFC 5389 subclause 6.
* http://tools.ietf.org/html/rfc5389#section-6
*/
typedef struct tnet_stun_message_s
{
typedef struct tnet_stun_message_s {
TSK_DECLARE_OBJECT;
/*

View File

@ -0,0 +1,308 @@
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#include "stun/tnet_stun_pkt.h"
#include "stun/tnet_stun_utils.h"
#include "tnet_endianness.h"
#include "tsk_memory.h"
#include "tsk_debug.h"
int tnet_stun_pkt_create(tnet_stun_pkt_type_t e_type, uint16_t u_length, const tnet_stun_transac_id_t* pc_transac_id, tnet_stun_pkt_t** pp_attr)
{
extern const tsk_object_def_t *tnet_stun_pkt_def_t;
if (!pp_attr) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if(!(*pp_attr = tsk_object_new(tnet_stun_pkt_def_t))) {
TSK_DEBUG_ERROR("Failed to create STUN pkt object");
return -2;
}
if (!((*pp_attr)->p_list_attrs = tsk_list_create())) {
TSK_OBJECT_SAFE_FREE(*pp_attr);
return -3;
}
if (pc_transac_id) {
memcpy((*pp_attr)->transac_id, *pc_transac_id, sizeof(tnet_stun_transac_id_t));
}
else {
tnet_stun_utils_transac_id_rand(&(*pp_attr)->transac_id);
}
(*pp_attr)->e_type = e_type;
(*pp_attr)->u_length = u_length;
return 0;
}
int tnet_stun_pkt_add_attr(tnet_stun_pkt_t* p_self, tnet_stun_attr_t** pp_attr)
{
if (!p_self || !pp_attr || !*pp_attr) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
tsk_list_push_back_data(p_self->p_list_attrs, (void**)pp_attr);
return 0;
}
int tnet_stun_pkt_add_attrs(tnet_stun_pkt_t* p_self, ...)
{
va_list ap;
int ret = 0;
tnet_stun_pkt_add_attr_t e_add_attr;
if (!p_self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
va_start(ap, p_self);
while ((e_add_attr = va_arg(ap, tnet_stun_pkt_add_attr_t)) != tnet_stun_pkt_add_attr_null) {
switch (e_add_attr) {
case tnet_stun_pkt_add_attr_vdata: {
// (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
const uint8_t* P_DATA_PTR = va_arg(ap, const uint8_t*);
uint16_t U_DATA_SIZE = va_arg(ap, uint16_t);
tnet_stun_attr_vdata_t *p_attr;
if ((ret = tnet_stun_attr_vdata_create(E_TYPE, P_DATA_PTR, U_DATA_SIZE, &p_attr))) {
goto bail;
}
if ((ret = tnet_stun_pkt_add_attr(p_self, (tnet_stun_attr_t**)&p_attr))) {
TSK_OBJECT_SAFE_FREE(p_attr);
goto bail;
}
break;
}
case tnet_stun_pkt_add_attr_address: {
// (enum tnet_stun_attr_type_e)(E_TYPE), (enum tnet_stun_address_family_e)(E_FAMILY), (uint16_t)(U_PORT), (const tnet_stun_addr_t*)PC_ADDR_PTR
enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
enum tnet_stun_address_family_e E_FAMILY = va_arg(ap, enum tnet_stun_address_family_e);
uint16_t U_PORT = va_arg(ap, uint16_t);
const tnet_stun_addr_t* PC_ADDR_PTR = va_arg(ap, const tnet_stun_addr_t*);
tnet_stun_attr_address_t *p_attr;
if ((ret = tnet_stun_attr_address_create(E_TYPE, E_FAMILY, U_PORT, PC_ADDR_PTR, &p_attr))) {
goto bail;
}
if ((ret = tnet_stun_pkt_add_attr(p_self, (tnet_stun_attr_t**)&p_attr))) {
TSK_OBJECT_SAFE_FREE(p_attr);
goto bail;
}
break;
}
default: {
TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
ret = -2;
goto bail;
}
}
}
bail:
va_end(ap);
return ret;
}
int tnet_stun_pkt_get_size_in_octetunits_without_padding(const tnet_stun_pkt_t* pc_self, tsk_size_t* p_size)
{
const tsk_list_item_t* pc_item;
const tnet_stun_attr_t* pc_attr;
tsk_size_t n_size;
int ret;
if (!pc_self || !p_size) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
*p_size = kStunPktHdrSizeInOctets;
tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
if ((ret = tnet_stun_attr_get_size_in_octetunits_without_padding(pc_attr, &n_size))) {
return ret;
}
*p_size += n_size;
}
}
return 0;
}
int tnet_stun_pkt_get_size_in_octetunits_with_padding(const tnet_stun_pkt_t* pc_self, tsk_size_t* p_size)
{
const tsk_list_item_t* pc_item;
const tnet_stun_attr_t* pc_attr;
tsk_size_t n_size;
int ret;
if (!pc_self || !p_size) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
*p_size = kStunPktHdrSizeInOctets;
tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
if ((ret = tnet_stun_attr_get_size_in_octetunits_with_padding(pc_attr, &n_size))) {
return ret;
}
*p_size += n_size;
}
}
return 0;
}
int tnet_stun_pkt_write_with_padding(const tnet_stun_pkt_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written)
{
const tsk_list_item_t* pc_item;
const tnet_stun_attr_t* pc_attr;
tsk_size_t n_size;
int ret;
if (!pc_self || !p_buff_ptr || !n_buff_size || !p_written) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, p_written))) {
return ret;
}
if ((n_buff_size < *p_written)) {
TSK_DEBUG_ERROR("Buffer too short: %u<%u", n_buff_size, *p_written);
return -1;
}
// write header
*((uint16_t*)&p_buff_ptr[0]) = tnet_htons((unsigned short)pc_self->e_type);
*((uint32_t*)&p_buff_ptr[4]) = tnet_htonl(kStunMagicCookie);
memcpy(&p_buff_ptr[8], pc_self->transac_id, sizeof(pc_self->transac_id));
p_buff_ptr += kStunPktHdrSizeInOctets;
n_buff_size -= kStunPktHdrSizeInOctets;
// write attributes
tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
if (pc_attr = (const tnet_stun_attr_t*)pc_item->data) {
if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, p_buff_ptr, n_buff_size, &n_size))) {
return ret;
}
p_buff_ptr += n_size;
n_buff_size -= n_size;
}
}
// Length
*((uint16_t*)&p_buff_ptr[2-*p_written]) = tnet_htons(*p_written - kStunPktHdrSizeInOctets);
return 0;
}
int tnet_stun_pkt_is_complete(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t *pb_is_complete)
{
if (!pb_is_complete) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
*pb_is_complete = tsk_false;
if (pc_buff_ptr && n_buff_size >= kStunPktHdrSizeInOctets) {
tsk_size_t n_paylen_in_octets = tnet_ntohs_2(&pc_buff_ptr[2]);
*pb_is_complete = ((n_buff_size - kStunPktHdrSizeInOctets) >= n_paylen_in_octets);
}
return 0;
}
int tnet_stun_pkt_read(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tnet_stun_pkt_t** pp_pkt)
{
tsk_bool_t b_is_complete;
tsk_size_t PayloadLengthInOctets;
tnet_stun_pkt_type_t Type;
tnet_stun_transac_id_t transac_id;
uint32_t MagicCookie;
int ret;
if (!pc_buff_ptr || !n_buff_size || !pp_pkt) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (!TNET_STUN_PKT_IS_STUN2(pc_buff_ptr, n_buff_size)) {
TSK_DEBUG_ERROR("Buffer doesn't contain a valid STUN2 pkt");
return -2;
}
if ((ret = tnet_stun_pkt_is_complete(pc_buff_ptr, n_buff_size, &b_is_complete))) {
return ret;
}
if (!b_is_complete) {
TSK_DEBUG_ERROR("Buffer too short(%u)", n_buff_size);
return -3;
}
// read the header
Type = tnet_ntohs_2(&pc_buff_ptr[0]);
PayloadLengthInOctets = tnet_ntohs_2(&pc_buff_ptr[2]);
MagicCookie = tnet_ntohl_2(&pc_buff_ptr[4]);
if (MagicCookie != kStunMagicCookieLong) {
TSK_DEBUG_ERROR("%x not a valid STUN2 magic cookie");
return -4;
}
memcpy(transac_id, &pc_buff_ptr[8], sizeof(tnet_stun_transac_id_t));
// create the pkt
if((ret = tnet_stun_pkt_create(Type, PayloadLengthInOctets, &transac_id, pp_pkt))) {
return ret;
}
if (PayloadLengthInOctets > 0) {
tnet_stun_attr_t* p_attr;
tsk_size_t n_consumed_octets;
pc_buff_ptr += kStunPktHdrSizeInOctets;
do {
if ((ret = tnet_stun_attr_read(&(*pp_pkt)->transac_id, pc_buff_ptr, PayloadLengthInOctets, &n_consumed_octets, &p_attr))) {
return ret;
}
if ((ret = tnet_stun_pkt_add_attr((*pp_pkt), &p_attr))) {
TSK_OBJECT_SAFE_FREE((*pp_pkt));
return ret;
}
PayloadLengthInOctets -= n_consumed_octets;
pc_buff_ptr += n_consumed_octets;
}
while (PayloadLengthInOctets >= kStunAttrHdrSizeInOctets);
}
return 0;
}
static tsk_object_t* tnet_stun_pkt_ctor(tsk_object_t * self, va_list * app)
{
tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
if (p_pkt) {
}
return self;
}
static tsk_object_t* tnet_stun_pkt_dtor(tsk_object_t * self)
{
tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
if (p_pkt) {
TSK_DEBUG_INFO("*** STUN pkt destroyed ***");
TSK_OBJECT_SAFE_FREE(p_pkt->p_list_attrs);
TSK_FREE(p_pkt->auth.p_username);
TSK_FREE(p_pkt->auth.p_password);
TSK_FREE(p_pkt->auth.p_realm);
TSK_FREE(p_pkt->auth.p_nonce);
}
return self;
}
static const tsk_object_def_t tnet_stun_pkt_def_s = {
sizeof(tnet_stun_pkt_t),
tnet_stun_pkt_ctor,
tnet_stun_pkt_dtor,
tsk_null,
};
const tsk_object_def_t *tnet_stun_pkt_def_t = &tnet_stun_pkt_def_s;

View File

@ -0,0 +1,110 @@
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#ifndef TNET_STUN_PKT_H
#define TNET_STUN_PKT_H
#include "tinynet_config.h"
#include "stun/tnet_stun_attr.h"
#include "tsk_object.h"
#include "tsk_list.h"
TNET_BEGIN_DECLS
/**@ingroup tnet_stun_group
* @def TNET_STUN_PKT_IS_REQ
* Checks whether the STUN message is a request or not.
*/
/**@ingroup tnet_stun_group
* @def TNET_STUN_PKT_IS_INDICATION
* Checks whether the STUN message is an indicaton message or not.
*/
/**@ingroup tnet_stun_group
* @def TNET_STUN_RESP_IS_SUCCESS
* Checks whether the STUN message is a success response or not.
*/
/**@ingroup tnet_stun_group
* @def TNET_STUN_RESP_IS_ERROR
* Checks whether the STUN message is an error response or not.
*/
#define TNET_STUN_PKT_IS_REQ(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_request))
#define TNET_STUN_PKT_IS_RESP(p_self) (TNET_STUN_PKT_RESP_IS_SUCCESS((p_self)) || TNET_STUN_PKT_RESP_IS_ERROR((self)))
#define TNET_STUN_PKT_IS_INDICATION(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_indication))
#define TNET_STUN_PKT_RESP_IS_SUCCESS(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_success))
#define TNET_STUN_PKT_RESP_IS_ERROR(p_self) ((p_self) && (((p_self)->e_type & 0x0110) == tnet_stun_mask_error))
typedef enum tnet_stun_pkt_add_attr_e {
tnet_stun_pkt_add_attr_null = 0,
tnet_stun_pkt_add_attr_none = tnet_stun_pkt_add_attr_null,
tnet_stun_pkt_add_attr_vdata,
tnet_stun_pkt_add_attr_address
}
tnet_stun_pkt_add_attr_t;
#define TNET_STUN_PKT_ADD_ATTR_NULL() tnet_stun_pkt_add_attr_null
#define TNET_STUN_PKT_ADD_ATTR_VDATA(E_TYPE, P_DATA_PTR, U_DATA_SIZE) tnet_stun_pkt_add_attr_vdata, (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
#define TNET_STUN_PKT_ADD_ATTR_ADDRESS(E_TYPE, E_FAMILY, U_PORT, PC_ADDR_PTR) tnet_stun_pkt_add_attr_address, (enum tnet_stun_attr_type_e)(E_TYPE), (enum tnet_stun_address_family_e)(E_FAMILY), (uint16_t)(U_PORT), (const tnet_stun_addr_t*)PC_ADDR_PTR
#define TNET_STUN_PKT_ADD_ATTR_ADDRESS_V4(E_TYPE, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ADDRESS((E_TYPE), tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ADD_ATTR_ADDRESS_V6(E_TYPE, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ADDRESS((E_TYPE), tnet_stun_address_family_ipv6, (U_PORT), (PC_ADDR_PTR))
// rfc5389 - 15.1. MAPPED-ADDRESS
#define TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS(E_FAMILY, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ADDRESS(tnet_stun_attr_type_mapped_address, (E_FAMILY), (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS_V4(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS(tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS_V6(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS(tnet_stun_address_family_ipv6, (U_PORT), (PC_ADDR_PTR))
// rfc5389 - 15.2. XOR-MAPPED-ADDRESS
#define TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS(E_FAMILY, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ADDRESS(tnet_stun_attr_type_xor_mapped_address, (E_FAMILY), (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS_V4(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS(tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS_V6(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS(tnet_stun_address_family_ipv6, (U_PORT), (PC_ADDR_PTR))
typedef struct tnet_stun_pkt_s {
TSK_DECLARE_OBJECT;
enum tnet_stun_pkt_type_e e_type;
uint16_t u_length; // 16bits: contain the size, in bytes, of the message not including the 20-byte STUN header
tnet_stun_transac_id_t transac_id; // 96bits : always in network byte-order
tnet_stun_attrs_L_t* p_list_attrs;
struct {
unsigned fingerprint:1;
unsigned integrity:1;
unsigned dontfrag:1;
unsigned nointegrity:1;
} opt;
struct {
char* p_username;
char* p_password;
char* p_realm;
char* p_nonce;
} auth;
} tnet_stun_pkt_t;
#define TNET_STUN_DECLARE_PKT struct tnet_stun_pkt_s __base__
#define TNET_STUN_PKT(p_self) ((struct tnet_stun_pkt_s*)(p_self))
typedef tsk_list_t tnet_stun_pkts_L_t;
TINYNET_API int tnet_stun_pkt_create(enum tnet_stun_pkt_type_e e_type, uint16_t u_length, const tnet_stun_transac_id_t* pc_transac_id, struct tnet_stun_pkt_s** pp_attr);
#define tnet_stun_pkt_create_empty(e_type, pp_attr) tnet_stun_pkt_create((e_type), 0, tsk_null, (pp_attr))
TINYNET_API int tnet_stun_pkt_add_attr(struct tnet_stun_pkt_s* p_self, struct tnet_stun_attr_s** pp_attr);
TINYNET_API int tnet_stun_pkt_add_attrs(struct tnet_stun_pkt_s* p_self, ...);
TINYNET_API int tnet_stun_pkt_get_size_in_octetunits_without_padding(const struct tnet_stun_pkt_s* pc_self, tsk_size_t* p_size);
TINYNET_API int tnet_stun_pkt_get_size_in_octetunits_with_padding(const struct tnet_stun_pkt_s* pc_self, tsk_size_t* p_size);
TINYNET_API int tnet_stun_pkt_write_with_padding(const struct tnet_stun_pkt_s* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written);
TINYNET_API int tnet_stun_pkt_is_complete(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t *pb_is_complete);
TINYNET_API int tnet_stun_pkt_read(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, struct tnet_stun_pkt_s** pp_pkt);
TNET_END_DECLS
#endif /* TNET_STUN_PKT_H */

View File

@ -0,0 +1,234 @@
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#ifndef TNET_STUN_TYPES_H
#define TNET_STUN_TYPES_H
#include "tinynet_config.h"
TNET_BEGIN_DECLS
typedef uint8_t tnet_stun_addr_t[16]; // IPv4(32bits) or IPv6(128bits)
/**@ingroup tnet_stun_group
* Checks if the pointer to the buffer hold a STUN header by checking that it starts with 0b00 and contain the magic cookie.
* As per RFC 5389 subclause 19: Explicitly point out that the most significant 2 bits of STUN are
* 0b00, allowing easy differentiation with RTP packets when used with ICE.
* As per RFC 5389 subclause 6: The magic cookie field MUST contain the fixed value 0x2112A442 in
* network byte order.
*
* @param PU8 The pointer to the buffer holding the STUN raw data.
**/
#define TNET_STUN_PKT_IS_STUN2(PU8, SIZE) \
( \
((PU8)) && \
((SIZE) >= kStunPktHdrSizeInOctets) && \
(((PU8)[0] & 0xc0) == 0x00) && \
( PU8[4] == 0x21 && PU8[5] == 0x12 && PU8[6] == 0xA4 && PU8[7] == 0x42 ) \
)
#if !defined(kStunPortDefaultTcpUdp)
# define kStunPortDefaultTcpUdp 3478
#endif /* kStunPortDefaultTcpUdp */
#if !defined(kStunPortDefaultTls)
# define kStunPortDefaultTls 5349
#endif /* kStunPortDefaultTls */
// rfc5389 - 15. STUN Attributes
#if !defined(kStunAttrHdrSizeInOctets)
# define kStunAttrHdrSizeInOctets 4
#endif /* kStunAttrHdrSizeInOctets */
// rfc5389 - 6. STUN Message Structure
#if !defined(kStunPktHdrSizeInOctets)
# define kStunPktHdrSizeInOctets 20
#endif /* kStunPktHdrSizeInOctets */
// STUN2 magic cookie value in network byte order as per RFC 5389 subclause 6.
#if !defined(kStunMagicCookieLong)
# define kStunMagicCookieLong 0x2112A442
#endif /* kStunMagicCookieLong */
#if !defined(kStunMagicCookie)
# define kStunMagicCookie kStunMagicCookieLong
#endif /* kStunMagicCookie */
#if !defined(kStunMagicCookieShort)
# define kStunMagicCookieShort 0x2112
#endif /* kStunMagicCookieShort */
#if !defined (kStunFingerprintXorConst)
# define kStunFingerprintXorConst 0x5354554e
#endif kStunFingerprintXorConst /* kStunFingerprintXorConst */
// STUN trasactionn ID size (96bits = 12bytes)
#if !defined(kStunTransacIdSize)
# define kStunTransacIdSize 12
#endif
typedef uint8_t tnet_stun_transac_id_t[kStunTransacIdSize];
/**@ingroup tnet_stun_group
* List of all supported STUN classes as per RFC 5389 subcaluse 6.
**/
typedef enum tnet_stun_class_e {
tnet_stun_class_request = 0x00, /**< Request class: 0b00 */
tnet_stun_class_indication = 0x01, /**< Indication class: 0b01 */
tnet_stun_class_success_response = 0x02, /**< Success response class: 0b10 */
tnet_stun_class_error_response = 0x03, /**< Error/failure response class: 0b11 */
}
tnet_stun_class_t;
/**@ingroup tnet_stun_group
* List of all supported STUN methods.
* RFC 5389 defines only one method(Bining). All other methods have been defined by TURN (rfc5766 section 13).
**/
typedef enum tnet_stun_method_e {
tnet_stun_method_binding = 0x0001, /**< RFC 5389 - Binding method: 0b000000000001 */
tnet_stun_method_allocate = 0x0003, /**< rfc5766 - Allocate (only request/response semantics defined) */
tnet_stun_method_refresh = 0x0004, /**< rfc5766 - Refresh (only request/response semantics defined) */
tnet_stun_method_send = 0x0006, /**< rfc5766 - Send (only indication semantics defined) */
tnet_stun_method_data = 0x0007, /**< rfc5766 - Data (only indication semantics defined) */
tnet_stun_method_createpermission = 0x0008, /**< rfc5766 - CreatePermission (only request/response semantics defined */
tnet_stun_method_channelbind = 0x0009, /**< rfc5766 - ChannelBind (only request/response semantics defined) */
}
tnet_stun_method_t;
/**@ingroup tnet_stun_group
*/
typedef enum tnet_stun_mask_e {
tnet_stun_mask_request = 0x0000,
tnet_stun_mask_indication = 0x0010,
tnet_stun_mask_success = 0x0100,
tnet_stun_mask_error = 0x0110
}
tnet_stun_mask_t;
/**@ingroup tnet_stun_group
* STUN IP family as per RFC 5389 subclause 15.1.
**/
typedef enum tnet_stun_address_family_e {
tnet_stun_address_family_ipv4 = 0x01,
tnet_stun_address_family_ipv6 = 0x02
} tnet_stun_address_family_t;
/**@ingroup tnet_stun_group
* STUN attr types as per RFC 5389 subclause 18.2.
**/
typedef enum tnet_stun_attr_type_e {
/* === RFC 5389 - Comprehension-required range (0x0000-0x7FFF) */
tnet_stun_attr_type_reserved = 0x0000, /**< (Reserved) */
tnet_stun_attr_type_mapped_address = 0x0001, /**< http://tools.ietf.org/html/rfc5389#page-32 */
tnet_stun_attr_type_response_address = 0x0002, /**< (Reserved; was RESPONSE-ADDRESS) */
tnet_stun_attr_type_change_address = 0x0003, /**< (Reserved; was CHANGE-ADDRESS) */
tnet_stun_attr_type_source_address = 0x0004, /**< (Reserved; was SOURCE-ADDRESS) */
tnet_stun_attr_type_changed_address = 0x0005, /**< (Reserved; was CHANGED-ADDRESS) */
tnet_stun_attr_type_username = 0x0006, /**< http://tools.ietf.org/html/rfc5389#page-34 */
tnet_stun_attr_type_password = 0x0007, /**< (Reserved; was PASSWORD) */
tnet_stun_attr_type_message_integrity = 0x0008, /**< http://tools.ietf.org/html/rfc5389#page-34 */
tnet_stun_attr_type_error_code = 0x0009, /**< http://tools.ietf.org/html/rfc5389#page-36 */
tnet_stun_attr_type_unknown_attrs = 0x000A, /**< http://tools.ietf.org/html/rfc5389#page-38 */
tnet_stun_attr_type_reflected_from = 0x000B, /**< (Reserved; was REFLECTED-FROM) */
tnet_stun_attr_type_realm = 0x0014, /**< http://tools.ietf.org/html/rfc5389#page-38 */
tnet_stun_attr_type_nonce = 0x0015, /**< http://tools.ietf.org/html/rfc5389#page-38 */
tnet_stun_attr_type_xor_mapped_address = 0x0020, /**< http://tools.ietf.org/html/rfc5389#page-33 */
/* === RFC 5389 - Comprehension-optional range (0x8000-0xFFFF) */
tnet_stun_attr_type_software = 0x8022, /**< http://tools.ietf.org/html/rfc5389#page-39 */
tnet_stun_attr_type_alternate_server = 0x8023, /**< http://tools.ietf.org/html/rfc5389#page-39 */
tnet_stun_attr_type_fingerprint = 0x8028, /**< http://tools.ietf.org/html/rfc5389#page-36 */
/* === rfc5766 */
tnet_stun_attr_type_channel_number = 0x000C, /**< rfc5766 - CHANNEL-NUMBER */
tnet_stun_attr_type_lifetime = 0x000D, /**< rfc5766 - LIFETIME */
tnet_stun_attr_type_reserved2 = 0x0010, /**< rfc5766 - Reserved (was BANDWIDTH) */
tnet_stun_attr_type_xor_peer_address = 0x0012, /**< rfc5766 - XOR-PEER-ADDRESS */
tnet_stun_attr_type_data = 0x0013, /**< rfc5766 - DATA */
tnet_stun_attr_type_xor_relayed_address = 0x0016, /**< rfc5766 - XOR-RELAYED-ADDRESS */
tnet_stun_attr_type_even_port = 0x0018, /**< rfc5766 - EVEN-PORT */
tnet_stun_attr_type_requested_transport = 0x0019, /**< rfc5766 - REQUESTED-TRANSPORT */
tnet_stun_attr_type_dont_fragment = 0x001A, /**< rfc5766 - DONT-FRAGMENT */
tnet_stun_attr_type_reserved3 = 0x0021, /**< rfc5766 - Reserved (was TIMER-VAL) */
tnet_stun_attr_type_reservation_token = 0x0022, /**< rfc5766 - RESERVATION-TOKEN */
/* RFC 5245 */
tnet_stun_attr_type_ice_priority = 0x0024, /**< 21.2. STUN Attributes */
tnet_stun_attr_type_ice_use_candidate = 0x0025, /**< 21.2. STUN Attributes */
tnet_stun_attr_type_ice_controlled = 0x8029, /**< 21.2. STUN Attributes */
tnet_stun_attr_type_ice_controlling = 0x802A, /**< 21.2. STUN Attributes */
} tnet_stun_attr_type_t;
/**@ingroup tnet_stun_group
* List of all supported STUN message types.
*/
typedef enum tnet_stun_pkt_type_e {
/* RFC 5389 - 6. STUN Message Structure
The message type defines the message class (request, success
response, failure response, or indication) and the message method
(the primary function) of the STUN message. Although there are four
message classes, there are only two types of transactions in STUN:
request/response transactions (which consist of a request message and
a response message) and indication transactions (which consist of a
single indication message). Response classes are split into error
and success responses to aid in quickly processing the STUN message.
The message type field is decomposed further into the following
structure:
0 1
2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
*/
tnet_stun_pkt_type_binding_request = (tnet_stun_method_binding | tnet_stun_mask_request),
tnet_stun_pkt_type_binding_indication = (tnet_stun_method_binding | tnet_stun_mask_indication),
tnet_stun_pkt_type_binding_success_response = (tnet_stun_method_binding | tnet_stun_mask_success),
tnet_stun_pkt_type_binding_error_response = (tnet_stun_method_binding | tnet_stun_mask_error),
tnet_stun_pkt_type_allocate_request = (tnet_stun_method_allocate | tnet_stun_mask_request),
tnet_stun_pkt_type_allocate_indication = (tnet_stun_method_allocate | tnet_stun_mask_indication),
tnet_stun_pkt_type_allocate_success_response = (tnet_stun_method_allocate | tnet_stun_mask_success),
tnet_stun_pkt_type_allocate_error_response = (tnet_stun_method_allocate | tnet_stun_mask_error),
tnet_stun_pkt_type_refresh_request = (tnet_stun_method_refresh | tnet_stun_mask_request),
tnet_stun_pkt_type_refresh_indication = (tnet_stun_method_refresh | tnet_stun_mask_indication),
tnet_stun_pkt_type_refresh_success_response = (tnet_stun_method_refresh | tnet_stun_mask_success),
tnet_stun_pkt_type_refresh_error_response = (tnet_stun_method_refresh | tnet_stun_mask_error),
tnet_stun_pkt_type_send_indication = (tnet_stun_method_send | tnet_stun_mask_indication),
tnet_stun_pkt_type_data_indication = (tnet_stun_method_data | tnet_stun_mask_indication),
tnet_stun_pkt_type_createpermission_request = (tnet_stun_method_createpermission | tnet_stun_mask_request),
tnet_stun_pkt_type_createpermission_indication = (tnet_stun_method_createpermission | tnet_stun_mask_indication),
tnet_stun_pkt_type_createpermission_success_response = (tnet_stun_method_createpermission | tnet_stun_mask_success),
tnet_stun_pkt_type_createpermission_error_response = (tnet_stun_method_createpermission | tnet_stun_mask_error),
tnet_stun_pkt_type_channelbind_request = (tnet_stun_method_channelbind | tnet_stun_mask_request),
tnet_stun_pkt_type_channelbind_indication = (tnet_stun_method_channelbind | tnet_stun_mask_indication),
tnet_stun_pkt_type_channelbind_success_response = (tnet_stun_method_channelbind | tnet_stun_mask_success),
tnet_stun_pkt_type_channelbind_error_response = (tnet_stun_method_channelbind | tnet_stun_mask_error),
}
tnet_stun_pkt_type_t;
TNET_END_DECLS
#endif /* TNET_STUN_TYPES_H */

View File

@ -0,0 +1,63 @@
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#include "stun/tnet_stun_utils.h"
#include "tnet_utils.h"
#include "tsk_debug.h"
int tnet_stun_utils_inet_pton(tsk_bool_t b_v6, const char* p_src, tnet_stun_addr_t* p_dst)
{
int ret;
if (!p_src || !p_dst) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if ((ret = tnet_inet_pton(b_v6 ? AF_INET6 : AF_INET, p_src, *p_dst) != 1)) { // success == 1
TSK_DEBUG_ERROR("tnet_inet_pton() with error code = %d", ret);
return -3;
}
return 0;
}
int tnet_stun_utils_inet_ntop(tsk_bool_t b_v6, const tnet_stun_addr_t* pc_src, tnet_ip_t* p_dst)
{
if (!pc_src || !p_dst) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (tnet_inet_ntop(b_v6 ? AF_INET6 : AF_INET, *pc_src, *p_dst, sizeof(*p_dst)) == tsk_null) {
TSK_DEBUG_ERROR("tnet_inet_ntop() failed");
return -2;
}
return 0;
}
int tnet_stun_utils_transac_id_rand(tnet_stun_transac_id_t* p_transac_id)
{
tsk_size_t u, s = sizeof(*p_transac_id);
if (!p_transac_id) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
for (u = 0; u < s; ++u) {
*(((uint8_t*)p_transac_id) + u) = rand() ^ rand();
}
return 0;
}

View File

@ -0,0 +1,39 @@
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#ifndef TNET_STUN_UTILS_H
#define TNET_STUN_UTILS_H
#include "tinynet_config.h"
#include "stun/tnet_stun_types.h"
#include "tnet_types.h"
TNET_BEGIN_DECLS
TINYNET_API int tnet_stun_utils_inet_pton(tsk_bool_t b_v6, const char* p_src, tnet_stun_addr_t* p_dst);
#define tnet_stun_utils_inet_pton_v4(p_src, p_dst) tnet_stun_utils_inet_pton(tsk_false, (p_src), (p_dst))
#define tnet_stun_utils_inet_pton_v6(p_src, p_dst) tnet_stun_utils_inet_pton(tsk_true, (p_src), (p_dst))
TINYNET_API int tnet_stun_utils_inet_ntop(tsk_bool_t b_v6, const tnet_stun_addr_t* pc_src, tnet_ip_t* p_dst);
#define tnet_stun_utils_inet_ntop_v4(pc_src, p_dst) tnet_stun_utils_inet_ntop(tsk_false, (pc_src), (p_dst))
#define tnet_stun_utils_inet_ntop_v6(pc_src, p_dst) tnet_stun_utils_inet_ntop(tsk_true, (pc_src), (p_dst))
TINYNET_API int tnet_stun_utils_transac_id_rand(tnet_stun_transac_id_t* p_transac_id);
TNET_END_DECLS
#endif /* TNET_STUN_UTILS_H */

View File

@ -84,6 +84,10 @@ extern Platform::String^ rt_tsk_str_to_managed(char const* str);
# include <fcntl.h>
#endif /* HAVE_FCNTL_H */
#if HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif /* HAVE_ARPA_INET_H */
#ifndef AF_LINK
# define AF_LINK AF_PACKET
#endif /* AF_LINK */
@ -1253,6 +1257,133 @@ int tnet_gethostname(tnet_host_t* result)
return gethostname(*result, sizeof(*result));
}
/**@ingroup tnet_utils_group
* see http://man7.org/linux/man-pages/man3/inet_pton.3.html
* @retval 1 if succeed.
*/
int tnet_inet_pton(int af, const char* src, void* dst)
{
if (!src || !dst) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
#if HAVE_INET_PTON
return inet_pton(af, src, dst);
#elif TNET_UNDER_WINDOWS
# if (_WIN32_WINNT <= 0x0501)
{
struct sockaddr_storage addr = { 0 };
int addr_len = sizeof(addr);
if (WSAStringToAddressA((LPSTR)src, af, NULL, (struct sockaddr *)&addr, &addr_len) == 0) {
if (af == AF_INET6) {
*((struct in6_addr *)dst) = ((struct sockaddr_in6 *)&addr)->sin6_addr;
}
else {
*((struct in_addr *)dst) = ((struct sockaddr_in *)&addr)->sin_addr;
}
return 1;
}
TNET_PRINT_LAST_ERROR("WSAStringToAddressA failed");
return -2;
}
# else
return InetPton(af, src, dst);
# endif // TNET_UNDER_WINDOWS
#else
{
struct sockaddr_storage addr = { 0 };
int ret;
if ((ret = tnet_sockaddr_init(src, 0, (af == AF_INET6 ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4), &addr))) {
return -2;
}
if (af == AF_INET6) {
*((struct in6_addr *)dst) = ((struct sockaddr_in6 *)&addr)->sin6_addr;
}
else {
*((struct in_addr *)dst) = ((struct sockaddr_in *)&addr)->sin_addr;
}
return 1;
}
#endif
}
/**@ingroup tnet_utils_group
* see http://pubs.opengroup.org/onlinepubs/009695399/functions/inet_ntop.html
*/
const char *tnet_inet_ntop(int af, const void *src, char *dst, int size)
{
if (!src || !dst || size <= 0) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
memset(dst, 0, size);
#if HAVE_INET_NTOP
return inet_ntop(af, src, dst, size);
#elif TNET_UNDER_WINDOWS
# if (_WIN32_WINNT <= 0x0501)
{
struct sockaddr_storage addr = { 0 };
int addr_len = sizeof(addr);
if (af == AF_INET6) {
if (size < INET6_ADDRSTRLEN) {
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
return tsk_null;
}
addr.ss_family = AF_INET6;
((struct sockaddr_in6 *)&addr)->sin6_addr = *((struct in6_addr *)src);
}
else {
if (size < INET_ADDRSTRLEN) {
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
return tsk_null;
}
addr.ss_family = AF_INET;
((struct sockaddr_in *)&addr)->sin_addr = *((struct in_addr *)src);
}
if (WSAAddressToStringA((struct sockaddr*)&addr, addr_len, NULL, dst, &size) == 0) {
return dst;
}
TNET_PRINT_LAST_ERROR("WSAAddressToStringA failed");
return tsk_null;
}
# else
return InetNtop(af, src, dst, size);
# endif // TNET_UNDER_WINDOWS
#else
{
struct sockaddr_storage addr = { 0 };
tnet_ip_t ip;
if (af == AF_INET6) {
if (size < INET6_ADDRSTRLEN) {
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
return tsk_null;
}
addr.ss_family = AF_INET6;
((struct sockaddr_in6 *)&addr)->sin6_addr = *((struct in6_addr *)src);
if (tnet_get_sockip((const struct sockaddr *)&addr, &ip)) {
return tsk_null;
}
memcpy(dst, ip, INET6_ADDRSTRLEN);
return dst;
}
else {
if (size < INET_ADDRSTRLEN) {
TSK_DEBUG_ERROR("Destination size too short(%d)", size);
return tsk_null;
}
addr.ss_family = AF_INET;
((struct sockaddr_in *)&addr)->sin_addr = *((struct in_addr *)src);
if (tnet_get_sockip((const struct sockaddr *)&addr, &ip)) {
return tsk_null;
}
memcpy(dst, ip, INET_ADDRSTRLEN);
return dst;
}
}
#endif
}
/**@ingroup tnet_utils_group
* Waits until the socket becomes writable/readable or @a timeout milliseconds passed.
* This function could be used just after you have @a connect()ed a non-blocking socket.

View File

@ -130,6 +130,9 @@ TINYNET_API int tnet_get_fd_opened_count(tsk_size_t* count);
TINYNET_API int tnet_getnameinfo(const struct sockaddr *sa, socklen_t salen, char* node, socklen_t nodelen, char* service, socklen_t servicelen, int flags);
TINYNET_API int tnet_gethostname(tnet_host_t* result);
TINYNET_API int tnet_inet_pton(int af, const char* src, void* dst);
TINYNET_API const char *tnet_inet_ntop(int af, const void *src, char * dst, int size);
TINYNET_API int tnet_sockfd_waitUntil(tnet_fd_t fd, long timeout, tsk_bool_t writable);
#define tnet_sockfd_waitUntilWritable(fd, timeout) tnet_sockfd_waitUntil(fd, timeout, tsk_true)
#define tnet_sockfd_waitUntilReadable(fd, timeout) tnet_sockfd_waitUntil(fd, timeout, tsk_false)

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -1,3 +1,21 @@
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#ifndef TNET_TEST_TARGETVER_H
#define TNET_TEST_TARGETVER_H

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
@ -21,6 +18,8 @@
*/
#include "stdafx.h"
#define BAIL_IF_ERR(expr) { int _ret_; if ((_ret_) = (expr)) { TSK_DEBUG_ERROR("Error %d", (_ret_)); goto bail; } }
#include "tsk.h"
#include "tinynet.h"

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org>
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
@ -17,6 +14,7 @@
*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
#ifndef TNET_TEST_ICE_H

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*
@ -22,13 +19,45 @@
#ifndef TNET_TEST_STUN_H
#define TNET_TEST_STUN_H
#define STUN_SERVER_IP "numb.viagenie.ca"
#define STUN_SERVER_PORT TNET_STUN_TCP_UDP_DEFAULT_PORT
#define STUN_SERVER_PROTO tnet_socket_type_udp_ipv4
#include "stun/tnet_stun_pkt.h"
#include "stun/tnet_stun_utils.h"
#define kStunServerIP "numb.viagenie.ca"
#define kStunServerPort kStunPortDefaultTcpUdp
#define kStunServerProto tnet_socket_type_udp_ipv4
#define TNET_TEST_STUN_SEND_BUFF(buff_ptr, buff_size) \
{ \
struct sockaddr_storage addr_to; \
tnet_socket_t* socket = tnet_socket_create(0, 0, kStunServerProto); \
tnet_sockaddr_init(kStunServerIP, kStunServerPort, kStunServerProto, &addr_to); \
tnet_sockfd_sendto(socket->fd, (const struct sockaddr *)&addr_to, (buff_ptr), (buff_size)); \
TSK_OBJECT_SAFE_FREE(socket); \
} \
uint8_t __parse_buff_write_ptr[1200];
static const tsk_size_t __parse_buff_write_size = sizeof(__parse_buff_write_ptr)/sizeof(__parse_buff_write_ptr[0]);
uint8_t __parse_buff_read_ptr[1200];
static const tsk_size_t __parse_buff_read_size = sizeof(__parse_buff_read_ptr)/sizeof(__parse_buff_read_ptr[0]);
// http://tools.ietf.org/html/draft-ietf-behave-stun-test-vectors-04
void test_stun_dump_transacid(tnet_stun_transacid_t transcid)
static int test_stun_buff_cmp(const uint8_t* pc_buf1_ptr, tsk_size_t n_buff1_size, const uint8_t* pc_buf2_ptr, tsk_size_t n_buff2_size)
{
int ret;
tsk_size_t u;
if (!pc_buf1_ptr || !pc_buf2_ptr || (n_buff1_size != n_buff2_size)) {
return -1;
}
for (u = 0; u < n_buff1_size; ++u) {
if ((ret = (pc_buf1_ptr[u] - pc_buf2_ptr[u]))) {
return ret;
}
}
return 0;
}
static void test_stun_dump_transacid(tnet_stun_transacid_t transcid)
{
char transac_idstriing[TNET_STUN_TRANSACID_SIZE*2+1];
tsk_str_from_hex(transcid, TNET_STUN_TRANSACID_SIZE, transac_idstriing);
@ -38,8 +67,41 @@ void test_stun_dump_transacid(tnet_stun_transacid_t transcid)
TSK_DEBUG_INFO("STUN transac id:%s", transac_idstriing);
}
void test_sun_sendMessage()
static void test_sun_parser()
{
tnet_stun_pkt_t* p_pkt = tsk_null;
tsk_size_t n_written_bytes, n_read_bytes;
static const char* __pc_mapped_addr_ipv4 = "192.168.0.37";
static const char* __pc_mapped_addr_ipv6 = "fdf8:f53b:82e4::53";
static const uint16_t __u_mapped_addr_port = 5060;
tnet_stun_addr_t addr_ipv4, addr_ipv6;
(n_read_bytes);
BAIL_IF_ERR(tnet_stun_pkt_create_empty(tnet_stun_pkt_type_binding_request, &p_pkt));
BAIL_IF_ERR(tnet_stun_utils_inet_pton_v4(__pc_mapped_addr_ipv4, &addr_ipv4));
BAIL_IF_ERR(tnet_stun_utils_inet_pton_v6(__pc_mapped_addr_ipv6, &addr_ipv6));
BAIL_IF_ERR(tnet_stun_pkt_add_attrs(p_pkt,
TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS_V4(__u_mapped_addr_port, &addr_ipv4),
TNET_STUN_PKT_ADD_ATTR_MAPPED_ADDRESS_V6(__u_mapped_addr_port, &addr_ipv6),
TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS_V4(__u_mapped_addr_port, &addr_ipv4),
TNET_STUN_PKT_ADD_ATTR_XOR_MAPPED_ADDRESS_V6(__u_mapped_addr_port, &addr_ipv6),
TNET_STUN_PKT_ADD_ATTR_NULL()));
BAIL_IF_ERR(tnet_stun_pkt_write_with_padding(p_pkt, __parse_buff_write_ptr, __parse_buff_write_size, &n_written_bytes));
// TNET_TEST_STUN_SEND_BUFF(__parse_buff_write_ptr, n_written_bytes);
TSK_OBJECT_SAFE_FREE(p_pkt);
BAIL_IF_ERR(tnet_stun_pkt_read(__parse_buff_write_ptr, n_written_bytes, &p_pkt));
BAIL_IF_ERR(tnet_stun_pkt_write_with_padding(p_pkt, __parse_buff_read_ptr, __parse_buff_read_size, &n_read_bytes));
TNET_TEST_STUN_SEND_BUFF(__parse_buff_read_ptr, n_read_bytes);
BAIL_IF_ERR(test_stun_buff_cmp(__parse_buff_write_ptr, n_written_bytes, __parse_buff_read_ptr, n_read_bytes));
TSK_DEBUG_INFO("test_sun_parser...OK");
bail:
TSK_OBJECT_SAFE_FREE(p_pkt);
#if 0
tnet_stun_message_t *message = tsk_null;
tsk_buffer_t *buffer = tsk_null;
tnet_socket_t *socket = tsk_null;
@ -70,13 +132,13 @@ void test_sun_sendMessage()
}
// Create blocking socket and bind it
socket = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO);
socket = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, kStunServerProto);
if(!TNET_SOCKET_IS_VALID(socket)){
goto bail;
}
// Create stun server's sockaddr structure
if(tnet_sockaddr_init(STUN_SERVER_IP, STUN_SERVER_PORT, STUN_SERVER_PROTO, &to)){
if(tnet_sockaddr_init(kStunServerIP, kStunServerPort, kStunServerProto, &to)){
goto bail;
}
@ -86,39 +148,12 @@ bail:
TSK_OBJECT_SAFE_FREE(message);
TSK_OBJECT_SAFE_FREE(socket);
TSK_OBJECT_SAFE_FREE(buffer);
#endif
}
void test_stun_context()
static void test_stun()
{
// tnet_socket_t *localSocket = 0;
// tnet_stun_context_t *context = 0;
//
// /* Somewhere in Your application ==> Create and bind your local socket
// */
// if(!(localSocket = tnet_socket_create_EX(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, STUN_SERVER_PROTO, 0)))
// {
// goto bail;
// }
//
// /* Create your STUN2 context
// */
// if(!(context = TNET_STUN_CONTEXT_CREATE("myusername", "mypassword", localSocket->fd)))
// {
// goto bail;
// }
//
// tnet_stun_resolve(context, STUN_SERVER_IP, STUN_SERVER_PORT, STUN_SERVER_PROTO);
//
//bail:
// TNET_OBJECT_SAFE_FREE(localSocket);
// TNET_OBJECT_SAFE_FREE(context);
}
void test_stun()
{
//test_stun_transacid();
test_sun_sendMessage();
//test_stun_context();
test_sun_parser();
}
#endif /* TNET_TEST_STUN_H */

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -1,7 +1,4 @@
/*
* Copyright (C) 2009 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
/* Copyright (C) 2014 Mamadou DIOP.
*
* This file is part of Open Source Doubango Framework.
*

View File

@ -228,6 +228,10 @@
RelativePath=".\src\stun\tnet_stun.c"
>
</File>
<File
RelativePath=".\src\stun\tnet_stun_attr.c"
>
</File>
<File
RelativePath=".\src\stun\tnet_stun_attribute.c"
>
@ -236,6 +240,14 @@
RelativePath=".\src\stun\tnet_stun_message.c"
>
</File>
<File
RelativePath=".\src\stun\tnet_stun_pkt.c"
>
</File>
<File
RelativePath=".\src\stun\tnet_stun_utils.c"
>
</File>
</Filter>
<Filter
Name="turn"
@ -460,6 +472,10 @@
RelativePath=".\src\stun\tnet_stun.h"
>
</File>
<File
RelativePath=".\src\stun\tnet_stun_attr.h"
>
</File>
<File
RelativePath=".\src\stun\tnet_stun_attribute.h"
>
@ -468,6 +484,18 @@
RelativePath=".\src\stun\tnet_stun_message.h"
>
</File>
<File
RelativePath=".\src\stun\tnet_stun_pkt.h"
>
</File>
<File
RelativePath=".\src\stun\tnet_stun_types.h"
>
</File>
<File
RelativePath=".\src\stun\tnet_stun_utils.h"
>
</File>
</Filter>
<Filter
Name="turn"