[Asterisk-code-review] pbx dundi: added IPv4/IPv6 dual bind support to DUNDi (asterisk[16])
Kirsty Tyerman
asteriskteam at digium.com
Tue Jan 8 00:17:51 CST 2019
Kirsty Tyerman has uploaded this change for review. ( https://gerrit.asterisk.org/10860
Change subject: pbx_dundi: added IPv4/IPv6 dual bind support to DUNDi
......................................................................
pbx_dundi: added IPv4/IPv6 dual bind support to DUNDi
ASTERISK-28234
Reported-by: Kirsty Tyerman
Change-Id: I5d6e6b52dbe51415046bb3953fd16f5b421bc2e1
---
M pbx/pbx_dundi.c
1 file changed, 108 insertions(+), 23 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/60/10860/1
diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c
index f196721..3b30eaa 100644
--- a/pbx/pbx_dundi.c
+++ b/pbx/pbx_dundi.c
@@ -184,6 +184,7 @@
static struct io_context *io;
static struct ast_sched_context *sched;
static int netsocket = -1;
+static int netsocket2 = -1;
static pthread_t netthreadid = AST_PTHREADT_NULL;
static pthread_t precachethreadid = AST_PTHREADT_NULL;
static pthread_t clearcachethreadid = AST_PTHREADT_NULL;
@@ -2079,14 +2080,14 @@
return 0;
}
-static int socket_read(int *id, int fd, short events, void *cbdata)
+static int socket_read(int *id, int fd, short events, void *sock)
{
struct ast_sockaddr sin;
int res;
struct dundi_hdr *h;
char buf[MAX_PACKET_SIZE];
- res = ast_recvfrom(netsocket, buf, sizeof(buf), 0, &sin);
+ res = ast_recvfrom(*((int *)sock), buf, sizeof(buf), 0, &sin);
if (res < 0) {
if (errno != ECONNREFUSED)
ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
@@ -2196,7 +2197,11 @@
from the network, and queue them for delivery to the channels */
int res;
/* Establish I/O callback for socket read */
- int *socket_read_id = ast_io_add(io, netsocket, socket_read, AST_IO_IN, NULL);
+ int *socket_read_id = ast_io_add(io, netsocket, socket_read, AST_IO_IN, &netsocket);
+ int *socket_read_id2 = NULL;
+ if (netsocket2 >= 0) {
+ socket_read_id2 = ast_io_add(io, netsocket2, socket_read, AST_IO_IN, &netsocket2);
+ }
while (!dundi_shutdown) {
res = ast_sched_wait(sched);
@@ -2213,6 +2218,10 @@
ast_io_remove(io, socket_read_id);
+ if (!socket_read_id2) {
+ ast_io_remove(io, socket_read_id2);
+ }
+
return NULL;
}
@@ -3158,7 +3167,17 @@
int res;
if (dundidebug)
dundi_showframe(pack->h, 0, &pack->parent->addr, pack->datalen - sizeof(struct dundi_hdr));
- res = ast_sendto(netsocket, pack->data, pack->datalen, 0, &pack->parent->addr);
+
+ if (netsocket2 < 0) {
+ res = ast_sendto(netsocket, pack->data, pack->datalen, 0, &pack->parent->addr);
+ } else {
+ if (ast_sockaddr_is_ipv4(&pack->parent->addr)) {
+ res = ast_sendto(netsocket, pack->data, pack->datalen, 0, &pack->parent->addr);
+ } else {
+ res = ast_sendto(netsocket2, pack->data, pack->datalen, 0, &pack->parent->addr);
+ }
+ }
+
if (res < 0) {
ast_log(LOG_WARNING, "Failed to transmit to '%s': %s\n",
ast_sockaddr_stringify(&pack->parent->addr), strerror(errno));
@@ -4912,7 +4931,7 @@
get_ipaddress(ipaddr, sizeof(ipaddr), hn, family);
}
-static int set_config(char *config_file, struct ast_sockaddr *sin, int reload)
+static int set_config(char *config_file, struct ast_sockaddr *sin, int reload, struct ast_sockaddr *sin2)
{
struct ast_config *cfg;
struct ast_variable *v;
@@ -4923,7 +4942,8 @@
int port = 0;
int globalpcmodel = 0;
dundi_eid testeid;
- char bind_addr[80];
+ char bind_addr[80]={0,};
+ char bind_addr2[80]={0,};
if (!(cfg = ast_config_load(config_file, config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
@@ -4953,6 +4973,12 @@
ast_log(LOG_WARNING, "Invalid host/IP '%s'\n", v->value);
}
}
+ } else if (!strcasecmp(v->name, "bindaddr2")) {
+ if (get_ipaddress(bind_addr2, sizeof(bind_addr2), v->value, AF_UNSPEC) == 0) {
+ if (!ast_sockaddr_parse(sin2, bind_addr2, 0)) {
+ ast_log(LOG_WARNING, "Invalid host/IP '%s'\n", v->value);
+ }
+ }
} else if (!strcasecmp(v->name, "authdebug")) {
authdebug = ast_true(v->value);
} else if (!strcasecmp(v->name, "ttl")) {
@@ -5027,6 +5053,10 @@
set_host_ipaddr(sin);
+ if (!ast_sockaddr_isnull(sin2)) {
+ ast_sockaddr_set_port(sin2, port);
+ }
+
AST_LIST_UNLOCK(&peers);
mark_mappings();
@@ -5089,6 +5119,18 @@
clearcachethreadid = AST_PTHREADT_NULL;
}
+ if (netsocket >= 0) {
+ close(netsocket);
+ }
+
+ if (netsocket2 >= 0) {
+ close(netsocket2);
+ }
+
+ if (io) {
+ io_context_destroy(io);
+ }
+
mark_mappings();
prune_mappings();
mark_peers();
@@ -5114,10 +5156,12 @@
static int reload(void)
{
struct ast_sockaddr sin;
+ struct ast_sockaddr sin2;
ast_sockaddr_setnull(&sin);
+ ast_sockaddr_setnull(&sin2);
- if (set_config("dundi.conf", &sin, 1))
+ if (set_config("dundi.conf", &sin, 1, &sin2))
return AST_MODULE_LOAD_FAILURE;
return AST_MODULE_LOAD_SUCCESS;
@@ -5126,6 +5170,7 @@
static int load_module(void)
{
struct ast_sockaddr sin;
+ struct ast_sockaddr sin2;
dundi_set_output(dundi_debug_output);
dundi_set_error(dundi_error_output);
@@ -5139,29 +5184,69 @@
}
ast_sockaddr_setnull(&sin);
+ ast_sockaddr_setnull(&sin2);
- if (set_config("dundi.conf", &sin, 0)) {
+ if (set_config("dundi.conf", &sin, 0, &sin2)) {
goto declined;
}
- if (ast_sockaddr_is_ipv6(&sin)) {
- netsocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
- } else {
+ if (!ast_sockaddr_isnull(&sin2)) {
+ if ((ast_sockaddr_is_ipv4(&sin) == ast_sockaddr_is_ipv4(&sin2)) || (ast_sockaddr_is_ipv6(&sin) == ast_sockaddr_is_ipv6(&sin2))) {
+ ast_log(LOG_ERROR, "bind & bind2 ip protocol should be different");
+ goto declined;
+ }
+
+ /*bind netsocket to ipv4, netsocket2 to ipv6 */
+
netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+ netsocket2 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+ if (netsocket < 0 || netsocket2 < 0) {
+ ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
+ goto declined;
+ }
+ if (ast_sockaddr_is_ipv4(&sin)) {
+ if (ast_bind(netsocket, &sin)) {
+ ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",
+ ast_sockaddr_stringify(&sin), strerror(errno));
+ goto declined;
+ }
+ if (ast_bind(netsocket2, &sin2)) {
+ ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",
+ ast_sockaddr_stringify(&sin), strerror(errno));
+ goto declined;
+ }
+ } else {
+ if (ast_bind(netsocket, &sin2)) {
+ ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",
+ ast_sockaddr_stringify(&sin), strerror(errno));
+ goto declined;
+ }
+ if (ast_bind(netsocket2, &sin)) {
+ ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",
+ ast_sockaddr_stringify(&sin), strerror(errno));
+ goto declined;
+ }
+ }
+ ast_set_qos(netsocket, tos, 0, "DUNDi");
+ ast_set_qos(netsocket2, tos, 0, "DUNDi");
+ } else {
+ if (ast_sockaddr_is_ipv6(&sin)) {
+ netsocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+ } else {
+ netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+ }
+ if (netsocket < 0) {
+ ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
+ goto declined;
+ }
+ if (ast_bind(netsocket, &sin)) {
+ ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",
+ ast_sockaddr_stringify(&sin), strerror(errno));
+ goto declined;
+ }
+ ast_set_qos(netsocket, tos, 0, "DUNDi");
}
- if (netsocket < 0) {
- ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
- goto declined;
- }
- if (ast_bind(netsocket, &sin)) {
- ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",
- ast_sockaddr_stringify(&sin), strerror(errno));
- goto declined;
- }
-
- ast_set_qos(netsocket, tos, 0, "DUNDi");
-
if (start_network_thread()) {
ast_log(LOG_ERROR, "Unable to start network thread\n");
goto declined;
--
To view, visit https://gerrit.asterisk.org/10860
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: 16
Gerrit-MessageType: newchange
Gerrit-Change-Id: I5d6e6b52dbe51415046bb3953fd16f5b421bc2e1
Gerrit-Change-Number: 10860
Gerrit-PatchSet: 1
Gerrit-Owner: Kirsty Tyerman <kirsty.tyerman at boeing.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20190108/38572394/attachment-0001.html>
More information about the asterisk-code-review
mailing list