⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tport_type_stun.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2006 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library 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 Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@CFILE tport_type_stun.c Transport using stun. * * See tport.docs for more detailed description of tport interface. * * @author Pekka Pessi <Pekka.Pessi@nokia.com> * @author Martti Mela <Martti.Mela@nokia.com> * * @date Created: Fri Mar 24 08:45:49 EET 2006 ppessi */#include "config.h"#define STUN_DISCOVERY_MAGIC_T  struct tport_primary#include "tport_internal.h"#include <stdlib.h>#include <time.h>#include <assert.h>#include <errno.h>#include <limits.h>/* ---------------------------------------------------------------------- *//* STUN */#include <sofia-sip/stun.h>static int tport_udp_init_stun(tport_primary_t *,			       tp_name_t tpn[1], 			       su_addrinfo_t *, 			       tagi_t const *,			       char const **return_culprit);static void tport_udp_deinit_stun(tport_primary_t *pri);staticvoid tport_stun_bind_cb(tport_primary_t *pri,			stun_handle_t *sh,			stun_discovery_t *sd,			stun_action_t action,			stun_state_t event);staticvoid tport_stun_bind_done(tport_primary_t *pri,			  stun_handle_t *sh,			  stun_discovery_t *sd);staticint tport_stun_keepalive(tport_t *tp, su_addrinfo_t const *ai,			 tagi_t const *taglist);static int tport_stun_response(tport_t const *self,			       void *dgram, size_t n,			       void *from, socklen_t fromlen);tport_vtable_t const tport_stun_vtable ={  "UDP", tport_type_stun,  sizeof (tport_primary_t),  tport_udp_init_stun,  tport_udp_deinit_stun,  NULL,  NULL,  sizeof (tport_t),  NULL,  NULL,  NULL,  NULL,  NULL,  tport_recv_dgram,  tport_send_dgram,  NULL,  NULL,  tport_stun_keepalive,  tport_stun_response};static int tport_udp_init_stun(tport_primary_t *pri,			       tp_name_t tpn[1], 			       su_addrinfo_t *ai, 			       tagi_t const *tags,			       char const **return_culprit){  stun_handle_t *sh;#if 0  if (!stun_is_requested(TAG_NEXT(tags)))    return -1;#endif  sh = stun_handle_init(pri->pri_master->mr_root, TAG_NEXT(tags));  if (!sh)    return *return_culprit = "stun_handle_init", -1;  pri->pri_stun_handle = sh;  tpn->tpn_canon = NULL;  if (tport_udp_init_primary(pri, tpn, ai, tags, return_culprit) < 0)    return -1;#if 0  if (stun_obtain_shared_secret(sh, tport_stun_tls_cb, pri, 				TAG_NEXT(tags)) < 0) {    return *return_culprit = "stun_request_shared_secret()", -1;  }#endif  if (stun_bind(sh, tport_stun_bind_cb, pri,		STUNTAG_SOCKET(pri->pri_primary->tp_socket),		STUNTAG_REGISTER_EVENTS(0),		TAG_NULL()) < 0) {    return *return_culprit = "stun_bind()", -1;  }  pri->pri_updating = 1;  return 0;}static void tport_udp_deinit_stun(tport_primary_t *pri){  if (pri->pri_stun_handle)     stun_handle_destroy(pri->pri_stun_handle);   pri->pri_stun_handle = NULL;}static int tport_stun_response(tport_t const *self,			       void *dgram, size_t n,			       void *from, socklen_t fromlen){  stun_process_message(self->tp_pri->pri_stun_handle, self->tp_socket,		       from, fromlen, (void *)dgram, n);  return 3;}/**Callback for STUN bind */staticvoid tport_stun_bind_cb(tport_primary_t *pri,			stun_handle_t *sh,			stun_discovery_t *sd,			stun_action_t action,			stun_state_t event){  tport_master_t *mr;  SU_DEBUG_3(("%s: %s\n", __func__, stun_str_state(event)));  mr = pri->pri_master;  if (event == stun_discovery_done) {    tport_stun_bind_done(pri, sh, sd);  }}staticvoid tport_stun_bind_done(tport_primary_t *pri,			  stun_handle_t *sh,			  stun_discovery_t *sd){  tport_t *self = pri->pri_primary;  su_socket_t socket;  su_sockaddr_t *su = self->tp_addr;  su_addrinfo_t *ai = self->tp_addrinfo;  socket = stun_discovery_get_socket(sd);  assert(pri->pri_primary->tp_socket == socket);  if (stun_discovery_get_address(sd, su, &ai->ai_addrlen) == 0) {    char ipname[SU_ADDRSIZE + 2] = { 0 };    ai->ai_addr = (void *)su;    SU_DEBUG_5(("%s: stun_bind() ok: local address NATed as %s:%u\n", 		__func__,		su_inet_ntop(su->su_family, SU_ADDR(su),			     ipname, sizeof(ipname)),		(unsigned) ntohs(su->su_port)));  }  /* Send message to calling application indicating    * there's a new public address available    */  tport_has_been_updated(self);    return;}/** Initialize STUN keepalives. * *@retval 0 */staticint tport_stun_keepalive(tport_t *tp, su_addrinfo_t const *ai,			 tagi_t const *taglist){  tport_primary_t *pri = tp->tp_pri;  int err;  err = stun_keepalive(pri->pri_stun_handle, 		       (su_sockaddr_t *)ai->ai_addr,		       STUNTAG_SOCKET(tp->tp_socket),		       STUNTAG_TIMEOUT(10000),		       TAG_NEXT(taglist));    if (err < 0)    return -1;  tp->tp_has_keepalive = 1;  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -