[asterisk-commits] dvossel: branch dvossel/sip_stun_support_improved r280619 - in /team/dvossel/...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Jul 30 12:37:32 CDT 2010
Author: dvossel
Date: Fri Jul 30 12:37:28 2010
New Revision: 280619
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=280619
Log:
improved sip stun support
Added:
team/dvossel/sip_stun_support_improved/channels/sip/include/sipstun.h (with props)
team/dvossel/sip_stun_support_improved/channels/sip/sipstun.c (with props)
Modified:
team/dvossel/sip_stun_support_improved/channels/chan_sip.c
team/dvossel/sip_stun_support_improved/configs/sip.conf.sample
Modified: team/dvossel/sip_stun_support_improved/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/sip_stun_support_improved/channels/chan_sip.c?view=diff&rev=280619&r1=280618&r2=280619
==============================================================================
--- team/dvossel/sip_stun_support_improved/channels/chan_sip.c (original)
+++ team/dvossel/sip_stun_support_improved/channels/chan_sip.c Fri Jul 30 12:37:28 2010
@@ -274,6 +274,7 @@
#include "asterisk/xml.h"
#include "sip/include/dialog.h"
#include "sip/include/dialplan_functions.h"
+#include "sip/include/sipstun.h"
/*** DOCUMENTATION
@@ -1155,6 +1156,8 @@
static time_t externexpire; /*!< Expiration counter for re-resolving external host name in dynamic DNS */
static int externrefresh = 10; /*!< Refresh timer for DNS-based external address (dyndns) */
static struct sockaddr_in stunaddr; /*!< stun server address */
+static struct sip_stun_args stun_client; /*!< stun client to send requests from */
+
static uint16_t externtcpport; /*!< external tcp port */
static uint16_t externtlsport; /*!< external tls port */
@@ -3151,7 +3154,7 @@
if (externexpire && time(NULL) >= externexpire) {
if (stunaddr.sin_addr.s_addr) {
ast_sockaddr_to_sin(&externaddr, &externaddr_sin);
- ast_stun_request(sipsock, &stunaddr, NULL, &externaddr_sin);
+ sip_stun_request(&stun_client, &stunaddr, NULL, &externaddr_sin);
} else {
if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) {
ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
@@ -26214,6 +26217,7 @@
/* Reset IP addresses */
ast_sockaddr_parse(&bindaddr, "0.0.0.0:0", 0);
+ sip_stun_set_default_bind(&stun_client);
memset(&stunaddr, 0, sizeof(stunaddr));
memset(&internip, 0, sizeof(internip));
@@ -26606,6 +26610,8 @@
ast_log(LOG_WARNING, "Invalid STUN server address: %s\n", v->value);
}
externexpire = time(NULL);
+ } else if (!strcasecmp(v->name, "stunbindaddr")) {
+ sip_stun_set_bindaddr(&stun_client, v->value);
} else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) {
if (ast_parse_arg(v->value, PARSE_ADDR, &bindaddr)) {
ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
@@ -26906,14 +26912,18 @@
}
}
}
+
if (stunaddr.sin_addr.s_addr != 0) {
- ast_debug(1, "stun to %s:%d\n",
- ast_inet_ntoa(stunaddr.sin_addr) , ntohs(stunaddr.sin_port));
+ ast_debug(1, "stun to %s:%d\n", ast_inet_ntoa(stunaddr.sin_addr) , ntohs(stunaddr.sin_port));
ast_sockaddr_to_sin(&externaddr, &externaddr_sin);
- ast_stun_request(sipsock, &stunaddr,
- NULL, &externaddr_sin);
- ast_debug(1, "STUN sees us at %s\n",
- ast_sockaddr_stringify(&externaddr));
+ if (sip_stun_bind_socket(&stun_client) != -1) {
+ sip_stun_request(&stun_client, &stunaddr, NULL, &externaddr_sin);
+ ast_debug(1, "STUN sees us at %s\n", ast_sockaddr_stringify(&externaddr));
+ } else {
+ ast_log(LOG_WARNING, "SIP STUN Error, can not request externaddr, socket failed to open.\n");
+ }
+ } else {
+ sip_stun_close_sock(&stun_client);
}
ast_mutex_unlock(&netlock);
@@ -28210,6 +28220,8 @@
ASTOBJ_CONTAINER_INIT(®l); /* Registry object list -- not searched for anything */
ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */
+ sip_stun_init(&stun_client);
+
if (!(sched = sched_context_create())) {
ast_log(LOG_ERROR, "Unable to create scheduler context\n");
return AST_MODULE_LOAD_FAILURE;
@@ -28463,6 +28475,8 @@
ast_cc_monitor_unregister(&sip_cc_monitor_callbacks);
ast_cc_agent_unregister(&sip_cc_agent_callbacks);
+ sip_stun_destroy(&stun_client);
+
sip_reqresp_parser_exit();
sip_unregister_tests();
Added: team/dvossel/sip_stun_support_improved/channels/sip/include/sipstun.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/sip_stun_support_improved/channels/sip/include/sipstun.h?view=auto&rev=280619
==============================================================================
--- team/dvossel/sip_stun_support_improved/channels/sip/include/sipstun.h (added)
+++ team/dvossel/sip_stun_support_improved/channels/sip/include/sipstun.h Fri Jul 30 12:37:28 2010
@@ -1,0 +1,65 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief sip stun client header file
+ */
+
+#ifndef _SIP_STUN_H
+#define _SIP_STUN_H
+#include "asterisk/lock.h"
+#include "asterisk/netsock2.h"
+
+#define STUN_DEFAULT_PORT 3478
+struct sip_stun_args {
+ struct ast_sockaddr stunbindaddr; /*!< The stun address we bind to. */
+ ast_mutex_t lock;
+ int stunsock;
+};
+
+/*!
+ * \brief set stun bind address
+ *
+ * \note sip_stun_bind_socket must be called before this will take effect
+ *
+ * \retval 0 success -1 failure
+ */
+int sip_stun_set_bindaddr(struct sip_stun_args *args, const char *value);
+
+/*!
+ * \brief
+ *
+ * \retval 0 success -1 failure
+ */
+int sip_stun_request(struct sip_stun_args *args, struct sockaddr_in *dst, const char *username, struct sockaddr_in *answer);
+
+/*!
+ * \brief closes old socket, creates new socket and binds address
+ *
+ * \retval 0 success -1 failure
+ */
+int sip_stun_bind_socket(struct sip_stun_args *args);
+
+void sip_stun_set_default_bind(struct sip_stun_args *args);
+
+void sip_stun_close_sock(struct sip_stun_args *args);
+
+void sip_stun_init(struct sip_stun_args *args);
+
+void sip_stun_destroy(struct sip_stun_args *args);
+
+#endif
Propchange: team/dvossel/sip_stun_support_improved/channels/sip/include/sipstun.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/dvossel/sip_stun_support_improved/channels/sip/include/sipstun.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/dvossel/sip_stun_support_improved/channels/sip/include/sipstun.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/dvossel/sip_stun_support_improved/channels/sip/sipstun.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/sip_stun_support_improved/channels/sip/sipstun.c?view=auto&rev=280619
==============================================================================
--- team/dvossel/sip_stun_support_improved/channels/sip/sipstun.c (added)
+++ team/dvossel/sip_stun_support_improved/channels/sip/sipstun.c Fri Jul 30 12:37:28 2010
@@ -1,0 +1,145 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief sip stun client
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "include/sipstun.h"
+#include "asterisk/stun.h"
+#include "asterisk/config.h"
+
+
+static void stun_close_sock(struct sip_stun_args *args, int lock)
+{
+ if (lock) {
+ ast_mutex_lock(&args->lock);
+ }
+
+ if (args->stunsock < 0) {
+ close(args->stunsock);
+ args->stunsock = -1;
+ }
+
+ if (lock) {
+ ast_mutex_unlock(&args->lock);
+ }
+}
+
+void sip_stun_close_sock(struct sip_stun_args *args)
+{
+ stun_close_sock(args, 1);
+}
+
+static void stun_set_default_bind(struct sip_stun_args *args, int lock)
+{
+ if (lock) {
+ ast_mutex_lock(&args->lock);
+ }
+
+ ast_sockaddr_parse(&args->stunbindaddr, "0.0.0.0:0", 0);
+
+ if (lock) {
+ ast_mutex_unlock(&args->lock);
+ }
+
+}
+
+void sip_stun_set_default_bind(struct sip_stun_args *args)
+{
+ stun_set_default_bind(args, 1);
+}
+
+int sip_stun_request(struct sip_stun_args *args, struct sockaddr_in *dst, const char *username, struct sockaddr_in *answer)
+{
+ int res;
+
+ ast_mutex_lock(&args->lock);
+ if (args->stunsock < 0) {
+ res = -1;
+ } else {
+ res = ast_stun_request(args->stunsock, dst, username, answer);
+ }
+ ast_mutex_unlock(&args->lock);
+
+ return res;
+}
+
+int sip_stun_set_bindaddr(struct sip_stun_args *args, const char *value)
+{
+ int res = 0;
+ ast_mutex_lock(&args->lock);
+ if (ast_parse_arg(value, PARSE_ADDR, &args->stunbindaddr)) {
+ ast_log(LOG_WARNING, "SIP STUN. invalid address: %s\n", value);
+ stun_set_default_bind(args, 0);
+ res = -1;
+ }
+ ast_mutex_unlock(&args->lock);
+ return res;
+}
+
+int sip_stun_bind_socket(struct sip_stun_args *args)
+{
+ int res = -1;
+
+ ast_mutex_lock(&args->lock);
+
+ /* close sock if it was already open */
+ stun_close_sock(args, 0);
+
+ /* open new socket and bind addr */
+ if (!ast_sockaddr_port(&args->stunbindaddr)) {
+ ast_sockaddr_set_port(&args->stunbindaddr, STUN_DEFAULT_PORT);
+ }
+ args->stunsock = socket(ast_sockaddr_is_ipv6(&args->stunbindaddr) ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
+ if (args->stunsock < 0) {
+ ast_log(LOG_WARNING, "Unable to create STUN socket: %s\n", strerror(errno));
+ goto stun_bind_cleanup;
+ } else {
+ const int reuseFlag = 1;
+ setsockopt(args->stunsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseFlag, sizeof(reuseFlag));
+
+ if (ast_bind(args->stunsock, &args->stunbindaddr) < 0) {
+ ast_log(LOG_WARNING, "SIP STUN Failed to bind to %s: %s\n", ast_sockaddr_stringify(&args->stunbindaddr), strerror(errno));
+ stun_close_sock(args, 0);
+ goto stun_bind_cleanup;
+ }
+ }
+ res = 0;
+
+stun_bind_cleanup:
+ ast_mutex_unlock(&args->lock);
+
+ return res;
+}
+
+void sip_stun_init(struct sip_stun_args *args)
+{
+ memset(args, 0, sizeof(args));
+ stun_set_default_bind(args, 0);
+ ast_mutex_init(&args->lock);
+}
+
+void sip_stun_destroy(struct sip_stun_args *args)
+{
+ stun_close_sock(args, 1);
+ ast_mutex_destroy(&args->lock);
+}
Propchange: team/dvossel/sip_stun_support_improved/channels/sip/sipstun.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/dvossel/sip_stun_support_improved/channels/sip/sipstun.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/dvossel/sip_stun_support_improved/channels/sip/sipstun.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/dvossel/sip_stun_support_improved/configs/sip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/sip_stun_support_improved/configs/sip.conf.sample?view=diff&rev=280619&r1=280618&r2=280619
==============================================================================
--- team/dvossel/sip_stun_support_improved/configs/sip.conf.sample (original)
+++ team/dvossel/sip_stun_support_improved/configs/sip.conf.sample Fri Jul 30 12:37:28 2010
@@ -706,6 +706,11 @@
;
; stunaddr = foo.stun.com:3478
; externrefresh = 15
+;
+; By default stun queries will be sent from port 3478. To bind the stun
+; client to a different address/port use the 'stunbindaddr' option.
+;
+; stunbindaddr = 0.0.0.0:5000 ; bind stun client address.
;
; Note that at the moment all these mechanism work only for the SIP socket.
; The IP address discovered with externaddr/externhost/STUN is reused for
More information about the asterisk-commits
mailing list