[Asterisk-code-review] pbx dundi: Added IPv6 support for dundi (asterisk[master])
Kirsty Tyerman
asteriskteam at digium.com
Mon Jun 11 18:16:18 CDT 2018
Kirsty Tyerman has uploaded this change for review. ( https://gerrit.asterisk.org/9175
Change subject: pbx_dundi: Added IPv6 support for dundi
......................................................................
pbx_dundi: Added IPv6 support for dundi
Change includes move to netsock2 library.
ASTERISK-27164
Reported-by: Adam Secombe
Change-Id: Ia9e8dc3d153de7a291dbda4bd87fc827dd2bb846
---
M pbx/dundi-parser.c
M pbx/dundi-parser.h
M pbx/pbx_dundi.c
3 files changed, 178 insertions(+), 124 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/75/9175/1
diff --git a/pbx/dundi-parser.c b/pbx/dundi-parser.c
index 808559c..242de63 100644
--- a/pbx/dundi-parser.c
+++ b/pbx/dundi-parser.c
@@ -37,6 +37,7 @@
#include "asterisk/dundi.h"
#include "dundi-parser.h"
+extern int netsock_ai_family;
static void internaloutput(const char *str)
{
fputs(str, stdout);
@@ -428,7 +429,7 @@
outputf("\n");
}
-void dundi_showframe(struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
+void dundi_showframe(struct dundi_hdr *fhi, int rx, struct ast_sockaddr *sin, int datalen)
{
char *pref[] = {
"Tx",
@@ -469,11 +470,13 @@
pref[rx],
fhi->oseqno, fhi->iseqno, class, fhi->cmdresp & 0x40 ? "Response" : "Command");
outputf(tmp);
+
snprintf(tmp, (int)sizeof(tmp),
- "%s Flags: %s STrans: %5.5d DTrans: %5.5d [%s:%d]%s\n", (rx > 1) ? " " : "",
+ "%s Flags: %s STrans: %5.5d DTrans: %5.5d [%s]%s\n", (rx > 1) ? " " : "",
subclass, ntohs(fhi->strans) & ~DUNDI_FLAG_RESERVED, ntohs(fhi->dtrans) & ~DUNDI_FLAG_RETRANS,
- ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port),
+ ast_sockaddr_stringify(sin),
fhi->cmdresp & 0x80 ? " (Final)" : "");
+
outputf(tmp);
dump_ies(fhi->ies, rx > 1, datalen);
}
@@ -580,9 +583,9 @@
return 0;
}
-int dundi_ie_append_addr(struct dundi_ie_data *ied, unsigned char ie, struct sockaddr_in *sin)
+int dundi_ie_append_addr(struct dundi_ie_data *ied, unsigned char ie, struct ast_sockaddr *sin)
{
- return dundi_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
+ return dundi_ie_append_raw(ied, ie, sin, (int)sizeof(struct ast_sockaddr));
}
int dundi_ie_append_int(struct dundi_ie_data *ied, unsigned char ie, unsigned int value)
diff --git a/pbx/dundi-parser.h b/pbx/dundi-parser.h
index b24d486..b405a42 100644
--- a/pbx/dundi-parser.h
+++ b/pbx/dundi-parser.h
@@ -60,12 +60,12 @@
extern void dundi_set_output(void (*output)(const char *data));
/* Choose a different function for errors */
extern void dundi_set_error(void (*output)(const char *data));
-extern void dundi_showframe(struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
+extern void dundi_showframe(struct dundi_hdr *fhi, int rx, struct ast_sockaddr *sin, int datalen);
extern const char *dundi_ie2str(int ie);
extern int dundi_ie_append_raw(struct dundi_ie_data *ied, unsigned char ie, void *data, int datalen);
-extern int dundi_ie_append_addr(struct dundi_ie_data *ied, unsigned char ie, struct sockaddr_in *sin);
+extern int dundi_ie_append_addr(struct dundi_ie_data *ied, unsigned char ie, struct ast_sockaddr *sin);
extern int dundi_ie_append_int(struct dundi_ie_data *ied, unsigned char ie, unsigned int value);
extern int dundi_ie_append_short(struct dundi_ie_data *ied, unsigned char ie, unsigned short value);
extern int dundi_ie_append_str(struct dundi_ie_data *ied, unsigned char ie, char *str);
diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c
index 0420917..9a86101 100644
--- a/pbx/pbx_dundi.c
+++ b/pbx/pbx_dundi.c
@@ -48,7 +48,6 @@
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__Darwin__)
#include <net/if_dl.h>
#include <ifaddrs.h>
-#include <signal.h>
#endif
#include "asterisk/file.h"
@@ -241,7 +240,7 @@
struct dundi_request;
struct dundi_transaction {
- struct sockaddr_in addr; /*!< Other end of transaction */
+ struct ast_sockaddr addr; /*!< Other end of transaction */
struct timeval start; /*!< When this transaction was created */
dundi_eid eids[DUNDI_MAX_STACK + 1];
int eidcount; /*!< Number of eids in eids */
@@ -300,7 +299,7 @@
struct dundi_peer {
dundi_eid eid;
- struct sockaddr_in addr; /*!< Address of DUNDi peer */
+ struct ast_sockaddr addr; /*!< Address of DUNDi peer */
AST_LIST_HEAD_NOLOCK(permissionlist, permission) permit;
struct permissionlist include;
dundi_eid us_eid;
@@ -350,6 +349,29 @@
static struct dundi_peer *any_peer;
static int dundi_xmit(struct dundi_packet *pack);
+
+static int get_ai_family(const char *address)
+{
+ struct addrinfo hint, *res = NULL;
+ int ret;
+
+ memset(&hint, '\0', sizeof hint);
+
+ hint.ai_family = PF_UNSPEC;
+ hint.ai_flags = AI_NUMERICHOST;
+
+ ret = getaddrinfo(address, NULL, &hint, &res);
+ if (ret) {
+ ast_log(LOG_ERROR, "Invalid address %s \n", address);
+ return -1;
+ }
+
+ ret = res->ai_family;
+
+ freeaddrinfo(res);
+
+ return ret;
+}
static void dundi_debug_output(const char *data)
{
@@ -406,13 +428,15 @@
static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *md, int *expiration, int cybpass, int modeselect, dundi_eid *skip, dundi_eid *avoid[], int direct[]);
static int dundi_precache_internal(const char *context, const char *number, int ttl, dundi_eid *avoids[]);
static struct dundi_transaction *create_transaction(struct dundi_peer *p);
-static struct dundi_transaction *find_transaction(struct dundi_hdr *hdr, struct sockaddr_in *sin)
+static struct dundi_transaction *find_transaction(struct dundi_hdr *hdr, struct ast_sockaddr *sin)
{
struct dundi_transaction *trans;
+ int cmp;
/* Look for an exact match first */
AST_LIST_TRAVERSE(&alltrans, trans, all) {
- if (!inaddrcmp(&trans->addr, sin) &&
+ cmp = ast_sockaddr_cmp(&trans->addr, sin);
+ if ( !cmp &&
((trans->strans == (ntohs(hdr->dtrans) & 32767)) /* Matches our destination */ ||
((trans->dtrans == (ntohs(hdr->strans) & 32767)) && (!hdr->dtrans))) /* We match their destination */) {
if (hdr->strans)
@@ -448,7 +472,7 @@
{
return dundi_send(trans, DUNDI_COMMAND_ACK, 0, final, NULL);
}
-static void dundi_reject(struct dundi_hdr *h, struct sockaddr_in *sin)
+static void dundi_reject(struct dundi_hdr *h, struct ast_sockaddr *sin)
{
struct {
struct dundi_packet pack;
@@ -460,7 +484,7 @@
return;
memset(&tmp, 0, sizeof(tmp));
memset(&trans, 0, sizeof(trans));
- memcpy(&trans.addr, sin, sizeof(trans.addr));
+ memcpy(&trans.addr, sin, sizeof(struct ast_sockaddr));
tmp.hdr.strans = h->dtrans;
tmp.hdr.dtrans = h->strans;
tmp.hdr.iseqno = h->oseqno;
@@ -992,9 +1016,9 @@
sizeof(trans->parent->dr[trans->parent->respcount].tech));
trans->parent->respcount++;
ast_clear_flag_nonstd(trans->parent->hmd, DUNDI_HINT_DONT_ASK);
- } else if (trans->parent->dr[z].weight > ntohs(ies->answers[x]->weight)) {
+ } else if (trans->parent->dr[z].weight > ies->answers[x]->weight) {
/* Update weight if appropriate */
- trans->parent->dr[z].weight = ntohs(ies->answers[x]->weight);
+ trans->parent->dr[z].weight = ies->answers[x]->weight;
}
} else
ast_log(LOG_NOTICE, "Dropping excessive answers in precache for %s@%s\n",
@@ -1290,8 +1314,8 @@
static void apply_peer(struct dundi_transaction *trans, struct dundi_peer *p)
{
- if (!trans->addr.sin_addr.s_addr)
- memcpy(&trans->addr, &p->addr, sizeof(trans->addr));
+ if ( ast_sockaddr_isnull(&trans->addr))
+ memcpy(&trans->addr, &p->addr, sizeof(struct ast_sockaddr));
trans->us_eid = p->us_eid;
trans->them_eid = p->eid;
/* Enable encryption if appropriate */
@@ -1705,13 +1729,12 @@
int needqual = 0;
AST_SCHED_DEL(sched, peer->registerexpire);
peer->registerexpire = ast_sched_add(sched, (expire + 10) * 1000, do_register_expire, peer);
- snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(trans->addr.sin_addr),
- ntohs(trans->addr.sin_port), expire);
+ snprintf(data,sizeof(data),"%s:%d",ast_sockaddr_stringify(&trans->addr),expire);
ast_db_put("dundi/dpeers", dundi_eid_to_str_short(eid_str, sizeof(eid_str), &peer->eid), data);
- if (inaddrcmp(&peer->addr, &trans->addr)) {
- ast_verb(3, "Registered DUNDi peer '%s' at '%s:%d'\n",
- ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),
- ast_inet_ntoa(trans->addr.sin_addr), ntohs(trans->addr.sin_port));
+ if ( ast_sockaddr_cmp(&peer->addr,&trans->addr)) {
+ ast_verb(3, "Registered DUNDi peer '%s' at '%s'\n",
+ ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),
+ ast_sockaddr_stringify(&trans->addr));
needqual = 1;
}
@@ -1763,9 +1786,9 @@
sizeof(trans->parent->dr[trans->parent->respcount].tech));
trans->parent->respcount++;
ast_clear_flag_nonstd(trans->parent->hmd, DUNDI_HINT_DONT_ASK);
- } else if (trans->parent->dr[z].weight > ntohs(ies.answers[x]->weight)) {
+ } else if (trans->parent->dr[z].weight > ies.answers[x]->weight) {
/* Update weight if appropriate */
- trans->parent->dr[z].weight = ntohs(ies.answers[x]->weight);
+ trans->parent->dr[z].weight = ies.answers[x]->weight;
}
} else
ast_log(LOG_NOTICE, "Dropping excessive answers to request for %s@%s\n",
@@ -1839,7 +1862,7 @@
ast_copy_string(trans->parent->dei->ipaddr, ies.q_ipaddr, sizeof(trans->parent->dei->ipaddr));
if (!ast_eid_cmp(&trans->them_eid, &trans->parent->query_eid)) {
/* If it's them, update our address */
- ast_copy_string(trans->parent->dei->ipaddr, ast_inet_ntoa(trans->addr.sin_addr), sizeof(trans->parent->dei->ipaddr));
+ ast_copy_string(trans->parent->dei->ipaddr,ast_sockaddr_stringify_addr(&trans->addr),sizeof(trans->parent->dei->ipaddr));
}
}
if (ies.hint) {
@@ -2022,7 +2045,7 @@
return 0;
}
-static int handle_frame(struct dundi_hdr *h, struct sockaddr_in *sin, int datalen)
+static int handle_frame(struct dundi_hdr *h, struct ast_sockaddr *sin, int datalen)
{
struct dundi_transaction *trans;
trans = find_transaction(h, sin);
@@ -2065,13 +2088,13 @@
static int socket_read(int *id, int fd, short events, void *cbdata)
{
- struct sockaddr_in sin;
+ struct ast_sockaddr sin;
int res;
struct dundi_hdr *h;
char buf[MAX_PACKET_SIZE];
- socklen_t len = sizeof(sin);
- res = recvfrom(netsocket, buf, sizeof(buf) - 1, 0,(struct sockaddr *) &sin, &len);
+ res = ast_recvfrom(netsocket,buf,sizeof(buf),0,&sin);
+
if (res < 0) {
if (errno != ECONNREFUSED)
ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
@@ -2624,8 +2647,8 @@
ast_cli(a->fd, "Peer: %s\n", ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));
ast_cli(a->fd, "Model: %s\n", model2str(peer->model));
ast_cli(a->fd, "Order: %s\n", order);
- ast_cli(a->fd, "Host: %s\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "<Unspecified>");
- ast_cli(a->fd, "Port: %d\n", ntohs(peer->addr.sin_port));
+ ast_cli(a->fd, "Host: %s\n", ast_sockaddr_isnull(&peer->addr) ?"<Unspecified>": ast_sockaddr_stringify_host(&peer->addr));
+ ast_cli(a->fd, "Port: %d\n", ast_sockaddr_port(&peer->addr));
ast_cli(a->fd, "Dynamic: %s\n", peer->dynamic ? "yes" : "no");
ast_cli(a->fd, "Reg: %s\n", peer->registerid < 0 ? "No" : "Yes");
ast_cli(a->fd, "In Key: %s\n", ast_strlen_zero(peer->inkey) ? "<None>" : peer->inkey);
@@ -2657,8 +2680,8 @@
static char *dundi_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
-#define FORMAT2 "%-20.20s %-15.15s %-6.6s %-10.10s %-8.8s %-15.15s\n"
-#define FORMAT "%-20.20s %-15.15s %s %-6d %-10.10s %-8.8s %-15.15s\n"
+#define FORMAT2 "%-20.20s %-39s %-6.6s %-10.10s %-8.8s %-15.15s\n"
+#define FORMAT "%-20.20s %-39s %s %-6d %-10.10s %-8.8s %-15.15s\n"
struct dundi_peer *peer;
int registeredonly=0;
char avgms[20];
@@ -2696,7 +2719,8 @@
int print_line = -1;
char srch[2000];
total_peers++;
- if (registeredonly && !peer->addr.sin_addr.s_addr)
+
+ if (registeredonly && ast_sockaddr_isnull(&peer->addr))
continue;
if (peer->maxms) {
if (peer->lastms < 0) {
@@ -2723,9 +2747,9 @@
snprintf(avgms, sizeof(avgms), "%d ms", peer->avgms);
else
strcpy(avgms, "Unavail");
- snprintf(srch, sizeof(srch), FORMAT, ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),
- peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
- peer->dynamic ? "(D)" : "(S)", ntohs(peer->addr.sin_port), model2str(peer->model), avgms, status);
+ snprintf(srch, sizeof(srch), FORMAT, ast_eid_to_str(eid_str, sizeof(eid_str),
+ &peer->eid),ast_sockaddr_stringify_host(&peer->addr),
+ peer->dynamic ? "(D)" : "(S)", ast_sockaddr_port(&peer->addr), model2str(peer->model), avgms, status);
if (a->argc == 5) {
if (!strcasecmp(a->argv[3],"include") && strstr(srch,a->argv[4])) {
@@ -2741,8 +2765,8 @@
if (print_line) {
ast_cli(a->fd, FORMAT, ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),
- peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
- peer->dynamic ? "(D)" : "(S)", ntohs(peer->addr.sin_port), model2str(peer->model), avgms, status);
+ ast_sockaddr_stringify_host(&peer->addr),
+ peer->dynamic ? "(D)" : "(S)", ast_sockaddr_port(&peer->addr), model2str(peer->model), avgms, status);
}
}
ast_cli(a->fd, "%d dundi peers [%d online, %d offline, %d unmonitored]\n", total_peers, online_peers, offline_peers, unmonitored_peers);
@@ -2754,8 +2778,8 @@
static char *dundi_show_trans(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
-#define FORMAT2 "%-22.22s %-5.5s %-5.5s %-3.3s %-3.3s %-3.3s\n"
-#define FORMAT "%-16.16s:%5d %-5.5d %-5.5d %-3.3d %-3.3d %-3.3d\n"
+#define FORMAT2 "%-44s %-5.5s %-5.5s %-3.3s %-3.3s %-3.3s\n"
+#define FORMAT "%-39s:%5d %-5.5d %-5.5d %-3.3d %-3.3d %-3.3d\n"
struct dundi_transaction *trans;
switch (cmd) {
case CLI_INIT:
@@ -2773,8 +2797,9 @@
AST_LIST_LOCK(&peers);
ast_cli(a->fd, FORMAT2, "Remote", "Src", "Dst", "Tx", "Rx", "Ack");
AST_LIST_TRAVERSE(&alltrans, trans, all) {
- ast_cli(a->fd, FORMAT, ast_inet_ntoa(trans->addr.sin_addr),
- ntohs(trans->addr.sin_port), trans->strans, trans->dtrans, trans->oseqno, trans->iseqno, trans->aseqno);
+ ast_cli(a->fd, FORMAT, ast_sockaddr_stringify_host(&trans->addr),
+ ast_sockaddr_port(&trans->addr), trans->strans, trans->dtrans,
+ trans->oseqno, trans->iseqno, trans->aseqno);
}
AST_LIST_UNLOCK(&peers);
return CLI_SUCCESS;
@@ -3094,7 +3119,8 @@
int tid;
/* Don't allow creation of transactions to non-registered peers */
- if (p && !p->addr.sin_addr.s_addr)
+
+ if (p && ast_sockaddr_isnull(&p->addr))
return NULL;
tid = get_trans_id();
if (tid < 1)
@@ -3124,11 +3150,10 @@
int res;
if (dundidebug)
dundi_showframe(pack->h, 0, &pack->parent->addr, pack->datalen - sizeof(struct dundi_hdr));
- res = sendto(netsocket, pack->data, pack->datalen, 0, (struct sockaddr *)&pack->parent->addr, sizeof(pack->parent->addr));
+ res = sendto(netsocket, pack->data, pack->datalen, 0, (struct sockaddr *)&pack->parent->addr, pack->parent->addr.len);
if (res < 0) {
- ast_log(LOG_WARNING, "Failed to transmit to '%s:%d': %s\n",
- ast_inet_ntoa(pack->parent->addr.sin_addr),
- ntohs(pack->parent->addr.sin_port), strerror(errno));
+ ast_log(LOG_WARNING, "Failed to transmit to '%s': %s\n",
+ ast_sockaddr_stringify(&pack->parent->addr), strerror(errno));
}
if (res > 0)
res = 0;
@@ -3235,9 +3260,8 @@
if (pack->retrans < 1) {
pack->retransid = -1;
if (!ast_test_flag(pack->parent, FLAG_ISQUAL))
- ast_log(LOG_NOTICE, "Max retries exceeded to host '%s:%d' msg %d on call %d\n",
- ast_inet_ntoa(pack->parent->addr.sin_addr),
- ntohs(pack->parent->addr.sin_port), pack->h->oseqno, ntohs(pack->h->strans));
+ ast_log(LOG_NOTICE, "Max retries exceeded to host '%s' msg %d on call %d\n",
+ ast_sockaddr_stringify(&pack->parent->addr), pack->h->oseqno, ntohs(pack->h->strans));
destroy_trans(pack->parent, 1);
res = 0;
} else {
@@ -3592,7 +3616,7 @@
char eid_str2[20];
/* Ignore if not registered */
- if (!p->addr.sin_addr.s_addr)
+ if (ast_sockaddr_isnull(&p->addr))
return 0;
if (p->maxms && ((p->lastms < 0) || (p->lastms >= p->maxms)))
return 0;
@@ -4532,9 +4556,18 @@
c++;
if (sscanf(c, "%5d:%30d", &port, &expire) == 2) {
/* Got it! */
- inet_aton(data, &peer->addr.sin_addr);
- peer->addr.sin_family = AF_INET;
- peer->addr.sin_port = htons(port);
+ struct ast_sockaddr *addrs;
+ int cnt;
+ cnt = ast_sockaddr_resolve(&addrs,data,PARSE_PORT_FORBID,AF_UNSPEC);
+ for ( int i=0; i < cnt; i++)
+ {
+ if ( i ==0 ) {
+ memcpy(&peer->addr,&addrs[i],sizeof(struct ast_sockaddr));
+ peer->addr.ss.ss_family = get_ai_family(data);
+ }
+ ast_free(&addrs[i]);
+ }
+ ast_sockaddr_set_port(&peer->addr,port);
peer->registerexpire = ast_sched_add(sched, (expire + 10) * 1000, do_register_expire, peer);
}
}
@@ -4542,11 +4575,9 @@
}
-static void build_peer(dundi_eid *eid, struct ast_variable *v, int *globalpcmode)
+static void build_peer(dundi_eid *eid, struct ast_variable *v, int *globalpcmode, sa_family_t family)
{
struct dundi_peer *peer;
- struct ast_hostent he;
- struct hostent *hp;
dundi_eid testeid;
int needregister=0;
char eid_str[20];
@@ -4566,8 +4597,8 @@
peer->registerid = -1;
peer->registerexpire = -1;
peer->qualifyid = -1;
- peer->addr.sin_family = AF_INET;
- peer->addr.sin_port = htons(DUNDI_PORT);
+ peer->addr.ss.ss_family = family;
+ ast_sockaddr_set_port(&peer->addr,DUNDI_PORT);
populate_addr(peer, eid);
AST_LIST_INSERT_HEAD(&peers, peer, list);
}
@@ -4583,20 +4614,28 @@
} else if (!strcasecmp(v->name, "outkey")) {
ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey));
} else if (!strcasecmp(v->name, "port")) {
- peer->addr.sin_port = htons(atoi(v->value));
+ ast_sockaddr_set_port(&peer->addr,atoi(v->value));
} else if (!strcasecmp(v->name, "host")) {
if (!strcasecmp(v->value, "dynamic")) {
peer->dynamic = 1;
} else {
- hp = ast_gethostbyname(v->value, &he);
- if (hp) {
- memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
- peer->dynamic = 0;
+ int cnt;
+ struct ast_sockaddr *addrs;
+ cnt = ast_sockaddr_resolve(&addrs,v->value,PARSE_PORT_FORBID,family);
+ if ( cnt > 0 ) {
+ for ( int i=0; i < cnt; i++) {
+ if ( i ==0 ) {
+ memcpy(&peer->addr,&addrs[i],sizeof(struct ast_sockaddr));
+ peer->addr.ss.ss_family = get_ai_family(v->value);
+ peer->dynamic = 0;
+ }
+ ast_free(&addrs[i]);
+ }
} else {
ast_log(LOG_WARNING, "Unable to find host '%s' at line %d\n", v->value, v->lineno);
peer->dead = 1;
}
- }
+ }
} else if (!strcasecmp(v->name, "ustothem")) {
if (!ast_str_to_eid(&testeid, v->value))
peer->us_eid = testeid;
@@ -4662,6 +4701,11 @@
}
}
}
+
+ if ( ast_sockaddr_port(&peer->addr) == 0 ){
+ ast_sockaddr_set_port(&peer->addr,DUNDI_PORT);
+ }
+
(*globalpcmode) |= peer->pcmodel;
if (!peer->model && !peer->pcmodel) {
ast_log(LOG_WARNING, "Peer '%s' lacks a model or pcmodel, discarding!\n",
@@ -4810,18 +4854,16 @@
.matchmore = dundi_matchmore,
};
-static int set_config(char *config_file, struct sockaddr_in* sin, int reload)
+
+static int set_config(char *config_file, struct ast_sockaddr* sin, int reload)
{
struct ast_config *cfg;
struct ast_variable *v;
char *cat;
int x;
struct ast_flags config_flags = { 0 };
- char hn[MAXHOSTNAMELEN] = "";
- struct ast_hostent he;
- struct hostent *hp;
- struct sockaddr_in sin2;
static int last_port = 0;
+ int port=0;
int globalpcmodel = 0;
dundi_eid testeid;
@@ -4830,25 +4872,14 @@
return -1;
}
+ sin->ss.ss_family = AF_INET; /*set default protocol as IPV4 */
+
dundi_ttl = DUNDI_DEFAULT_TTL;
dundi_cache_time = DUNDI_DEFAULT_CACHE_TIME;
any_peer = NULL;
- ipaddr[0] = '\0';
- if (!gethostname(hn, sizeof(hn)-1)) {
- hp = ast_gethostbyname(hn, &he);
- if (hp) {
- memcpy(&sin2.sin_addr, hp->h_addr, sizeof(sin2.sin_addr));
- ast_copy_string(ipaddr, ast_inet_ntoa(sin2.sin_addr), sizeof(ipaddr));
- } else
- ast_log(LOG_WARNING, "Unable to look up host '%s'\n", hn);
- } else
- ast_log(LOG_WARNING, "Unable to get host name!\n");
AST_LIST_LOCK(&peers);
- if (ast_eid_is_empty(&ast_eid_default)) {
- ast_log(LOG_WARNING, "Entity ID is not set.\n");
- }
memcpy(&global_eid, &ast_eid_default, sizeof(global_eid));
global_storehistory = 0;
@@ -4856,19 +4887,28 @@
v = ast_variable_browse(cfg, "general");
while(v) {
if (!strcasecmp(v->name, "port")){
- sin->sin_port = htons(atoi(v->value));
- if(last_port==0){
- last_port=sin->sin_port;
- } else if(sin->sin_port != last_port)
- ast_log(LOG_WARNING, "change to port ignored until next asterisk re-start\n");
+ port = atoi(v->value);
} else if (!strcasecmp(v->name, "bindaddr")) {
- struct hostent *hep;
- struct ast_hostent hent;
- hep = ast_gethostbyname(v->value, &hent);
- if (hep) {
- memcpy(&sin->sin_addr, hep->h_addr, sizeof(sin->sin_addr));
- } else
- ast_log(LOG_WARNING, "Invalid host/IP '%s'\n", v->value);
+ if( get_ai_family(v->value)== AF_INET6) {
+ struct in6_addr *ip6;
+ ip6 = &((struct sockaddr_in6*)&sin->ss)->sin6_addr;
+ if ( inet_pton(AF_INET6,v->value, ip6)< 0 ) {
+ ast_log(LOG_WARNING, "Invalid host/IP '%s'\n", v->value);
+ }
+ sin->ss.ss_family = AF_INET6;
+ sin->len = sizeof(struct sockaddr_in6);
+ } else {
+ struct ast_hostent hent;
+ struct hostent *hep;
+ struct in_addr *ip4;
+ hep = ast_gethostbyname(v->value, &hent);
+ if (hep) {
+ ip4 = &((struct sockaddr_in*)&sin->ss)->sin_addr;
+ memcpy(ip4, hep->h_addr, sizeof(*ip4));
+ sin->len = sizeof(struct sockaddr_in);
+ } else
+ 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")) {
@@ -4923,6 +4963,17 @@
}
v = v->next;
}
+
+ if ( port == 0) {
+ ast_sockaddr_set_port(sin,DUNDI_PORT);
+ last_port = DUNDI_PORT;
+ } else {
+ if ( port != last_port) {
+ ast_sockaddr_set_port(sin,port);
+ last_port = port;
+ }
+ }
+
AST_LIST_UNLOCK(&peers);
mark_mappings();
v = ast_variable_browse(cfg, "mappings");
@@ -4937,9 +4988,9 @@
if (strcasecmp(cat, "general") && strcasecmp(cat, "mappings")) {
/* Entries */
if (!ast_str_to_eid(&testeid, cat))
- build_peer(&testeid, ast_variable_browse(cfg, cat), &globalpcmodel);
+ build_peer(&testeid, ast_variable_browse(cfg, cat), &globalpcmodel,sin->ss.ss_family);
else if (!strcasecmp(cat, "*")) {
- build_peer(&empty_eid, ast_variable_browse(cfg, cat), &globalpcmodel);
+ build_peer(&empty_eid, ast_variable_browse(cfg, cat), &globalpcmodel,sin->ss.ss_family);
any_peer = find_peer(NULL);
} else
ast_log(LOG_NOTICE, "Ignoring invalid EID entry '%s'\n", cat);
@@ -4993,7 +5044,7 @@
static int reload(void)
{
- struct sockaddr_in sin;
+ struct ast_sockaddr sin;
if (set_config("dundi.conf", &sin, 1))
return AST_MODULE_LOAD_FAILURE;
@@ -5003,44 +5054,48 @@
static int load_module(void)
{
- struct sockaddr_in sin;
+ struct ast_sockaddr sin;
dundi_set_output(dundi_debug_output);
dundi_set_error(dundi_error_output);
-
- sin.sin_family = AF_INET;
- sin.sin_port = htons(DUNDI_PORT);
- sin.sin_addr.s_addr = INADDR_ANY;
/* Make a UDP socket */
io = io_context_create();
sched = ast_sched_context_create();
- if (!io || !sched) {
- goto declined;
- }
+ if (!io || !sched)
+ return AST_MODULE_LOAD_DECLINE;
- if (set_config("dundi.conf", &sin, 0)) {
- goto declined;
- }
+ memset(&sin,0,sizeof(struct ast_sockaddr));
- netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+
+ if (set_config("dundi.conf", &sin, 0))
+ return AST_MODULE_LOAD_DECLINE;
+
+ if (sin.ss.ss_family == AF_INET6) {
+ 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;
+ return AST_MODULE_LOAD_DECLINE;
}
- if (bind(netsocket, (struct sockaddr *) &sin, sizeof(sin))) {
- ast_log(LOG_ERROR, "Unable to bind to %s port %d: %s\n",
- ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 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));
+ return AST_MODULE_LOAD_DECLINE;
}
ast_set_qos(netsocket, tos, 0, "DUNDi");
if (start_network_thread()) {
ast_log(LOG_ERROR, "Unable to start network thread\n");
- goto declined;
+ close(netsocket);
+ return AST_MODULE_LOAD_DECLINE;
}
ast_cli_register_multiple(cli_dundi, ARRAY_LEN(cli_dundi));
@@ -5050,13 +5105,9 @@
ast_custom_function_register(&dundi_query_function);
ast_custom_function_register(&dundi_result_function);
- ast_verb(2, "DUNDi Ready and Listening on %s port %d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
+ ast_verb(2, "DUNDi Ready and Listening on %s\n", ast_sockaddr_stringify(&sin));
return AST_MODULE_LOAD_SUCCESS;
-
-declined:
- unload_module();
- return AST_MODULE_LOAD_DECLINE;
}
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Distributed Universal Number Discovery (DUNDi)",
--
To view, visit https://gerrit.asterisk.org/9175
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia9e8dc3d153de7a291dbda4bd87fc827dd2bb846
Gerrit-Change-Number: 9175
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/20180611/6bf4e590/attachment-0001.html>
More information about the asterisk-code-review
mailing list