TURN episode #3

This commit is contained in:
bossiel 2014-05-02 07:03:07 +00:00
parent e9c79f8911
commit 2a6fc091ce
10 changed files with 656 additions and 109 deletions

View File

@ -38,8 +38,10 @@
#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_UINT8(e_type) \
(e_type == tnet_stun_attr_type_requested_transport)
#define IS_VDATA_UINT32(e_type) \
(e_type == tnet_stun_attr_type_fingerprint || e_type == tnet_stun_attr_type_ice_priority)
(e_type == tnet_stun_attr_type_fingerprint || e_type == tnet_stun_attr_type_lifetime || 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)
@ -76,6 +78,7 @@ 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_dont_fragment:
case tnet_stun_attr_type_software:
case tnet_stun_attr_type_nonce:
case tnet_stun_attr_type_realm:
@ -83,6 +86,8 @@ static int _tnet_stun_attr_get_size_in_octetunits(const tnet_stun_attr_t* pc_sel
case tnet_stun_attr_type_password:
case tnet_stun_attr_type_message_integrity:
case tnet_stun_attr_type_fingerprint:
case tnet_stun_attr_type_lifetime:
case tnet_stun_attr_type_requested_transport:
case tnet_stun_attr_type_ice_use_candidate:
case tnet_stun_attr_type_ice_priority:
case tnet_stun_attr_type_ice_controlled:
@ -182,6 +187,7 @@ static int _tnet_stun_attr_write(const tnet_stun_transac_id_t* pc_transac_id, co
}
case tnet_stun_attr_type_unknown_attrs:
case tnet_stun_attr_type_dont_fragment:
case tnet_stun_attr_type_software:
case tnet_stun_attr_type_nonce:
case tnet_stun_attr_type_realm:
@ -189,6 +195,8 @@ static int _tnet_stun_attr_write(const tnet_stun_transac_id_t* pc_transac_id, co
case tnet_stun_attr_type_password:
case tnet_stun_attr_type_message_integrity:
case tnet_stun_attr_type_fingerprint:
case tnet_stun_attr_type_lifetime:
case tnet_stun_attr_type_requested_transport:
case tnet_stun_attr_type_ice_use_candidate:
case tnet_stun_attr_type_ice_priority:
case tnet_stun_attr_type_ice_controlled:
@ -353,6 +361,7 @@ int tnet_stun_attr_read(const tnet_stun_transac_id_t* pc_transac_id, const uint8
}
case tnet_stun_attr_type_unknown_attrs:
case tnet_stun_attr_type_dont_fragment:
case tnet_stun_attr_type_software:
case tnet_stun_attr_type_nonce:
case tnet_stun_attr_type_realm:
@ -360,6 +369,8 @@ int tnet_stun_attr_read(const tnet_stun_transac_id_t* pc_transac_id, const uint8
case tnet_stun_attr_type_password:
case tnet_stun_attr_type_message_integrity:
case tnet_stun_attr_type_fingerprint:
case tnet_stun_attr_type_lifetime:
case tnet_stun_attr_type_requested_transport:
case tnet_stun_attr_type_ice_use_candidate:
case tnet_stun_attr_type_ice_priority:
case tnet_stun_attr_type_ice_controlled:

View File

@ -52,7 +52,7 @@ int tnet_stun_pkt_create(tnet_stun_pkt_type_t e_type, uint16_t u_length, const t
return 0;
}
int tnet_stun_pkt_add_attr(tnet_stun_pkt_t* p_self, tnet_stun_attr_t** pp_attr)
int tnet_stun_pkt_attr_add(tnet_stun_pkt_t* p_self, tnet_stun_attr_t** pp_attr)
{
if (!p_self || !pp_attr || !*pp_attr) {
TSK_DEBUG_ERROR("Invalid parameter");
@ -62,20 +62,20 @@ int tnet_stun_pkt_add_attr(tnet_stun_pkt_t* p_self, tnet_stun_attr_t** pp_attr)
return 0;
}
int tnet_stun_pkt_add_attrs(tnet_stun_pkt_t* p_self, ...)
int tnet_stun_pkt_attrs_add(tnet_stun_pkt_t* p_self, ...)
{
va_list ap;
int ret = 0;
tnet_stun_pkt_add_attr_t e_add_attr;
tnet_stun_pkt_attr_add_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) {
while ((e_add_attr = va_arg(ap, tnet_stun_pkt_attr_add_t)) != tnet_stun_pkt_attr_add_null) {
switch (e_add_attr) {
case tnet_stun_pkt_add_attr_vdata: {
case tnet_stun_pkt_attr_add_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*);
@ -84,13 +84,13 @@ int tnet_stun_pkt_add_attrs(tnet_stun_pkt_t* p_self, ...)
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))) {
if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
TSK_OBJECT_SAFE_FREE(p_attr);
goto bail;
}
break;
}
case tnet_stun_pkt_add_attr_address: {
case tnet_stun_pkt_attr_add_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);
@ -100,13 +100,13 @@ int tnet_stun_pkt_add_attrs(tnet_stun_pkt_t* p_self, ...)
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))) {
if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
TSK_OBJECT_SAFE_FREE(p_attr);
goto bail;
}
break;
}
case tnet_stun_pkt_add_attr_error_code: {
case tnet_stun_pkt_attr_add_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);
@ -115,13 +115,13 @@ int tnet_stun_pkt_add_attrs(tnet_stun_pkt_t* p_self, ...)
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))) {
if ((ret = tnet_stun_pkt_attr_add(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: {
case tnet_stun_pkt_attr_add_unknown_attrs: {
// (...)
tsk_buffer_t* p_buffer = tsk_buffer_create_null();
tnet_stun_attr_vdata_t *p_attr;
@ -131,8 +131,8 @@ int tnet_stun_pkt_add_attrs(tnet_stun_pkt_t* p_self, ...)
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) {
while ((e_add_attr = va_arg(ap, tnet_stun_pkt_attr_add_t)) != tnet_stun_pkt_attr_add_null) {
if (e_add_attr != tnet_stun_pkt_attr_add_unknown_attrs_val) {
TSK_OBJECT_SAFE_FREE(p_buffer);
TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
ret = -3;
@ -146,7 +146,7 @@ int tnet_stun_pkt_add_attrs(tnet_stun_pkt_t* p_self, ...)
goto bail;
}
TSK_OBJECT_SAFE_FREE(p_buffer);
if ((ret = tnet_stun_pkt_add_attr(p_self, (tnet_stun_attr_t**)&p_attr))) {
if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
TSK_OBJECT_SAFE_FREE(p_attr);
goto bail;
}
@ -165,6 +165,33 @@ bail:
return ret;
}
int tnet_stun_pkt_attr_find(const tnet_stun_pkt_t* pc_self, tnet_stun_attr_type_t e_type, tsk_size_t u_index, const tnet_stun_attr_t** ppc_attr)
{
const tsk_list_item_t* pc_item;
const tnet_stun_attr_t* pc_attr;
if (!pc_self || !ppc_attr) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
*ppc_attr = tsk_null;
tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
if (pc_attr->hdr.e_type == e_type && !u_index--) {
*ppc_attr = pc_attr;
break;
}
}
}
return 0;
}
tsk_bool_t tnet_stun_pkt_attr_exists(const tnet_stun_pkt_t* pc_self, tnet_stun_attr_type_t e_type)
{
const tnet_stun_attr_t* pc_attr;
int ret = tnet_stun_pkt_attr_find(pc_self, e_type, 0, &pc_attr);
return (pc_attr && (ret == 0));
}
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;
@ -314,7 +341,7 @@ int tnet_stun_pkt_read(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tnet
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))) {
if ((ret = tnet_stun_pkt_attr_add((*pp_pkt), &p_attr))) {
TSK_OBJECT_SAFE_FREE((*pp_pkt));
return ret;
}

View File

@ -50,65 +50,74 @@ TNET_BEGIN_DECLS
#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_error_code,
tnet_stun_pkt_add_attr_unknown_attrs,
tnet_stun_pkt_add_attr_unknown_attrs_val,
typedef enum tnet_stun_pkt_attr_add_e {
tnet_stun_pkt_attr_add_null = 0,
tnet_stun_pkt_attr_add_none = tnet_stun_pkt_attr_add_null,
tnet_stun_pkt_attr_add_vdata,
tnet_stun_pkt_attr_add_address,
tnet_stun_pkt_attr_add_error_code,
tnet_stun_pkt_attr_add_unknown_attrs,
tnet_stun_pkt_attr_add_unknown_attrs_val,
}
tnet_stun_pkt_add_attr_t;
tnet_stun_pkt_attr_add_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))
#define TNET_STUN_PKT_ATTR_ADD_NULL() tnet_stun_pkt_attr_add_null
#define TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, P_DATA_PTR, U_DATA_SIZE) tnet_stun_pkt_attr_add_vdata, (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
#define TNET_STUN_PKT_ATTR_ADD_UINT0(E_TYPE) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, 0, 0)
#define TNET_STUN_PKT_ATTR_ADD_UINT8(E_TYPE, U8) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, &U8, 1)
#define TNET_STUN_PKT_ATTR_ADD_UINT32(E_TYPE, U32) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, &U32, 4)
#define TNET_STUN_PKT_ATTR_ADD_UINT64(E_TYPE, U64) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, &U64, 8)
#define TNET_STUN_PKT_ATTR_ADD_STR(E_TYPE, PC_STR) TNET_STUN_PKT_ATTR_ADD_VDATA(E_TYPE, PC_STR, tsk_strlen(PC_STR))
#define TNET_STUN_PKT_ATTR_ADD_ADDRESS(E_TYPE, E_FAMILY, U_PORT, PC_ADDR_PTR) tnet_stun_pkt_attr_add_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_ATTR_ADD_ADDRESS_V4(E_TYPE, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_ADDRESS((E_TYPE), tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ATTR_ADD_ADDRESS_V6(E_TYPE, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_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))
#define TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS(E_FAMILY, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_ADDRESS(tnet_stun_attr_type_mapped_address, (E_FAMILY), (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS_V4(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS(tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS_V6(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_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))
#define TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS(E_FAMILY, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_ADDRESS(tnet_stun_attr_type_xor_mapped_address, (E_FAMILY), (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS_V4(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS(tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS_V6(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_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))
#define TNET_STUN_PKT_ATTR_ADD_USERNAME(PC_USERNAME_STR, U_USERNAME_STR) TNET_STUN_PKT_ATTR_ADD_VDATA(tnet_stun_attr_type_username, (PC_USERNAME_STR), (U_USERNAME_STR))
#define TNET_STUN_PKT_ATTR_ADD_USERNAME_ZT(PC_USERNAME_STR) TNET_STUN_PKT_ATTR_ADD_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))
#define TNET_STUN_PKT_ATTR_ADD_MESSAGE_INTEGRITY(PC_SHA1_STR, U_SHA1_STR) TNET_STUN_PKT_ATTR_ADD_VDATA(tnet_stun_attr_type_message_integrity, (PC_SHA1_STR), (U_SHA1_STR))
#define TNET_STUN_PKT_ATTR_ADD_MESSAGE_INTEGRITY_ZT(PC_SHA1_STR) TNET_STUN_PKT_ATTR_ADD_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)
#define TNET_STUN_PKT_ATTR_ADD_FINGERPRINT(U32_CRC32) TNET_STUN_PKT_ATTR_ADD_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)
#define TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(U8_CLASS, U8_NUMBER, PC_REASON_STR) tnet_stun_pkt_attr_add_error_code, (uint8_t)(U8_CLASS), (uint8_t)(U8_NUMBER), (const char*)(PC_REASON_STR)
#define TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_TRY_ALTERNATE() TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(kStunErrorClassTryAlternate, kStunErrorNumberTryAlternate, kStunErrorPhraseTryAlternate)
#define TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_BAD_REQUEST() TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(kStunErrorClassBadRequest, kStunErrorNumberBadRequest, kStunErrorPhraseBadRequest)
#define TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_UNAUTHORIZED() TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(kStunErrorClassUnauthorized, kStunErrorNumberUnauthorized, kStunErrorPhraseUnauthorized)
#define TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_UNKNOWN_ATTRIBUTE() TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(kStunErrorClassUnknownAttribute, kStunErrorNumberUnknownAttribute, kStunErrorPhraseUnknownAttribute)
#define TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_STALE_NONCE() TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(kStunErrorClassStaleNonce, kStunErrorNumberStaleNonce, kStunErrorPhraseStaleNonce)
#define TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_SERVER_ERROR() TNET_STUN_PKT_ATTR_ADD_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))
#define TNET_STUN_PKT_ATTR_ADD_REALM(PC_REALM_STR, U_REALM_STR) TNET_STUN_PKT_ATTR_ADD_VDATA(tnet_stun_attr_type_realm, (PC_REALM_STR), (U_REALM_STR))
#define TNET_STUN_PKT_ATTR_ADD_REALM_ZT(PC_REALM_STR) TNET_STUN_PKT_ATTR_ADD_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))
#define TNET_STUN_PKT_ATTR_ADD_NONCE(PC_NONCE_STR, U_NONCE_STR) TNET_STUN_PKT_ATTR_ADD_VDATA(tnet_stun_attr_type_nonce, (PC_NONCE_STR), (U_NONCE_STR))
#define TNET_STUN_PKT_ATTR_ADD_NONCE_ZT(PC_NONCE_STR) TNET_STUN_PKT_ATTR_ADD_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
#define TNET_STUN_PKT_ATTR_ADD_UNKNOWN_ATTRS(...) tnet_stun_pkt_attr_add_unknown_attrs, ##__VA_ARGS__
#define TNET_STUN_PKT_ATTR_ADD_UNKNOWN_ATTRS_VAL(U16_VAL) tnet_stun_pkt_attr_add_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))
#define TNET_STUN_PKT_ATTR_ADD_SOFTWARE(PC_SOFTWARE_STR, U_SOFTWARE_STR) TNET_STUN_PKT_ATTR_ADD_VDATA(tnet_stun_attr_type_software, (PC_SOFTWARE_STR), (U_SOFTWARE_STR))
#define TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(PC_SOFTWARE_STR) TNET_STUN_PKT_ATTR_ADD_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))
#define TNET_STUN_PKT_ATTR_ADD_ALTERNATE_SERVER(E_FAMILY, U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_ADDRESS(tnet_stun_attr_type_alternate_server, (E_FAMILY), (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ATTR_ADD_ALTERNATE_SERVER_V4(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_ALTERNATE_SERVER(tnet_stun_address_family_ipv4, (U_PORT), (PC_ADDR_PTR))
#define TNET_STUN_PKT_ATTR_ADD_ALTERNATE_SERVER_V6(U_PORT, PC_ADDR_PTR) TNET_STUN_PKT_ATTR_ADD_ALTERNATE_SERVER(tnet_stun_address_family_ipv6, (U_PORT), (PC_ADDR_PTR))
// rfc5766(TURN) - 14.2. LIFETIME
#define TNET_STUN_PKT_ATTR_ADD_LIFETIME(U32_LIFETIME) TNET_STUN_PKT_ATTR_ADD_UINT32(tnet_stun_attr_type_lifetime, U32_LIFETIME)
// rfc5766(TURN) - 14.7. REQUESTED-TRANSPORT
#define TNET_STUN_PKT_ATTR_ADD_REQUESTED_TRANSPORT(U8_PROTOCOL) TNET_STUN_PKT_ATTR_ADD_UINT8(tnet_stun_attr_type_requested_transport, U8_PROTOCOL)
// rfc5766(TURN) - 14.8. DONT-FRAGMENT
#define TNET_STUN_PKT_ATTR_ADD_DONT_FRAGMENT() TNET_STUN_PKT_ATTR_ADD_UINT0(tnet_stun_attr_type_dont_fragment)
typedef struct tnet_stun_pkt_s {
TSK_DECLARE_OBJECT;
@ -135,8 +144,11 @@ 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_attr_add(struct tnet_stun_pkt_s* p_self, struct tnet_stun_attr_s** pp_attr);
TINYNET_API int tnet_stun_pkt_attrs_add(struct tnet_stun_pkt_s* p_self, ...);
TINYNET_API int tnet_stun_pkt_attr_find(const struct tnet_stun_pkt_s* pc_self, enum tnet_stun_attr_type_e e_type, tsk_size_t u_index, const struct tnet_stun_attr_s** ppc_attr);
#define tnet_stun_pkt_attr_find_first(pc_self, e_type, ppc_attr) tnet_stun_pkt_attr_find((pc_self), (e_type), 0, (ppc_attr))
TINYNET_API tsk_bool_t tnet_stun_pkt_attr_exists(const struct tnet_stun_pkt_s* pc_self, enum tnet_stun_attr_type_e e_type);
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);

View File

@ -42,6 +42,14 @@ typedef uint8_t tnet_stun_addr_t[16]; // IPv4(32bits) or IPv6(128bits)
( PU8[4] == 0x21 && PU8[5] == 0x12 && PU8[6] == 0xA4 && PU8[7] == 0x42 ) \
)
#if !defined(kStunBuffMinPad)
# define kStunBuffMinPad 40 // to make the buffer kasher
#endif /* kStunBuffMinPad */
#if !defined(kStunSoftware)
# define kStunSoftware "tinyNET 2.0"
#endif /* kStunSoftware */
#if !defined(kStunPortDefaultTcpUdp)
# define kStunPortDefaultTcpUdp 3478
#endif /* kStunPortDefaultTcpUdp */
@ -127,24 +135,44 @@ typedef enum tnet_stun_address_family_e {
} 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"
#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"
// rfc5766 - 15. New STUN Error Response Codes
#define kStunErrorClassForbidden 4
#define kStunErrorNumberForbidden 3
#define kStunErrorPhraseForbidden "Forbidden"
#define kStunErrorClassAllocationMismatch 4
#define kStunErrorNumberAllocationMismatch 37
#define kStunErrorPhraseAllocationMismatch "Allocation Mismatch"
#define kStunErrorClassWrongCredentials 4
#define kStunErrorNumberWrongCredentials 42
#define kStunErrorPhraseWrongCredentials "Wrong Credentials"
#define kStunErrorClassUnsupportedTransportProtocol 4
#define kStunErrorNumberUnsupportedTransportProtocol 42
#define kStunErrorPhraseUnsupportedTransportProtocol "Unsupported Transport Protocol"
#define kStunErrorClassAllocationQuotaReached 4
#define kStunErrorNumberAllocationQuotaReached 86
#define kStunErrorPhraseAllocationQuotaReached "Allocation Quota Reached"
#define kStunErrorClassInsufficientCapacity 5
#define kStunErrorNumberInsufficientCapacity 8
#define kStunErrorPhraseInsufficientCapacity "Insufficient Capacity"
/**@ingroup tnet_stun_group
* STUN attr types as per RFC 5389 subclause 18.2.
@ -249,6 +277,22 @@ typedef enum tnet_stun_pkt_type_e {
}
tnet_stun_pkt_type_t;
// rfc5766 - 2.2. Allocations
#if !defined(kTurnAllocationTimeOutInSec)
# define kTurnAllocationTimeOutInSec 600 /* 10min */
#endif /* kTurnAllocationTimeOutInSec */
// rfc5766 - 2.3. Permissions
#if !defined(kTurnPermissionTimeOutInSec)
# define kTurnPermissionTimeOutInSec 300 /* 5min */
#endif /* kTurnPermissionTimeOutInSec */
// rfc5766 - 2.5. Channels
#if !defined(kTurnChannelBindingTimeOutInSec)
# define kTurnChannelBindingTimeOutInSec 600 /* 10min */
#endif /* kTurnChannelBindingTimeOutInSec */
TNET_END_DECLS
#endif /* TNET_STUN_TYPES_H */

View File

@ -0,0 +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.
*
*/
#include "turn/tnet_turn_attr.h"
#include "tsk_debug.h"

View File

@ -0,0 +1,32 @@
/* 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_TURN_ATTR_H
#define TNET_TURN_ATTR_H
#include "tinynet_config.h"
#include "stun/tnet_stun_types.h"
#include "tsk_object.h"
#include "tsk_list.h"
TNET_BEGIN_DECLS
TNET_END_DECLS
#endif /* TNET_TURN_ATTR_H */

View File

@ -0,0 +1,319 @@
/* 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 "turn/tnet_turn_session.h"
#include "stun/tnet_stun_pkt.h"
#include "stun/tnet_stun_utils.h"
#include "tinynet.h"
#include "tsk_string.h"
#include "tsk_timer.h"
#include "tsk_time.h"
#include "tsk_safeobj.h"
#include "tsk_debug.h"
typedef tnet_stun_pkt_t tnet_turn_pkt_t;
typedef struct tnet_turn_session_s
{
TSK_DECLARE_OBJECT;
tsk_bool_t b_prepared;
tsk_bool_t b_started;
uint32_t u_timeout_alloc_in_sec;
uint8_t u_req_transport;
tnet_turn_pkt_t* p_pkt_alloc;
void* p_buff_send_ptr;
tsk_size_t u_buff_send_size;
struct {
char* p_usr_name;
char* p_pwd;
char* p_realm;
} cred;
tnet_socket_t* p_lcl_sock;
struct sockaddr_storage srv_addr;
TSK_DECLARE_SAFEOBJ;
}
tnet_turn_session_t;
static int _tnet_turn_session_send_buff(tnet_turn_session_t* p_self, const void* pc_buff_ptr, tsk_size_t u_buff_size);
static int _tnet_turn_session_send_pkt(tnet_turn_session_t* p_self, const tnet_turn_pkt_t *pc_pkt);
int tnet_turn_session_create(struct tnet_socket_s* p_lcl_sock, const char* pc_srv_ip, uint16_t u_srv_port, struct tnet_turn_session_s** pp_self)
{
int ret;
extern const tsk_object_def_t *tnet_turn_session_def_t;
tnet_turn_session_t* p_self;
if (!p_lcl_sock || !TNET_SOCKET_IS_VALID(p_lcl_sock) || !pc_srv_ip || !u_srv_port || !pp_self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (!(p_self = tsk_object_new(tnet_turn_session_def_t))) {
TSK_DEBUG_ERROR("Failed to create 'tnet_turn_session_def_t' object");
return -2;
}
if ((ret = tnet_sockaddr_init(pc_srv_ip, u_srv_port, p_lcl_sock->type, &p_self->srv_addr))) {
TSK_DEBUG_ERROR("Invalid TURN SRV address [%s:%u]", pc_srv_ip, u_srv_port);
goto bail;
}
p_self->p_lcl_sock = tsk_object_ref(p_lcl_sock);
p_self->u_req_transport = TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type) ? IPPROTO_UDP : IPPROTO_TCP;
*pp_self = p_self;
bail:
if (ret) {
TSK_OBJECT_SAFE_FREE(p_self);
}
return ret;
}
int tnet_turn_session_create_2(const char* pc_lcl_ip, uint16_t u_lcl_port, enum tnet_socket_type_e e_lcl_type, const char* pc_srv_ip, uint16_t u_srv_port, struct tnet_turn_session_s** pp_self)
{
tnet_socket_t* p_lcl_sock;
int ret;
if (!pc_srv_ip || !u_srv_port || !pp_self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if(!(p_lcl_sock = tnet_socket_create(pc_lcl_ip, u_lcl_port, e_lcl_type))) {
TSK_DEBUG_ERROR("Failed to create socket(%s:%u$%d)", pc_lcl_ip, u_lcl_port, e_lcl_type);
return -2;
}
ret = tnet_turn_session_create(p_lcl_sock, pc_srv_ip, u_srv_port, pp_self);
TSK_OBJECT_SAFE_FREE(p_lcl_sock);
return ret;
}
int tnet_turn_session_set_cred(tnet_turn_session_t* p_self, const char* pc_usr_name, const char* pc_pwd)
{
if (!p_self || !pc_usr_name || !pc_pwd) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
tsk_strupdate(&p_self->cred.p_usr_name, pc_usr_name);
tsk_strupdate(&p_self->cred.p_pwd, pc_pwd);
return 0;
}
int tnet_turn_session_prepare(tnet_turn_session_t* p_self)
{
int ret = 0;
if (!p_self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
tsk_safeobj_lock(p_self);
if (p_self->b_prepared) {
goto bail;
}
TSK_OBJECT_SAFE_FREE(p_self->p_pkt_alloc);
// create Allocate Request
if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_allocate_request, &p_self->p_pkt_alloc))) {
TSK_DEBUG_ERROR("Failed to create TURN Allocate request");
goto bail;
}
// add attributes
ret = tnet_stun_pkt_attrs_add(p_self->p_pkt_alloc,
TNET_STUN_PKT_ATTR_ADD_LIFETIME(p_self->u_timeout_alloc_in_sec),
TNET_STUN_PKT_ATTR_ADD_REQUESTED_TRANSPORT(p_self->u_req_transport),
#if 0 // "numb.viagenie.ca" -> 420 Unknown attribute
TNET_STUN_PKT_ATTR_ADD_DONT_FRAGMENT(),
#endif
TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware),
TNET_STUN_PKT_ATTR_ADD_NULL());
if (ret) {
goto bail;
}
// FIXME
_tnet_turn_session_send_pkt(p_self, p_self->p_pkt_alloc);
p_self->b_prepared = tsk_true;
bail:
tsk_safeobj_unlock(p_self);
return ret;
}
int tnet_turn_session_start(tnet_turn_session_t* p_self)
{
int ret = 0;
if (!p_self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
tsk_safeobj_lock(p_self);
if (p_self->b_started) {
goto bail;
}
if (!p_self->b_prepared) {
TSK_DEBUG_ERROR("TURN session not prepared yet");
ret = -2;
goto bail;
}
p_self->b_started = tsk_true;
bail:
tsk_safeobj_unlock(p_self);
return ret;
}
int tnet_turn_session_stop(tnet_turn_session_t* p_self)
{
int ret = 0;
if (!p_self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
return ret;
}
static int _tnet_turn_session_send_buff(tnet_turn_session_t* p_self, const void* pc_buff_ptr, tsk_size_t u_buff_size)
{
int ret = 0;
tsk_size_t u_sent_bytes = 0;
if (!p_self || !pc_buff_ptr || !u_buff_size) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
// lock()
tsk_safeobj_lock(p_self);
#if 0
if (!p_self->b_started) {
TSK_DEBUG_ERROR("TURN session not started");
ret = -2;
goto bail;
}
#endif
if (p_self->u_req_transport == IPPROTO_UDP) {
u_sent_bytes = tnet_sockfd_sendto(p_self->p_lcl_sock->fd, (const struct sockaddr *)&p_self->srv_addr, pc_buff_ptr, u_buff_size);
}
else {
TSK_DEBUG_ERROR("Not implemented yet");
ret = -3;
goto bail;
}
if (u_sent_bytes != u_buff_size) {
TSK_DEBUG_ERROR("Failed to send %u bytes. Only %u sent", u_buff_size, u_sent_bytes);
ret = -2;
goto bail;
}
bail:
// unlock()
tsk_safeobj_unlock(p_self);
return ret;
}
static int _tnet_turn_session_send_pkt(tnet_turn_session_t* p_self, const tnet_turn_pkt_t *pc_pkt)
{
int ret;
tsk_size_t u_min_size;
if (!p_self || !pc_pkt) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
tsk_safeobj_lock(p_self);
if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_pkt, &u_min_size))) {
goto bail;
}
u_min_size += kStunBuffMinPad;
if (p_self->u_buff_send_size < u_min_size) {
if (!(p_self->p_buff_send_ptr = tsk_realloc(p_self->p_buff_send_ptr, u_min_size))) {
TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", u_min_size);
ret = -3;
p_self->u_buff_send_size = 0;
goto bail;
}
p_self->u_buff_send_size = u_min_size;
}
if ((ret = tnet_stun_pkt_write_with_padding(pc_pkt, p_self->p_buff_send_ptr, p_self->u_buff_send_size, &u_min_size))) {
goto bail;
}
if ((ret = _tnet_turn_session_send_buff(p_self, p_self->p_buff_send_ptr, u_min_size))) {
goto bail;
}
bail:
tsk_safeobj_unlock(p_self);
return ret;
}
static tsk_object_t* tnet_turn_session_ctor(tsk_object_t * self, va_list * app)
{
tnet_turn_session_t *p_ss = (tnet_turn_session_t *)self;
if (p_ss) {
p_ss->u_timeout_alloc_in_sec = kTurnAllocationTimeOutInSec;
tsk_safeobj_init(p_ss);
}
return self;
}
static tsk_object_t* tnet_turn_session_dtor(tsk_object_t * self)
{
tnet_turn_session_t *p_ss = (tnet_turn_session_t *)self;
if (p_ss) {
TSK_DEBUG_INFO("*** STUN Session destroyed ***");
// cred
TSK_FREE(p_ss->cred.p_usr_name);
TSK_FREE(p_ss->cred.p_pwd);
TSK_FREE(p_ss->cred.p_realm);
// others
TSK_OBJECT_SAFE_FREE(p_ss->p_pkt_alloc);
TSK_OBJECT_SAFE_FREE(p_ss->p_lcl_sock);
TSK_FREE(p_ss->p_buff_send_ptr);
tsk_safeobj_deinit(p_ss);
}
return self;
}
static int tnet_turn_session_cmp(const tsk_object_t *_ss1, const tsk_object_t *_ss2)
{
const tnet_turn_session_t *pc_ss1 = (const tnet_turn_session_t *)_ss1;
const tnet_turn_session_t *pc_ss2 = (const tnet_turn_session_t *)_ss2;
return (int)(pc_ss1 - pc_ss2);
}
static const tsk_object_def_t tnet_turn_session_def_s = {
sizeof(tnet_turn_session_t),
tnet_turn_session_ctor,
tnet_turn_session_dtor,
tnet_turn_session_cmp,
};
const tsk_object_def_t *tnet_turn_session_def_t = &tnet_turn_session_def_s;

View File

@ -0,0 +1,44 @@
/* 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_TURN_SESSION_H
#define TNET_TURN_SESSION_H
#include "tinynet_config.h"
#include "stun/tnet_stun_types.h"
TNET_BEGIN_DECLS
struct tnet_turn_session_s;
struct tnet_socket_s;
enum tnet_socket_type_e;
TINYNET_API int tnet_turn_session_create(struct tnet_socket_s* p_lcl_sock, const char* pc_srv_ip, uint16_t u_srv_port, struct tnet_turn_session_s** pp_self);
TINYNET_API int tnet_turn_session_create_2(const char* pc_lcl_ip, uint16_t u_lcl_port, enum tnet_socket_type_e e_lcl_type, const char* pc_srv_ip, uint16_t u_srv_port, struct tnet_turn_session_s** pp_self);
#define tnet_turn_session_create_3(e_lcl_type, pc_srv_ip, u_srv_port, pp_self) tnet_turn_session_create_2(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, (e_lcl_type), (pc_srv_ip), (u_srv_port), (pp_self))
#define tnet_turn_session_create_udp_ipv4(pc_srv_ip, u_srv_port, pp_self) tnet_turn_session_create_3(tnet_socket_type_udp_ipv4, pc_srv_ip, u_srv_port, pp_self)
#define tnet_turn_session_create_udp_ipv6(pc_srv_ip, u_srv_port, pp_self) tnet_turn_session_create_3(tnet_socket_type_udp_ipv6, pc_srv_ip, u_srv_port, pp_self)
#define tnet_turn_session_create_udp_ipv46(pc_srv_ip, u_srv_port, pp_self) tnet_turn_session_create_3(tnet_socket_type_udp_ipv46, pc_srv_ip, u_srv_port, pp_self)
TINYNET_API int tnet_turn_session_set_cred(struct tnet_turn_session_s* p_self, const char* pc_usr_name, const char* pc_pwd);
TINYNET_API int tnet_turn_session_prepare(struct tnet_turn_session_s* p_self);
TINYNET_API int tnet_turn_session_start(struct tnet_turn_session_s* p_self);
TINYNET_API int tnet_turn_session_stop(struct tnet_turn_session_s* p_self);
TNET_END_DECLS
#endif /* TNET_TURN_SESSION_H */

View File

@ -21,7 +21,10 @@
#include "stun/tnet_stun_pkt.h"
#include "stun/tnet_stun_utils.h"
#include "turn/tnet_turn_session.h"
#define kStunUsrName "bossiel@yahoo.fr"
#define kStunUsrName "bossiel@yahoo.fr"
#define kStunServerIP "numb.viagenie.ca"
#define kStunServerPort kStunPortDefaultTcpUdp
#define kStunServerProto tnet_socket_type_udp_ipv4
@ -89,41 +92,46 @@ static void test_sun_parser()
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);
static const uint32_t __u_life_time = 600;
static const uint32_t __u_req_transport = 17; // UDP
(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_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),
BAIL_IF_ERR(tnet_stun_pkt_attrs_add(p_pkt,
TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS_V4(__u_mapped_addr_port, &addr_ipv4),
TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS_V6(__u_mapped_addr_port, &addr_ipv6),
TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS_V4(__u_mapped_addr_port, &addr_ipv4),
TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS_V6(__u_mapped_addr_port, &addr_ipv6),
TNET_STUN_PKT_ATTR_ADD_USERNAME_ZT(__pc_username),
TNET_STUN_PKT_ATTR_ADD_MESSAGE_INTEGRITY(__pc_integrity, __u_integrity),
TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(__u_error_class, __u_error_number, __pc_error_reason),
TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_TRY_ALTERNATE(),
TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_BAD_REQUEST(),
TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_UNAUTHORIZED(),
TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_UNKNOWN_ATTRIBUTE(),
TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_STALE_NONCE(),
TNET_STUN_PKT_ATTR_ADD_ERROR_CODE_SERVER_ERROR(),
TNET_STUN_PKT_ATTR_ADD_REALM_ZT(__pc_realm),
TNET_STUN_PKT_ATTR_ADD_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_ATTR_ADD_UNKNOWN_ATTRS(
TNET_STUN_PKT_ATTR_ADD_UNKNOWN_ATTRS_VAL(0x0001), // MAPPED-ADDRESS
TNET_STUN_PKT_ATTR_ADD_UNKNOWN_ATTRS_VAL(0x0006), // USERNAME
TNET_STUN_PKT_ATTR_ADD_UNKNOWN_ATTRS_VAL(0x0007), // PASSWORD
TNET_STUN_PKT_ATTR_ADD_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_ATTR_ADD_SOFTWARE_ZT(__pc_software),
TNET_STUN_PKT_ATTR_ADD_ALTERNATE_SERVER_V4(__u_mapped_addr_port, &addr_ipv4),
TNET_STUN_PKT_ATTR_ADD_ALTERNATE_SERVER_V6(__u_mapped_addr_port, &addr_ipv6),
TNET_STUN_PKT_ATTR_ADD_LIFETIME(__u_life_time),
TNET_STUN_PKT_ATTR_ADD_REQUESTED_TRANSPORT(__u_req_transport),
TNET_STUN_PKT_ATTR_ADD_DONT_FRAGMENT(),
TNET_STUN_PKT_ADD_ATTR_FINGERPRINT(__u_fingerprint),
TNET_STUN_PKT_ADD_ATTR_NULL()));
TNET_STUN_PKT_ATTR_ADD_FINGERPRINT(__u_fingerprint),
TNET_STUN_PKT_ATTR_ADD_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);
@ -188,9 +196,22 @@ bail:
#endif
}
static void test_turn_session()
{
struct tnet_turn_session_s* p_ss = tsk_null;
BAIL_IF_ERR(tnet_turn_session_create_udp_ipv4(kStunServerIP, kStunServerPort, &p_ss));
BAIL_IF_ERR(tnet_turn_session_prepare(p_ss));
bail:
TSK_OBJECT_SAFE_FREE(p_ss);
}
static void test_stun()
{
test_sun_parser();
//test_sun_parser();
test_turn_session();
}
#endif /* TNET_TEST_STUN_H */

View File

@ -256,6 +256,10 @@
RelativePath=".\src\turn\tnet_turn.c"
>
</File>
<File
RelativePath=".\src\turn\tnet_turn_attr.c"
>
</File>
<File
RelativePath=".\src\turn\tnet_turn_attribute.c"
>
@ -264,6 +268,10 @@
RelativePath=".\src\turn\tnet_turn_message.c"
>
</File>
<File
RelativePath=".\src\turn\tnet_turn_session.c"
>
</File>
</Filter>
<Filter
Name="ice"
@ -504,6 +512,10 @@
RelativePath=".\src\turn\tnet_turn.h"
>
</File>
<File
RelativePath=".\src\turn\tnet_turn_attr.h"
>
</File>
<File
RelativePath=".\src\turn\tnet_turn_attribute.h"
>
@ -512,6 +524,10 @@
RelativePath=".\src\turn\tnet_turn_message.h"
>
</File>
<File
RelativePath=".\src\turn\tnet_turn_session.h"
>
</File>
</Filter>
<Filter
Name="ice"