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