[asterisk-commits] elguero: trunk r400568 - in /trunk: ./ channels/ channels/iax2/ channels/iax2...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Oct 4 16:42:02 CDT 2013
Author: elguero
Date: Fri Oct 4 16:41:58 2013
New Revision: 400568
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=400568
Log:
Add IPv6 Support To chan_iax2
This patch adds IPv6 support to chan_iax2. Yay!
(closes issue ASTERISK-22025)
Patches:
iax2-ipv6-v5-reviewboard.diff by Michael L. Young (license 5026)
Review: https://reviewboard.asterisk.org/r/2660/
........
Merged revisions 400567 from http://svn.asterisk.org/svn/asterisk/branches/12
Modified:
trunk/ (props changed)
trunk/CHANGES
trunk/channels/chan_iax2.c
trunk/channels/iax2/include/parser.h
trunk/channels/iax2/parser.c
trunk/include/asterisk/netsock2.h
trunk/main/acl.c
trunk/main/netsock.c
trunk/main/netsock2.c
Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-12-merged' - no diff available.
Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=400568&r1=400567&r2=400568
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Fri Oct 4 16:41:58 2013
@@ -770,7 +770,6 @@
Stasis can be configured in stasis.conf. Note that these parameters operate
at a very low level in Asterisk, and generally will not require changes.
-
Channel Drivers
------------------
* When a channel driver is configured to enable jiterbuffers, they are now
@@ -814,6 +813,11 @@
* Added the CLI command 'dahdi create channels'. A range of channels can be
specified to be created, or the keyword 'new' can be used to add channels
not yet created.
+
+chan_iax2
+------------------
+ * IPv6 support has been added. We are now able to bind to and
+ communicate using IPv6 addresses.
chan_local
------------------
Modified: trunk/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_iax2.c?view=diff&rev=400568&r1=400567&r2=400568
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Fri Oct 4 16:41:58 2013
@@ -110,7 +110,6 @@
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
#include "asterisk/data.h"
-#include "asterisk/netsock2.h"
#include "asterisk/security_events.h"
#include "asterisk/stasis_endpoints.h"
#include "asterisk/bridge.h"
@@ -538,12 +537,12 @@
struct ast_sockaddr addr;
int formats;
int sockfd; /*!< Socket to use for transmission */
- struct in_addr mask;
+ struct ast_sockaddr mask;
int adsi;
uint64_t flags;
/* Dynamic Registration fields */
- struct sockaddr_in defaddr; /*!< Default address if there is one */
+ struct ast_sockaddr defaddr; /*!< Default address if there is one */
int authmethods; /*!< Authentication methods (IAX_AUTH_*) */
int encmethods; /*!< Encryption methods (IAX_ENCRYPT_*) */
@@ -576,7 +575,7 @@
struct iax2_trunk_peer {
ast_mutex_t lock;
int sockfd;
- struct sockaddr_in addr;
+ struct ast_sockaddr addr;
struct timeval txtrunktime; /*!< Transmit trunktime */
struct timeval rxtrunktime; /*!< Receive trunktime */
struct timeval lasttxtime; /*!< Last transmitted trunktime */
@@ -627,7 +626,7 @@
enum iax_reg_state regstate;
int messages; /*!< Message count, low 8 bits = new, high 8 bits = old */
int callno; /*!< Associated call number if applicable */
- struct sockaddr_in us; /*!< Who the server thinks we are */
+ struct ast_sockaddr us; /*!< Who the server thinks we are */
struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
AST_LIST_ENTRY(iax2_registry) entry;
};
@@ -707,7 +706,7 @@
/*! Max time for initial response */
int maxtime;
/*! Peer Address */
- struct sockaddr_in addr;
+ struct ast_sockaddr addr;
/*! Actual used codec preferences */
struct ast_codec_pref prefs;
/*! Requested codec preferences */
@@ -823,7 +822,7 @@
/*! Transfer identifier */
int transferid;
/*! Who we are IAX transferring to */
- struct sockaddr_in transfer;
+ struct ast_sockaddr transfer;
/*! What's the new call number for the transfer */
unsigned short transfercallno;
/*! Transfer encrypt AES-128 Key */
@@ -955,7 +954,7 @@
* consumed by a single ip address */
struct peercnt {
/*! ip address consuming call numbers */
- unsigned long addr;
+ struct ast_sockaddr addr;
/*! Number of call numbers currently used by this ip address */
uint16_t cur;
/*! Max call numbers allowed for this ip address */
@@ -1009,8 +1008,8 @@
static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
static void reg_source_db(struct iax2_peer *p);
-static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
-static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
+static struct iax2_peer *realtime_peer(const char *peername, struct ast_sockaddr *addr);
+static struct iax2_user *realtime_user(const char *username, struct ast_sockaddr *addr);
static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags);
@@ -1048,7 +1047,7 @@
int actions;
pthread_t threadid;
int threadnum;
- struct sockaddr_in iosin;
+ struct ast_sockaddr ioaddr;
unsigned char readbuf[4096];
unsigned char *buf;
ssize_t buf_len;
@@ -1065,7 +1064,7 @@
frames for that callno to other threads */
struct {
unsigned short callno;
- struct sockaddr_in sin;
+ struct ast_sockaddr addr;
unsigned char type;
unsigned char csub;
} ffinfo;
@@ -1159,20 +1158,21 @@
#define TRUNK_CALL_START (IAX_MAX_CALLS / 2)
/* Debug routines... */
-static struct sockaddr_in debugaddr;
-
-static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
+static struct ast_sockaddr debugaddr;
+
+static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct ast_sockaddr *addr, int datalen)
{
if (iaxdebug ||
- (sin && debugaddr.sin_addr.s_addr &&
- (!ntohs(debugaddr.sin_port) ||
- debugaddr.sin_port == sin->sin_port) &&
- debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
+ (addr && !ast_sockaddr_isnull(&debugaddr) &&
+ (!ast_sockaddr_port(&debugaddr) ||
+ ast_sockaddr_port(&debugaddr) == ast_sockaddr_port(addr)) &&
+ !ast_sockaddr_cmp_addr(&debugaddr, addr))) {
+
if (iaxdebug) {
- iax_showframe(f, fhi, rx, sin, datalen);
+ iax_showframe(f, fhi, rx, addr, datalen);
} else {
iaxdebug = 1;
- iax_showframe(f, fhi, rx, sin, datalen);
+ iax_showframe(f, fhi, rx, addr, datalen);
iaxdebug = 0;
}
}
@@ -1236,7 +1236,7 @@
static int iax2_hangup(struct ast_channel *c);
static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
-static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force);
+static int iax2_provision(struct ast_sockaddr *end, int sockfd, const char *dest, const char *template, int force);
static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
@@ -1270,7 +1270,7 @@
static void build_rand_pad(unsigned char *buf, ssize_t len);
static int get_unused_callno(enum callno_type type, int validated, callno_entry *entry);
static int replace_callno(const void *obj);
-static void sched_delay_remove(struct sockaddr_in *sin, callno_entry entry);
+static void sched_delay_remove(struct ast_sockaddr *addr, callno_entry entry);
static void network_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message);
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message);
@@ -1853,9 +1853,9 @@
peer = ao2_find(peers, name, OBJ_KEY);
/* Now go for realtime if applicable */
- if(!peer && realtime)
+ if (!peer && realtime) {
peer = realtime_peer(name, NULL);
-
+ }
return peer;
}
@@ -1887,7 +1887,7 @@
return NULL;
}
-static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
+static int iax2_getpeername(struct ast_sockaddr addr, char *host, int len)
{
struct iax2_peer *peer = NULL;
int res = 0;
@@ -1895,12 +1895,8 @@
i = ao2_iterator_init(peers, 0);
while ((peer = ao2_iterator_next(&i))) {
- struct sockaddr_in peer_addr;
-
- ast_sockaddr_to_sin(&peer->addr, &peer_addr);
-
- if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
- (peer_addr.sin_port == sin.sin_port)) {
+
+ if (!ast_sockaddr_cmp(&peer->addr, &addr)) {
ast_copy_string(host, peer->name, len);
peer_unref(peer);
res = 1;
@@ -1911,7 +1907,7 @@
ao2_iterator_destroy(&i);
if (!peer) {
- peer = realtime_peer(NULL, &sin);
+ peer = realtime_peer(NULL, &addr);
if (peer) {
ast_copy_string(host, peer->name, len);
peer_unref(peer);
@@ -2068,7 +2064,7 @@
}
-static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
+static struct chan_iax2_pvt *new_iax(struct ast_sockaddr *addr, const char *host)
{
struct chan_iax2_pvt *tmp;
jb_conf jbconf;
@@ -2139,10 +2135,9 @@
NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
};
-static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
-{
- if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
- (cur->addr.sin_port == sin->sin_port)) {
+static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
+{
+ if (!ast_sockaddr_cmp(&cur->addr, addr)) {
/* This is the main host */
if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
(check_dcallno ? dcallno == cur->callno : 1) ) {
@@ -2150,8 +2145,7 @@
return 1;
}
}
- if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
- (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
+ if (!ast_sockaddr_cmp(&cur->transfer, addr) && cur->transferring) {
/* We're transferring */
if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
return 1;
@@ -2274,9 +2268,7 @@
static int addr_range_hash_cb(const void *obj, const int flags)
{
const struct addr_range *lim = obj;
- struct sockaddr_in sin;
- ast_sockaddr_to_sin(&lim->ha.addr, &sin);
- return abs((int) sin.sin_addr.s_addr);
+ return abs(ast_sockaddr_hash(&lim->ha.addr));
}
static int addr_range_cmp_cb(void *obj, void *arg, int flags)
@@ -2290,26 +2282,28 @@
static int peercnt_hash_cb(const void *obj, const int flags)
{
const struct peercnt *peercnt = obj;
- return abs((int) peercnt->addr);
+
+ if (ast_sockaddr_isnull(&peercnt->addr)) {
+ return 0;
+ }
+ return ast_sockaddr_hash(&peercnt->addr);
}
static int peercnt_cmp_cb(void *obj, void *arg, int flags)
{
struct peercnt *peercnt1 = obj, *peercnt2 = arg;
- return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
+ return !ast_sockaddr_cmp_addr(&peercnt1->addr, &peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
}
static int addr_range_match_address_cb(void *obj, void *arg, int flags)
{
struct addr_range *addr_range = obj;
- struct sockaddr_in *sin = arg;
- struct sockaddr_in ha_netmask_sin;
- struct sockaddr_in ha_addr_sin;
-
- ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
- ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
-
- if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
+ struct ast_sockaddr *addr = arg;
+ struct ast_sockaddr tmp_addr;
+
+ ast_sockaddr_apply_netmask(addr, &addr_range->ha.netmask, &tmp_addr);
+
+ if (!ast_sockaddr_cmp_addr(&tmp_addr, &addr_range->ha.addr)) {
return CMP_MATCH | CMP_STOP;
}
return 0;
@@ -2318,9 +2312,9 @@
/*!
* \internal
*
- * \brief compares sin to calltoken_ignores table to determine if validation is required.
+ * \brief compares addr to calltoken_ignores table to determine if validation is required.
*/
-static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
+static int calltoken_required(struct ast_sockaddr *addr, const char *name, int subclass)
{
struct addr_range *addr_range;
struct iax2_peer *peer = NULL;
@@ -2337,7 +2331,7 @@
*/
/* ----- Case 1 ----- */
- if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
+ if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, addr))) {
ao2_ref(addr_range, -1);
optional = 1;
}
@@ -2345,11 +2339,11 @@
/* ----- Case 2 ----- */
if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
calltoken_required = user->calltoken_required;
- } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
+ } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, addr))) {
calltoken_required = user->calltoken_required;
} else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
calltoken_required = peer->calltoken_required;
- } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
+ } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, addr))) {
calltoken_required = peer->calltoken_required;
}
@@ -2360,7 +2354,7 @@
user_unref(user);
}
- ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required);
+ ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %d \n", ast_sockaddr_stringify_addr(addr), name, optional, calltoken_required);
if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
(optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
res = 0;
@@ -2383,18 +2377,17 @@
{
uint16_t limit = global_maxcallno;
struct addr_range *addr_range;
- struct sockaddr_in sin = {
- .sin_addr.s_addr = peercnt->addr,
- };
-
+ struct ast_sockaddr addr;
+
+ ast_sockaddr_copy(&addr, &peercnt->addr);
if (peercnt->reg && peercnt->limit) {
return; /* this peercnt has a custom limit set by a registration */
}
- if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
+ if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &addr))) {
limit = addr_range->limit;
- ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
+ ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_sockaddr_stringify(&addr));
ao2_ref(addr_range, -1);
}
@@ -2434,14 +2427,9 @@
{
/* this function turns off and on custom callno limits set by peer registration */
struct peercnt *peercnt;
- struct peercnt tmp = {
- .addr = 0,
- };
- struct sockaddr_in sin;
-
- ast_sockaddr_to_sin(sockaddr, &sin);
-
- tmp.addr = sin.sin_addr.s_addr;
+ struct peercnt tmp;
+
+ ast_sockaddr_copy(&tmp.addr, sockaddr);
if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
peercnt->reg = reg;
@@ -2450,7 +2438,7 @@
} else {
set_peercnt_limit(peercnt);
}
- ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
+ ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_sockaddr_stringify_addr(sockaddr), peercnt->limit, peercnt->reg);
ao2_ref(peercnt, -1); /* decrement ref from find */
}
}
@@ -2463,14 +2451,13 @@
* the current count is incremented. If not found a new peercnt is allocated
* and linked into the peercnts table with a call number count of 1.
*/
-static int peercnt_add(struct sockaddr_in *sin)
+static int peercnt_add(struct ast_sockaddr *addr)
{
struct peercnt *peercnt;
- unsigned long addr = sin->sin_addr.s_addr;
int res = 0;
- struct peercnt tmp = {
- .addr = addr,
- };
+ struct peercnt tmp;
+
+ ast_sockaddr_copy(&tmp.addr, addr);
/* Reasoning for peercnts container lock: Two identical ip addresses
* could be added by different threads at the "same time". Without the container
@@ -2484,7 +2471,7 @@
} else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
ao2_lock(peercnt);
/* create and set defaults */
- peercnt->addr = addr;
+ ast_sockaddr_copy(&peercnt->addr, addr);
set_peercnt_limit(peercnt);
/* guarantees it does not go away after unlocking table
* ao2_find automatically adds this */
@@ -2497,9 +2484,9 @@
/* check to see if the address has hit its callno limit. If not increment cur. */
if (peercnt->limit > peercnt->cur) {
peercnt->cur++;
- ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
+ ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_sockaddr_stringify_addr(addr));
} else { /* max num call numbers for this peer has been reached! */
- ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
+ ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_sockaddr_stringify_addr(addr));
res = -1;
}
@@ -2517,9 +2504,9 @@
*/
static void peercnt_remove(struct peercnt *peercnt)
{
- struct sockaddr_in sin = {
- .sin_addr.s_addr = peercnt->addr,
- };
+ struct ast_sockaddr addr;
+
+ ast_sockaddr_copy(&addr, &peercnt->addr);
/*
* Container locked here since peercnt may be unlinked from
@@ -2529,7 +2516,7 @@
*/
ao2_lock(peercnts);
peercnt->cur--;
- ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
+ ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_sockaddr_stringify_addr(&addr));
/* if this was the last connection from the peer remove it from table */
if (peercnt->cur == 0) {
ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
@@ -2555,12 +2542,12 @@
* \internal
* \brief decrements peercnts connection count, finds by addr
*/
-static int peercnt_remove_by_addr(struct sockaddr_in *sin)
+static int peercnt_remove_by_addr(struct ast_sockaddr *addr)
{
struct peercnt *peercnt;
- struct peercnt tmp = {
- .addr = sin->sin_addr.s_addr,
- };
+ struct peercnt tmp;
+
+ ast_sockaddr_copy(&tmp.addr, addr);
if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
peercnt_remove(peercnt);
@@ -2673,7 +2660,7 @@
{
struct ao2_iterator i;
struct peercnt *peercnt;
- struct sockaddr_in sin;
+ struct ast_sockaddr addr;
int found = 0;
switch (cmd) {
@@ -2690,22 +2677,23 @@
return CLI_SHOWUSAGE;
if (a->argc == 4) {
- ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
+ ast_cli(a->fd, "%-45s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
}
i = ao2_iterator_init(peercnts, 0);
while ((peercnt = ao2_iterator_next(&i))) {
- sin.sin_addr.s_addr = peercnt->addr;
+ ast_sockaddr_copy(&addr, &peercnt->addr);
+
if (a->argc == 5) {
- if (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr))) {
- ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
- ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
+ if (!strcasecmp(a->argv[4], ast_sockaddr_stringify(&addr))) {
+ ast_cli(a->fd, "%-45s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
+ ast_cli(a->fd, "%-45s %-12d %-12d\n", ast_sockaddr_stringify(&addr), peercnt->cur, peercnt->limit);
ao2_ref(peercnt, -1);
found = 1;
break;
}
} else {
- ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
+ ast_cli(a->fd, "%-45s %-12d %-12d\n", ast_sockaddr_stringify(&addr), peercnt->cur, peercnt->limit);
}
ao2_ref(peercnt, -1);
}
@@ -2886,17 +2874,17 @@
* avaliable again, and the address from the previous connection must be decremented
* from the peercnts table. This function schedules these operations to take place.
*/
-static void sched_delay_remove(struct sockaddr_in *sin, callno_entry entry)
+static void sched_delay_remove(struct ast_sockaddr *addr, callno_entry entry)
{
int i;
struct peercnt *peercnt;
- struct peercnt tmp = {
- .addr = sin->sin_addr.s_addr,
- };
+ struct peercnt tmp;
+
+ ast_sockaddr_copy(&tmp.addr, addr);
if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
/* refcount is incremented with ao2_find. keep that ref for the scheduler */
- ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
+ ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_sockaddr_stringify_addr(addr), MIN_REUSE_TIME);
i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
if (i == -1) {
ao2_ref(peercnt, -1);
@@ -2940,7 +2928,7 @@
/*
* \note Calling this function while holding another pvt lock can cause a deadlock.
*/
-static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
+static int __find_callno(unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int return_locked, int check_dcallno)
{
int res = 0;
int x;
@@ -2960,7 +2948,7 @@
.frames_received = check_dcallno,
};
- memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
+ ast_sockaddr_copy(&tmp_pvt.addr, addr);
/* this works for finding normal call numbers not involving transfering */
if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
if (return_locked) {
@@ -2973,7 +2961,7 @@
}
/* this searches for transfer call numbers that might not get caught otherwise */
memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
- memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
+ ast_sockaddr_copy(&tmp_pvt.transfer, addr);
if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
if (return_locked) {
ast_mutex_lock(&iaxsl[pvt->callno]);
@@ -2989,7 +2977,7 @@
if (dcallno) {
ast_mutex_lock(&iaxsl[dcallno]);
}
- if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
+ if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(addr, callno, dcallno, iaxs[dcallno], check_dcallno)) {
iaxs[dcallno]->peercallno = callno;
res = dcallno;
store_by_peercallno(iaxs[dcallno]);
@@ -3004,16 +2992,17 @@
}
if (!res && (new >= NEW_ALLOW)) {
callno_entry entry;
+
/* It may seem odd that we look through the peer list for a name for
* this *incoming* call. Well, it is weird. However, users don't
* have an IP address/port number that we can match against. So,
* this is just checking for a peer that has that IP/port and
* assuming that we have a user of the same name. This isn't always
* correct, but it will be changed if needed after authentication. */
- if (!iax2_getpeername(*sin, host, sizeof(host)))
- snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
-
- if (peercnt_add(sin)) {
+ if (!iax2_getpeername(*addr, host, sizeof(host)))
+ snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(addr));
+
+ if (peercnt_add(addr)) {
/* This address has hit its callnumber limit. When the limit
* is reached, the connection is not added to the peercnts table.*/
return 0;
@@ -3022,22 +3011,20 @@
if (get_unused_callno(CALLNO_TYPE_NORMAL, validated, &entry)) {
/* since we ran out of space, remove the peercnt
* entry we added earlier */
- peercnt_remove_by_addr(sin);
+ peercnt_remove_by_addr(addr);
ast_log(LOG_WARNING, "No more space\n");
return 0;
}
x = CALLNO_ENTRY_GET_CALLNO(entry);
ast_mutex_lock(&iaxsl[x]);
- iaxs[x] = new_iax(sin, host);
+ iaxs[x] = new_iax(addr, host);
if (iaxs[x]) {
if (iaxdebug)
ast_debug(1, "Creating new call structure %d\n", x);
iaxs[x]->callno_entry = entry;
iaxs[x]->sockfd = sockfd;
- iaxs[x]->addr.sin_port = sin->sin_port;
- iaxs[x]->addr.sin_family = sin->sin_family;
- iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
+ ast_sockaddr_copy(&iaxs[x]->addr, addr);
iaxs[x]->peercallno = callno;
iaxs[x]->callno = x;
iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
@@ -3067,13 +3054,13 @@
return res;
}
-static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
- return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
-}
-
-static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
-
- return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
+static int find_callno(unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int full_frame) {
+ return __find_callno(callno, dcallno, addr, new, sockfd, 0, full_frame);
+}
+
+static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int full_frame) {
+
+ return __find_callno(callno, dcallno, addr, new, sockfd, 1, full_frame);
}
/*!
@@ -3222,11 +3209,11 @@
return 0;
}
-static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
+static int transmit_trunk(struct iax_frame *f, struct ast_sockaddr *addr, int sockfd)
{
int res;
- res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
- sizeof(*sin));
+ res = ast_sendto(sockfd, f->data, f->datalen, 0, addr);
+
if (res < 0) {
ast_debug(1, "Received error: %s\n", strerror(errno));
handle_error();
@@ -3245,15 +3232,15 @@
return -1;
/* Called with iaxsl held */
- if (iaxdebug)
- ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
-
+ if (iaxdebug) {
+ ast_debug(3, "Sending %d on %d/%d to %s\n", f->ts, callno, iaxs[callno]->peercallno, ast_sockaddr_stringify(&iaxs[callno]->addr));
+ }
if (f->transfer) {
iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
- res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
+ res = ast_sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0, &iaxs[callno]->transfer);
} else {
iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
- res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
+ res = ast_sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0, &iaxs[callno]->addr);
}
if (res < 0) {
if (iaxdebug)
@@ -3406,7 +3393,7 @@
} else {
if (iaxs[callno]->owner) {
ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n",
- ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),
+ ast_sockaddr_stringify_addr(&iaxs[f->callno]->addr),
ast_channel_name(iaxs[f->callno]->owner),
f->af.frametype,
f->af.subclass.integer,
@@ -3677,9 +3664,13 @@
peer = find_peer(a->argv[3], load_realtime);
if (peer) {
- struct sockaddr_in peer_addr;
-
- ast_sockaddr_to_sin(&peer->addr, &peer_addr);
+ char *str_addr, *str_defaddr;
+ char *str_port, *str_defport;
+
+ str_addr = ast_strdupa(ast_sockaddr_stringify_addr(&peer->addr));
+ str_port = ast_strdupa(ast_sockaddr_stringify_port(&peer->addr));
+ str_defaddr = ast_strdupa(ast_sockaddr_stringify_addr(&peer->defaddr));
+ str_defport = ast_strdupa(ast_sockaddr_stringify_port(&peer->defaddr));
encmethods_to_str(peer->encmethods, &encmethods);
ast_cli(a->fd, "\n\n");
@@ -3697,8 +3688,8 @@
ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
ast_cli(a->fd, " Expire : %d\n", peer->expire);
ast_cli(a->fd, " ACL : %s\n", (ast_acl_list_is_empty(peer->acl) ? "No" : "Yes"));
- ast_cli(a->fd, " Addr->IP : %s Port %d\n", peer_addr.sin_addr.s_addr ? ast_inet_ntoa(peer_addr.sin_addr) : "(Unspecified)", ntohs(peer_addr.sin_port));
- ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
+ ast_cli(a->fd, " Addr->IP : %s Port %s\n", str_addr ? str_addr : "(Unspecified)", str_port);
+ ast_cli(a->fd, " Defaddr->IP : %s Port %s\n", str_defaddr, str_defport);
ast_cli(a->fd, " Username : %s\n", peer->username);
ast_cli(a->fd, " Codecs : ");
iax2_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
@@ -4241,22 +4232,25 @@
* \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
* so do not call this with a pvt lock held.
*/
-static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
+static struct iax2_peer *realtime_peer(const char *peername, struct ast_sockaddr *addr)
{
struct ast_variable *var = NULL;
struct ast_variable *tmp;
struct iax2_peer *peer=NULL;
time_t regseconds = 0, nowtime;
int dynamic=0;
+ char *str_addr, *str_port;
+
+ str_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
+ str_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
if (peername) {
var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
- if (!var && sin)
- var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
- } else if (sin) {
- char porta[25];
- sprintf(porta, "%d", ntohs(sin->sin_port));
- var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
+ if (!var && !ast_sockaddr_isnull(addr)) {
+ var = ast_load_realtime("iaxpeers", "name", peername, "host", str_addr, SENTINEL);
+ }
+ } else if (!ast_sockaddr_isnull(addr)) {
+ var = ast_load_realtime("iaxpeers", "ipaddr", str_addr, "port", str_port, SENTINEL);
if (var) {
/* We'll need the peer name in order to build the structure! */
for (tmp = var; tmp; tmp = tmp->next) {
@@ -4273,12 +4267,13 @@
* is because we only have the IP address and the host field might be
* set as a name (and the reverse PTR might not match).
*/
- if (var && sin) {
+ if (var && !ast_sockaddr_isnull(addr)) {
for (tmp = var; tmp; tmp = tmp->next) {
if (!strcasecmp(tmp->name, "host")) {
- struct ast_hostent ahp;
- struct hostent *hp;
- if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
+ struct ast_sockaddr *hostaddr;
+
+ if (!ast_sockaddr_resolve(&hostaddr, tmp->value, PARSE_PORT_FORBID, 0)
+ || ast_sockaddr_cmp_addr(hostaddr, addr)) {
/* No match */
ast_variables_destroy(var);
var = NULL;
@@ -4310,11 +4305,19 @@
} else if (!strcasecmp(tmp->name, "regseconds")) {
ast_get_time_t(tmp->value, ®seconds, 0, NULL);
} else if (!strcasecmp(tmp->name, "ipaddr")) {
- if (!ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE)) {
+ int setport = ast_sockaddr_port(&peer->addr);
+ if (ast_parse_arg(tmp->value, PARSE_ADDR | PARSE_PORT_FORBID, NULL)) {
ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name);
+ } else {
+ ast_sockaddr_parse(&peer->addr, tmp->value, 0);
}
+ ast_sockaddr_set_port(&peer->addr, setport);
} else if (!strcasecmp(tmp->name, "port")) {
- ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
+ int bindport;
+ if (ast_parse_arg(tmp->value, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
+ bindport = IAX_DEFAULT_PORTNO;
+ }
+ ast_sockaddr_set_port(&peer->addr, bindport);
} else if (!strcasecmp(tmp->name, "host")) {
if (!strcasecmp(tmp->value, "dynamic"))
dynamic = 1;
@@ -4322,9 +4325,6 @@
}
ast_variables_destroy(var);
-
- if (!peer)
- return NULL;
if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
@@ -4363,21 +4363,23 @@
return peer;
}
-static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
+static struct iax2_user *realtime_user(const char *username, struct ast_sockaddr *addr)
{
struct ast_variable *var;
struct ast_variable *tmp;
struct iax2_user *user=NULL;
+ char *str_addr, *str_port;
+
+ str_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
+ str_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
if (!var)
- var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
- if (!var && sin) {
- char porta[6];
- snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
- var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
+ var = ast_load_realtime("iaxusers", "name", username, "host", str_addr, SENTINEL);
+ if (!var && !ast_sockaddr_isnull(addr)) {
+ var = ast_load_realtime("iaxusers", "name", username, "ipaddr", str_addr, "port", str_port, SENTINEL);
if (!var)
- var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
+ var = ast_load_realtime("iaxusers", "ipaddr", str_addr, "port", str_port, SENTINEL);
}
if (!var) { /* Last ditch effort */
var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
@@ -4390,9 +4392,10 @@
if (var) {
for (tmp = var; tmp; tmp = tmp->next) {
if (!strcasecmp(tmp->name, "host")) {
- struct ast_hostent ahp;
- struct hostent *hp;
- if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
+ struct ast_sockaddr *hostaddr;
+
+ if (!ast_sockaddr_resolve(&hostaddr, tmp->value, PARSE_PORT_FORBID, 0)
+ || ast_sockaddr_cmp_addr(hostaddr, addr)) {
/* No match */
ast_variables_destroy(var);
var = NULL;
@@ -4436,10 +4439,10 @@
static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
{
- char port[10];
char regseconds[20];
const char *sysname = ast_config_AST_SYSTEM_NAME;
char *syslabel = NULL;
+ char *port;
if (ast_strlen_zero(sysname)) /* No system name, disable this */
sysname = NULL;
@@ -4447,9 +4450,10 @@
syslabel = "regserver";
snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
- snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
+ port = ast_strdupa(ast_sockaddr_stringify_port(sockaddr));
ast_update_realtime("iaxpeers", "name", peername,
- "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port,
+ "ipaddr", ast_sockaddr_isnull(sockaddr) ? "" : ast_sockaddr_stringify_addr(sockaddr),
+ "port", ast_sockaddr_isnull(sockaddr) ? "" : port,
"regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */
}
@@ -4474,31 +4478,30 @@
char mohsuggest[MAX_MUSICCLASS];
};
-static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
+static int create_addr(const char *peername, struct ast_channel *c, struct ast_sockaddr *addr, struct create_addr_info *cai)
{
struct iax2_peer *peer;
int res = -1;
struct ast_codec_pref ourprefs;
- struct sockaddr_in peer_addr;
ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
cai->sockfd = defaultsockfd;
cai->maxtime = 0;
- sin->sin_family = AF_INET;
if (!(peer = find_peer(peername, 1))) {
- struct ast_sockaddr sin_tmp;
+ struct ast_sockaddr peer_addr;
cai->found = 0;
- sin_tmp.ss.ss_family = AF_INET;
- if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
+ if (ast_get_ip_or_srv(&peer_addr, peername, srvlookup ? "_iax._udp" : NULL)) {
ast_log(LOG_WARNING, "No such host: %s\n", peername);
return -1;
}
- ast_sockaddr_to_sin(&sin_tmp, sin);
- if (sin->sin_port == 0) {
- sin->sin_port = htons(IAX_DEFAULT_PORTNO);
- }
+
+ if (!ast_sockaddr_port(&peer_addr)) {
+ ast_sockaddr_set_port(&peer_addr, IAX_DEFAULT_PORTNO);
+ }
+
+ ast_sockaddr_copy(addr, &peer_addr);
/* use global iax prefs for unknown peer/user */
/* But move the calling channel's native codec to the top of the preference list */
memcpy(&ourprefs, &prefs, sizeof(ourprefs));
@@ -4516,10 +4519,8 @@
cai->found = 1;
- ast_sockaddr_to_sin(&peer->addr, &peer_addr);
-
/* if the peer has no address (current or default), return failure */
- if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
+ if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) {
goto return_unref;
}
@@ -4570,12 +4571,10 @@
}
}
- if (peer_addr.sin_addr.s_addr) {
- sin->sin_addr = peer_addr.sin_addr;
- sin->sin_port = peer_addr.sin_port;
+ if (!ast_sockaddr_isnull(&peer->addr)) {
+ ast_sockaddr_copy(addr, &peer->addr);
} else {
- sin->sin_addr = peer->defaddr.sin_addr;
- sin->sin_port = peer->defaddr.sin_port;
+ ast_sockaddr_copy(addr, &peer->defaddr);
}
res = 0;
@@ -4635,7 +4634,7 @@
};
static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
- struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
+ struct ast_sockaddr *addr, int command, int ts, unsigned char seqno,
int sockfd, struct iax_ie_data *ied)
{
struct {
@@ -4657,9 +4656,9 @@
data.f.type = AST_FRAME_IAX;
data.f.csub = compress_subclass(command);
- iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr));
-
- return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
+ iax_outputframe(NULL, &data.f, 0, addr, size - sizeof(struct ast_iax2_full_hdr));
+
+ return ast_sendto(sockfd, &data, size, 0, addr);
}
static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
@@ -4795,9 +4794,9 @@
* to decide how this should be handled (reject or permit without calltoken)
*/
static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
- struct sockaddr_in *sin, int fd)
-{
-#define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */
+ struct ast_sockaddr *addr, int fd)
+{
+#define CALLTOKEN_HASH_FORMAT "%s%u%d" /* address + port + ts + randomcalldata */
#define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */
struct ast_str *buf = ast_str_alloca(256);
time_t t = time(NULL);
@@ -4812,12 +4811,12 @@
};
/* create the hash with their address data and our timestamp */
- ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
+ ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_sockaddr_stringify(addr), (unsigned int) t, randomcalltokendata);
ast_sha1_hash(hash, ast_str_buffer(buf));
ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
- send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
[... 2616 lines stripped ...]
More information about the asterisk-commits
mailing list