doubango/tinyNET/src/stun/tnet_stun_binding.c
c732d49e
 #if HAVE_CRT
 #define _CRTDBG_MAP_ALLOC 
 #include <stdlib.h> 
 #include <crtdbg.h>
 #endif //HAVE_CRT
 /*
74ca6d11
 * Copyright (C) 2020, University of the Basque Country (UPV/EHU)
c732d49e
 * Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
 *
 * The original file was part of Open Source Doubango Framework
 * Copyright (C) 2010-2011 Mamadou Diop.
 * Copyright (C) 2012 Doubango Telecom <http://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.
 *
 */
 #include "stun/tnet_stun_binding.h"
 #include "stun/tnet_stun_pkt.h"
 #include "stun/tnet_stun_attr.h"
 #include "tnet_utils.h"
 
 #include "tsk_string.h"
 #include "tsk_memory.h"
 #include "tsk_debug.h"
 
 int tnet_stun_binding_create(tnet_fd_t fd, enum tnet_socket_type_e socket_type, const char* pc_server_address, tnet_port_t server_port, const char* pc_username, const char* pc_password, tnet_stun_binding_t** pp_bind)
 {
     extern const tsk_object_def_t *tnet_stun_binding_def_t;
     static long __unique_id = 0;
 
     if (!pp_bind) {
         TSK_DEBUG_ERROR("Invalid parameter");
         return -1;
     }
     if (!(*pp_bind = tsk_object_new(tnet_stun_binding_def_t))) {
         TSK_DEBUG_ERROR("Failed to create STUN binding object");
         return -2;
     }
     tsk_atomic_inc(&__unique_id);
     (*pp_bind)->id = __unique_id;
     (*pp_bind)->localFD = fd;
     (*pp_bind)->socket_type = socket_type;
     (*pp_bind)->p_username = tsk_strdup(pc_username);
     (*pp_bind)->p_password = tsk_strdup(pc_password);
 
     if (pc_server_address && server_port) {
         int ret;
         if ((ret = tnet_sockaddr_init(pc_server_address, server_port, socket_type, &(*pp_bind)->addr_server))) {
             TSK_OBJECT_SAFE_FREE((*pp_bind));
             TSK_DEBUG_ERROR("Failed to init STUN server address");
             return ret;
         }
     }
     return 0;
 }
 
 int tnet_stun_binding_create_req(const struct tnet_stun_binding_s* pc_self, struct tnet_stun_pkt_s **pp_req)
 {
     int ret;
     if (!pc_self || !pp_req) {
         TSK_DEBUG_ERROR("Invalid parameter");
         return -1;
     }
 
     if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_binding_request, pp_req))) {
         TSK_DEBUG_ERROR("Failed to create STUN Bind request");
         goto bail;
     }
     // add attributes
     (*pp_req)->opt.dontfrag = 0;
     ret = tnet_stun_pkt_attrs_add(*pp_req,
                                   TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware),
                                   TNET_STUN_PKT_ATTR_ADD_NULL());
     if (ret) {
         goto bail;
     }
     if (pc_self->p_username && pc_self->p_realm && pc_self->p_nonce) {
         if ((ret = tnet_stun_pkt_auth_prepare(*pp_req, pc_self->p_username, pc_self->p_password, pc_self->p_realm, pc_self->p_nonce))) {
             goto bail;
         }
     }
 
 bail:
     if (ret) {
         TSK_OBJECT_SAFE_FREE(*pp_req);
     }
     return ret;
 }
 
 static tsk_object_t* tnet_stun_binding_ctor(tsk_object_t * self, va_list * app)
 {
     tnet_stun_binding_t *p_bind = (tnet_stun_binding_t *)self;
     if (p_bind) {
     }
     return self;
 }
 static tsk_object_t* tnet_stun_binding_dtor(tsk_object_t * self)
 {
     tnet_stun_binding_t *p_bind = (tnet_stun_binding_t *)self;
     if (p_bind) {
         TSK_DEBUG_INFO("*** STUN BINDING destroyed ***");
         TSK_FREE(p_bind->p_username);
         TSK_FREE(p_bind->p_password);
         TSK_FREE(p_bind->p_realm);
         TSK_FREE(p_bind->p_nonce);
 
         TSK_OBJECT_SAFE_FREE(p_bind->p_maddr);
         TSK_OBJECT_SAFE_FREE(p_bind->p_xmaddr);
     }
     return self;
 }
 static int tnet_stun_binding_cmp(const tsk_object_t *_bind1, const tsk_object_t *_bind2)
 {
     const tnet_stun_binding_t *pc_bind1 = (const tnet_stun_binding_t *)_bind1;
     const tnet_stun_binding_t *pc_bind2 = (const tnet_stun_binding_t *)_bind2;
 
     return (pc_bind1 && pc_bind2) ? (int)(pc_bind1->id - pc_bind2->id) : (int)(pc_bind1 - pc_bind2);
 }
 static const tsk_object_def_t tnet_stun_binding_def_s = {
     sizeof(tnet_stun_binding_t),
     tnet_stun_binding_ctor,
     tnet_stun_binding_dtor,
     tnet_stun_binding_cmp,
 };
 const tsk_object_def_t *tnet_stun_binding_def_t = &tnet_stun_binding_def_s;