aboutsummaryrefslogtreecommitdiffstats
path: root/main/acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/acl.c')
-rw-r--r--main/acl.c101
1 files changed, 63 insertions, 38 deletions
diff --git a/main/acl.c b/main/acl.c
index caa1d56f0..082048a16 100644
--- a/main/acl.c
+++ b/main/acl.c
@@ -48,7 +48,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/srv.h"
#if (!defined(SOLARIS) && !defined(HAVE_GETIFADDRS))
-static int get_local_address(struct in_addr *ourip)
+static int get_local_address(struct ast_sockaddr *ourip)
{
return -1;
}
@@ -112,7 +112,7 @@ static void score_address(const struct sockaddr_in *sin, struct in_addr *best_ad
}
}
-static int get_local_address(struct in_addr *ourip)
+static int get_local_address(struct ast_sockaddr *ourip)
{
int s, res = -1;
#ifdef SOLARIS
@@ -207,7 +207,9 @@ static int get_local_address(struct in_addr *ourip)
#endif /* BSD_OR_LINUX */
if (res == 0 && ourip) {
- memcpy(ourip, &best_addr, sizeof(*ourip));
+ ast_sockaddr_setnull(ourip);
+ ourip->ss.ss_family = AF_INET;
+ ((struct sockaddr_in *)&ourip->ss)->sin_addr = best_addr;
}
return res;
}
@@ -372,27 +374,49 @@ int ast_apply_ha(struct ast_ha *ha, struct sockaddr_in *sin)
return res;
}
-int ast_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service)
+static int resolve_first(struct ast_sockaddr *addr, const char *name, int flag,
+ int family)
+{
+ struct ast_sockaddr *addrs;
+ int addrs_cnt;
+
+ addrs_cnt = ast_sockaddr_resolve(&addrs, name, flag, family);
+ if (addrs_cnt > 0) {
+ if (addrs_cnt > 1) {
+ ast_debug(1, "Multiple addresses. Using the first only\n");
+ }
+ ast_sockaddr_copy(addr, &addrs[0]);
+ ast_free(addrs);
+ } else {
+ ast_log(LOG_WARNING, "Unable to lookup '%s'\n", name);
+ return -1;
+ }
+
+ return 0;
+}
+
+int ast_get_ip_or_srv(struct ast_sockaddr *addr, const char *value, const char *service)
{
- struct hostent *hp;
- struct ast_hostent ahp;
char srv[256];
char host[256];
- int tportno = ntohs(sin->sin_port);
+ int srv_ret = 0;
+ int tportno;
+
if (service) {
snprintf(srv, sizeof(srv), "%s.%s", service, value);
- if (ast_get_srv(NULL, host, sizeof(host), &tportno, srv) > 0) {
- sin->sin_port = htons(tportno);
+ if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, srv)) > 0) {
value = host;
}
}
- if ((hp = ast_gethostbyname(value, &ahp))) {
- sin->sin_family = hp->h_addrtype;
- memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
- } else {
- ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
+
+ if (resolve_first(addr, value, PARSE_PORT_FORBID, addr->ss.ss_family) != 0) {
return -1;
}
+
+ if (srv_ret > 0) {
+ ast_sockaddr_set_port(addr, tportno);
+ }
+
return 0;
}
@@ -474,51 +498,53 @@ const char *ast_tos2str(unsigned int tos)
return "unknown";
}
-int ast_get_ip(struct sockaddr_in *sin, const char *value)
+int ast_get_ip(struct ast_sockaddr *addr, const char *value)
{
- return ast_get_ip_or_srv(sin, value, NULL);
+ return ast_get_ip_or_srv(addr, value, NULL);
}
-int ast_ouraddrfor(struct in_addr *them, struct in_addr *us)
+int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
{
+ int port;
int s;
- struct sockaddr_in sin;
- socklen_t slen;
- if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+ port = ast_sockaddr_port(us);
+
+ if ((s = socket(ast_sockaddr_is_ipv6(them) ? AF_INET6 : AF_INET,
+ SOCK_DGRAM, 0)) < 0) {
ast_log(LOG_ERROR, "Cannot create socket\n");
return -1;
}
- sin.sin_family = AF_INET;
- sin.sin_port = htons(5060);
- sin.sin_addr = *them;
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin))) {
+
+ if (ast_connect(s, them)) {
ast_log(LOG_WARNING, "Cannot connect\n");
close(s);
return -1;
}
- slen = sizeof(sin);
- if (getsockname(s, (struct sockaddr *)&sin, &slen)) {
+ if (ast_getsockname(s, us)) {
+
ast_log(LOG_WARNING, "Cannot get socket name\n");
close(s);
return -1;
}
close(s);
- ast_debug(3, "Found IP address for this socket\n");
- *us = sin.sin_addr;
+ ast_debug(3, "For destination '%s', our source address is '%s'.\n",
+ ast_sockaddr_stringify_addr(them),
+ ast_sockaddr_stringify_addr(us));
+
+ ast_sockaddr_set_port(us, port);
+
return 0;
}
-int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr)
+int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr)
{
char ourhost[MAXHOSTNAMELEN] = "";
- struct ast_hostent ahp;
- struct hostent *hp;
- struct in_addr saddr;
+ struct ast_sockaddr root;
/* just use the bind address if it is nonzero */
- if (ntohl(bindaddr.sin_addr.s_addr)) {
- memcpy(ourip, &bindaddr.sin_addr, sizeof(*ourip));
+ if (!ast_sockaddr_is_any(bindaddr)) {
+ ast_sockaddr_copy(ourip, bindaddr);
ast_debug(3, "Attached to given IP address\n");
return 0;
}
@@ -526,15 +552,14 @@ int ast_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr)
if (gethostname(ourhost, sizeof(ourhost) - 1)) {
ast_log(LOG_WARNING, "Unable to get hostname\n");
} else {
- if ((hp = ast_gethostbyname(ourhost, &ahp))) {
- memcpy(ourip, hp->h_addr, sizeof(*ourip));
- ast_debug(3, "Found one IP address based on local hostname %s.\n", ourhost);
+ if (resolve_first(ourip, ourhost, PARSE_PORT_FORBID, 0) == 0) {
return 0;
}
}
ast_debug(3, "Trying to check A.ROOT-SERVERS.NET and get our IP address for that connection\n");
/* A.ROOT-SERVERS.NET. */
- if (inet_aton("198.41.0.4", &saddr) && !ast_ouraddrfor(&saddr, ourip)) {
+ if (!resolve_first(&root, "A.ROOT-SERVERS.NET", PARSE_PORT_FORBID, 0) &&
+ !ast_ouraddrfor(&root, ourip)) {
return 0;
}
return get_local_address(ourip);