diff --git a/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_attr.c b/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_attr.c index 131f84c7..ea289763 100644 --- a/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_attr.c +++ b/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_attr.c @@ -21,6 +21,7 @@ #include "tnet_endianness.h" +#include "tsk_string.h" #include "tsk_memory.h" #include "tsk_debug.h" @@ -35,8 +36,12 @@ (size_in_octes) += c; \ } -#define IS_XOR(e_type) \ +#define IS_ADDRESS_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) +#define IS_VDATA_UINT32(e_type) \ + (e_type == tnet_stun_attr_type_fingerprint || e_type == tnet_stun_attr_type_ice_priority) +#define IS_VDATA_UINT64(e_type) \ + (e_type == tnet_stun_attr_type_ice_controlled || e_type == tnet_stun_attr_type_ice_controlling) static int _tnet_stun_attr_cmp(const tsk_object_t *_att1, const tsk_object_t *_att2) { @@ -54,6 +59,7 @@ static int _tnet_stun_attr_get_size_in_octetunits(const tnet_stun_attr_t* pc_sel } switch (pc_self->hdr.e_type) { case tnet_stun_attr_type_mapped_address: + case tnet_stun_attr_type_alternate_server: case tnet_stun_attr_type_xor_mapped_address: case tnet_stun_attr_type_xor_peer_address: case tnet_stun_attr_type_xor_relayed_address: { @@ -69,8 +75,18 @@ static int _tnet_stun_attr_get_size_in_octetunits(const tnet_stun_attr_t* pc_sel } return 0; } + case tnet_stun_attr_type_unknown_attrs: + case tnet_stun_attr_type_software: + case tnet_stun_attr_type_nonce: + case tnet_stun_attr_type_realm: case tnet_stun_attr_type_username: - case tnet_stun_attr_type_password: { + case tnet_stun_attr_type_password: + case tnet_stun_attr_type_message_integrity: + case tnet_stun_attr_type_fingerprint: + case tnet_stun_attr_type_ice_use_candidate: + case tnet_stun_attr_type_ice_priority: + case tnet_stun_attr_type_ice_controlled: + case tnet_stun_attr_type_ice_controlling: { 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) { @@ -83,6 +99,14 @@ static int _tnet_stun_attr_get_size_in_octetunits(const tnet_stun_attr_t* pc_sel } return 0; } + case tnet_stun_attr_type_error_code: { + const tnet_stun_attr_error_code_t* _pc_self = (const tnet_stun_attr_error_code_t*)pc_self; + *p_size = (kStunAttrHdrSizeInOctets + 4 + tsk_strlen(_pc_self->p_reason_phrase)); + 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); @@ -116,13 +140,14 @@ static int _tnet_stun_attr_write(const tnet_stun_transac_id_t* pc_transac_id, co switch (pc_self->hdr.e_type) { case tnet_stun_attr_type_mapped_address: + case tnet_stun_attr_type_alternate_server: 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); + tsk_bool_t b_xor = IS_ADDRESS_XOR(pc_self->hdr.e_type); if (pc_self->__def__ != tnet_stun_attr_address_def_t) { TSK_DEBUG_ERROR("Invalid base type"); return -2; @@ -155,8 +180,19 @@ static int _tnet_stun_attr_write(const tnet_stun_transac_id_t* pc_transac_id, co } return 0; } + + case tnet_stun_attr_type_unknown_attrs: + case tnet_stun_attr_type_software: + case tnet_stun_attr_type_nonce: + case tnet_stun_attr_type_realm: case tnet_stun_attr_type_username: - case tnet_stun_attr_type_password: { + case tnet_stun_attr_type_password: + case tnet_stun_attr_type_message_integrity: + case tnet_stun_attr_type_fingerprint: + case tnet_stun_attr_type_ice_use_candidate: + case tnet_stun_attr_type_ice_priority: + case tnet_stun_attr_type_ice_controlled: + case tnet_stun_attr_type_ice_controlling: { 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) { @@ -164,7 +200,22 @@ static int _tnet_stun_attr_write(const tnet_stun_transac_id_t* pc_transac_id, co 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); + if (IS_VDATA_UINT32(pc_self->hdr.e_type) && _pc_self->u_data_size == 4) { + *((uint32_t*)&p_buff_ptr[*p_written]) = tnet_htonl_2(&_pc_self->p_data_ptr[0]); + } + else if (IS_VDATA_UINT64(pc_self->hdr.e_type) && _pc_self->u_data_size == 8) { + *((uint32_t*)&p_buff_ptr[*p_written]) = tnet_htonl_2(&_pc_self->p_data_ptr[0]); + *((uint32_t*)&p_buff_ptr[*p_written + 4]) = tnet_htonl_2(&_pc_self->p_data_ptr[4]); + } + else if (pc_self->hdr.e_type == tnet_stun_attr_type_unknown_attrs && _pc_self->u_data_size && !(_pc_self->u_data_size & 1)) { + uint16_t u; + for (u = 0; u < _pc_self->u_data_size; u+=2) { + *((uint16_t*)&p_buff_ptr[*p_written + u]) = tnet_htons_2(&_pc_self->p_data_ptr[u]); + } + } + else { + 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); @@ -173,6 +224,19 @@ static int _tnet_stun_attr_write(const tnet_stun_transac_id_t* pc_transac_id, co } return 0; } + case tnet_stun_attr_type_error_code: { + const tnet_stun_attr_error_code_t* _pc_self = (const tnet_stun_attr_error_code_t*)pc_self; + *((uint32_t*)&p_buff_ptr[*p_written]) = tnet_htonl(((_pc_self->u_class & 0x07) << 8) | _pc_self->u_number); + if (_pc_self->p_reason_phrase) { + memcpy(&p_buff_ptr[*p_written + 4], _pc_self->p_reason_phrase, tsk_strlen(_pc_self->p_reason_phrase)); + } + *p_written += 4 + tsk_strlen(_pc_self->p_reason_phrase); + *((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; @@ -241,6 +305,7 @@ int tnet_stun_attr_read(const tnet_stun_transac_id_t* pc_transac_id, const uint8 switch (Type) { case tnet_stun_attr_type_mapped_address: + case tnet_stun_attr_type_alternate_server: case tnet_stun_attr_type_xor_mapped_address: case tnet_stun_attr_type_xor_peer_address: case tnet_stun_attr_type_xor_relayed_address: { @@ -248,7 +313,7 @@ int tnet_stun_attr_read(const tnet_stun_transac_id_t* pc_transac_id, const uint8 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); + tsk_bool_t b_xor = IS_ADDRESS_XOR(Type); uint16_t u, u_addr_size = (e_family == tnet_stun_address_family_ipv6) ? 16 : 4; if (b_xor) { @@ -271,17 +336,70 @@ int tnet_stun_attr_read(const tnet_stun_transac_id_t* pc_transac_id, const uint8 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_error_code: { + // First 21bits must be ignored + uint8_t Class = pc_buff_ptr[6] & 0x07; + uint8_t Number = pc_buff_ptr[7] & 0xff; + tnet_stun_attr_error_code_t* p_attr; + if ((ret = tnet_stun_attr_error_code_create(Class, Number, &pc_buff_ptr[8], (Length - 4), &p_attr))) { + return ret; + } + *pp_attr = TNET_STUN_ATTR(p_attr); + break; + } + + case tnet_stun_attr_type_unknown_attrs: + case tnet_stun_attr_type_software: + case tnet_stun_attr_type_nonce: + case tnet_stun_attr_type_realm: case tnet_stun_attr_type_username: case tnet_stun_attr_type_password: + case tnet_stun_attr_type_message_integrity: + case tnet_stun_attr_type_fingerprint: + case tnet_stun_attr_type_ice_use_candidate: + case tnet_stun_attr_type_ice_priority: + case tnet_stun_attr_type_ice_controlled: + case tnet_stun_attr_type_ice_controlling: 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; + if (IS_VDATA_UINT32(Type) && Length == 4) { + uint32_t u32 = tnet_ntohl_2(&pc_buff_ptr[4]); + if ((ret = tnet_stun_attr_vdata_create(Type, (uint8_t*)&u32, 4, &p_attr))) { + return ret; + } + } + else if (IS_VDATA_UINT64(Type) && Length == 8) { + uint64_t u64 = ((uint64_t)tnet_ntohl_2(&pc_buff_ptr[4])) << 32; + u64 |= tnet_ntohl_2(&pc_buff_ptr[8]); + if ((ret = tnet_stun_attr_vdata_create(Type, (uint8_t*)&u64, 8, &p_attr))) { + return ret; + } + } + else if (Type == tnet_stun_attr_type_unknown_attrs && Length && !(Length & 1)) { + uint16_t u; + uint8_t *_p_data_ptr = tsk_malloc(Length); + if (!_p_data_ptr) { + TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", Length); + return -4; + } + memcpy(_p_data_ptr, &pc_buff_ptr[4], Length); + for (u = 0; u < Length; u+=2) { + *((uint16_t*)&_p_data_ptr[u]) = tnet_htons_2(&_p_data_ptr[u]); + } + if ((ret = tnet_stun_attr_vdata_create(Type, _p_data_ptr, Length, &p_attr))) { + TSK_FREE(_p_data_ptr); + return ret; + } + TSK_FREE(_p_data_ptr); + } + else { + 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; @@ -317,6 +435,7 @@ int tnet_stun_attr_vdata_create(tnet_stun_attr_type_t e_type, const uint8_t* pc_ memcpy(p_attr->p_data_ptr, pc_data_ptr, u_length); p_attr->u_data_size = u_length; } + *pp_attr = p_attr; bail: if (ret) { @@ -404,3 +523,64 @@ static const tsk_object_def_t tnet_stun_attr_address_def_s = { _tnet_stun_attr_cmp, }; const tsk_object_def_t *tnet_stun_attr_address_def_t = &tnet_stun_attr_address_def_s; + + + +// ================ 15.6. ERROR-CODE ========== // +int tnet_stun_attr_error_code_create(uint8_t u_class, uint8_t u_number, const void* pc_reason_phrase, uint16_t u_reason_phrase, struct tnet_stun_attr_error_code_s** pp_attr) +{ + int ret = - 1; + extern const tsk_object_def_t *tnet_stun_attr_error_code_def_t; + tnet_stun_attr_error_code_t* p_attr = tsk_null; + uint16_t u_length = 4 + tsk_strlen(pc_reason_phrase); + if (!pp_attr) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if (!(p_attr = tsk_object_new(tnet_stun_attr_error_code_def_t))) { + ret = -2; + goto bail; + } + if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), tnet_stun_attr_type_error_code, u_length))) { + goto bail; + } + p_attr->u_class = u_class; + p_attr->u_number = u_number; + if (pc_reason_phrase && u_reason_phrase) { + if (!(p_attr->p_reason_phrase = tsk_strndup(pc_reason_phrase, u_reason_phrase))) { + ret = -3; + goto bail; + } + } + *pp_attr = p_attr; + +bail: + if (ret) { + TSK_OBJECT_SAFE_FREE(p_attr); + } + return ret; +} + +static tsk_object_t* tnet_stun_attr_error_code_ctor(tsk_object_t * self, va_list * app) +{ + tnet_stun_attr_error_code_t *p_ec = (tnet_stun_attr_error_code_t *)self; + if (p_ec) { + } + return self; +} +static tsk_object_t* tnet_stun_attr_error_code_dtor(tsk_object_t * self) +{ + tnet_stun_attr_error_code_t *p_ec = (tnet_stun_attr_error_code_t *)self; + if (p_ec) { + TSK_DEBUG_INFO("*** STUN Attribute(ERROR-CODE) destroyed ***"); + TSK_FREE(p_ec->p_reason_phrase); + } + return self; +} +static const tsk_object_def_t tnet_stun_attr_error_code_def_s = { + sizeof(tnet_stun_attr_error_code_t), + tnet_stun_attr_error_code_ctor, + tnet_stun_attr_error_code_dtor, + _tnet_stun_attr_cmp, +}; +const tsk_object_def_t *tnet_stun_attr_error_code_def_t = &tnet_stun_attr_error_code_def_s; diff --git a/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_attr.h b/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_attr.h index 005fb28d..7ce8f8e0 100644 --- a/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_attr.h +++ b/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_attr.h @@ -48,7 +48,7 @@ TINYNET_API int tnet_stun_attr_write_without_padding(const tnet_stun_transac_id_ 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, ...) ================ // +// ============== VDATA (USERNAME, MESSAGE-INTEGRITY, REALM, NONCE, ...) ================ // typedef struct tnet_stun_attr_vdata_s { TNET_STUN_DECLARE_ATTR; uint8_t *p_data_ptr; @@ -56,7 +56,6 @@ typedef struct tnet_stun_attr_vdata_s { } 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; @@ -67,6 +66,15 @@ typedef struct tnet_stun_attr_address_s { 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); +// ================ 15.6. ERROR-CODE ========== // +typedef struct tnet_stun_attr_error_code_s { + TNET_STUN_DECLARE_ATTR; + uint8_t u_class; // 3bits + uint8_t u_number; // 8bits + char* p_reason_phrase; +} tnet_stun_attr_error_code_t; +int tnet_stun_attr_error_code_create(uint8_t u_class, uint8_t u_number, const void* pc_reason_phrase, uint16_t u_reason_phrase, struct tnet_stun_attr_error_code_s** pp_attr); + TNET_END_DECLS #endif /* TNET_STUN_ATTR_H */ diff --git a/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_pkt.c b/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_pkt.c index 6ca111eb..f0f05cf3 100644 --- a/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_pkt.c +++ b/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_pkt.c @@ -21,6 +21,8 @@ #include "tnet_endianness.h" +#include "tsk_buffer.h" +#include "tsk_string.h" #include "tsk_memory.h" #include "tsk_debug.h" @@ -104,6 +106,52 @@ int tnet_stun_pkt_add_attrs(tnet_stun_pkt_t* p_self, ...) } break; } + case tnet_stun_pkt_add_attr_error_code: { + // (uint8_t)(U8_CLASS), (uint8_t)(U8_NUMBER), (const char*)(PC_REASON_STR) + uint8_t U8_CLASS = va_arg(ap, uint8_t); + uint8_t U8_NUMBER = va_arg(ap, uint8_t); + const char* PC_REASON_STR = va_arg(ap, const char*); + tnet_stun_attr_error_code_t *p_attr; + if ((ret = tnet_stun_attr_error_code_create(U8_CLASS, U8_NUMBER, PC_REASON_STR, tsk_strlen(PC_REASON_STR), &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_unknown_attrs: { + // (...) + tsk_buffer_t* p_buffer = tsk_buffer_create_null(); + tnet_stun_attr_vdata_t *p_attr; + uint16_t u_16; + if (!p_buffer) { + TSK_DEBUG_ERROR("Failed to create buffer"); + ret = -4; + goto bail; + } + while ((e_add_attr = va_arg(ap, tnet_stun_pkt_add_attr_t)) != tnet_stun_pkt_add_attr_null) { + if (e_add_attr != tnet_stun_pkt_add_attr_unknown_attrs_val) { + TSK_OBJECT_SAFE_FREE(p_buffer); + TSK_DEBUG_ERROR("Arguments corrupted or invalid."); + ret = -3; + goto bail; + } + u_16 = va_arg(ap, uint16_t); + tsk_buffer_append(p_buffer, &u_16, 2); + } + if ((ret = tnet_stun_attr_vdata_create(tnet_stun_attr_type_unknown_attrs, p_buffer->data, p_buffer->size, &p_attr))) { + TSK_OBJECT_SAFE_FREE(p_buffer); + goto bail; + } + TSK_OBJECT_SAFE_FREE(p_buffer); + 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; diff --git a/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_pkt.h b/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_pkt.h index 2c51ac52..20289f95 100644 --- a/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_pkt.h +++ b/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_pkt.h @@ -54,12 +54,18 @@ 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_address, + tnet_stun_pkt_add_attr_error_code, + tnet_stun_pkt_add_attr_unknown_attrs, + tnet_stun_pkt_add_attr_unknown_attrs_val, } 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_UINT32(E_TYPE, U32) TNET_STUN_PKT_ADD_ATTR_VDATA(E_TYPE, &U32, 4) +#define TNET_STUN_PKT_ADD_ATTR_UINT64(E_TYPE, U64) TNET_STUN_PKT_ADD_ATTR_VDATA(E_TYPE, &U64, 8) +#define TNET_STUN_PKT_ADD_ATTR_STR(E_TYPE, PC_STR) TNET_STUN_PKT_ADD_ATTR_VDATA(E_TYPE, PC_STR, tsk_strlen(PC_STR)) #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)) @@ -71,6 +77,38 @@ tnet_stun_pkt_add_attr_t; #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)) +// rfc5389 - 15.3. USERNAME +#define TNET_STUN_PKT_ADD_ATTR_USERNAME(PC_USERNAME_STR, U_USERNAME_STR) TNET_STUN_PKT_ADD_ATTR_VDATA(tnet_stun_attr_type_username, (PC_USERNAME_STR), (U_USERNAME_STR)) +#define TNET_STUN_PKT_ADD_ATTR_USERNAME_ZT(PC_USERNAME_STR) TNET_STUN_PKT_ADD_ATTR_USERNAME(PC_USERNAME_STR, tsk_strlen(PC_USERNAME_STR)) +// rfc5389 - 15.4. MESSAGE-INTEGRITY +#define TNET_STUN_PKT_ADD_ATTR_MESSAGE_INTEGRITY(PC_SHA1_STR, U_SHA1_STR) TNET_STUN_PKT_ADD_ATTR_VDATA(tnet_stun_attr_type_message_integrity, (PC_SHA1_STR), (U_SHA1_STR)) +#define TNET_STUN_PKT_ADD_ATTR_MESSAGE_INTEGRITY_ZT(PC_SHA1_STR) TNET_STUN_PKT_ADD_ATTR_MESSAGE_INTEGRITY(PC_SHA1_STR, tsk_strlen(PC_SHA1_STR)) +// rfc5389 - 15.5. FINGERPRINT +#define TNET_STUN_PKT_ADD_ATTR_FINGERPRINT(U32_CRC32) TNET_STUN_PKT_ADD_ATTR_UINT32(tnet_stun_attr_type_fingerprint, U32_CRC32) +// rfc5389 - 15.6. ERROR-CODE +#define TNET_STUN_PKT_ADD_ATTR_ERROR_CODE(U8_CLASS, U8_NUMBER, PC_REASON_STR) tnet_stun_pkt_add_attr_error_code, (uint8_t)(U8_CLASS), (uint8_t)(U8_NUMBER), (const char*)(PC_REASON_STR) +#define TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_TRY_ALTERNATE() TNET_STUN_PKT_ADD_ATTR_ERROR_CODE(kStunErrorClassTryAlternate, kStunErrorNumberTryAlternate, kStunErrorPhraseTryAlternate) +#define TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_BAD_REQUEST() TNET_STUN_PKT_ADD_ATTR_ERROR_CODE(kStunErrorClassBadRequest, kStunErrorNumberBadRequest, kStunErrorPhraseBadRequest) +#define TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_UNAUTHORIZED() TNET_STUN_PKT_ADD_ATTR_ERROR_CODE(kStunErrorClassUnauthorized, kStunErrorNumberUnauthorized, kStunErrorPhraseUnauthorized) +#define TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_UNKNOWN_ATTRIBUTE() TNET_STUN_PKT_ADD_ATTR_ERROR_CODE(kStunErrorClassUnknownAttribute, kStunErrorNumberUnknownAttribute, kStunErrorPhraseUnknownAttribute) +#define TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_STALE_NONCE() TNET_STUN_PKT_ADD_ATTR_ERROR_CODE(kStunErrorClassStaleNonce, kStunErrorNumberStaleNonce, kStunErrorPhraseStaleNonce) +#define TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_SERVER_ERROR() TNET_STUN_PKT_ADD_ATTR_ERROR_CODE(kStunErrorClassServerError, kStunErrorNumberServerError, kStunErrorPhraseServerError) +// rfc5389 - 15.7. REALM +#define TNET_STUN_PKT_ADD_ATTR_REALM(PC_REALM_STR, U_REALM_STR) TNET_STUN_PKT_ADD_ATTR_VDATA(tnet_stun_attr_type_realm, (PC_REALM_STR), (U_REALM_STR)) +#define TNET_STUN_PKT_ADD_ATTR_REALM_ZT(PC_REALM_STR) TNET_STUN_PKT_ADD_ATTR_REALM(PC_REALM_STR, tsk_strlen(PC_REALM_STR)) +// rfc5389 - 15.8. NONCE +#define TNET_STUN_PKT_ADD_ATTR_NONCE(PC_NONCE_STR, U_NONCE_STR) TNET_STUN_PKT_ADD_ATTR_VDATA(tnet_stun_attr_type_nonce, (PC_NONCE_STR), (U_NONCE_STR)) +#define TNET_STUN_PKT_ADD_ATTR_NONCE_ZT(PC_NONCE_STR) TNET_STUN_PKT_ADD_ATTR_NONCE(PC_NONCE_STR, tsk_strlen(PC_NONCE_STR)) +// rfc5389 - 15.9. UNKNOWN-ATTRIBUTES +#define TNET_STUN_PKT_ADD_ATTR_UNKNOWN_ATTRS(...) tnet_stun_pkt_add_attr_unknown_attrs, ##__VA_ARGS__ +#define TNET_STUN_PKT_ADD_ATTR_UNKNOWN_ATTRS_VAL(U16_VAL) tnet_stun_pkt_add_attr_unknown_attrs_val, (uint16_t)U16_VAL +// rfc5389 - 15.10. SOFTWARE +#define TNET_STUN_PKT_ADD_ATTR_SOFTWARE(PC_SOFTWARE_STR, U_SOFTWARE_STR) TNET_STUN_PKT_ADD_ATTR_VDATA(tnet_stun_attr_type_software, (PC_SOFTWARE_STR), (U_SOFTWARE_STR)) +#define TNET_STUN_PKT_ADD_ATTR_SOFTWARE_ZT(PC_SOFTWARE_STR) TNET_STUN_PKT_ADD_ATTR_SOFTWARE(PC_SOFTWARE_STR, tsk_strlen(PC_SOFTWARE_STR)) +// rfc5389 - 15.11. ALTERNATE-SERVER +#define TNET_STUN_PKT_ADD_ATTR_ALTERNATE_SERVER(E_FAMILY, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ADDRESS(tnet_stun_attr_type_alternate_server, (E_FAMILY), (U_PORT), (PC_ADDR_PTR)) +#define TNET_STUN_PKT_ADD_ATTR_ALTERNATE_SERVER_V4(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ALTERNATE_SERVER(tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR)) +#define TNET_STUN_PKT_ADD_ATTR_ALTERNATE_SERVER_V6(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ADD_ATTR_ALTERNATE_SERVER(tnet_stun_address_family_ipv6, (U_PORT), (PC_ADDR_PTR)) typedef struct tnet_stun_pkt_s { TSK_DECLARE_OBJECT; diff --git a/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_types.h b/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_types.h index 40372ba5..b0dbd1ac 100644 --- a/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_types.h +++ b/branches/2.0/doubango/tinyNET/src/stun/tnet_stun_types.h @@ -126,6 +126,26 @@ typedef enum tnet_stun_address_family_e { tnet_stun_address_family_ipv6 = 0x02 } tnet_stun_address_family_t; +// RFC 5389 - 15.6. ERROR-CODE +#define kStunErrorClassTryAlternate 3 +#define kStunErrorNumberTryAlternate 0 +#define kStunErrorPhraseTryAlternate "Try Alternate" +#define kStunErrorClassBadRequest 4 +#define kStunErrorNumberBadRequest 0 +#define kStunErrorPhraseBadRequest "Bad Request" +#define kStunErrorClassUnauthorized 4 +#define kStunErrorNumberUnauthorized 1 +#define kStunErrorPhraseUnauthorized "Unauthorized" +#define kStunErrorClassUnknownAttribute 4 +#define kStunErrorNumberUnknownAttribute 20 +#define kStunErrorPhraseUnknownAttribute "Unknown Attribute" +#define kStunErrorClassStaleNonce 4 +#define kStunErrorNumberStaleNonce 38 +#define kStunErrorPhraseStaleNonce "Stale Nonce" +#define kStunErrorClassServerError 5 +#define kStunErrorNumberServerError 0 +#define kStunErrorPhraseServerError "Server Error" + /**@ingroup tnet_stun_group * STUN attr types as per RFC 5389 subclause 18.2. **/ diff --git a/branches/2.0/doubango/tinyNET/test/test_stun.h b/branches/2.0/doubango/tinyNET/test/test_stun.h index 9ddb09aa..cff332a7 100644 --- a/branches/2.0/doubango/tinyNET/test/test_stun.h +++ b/branches/2.0/doubango/tinyNET/test/test_stun.h @@ -74,7 +74,21 @@ static void test_sun_parser() 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; + static const char __pc_username[] = "Mamadou DIOP"; + static const uint16_t __u_username = sizeof(__pc_username); + static const char __pc_integrity[TSK_SHA1_DIGEST_SIZE] = { 0 }; + static const uint16_t __u_integrity = sizeof(__pc_integrity); + static const uint32_t __u_fingerprint = 19831983; + static const uint8_t __u_error_class = 4; // (4 * 100) = 404 + static const uint8_t __u_error_number = 4; // + 4 = 404 + static const char* __pc_error_reason = "Not Found"; tnet_stun_addr_t addr_ipv4, addr_ipv6; + static const char __pc_realm[] = "doubango.org"; + static const uint16_t __u_realm = sizeof(__pc_realm); + static const char __pc_nonce[128] = { 0 }; + static const uint16_t __u_nonce = sizeof(__pc_nonce); + static const char __pc_software[] = "tinyNET 2.0"; + static const uint16_t __u_software = sizeof(__pc_software); (n_read_bytes); @@ -86,14 +100,37 @@ static void test_sun_parser() 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_USERNAME_ZT(__pc_username), + TNET_STUN_PKT_ADD_ATTR_MESSAGE_INTEGRITY(__pc_integrity, __u_integrity), + TNET_STUN_PKT_ADD_ATTR_ERROR_CODE(__u_error_class, __u_error_number, __pc_error_reason), + TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_TRY_ALTERNATE(), + TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_BAD_REQUEST(), + TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_UNAUTHORIZED(), + TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_UNKNOWN_ATTRIBUTE(), + TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_STALE_NONCE(), + TNET_STUN_PKT_ADD_ATTR_ERROR_CODE_SERVER_ERROR(), + TNET_STUN_PKT_ADD_ATTR_REALM_ZT(__pc_realm), + TNET_STUN_PKT_ADD_ATTR_NONCE(__pc_nonce, __u_nonce), + + TNET_STUN_PKT_ADD_ATTR_UNKNOWN_ATTRS( + TNET_STUN_PKT_ADD_ATTR_UNKNOWN_ATTRS_VAL(0x0001), // MAPPED-ADDRESS + TNET_STUN_PKT_ADD_ATTR_UNKNOWN_ATTRS_VAL(0x0006), // USERNAME + TNET_STUN_PKT_ADD_ATTR_UNKNOWN_ATTRS_VAL(0x0007), // PASSWORD + TNET_STUN_PKT_ADD_ATTR_NULL()), + + TNET_STUN_PKT_ADD_ATTR_SOFTWARE_ZT(__pc_software), + TNET_STUN_PKT_ADD_ATTR_ALTERNATE_SERVER_V4(__u_mapped_addr_port, &addr_ipv4), + TNET_STUN_PKT_ADD_ATTR_ALTERNATE_SERVER_V6(__u_mapped_addr_port, &addr_ipv6), + + TNET_STUN_PKT_ADD_ATTR_FINGERPRINT(__u_fingerprint), 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); + 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); + //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");