diff options
Diffstat (limited to 'branches/1.0/tinyNET/src/stun')
-rw-r--r-- | branches/1.0/tinyNET/src/stun/tnet_stun.c | 440 | ||||
-rw-r--r-- | branches/1.0/tinyNET/src/stun/tnet_stun.h | 128 | ||||
-rw-r--r-- | branches/1.0/tinyNET/src/stun/tnet_stun_attribute.c | 960 | ||||
-rw-r--r-- | branches/1.0/tinyNET/src/stun/tnet_stun_attribute.h | 329 | ||||
-rw-r--r-- | branches/1.0/tinyNET/src/stun/tnet_stun_message.c | 440 | ||||
-rw-r--r-- | branches/1.0/tinyNET/src/stun/tnet_stun_message.h | 240 |
6 files changed, 0 insertions, 2537 deletions
diff --git a/branches/1.0/tinyNET/src/stun/tnet_stun.c b/branches/1.0/tinyNET/src/stun/tnet_stun.c deleted file mode 100644 index 5faa974..0000000 --- a/branches/1.0/tinyNET/src/stun/tnet_stun.c +++ /dev/null @@ -1,440 +0,0 @@ -/*
-* Copyright (C) 2009-2010 Mamadou Diop.
-*
-* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
-* 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 General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with DOUBANGO.
-*
-*/
-
-/**@file tnet_stun.c
- * @brief Session Traversal Utilities for NAT (STUN) implementation as per RFC 5389 and RFC 3489(Obsolete).
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#include "tnet_stun.h"
-
-#include "../tnet_nat.h"
-#include "../tnet_utils.h"
-
-#include "tsk_md5.h"
-#include "tsk_string.h"
-#include "tsk_memory.h"
-#include "tsk_buffer.h"
-#include "tsk_debug.h"
-
-#include <string.h>
-
-/**@defgroup tnet_stun_group STUN2 (RFC 5389) implementation.
-*/
-
-
-/**@ingroup tnet_stun_group
-* Creates new @ref tnet_stun_binding_t object.
-*/
-tnet_stun_binding_t* tnet_stun_binding_create(tnet_fd_t fd, tnet_socket_type_t socket_type, const char* server_address, tnet_port_t server_port, const char* username, const char* password)
-{
- return tsk_object_new(tnet_stun_binding_def_t, fd, socket_type, server_address, server_port, username, password);
-}
-
-/**@ingroup tnet_stun_group
- *
- * Create generic STUN2 request with all mandatory headers and attributes.
- *
- * @param [in,out] binding The binding object from which to create the request.
- *
- * @retval STUN2 request if succeed and NULL otherwise.
-**/
-tnet_stun_message_t *tnet_stun_create_request(const tnet_stun_binding_t* binding)
-{
- tnet_stun_message_t *message = tnet_stun_message_create(binding->username, binding->password);
- message->realm = tsk_strdup(binding->realm);
- message->nonce = tsk_strdup(binding->nonce);
-
- if(message){
- /* Set the request type (RFC 5389 defines only one type) */
- message->type = stun_binding_request;
-
- { /* Create random transaction id */
- tsk_istr_t random;
- tsk_md5digest_t digest;
-
- tsk_strrandom(&random);
- TSK_MD5_DIGEST_CALC(random, sizeof(random), digest);
-
- memcpy(message->transaction_id, digest, TNET_STUN_TRANSACID_SIZE);
- }
-
- /* Add software attribute */
- if(binding->software){
- tnet_stun_attribute_t* attribute = (tnet_stun_attribute_t*)tnet_stun_attribute_software_create(binding->software, tsk_strlen(binding->software));
- tnet_stun_message_add_attribute(message, &attribute);
- }
- }
-
- return message;
-}
-
-int tnet_stun_send_reliably(const tnet_stun_message_t* message)
-{
- return -1;
-}
-
-
-/**@ingroup tnet_stun_group
- *
- * Internal function to send a STUN message using unrealiable protocol such as UDP.
- *
- *
- * @param localFD The local file descriptor.
- * @param RTO The Retransmission TimeOut.
- * @param Rc The Number of retransmissions.
- * @param [in,out] message The message to send.
- * @param [in,out] server The destination STUN server.
- *
- * @return The response from the server or NULL if transport error.
-**/
-tnet_stun_response_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO, uint16_t Rc, const tnet_stun_message_t* message, struct sockaddr* server)
-{
- /* RFC 5389 - 7.2.1. Sending over UDP
- STUN indications are not retransmitted; thus, indication transactions over UDP
- are not reliable.
- */
- //int retransmit = (message->type == stun_binding_request);
-
- int ret = -1;
- uint16_t i, rto = RTO;
- struct timeval tv;
- fd_set set;
-
- tsk_buffer_t *buffer = tnet_stun_message_serialize(message);
- tnet_stun_response_t *response = 0;
-
- if(!buffer)
- {
- goto bail;
- }
-
- {
-//#ifndef SIO_UDP_CONNRESET
-//# ifndef IOC_VENDOR
-//# define IOC_VENDOR 0x18000000
-//# endif
-//# ifndef _WSAIOW
-//# define _WSAIOW(x,y) (IOC_IN|(x)|(y))
-//# endif
-//# define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
-//#endif
-// DWORD dwBytesReturned = 0;
-// BOOL bNewBehavior = TRUE;
-// DWORD status;
-//
-// // disable new behavior using
-// // IOCTL: SIO_UDP_CONNRESET
-// status = WSAIoctl(localFD, SIO_UDP_CONNRESET, &bNewBehavior, sizeof(bNewBehavior),
-// NULL, 0, &dwBytesReturned, NULL, NULL);
- }
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
-
- /* RFC 5389 - 7.2.1. Sending over UDP
- A client SHOULD retransmit a STUN request message starting with an
- interval of RTO ("Retransmission TimeOut"), doubling after each
- retransmission.
-
- e.g. 0 ms, 500 ms, 1500 ms, 3500 ms, 7500ms, 15500 ms, and 31500 ms
- */
- for(i=0; i<Rc; i++){
- tv.tv_sec += rto/1000;
- tv.tv_usec += (rto% 1000) * 1000;
-
- FD_ZERO(&set);
- FD_SET(localFD, &set);
-
- ret = tnet_sockfd_sendto(localFD, server, buffer->data, buffer->size);
-
- if((ret = select(localFD+1, &set, NULL, NULL, &tv))<0){
- goto bail;
- }
- else if(ret == 0){
- /* timeout */
- TSK_DEBUG_INFO("STUN request timedout at %d", i);
- rto *= 2;
- continue;
- }
- else if(FD_ISSET(localFD, &set)){
- /* there is data to read */
-
- tsk_size_t len = 0;
- void* data = 0;
-
- TSK_DEBUG_INFO("STUN request got response");
-
- /* Check how how many bytes are pending */
- if((ret = tnet_ioctlt(localFD, FIONREAD, &len))<0){
- goto bail;
- }
-
- if(len==0){
- TSK_DEBUG_INFO("tnet_ioctlt() returent zero bytes");
- continue;
- }
-
- /* Receive pending data */
- data = tsk_calloc(len, sizeof(uint8_t));
- if((ret = tnet_sockfd_recvfrom(localFD, data, len, 0, server))<0){
- TSK_FREE(data);
-
- TSK_DEBUG_ERROR("Recving STUN dgrams failed with error code:%d", tnet_geterrno());
- goto bail;
- }
-
- /* Parse the incoming response. */
- response = tnet_stun_message_deserialize(data, (tsk_size_t)ret);
- TSK_FREE(data);
-
- if(response){
- if(tnet_stun_transacid_cmp(message->transaction_id, response->transaction_id)){
- /* Not same transaction id */
- TSK_OBJECT_SAFE_FREE(response);
- continue;
- }
- }
-
- goto bail;
- }
- else{
- continue;
- }
- }
-
-bail:
- TSK_OBJECT_SAFE_FREE(buffer);
-
- return response;
-}
-
-/**@ingroup tnet_stun_group
- * Internal function to send a STUN2 binding request over the network.
- *
- * @param [in,out] context The NAT context holding the user preferences.
- * @param [in,out] binding The STUN binding object used to create the message to send.
- *
- * @return Zero if succeed and non-zero error code otherwise.
-**/
-int tnet_stun_send_bind(const tnet_nat_context_t* context, tnet_stun_binding_t *binding)
-{
- int ret = -1;
- tnet_stun_response_t *response = 0;
- tnet_stun_request_t *request = 0;
-
-
- goto stun_phase0;
-
- /* RFC 5389 - 10.2.1.1. First Request
- If the client has not completed a successful request/response
- transaction with the server (as identified by hostname, if the DNS
- procedures of Section 9 are used, else IP address if not), it SHOULD
- omit the USERNAME, MESSAGE-INTEGRITY, REALM, and NONCE attributes.
- In other words, the very first request is sent as if there were no
- authentication or message integrity applied.
- */
-stun_phase0:
- {
- if(!(request = tnet_stun_create_request(binding))){
- goto bail;
- }
-
- if(TNET_SOCKET_TYPE_IS_DGRAM(context->socket_type)){
- response = tnet_stun_send_unreliably(binding->localFD, context->RTO, context->Rc, request, (struct sockaddr*)&binding->server);
- }
-
- if(response){
- if(TNET_STUN_RESPONSE_IS_ERROR(response)){
- short code = tnet_stun_message_get_errorcode(response);
- const char* realm = tnet_stun_message_get_realm(response);
- const char* nonce = tnet_stun_message_get_nonce(response);
-
- if(code == 401 && realm && nonce){
- if(!binding->nonce){
- /* First time we get a nonce */
- tsk_strupdate(&binding->nonce, nonce);
- tsk_strupdate(&binding->realm, realm);
-
- /* Delete the message and response before retrying*/
- TSK_OBJECT_SAFE_FREE(response);
- TSK_OBJECT_SAFE_FREE(request);
-
- // Send again using new transaction identifier
- return tnet_stun_send_bind(context, binding);
- }
- else{
- ret = -3;
- }
- }
- else{
- ret = -2;
- }
- }
- else{
- const tnet_stun_attribute_t *attribute;
- if((attribute= tnet_stun_message_get_attribute(response, stun_xor_mapped_address))){
- ret = 0;
- binding->xmaddr = tsk_object_ref((void*)attribute);
- }
- else if((attribute= tnet_stun_message_get_attribute(response, stun_mapped_address))){
- ret = 0;
- binding->maddr = tsk_object_ref((void*)attribute);
- }
- }
- }
- }
- /* END OF stun_phase0 */
-
-bail:
- TSK_OBJECT_SAFE_FREE(response);
- TSK_OBJECT_SAFE_FREE(request);
-
- return ret;
-}
-
-/**@ingroup tnet_stun_group
- *
- * Public function to create a binding context.
- *
- * @param [in,out] nat_context The NAT context.
- * @param localFD The local file descriptor for which to create the binding context.
- *
- * @return A valid binding id if succeed and @ref TNET_STUN_INVALID_BINDING_ID otherwise. If the returned id is valid then
- * the newly created binding will contain the server reflexive address associated to the local file descriptor.
-**/
-tnet_stun_binding_id_t tnet_stun_bind(const tnet_nat_context_t* nat_context, tnet_fd_t localFD)
-{
- tnet_stun_binding_id_t id = TNET_STUN_INVALID_BINDING_ID;
-
- tnet_stun_binding_t *binding = 0;
-
- if(nat_context && localFD != TNET_INVALID_FD){
- if(!(binding = tnet_stun_binding_create(localFD, nat_context->socket_type, nat_context->server_address, nat_context->server_port, nat_context->username, nat_context->password))){
- goto bail;
- }
-
- if(tnet_stun_send_bind(nat_context, binding)){
- TSK_OBJECT_SAFE_FREE(binding);
- goto bail;
- }
-
- id = binding->id;
- tsk_list_push_back_data(nat_context->stun_bindings, (void**)&binding);
- }
-
-bail:
- return id;
-}
-
-/**@ingroup tnet_stun_group
- * Compares two transaction ids.
- *
- * @param id1 The first transaction identifier.
- * @param id2 The second transaction identifier.
- *
- * @return Zero if the two identifiers are equal and non-zero value otherwise.
-**/
-int tnet_stun_transacid_cmp(const tnet_stun_transacid_t id1, const tnet_stun_transacid_t id2)
-{
- tsk_size_t i;
- for(i=0; i<sizeof(tnet_stun_transacid_t); i++){
- if(id1[i] != id2[i]){
- return (id1[i] - id2[i]);
- }
- }
- return 0;
-}
-
-
-
-
-
-
-
-
-
-
-//=================================================================================================
-// STUN2 BINDING object definition
-//
-static tsk_object_t* tnet_stun_binding_ctor(tsk_object_t * self, va_list * app)
-{
- tnet_stun_binding_t *binding = self;
- if(binding){
- static tnet_stun_binding_id_t __binding_unique_id = 0;
-
- const char* server_address;
- tnet_port_t server_port;
-
- binding->id = ++__binding_unique_id;
-
- binding->localFD = va_arg(*app, tnet_fd_t);
- binding->socket_type = va_arg(*app, tnet_socket_type_t);
-
- server_address = tsk_strdup(va_arg(*app, const char*));
-#if defined(__GNUC__)
- server_port = (tnet_port_t)va_arg(*app, unsigned);
-#else
- server_port = va_arg(*app, tnet_port_t);
-#endif
-
- binding->username = tsk_strdup(va_arg(*app, const char*));
- binding->password = tsk_strdup(va_arg(*app, const char*));
-
- tnet_sockaddr_init(server_address, server_port, binding->socket_type, &binding->server);
-
- binding->software = tsk_strdup(TNET_SOFTWARE);
- }
- return self;
-}
-
-static tsk_object_t* tnet_stun_binding_dtor(tsk_object_t * self)
-{
- tnet_stun_binding_t *binding = self;
- if(binding){
- TSK_FREE(binding->username);
- TSK_FREE(binding->password);
- TSK_FREE(binding->realm);
- TSK_FREE(binding->nonce);
-
- TSK_FREE(binding->software);
-
- TSK_OBJECT_SAFE_FREE(binding->maddr);
- TSK_OBJECT_SAFE_FREE(binding->xmaddr);
- }
-
- return self;
-}
-
-static const tsk_object_def_t tnet_stun_binding_def_s =
-{
- sizeof(tnet_stun_binding_t),
- tnet_stun_binding_ctor,
- tnet_stun_binding_dtor,
- tsk_null,
-};
-const tsk_object_def_t *tnet_stun_binding_def_t = &tnet_stun_binding_def_s;
-
-
diff --git a/branches/1.0/tinyNET/src/stun/tnet_stun.h b/branches/1.0/tinyNET/src/stun/tnet_stun.h deleted file mode 100644 index 05933ca..0000000 --- a/branches/1.0/tinyNET/src/stun/tnet_stun.h +++ /dev/null @@ -1,128 +0,0 @@ -/*
-* Copyright (C) 2009-2010 Mamadou Diop.
-*
-* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
-* 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 General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with DOUBANGO.
-*
-*/
-
-/**@file tnet_stun.h
- * @brief Session Traversal Utilities for NAT (STUN) implementation as per RFC 5389 and RFC 3489(Obsolete).
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#ifndef TNET_STUN_H
-#define TNET_STUN_H
-
-#include "tinynet_config.h"
-#include "stun/tnet_stun_message.h"
-#include "tnet_types.h"
-#include "tnet_socket.h"
-
-#include "tsk_object.h"
-
-TNET_BEGIN_DECLS
-
-/**@ingroup tnet_stun_group
-*/
-typedef uint64_t tnet_stun_binding_id_t;
-/**@ingroup tnet_stun_group
- * @def TNET_STUN_INVALID_BINDING_ID
- * STUN2 invalid binding id.
-**/
-/**@ingroup tnet_stun_group
- * @def TNET_STUN_IS_VALID_BINDING_ID
- * Checks the validity of the STUN @a id.
-**/
-#define TNET_STUN_INVALID_BINDING_ID 0
-#define TNET_STUN_IS_VALID_BINDING_ID(id) (id != TNET_STUN_INVALID_BINDING_ID)
-
-/**@ingroup tnet_stun_group
- * Default port for both TCP and UDP protos as per RFC 5389 subclause 9.
-**/
-#define TNET_STUN_TCP_UDP_DEFAULT_PORT 3478
-
-/**@ingroup tnet_stun_group
- * Default port for TLS protocol as per RFC 5389 subclause 9.
-**/
-#define TNET_STUN_TLS_DEFAULT_PORT 5349
-
-
-/**@ingroup tnet_stun_group
- * STUN2 magic cookie value in network byte order as per RFC 5389 subclause 6.
-**/
-#define TNET_STUN_MAGIC_COOKIE 0x2112A442
-
-/**@ingroup tnet_stun_group
- * STUN2 header size as per RFC 5389 subclause 6.
-**/
-#define TNET_STUN_HEADER_SIZE 20
-
-/**@ingroup tnet_stun_group
- * STUN2 binding context.
-**/
-typedef struct tnet_stun_binding_s
-{
- TSK_DECLARE_OBJECT;
-
- //! A unique id to identify this binding.
- tnet_stun_binding_id_t id;
-
- //! The username to authenticate to the STUN server.
- char* username;
- //! The password to authenticate to the STUN server.
- char* password;
- //! The realm.
- char* realm;
- //! The nonce.
- char* nonce;
- //! The client name.
- char* software;
- //! Local file descriptor for which to get server reflexive address.
- tnet_fd_t localFD;
- //! The type of the bound socket.
- tnet_socket_type_t socket_type;
- //! The address of the STUN server.
- struct sockaddr_storage server;
- //! Server reflexive address of the local socket(STUN1 as per RFC 3489).
- tnet_stun_attribute_mapped_addr_t *maddr;
- //! XORed server reflexive address (STUN2 as per RFC 5389).
- tnet_stun_attribute_xmapped_addr_t *xmaddr;
-}tnet_stun_binding_t;
-
-TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_binding_def_t;
-/**@ingroup tnet_stun_group
- * List of @ref tnet_stun_binding_t elements.
-**/
-typedef tsk_list_t tnet_stun_bindings_L_t;
-
-//#if defined(__SYMBIAN32__) || ANDROID /* Forward declaration */
-struct tnet_nat_context_s;
-//#endif
-
-int tnet_stun_send_reliably(const tnet_stun_message_t* message);
-tnet_stun_response_t* tnet_stun_send_unreliably(tnet_fd_t localFD, uint16_t RTO, uint16_t Rc, const tnet_stun_message_t* message, struct sockaddr* server);
-TINYNET_API tnet_stun_binding_id_t tnet_stun_bind(const struct tnet_nat_context_s* nat_context, tnet_fd_t localFD);
-int tnet_stun_transacid_cmp(const tnet_stun_transacid_t id1, const tnet_stun_transacid_t id2);
-
-TNET_END_DECLS
-
-
-#endif /* TNET_STUN_H */
-
diff --git a/branches/1.0/tinyNET/src/stun/tnet_stun_attribute.c b/branches/1.0/tinyNET/src/stun/tnet_stun_attribute.c deleted file mode 100644 index feb6909..0000000 --- a/branches/1.0/tinyNET/src/stun/tnet_stun_attribute.c +++ /dev/null @@ -1,960 +0,0 @@ -/* -* Copyright (C) 2009-2010 Mamadou Diop. -* -* Contact: Mamadou Diop <diopmamadou(at)doubango.org> -* -* 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with DOUBANGO. -* -*/ - -/**@file tnet_stun_attribute.c - * @brief STUN2(RFC 5389) attribute parser. - * - * @author Mamadou Diop <diopmamadou(at)doubango.org> - * - * @date Created: Sat Nov 8 16:54:58 2009 mdiop - */ -#include "tnet_stun_attribute.h" - -#include "tnet_stun.h" - -#include "../tnet_types.h" -#include "../tnet_endianness.h" - -#include "../turn/tnet_turn_attribute.h" - -#include "tsk_memory.h" -#include "tsk_string.h" -#include "tsk_debug.h" - -#include <string.h> - - -/**@ingroup tnet_stun_group -* RFC 5389 - 15. STUN Attributes -* Creates new @ref tnet_stun_attribute_def_t object. -*/ -tnet_stun_attribute_t* tnet_stun_attribute_create() -{ - return tsk_object_new(tnet_stun_attribute_def_t); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.1. MAPPED-ADDRESS. -* Creates new @ref tnet_stun_attribute_mapped_addr_t object. -*/ -tnet_stun_attribute_mapped_addr_t* tnet_stun_attribute_mapped_address_create(const void* payload, tsk_size_t payload_size) -{ - return tsk_object_new(tnet_stun_attribute_mapped_addr_def_t, payload, payload_size); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.2. XOR-MAPPED-ADDRESS. -* Creates new @ref tnet_stun_attribute_xmapped_addr_t object. -*/ -tnet_stun_attribute_xmapped_addr_t* tnet_stun_attribute_xmapped_address_create(const void* payload, tsk_size_t payload_size) -{ - return tsk_object_new(tnet_stun_attribute_xmapped_addr_def_t, payload, payload_size); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.3. USERNAME. -* Creates new @ref tnet_stun_attribute_username_t object. -*/ -tnet_stun_attribute_username_t* tnet_stun_attribute_username_create(const void* payload, tsk_size_t payload_size) -{ - return tsk_object_new(tnet_stun_attribute_username_def_t, payload, payload_size); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.4. MESSAGE-INTEGRITY. -* Creates new @ref tnet_stun_attribute_integrity_t object. -*/ -tnet_stun_attribute_integrity_t* tnet_stun_attribute_integrity_create(const void* payload, tsk_size_t payload_size) -{ - return tsk_object_new(tnet_stun_attribute_integrity_def_t, payload, payload_size); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.5. FINGERPRINT. -* Creates new @ref tnet_stun_attribute_fingerprint_t object. -*/ -tnet_stun_attribute_fingerprint_t* tnet_stun_attribute_fingerprint_create(uint32_t fingerprint) -{ - return tsk_object_new(tnet_stun_attribute_fingerprint_def_t, fingerprint); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.6. ERROR-CODE -* Creates new @ref tnet_stun_attribute_errorcode_t object. -*/ -tnet_stun_attribute_errorcode_t* tnet_stun_attribute_errorcode_create(const void* payload, tsk_size_t payload_size) -{ - return tsk_object_new(tnet_stun_attribute_errorcode_def_t, payload, payload_size); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.7. REALM. -* Creates new @ref tnet_stun_attribute_realm_t object. -*/ -tnet_stun_attribute_realm_t* tnet_stun_attribute_realm_create(const void* payload, tsk_size_t payload_size) -{ - return tsk_object_new(tnet_stun_attribute_realm_def_t, payload, payload_size); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.8. NONCE. -* Creates new @ref tnet_stun_attribute_nonce_t object. -*/ -tnet_stun_attribute_nonce_t* tnet_stun_attribute_nonce_create(const void* payload, tsk_size_t payload_size) -{ - return tsk_object_new(tnet_stun_attribute_nonce_def_t, payload, payload_size); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.9. UNKNOWN-ATTRIBUTES. -* Creates new @ref tnet_stun_attribute_unknowns_t object. -*/ -tnet_stun_attribute_unknowns_t* tnet_stun_attribute_unknowns_create(const void* payload, tsk_size_t payload_size) -{ - return tsk_object_new(tnet_stun_attribute_unknowns_def_t, payload, payload_size); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.10. SOFTWARE. -* Creates new @ref tnet_stun_attribute_software_t object. -*/ -tnet_stun_attribute_software_t* tnet_stun_attribute_software_create(const void* payload, tsk_size_t payload_size) -{ - return tsk_object_new(tnet_stun_attribute_software_def_t, payload, payload_size); -} - -/**@ingroup tnet_stun_group -* RFC 5389 - 15.11. ALTERNATE-SERVER. -* Creates new @ref tnet_stun_attribute_altserver_t object. -*/ -tnet_stun_attribute_altserver_t* tnet_stun_attribute_altserver_create(const void* payload, tsk_size_t payload_size) -{ - return tsk_object_new(tnet_stun_attribute_altserver_def_t, payload, payload_size); -} - -/**@ingroup tnet_stun_group -* Creates @ref tnet_stun_attribute_t from raw buffer. -* @param data Raw buffer from which to create the STUN attribute.* -* @param size The size of the eaw buffer. -* @retval @ref tnet_stun_attribute_t object if succeed and NULL other wise. -*/ -tnet_stun_attribute_t* tnet_stun_attribute_deserialize(const void* data, tsk_size_t size) -{ - tnet_stun_attribute_t *attribute = 0; - const uint8_t* dataPtr = data; - - tnet_stun_attribute_type_t type = (tnet_stun_attribute_type_t)tnet_ntohs_2(dataPtr); - uint16_t length = tnet_ntohs_2(&dataPtr[2]); - - /* Check validity */ - if(!data || size<=4/* Type(2-bytes) plus Length (2-bytes) */) - { - return 0; - } - - dataPtr += (2 /* Type */+ 2/* Length */); - - /* Attribute Value - */ - - switch(type) - { - /* RFC 5389 - 15.1. 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: - { - attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_xmapped_address_create(dataPtr, length); - break; - } - - /* RFC 5389 - 15.3. 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: - { - if(length == TSK_SHA1_DIGEST_SIZE){ - attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_integrity_create(dataPtr, length); - } - break; - } - - /* RFC 5389 - 15.5. 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: - { - attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_errorcode_create(dataPtr, length); - break; - } - - /* RFC 5389 - 15.7. 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: - { - attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_nonce_create(dataPtr, length); - break; - } - - /* RFC 5389 - 15.9. 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: - { - attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_software_create(dataPtr, length); - break; - } - - /* RFC 5389 - 15.11. ALTERNATE-SERVER */ - case stun_alternate_server: - { - attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_altserver_create(dataPtr, length); - break; - } - - /* draft-ietf-behave-turn-16 subclause 14 */ - case stun_channel_number: - case stun_lifetime: - case stun_reserved2: - case stun_xor_peer_address: - case stun_data: - case stun_xor_relayed_address: - case stun_even_port: - case stun_requested_transport: - case stun_dont_fragment: - case stun_reserved3: - case stun_reservation_token: - { - attribute = tnet_turn_attribute_deserialize(type, length, dataPtr, length); - break; - } - - default: - //TSK_DEBUG_WARN("==> NOT IMPLEMENTED"); - break; - } - - if(!attribute){ - /* Create default */ - attribute = tnet_stun_attribute_create(); - } - - /* Set common values (Do I need this ==> already set by the constructor). */ - attribute->type = type; - attribute->length = length; - - return attribute; -} - -/**@ingroup tnet_stun_group -* Serializes a @ref tnet_stun_attribute_t objet in binary format. -* @param attribute The STUN attribute to serialize. -* @param output The output binary buffer. -* @retval Zero if succeed and non-zero error code otherwise. -*/ -int tnet_stun_attribute_serialize(const tnet_stun_attribute_t* attribute, tsk_buffer_t *output) -{ - if(!attribute || !output){ - return -1; - } - - /* Attribute Type - */ - { - uint16_t type = tnet_htons(attribute->type); - tsk_buffer_append(output, &(type), 2); - } - - /* Attribute Length - */ - { - uint16_t length = tnet_htons(attribute->length); - tsk_buffer_append(output, &(length), 2); - } - - /* Attribute Value - */ - - switch(attribute->type){ - /* RFC 5389 - 15.1. MAPPED-ADDRESS */ - case stun_mapped_address: - { - TSK_DEBUG_ERROR("NOT IMPLEMENTED"); - return -3; - } - - /* RFC 5389 - 15.2. XOR-MAPPED-ADDRESS*/ - case stun_xor_mapped_address: - { - TSK_DEBUG_ERROR("NOT IMPLEMENTED"); - return -3; - } - - /* RFC 5389 - 15.3. 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; - } - - - /* RFC 5389 - 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: - { - 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: - { - TSK_DEBUG_ERROR("NOT IMPLEMENTED"); - return -3; - } - - /* RFC 5389 - 15.7. 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: - { - 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: - { - TSK_DEBUG_ERROR("NOT IMPLEMENTED"); - return -3; - } - - /* RFC 5389 - 15.10. 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: - { - TSK_DEBUG_ERROR("NOT IMPLEMENTED"); - return -3; - } - /* draft-ietf-behave-turn-16 - */ - case stun_channel_number: - case stun_lifetime: - case stun_reserved2: - case stun_xor_peer_address: - case stun_data: - case stun_xor_relayed_address: - case stun_even_port: - case stun_requested_transport: - case stun_dont_fragment: - case stun_reserved3: - case stun_reservation_token: - { - return tnet_turn_attribute_serialize(attribute, output); - } - - default: - return -2; - } -} - -/**@ingroup tnet_stun_group -* Pads a STUN attribute to align it on 4 octets. -* @param attribute The STUN attribute to pad. -* @param output The output buffer into which to put zeros. -*/ -void tnet_stun_attribute_pad(const tnet_stun_attribute_t* attribute, tsk_buffer_t *output) -{ - if(attribute->length%4){ - static uint32_t zeros = 0x00000000; - tsk_buffer_append(output, &zeros, 4-(attribute->length%4)); - } -} - - - - -//================================================================================================= -// [[RFC 5389 - 15. STUN Attributes]] object definition -// -static tsk_object_t* tnet_stun_attribute_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_t *attribute = self; - if(attribute){ - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_t *attribute = self; - if(attribute){ - } - return self; -} - -static const tsk_object_def_t tnet_stun_attribute_def_s = -{ - sizeof(tnet_stun_attribute_t), - tnet_stun_attribute_ctor, - tnet_stun_attribute_dtor, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_def_t = &tnet_stun_attribute_def_s; - - -//================================================================================================= -// [[RFC 5389 - 15.1. MAPPED-ADDRESS]] object definition -// -static tsk_object_t* tnet_stun_attribute_mapped_addr_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_mapped_addr_t *attribute = self; - if(attribute){ - const void *payload = va_arg(*app, const void*); - tsk_size_t payload_size = va_arg(*app, tsk_size_t); - - if(payload && payload_size){ - const uint8_t *payloadPtr = (const uint8_t*)payload; - payloadPtr += 1; /* Ignore first 8bits */ - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_mapped_address; - TNET_STUN_ATTRIBUTE(attribute)->length = payload_size; - - attribute->family = (tnet_stun_addr_family_t) (*(payloadPtr++)); - attribute->port = tnet_ntohs_2(payloadPtr); - payloadPtr+=2; - - { /*=== Compute IP address */ - tsk_size_t addr_size = (attribute->family == stun_ipv6) ? 16 : (attribute->family == stun_ipv4 ? 4 : 0); - if(addr_size){ - tsk_size_t i; - - for(i=0; i<addr_size; i+=4){ - // ntohl() not needed : byte per byte to avoid endianness problem - attribute->address[i] = payloadPtr[0], - attribute->address[i+1] = payloadPtr[1], - attribute->address[i+2] = payloadPtr[2], - attribute->address[i+3] = payloadPtr[3]; - payloadPtr+=4; - } - } - else{ - TSK_DEBUG_ERROR("UNKNOWN FAMILY [%u].", attribute->family); - } - } - } - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_mapped_addr_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_mapped_addr_t *attribute = self; - if(attribute){ - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_mapped_addr_def_t = &tnet_stun_attribute_mapped_addr_def_s; - -//================================================================================================= -// [[RFC 5389 - 15.2. XOR-MAPPED-ADDRESS]] object definition -// -static tsk_object_t* tnet_stun_attribute_xmapped_addr_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_xmapped_addr_t *attribute = self; - if(attribute){ - const void *payload = va_arg(*app, const void*); - tsk_size_t payload_size = va_arg(*app, tsk_size_t); - - if(payload && payload_size){ - const uint8_t *payloadPtr = (const uint8_t*)payload; - payloadPtr += 1; /* Ignore first 8bits */ - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_xor_mapped_address; - TNET_STUN_ATTRIBUTE(attribute)->length = payload_size; - - attribute->family = (tnet_stun_addr_family_t)(*(payloadPtr++)); - - /* RFC 5389 - 15.2. XOR-MAPPED-ADDRESS - X-Port is computed by taking the mapped port in host byte order, - XOR'ing it with the most significant 16 bits of the magic cookie, and - then the converting the result to network byte order. - */ - attribute->xport = tnet_ntohs_2(payloadPtr); - attribute->xport ^= 0x2112; - payloadPtr+=2; - - - { /*=== Compute IP address */ - - /* RFC 5389 - 15.2. XOR-MAPPED-ADDRESS - If the IP address family is IPv4, X-Address is computed by taking the mapped IP - address in host byte order, XOR'ing it with the magic cookie, and - converting the result to network byte order. - */ - tsk_size_t addr_size = (attribute->family == stun_ipv6) ? 16 : (attribute->family == stun_ipv4 ? 4 : 0); - if(addr_size){ - tsk_size_t i; - uint32_t addr; - - for(i=0; i<addr_size; i+=4){ - addr = tnet_ntohl(tnet_ntohl_2(payloadPtr) ^ TNET_STUN_MAGIC_COOKIE); - memcpy(&attribute->xaddress[i], &addr, 4); - payloadPtr+=4; - } - } - else{ - TSK_DEBUG_ERROR("UNKNOWN FAMILY [%u].", attribute->family); - } - } - } - - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_xmapped_addr_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_xmapped_addr_t *attribute = self; - if(attribute){ - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_xmapped_addr_def_t = &tnet_stun_attribute_xmapped_addr_def_s; - - -//================================================================================================= -// [[RFC 5389 - 15.3. USERNAME]] object definition -// -static tsk_object_t* tnet_stun_attribute_username_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_username_t *attribute = self; - if(attribute){ - const void *payload = va_arg(*app, const void*); - tsk_size_t payload_size = va_arg(*app, tsk_size_t); - - attribute->value = tsk_strndup(payload, payload_size); - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_username; - TNET_STUN_ATTRIBUTE(attribute)->length = payload_size; - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_username_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_username_t *attribute = self; - if(attribute){ - TSK_FREE(attribute->value); - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_username_def_t = &tnet_stun_attribute_username_def_s; - - -//================================================================================================= -// [[RFC 5389 - 15.4. MESSAGE-INTEGRITY]] object definition -// -static tsk_object_t* tnet_stun_attribute_integrity_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_integrity_t *attribute = self; - if(attribute){ - const void *payload = va_arg(*app, const void*); - tsk_size_t payload_size = va_arg(*app, tsk_size_t); - - if(payload_size == TSK_SHA1_DIGEST_SIZE){ - memcpy(attribute->sha1digest, payload, TSK_SHA1_DIGEST_SIZE); - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_message_integrity; - TNET_STUN_ATTRIBUTE(attribute)->length = TSK_SHA1_DIGEST_SIZE; - } - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_integrity_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_integrity_t *attribute = self; - if(attribute){ - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_integrity_def_t = &tnet_stun_attribute_integrity_def_s; - - -//================================================================================================= -// [[RFC 5389 - 15.5. FINGERPRINT]] object definition -// -static tsk_object_t* tnet_stun_attribute_fingerprint_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_fingerprint_t *attribute = self; - if(attribute){ - attribute->value = va_arg(*app, uint32_t); - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_fingerprint; - TNET_STUN_ATTRIBUTE(attribute)->length = 4; - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_fingerprint_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_fingerprint_t *attribute = self; - if(attribute){ - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_fingerprint_def_t = &tnet_stun_attribute_fingerprint_def_s; - - - -//================================================================================================= -// [[RFC 5389 - 15.6. ERROR-CODE]] object definition -// -static tsk_object_t* tnet_stun_attribute_errorcode_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_errorcode_t *attribute = self; - if(attribute){ - const uint8_t *payload = (const uint8_t*)va_arg(*app, const void*); - tsk_size_t payload_size = va_arg(*app, tsk_size_t); - - if(payload_size >4){ - uint32_t code = tnet_htonl_2(payload); - payload += 4; - - attribute->_class = code >>8; - attribute->number = (code & 0xFF); - attribute->reason_phrase = tsk_strndup((const char*)payload, (payload_size-4)); - } - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_error_code; - TNET_STUN_ATTRIBUTE(attribute)->length = payload_size; - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_errorcode_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_errorcode_t *attribute = self; - if(attribute){ - TSK_FREE(attribute->reason_phrase); - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_errorcode_def_t = &tnet_stun_attribute_errorcode_def_s; - - -//================================================================================================= -// [[RFC 5389 - 15.7. REALM]] object definition -// -static tsk_object_t* tnet_stun_attribute_realm_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_realm_t *attribute = self; - if(attribute){ - const void *payload = va_arg(*app, const void*); - tsk_size_t payload_size = va_arg(*app, tsk_size_t); - - attribute->value = tsk_strndup(payload, payload_size); - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_realm; - TNET_STUN_ATTRIBUTE(attribute)->length = payload_size; - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_realm_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_realm_t *attribute = self; - if(attribute){ - TSK_FREE(attribute->value); - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_realm_def_t = &tnet_stun_attribute_realm_def_s; - - -//================================================================================================= -// [[RFC 5389 - 15.8. NONCE]] object definition -// -static tsk_object_t* tnet_stun_attribute_nonce_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_nonce_t *attribute = self; - if(attribute){ - const void *payload = va_arg(*app, const void*); - tsk_size_t payload_size = va_arg(*app, tsk_size_t); - - attribute->value = tsk_strndup(payload, payload_size); - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_nonce; - TNET_STUN_ATTRIBUTE(attribute)->length = payload_size; - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_nonce_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_nonce_t *attribute = self; - if(attribute){ - TSK_FREE(attribute->value); - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_nonce_def_t = &tnet_stun_attribute_nonce_def_s; - - -//================================================================================================= -// [[RFC 5389 - 15.9. UNKNOWN-ATTRIBUTES]] object definition -// -static tsk_object_t* tnet_stun_attribute_unknowns_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_unknowns_t *attribute = self; - if(attribute){ - //--const void *payload = va_arg(*app, const void*); - //--tsk_size_t payload_size = va_arg(*app, tsk_size_t); - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_unknown_attributes; - attribute->value = tsk_buffer_create_null(); - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_unknowns_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_unknowns_t *attribute = self; - if(attribute){ - TSK_OBJECT_SAFE_FREE(attribute->value); - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_unknowns_def_t = &tnet_stun_attribute_unknowns_def_s; - -//================================================================================================= -// [[RFC 5389 - 15.10. SOFTWARE]] object definition -// -static tsk_object_t* tnet_stun_attribute_software_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_software_t *attribute = self; - if(attribute){ - const void *payload = va_arg(*app, const void*); - tsk_size_t payload_size = va_arg(*app, tsk_size_t); - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_software; - - attribute->value = tsk_strndup(payload, payload_size); - TNET_STUN_ATTRIBUTE(attribute)->length = tsk_strlen(attribute->value); - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_software_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_software_t *attribute = self; - if(attribute){ - TSK_FREE(attribute->value); - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_software_def_t = &tnet_stun_attribute_software_def_s; - -//================================================================================================= -// [[RFC 5389 - 15.11. ALTERNATE-SERVER]] object definition -// -static tsk_object_t* tnet_stun_attribute_altserver_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_attribute_altserver_t *attribute = self; - if(attribute){ - const void *payload = va_arg(*app, const void*); - tsk_size_t payload_size = va_arg(*app, tsk_size_t); - - const uint8_t *payloadPtr = (const uint8_t*)payload; - payloadPtr += 1; /* Ignore first 8bits */ - - TNET_STUN_ATTRIBUTE(attribute)->type = stun_alternate_server; - TNET_STUN_ATTRIBUTE(attribute)->length = payload_size; - - attribute->family = (tnet_stun_addr_family_t) (*(payloadPtr++)); - attribute->port = tnet_ntohs_2(payloadPtr); - payloadPtr+=2; - - if(attribute->family == stun_ipv4){ - uint32_t addr = tnet_htonl_2(payloadPtr); - memcpy(attribute->server, &addr, 4); - payloadPtr+=4; - } - else if(attribute->family == stun_ipv6){ - TSK_DEBUG_ERROR("IPv6 not supported yet."); - } - else{ - TSK_DEBUG_ERROR("UNKNOWN FAMILY."); - } - } - return self; -} - -static tsk_object_t* tnet_stun_attribute_altserver_dtor(tsk_object_t * self) -{ - tnet_stun_attribute_altserver_t *attribute = self; - if(attribute){ - } - return self; -} - -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, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_attribute_altserver_def_t = &tnet_stun_attribute_altserver_def_s; - diff --git a/branches/1.0/tinyNET/src/stun/tnet_stun_attribute.h b/branches/1.0/tinyNET/src/stun/tnet_stun_attribute.h deleted file mode 100644 index 66fd7ff..0000000 --- a/branches/1.0/tinyNET/src/stun/tnet_stun_attribute.h +++ /dev/null @@ -1,329 +0,0 @@ -/*
-* Copyright (C) 2009-2010 Mamadou Diop.
-*
-* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
-* 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 General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with DOUBANGO.
-*
-*/
-
-/**@file tnet_stun_attribute.h
- * @brief STUN2(RFC 5389) attribute parser.
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#ifndef TNET_STUN_ATTRIBUTE_H
-#define TNET_STUN_ATTRIBUTE_H
-
-#include "tinynet_config.h"
-
-#include "tnet_types.h"
-
-#include "tsk_object.h"
-#include "tsk_buffer.h"
-#include "tsk_sha1.h"
-
-/**@ingroup tnet_stun_group
-* @def TNET_STUN_ATTRIBUTE
-* Converts (cast) any STUN attribute to @ref tnet_stun_attribute_t pointer.
-* @param self The attribute to convert (cast).
-* @retval A pointer to @ref tnet_stun_attribute_t object.
-*/
-TNET_BEGIN_DECLS
-
-#define TNET_STUN_ATTRIBUTE(self) ((tnet_stun_attribute_t*)(self))
-
-/**@ingroup tnet_stun_group
- * STUN IP family as per RFC 5389 subclause 15.1.
-**/
-typedef enum tnet_stun_addr_family_e
-{
- stun_ipv4 = 0x01,
- stun_ipv6 = 0x02
-}
-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
-{
- /* === RFC 5389 - Comprehension-required range (0x0000-0x7FFF):
- */
- stun_reserved = 0x0000, /**< (Reserved) */
- stun_mapped_address = 0x0001, /**< http://tools.ietf.org/html/rfc5389#page-32 */
- stun_response_address = 0x0002, /**< (Reserved; was RESPONSE-ADDRESS) */
- stun_change_address = 0x0003, /**< (Reserved; was CHANGE-ADDRESS) */
- stun_source_address = 0x0004, /**< (Reserved; was SOURCE-ADDRESS) */
- stun_changed_address = 0x0005, /**< (Reserved; was CHANGED-ADDRESS) */
- stun_username = 0x0006, /**< http://tools.ietf.org/html/rfc5389#page-34 */
- stun_password = 0x0007, /**< (Reserved; was PASSWORD) */
- stun_message_integrity = 0x0008, /**< http://tools.ietf.org/html/rfc5389#page-34 */
- stun_error_code = 0x0009, /**< http://tools.ietf.org/html/rfc5389#page-36 */
- stun_unknown_attributes = 0x000A, /**< http://tools.ietf.org/html/rfc5389#page-38 */
- stun_reflected_from = 0x000B, /**< (Reserved; was REFLECTED-FROM) */
- stun_realm = 0x0014, /**< http://tools.ietf.org/html/rfc5389#page-38 */
- stun_nonce = 0x0015, /**< http://tools.ietf.org/html/rfc5389#page-38 */
- stun_xor_mapped_address = 0x0020, /**< http://tools.ietf.org/html/rfc5389#page-33 */
-
- /* === RFC 5389 - Comprehension-optional range (0x8000-0xFFFF)
- */
- stun_software = 0x8022, /**< http://tools.ietf.org/html/rfc5389#page-39 */
- stun_alternate_server = 0x8023, /**< http://tools.ietf.org/html/rfc5389#page-39 */
- stun_fingerprint = 0x8028, /**< http://tools.ietf.org/html/rfc5389#page-36 */
-
- /* === draft-ietf-behave-turn-16
- */
- stun_channel_number = 0x000C, /**< draft-ietf-behave-turn-16 - CHANNEL-NUMBER */
- stun_lifetime = 0x000D, /**< draft-ietf-behave-turn-16 - LIFETIME */
- stun_reserved2 = 0x0010, /**< draft-ietf-behave-turn-16 - Reserved (was BANDWIDTH) */
- stun_xor_peer_address = 0x0012, /**< draft-ietf-behave-turn-16 - XOR-PEER-ADDRESS */
- stun_data = 0x0013, /**< draft-ietf-behave-turn-16 - DATA */
- stun_xor_relayed_address = 0x0016, /**< draft-ietf-behave-turn-16 - XOR-RELAYED-ADDRESS */
- stun_even_port = 0x0018, /**< draft-ietf-behave-turn-16 - EVEN-PORT */
- stun_requested_transport = 0x0019, /**< draft-ietf-behave-turn-16 - REQUESTED-TRANSPORT */
- stun_dont_fragment = 0x001A, /**< draft-ietf-behave-turn-16 - DONT-FRAGMENT */
- stun_reserved3 = 0x0021, /**< draft-ietf-behave-turn-16 - Reserved (was TIMER-VAL) */
- stun_reservation_token = 0x0022, /**< draft-ietf-behave-turn-16 - RESERVATION-TOKEN */
-}
-tnet_stun_attribute_type_t;
-
-
-/**@ingroup tnet_stun_group
- RFC 5389 - 15. STUN Attributes
-*/
-typedef struct tnet_stun_attribute_s
-{
- TSK_DECLARE_OBJECT;
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type | Length |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Value (variable) ....
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- tnet_stun_attribute_type_t type;
- uint16_t length;
-}
-tnet_stun_attribute_t;
-
-typedef tsk_list_t tnet_stun_attributes_L_t;
-TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_def_t;
-
-#define TNET_STUN_DECLARE_ATTRIBUTE tnet_stun_attribute_t attribute
-
-
-/**@ingroup tnet_stun_group
- *RFC 5389 - 15.1. MAPPED-ADDRESS
- */
-typedef struct tnet_stun_attribute_mapped_addr_s
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
-
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |0 0 0 0 0 0 0 0| Family | Port |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | |
- | Address (32 bits or 128 bits) |
- | |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- tnet_stun_addr_family_t family;
- uint16_t port;
- uint8_t address[16];
-}
-tnet_stun_attribute_mapped_addr_t;
-
-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
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
-
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |x x x x x x x x| Family | X-Port |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | X-Address (Variable)
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- tnet_stun_addr_family_t family;
- uint16_t xport;
- uint8_t xaddress[16];
-}
-tnet_stun_attribute_xmapped_addr_t;
-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
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
-
- char* value;
-}
-tnet_stun_attribute_username_t;
-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
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
-
- tsk_sha1digest_t sha1digest;
-}
-tnet_stun_attribute_integrity_t;
-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
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
-
- uint32_t value;
-}
-tnet_stun_attribute_fingerprint_t;
-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
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Reserved, should be 0 |Class| Number |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Reason Phrase (variable) ..
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- uint8_t _class;
- uint8_t number;
- char* reason_phrase;
-}
-tnet_stun_attribute_errorcode_t;
-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
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
-
- char* value;
-}
-tnet_stun_attribute_realm_t;
-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
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
-
- char* value;
-}
-tnet_stun_attribute_nonce_t;
-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
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
-
- tsk_buffer_t *value;
-}
-tnet_stun_attribute_unknowns_t;
-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
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
-
- char *value;
-}
-tnet_stun_attribute_software_t;
-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
-{
- TNET_STUN_DECLARE_ATTRIBUTE;
-
- tnet_stun_addr_family_t family;
- uint16_t port;
- uint8_t server[128];
-}
-tnet_stun_attribute_altserver_t;
-TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_attribute_altserver_def_t;
-
-
-tnet_stun_attribute_t* tnet_stun_attribute_deserialize(const void* data, tsk_size_t size);
-int tnet_stun_attribute_serialize(const tnet_stun_attribute_t* attribute, tsk_buffer_t *output);
-void tnet_stun_attribute_pad(const tnet_stun_attribute_t* attribute, tsk_buffer_t *output);
-
-
-
-
-tnet_stun_attribute_t* tnet_stun_attribute_create();
-tnet_stun_attribute_mapped_addr_t* tnet_stun_attribute_mapped_address_create(const void* payload, tsk_size_t payload_size);
-tnet_stun_attribute_xmapped_addr_t* tnet_stun_attribute_xmapped_address_create(const void* payload, tsk_size_t payload_size);
-tnet_stun_attribute_username_t* tnet_stun_attribute_username_create(const void* payload, tsk_size_t payload_size);
-tnet_stun_attribute_integrity_t* tnet_stun_attribute_integrity_create(const void* payload, tsk_size_t payload_size);
-tnet_stun_attribute_fingerprint_t* tnet_stun_attribute_fingerprint_create(uint32_t fingerprint);
-tnet_stun_attribute_errorcode_t* tnet_stun_attribute_errorcode_create(const void* payload, tsk_size_t payload_size);
-tnet_stun_attribute_realm_t* tnet_stun_attribute_realm_create(const void* payload, tsk_size_t payload_size);
-tnet_stun_attribute_nonce_t* tnet_stun_attribute_nonce_create(const void* payload, tsk_size_t payload_size);
-tnet_stun_attribute_unknowns_t* tnet_stun_attribute_unknowns_create(const void* payload, tsk_size_t payload_size);
-tnet_stun_attribute_software_t* tnet_stun_attribute_software_create(const void* payload, tsk_size_t payload_size);
-tnet_stun_attribute_altserver_t* tnet_stun_attribute_altserver_create(const void* payload, tsk_size_t payload_size);
-
-
-TNET_END_DECLS
-
-#endif /* TNET_STUN_ATTRIBUTE_H */
-
diff --git a/branches/1.0/tinyNET/src/stun/tnet_stun_message.c b/branches/1.0/tinyNET/src/stun/tnet_stun_message.c deleted file mode 100644 index 9769092..0000000 --- a/branches/1.0/tinyNET/src/stun/tnet_stun_message.c +++ /dev/null @@ -1,440 +0,0 @@ -/* -* Copyright (C) 2009-2010 Mamadou Diop. -* -* Contact: Mamadou Diop <diopmamadou(at)doubango.org> -* -* 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 General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with DOUBANGO. -* -*/ - -/**@file tnet_stun_message.c - * @brief STUN2 (RFC 5389) message parser. - * - * @author Mamadou Diop <diopmamadou(at)doubango.org> - * - * @date Created: Sat Nov 8 16:54:58 2009 mdiop - */ -#include "tnet_stun_message.h" - -#include "tnet_stun.h" - -#include "../tnet_types.h" -#include "../tnet_endianness.h" -#include "../turn/tnet_turn_attribute.h" - -#include "tsk_memory.h" -#include "tsk_hmac.h" -#include "tsk_string.h" -#include "tsk_ppfcs32.h" - -#include <string.h> - - -/**@ingroup tnet_stun_group -* Creates new STUN message. -* @retval @ref tnet_stun_message_t object. -* @sa tnet_stun_message_create_null. -*/ - -tnet_stun_message_t* tnet_stun_message_create(const char* username, const char* password) -{ - return tsk_object_new(tnet_stun_message_def_t, username, password); -} - -/**@ingroup tnet_stun_group -* Creates new STUN message. -* @retval @ref tnet_stun_message_t object. -* @sa tnet_stun_message_create. -*/ -tnet_stun_message_t* tnet_stun_message_create_null() -{ - return tnet_stun_message_create(tsk_null, tsk_null); -} - -#define SERIALIZE_N_ADD_ATTRIBUTE(att_name, payload, payload_size) \ - attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_##att_name##_create(payload, payload_size); \ - tnet_stun_attribute_serialize(attribute, output); \ - tnet_stun_attribute_pad(attribute, output); \ - TSK_OBJECT_SAFE_FREE(attribute); - -/**@ingroup tnet_stun_group - * Serializes a STUN message as binary data. - * @param [in,out] self The STUN message to serialize. - * @retval A buffer holding the binary data (result) if serialization succeed and zero otherwise. -**/ -tsk_buffer_t* tnet_stun_message_serialize(const tnet_stun_message_t *self) -{ - tsk_buffer_t *output = 0; - tnet_stun_attribute_t *attribute; - unsigned compute_integrity = self->integrity; - - if(!self){ - goto bail; - } - - output = tsk_buffer_create_null(); - - /* RFC 5389 - 6. STUN Message Structure - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |0 0| STUN Message Type | Message Length | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Magic Cookie | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - | Transaction ID (96 bits) | - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - - /* STUN Message Type - */ - { - uint16_t type = tnet_htons(self->type); - tsk_buffer_append(output, &(type), 2); - } - - /* Message Length ==> Will be updated after attributes have been added. */ - { - uint16_t length = 0; - tsk_buffer_append(output, &(length), 2); - } - - /* Magic Cookie - */ - { - uint32_t cookie = tnet_htonl(self->cookie); - tsk_buffer_append(output, &(cookie), 4); - } - - - /* Transaction ID (96 bits==>16bytes) - */ - tsk_buffer_append(output, self->transaction_id, TNET_STUN_TRANSACID_SIZE); - - /* DONT-FRAGMENT - */ - if(self->dontfrag){ - attribute = (tnet_stun_attribute_t *)tnet_turn_attribute_dontfrag_create(); - tnet_stun_attribute_serialize(attribute, output); - TSK_OBJECT_SAFE_FREE(attribute); - } - - /*=== Attributes === - */ - { - tsk_list_item_t *item; - tsk_list_foreach(item, self->attributes) - { - attribute = item->data; - tnet_stun_attribute_serialize(attribute, output); - tnet_stun_attribute_pad(attribute, output); - } - } - - /* AUTHENTICATION */ - if(self->realm && self->nonce){ - SERIALIZE_N_ADD_ATTRIBUTE(username, self->username, tsk_strlen(self->username)); - SERIALIZE_N_ADD_ATTRIBUTE(realm, self->realm, tsk_strlen(self->realm)); - SERIALIZE_N_ADD_ATTRIBUTE(nonce, self->nonce, tsk_strlen(self->nonce)); - - compute_integrity = 1; - } - - /* Message Length: The message length MUST contain the size, in bytes, of the message - not including the 20-byte STUN header. - */ - { - uint16_t length = (output->size) - TNET_STUN_HEADER_SIZE; - if(self->fingerprint) - length += (2/* Type */ + 2 /* Length */+ 4 /* FINGERPRINT VALUE*/); - - if(compute_integrity) - length += (2/* Type */ + 2 /* Length */+ TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/); - - *(((uint16_t*)output->data)+1) = tnet_htons(length); - } - - /* MESSAGE-INTEGRITY */ - if(compute_integrity){ - /* RFC 5389 - 15.4. MESSAGE-INTEGRITY - The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message. - - For long-term credentials ==> key = MD5(username ":" realm ":" SASLprep(password)) - For short-term credentials ==> key = SASLprep(password) - FIXME: what about short term credentials? - FIXME: what about SASLprep - */ - char* keystr = 0; - tsk_sha1digest_t hmac; - tsk_md5digest_t md5; - - tsk_sprintf(&keystr, "%s:%s:%s", self->username, self->realm, self->password); - TSK_MD5_DIGEST_CALC(keystr, tsk_strlen(keystr), md5); - hmac_sha1digest_compute(output->data, output->size, (const char*)md5, TSK_MD5_DIGEST_SIZE, hmac); - - SERIALIZE_N_ADD_ATTRIBUTE(integrity, hmac, TSK_SHA1_DIGEST_SIZE); - - TSK_FREE(keystr); - } - - /* FINGERPRINT */ - if(self->fingerprint){ - /* RFC 5389 - 15.5. FINGERPRINT - The FINGERPRINT attribute MAY be present in all STUN messages. The - value of the attribute is computed as the CRC-32 of the STUN message - up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with - the 32-bit value 0x5354554e - */ - uint32_t fingerprint = tsk_pppfcs32(TSK_PPPINITFCS32, output->data, output->size); - fingerprint ^= 0x5354554e; - fingerprint = tnet_htonl(fingerprint); - - attribute = (tnet_stun_attribute_t *)tnet_stun_attribute_fingerprint_create(fingerprint); - tnet_stun_attribute_serialize(attribute, output); - TSK_OBJECT_SAFE_FREE(attribute); - } - -bail: - return output; -} - - -/**@ingroup tnet_stun_group - * - * Deserializes a STUN message from binary data. - * - * @param [in,out] data A pointer to the binary data. - * @param size The size of the binary data. - * - * @retval A STUN message if deserialization succeed or NULL otherwise. -**/ -tnet_stun_message_t* tnet_stun_message_deserialize(const uint8_t *data, tsk_size_t size) -{ - tnet_stun_message_t *message = 0; - uint8_t* dataPtr, *dataEnd; - - - if(!data || (size < TNET_STUN_HEADER_SIZE) || !TNET_IS_STUN2(data)) - { - goto bail; - } - - dataPtr = (uint8_t*)data; - dataEnd = (dataPtr + size); - - message = tnet_stun_message_create_null(); - - /* Message Type - */ - message->type = (tnet_stun_message_type_t)tnet_ntohs_2(dataPtr); - dataPtr += 2; - - /* Message Length - */ - message->length = tnet_ntohs_2(dataPtr); - dataPtr += 2; - - /* Check message validity - */ - if((message->length + TNET_STUN_HEADER_SIZE) != size) - { - TSK_OBJECT_SAFE_FREE(message); - goto bail; - } - - /* Magic Cookie - ==> already set by the constructor and checked by @ref TNET_IS_STUN2 - */ - dataPtr += 4; - - /* Transaction ID - */ - memcpy(message->transaction_id, dataPtr, TNET_STUN_TRANSACID_SIZE); - dataPtr += TNET_STUN_TRANSACID_SIZE; - - /* == Parse attributes - */ - while(dataPtr < dataEnd){ - tnet_stun_attribute_t *attribute = tnet_stun_attribute_deserialize(dataPtr, (dataEnd - dataPtr)); - if(attribute){ - tsk_size_t att_size = (attribute->length + 2 /* Type*/ + 2/* Length */); - att_size += (att_size%4) ? 4-(att_size%4) : 0; // Skip zero bytes used to pad the attribute. - - dataPtr += att_size; - tsk_list_push_back_data(message->attributes, (void**)&attribute); - - continue; - } - else{ - continue; - } - - - - - } - - -bail: - return message; -} - -/**@ingroup tnet_stun_group -* Adds an attribute to a STUN message. -* @param self The STUN message into which to add the attribute. -* @param attribute The attribute to add. -* @retval Zero if succeed and non-zero error code otherwise. -*/ -int tnet_stun_message_add_attribute(tnet_stun_message_t *self, tnet_stun_attribute_t** attribute) -{ - //if(self && attribute) - { - tsk_list_push_back_data(self->attributes, (void**)attribute); - return 0; - } - return -1; -} - -/**@ingroup tnet_stun_group -* Gets a STUN attribute from a message. -* @param self The message from which to get the attribute. -* @param type The type of the attribute to retrieve. -* @retval @ref tnet_stun_attribute_t object if found and NULL otherwise. -*/ -const tnet_stun_attribute_t* tnet_stun_message_get_attribute(const tnet_stun_message_t *self, tnet_stun_attribute_type_t type) -{ - tnet_stun_attribute_t* attribute; - - if(self && !TSK_LIST_IS_EMPTY(self->attributes)){ - tsk_list_item_t *item; - tsk_list_foreach(item, self->attributes){ - if((attribute = item->data) && attribute->type == type){ - return attribute; - } - } - } - return 0; -} - -/**@ingroup tnet_stun_group -* Gets the STUN error-code attribute value from the message. -* @param self The STUN message from which to get the error code. -* @retval The error code if the message contain such attribute or -1 otherwise. -*/ -short tnet_stun_message_get_errorcode(const tnet_stun_message_t *self) -{ - const tnet_stun_attribute_errorcode_t* error = (const tnet_stun_attribute_errorcode_t*)tnet_stun_message_get_attribute(self, stun_error_code); - if(error){ - return ((error->_class*100) + error->number); - } - return -1; -} - -/**@ingroup tnet_stun_group -* Gets the STUN @b realm attribute value from the message. -* @param self The STUN message from which to get the @b realm. -* @retval The @b realm as a string pointer code if the message contain such attribute or NULL otherwise. -*/ -const char* tnet_stun_message_get_realm(const tnet_stun_message_t *self) -{ - const tnet_stun_attribute_realm_t* realm = (const tnet_stun_attribute_realm_t*)tnet_stun_message_get_attribute(self, stun_realm); - if(realm){ - return realm->value; - } - return 0; -} - -/**@ingroup tnet_stun_group -* Gets the STUN @b nonce attribute value from the message. -* @param self The STUN message from which to get the @b nonce. -* @retval The @b nonce as a string pointer code if the message contain such attribute or NULL otherwise. -*/ -const char* tnet_stun_message_get_nonce(const tnet_stun_message_t *self) -{ - const tnet_stun_attribute_nonce_t* nonce = (const tnet_stun_attribute_nonce_t*)tnet_stun_message_get_attribute(self, stun_nonce); - if(nonce){ - return nonce->value; - } - return 0; -} - -/**@ingroup tnet_stun_group -* Gets the STUN @b lifetime attribute value from the message. -* @param self The STUN message from which to get the @b lifetime. -* @retval The @b lifetime (any positive value) if the message contain such attribute or -1 otherwise. -*/ -int32_t tnet_stun_message_get_lifetime(const tnet_stun_message_t *self) -{ - const tnet_turn_attribute_lifetime_t* lifetime = (const tnet_turn_attribute_lifetime_t*)tnet_stun_message_get_attribute(self, stun_lifetime); - if(lifetime){ - return lifetime->value; - } - return -1; -} - - - - - - - - - -//================================================================================================= -// STUN2 MESSAGE object definition -// -static tsk_object_t* tnet_stun_message_ctor(tsk_object_t * self, va_list * app) -{ - tnet_stun_message_t *message = self; - if(message){ - message->username = tsk_strdup(va_arg(*app, const char*)); - message->password = tsk_strdup(va_arg(*app, const char*)); - - message->cookie = TNET_STUN_MAGIC_COOKIE; - message->attributes = tsk_list_create(); - - message->fingerprint = 1; - message->integrity = 0; - } - return self; -} - -static tsk_object_t* tnet_stun_message_dtor(tsk_object_t * self) -{ - tnet_stun_message_t *message = self; - if(message){ - TSK_FREE(message->username); - TSK_FREE(message->password); - TSK_FREE(message->realm); - TSK_FREE(message->nonce); - - TSK_OBJECT_SAFE_FREE(message->attributes); - } - - return self; -} - -static const tsk_object_def_t tnet_stun_message_def_s = -{ - sizeof(tnet_stun_message_t), - tnet_stun_message_ctor, - tnet_stun_message_dtor, - tsk_null, -}; -const tsk_object_def_t *tnet_stun_message_def_t = &tnet_stun_message_def_s; - diff --git a/branches/1.0/tinyNET/src/stun/tnet_stun_message.h b/branches/1.0/tinyNET/src/stun/tnet_stun_message.h deleted file mode 100644 index 862c7b6..0000000 --- a/branches/1.0/tinyNET/src/stun/tnet_stun_message.h +++ /dev/null @@ -1,240 +0,0 @@ -/*
-* Copyright (C) 2009-2010 Mamadou Diop.
-*
-* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
-*
-* 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 General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with DOUBANGO.
-*
-*/
-
-/**@file tnet_stun_message.h
- * @brief STUN2 (RFC 5389) message parser.
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-#ifndef TNET_STUN_MESSAGE_H
-#define TNET_STUN_MESSAGE_H
-
-#include "tinynet_config.h"
-#include "stun/tnet_stun_attribute.h"
-
-#include "tsk_buffer.h"
-
-TNET_BEGIN_DECLS
-
-#define TNET_STUN_CLASS_REQUEST_MASK (0x0000)
-#define TNET_STUN_CLASS_INDICATION_MASK (0x0010)
-#define TNET_STUN_CLASS_SUCCESS_MASK (0x0100)
-#define TNET_STUN_CLASS_ERROR_MASK (0x0110)
-
-/**@ingroup tnet_stun_group
-* @def TNET_STUN_RESPONSE_IS_REQUEST
-* Checks whether the STUN message is a request or not.
-*/
-/**@ingroup tnet_stun_group
-* @def TNET_STUN_RESPONSE_IS_INDICATION
-* Checks whether the STUN message is an indicaton message or not.
-*/
-/**@ingroup tnet_stun_group
-* @def TNET_STUN_RESPONSE_IS_SUCCESS
-* Checks whether the STUN message is a success response or not.
-*/
-/**@ingroup tnet_stun_group
-* @def TNET_STUN_RESPONSE_IS_ERROR
-* Checks whether the STUN message is an error response or not.
-*/
-#define TNET_STUN_RESPONSE_IS_REQUEST(self) ((self->type & TNET_STUN_CLASS_REQUEST_MASK) == TNET_STUN_CLASS_REQUEST_MASK)
-#define TNET_STUN_RESPONSE_IS_INDICATION(self) ((self->type & TNET_STUN_CLASS_INDICATION_MASK) == TNET_STUN_CLASS_INDICATION_MASK)
-#define TNET_STUN_RESPONSE_IS_SUCCESS(self) ((self->type & TNET_STUN_CLASS_SUCCESS_MASK) == TNET_STUN_CLASS_SUCCESS_MASK)
-#define TNET_STUN_RESPONSE_IS_ERROR(self) ((self->type & TNET_STUN_CLASS_ERROR_MASK) == TNET_STUN_CLASS_ERROR_MASK)
-
-/**@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_IS_STUN2(PU8) \
- (((PU8)[0] & 0xc0) == 0x00) && \
- ( (*(((uint32_t *)(PU8))+1)) == tnet_htonl(TNET_STUN_MAGIC_COOKIE) )
-
-/**@ingroup tnet_stun_group
- * STUN trasactionn ID size (96bits = 12bytes).
-*/
-#define TNET_STUN_TRANSACID_SIZE 12
-
-/**@ingroup tnet_stun_group
- * Defines an alias representing the STUN transaction id type.
-**/
-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
-{
- stun_class_request = 0x00, /**< Request class: 0b00 */
- stun_class_indication = 0x01, /**< Indication class: 0b01 */
- stun_class_success_response = 0x02, /**< Success response class: 0b10 */
- stun_class_error_response = 0x03, /**< Error/failure response class: 0b11 */
-}
-tnet_stun_class_type_t;
-
-/**@ingroup tnet_stun_group
- * List of all supported STUN methods.
- * 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
-{
- stun_method_binding = 0x0001, /**< RFC 5389 - Binding method: 0b000000000001 */
-
- stun_method_allocate = 0x0003, /**< draft-ietf-behave-turn-16 - Allocate (only request/response semantics defined) */
- stun_method_refresh = 0x0004, /**< draft-ietf-behave-turn-16 - Refresh (only request/response semantics defined) */
- stun_method_send = 0x0006, /**< draft-ietf-behave-turn-16 - Send (only indication semantics defined) */
- stun_method_data = 0x0007, /**< draft-ietf-behave-turn-16 - Data (only indication semantics defined) */
- stun_method_createpermission = 0x0008, /**< draft-ietf-behave-turn-16 - CreatePermission (only request/response semantics defined */
- stun_method_channelbind = 0x0009, /**< draft-ietf-behave-turn-16 - ChannelBind (only request/response semantics defined) */
-}
-tnet_stun_method_type_t;
-
-/**@ingroup tnet_stun_group
-* List of all supported STUN types.
-*/
-typedef enum tnet_stun_message_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|
- +--+--+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- stun_binding_request = (stun_method_binding | TNET_STUN_CLASS_REQUEST_MASK),
- stun_binding_indication = (stun_method_binding | TNET_STUN_CLASS_INDICATION_MASK),
- stun_binding_success_response = (stun_method_binding | TNET_STUN_CLASS_SUCCESS_MASK),
- stun_binding_error_response = (stun_method_binding | TNET_STUN_CLASS_ERROR_MASK),
-
- stun_allocate_request = (stun_method_allocate | TNET_STUN_CLASS_REQUEST_MASK),
- stun_allocate_indication = (stun_method_allocate | TNET_STUN_CLASS_INDICATION_MASK),
- stun_allocate_success_response = (stun_method_allocate | TNET_STUN_CLASS_SUCCESS_MASK),
- stun_allocate_error_response = (stun_method_allocate | TNET_STUN_CLASS_ERROR_MASK),
-
- stun_refresh_request = (stun_method_refresh | TNET_STUN_CLASS_REQUEST_MASK),
- stun_refresh_indication = (stun_method_refresh | TNET_STUN_CLASS_INDICATION_MASK),
- stun_refresh_success_response = (stun_method_refresh | TNET_STUN_CLASS_SUCCESS_MASK),
- stun_refresh_error_response = (stun_method_refresh | TNET_STUN_CLASS_ERROR_MASK),
-
- stun_send_indication = (stun_method_send | TNET_STUN_CLASS_INDICATION_MASK),
-
- stun_data_indication = (stun_method_data | TNET_STUN_CLASS_INDICATION_MASK),
-
- stun_createpermission_request = (stun_method_createpermission | TNET_STUN_CLASS_REQUEST_MASK),
- stun_createpermission_indication = (stun_method_createpermission | TNET_STUN_CLASS_INDICATION_MASK),
- stun_createpermission_success_response = (stun_method_createpermission | TNET_STUN_CLASS_SUCCESS_MASK),
- stun_createpermission_error_response = (stun_method_createpermission | TNET_STUN_CLASS_ERROR_MASK),
-
- stun_channelbind_request = (stun_method_channelbind | TNET_STUN_CLASS_REQUEST_MASK),
- stun_channelbind_indication = (stun_method_channelbind | TNET_STUN_CLASS_INDICATION_MASK),
- stun_channelbind_success_response = (stun_method_channelbind | TNET_STUN_CLASS_SUCCESS_MASK),
- stun_channelbind_error_response = (stun_method_channelbind | TNET_STUN_CLASS_ERROR_MASK),
-}
-tnet_stun_message_type_t;
-
-/**@ingroup tnet_stun_group
- *
- * STUN Message structure as per RFC 5389 subclause 6.
- * http://tools.ietf.org/html/rfc5389#section-6
-*/
-typedef struct tnet_stun_message_s
-{
- TSK_DECLARE_OBJECT;
-
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |0 0| STUN Message Type | Message Length |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Magic Cookie |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | |
- | Transaction ID (96 bits) |
- | |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
- tnet_stun_message_type_t type;
- uint16_t length;
- uint32_t cookie;
- tnet_stun_transacid_t transaction_id;
-
- unsigned fingerprint:1;
- unsigned integrity:1;
- unsigned dontfrag:1;
-
- char* username;
- char* password;
- char* realm;
- char* nonce;
-
- tnet_stun_attributes_L_t *attributes; /**< List of all attributes associated to this message */
-}
-tnet_stun_message_t;
-
-typedef tnet_stun_message_t tnet_stun_response_t;
-typedef tnet_stun_message_t tnet_stun_request_t;
-
-tsk_buffer_t* tnet_stun_message_serialize(const tnet_stun_message_t *message);
-tnet_stun_message_t* tnet_stun_message_deserialize(const uint8_t *data, tsk_size_t size);
-int tnet_stun_message_add_attribute(tnet_stun_message_t *self, tnet_stun_attribute_t** attribute);
-const tnet_stun_attribute_t* tnet_stun_message_get_attribute(const tnet_stun_message_t *self, tnet_stun_attribute_type_t type);
-short tnet_stun_message_get_errorcode(const tnet_stun_message_t *self);
-const char* tnet_stun_message_get_realm(const tnet_stun_message_t *self);
-const char* tnet_stun_message_get_nonce(const tnet_stun_message_t *self);
-int32_t tnet_stun_message_get_lifetime(const tnet_stun_message_t *self);
-
-
-tnet_stun_message_t* tnet_stun_message_create(const char* username, const char* password);
-tnet_stun_message_t* tnet_stun_message_create_null();
-
-TINYNET_GEXTERN const tsk_object_def_t *tnet_stun_message_def_t;
-
-
-TNET_END_DECLS
-
-
-#endif /* TNET_STUN_MESSAGE_H */
-
|