mirror of
https://github.com/asterisk/asterisk.git
synced 2025-08-21 05:03:51 +00:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f83cc08b8b | ||
|
c89d2999a6 | ||
|
4208af2204 | ||
|
5fcb051bd4 | ||
|
619d7542d8 | ||
|
04e4f3d345 | ||
|
0f7afb14e4 | ||
|
1e6902b29d | ||
|
1897d857f0 | ||
|
c58235bed4 | ||
|
0edee75c07 | ||
|
726fa701da | ||
|
330090142f | ||
|
2cdedcbe94 | ||
|
ea98dd3dfc | ||
|
32ade7d7fc | ||
|
325bfeeda5 |
1
.lastclean
Normal file
1
.lastclean
Normal file
@@ -0,0 +1 @@
|
||||
9
|
2
LICENSE
2
LICENSE
@@ -32,7 +32,7 @@ GPL'd products (although if you've written a module for Asterisk we
|
||||
would strongly encourage you to make the same exception that we do).
|
||||
|
||||
Specific permission is also granted to link Asterisk with OpenSSL and
|
||||
OpenH323.
|
||||
OpenH323 and distribute the resulting binary files.
|
||||
|
||||
In addition, Asterisk implements two management/control protocols: the
|
||||
Asterisk Manager Interface (AMI) and the Asterisk Gateway Interface
|
||||
|
@@ -482,9 +482,9 @@ static int macroif_exec(struct ast_channel *chan, void *data)
|
||||
label_b++;
|
||||
}
|
||||
if (pbx_checkcondition(expr))
|
||||
macro_exec(chan, label_a);
|
||||
res = macro_exec(chan, label_a);
|
||||
else if (label_b)
|
||||
macro_exec(chan, label_b);
|
||||
res = macro_exec(chan, label_b);
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Invalid Syntax.\n");
|
||||
|
||||
|
@@ -72,6 +72,7 @@ static int pgsql_log(struct ast_cdr *cdr)
|
||||
struct tm tm;
|
||||
char sqlcmd[2048] = "", timestr[128];
|
||||
char *pgerror;
|
||||
int pgerr;
|
||||
|
||||
ast_mutex_lock(&pgsql_lock);
|
||||
|
||||
@@ -91,28 +92,32 @@ static int pgsql_log(struct ast_cdr *cdr)
|
||||
|
||||
if (connected) {
|
||||
char *clid=NULL, *dcontext=NULL, *channel=NULL, *dstchannel=NULL, *lastapp=NULL, *lastdata=NULL;
|
||||
char *uniqueid=NULL, *userfield=NULL;
|
||||
char *uniqueid=NULL, *userfield=NULL, *src=NULL, *dst=NULL;
|
||||
|
||||
/* Maximum space needed would be if all characters needed to be escaped, plus a trailing NULL */
|
||||
if ((clid = alloca(strlen(cdr->clid) * 2 + 1)) != NULL)
|
||||
PQescapeString(clid, cdr->clid, strlen(cdr->clid));
|
||||
PQescapeStringConn(conn, clid, cdr->clid, strlen(cdr->clid), &pgerr);
|
||||
if ((dcontext = alloca(strlen(cdr->dcontext) * 2 + 1)) != NULL)
|
||||
PQescapeString(dcontext, cdr->dcontext, strlen(cdr->dcontext));
|
||||
PQescapeStringConn(conn, dcontext, cdr->dcontext, strlen(cdr->dcontext), &pgerr);
|
||||
if ((channel = alloca(strlen(cdr->channel) * 2 + 1)) != NULL)
|
||||
PQescapeString(channel, cdr->channel, strlen(cdr->channel));
|
||||
PQescapeStringConn(conn, channel, cdr->channel, strlen(cdr->channel), &pgerr);
|
||||
if ((dstchannel = alloca(strlen(cdr->dstchannel) * 2 + 1)) != NULL)
|
||||
PQescapeString(dstchannel, cdr->dstchannel, strlen(cdr->dstchannel));
|
||||
PQescapeStringConn(conn, dstchannel, cdr->dstchannel, strlen(cdr->dstchannel), &pgerr);
|
||||
if ((lastapp = alloca(strlen(cdr->lastapp) * 2 + 1)) != NULL)
|
||||
PQescapeString(lastapp, cdr->lastapp, strlen(cdr->lastapp));
|
||||
PQescapeStringConn(conn, lastapp, cdr->lastapp, strlen(cdr->lastapp), &pgerr);
|
||||
if ((lastdata = alloca(strlen(cdr->lastdata) * 2 + 1)) != NULL)
|
||||
PQescapeString(lastdata, cdr->lastdata, strlen(cdr->lastdata));
|
||||
PQescapeStringConn(conn, lastdata, cdr->lastdata, strlen(cdr->lastdata), &pgerr);
|
||||
if ((uniqueid = alloca(strlen(cdr->uniqueid) * 2 + 1)) != NULL)
|
||||
PQescapeString(uniqueid, cdr->uniqueid, strlen(cdr->uniqueid));
|
||||
PQescapeStringConn(conn, uniqueid, cdr->uniqueid, strlen(cdr->uniqueid), &pgerr);
|
||||
if ((userfield = alloca(strlen(cdr->userfield) * 2 + 1)) != NULL)
|
||||
PQescapeString(userfield, cdr->userfield, strlen(cdr->userfield));
|
||||
PQescapeStringConn(conn, userfield, cdr->userfield, strlen(cdr->userfield), &pgerr);
|
||||
if ((src = alloca(strlen(cdr->src) * 2 + 1)) != NULL)
|
||||
PQescapeStringConn(conn, src, cdr->src, strlen(cdr->src), &pgerr);
|
||||
if ((dst = alloca(strlen(cdr->dst) * 2 + 1)) != NULL)
|
||||
PQescapeStringConn(conn, dst, cdr->dst, strlen(cdr->dst), &pgerr);
|
||||
|
||||
/* Check for all alloca failures above at once */
|
||||
if ((!clid) || (!dcontext) || (!channel) || (!dstchannel) || (!lastapp) || (!lastdata) || (!uniqueid) || (!userfield)) {
|
||||
if ((!clid) || (!dcontext) || (!channel) || (!dstchannel) || (!lastapp) || (!lastdata) || (!uniqueid) || (!userfield) || (!src) || (!dst)) {
|
||||
ast_log(LOG_ERROR, "cdr_pgsql: Out of memory error (insert fails)\n");
|
||||
ast_mutex_unlock(&pgsql_lock);
|
||||
return -1;
|
||||
@@ -123,7 +128,7 @@ static int pgsql_log(struct ast_cdr *cdr)
|
||||
snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s (calldate,clid,src,dst,dcontext,channel,dstchannel,"
|
||||
"lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) VALUES"
|
||||
" ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%ld,%ld,'%s',%ld,'%s','%s','%s')",
|
||||
table,timestr,clid,cdr->src, cdr->dst, dcontext,channel, dstchannel, lastapp, lastdata,
|
||||
table, timestr, clid, src, dst, dcontext,channel, dstchannel, lastapp, lastdata,
|
||||
cdr->duration,cdr->billsec,ast_cdr_disp2str(cdr->disposition),cdr->amaflags, cdr->accountcode, uniqueid, userfield);
|
||||
|
||||
ast_log(LOG_DEBUG,"cdr_pgsql: SQL command executed: %s\n",sqlcmd);
|
||||
|
@@ -2620,16 +2620,18 @@ static void realtime_update_peer(const char *peername, struct sockaddr_in *sin,
|
||||
|
||||
static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
|
||||
{
|
||||
struct ast_variable *var;
|
||||
struct ast_variable *var = NULL;
|
||||
struct ast_variable *tmp;
|
||||
struct iax2_peer *peer=NULL;
|
||||
time_t regseconds, nowtime;
|
||||
int dynamic=0;
|
||||
char iabuf[INET_ADDRSTRLEN];
|
||||
|
||||
if (peername)
|
||||
var = ast_load_realtime("iaxpeers", "name", peername, NULL);
|
||||
else {
|
||||
char iabuf[INET_ADDRSTRLEN];
|
||||
if (peername) {
|
||||
var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
|
||||
if (!var && sin)
|
||||
var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
|
||||
} else if (sin) {
|
||||
char porta[25];
|
||||
ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
|
||||
sprintf(porta, "%d", ntohs(sin->sin_port));
|
||||
@@ -2644,6 +2646,29 @@ static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!var && peername) { /* Last ditch effort */
|
||||
var = ast_load_realtime("iaxpeers", "name", peername, NULL);
|
||||
/*!\note
|
||||
* If this one loaded something, then we need to ensure that the host
|
||||
* field matched. The only reason why we can't have this as a criteria
|
||||
* 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) {
|
||||
for (tmp = var; tmp; tmp = tmp->next) {
|
||||
if (!strcasecmp(tmp->name, "host")) {
|
||||
struct in_addr sin2 = { 0, };
|
||||
struct ast_dnsmgr_entry *dnsmgr = NULL;
|
||||
if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) {
|
||||
/* No match */
|
||||
ast_variables_destroy(var);
|
||||
var = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!var)
|
||||
return NULL;
|
||||
|
||||
@@ -2720,13 +2745,46 @@ static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in
|
||||
return peer;
|
||||
}
|
||||
|
||||
static struct iax2_user *realtime_user(const char *username)
|
||||
static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
|
||||
{
|
||||
struct ast_variable *var;
|
||||
struct ast_variable *tmp;
|
||||
struct iax2_user *user=NULL;
|
||||
char iabuf[INET_ADDRSTRLEN];
|
||||
|
||||
var = ast_load_realtime("iaxusers", "name", username, NULL);
|
||||
var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
|
||||
if (!var && sin)
|
||||
var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
|
||||
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(iabuf, sizeof(iabuf), sin->sin_addr), "port", porta, NULL);
|
||||
if (!var)
|
||||
var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), "port", porta, NULL);
|
||||
}
|
||||
if (!var) { /* Last ditch effort */
|
||||
var = ast_load_realtime("iaxusers", "name", username, NULL);
|
||||
/*!\note
|
||||
* If this one loaded something, then we need to ensure that the host
|
||||
* field matched. The only reason why we can't have this as a criteria
|
||||
* 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) {
|
||||
for (tmp = var; tmp; tmp = tmp->next) {
|
||||
if (!strcasecmp(tmp->name, "host")) {
|
||||
struct in_addr sin2 = { 0, };
|
||||
struct ast_dnsmgr_entry *dnsmgr = NULL;
|
||||
if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) {
|
||||
/* No match */
|
||||
ast_variables_destroy(var);
|
||||
var = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!var)
|
||||
return NULL;
|
||||
|
||||
@@ -4878,7 +4936,7 @@ static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies
|
||||
ast_mutex_unlock(&userl.lock);
|
||||
user = best;
|
||||
if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
|
||||
user = realtime_user(iaxs[callno]->username);
|
||||
user = realtime_user(iaxs[callno]->username, sin);
|
||||
if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */
|
||||
!apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */
|
||||
destroy_user(user);
|
||||
|
@@ -81,6 +81,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
#include "asterisk/dnsmgr.h"
|
||||
#include "asterisk/devicestate.h"
|
||||
#include "asterisk/linkedlists.h"
|
||||
#include "asterisk/dnsmgr.h"
|
||||
|
||||
#ifdef OSP_SUPPORT
|
||||
#include "asterisk/astosp.h"
|
||||
@@ -1698,9 +1699,35 @@ static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *
|
||||
char iabuf[80];
|
||||
|
||||
/* First check on peer name */
|
||||
if (newpeername)
|
||||
var = ast_load_realtime("sippeers", "name", peername, NULL);
|
||||
else if (sin) { /* Then check on IP address */
|
||||
if (newpeername) {
|
||||
var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", NULL);
|
||||
if (!var && sin) {
|
||||
var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), NULL);
|
||||
if (!var) {
|
||||
var = ast_load_realtime("sippeers", "name", newpeername, NULL);
|
||||
/*!\note
|
||||
* If this one loaded something, then we need to ensure that the host
|
||||
* field matched. The only reason why we can't have this as a criteria
|
||||
* 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) {
|
||||
for (tmp = var; tmp; tmp = tmp->next) {
|
||||
if (!strcasecmp(var->name, "host")) {
|
||||
struct in_addr sin2 = { 0, };
|
||||
struct ast_dnsmgr_entry *dnsmgr = NULL;
|
||||
if ((ast_dnsmgr_lookup(tmp->value, &sin2, &dnsmgr) < 0) || (memcmp(&sin2, &sin->sin_addr, sizeof(sin2)) != 0)) {
|
||||
/* No match */
|
||||
ast_variables_destroy(var);
|
||||
var = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (sin) { /* Then check on IP address */
|
||||
ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
|
||||
var = ast_load_realtime("sippeers", "host", iabuf, NULL); /* First check for fixed IP hosts */
|
||||
if (!var)
|
||||
|
@@ -1726,20 +1726,14 @@ static int restore_gains(struct zt_pvt *p)
|
||||
|
||||
static inline int zt_set_hook(int fd, int hs)
|
||||
{
|
||||
int x, res, count = 0;
|
||||
int x, res;
|
||||
|
||||
x = hs;
|
||||
res = ioctl(fd, ZT_HOOK, &x);
|
||||
|
||||
while (res < 0 && count < 20) {
|
||||
usleep(100000); /* 1/10 sec. */
|
||||
x = hs;
|
||||
res = ioctl(fd, ZT_HOOK, &x);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (res < 0) {
|
||||
if (errno == EINPROGRESS) return 0;
|
||||
if (errno == EINPROGRESS)
|
||||
return 0;
|
||||
ast_log(LOG_WARNING, "zt hook failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
@@ -6477,7 +6471,7 @@ static int handle_init_event(struct zt_pvt *i, int event)
|
||||
else
|
||||
res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_DIALTONE);
|
||||
if (res < 0)
|
||||
ast_log(LOG_WARNING, "Unable to play dialtone on channel %d\n", i->channel);
|
||||
ast_log(LOG_WARNING, "Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined?\n", i->channel);
|
||||
if (ast_pthread_create(&threadid, &attr, ss_thread, chan)) {
|
||||
ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
|
||||
res = tone_zone_play_tone(i->subs[SUB_REAL].zfd, ZT_TONE_CONGESTION);
|
||||
|
@@ -3,8 +3,19 @@
|
||||
# lame quickie script to snarf a core of a hung asterisk process.
|
||||
# bugs to ast_grab_core, blinky-lights.org (derrick daugherty)
|
||||
|
||||
# we have found that gcore doesn't yield as useful a core file
|
||||
# as that yielded by a signal-caused core dump. So we are going to change
|
||||
# the strategy to sending a SEGV signal to the asterisk process,
|
||||
# and have it 'burn to the ground', leaving behind a core file.
|
||||
# the main difference is that you cannot control where the
|
||||
# core file will end up. We will assume that safe_asterisk was
|
||||
# used to start asterisk, and the core file should therefore end
|
||||
# up in /tmp (because safe_asterisk cd's there before starting asterisk).
|
||||
# if this is not the case, set DUMPDIR to the place where the core
|
||||
# file can be found.
|
||||
|
||||
DATE=`date +%Y%m%d%H%M`
|
||||
DUMPDIR=/var/tmp
|
||||
DUMPDIR=/tmp
|
||||
HOSTNAME=`hostname`
|
||||
ADMINEMAIL="root@localhost"
|
||||
|
||||
@@ -27,20 +38,16 @@ echo \*\*\* WARNING \*\*\* If the system is not already locked this will cause
|
||||
echo \*\*\* WARNING \*\*\* process to STOP while memory is dumped to disk.
|
||||
echo
|
||||
|
||||
/usr/bin/gdb > /dev/null << EOF
|
||||
attach ${PID}
|
||||
gcore ${DUMPDIR}/asterisk_${DATE}.core.${PID}
|
||||
detach
|
||||
quit
|
||||
EOF
|
||||
/usr/bin/kill -11 ${PID}
|
||||
|
||||
echo Snarfed! ${DUMPDIR}/asterisk_${DATE}.core.${PID}
|
||||
echo Snarfed! ${DUMPDIR}/core.${PID}
|
||||
echo
|
||||
|
||||
|
||||
echo Trying for a backtrace of the captured core.
|
||||
/usr/bin/gdb /usr/sbin/asterisk ${DUMPDIR}/asterisk_${DATE}.core.${PID} > /tmp/gdb_dump.${PID} 2> /dev/null << EOF
|
||||
/usr/bin/gdb /usr/sbin/asterisk ${DUMPDIR}/core.${PID} > /tmp/gdb_dump.${PID} 2> /dev/null << EOF
|
||||
set prompt \n
|
||||
set print pretty\n
|
||||
echo --------------------------------------------------------------------------------\n
|
||||
echo INFO THREAD
|
||||
info thread
|
||||
@@ -56,7 +63,7 @@ echo Done trying for a bt.
|
||||
|
||||
|
||||
echo Notifying admins of the core.
|
||||
/usr/bin/mail -s "${HOSTNAME} core dumped at ${DUMPDIR}/asterisk_${DATE}.core.${PID}" ${ADMINEMAIL} < /tmp/gdb_dump.${PID}
|
||||
/usr/bin/mail -s "${HOSTNAME} core dumped at ${DUMPDIR}/core.${PID}" ${ADMINEMAIL} < /tmp/gdb_dump.${PID}
|
||||
/bin/rm /tmp/gdb_dump.${PID}
|
||||
echo Done.
|
||||
echo
|
||||
|
@@ -185,6 +185,9 @@ int fsk_serie(fsk_data *fskd, short *buffer, int *len, int *outbyte)
|
||||
int i,j,n1,r;
|
||||
int samples=0;
|
||||
int olen;
|
||||
int beginlen=*len;
|
||||
int beginlenx;
|
||||
|
||||
switch(fskd->state) {
|
||||
/* Pick up where we left off */
|
||||
case STATE_SEARCH_STARTBIT2:
|
||||
@@ -212,12 +215,13 @@ of a transmission (what a LOSING design), we cant do it this elegantly */
|
||||
beginning of a start bit in the TDD sceanario. It just looks for sufficient
|
||||
level to maybe, perhaps, guess, maybe that its maybe the beginning of
|
||||
a start bit, perhaps. This whole thing stinks! */
|
||||
beginlenx=beginlen; /* just to avoid unused war warnings */
|
||||
if (demodulador(fskd,&fskd->x1,GET_SAMPLE)) return(-1);
|
||||
samples++;
|
||||
for(;;)
|
||||
{
|
||||
search_startbit2:
|
||||
if (!*len) {
|
||||
if (*len <= 0) {
|
||||
fskd->state = STATE_SEARCH_STARTBIT2;
|
||||
return 0;
|
||||
}
|
||||
@@ -235,7 +239,7 @@ search_startbit3:
|
||||
fskd->state = STATE_SEARCH_STARTBIT3;
|
||||
return 0;
|
||||
}
|
||||
for(;i;i--) { if (demodulador(fskd,&fskd->x1,GET_SAMPLE)) return(-1);
|
||||
for(;i>0;i--) { if (demodulador(fskd,&fskd->x1,GET_SAMPLE)) return(-1);
|
||||
#if 0
|
||||
printf("x1 = %5.5f ", fskd->x1);
|
||||
#endif
|
||||
|
@@ -268,7 +268,7 @@ static inline int __ast_pthread_mutex_lock(const char *filename, int lineno, con
|
||||
}
|
||||
} else {
|
||||
__ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
|
||||
filename, lineno, func, strerror(errno));
|
||||
filename, lineno, func, strerror(res));
|
||||
#ifdef THREAD_CRASH
|
||||
DO_THREAD_CRASH;
|
||||
#endif
|
||||
|
@@ -1103,7 +1103,8 @@ static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, char **argv
|
||||
}
|
||||
fdprintf(agi->fd, "200 result=%d\n", res);
|
||||
|
||||
return res >= 0 ? RESULT_SUCCESS : RESULT_FAILURE;
|
||||
/* Even though this is wrong, users are depending upon this result. */
|
||||
return res;
|
||||
}
|
||||
|
||||
static int handle_setcallerid(struct ast_channel *chan, AGI *agi, int argc, char **argv)
|
||||
|
Reference in New Issue
Block a user