#if HAVE_CRT #define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #endif //HAVE_CRT /* * Copyright (C) 2020, University of the Basque Country (UPV/EHU) * 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;