* Asterisk -- A telephony toolkit for Linux.
*
* Implementation of Inter-Asterisk eXchange
- *
+ *
* Copyright (C) 1999, Mark Spencer
*
* Mark Spencer <markster@linux-support.net>
* the GNU General Public License
*/
+#include <asterisk/lock.h>
#include <asterisk/frame.h>
#include <asterisk/channel.h>
#include <asterisk/channel_pvt.h>
#include <asterisk/md5.h>
#include <asterisk/cdr.h>
#include <asterisk/crypto.h>
+#include <asterisk/acl.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
static int expirey = AST_DEFAULT_REG_EXPIRE;
static int usecnt;
-static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t iaxs_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
+static pthread_mutex_t iaxs_lock = AST_MUTEX_INITIALIZER;
int (*regfunk)(char *username, int onoff) = NULL;
#define IAX_STATE_AUTHENTICATED (1 << 1)
#define IAX_STATE_TBD (1 << 2)
-#define IAX_SENSE_DENY 0
-#define IAX_SENSE_ALLOW 1
-
-struct iax_ha {
- /* Host access rule */
- struct in_addr netaddr;
- struct in_addr netmask;
- int sense;
- struct iax_ha *next;
-};
-
struct iax_context {
char context[AST_MAX_EXTENSION];
struct iax_context *next;
int amaflags;
int hascallerid;
char callerid[AST_MAX_EXTENSION];
- struct iax_ha *ha;
+ struct ast_ha *ha;
struct iax_context *contexts;
struct iax_user *next;
};
char username[80];
char secret[80];
char outkey[80]; /* What key we use to talk to this peer */
+ char context[AST_MAX_EXTENSION]; /* Default context (for transfer really) */
struct sockaddr_in addr;
int formats;
struct in_addr mask;
int expirey; /* How soon to expire */
int capability; /* Capability */
int delme; /* I need to be deleted */
- struct iax_ha *ha;
+ struct ast_ha *ha;
struct iax_peer *next;
};
/* Pipes for communication. pipe[1] belongs to the
network thread (write), and pipe[0] belongs to the individual
channel (read) */
- int pipe[2];
/* Whether or not we Quelch audio */
int quelch;
/* Last received voice format */
/* Retransmission ID */
int retrans;
-
+
/* Easy linking */
struct ast_iax_frame *next;
struct ast_iax_frame *prev;
pthread_mutex_t dpcache_lock;
#ifdef DEBUG_SUPPORT
-void showframe(struct ast_iax_frame *f, struct ast_iax_full_hdr *fhi, int rx)
+void showframe(struct ast_iax_frame *f, struct ast_iax_full_hdr *fhi, int rx, struct sockaddr_in *sin)
{
char *frames[] = {
"(0?)",
subclass = subclass2;
}
ast_verbose(
-"%s-Frame Retry[%s] -- Seqno: %2.2d Type: %s Subclass: %s\n",
+"%s-Frame Retry[%s] -- Seqno: %2.2d Type: %s Subclass: %s\n",
(rx ? "Rx" : "Tx"),
retries, ntohs(fh->seqno), class, subclass);
- fprintf(stderr,
-" Timestamp: %05dms Callno: %4.4d DCall: %4.4d\n",
+ fprintf(stderr,
+" Timestamp: %05dms Callno: %5.5d DCall: %5.5d [%s:%d]\n",
ntohl(fh->ts),
- ntohs(fh->callno) & ~AST_FLAG_FULL, (short) ntohs(fh->dcallno));
+ (short)(ntohs(fh->callno) & ~AST_FLAG_FULL), (short) ntohs(fh->dcallno),
+ inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
}
#endif
if (iaxs[callno]) {
#ifdef BRIDGE_OPTIMIZATION
if (iaxs[callno]->bridgecallno < 0)
-#endif
+#endif
send_command(iaxs[callno], AST_FRAME_IAX, AST_IAX_COMMAND_PING, 0, NULL, 0, -1);
return 1;
} else
static struct chan_iax_pvt *new_iax(void)
{
struct chan_iax_pvt *tmp;
- int flags;
tmp = malloc(sizeof(struct chan_iax_pvt));
if (tmp) {
memset(tmp, 0, sizeof(struct chan_iax_pvt));
- /* On my linux system, pipe's are more than 2x as fast as socketpairs, but too short, so
- I go to socketpairs */
- if (socketpair(AF_LOCAL, SOCK_STREAM, 0, tmp->pipe)) {
- ast_log(LOG_WARNING, "Unable to create pipe: %s\n", strerror(errno));
- free(tmp);
- return NULL;
- }
- flags = fcntl(tmp->pipe[1], F_GETFL);
- if (flags < 0)
- ast_log(LOG_WARNING, "Unable to get flags\n");
-#if 1
- if (fcntl(tmp->pipe[1], F_SETFL, flags | O_NONBLOCK))
- ast_log(LOG_WARNING, "Unable to set flags\n");
-#endif
tmp->callno = -1;
tmp->peercallno = -1;
tmp->transfercallno = -1;
if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
(cur->addr.sin_port == sin->sin_port)) {
/* This is the main host */
- if ((cur->peercallno == callno) ||
+ if ((cur->peercallno == callno) ||
((dcallno == cur->callno) && (cur->peercallno) == -1)) {
/* That's us. Be sure we keep track of the peer call number */
return 1;
if ((res < 0) && (new >= NEW_ALLOW)) {
/* Create a new one */
start = nextcallno;
- for (x = (nextcallno + 1) % AST_IAX_MAX_CALLS; iaxs[x] && (x != start); x = (x + 1) % AST_IAX_MAX_CALLS)
+ for (x = (nextcallno + 1) % AST_IAX_MAX_CALLS; iaxs[x] && (x != start); x = (x + 1) % AST_IAX_MAX_CALLS)
if (x == start) {
ast_log(LOG_WARNING, "Unable to accept more calls\n");
return -1;
static int do_deliver(void *data)
{
- /* Just deliver the packet by writing it to half of the pipe. */
+ /* Just deliver the packet by using queueing */
struct ast_iax_frame *fr = data;
unsigned int ts;
fr->retrans = -1;
iaxs[fr->callno]->lag = ts - fr->ts;
}
} else {
- ast_fr_fdwrite(iaxs[fr->callno]->pipe[1], fr->f);
+ if (iaxs[fr->callno]->owner) {
+ ast_queue_frame(iaxs[fr->callno]->owner, fr->f, 1);
+ }
}
}
/* Free the packet */
ast_log(LOG_WARNING, "Call number = %d\n", f->callno);
return -1;
}
+ if (!iaxs[f->callno])
+ return -1;
if (iaxs[f->callno]->error)
return -1;
+ if (f->transfer) {
#ifdef DEBUG_SUPPORT
- if (iaxdebug)
- showframe(f, NULL, 0);
+ if (iaxdebug)
+ showframe(f, NULL, 0, &iaxs[f->callno]->transfer);
#endif
- if (f->transfer) {
- res = sendto(netsocket, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer,
+ res = sendto(netsocket, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer,
sizeof(iaxs[f->callno]->transfer));
- } else
- res = sendto(netsocket, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr,
+ } else {
+#ifdef DEBUG_SUPPORT
+ if (iaxdebug)
+ showframe(f, NULL, 0, &iaxs[f->callno]->addr);
+#endif
+ res = sendto(netsocket, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr,
sizeof(iaxs[f->callno]->addr));
- if (res < 0) {
+ }
+ if (res < 0) {
if (option_debug)
ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
handle_error();
- } else
+ } else
res = 0;
return res;
}
if (pvt->owner) {
/* If there's an owner, prod it to give up */
- ast_fr_fdhangup(pvt->pipe[1]);
+ ast_queue_hangup(pvt->owner, 1);
return;
}
if (pvt->reg) {
pvt->reg->callno = -1;
}
- close(pvt->pipe[0]);
- close(pvt->pipe[1]);
free(pvt);
}
}
struct ast_iax_frame *f = data;
int freeme=0;
/* Make sure this call is still active */
- if (iaxs[f->callno]) {
+ if ((f->callno > -1) && iaxs[f->callno]) {
if ((f->retries < 0) /* Already ACK'd */ ||
(f->retries >= max_retries) /* Too many attempts */) {
/* Record an error if we've transmitted too many times */
iaxs[f->callno]->error = ETIMEDOUT;
if (iaxs[f->callno]->owner)
/* Hangup the fd */
- ast_fr_fdhangup(iaxs[f->callno]->pipe[1]);
+ ast_queue_hangup(iaxs[f->callno]->owner, 1);
else {
if (iaxs[f->callno]->reg) {
memset(&iaxs[f->callno]->reg->us, 0, sizeof(iaxs[f->callno]->reg->us));
packet we received, which always has a lateness of 1. */
ms = calc_rxstamp(iaxs[fr->callno]) - fr->ts;
- if (ms > 32768) {
+ if (ms > 32767) {
/* What likely happened here is that our counter has circled but we haven't
gotten the update from the main packet. We'll just pretend that we did, and
update the timestamp appropriately. */
return 0;
}
-static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, char *peer)
+static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, char *peer, char *context)
{
struct hostent *hp;
struct iax_peer *p;
if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
if (sendani)
*sendani = p->sendani;
+ if (context)
+ strncpy(context, p->context, AST_MAX_EXTENSION - 1);
if (p->addr.sin_addr.s_addr) {
sin->sin_addr = p->addr.sin_addr;
sin->sin_port = p->addr.sin_port;
char *hname;
char requeststr[256] = "";
char myrdest [5] = "s";
+ char context[AST_MAX_EXTENSION] ="";
char *portno = NULL;
struct chan_iax_pvt *p = c->pvt->pvt;
if ((c->state != AST_STATE_DOWN) && (c->state != AST_STATE_RESERVED)) {
strtok(hname, ":");
portno = strtok(hname, ":");
}
- if (create_addr(&sin, NULL, NULL, hname)) {
+ if (create_addr(&sin, NULL, NULL, hname, context)) {
ast_log(LOG_WARNING, "No address associated with '%s'\n", hname);
return -1;
}
+ /* Keep track of the context for outgoing calls too */
+ strncpy(c->context, context, sizeof(c->context) - 1);
if (portno) {
sin.sin_port = htons(atoi(portno));
}
}
static struct ast_frame *iax_read(struct ast_channel *c)
{
- struct chan_iax_pvt *pvt = c->pvt->pvt;
- struct ast_frame *f;
- if (pvt->error) {
- ast_log(LOG_DEBUG, "Connection closed, error: %s\n", strerror(pvt->error));
- return NULL;
- }
- f = ast_fr_fdread(pvt->pipe[0]);
- if (f) {
- if ((f->frametype == AST_FRAME_CONTROL) &&
- (f->subclass == AST_CONTROL_ANSWER))
- c->state = AST_STATE_UP;
- }
- return f;
+ ast_log(LOG_NOTICE, "I should never be called!\n");
+ return NULL;
}
static int iax_start_transfer(struct ast_channel *c0, struct ast_channel *c1)
{
char host[256];
struct ast_channel *tmp;
- tmp = ast_channel_alloc();
+ tmp = ast_channel_alloc(1);
if (tmp) {
if (!iax_getpeername(i->addr, host, sizeof(host)))
snprintf(host, sizeof(host), "%s:%d", inet_ntoa(i->addr.sin_addr), ntohs(i->addr.sin_port));
else
snprintf(tmp->name, sizeof(tmp->name), "IAX[%s]/%d", host, i->callno);
tmp->type = type;
- tmp->fds[0] = i->pipe[0];
/* We can support any format by default, until we get restricted */
tmp->nativeformats = capability;
tmp->readformat = 0;
return 0;
}
-static int apply_ha(struct iax_ha *ha, struct sockaddr_in *sin)
-{
- /* Start optimistic */
- int res = IAX_SENSE_ALLOW;
- while(ha) {
- /* For each rule, if this address and the netmask = the net address
- apply the current rule */
- if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == (ha->netaddr.s_addr))
- res = ha->sense;
- ha = ha->next;
- }
- return res;
-}
-
static int iax_getformats(int callno, char *orequest)
{
char *var, *value;
while(user) {
if ((!strlen(iaxs[callno]->username) || /* No username specified */
!strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
- && (apply_ha(user->ha, sin) == IAX_SENSE_ALLOW) /* Access is permitted from this IP */
+ && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */
&& (!strlen(iaxs[callno]->context) || /* No context specified */
apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */
/* We found our match (use the first) */
return -1;
}
- if (apply_ha(p->ha, sin) != IAX_SENSE_ALLOW) {
+ if (!ast_apply_ha(p->ha, sin)) {
ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", inet_ntoa(sin->sin_addr), p->name);
return -1;
}
dp->flags |= CACHE_FLAG_TRANSMITTED;
}
+static int iax_vnak(int callno)
+{
+ return send_command_immediate(iaxs[callno], AST_FRAME_IAX, AST_IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
+}
+
+static void vnak_retransmit(int callno, int last)
+{
+ struct ast_iax_frame *f;
+ ast_pthread_mutex_lock(&iaxq.lock);
+ f = iaxq.head;
+ while(f) {
+ /* Send a copy immediately */
+ if ((f->callno == callno) && iaxs[f->callno] &&
+ (f->seqno >= last)) {
+ send_packet(f);
+ }
+ f = f->next;
+ }
+ ast_pthread_mutex_unlock(&iaxq.lock);
+}
+
static int socket_read(int *id, int fd, short events, void *cbdata)
{
struct sockaddr_in sin;
struct ast_channel *c;
struct iax_dpcache *dp;
int format;
+ int exists;
char rel0[256];
char rel1[255];
char empty[32]=""; /* Safety measure */
ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, sizeof(struct ast_iax_mini_hdr));
return 1;
}
-#ifdef DEBUG_SUPPORT
+#ifdef DEBUG_SUPPORT
if (iaxdebug)
- showframe(NULL, fh, 1);
-#endif
+ showframe(NULL, fh, 1, &sin);
+#endif
if (ntohs(mh->callno) & AST_FLAG_FULL) {
/* Get the destination call number */
dcallno = ntohs(fh->dcallno);
/* We can only raw hangup control frames */
if (((f.subclass != AST_IAX_COMMAND_INVAL) &&
(f.subclass != AST_IAX_COMMAND_TXCNT) &&
- (f.subclass != AST_IAX_COMMAND_TXACC))||
+ (f.subclass != AST_IAX_COMMAND_TXACC))||
(f.frametype != AST_FRAME_IAX))
raw_hangup(&sin, ntohs(fh->dcallno), ntohs(mh->callno) & ~AST_FLAG_FULL
);
ast_pthread_mutex_unlock(&iaxs_lock);
return 1;
}
- if (((f.subclass != AST_IAX_COMMAND_TXCNT) &&
+ if (((f.subclass != AST_IAX_COMMAND_TXCNT) &&
(f.subclass != AST_IAX_COMMAND_TXACC)) || (f.frametype != AST_FRAME_IAX))
- iaxs[fr.callno]->peercallno = ntohs(mh->callno) & ~AST_FLAG_FULL;
+ iaxs[fr.callno]->peercallno = (short)(ntohs(mh->callno) & ~AST_FLAG_FULL);
if (ntohs(mh->callno) & AST_FLAG_FULL) {
if (option_debug)
ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", ntohs(fh->seqno), f.frametype, f.subclass);
/* Check if it's out of order (and not an ACK or INVAL) */
fr.seqno = ntohs(fh->seqno);
if ((iaxs[fr.callno]->iseqno != fr.seqno) &&
- (iaxs[fr.callno]->iseqno ||
+ (iaxs[fr.callno]->iseqno ||
((f.subclass != AST_IAX_COMMAND_TXCNT) &&
(f.subclass != AST_IAX_COMMAND_TXACC)) ||
(f.subclass != AST_FRAME_IAX))) {
if (
- ((f.subclass != AST_IAX_COMMAND_ACK) &&
+ ((f.subclass != AST_IAX_COMMAND_ACK) &&
(f.subclass != AST_IAX_COMMAND_INVAL) &&
(f.subclass != AST_IAX_COMMAND_TXCNT) &&
(f.subclass != AST_IAX_COMMAND_TXACC)) ||
ast_log(LOG_DEBUG, "Acking anyway\n");
send_command_immediate(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_ACK, fr.ts, NULL, 0,fr.seqno);
}
+ } else {
+ /* Send a VNAK requesting retransmission */
+ iax_vnak(fr.callno);
}
ast_pthread_mutex_unlock(&iaxs_lock);
return 1;
if (check_access(fr.callno, &sin, f.data, f.datalen)) {
/* They're not allowed on */
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No authority found", strlen("No authority found"), -1);
- ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s'\n", inet_ntoa(sin.sin_addr), f.data);
+ ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s'\n", inet_ntoa(sin.sin_addr), (char *)f.data);
break;
}
+ ast_pthread_mutex_unlock(&iaxs_lock);
+ /* This might re-enter the IAX code and need the lock */
+ exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->callerid);
+ ast_pthread_mutex_lock(&iaxs_lock);
if (!strlen(iaxs[fr.callno]->secret) && !strlen(iaxs[fr.callno]->inkeys)) {
- if (strcmp(iaxs[fr.callno]->exten, "TBD") && !ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->callerid)) {
+ if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) {
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No such context/extension", strlen("No such context/extension"), -1);
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
} else {
if (f.data)
((char *)f.data)[f.datalen] = '\0';
if (iaxs[fr.callno]->owner)
- ast_log(LOG_WARNING, "Call rejected by %s: %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), f.data);
+ ast_log(LOG_WARNING, "Call rejected by %s: %s\n", inet_ntoa(iaxs[fr.callno]->addr.sin_addr), (char *)f.data);
iaxs[fr.callno]->error = EPERM;
iax_destroy(fr.callno);
break;
if (authenticate_reply(iaxs[fr.callno], &iaxs[fr.callno]->addr, (char *)f.data, iaxs[fr.callno]->secret, iaxs[fr.callno]->outkey)) {
ast_log(LOG_WARNING,
"I don't know how to authenticate %s to %s\n",
- f.data, inet_ntoa(iaxs[fr.callno]->addr.sin_addr));
+ (char *)f.data, inet_ntoa(iaxs[fr.callno]->addr.sin_addr));
}
break;
case AST_IAX_COMMAND_AUTHREP:
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No authority found", strlen("No authority found"), -1);
break;
}
- if (strcmp(iaxs[fr.callno]->exten, "TBD") && !ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->callerid)) {
+ ast_pthread_mutex_unlock(&iaxs_lock);
+ /* This might re-enter the IAX code and need the lock */
+ exists = ast_exists_extension(NULL, iaxs[fr.callno]->context, iaxs[fr.callno]->exten, 1, iaxs[fr.callno]->callerid);
+ ast_pthread_mutex_lock(&iaxs_lock);
+ if (strcmp(iaxs[fr.callno]->exten, "TBD") && !exists) {
send_command_final(iaxs[fr.callno], AST_FRAME_IAX, AST_IAX_COMMAND_REJECT, 0, "No such context/extension", strlen("No such context/extension"), -1);
ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", inet_ntoa(sin.sin_addr), iaxs[fr.callno]->exten, iaxs[fr.callno]->context);
} else {
ast_log(LOG_DEBUG, "Destroying call %d\n", fr.callno);
break;
case AST_IAX_COMMAND_VNAK:
+ ast_log(LOG_DEBUG, "Sending VNAK\n");
/* Force retransmission */
- ast_log(LOG_NOTICE, "Need to implement VNAK\n");
+ vnak_retransmit(fr.callno, fr.seqno);
break;
case AST_IAX_COMMAND_REGREQ:
if (f.data)
if (f.data)
((char *)f.data)[f.datalen] = '\0';
if (iaxs[fr.callno]->reg) {
- ast_log(LOG_NOTICE, "Registration of '%s' rejected: %s\n", iaxs[fr.callno]->reg->username, f.data);
+ ast_log(LOG_NOTICE, "Registration of '%s' rejected: %s\n", iaxs[fr.callno]->reg->username, (char *)f.data);
iaxs[fr.callno]->reg->regstate = REG_STATE_REJECTED;
}
iax_destroy(fr.callno);
f.subclass = iaxs[fr.callno]->voiceformat;
else {
ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
+ iax_vnak(fr.callno);
ast_pthread_mutex_unlock(&iaxs_lock);
return 1;
}
return 0;
}
-static void free_ha(struct iax_ha *ha)
-{
- struct iax_ha *hal;
- while(ha) {
- hal = ha;
- ha = ha->next;
- free(hal);
- }
-}
-
static void free_context(struct iax_context *con)
{
struct iax_context *conl;
if (!st)
st = s;
/* Populate our address from the given */
- if (create_addr(&sin, &capability, &sendani, st)) {
+ if (create_addr(&sin, &capability, &sendani, st, NULL)) {
return NULL;
}
ast_pthread_mutex_lock(&iaxs_lock);
ast_sched_runq(sched);
}
}
+ return NULL;
}
static int start_network_thread()
return con;
}
-static struct iax_ha *build_ha(char *sense, char *stuff)
-{
- struct iax_ha *ha = malloc(sizeof(struct iax_ha));
- char *nm;
- if (ha) {
- strtok(stuff, "/");
- nm = strtok(NULL, "/");
- if (!nm)
- nm = "255.255.255.255";
- if (!inet_aton(stuff, &ha->netaddr)) {
- ast_log(LOG_WARNING, "%s not a valid IP\n", stuff);
- free(ha);
- return NULL;
- }
- if (!inet_aton(nm, &ha->netmask)) {
- ast_log(LOG_WARNING, "%s not a valid netmask\n", nm);
- free(ha);
- return NULL;
- }
- ha->netaddr.s_addr &= ha->netmask.s_addr;
- if (!strncasecmp(sense, "p", 1)) {
- ha->sense = IAX_SENSE_ALLOW;
- } else {
- ha->sense = IAX_SENSE_DENY;
- }
- ha->next = NULL;
- }
- return ha;
-}
-
-static int get_ip(struct sockaddr_in *sin, char *value)
-{
- struct hostent *hp;
- hp = gethostbyname(value);
- if (hp) {
- memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
- } else {
- ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
- return -1;
- }
- return 0;
-}
-
static struct iax_peer *build_peer(char *name, struct ast_variable *v)
{
struct iax_peer *peer;
struct iax_peer *prev;
- struct iax_ha *ha, *hal = NULL;
int maskfound=0;
int format;
int found=0;
ast_sched_del(sched, peer->expire);
peer->expire = -1;
peer->dynamic = 0;
- if (get_ip(&peer->addr, v->value)) {
+ if (ast_get_ip(&peer->addr, v->value)) {
free(peer);
return NULL;
}
if (!maskfound)
inet_aton("255.255.255.255", &peer->mask);
} else if (!strcasecmp(v->name, "defaultip")) {
- if (get_ip(&peer->defaddr, v->value)) {
+ if (ast_get_ip(&peer->defaddr, v->value)) {
free(peer);
return NULL;
}
} else if (!strcasecmp(v->name, "permit") ||
!strcasecmp(v->name, "deny")) {
- ha = build_ha(v->name, v->value);
- if (ha) {
- if (hal)
- hal->next = ha;
- else
- peer->ha = ha;
- hal = ha;
- }
+ peer->ha = ast_append_ha(v->name, v->value, peer->ha);
} else if (!strcasecmp(v->name, "mask")) {
maskfound++;
inet_aton(v->value, &peer->mask);
+ } else if (!strcasecmp(v->name, "context")) {
+ if (!strlen(peer->context))
+ strncpy(peer->context, v->value, sizeof(peer->context) - 1);
} else if (!strcasecmp(v->name, "port")) {
if (peer->dynamic)
peer->defaddr.sin_port = htons(atoi(v->value));
{
struct iax_user *user;
struct iax_context *con, *conl = NULL;
- struct iax_ha *ha, *hal = NULL;
int format;
user = (struct iax_user *)malloc(sizeof(struct iax_user));
if (user) {
}
} else if (!strcasecmp(v->name, "permit") ||
!strcasecmp(v->name, "deny")) {
- ha = build_ha(v->name, v->value);
- if (ha) {
- if (hal)
- hal->next = ha;
- else
- user->ha = ha;
- hal = ha;
- }
+ user->ha = ast_append_ha(v->name, v->value, user->ha);
} else if (!strcasecmp(v->name, "auth")) {
strncpy(user->methods, v->value, sizeof(user->methods)-1);
} else if (!strcasecmp(v->name, "secret")) {
/* Delete all users */
ast_pthread_mutex_lock(&userl.lock);
for (user=userl.users;user;) {
- free_ha(user->ha);
+ ast_free_ha(user->ha);
free_context(user->contexts);
userlast = user;
user=user->next;
host = st;
}
/* Populate our address from the given */
- if (create_addr(&sin, NULL, NULL, host)) {
+ if (create_addr(&sin, NULL, NULL, host, NULL)) {
return -1;
}
ast_log(LOG_DEBUG, "host: %s, user: %s, password: %s, context: %s\n", host, username, password, context);
return -1;
}
- pthread_mutex_init(&iaxq.lock, NULL);
- pthread_mutex_init(&userl.lock, NULL);
+ ast_pthread_mutex_init(&iaxq.lock);
+ ast_pthread_mutex_init(&userl.lock);
ast_cli_register(&cli_show_users);
ast_cli_register(&cli_show_channels);