61 #include <sys/socket.h>
62 #include <netinet/in.h>
63 #include <arpa/inet.h>
64 #include <netinet/in_systm.h>
65 #include <netinet/ip.h>
110 #include "asterisk/stasis_system.h"
111 #include "asterisk/stasis_channels.h"
281 #define SCHED_MULTITHREADED
285 #define DEBUG_SCHED_MULTITHREAD
289 static int nochecksums = 0;
292 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
293 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
295 #define DEFAULT_THREAD_COUNT 10
296 #define DEFAULT_MAX_THREAD_COUNT 100
297 #define DEFAULT_RETRY_TIME 1000
298 #define MEMORY_SIZE 100
299 #define DEFAULT_DROP 3
301 #define DEBUG_SUPPORT
303 #define MIN_REUSE_TIME 60
310 static const char tdesc[] =
"Inter Asterisk eXchange Driver (Ver 2)";
315 #define MAX_TRUNK_MTU 1240
320 #define DEFAULT_CONTEXT "default"
329 static int network_change_sched_id = -1;
331 static int maxauthreq = 3;
332 static int max_retries = 4;
333 static int ping_time = 21;
334 static int lagrq_time = 10;
335 static int maxjitterbuffer=1000;
336 static int resyncthreshold=1000;
337 static int maxjitterinterps=10;
338 static int jittertargetextra = 40;
340 #define MAX_TRUNKDATA 640 * 200
342 static int trunkfreq = 20;
345 static int authdebug = 0;
346 static int autokill = 0;
347 static int iaxcompat = 0;
348 static int last_authmethod = 0;
350 static int iaxdefaultdpcache=10 * 60;
352 static int iaxdefaulttimeout = 5;
359 static int min_reg_expire;
360 static int max_reg_expire;
362 static int srvlookup = 0;
368 static int defaultsockfd = -1;
370 static int (*iax2_regfunk)(
const char *username,
int onoff) = NULL;
373 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
375 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
377 ~AST_FORMAT_SLIN16 & \
378 ~AST_FORMAT_SIREN7 & \
379 ~AST_FORMAT_SIREN14 & \
385 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
387 ~AST_FORMAT_G726_AAL2 & \
390 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
394 #define DEFAULT_MAXMS 2000
395 #define DEFAULT_FREQ_OK 60 * 1000
396 #define DEFAULT_FREQ_NOTOK 10 * 1000
401 [IAX_AUTH_PLAINTEXT] =
"plaintext",
402 [IAX_AUTH_MD5] =
"MD5",
403 [IAX_AUTH_RSA] =
"RSA",
407 #define AUTH_METHOD_NAMES_BUFSIZE 19
421 if (authmethods & IAX_AUTH_RSA) {
422 pos += sprintf(pos,
"|RSA");
424 if (authmethods & IAX_AUTH_MD5) {
425 pos += sprintf(pos,
"|MD5");
427 if (authmethods & IAX_AUTH_PLAINTEXT) {
428 pos += sprintf(pos,
"|plaintext");
440 #define IAX_CALLENCRYPTED(pvt) \
441 (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))
443 #define IAX_DEBUGDIGEST(msg, key) do { \
445 char digest[33] = ""; \
450 for (idx = 0; idx < 16; idx++) \
451 sprintf(digest + (idx << 1), "%02hhx", (unsigned char) key[idx]); \
453 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
459 static iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
461 static int iaxdebug = 0;
463 static int iaxtrunkdebug = 0;
465 static int test_losspct = 0;
467 static int test_late = 0;
468 static int test_resync = 0;
469 static int test_jit = 0;
470 static int test_jitpct = 0;
476 static int amaflags = 0;
478 static int delayreject = 0;
479 static int iax2_encryption = 0;
480 static int iax2_authmethods = 0;
484 static pthread_t netthreadid = AST_PTHREADT_NULL;
487 IAX_STATE_STARTED = (1 << 0),
488 IAX_STATE_AUTHENTICATED = (1 << 1),
489 IAX_STATE_TBD = (1 << 2),
498 #define IAX_HASCALLERID (uint64_t)(1LLU << 0)
499 #define IAX_DELME (uint64_t)(1LLU << 1)
500 #define IAX_TEMPONLY (uint64_t)(1LLU << 2)
501 #define IAX_TRUNK (uint64_t)(1LLU << 3)
502 #define IAX_NOTRANSFER (uint64_t)(1LLU << 4)
503 #define IAX_USEJITTERBUF (uint64_t)(1LLU << 5)
504 #define IAX_DYNAMIC (uint64_t)(1LLU << 6)
505 #define IAX_SENDANI (uint64_t)(1LLU << 7)
506 #define IAX_RTSAVE_SYSNAME (uint64_t)(1LLU << 8)
507 #define IAX_ALREADYGONE (uint64_t)(1LLU << 9)
508 #define IAX_PROVISION (uint64_t)(1LLU << 10)
509 #define IAX_QUELCH (uint64_t)(1LLU << 11)
510 #define IAX_ENCRYPTED (uint64_t)(1LLU << 12)
511 #define IAX_KEYPOPULATED (uint64_t)(1LLU << 13)
512 #define IAX_CODEC_USER_FIRST (uint64_t)(1LLU << 14)
513 #define IAX_CODEC_NOPREFS (uint64_t)(1LLU << 15)
514 #define IAX_CODEC_NOCAP (uint64_t)(1LLU << 16)
515 #define IAX_RTCACHEFRIENDS (uint64_t)(1LLU << 17)
516 #define IAX_RTUPDATE (uint64_t)(1LLU << 18)
517 #define IAX_RTAUTOCLEAR (uint64_t)(1LLU << 19)
518 #define IAX_RTIGNOREREGEXPIRE (uint64_t)(1LLU << 21)
519 #define IAX_TRUNKTIMESTAMPS (uint64_t)(1LLU << 22)
520 #define IAX_TRANSFERMEDIA (uint64_t)(1LLU << 23)
521 #define IAX_MAXAUTHREQ (uint64_t)(1LLU << 24)
522 #define IAX_DELAYPBXSTART (uint64_t)(1LLU << 25)
523 #define IAX_ALLOWFWDOWNLOAD (uint64_t)(1LLU << 26)
524 #define IAX_IMMEDIATE (uint64_t)(1LLU << 27)
525 #define IAX_SENDCONNECTEDLINE (uint64_t)(1LLU << 28)
526 #define IAX_RECVCONNECTEDLINE (uint64_t)(1LLU << 29)
527 #define IAX_FORCE_ENCRYPT (uint64_t)(1LLU << 30)
528 #define IAX_SHRINKCALLERID (uint64_t)(1LLU << 31)
529 static int global_rtautoclear = 120;
531 static int reload_config(
int forced_reload);
638 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
650 unsigned char *trunkdata;
651 unsigned int trunkdatalen;
652 unsigned int trunkdataalloc;
662 REG_STATE_UNREGISTERED = 0,
665 REG_STATE_REGISTERED,
671 enum iax_transfer_state {
676 TRANSFER_PASSTHROUGH,
680 TRANSFER_MPASSTHROUGH,
691 enum iax_reg_state regstate;
704 #define MIN_RETRY_TIME 100
705 #define MAX_RETRY_TIME 10000
707 #define MAX_JITTER_BUFFER 50
708 #define MIN_JITTER_BUFFER 10
710 #define DEFAULT_TRUNKDATA 640 * 10
712 #define MAX_TIMESTAMP_SKEW 160
715 #define TS_GAP_FOR_JB_RESYNC 5000
718 #define MARK_IAX_SUBCLASS_TX 0x8000
720 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
721 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
722 static int iaxdynamicthreadcount = 0;
723 static int iaxdynamicthreadnum = 0;
724 static int iaxactivethreadcount = 0;
740 typedef uint16_t callno_entry;
770 unsigned int notsilenttx:1;
796 struct timeval offset;
798 struct timeval rxcore;
880 unsigned char semirand[32];
882 struct iax2_registry *
reg;
890 enum iax_transfer_state transferring;
931 int destroy_initiated;
933 unsigned char calltoken_ie_len;
950 #define PTR_TO_CALLNO_ENTRY(a) ((uint16_t)(unsigned long)(a))
951 #define CALLNO_ENTRY_TO_PTR(a) ((void *)(unsigned long)(a))
953 #define CALLNO_ENTRY_SET_VALIDATED(a) ((a) |= 0x8000)
954 #define CALLNO_ENTRY_IS_VALIDATED(a) ((a) & 0x8000)
955 #define CALLNO_ENTRY_GET_CALLNO(a) ((a) & 0x7FFF)
960 callno_entry numbers[IAX_MAX_CALLS / 2 + 1];
963 AST_MUTEX_DEFINE_STATIC(callno_pool_lock);
984 static
int randomcalltokendata;
986 static time_t max_calltoken_delay = 10;
996 #define MAX_PEER_BUCKETS 17
998 #define MAX_PEER_BUCKETS 563
1002 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
1014 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
1016 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
1018 static uint16_t global_maxcallno;
1023 static uint16_t total_nonval_callno_used = 0;
1071 struct timeval orig;
1072 struct timeval expiry;
1074 unsigned short callno;
1082 static void reg_source_db(
struct iax2_peer *p);
1086 static int ast_cli_netstats(
struct mansession *s,
int fd,
int limit_fmt);
1087 static char *complete_iax2_peers(
const char *line,
const char *word,
int pos,
int state, uint64_t flags);
1088 static char *complete_iax2_unregister(
const char *line,
const char *word,
int pos,
int state);
1090 enum iax2_thread_iostate {
1093 IAX_IOSTATE_PROCESSING,
1094 IAX_IOSTATE_SCHEDREADY,
1097 enum iax2_thread_type {
1098 IAX_THREAD_TYPE_POOL,
1099 IAX_THREAD_TYPE_DYNAMIC,
1105 unsigned char buf[1];
1110 enum iax2_thread_type type;
1111 enum iax2_thread_iostate iostate;
1112 #ifdef SCHED_MULTITHREADED
1113 void (*schedfunc)(
const void *);
1114 const void *scheddata;
1116 #ifdef DEBUG_SCHED_MULTITHREAD
1123 unsigned char readbuf[4096];
1132 ast_cond_t init_cond;
1138 unsigned short callno;
1156 static void iax2_destroy(
int callno);
1158 static void signal_condition(
ast_mutex_t *lock, ast_cond_t *cond)
1160 ast_mutex_lock(lock);
1161 ast_cond_signal(cond);
1162 ast_mutex_unlock(lock);
1175 static ast_callid iax_pvt_callid_get(
int callno)
1180 static void iax_pvt_callid_set(
int callno, ast_callid callid)
1185 static void iax_pvt_callid_new(
int callno)
1188 char buffer[AST_CALLID_BUFFER_LENGTH];
1190 iax_pvt_callid_set(callno, callid);
1222 #define TRUNK_CALL_START (IAX_MAX_CALLS / 2)
1236 iax_showframe(f, fhi, rx, addr, datalen);
1239 iax_showframe(f, fhi, rx, addr, datalen);
1245 static void iax_debug_output(
const char *data)
1248 ast_verbose(
"%s", data);
1251 static void iax_error_output(
const char *data)
1253 ast_log(LOG_WARNING,
"%s", data);
1256 static void __attribute__((format(printf, 1, 2))) jb_error_output(const
char *fmt, ...)
1261 va_start(args, fmt);
1262 vsnprintf(buf,
sizeof(buf), fmt, args);
1265 ast_log(LOG_ERROR,
"%s", buf);
1268 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const
char *fmt, ...)
1273 va_start(args, fmt);
1274 vsnprintf(buf,
sizeof(buf), fmt, args);
1277 ast_log(LOG_WARNING,
"%s", buf);
1280 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const
char *fmt, ...)
1285 va_start(args, fmt);
1286 vsnprintf(buf,
sizeof(buf), fmt, args);
1289 ast_verbose(
"%s", buf);
1292 static int expire_registry(
const void *data);
1294 static int iax2_call(
struct ast_channel *c,
const char *dest,
int timeout);
1296 static int iax2_digit_begin(
struct ast_channel *c,
char digit);
1297 static int iax2_digit_end(
struct ast_channel *c,
char digit,
unsigned int duration);
1298 static int iax2_do_register(
struct iax2_registry *reg);
1301 static int iax2_indicate(
struct ast_channel *c,
int condition,
const void *data,
size_t datalen);
1302 static int iax2_poke_peer(
struct iax2_peer *peer,
int heldcall);
1303 static int iax2_provision(
struct ast_sockaddr *end,
int sockfd,
const char *dest,
const char *
template,
int force);
1304 static int iax2_send(
struct chan_iax2_pvt *pvt,
struct ast_frame *f,
unsigned int ts,
int seqno,
int now,
int transfer,
int final);
1305 static int iax2_sendhtml(
struct ast_channel *c,
int subclass,
const char *data,
int datalen);
1307 static int iax2_sendtext(
struct ast_channel *c,
const char *text);
1308 static int iax2_setoption(
struct ast_channel *c,
int option,
void *data,
int datalen);
1309 static int iax2_queryoption(
struct ast_channel *c,
int option,
void *data,
int *datalen);
1310 static int iax2_transfer(
struct ast_channel *c,
const char *dest);
1314 static int send_trunk(
struct iax2_trunk_peer *tpeer,
struct timeval *now);
1315 static int send_command(
struct chan_iax2_pvt *,
char,
int,
unsigned int,
const unsigned char *,
int,
int);
1317 static int send_command_immediate(
struct chan_iax2_pvt *,
char,
int,
unsigned int,
const unsigned char *,
int,
int);
1318 static int send_command_locked(
unsigned short callno,
char,
int,
unsigned int,
const unsigned char *,
int,
int);
1319 static int send_command_transfer(
struct chan_iax2_pvt *,
char,
int,
unsigned int,
const unsigned char *,
int);
1324 static void realtime_update_peer(
const char *peername,
struct ast_sockaddr *sockaddr, time_t regtime);
1325 static void *iax2_dup_variable_datastore(
void *);
1326 static void prune_peers(
void);
1327 static void prune_users(
void);
1328 static void iax2_free_variable_datastore(
void *);
1330 static int acf_channel_read(
struct ast_channel *chan,
const char *funcname,
char *preparse,
char *buf,
size_t buflen);
1333 static void build_ecx_key(
const unsigned char *digest,
struct chan_iax2_pvt *pvt);
1334 static void build_rand_pad(
unsigned char *buf, ssize_t len);
1335 static int get_unused_callno(
enum callno_type type,
int validated, callno_entry *entry);
1336 static int replace_callno(
const void *obj);
1337 static void sched_delay_remove(
struct ast_sockaddr *addr, callno_entry entry);
1343 .description = tdesc,
1345 .requester = iax2_request,
1347 .send_digit_begin = iax2_digit_begin,
1348 .send_digit_end = iax2_digit_end,
1349 .send_text = iax2_sendtext,
1350 .send_image = iax2_sendimage,
1351 .send_html = iax2_sendhtml,
1353 .hangup = iax2_hangup,
1354 .answer = iax2_answer,
1356 .write = iax2_write,
1357 .write_video = iax2_write,
1358 .indicate = iax2_indicate,
1359 .setoption = iax2_setoption,
1360 .queryoption = iax2_queryoption,
1361 .transfer = iax2_transfer,
1362 .fixup = iax2_fixup,
1363 .func_channel_read = acf_channel_read,
1381 static void iax2_lock_owner(
int callno)
1384 if (!iaxs[callno] || !iaxs[callno]->owner) {
1388 if (!ast_channel_trylock(iaxs[callno]->owner)) {
1393 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
1405 static int iax2_is_control_frame_allowed(
int subtype)
1415 if (subtype == -1) {
1501 static void network_change_stasis_subscribe(
void)
1503 if (!network_change_sub) {
1505 network_change_stasis_cb, NULL);
1511 static void network_change_stasis_unsubscribe(
void)
1516 static void acl_change_stasis_subscribe(
void)
1518 if (!acl_change_sub) {
1520 acl_change_stasis_cb, NULL);
1526 static void acl_change_stasis_unsubscribe(
void)
1531 static int network_change_sched_cb(
const void *data)
1533 struct iax2_registry *reg;
1534 network_change_sched_id = -1;
1537 iax2_do_register(reg);
1552 ast_verb(1,
"IAX, got a network change message, renewing all IAX registrations.\n");
1553 if (network_change_sched_id == -1) {
1554 network_change_sched_id = iax2_sched_add(sched, 1000, network_change_sched_cb, NULL);
1565 ast_log(LOG_NOTICE,
"Reloading chan_iax2 in response to ACL change event.\n");
1570 .
type =
"IAX2_VARIABLE",
1571 .duplicate = iax2_dup_variable_datastore,
1572 .destroy = iax2_free_variable_datastore,
1575 static void *iax2_dup_variable_datastore(
void *old)
1582 ast_log(LOG_ERROR,
"Unable to duplicate iax2 variables\n");
1589 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
1593 ast_log(LOG_ERROR,
"Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
1599 static void iax2_free_variable_datastore(
void *old)
1619 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
1659 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread =
ast_calloc(1,
sizeof(*thread))))
1665 thread->type = IAX_THREAD_TYPE_DYNAMIC;
1668 ast_mutex_init(&thread->lock);
1669 ast_cond_init(&thread->cond, NULL);
1670 ast_mutex_init(&thread->init_lock);
1671 ast_cond_init(&thread->init_cond, NULL);
1672 ast_mutex_lock(&thread->init_lock);
1675 if (ast_pthread_create_background(&thread->threadid, NULL,
iax2_process_thread, thread)) {
1676 ast_cond_destroy(&thread->cond);
1677 ast_mutex_destroy(&thread->lock);
1678 ast_mutex_unlock(&thread->init_lock);
1679 ast_cond_destroy(&thread->init_cond);
1680 ast_mutex_destroy(&thread->init_lock);
1690 ast_cond_wait(&thread->init_cond, &thread->init_lock);
1693 ast_mutex_unlock(&thread->init_lock);
1698 #ifdef SCHED_MULTITHREADED
1699 static int __schedule_action(
void (*func)(
const void *data),
const void *data,
const char *funcname)
1702 static time_t lasterror;
1705 thread = find_idle_thread();
1706 if (thread != NULL) {
1707 thread->schedfunc = func;
1708 thread->scheddata = data;
1709 thread->iostate = IAX_IOSTATE_SCHEDREADY;
1710 #ifdef DEBUG_SCHED_MULTITHREAD
1713 signal_condition(&thread->lock, &thread->cond);
1717 if (t != lasterror) {
1719 ast_debug(1,
"Out of idle IAX2 threads for scheduling! (%s)\n", funcname);
1724 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
1747 ast_mutex_lock(&iaxsl[callno]);
1751 if (!iaxs[callno] || iaxs[callno]->destroy_initiated) {
1752 ast_debug(3,
"I wanted to lock callno %d, but it is dead or going to die.\n", callno);
1753 ast_mutex_unlock(&iaxsl[callno]);
1761 static int send_ping(
const void *data);
1763 static void __send_ping(
const void *data)
1765 int callno = PTR_TO_CALLNO(data);
1768 ast_debug(3,
"Hangup initiated on call %d, aborting __send_ping\n", callno);
1773 iaxs[callno]->
pingid = -1;
1776 if (iaxs[callno]->peercallno) {
1778 send_command(iaxs[callno],
AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
1781 iaxs[callno]->
pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
1784 ast_mutex_unlock(&iaxsl[callno]);
1787 static int send_ping(
const void *data)
1789 #ifdef SCHED_MULTITHREADED
1790 if (schedule_action(__send_ping, data))
1797 static void encmethods_to_str(
int e,
struct ast_str **buf)
1800 if (e & IAX_ENCRYPT_AES128) {
1813 static int get_encrypt_methods(
const char *s)
1816 if (!strcasecmp(s,
"aes128"))
1825 static int send_lagrq(
const void *data);
1827 static void __send_lagrq(
const void *data)
1829 int callno = PTR_TO_CALLNO(data);
1832 ast_debug(3,
"Hangup initiated on call %d, aborting __send_lagrq\n", callno);
1837 iaxs[callno]->
lagid = -1;
1840 if (iaxs[callno]->peercallno) {
1842 send_command(iaxs[callno],
AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
1845 iaxs[callno]->
lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
1848 ast_mutex_unlock(&iaxsl[callno]);
1851 static int send_lagrq(
const void *data)
1853 #ifdef SCHED_MULTITHREADED
1854 if (schedule_action(__send_lagrq, data))
1860 static unsigned char compress_subclass(
iax2_format subclass)
1865 if (subclass < IAX_FLAG_SC_LOG)
1868 for (x = 0; x < IAX_MAX_SHIFT; x++) {
1869 if (subclass & (1LL << x)) {
1871 ast_log(LOG_WARNING,
"Can't compress subclass %lld\n", (
long long) subclass);
1877 return power | IAX_FLAG_SC_LOG;
1880 static iax2_format uncompress_subclass(
unsigned char csub)
1883 if (csub & IAX_FLAG_SC_LOG) {
1888 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
1899 for (x = 0; x < ARRAY_LEN(pref->
order); ++x) {
1901 uint64_t pref_bitfield;
1904 if (!pref_bitfield) {
1920 return found_format;
1923 ast_debug(4,
"Could not find preferred codec - Returning zero codec.\n");
1924 ao2_cleanup(found_format);
1936 tmpfmt = codec_choose_from_prefs(pref, cap);
1962 static const char *iax2_getformatname_multiple(
iax2_format format,
struct ast_str **codec_buf)
2012 const char *name = obj;
2022 struct iax2_peer *peer = obj, *peer2 = arg;
2023 const char *name = arg;
2025 return !strcmp(peer->name, flags &
OBJ_KEY ? name : peer2->name) ?
2035 const char *name = obj;
2046 const char *name = arg;
2048 return !strcmp(user->name, flags &
OBJ_KEY ? name : user2->name) ?
2060 peer = ao2_find(peers, name,
OBJ_KEY);
2063 if (!peer && realtime) {
2081 static struct iax2_user *find_user(
const char *name)
2083 return ao2_find(users, name,
OBJ_KEY);
2092 static int iax2_getpeername(
struct ast_sockaddr addr,
char *host,
int len)
2099 while ((peer = ao2_iterator_next(&i))) {
2124 static int iax2_delete_from_sched(
const void* data)
2164 iax2_sched_add(sched, 0, iax2_delete_from_sched, (
void*)(
long)pvt->
pingid);
2165 iax2_sched_add(sched, 0, iax2_delete_from_sched, (
void*)(
long)pvt->
lagid);
2177 static void iax2_frame_free(
struct iax_frame *fr)
2183 static int scheduled_destroy(
const void *vid)
2185 unsigned short callno = PTR_TO_CALLNO(vid);
2186 ast_mutex_lock(&iaxsl[callno]);
2188 ast_debug(1,
"Really destroying %d now...\n", callno);
2189 iax2_destroy(callno);
2191 ast_mutex_unlock(&iaxsl[callno]);
2198 ast_free(s->f.
data.ptr);
2210 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
2211 free_signaling_queue_entry(s);
2233 free_signaling_queue_entry(qe);
2243 static void pvt_destructor(
void *obj)
2249 ast_mutex_lock(&iaxsl[pvt->
callno]);
2264 ast_mutex_unlock(&iaxsl[pvt->
callno]);
2267 free_signaling_queue_entry(s);
2282 iax2_frame_free(frame.data);
2295 if (!(tmp = ao2_alloc(
sizeof(*tmp), pvt_destructor))) {
2313 tmp->
prefs = prefs_global;
2338 memcpy(
new, fr,
sizeof(*
new));
2339 iax_frame_wrap(
new, &fr->
af);
2343 new->direction = DIRECTION_INGRESS;
2359 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
2367 (check_dcallno ? dcallno == cur->
callno : 1) ) {
2385 if (iaxs[callno]->oseqno) {
2386 ast_log(LOG_WARNING,
"Can't make trunk once a call has started!\n");
2389 if (callno >= TRUNK_CALL_START) {
2390 ast_log(LOG_WARNING,
"Call %d is already a trunk\n", callno);
2394 if (get_unused_callno(
2396 CALLNO_ENTRY_IS_VALIDATED(iaxs[callno]->callno_entry),
2398 ast_log(LOG_WARNING,
"Unable to trunk call: Insufficient space\n");
2402 x = CALLNO_ENTRY_GET_CALLNO(entry);
2403 ast_mutex_lock(&iaxsl[x]);
2417 if (iaxs[x]->callno_entry) {
2420 MIN_REUSE_TIME * 1000,
2422 CALLNO_ENTRY_TO_PTR(iaxs[x]->callno_entry));
2429 iaxs[x]->
pingid = iax2_sched_add(sched,
2430 ping_time * 1000, send_ping, (
void *)(
long)x);
2431 iaxs[x]->
lagid = iax2_sched_add(sched,
2432 lagrq_time * 1000, send_lagrq, (
void *)(
long)x);
2435 ast_mutex_unlock(&iaxsl[callno]);
2438 ast_mutex_unlock(&iaxsl[x]);
2441 ast_debug(1,
"Made call %d into trunk call %d\n", callno, x);
2446 static void store_by_transfercallno(
struct chan_iax2_pvt *pvt)
2449 ast_log(LOG_ERROR,
"This should not be called without a transfer call number.\n");
2453 ao2_link(iax_transfercallno_pvts, pvt);
2456 static void remove_by_transfercallno(
struct chan_iax2_pvt *pvt)
2459 ast_log(LOG_ERROR,
"This should not be called without a transfer call number.\n");
2468 ast_log(LOG_ERROR,
"This should not be called without a peer call number.\n");
2472 ao2_link(iax_peercallno_pvts, pvt);
2478 ast_log(LOG_ERROR,
"This should not be called without a peer call number.\n");
2485 static int addr_range_delme_cb(
void *obj,
void *arg,
int flags)
2492 static int addr_range_hash_cb(
const void *obj,
const int flags)
2498 static int addr_range_cmp_cb(
void *obj,
void *arg,
int flags)
2506 static int peercnt_hash_cb(
const void *obj,
const int flags)
2516 static int peercnt_cmp_cb(
void *obj,
void *arg,
int flags)
2518 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
2522 static int addr_range_match_address_cb(
void *obj,
void *arg,
int flags)
2541 static int calltoken_required(
struct ast_sockaddr *addr,
const char *name,
int subclass)
2543 struct addr_range *addr_range;
2547 const char *find =
S_OR(name,
"guest");
2558 if ((addr_range =
ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, addr))) {
2564 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
2566 }
else if ((subclass == IAX_COMMAND_NEW) && (user =
realtime_user(find, addr))) {
2568 }
else if ((subclass != IAX_COMMAND_NEW) && (peer =
find_peer(find, 0))) {
2570 }
else if ((subclass != IAX_COMMAND_NEW) && (peer =
realtime_peer(find, addr))) {
2581 ast_debug(1,
"Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %u \n",
ast_sockaddr_stringify_addr(addr), name, optional, calltoken_required);
2600 static void set_peercnt_limit(
struct peercnt *peercnt)
2602 uint16_t limit = global_maxcallno;
2603 struct addr_range *addr_range;
2608 if (peercnt->
reg && peercnt->
limit) {
2612 if ((addr_range =
ao2_callback(callno_limits, 0, addr_range_match_address_cb, &addr))) {
2613 limit = addr_range->
limit;
2618 peercnt->
limit = limit;
2625 static int set_peercnt_limit_all_cb(
void *obj,
void *arg,
int flags)
2627 struct peercnt *peercnt = obj;
2629 set_peercnt_limit(peercnt);
2630 ast_debug(1,
"Reset limits for peercnts table\n");
2639 static int prune_addr_range_cb(
void *obj,
void *arg,
int flags)
2641 struct addr_range *addr_range = obj;
2650 static void peercnt_modify(
unsigned char reg, uint16_t limit,
struct ast_sockaddr *sockaddr)
2653 struct peercnt *peercnt;
2658 if ((peercnt = ao2_find(peercnts, &tmp,
OBJ_POINTER))) {
2663 set_peercnt_limit(peercnt);
2680 struct peercnt *peercnt;
2693 if ((peercnt = ao2_find(peercnts, &tmp,
OBJ_POINTER))) {
2695 }
else if ((peercnt = ao2_alloc(
sizeof(*peercnt), NULL))) {
2699 set_peercnt_limit(peercnt);
2704 ao2_unlock(peercnts);
2709 if (peercnt->
limit > peercnt->
cur) {
2718 ao2_unlock(peercnt);
2719 ao2_unlock(peercnts);
2729 static void peercnt_remove(
struct peercnt *peercnt)
2745 if (peercnt->
cur == 0) {
2748 ao2_unlock(peercnts);
2755 static int peercnt_remove_cb(
const void *obj)
2757 struct peercnt *peercnt = (
struct peercnt *) obj;
2759 peercnt_remove(peercnt);
2769 static int peercnt_remove_by_addr(
struct ast_sockaddr *addr)
2771 struct peercnt *peercnt;
2776 if ((peercnt = ao2_find(peercnts, &tmp,
OBJ_POINTER))) {
2777 peercnt_remove(peercnt);
2787 static void build_callno_limits(
struct ast_variable *v)
2789 struct addr_range *addr_range = NULL;
2790 struct addr_range tmp;
2796 for (; v; v = v->
next) {
2804 ast_log(LOG_ERROR,
"Call number limit for %s could not be added, Invalid address range\n.", v->
name);
2806 }
else if ((sscanf(v->
value,
"%d", &limit) != 1) || (limit < 0)) {
2807 ast_log(LOG_ERROR,
"Call number limit for %s could not be added. Invalid limit %s\n.", v->
name, v->
value);
2814 if ((addr_range = ao2_find(callno_limits, &tmp,
OBJ_POINTER))) {
2815 ao2_lock(addr_range);
2817 }
else if (!(addr_range = ao2_alloc(
sizeof(*addr_range), NULL))) {
2825 addr_range->
limit = limit;
2826 addr_range->
delme = 0;
2830 ao2_unlock(addr_range);
2832 ao2_link(callno_limits, addr_range);
2842 static int add_calltoken_ignore(
const char *addr)
2844 struct addr_range tmp;
2845 struct addr_range *addr_range = NULL;
2846 struct ast_ha *ha = NULL;
2849 if (ast_strlen_zero(addr)) {
2850 ast_log(LOG_WARNING,
"invalid calltokenoptional (null)\n");
2858 ast_log(LOG_WARNING,
"Error %d creating calltokenoptional entry %s\n", error, addr);
2864 if ((addr_range = ao2_find(calltoken_ignores, &tmp,
OBJ_POINTER))) {
2865 ao2_lock(addr_range);
2866 addr_range->
delme = 0;
2867 ao2_unlock(addr_range);
2868 }
else if ((addr_range = ao2_alloc(
sizeof(*addr_range), NULL))) {
2871 ao2_link(calltoken_ignores, addr_range);
2886 struct peercnt *peercnt;
2892 e->
command =
"iax2 show callnumber usage";
2894 "Usage: iax2 show callnumber usage [IP address]\n"
2895 " Shows current IP addresses which are consuming iax2 call numbers\n";
2900 if (a->argc < 4 || a->argc > 5)
2901 return CLI_SHOWUSAGE;
2904 ast_cli(a->fd,
"%-45s %-12s %-12s\n",
"Address",
"Callno Usage",
"Callno Limit");
2908 while ((peercnt = ao2_iterator_next(&i))) {
2913 ast_cli(a->fd,
"%-45s %-12s %-12s\n",
"Address",
"Callno Usage",
"Callno Limit");
2930 ast_cli(a->fd,
"\nNon-CallToken Validation Callno Limit: %d\n"
2931 "Non-CallToken Validated Callno Used: %d\n",
2932 global_maxcallno_nonval,
2933 total_nonval_callno_used);
2935 ast_cli(a->fd,
"Total Available Callno: %zu\n"
2936 "Regular Callno Available: %zu\n"
2937 "Trunk Callno Available: %zu\n",
2938 pool_avail + trunk_pool_avail,
2941 }
else if (a->argc == 5 && !found) {
2942 ast_cli(a->fd,
"No call number table entries for %s found\n", a->argv[4] );
2952 static int get_unused_callno(
enum callno_type type,
int validated, callno_entry *entry)
2959 case CALLNO_TYPE_NORMAL:
2962 case CALLNO_TYPE_TRUNK:
2975 ast_mutex_lock(&callno_pool_lock);
2978 if (!pool->available) {
2979 ast_log(LOG_WARNING,
"Out of call numbers\n");
2980 ast_mutex_unlock(&callno_pool_lock);
2987 if (!validated && total_nonval_callno_used >= global_maxcallno_nonval) {
2988 ast_log(LOG_WARNING,
2989 "NON-CallToken callnumber limit is reached. Current: %d Max: %d\n",
2990 total_nonval_callno_used,
2991 global_maxcallno_nonval);
2992 ast_mutex_unlock(&callno_pool_lock);
3010 choice = ast_random() % pool->available;
3012 *entry = pool->numbers[choice];
3013 swap = pool->numbers[pool->available - 1];
3015 pool->numbers[choice] = swap;
3019 CALLNO_ENTRY_SET_VALIDATED(*entry);
3021 total_nonval_callno_used++;
3024 ast_mutex_unlock(&callno_pool_lock);
3029 static int replace_callno(
const void *obj)
3031 callno_entry entry = PTR_TO_CALLNO_ENTRY(obj);
3036 ast_mutex_lock(&callno_pool_lock);
3038 if (!CALLNO_ENTRY_IS_VALIDATED(entry)) {
3039 if (total_nonval_callno_used) {
3040 total_nonval_callno_used--;
3043 "Attempted to decrement total non calltoken validated "
3044 "callnumbers below zero. Callno is: %d\n",
3045 CALLNO_ENTRY_GET_CALLNO(entry));
3049 if (CALLNO_ENTRY_GET_CALLNO(entry) < TRUNK_CALL_START) {
3055 ast_assert(pool->capacity > pool->available);
3058 entry = CALLNO_ENTRY_GET_CALLNO(entry);
3060 pool->numbers[pool->available] = entry;
3063 ast_mutex_unlock(&callno_pool_lock);
3068 static int create_callno_pools(
void)
3075 for (i = 2; i < TRUNK_CALL_START; i++) {
3080 for (i = TRUNK_CALL_START; i < IAX_MAX_CALLS; i++) {
3101 static void sched_delay_remove(
struct ast_sockaddr *addr, callno_entry entry)
3104 struct peercnt *peercnt;
3109 if ((peercnt = ao2_find(peercnts, &tmp,
OBJ_POINTER))) {
3112 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
3120 MIN_REUSE_TIME * 1000,
3122 CALLNO_ENTRY_TO_PTR(entry));
3132 static inline int attribute_pure iax2_allow_new(
int frametype,
int subclass,
int inbound)
3138 case IAX_COMMAND_NEW:
3155 static int __find_callno(
unsigned short callno,
unsigned short dcallno,
struct ast_sockaddr *addr,
int new,
int sockfd,
int return_locked,
int check_dcallno)
3161 int validated = (
new > NEW_ALLOW) ? 1 : 0;
3164 if (
new <= NEW_ALLOW) {
3170 .transfercallno =
callno,
3172 .frames_received = check_dcallno,
3177 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt,
OBJ_POINTER))) {
3178 if (return_locked) {
3179 ast_mutex_lock(&iaxsl[pvt->
callno]);
3187 memset(&tmp_pvt.
addr, 0,
sizeof(tmp_pvt.
addr));
3189 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt,
OBJ_POINTER))) {
3190 if (return_locked) {
3191 ast_mutex_lock(&iaxsl[pvt->
callno]);
3202 ast_mutex_lock(&iaxsl[dcallno]);
3204 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(addr, callno, dcallno, iaxs[dcallno], check_dcallno)) {
3207 store_by_peercallno(iaxs[dcallno]);
3208 if (!res || !return_locked) {
3209 ast_mutex_unlock(&iaxsl[dcallno]);
3214 ast_mutex_unlock(&iaxsl[dcallno]);
3217 if (!res && (
new >= NEW_ALLOW)) {
3226 if (!iax2_getpeername(*addr, host,
sizeof(host)))
3229 if (peercnt_add(addr)) {
3235 if (get_unused_callno(CALLNO_TYPE_NORMAL, validated, &entry)) {
3238 peercnt_remove_by_addr(addr);
3239 ast_log(LOG_WARNING,
"No more space\n");
3242 x = CALLNO_ENTRY_GET_CALLNO(entry);
3243 ast_mutex_lock(&iaxsl[x]);
3245 iaxs[x] = new_iax(addr, host);
3248 ast_debug(1,
"Creating new call structure %d\n", x);
3254 iaxs[x]->
pingtime = DEFAULT_RETRY_TIME;
3255 iaxs[x]->
expiry = min_reg_expire;
3256 iaxs[x]->
pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (
void *)(
long)x);
3257 iaxs[x]->
lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (
void *)(
long)x);
3258 iaxs[x]->amaflags = amaflags;
3265 if (iaxs[x]->peercallno) {
3266 store_by_peercallno(iaxs[x]);
3269 ast_log(LOG_WARNING,
"Out of resources\n");
3270 ast_mutex_unlock(&iaxsl[x]);
3271 replace_callno(CALLNO_ENTRY_TO_PTR(entry));
3275 ast_mutex_unlock(&iaxsl[x]);
3281 static int find_callno(
unsigned short callno,
unsigned short dcallno,
struct ast_sockaddr *addr,
int new,
int sockfd,
int full_frame) {
3282 return __find_callno(callno, dcallno, addr,
new, sockfd, 0, full_frame);
3285 static int find_callno_locked(
unsigned short callno,
unsigned short dcallno,
struct ast_sockaddr *addr,
int new,
int sockfd,
int full_frame) {
3287 return __find_callno(callno, dcallno, addr,
new, sockfd, 1, full_frame);
3302 iax2_lock_owner(callno);
3303 if (iaxs[callno] && iaxs[callno]->owner) {
3305 ast_channel_unlock(iaxs[callno]->owner);
3325 iax2_lock_owner(callno);
3326 if (iaxs[callno] && iaxs[callno]->owner) {
3328 ast_channel_unlock(iaxs[callno]->owner);
3348 iax2_lock_owner(callno);
3349 if (iaxs[callno] && iaxs[callno]->owner) {
3351 ast_channel_unlock(iaxs[callno]->owner);
3371 iax2_lock_owner(callno);
3372 if (iaxs[callno] && iaxs[callno]->owner) {
3374 ast_channel_unlock(iaxs[callno]->owner);
3397 iax2_frame_free(fr);
3402 static int handle_error(
void)
3408 struct sockaddr_in *sin;
3411 struct sock_extended_err e;
3416 m.msg_controllen =
sizeof(e);
3418 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
3420 ast_log(LOG_WARNING,
"Error detected, but unable to read error: %s\n", strerror(errno));
3422 if (m.msg_controllen) {
3423 sin = (
struct sockaddr_in *)SO_EE_OFFENDER(&e);
3425 ast_log(LOG_WARNING,
"Receive error from %s\n",
ast_inet_ntoa(sin->sin_addr));
3427 ast_log(LOG_WARNING,
"No address detected??\n");
3429 ast_log(LOG_WARNING,
"Local error: %s\n", strerror(e.ee_errno));
3442 ast_debug(1,
"Received error: %s\n", strerror(errno));
3449 static int send_packet(
struct iax_frame *f)
3455 if (!callno || !iaxs[callno] || iaxs[callno]->error)
3471 ast_debug(1,
"Received error: %s\n", strerror(errno));
3496 if ((c = pvt->
owner)) {
3497 ast_channel_tech_pvt_set(c, NULL);
3506 static void iax2_destroy(
int callno)
3512 if ((pvt = iaxs[callno])) {
3525 owner = pvt ? pvt->
owner : NULL;
3528 if (ast_channel_trylock(owner)) {
3529 ast_debug(3,
"Avoiding IAX destroy deadlock\n");
3530 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
3536 iaxs[callno] = NULL;
3550 remove_by_peercallno(pvt);
3554 remove_by_transfercallno(pvt);
3564 ast_channel_unlock(owner);
3568 static int update_packet(
struct iax_frame *f)
3594 static int attempt_transmit(
const void *data);
3595 static void __attempt_transmit(
const void *data)
3605 ast_mutex_lock(&iaxsl[callno]);
3606 if (callno && iaxs[callno]) {
3610 }
else if (f->
retries >= max_retries) {
3615 }
else if (f->
final) {
3616 iax2_destroy(callno);
3618 if (iaxs[callno]->owner) {
3619 ast_log(LOG_WARNING,
"Max retries exceeded to host %s on %s (type = %u, subclass = %d, ts=%u, seqno=%d)\n",
3628 if (iaxs[callno]->owner) {
3633 if (iaxs[callno] && iaxs[callno]->owner)
3634 ast_channel_hangupcause_set(iaxs[callno]->owner, AST_CAUSE_DESTINATION_OUT_OF_ORDER);
3636 if (iaxs[callno]->reg) {
3637 memset(&iaxs[callno]->reg->us, 0,
sizeof(iaxs[callno]->
reg->
us));
3638 iaxs[callno]->
reg->regstate = REG_STATE_TIMEOUT;
3641 iax2_destroy(callno);
3669 ast_mutex_unlock(&iaxsl[callno]);
3673 }
else if (callno) {
3674 ast_mutex_unlock(&iaxsl[callno]);
3678 static int attempt_transmit(
const void *data)
3680 #ifdef SCHED_MULTITHREADED
3681 if (schedule_action(__attempt_transmit, data))
3683 __attempt_transmit(data);
3691 static const char *
const choices[] = {
"all", NULL };
3696 e->
command =
"iax2 prune realtime";
3698 "Usage: iax2 prune realtime [<peername>|all]\n"
3699 " Prunes object(s) from the cache\n";
3705 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n -
sizeof(choices),
IAX_RTCACHEFRIENDS);
3711 return CLI_SHOWUSAGE;
3712 if (!strcmp(a->argv[3],
"all")) {
3715 ast_cli(a->fd,
"Cache flushed successfully.\n");
3719 user = find_user(a->argv[3]);
3724 expire_registry(peer_ref(peer));
3725 ast_cli(a->fd,
"Peer %s was removed from the cache.\n", a->argv[3]);
3727 ast_cli(a->fd,
"Peer %s is not eligible for this operation.\n", a->argv[3]);
3734 ast_cli(a->fd,
"User %s was removed from the cache.\n", a->argv[3]);
3736 ast_cli(a->fd,
"User %s is not eligible for this operation.\n", a->argv[3]);
3742 ast_cli(a->fd,
"%s was not found in the cache.\n", a->argv[3]);
3752 e->
command =
"iax2 test losspct";
3754 "Usage: iax2 test losspct <percentage>\n"
3755 " For testing, throws away <percentage> percent of incoming packets\n";
3761 return CLI_SHOWUSAGE;
3763 test_losspct = atoi(a->argv[3]);
3773 e->
command =
"iax2 test late";
3775 "Usage: iax2 test late <ms>\n"
3776 " For testing, count the next frame as <ms> ms late\n";
3783 return CLI_SHOWUSAGE;
3785 test_late = atoi(a->argv[3]);
3794 e->
command =
"iax2 test resync";
3796 "Usage: iax2 test resync <ms>\n"
3797 " For testing, adjust all future frames by <ms> ms\n";
3804 return CLI_SHOWUSAGE;
3806 test_resync = atoi(a->argv[3]);
3815 e->
command =
"iax2 test jitter";
3817 "Usage: iax2 test jitter <ms> <pct>\n"
3818 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
3819 " percentage of packets. If <pct> is not specified, adds\n"
3820 " jitter to all packets.\n";
3826 if (a->argc < 4 || a->argc > 5)
3827 return CLI_SHOWUSAGE;
3829 test_jit = atoi(a->argv[3]);
3831 test_jitpct = atoi(a->argv[4]);
3846 snprintf(status, statuslen,
"LAGGED (%d ms)", peer->
lastms);
3848 }
else if (peer->
lastms) {
3849 snprintf(status, statuslen,
"OK (%d ms)", peer->
lastms);
3868 struct ast_str *encmethods = ast_str_alloca(256);
3869 int load_realtime = 0;
3873 e->
command =
"iax2 show peer";
3875 "Usage: iax2 show peer <name>\n"
3876 " Display details on specific IAX peer\n";
3880 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
3885 return CLI_SHOWUSAGE;
3887 load_realtime = (a->argc == 5 && !strcmp(a->argv[4],
"load")) ? 1 : 0;
3889 peer =
find_peer(a->argv[3], load_realtime);
3891 char *str_addr, *str_defaddr;
3892 char *str_port, *str_defport;
3899 encmethods_to_str(peer->
encmethods, &encmethods);
3900 ast_cli(a->fd,
"\n\n");
3901 ast_cli(a->fd,
" * Name : %s\n", peer->name);
3902 ast_cli(a->fd,
" Description : %s\n", peer->
description);
3903 ast_cli(a->fd,
" Secret : %s\n", ast_strlen_zero(peer->secret) ?
"<Not set>" :
"<Set>");
3904 ast_cli(a->fd,
" Context : %s\n", peer->
context);
3905 ast_cli(a->fd,
" Parking lot : %s\n", peer->
parkinglot);
3906 ast_cli(a->fd,
" Mailbox : %s\n", peer->
mailbox);
3907 ast_cli(a->fd,
" Dynamic : %s\n", ast_test_flag64(peer,
IAX_DYNAMIC) ?
"Yes" :
"No");
3908 ast_cli(a->fd,
" Callnum limit: %d\n", peer->
maxcallno);
3910 ast_cli(a->fd,
" Trunk : %s\n", ast_test_flag64(peer,
IAX_TRUNK) ?
"Yes" :
"No");
3912 ast_cli(a->fd,
" Callerid : %s\n", ast_callerid_merge(cbuf,
sizeof(cbuf), peer->
cid_name, peer->
cid_num,
"<unspecified>"));
3913 ast_cli(a->fd,
" Expire : %d\n", peer->
expire);
3915 ast_cli(a->fd,
" Addr->IP : %s Port %s\n", str_addr ? str_addr :
"(Unspecified)", str_port);
3916 ast_cli(a->fd,
" Defaddr->IP : %s Port %s\n", str_defaddr, str_defport);
3917 ast_cli(a->fd,
" Username : %s\n", peer->username);
3918 ast_cli(a->fd,
" Codecs : %s\n", iax2_getformatname_multiple(peer->
capability, &codec_buf));
3921 strcpy(cbuf,
"Error");
3923 ast_cli(a->fd,
" Codec Order : %s\n", cbuf);
3926 ast_cli(a->fd,
" Status : %s\n", status);
3927 ast_cli(a->fd,
" Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->
pokefreqok, peer->
pokefreqnotok, peer->
smoothing ?
"On" :
"Off");
3928 ast_cli(a->fd,
"\n");
3931 ast_cli(a->fd,
"Peer %s not found.\n", a->argv[3]);
3932 ast_cli(a->fd,
"\n");
3938 static char *complete_iax2_peers(
const char *line,
const char *word,
int pos,
int state, uint64_t flags)
3943 int wordlen = strlen(word);
3947 while ((peer = ao2_iterator_next(&i))) {
3948 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
3949 && (!flags || ast_test_flag64(peer, flags))) {
3964 int cnt = 0, dead = 0,
final = 0, i = 0;
3968 e->
command =
"iax2 show stats";
3970 "Usage: iax2 show stats\n"
3971 " Display statistics on IAX channel driver.\n";
3978 return CLI_SHOWUSAGE;
3981 ast_mutex_lock(&iaxsl[i]);
3989 ast_mutex_unlock(&iaxsl[i]);
3992 ast_cli(a->fd,
" IAX Statistics\n");
3993 ast_cli(a->fd,
"---------------------\n");
3994 ast_cli(a->fd,
"Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
3995 ast_cli(a->fd,
"%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
3997 ast_cli(a->fd,
"Packets in transmit queue: %d dead, %d final, %d total\n\n", dead,
final, cnt);
3999 trunk_timed = trunk_untimed = 0;
4015 "Usage: iax2 set mtu <value>\n"
4016 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
4017 " zero to disable. Disabling means that the operating system\n"
4018 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
4019 " packet exceeds the UDP payload size. This is substantially\n"
4020 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
4021 " greater for G.711 samples.\n";
4028 return CLI_SHOWUSAGE;
4029 if (strncasecmp(a->argv[3],
"default", strlen(a->argv[3])) == 0)
4032 mtuv = atoi(a->argv[3]);
4039 if (mtuv < 172 || mtuv > 4000) {
4040 ast_cli(a->fd,
"Trunk MTU must be between 172 and 4000\n");
4041 return CLI_SHOWUSAGE;
4051 char tmp[1024], *pc = NULL;
4057 e->
command =
"iax2 show cache";
4059 "Usage: iax2 show cache\n"
4060 " Display currently cached IAX Dialplan results.\n";
4068 ast_cli(a->fd,
"%-20.20s %-12.12s %-9.9s %-8.8s %s\n",
"Peer/Context",
"Exten",
"Exp.",
"Wait.",
"Flags");
4071 s = dp->expiry.tv_sec - now.tv_sec;
4074 strncat(tmp,
"EXISTS|",
sizeof(tmp) - strlen(tmp) - 1);
4076 strncat(tmp,
"NONEXISTENT|",
sizeof(tmp) - strlen(tmp) - 1);
4078 strncat(tmp,
"CANEXIST|",
sizeof(tmp) - strlen(tmp) - 1);
4080 strncat(tmp,
"PENDING|",
sizeof(tmp) - strlen(tmp) - 1);
4082 strncat(tmp,
"TIMEOUT|",
sizeof(tmp) - strlen(tmp) - 1);
4084 strncat(tmp,
"TRANSMITTED|",
sizeof(tmp) - strlen(tmp) - 1);
4086 strncat(tmp,
"MATCHMORE|",
sizeof(tmp) - strlen(tmp) - 1);
4088 strncat(tmp,
"UNKNOWN|",
sizeof(tmp) - strlen(tmp) - 1);
4090 if (!ast_strlen_zero(tmp)) {
4091 tmp[strlen(tmp) - 1] =
'\0';
4096 pc = strchr(dp->peercontext,
'@');
4098 pc = dp->peercontext;
4102 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
4103 if (dp->waiters[x] > -1)
4107 ast_cli(a->fd,
"%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
4109 ast_cli(a->fd,
"%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten,
"(expired)", y, tmp);
4118 static unsigned int calc_rxstamp(
struct chan_iax2_pvt *p,
unsigned int offset);
4120 static void unwrap_timestamp(
struct iax_frame *fr)
4125 const int lower_mask = (1 << ts_shift) - 1;
4126 const int upper_mask = ~lower_mask;
4127 const int last_upper = iaxs[fr->
callno]->
last & upper_mask;
4129 if ( (fr->
ts & upper_mask) == last_upper ) {
4131 const int threshold = (ts_shift == 15) ? 25000 : 50000;
4133 if (x < -threshold) {
4138 fr->
ts = (last_upper + (1 << ts_shift)) | (fr->
ts & lower_mask);
4140 ast_debug(1,
"schedule_delivery: pushed forward timestamp\n");
4141 }
else if (x > threshold) {
4146 fr->
ts = (last_upper - (1 << ts_shift)) | (fr->
ts & lower_mask);
4148 ast_debug(1,
"schedule_delivery: pushed back timestamp\n");
4153 static int get_from_jb(
const void *p);
4168 pvt->
jbid = iax2_sched_replace(pvt->
jbid, sched, when, get_from_jb,
4169 CALLNO_TO_PTR(pvt->
callno));
4172 static void __get_from_jb(
const void *p)
4174 int callno = PTR_TO_CALLNO(p);
4185 ast_mutex_lock(&iaxsl[callno]);
4189 ast_mutex_unlock(&iaxsl[callno]);
4198 now.tv_usec += 1000;
4211 ast_log(LOG_WARNING,
"No voice format and no peer format available on %s, backlogging frame\n", ast_channel_name(pvt->
owner));
4230 af.
src =
"IAX2 JB interpolation";
4244 iax2_frame_free(frame.data);
4257 update_jbsched(pvt);
4258 ast_mutex_unlock(&iaxsl[callno]);
4261 static int get_from_jb(
const void *data)
4263 #ifdef SCHED_MULTITHREADED
4264 if (schedule_action(__get_from_jb, data))
4266 __get_from_jb(data);
4292 unwrap_timestamp(fr);
4299 ast_debug(1,
"schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
4324 calc_rxstamp(iaxs[fr->
callno],fr->
ts));
4325 if (ret == JB_DROP) {
4327 }
else if (ret == JB_SCHED) {
4328 update_jbsched(iaxs[fr->
callno]);
4334 iax2_frame_free(fr);
4340 static int transmit_frame(
void *data)
4344 ast_mutex_lock(&iaxsl[fr->
callno]);
4353 ast_mutex_unlock(&iaxsl[fr->
callno]);
4361 ast_mutex_unlock(&iaxsl[fr->
callno]);
4367 static int iax2_transmit(
struct iax_frame *fr)
4374 static int iax2_digit_begin(
struct ast_channel *c,
char digit)
4376 return send_command_locked(PTR_TO_CALLNO(ast_channel_tech_pvt(c)),
AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
4379 static int iax2_digit_end(
struct ast_channel *c,
char digit,
unsigned int duration)
4381 return send_command_locked(PTR_TO_CALLNO(ast_channel_tech_pvt(c)),
AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
4384 static int iax2_sendtext(
struct ast_channel *c,
const char *text)
4387 return send_command_locked(PTR_TO_CALLNO(ast_channel_tech_pvt(c)),
AST_FRAME_TEXT,
4388 0, 0, (
unsigned char *)text, strlen(text) + 1, -1);
4396 static int iax2_sendhtml(
struct ast_channel *c,
int subclass,
const char *data,
int datalen)
4398 return send_command_locked(PTR_TO_CALLNO(ast_channel_tech_pvt(c)),
AST_FRAME_HTML, subclass, 0, (
unsigned char *)data, datalen, -1);
4403 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(newchan));
4404 ast_mutex_lock(&iaxsl[callno]);
4408 ast_log(LOG_WARNING,
"Uh, this isn't a good sign...\n");
4409 ast_mutex_unlock(&iaxsl[callno]);
4422 time_t regseconds = 0, nowtime;
4424 char *str_addr, *str_port;
4430 var = ast_load_realtime(
"iaxpeers",
"name", peername,
"host",
"dynamic", SENTINEL);
4432 var = ast_load_realtime(
"iaxpeers",
"name", peername,
"host", str_addr, SENTINEL);
4435 var = ast_load_realtime(
"iaxpeers",
"ipaddr", str_addr,
"port", str_port, SENTINEL);
4438 for (tmp = var; tmp; tmp = tmp->
next) {
4439 if (!strcasecmp(tmp->
name,
"name"))
4440 peername = tmp->
value;
4444 if (!var && peername) {
4445 var = ast_load_realtime(
"iaxpeers",
"name", peername, SENTINEL);
4453 for (tmp = var; tmp; tmp = tmp->
next) {
4454 if (!strcasecmp(tmp->
name,
"host")) {
4479 for (tmp = var; tmp; tmp = tmp->
next) {
4481 if (!strcasecmp(tmp->
name,
"type")) {
4482 if (strcasecmp(tmp->
value,
"friend") &&
4483 strcasecmp(tmp->
value,
"peer")) {
4485 peer = peer_unref(peer);
4488 }
else if (!strcasecmp(tmp->
name,
"regseconds")) {
4490 }
else if (!strcasecmp(tmp->
name,
"ipaddr")) {
4493 ast_log(LOG_WARNING,
"Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->
value, tmp->
name);
4498 }
else if (!strcasecmp(tmp->
name,
"port")) {
4501 bindport = IAX_DEFAULT_PORTNO;
4504 }
else if (!strcasecmp(tmp->
name,
"host")) {
4505 if (!strcasecmp(tmp->
value,
"dynamic"))
4521 peer->
expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
4527 reg_source_db(peer);
4535 memset(&peer->addr, 0,
sizeof(peer->addr));
4536 realtime_update_peer(peer->name, &peer->addr, 0);
4537 ast_debug(1,
"realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
4538 peername, (
int)(nowtime - regseconds), (
int)regseconds, (
int)nowtime);
4541 ast_debug(1,
"realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
4542 peername, (
int)(nowtime - regseconds), (
int)regseconds, (
int)nowtime);
4554 char *str_addr, *str_port;
4559 var = ast_load_realtime(
"iaxusers",
"name", username,
"host",
"dynamic", SENTINEL);
4561 var = ast_load_realtime(
"iaxusers",
"name", username,
"host", str_addr, SENTINEL);
4563 var = ast_load_realtime(
"iaxusers",
"name", username,
"ipaddr", str_addr,
"port", str_port, SENTINEL);
4565 var = ast_load_realtime(
"iaxusers",
"ipaddr", str_addr,
"port", str_port, SENTINEL);
4568 var = ast_load_realtime(
"iaxusers",
"name", username, SENTINEL);
4576 for (tmp = var; tmp; tmp = tmp->
next) {
4577 if (!strcasecmp(tmp->
name,
"host")) {
4598 if (!strcasecmp(tmp->
name,
"type")) {
4599 if (strcasecmp(tmp->
value,
"friend") &&
4600 strcasecmp(tmp->
value,
"user")) {
4624 static void realtime_update_peer(
const char *peername,
struct ast_sockaddr *sockaddr, time_t regtime)
4626 char regseconds[20];
4627 const char *sysname = ast_config_AST_SYSTEM_NAME;
4628 char *syslabel = NULL;
4631 if (ast_strlen_zero(sysname))
4634 syslabel =
"regserver";
4636 snprintf(regseconds,
sizeof(regseconds),
"%d", (
int)regtime);
4641 "regseconds", regseconds, syslabel, sysname, SENTINEL);
4672 cai->sockfd = defaultsockfd;
4678 peer_addr.ss.ss_family = AST_AF_UNSPEC;
4681 ast_log(LOG_WARNING,
"No such host: %s\n", peername);
4695 cai->prefs = prefs_global;
4701 ast_channel_nativeformats(c), i);
4723 cai->maxtime = peer->
maxms;
4727 cai->sockfd = peer->
sockfd;
4728 cai->adsi = peer->adsi;
4729 cai->prefs = peer->prefs;
4736 ast_channel_nativeformats(c), i);
4745 ast_copy_string(cai->username, peer->username,
sizeof(cai->username));
4750 ast_copy_string(cai->mohinterpret, peer->mohinterpret,
sizeof(cai->mohinterpret));
4751 ast_copy_string(cai->mohsuggest, peer->mohsuggest,
sizeof(cai->mohsuggest));
4752 if (ast_strlen_zero(peer->dbsecret)) {
4759 key = strchr(family,
'/');
4762 if (!key ||
ast_db_get(family, key, cai->secret,
sizeof(cai->secret))) {
4763 ast_log(LOG_WARNING,
"Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
4782 static void __auto_congest(
const void *nothing)
4784 int callno = PTR_TO_CALLNO(nothing);
4786 ast_mutex_lock(&iaxsl[callno]);
4788 iaxs[callno]->
initid = -1;
4790 ast_log(LOG_NOTICE,
"Auto-congesting call due to slow response\n");
4792 ast_mutex_unlock(&iaxsl[callno]);
4795 static int auto_congest(
const void *data)
4797 #ifdef SCHED_MULTITHREADED
4798 if (schedule_action(__auto_congest, data))
4800 __auto_congest(data);
4804 static unsigned int iax2_datetime(
const char *tz)
4810 tmp = (tm.tm_sec >> 1) & 0x1f;
4811 tmp |= (tm.tm_min & 0x3f) << 5;
4812 tmp |= (tm.tm_hour & 0x1f) << 11;
4813 tmp |= (tm.tm_mday & 0x1f) << 16;
4814 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
4815 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
4830 static int send_apathetic_reply(
unsigned short callno,
unsigned short dcallno,
4831 struct ast_sockaddr *addr,
int command,
int ts,
unsigned char seqno,
4842 memcpy(&data.ied, ied->buf, ied->pos);
4845 data.f.scallno = htons(0x8000 | callno);
4846 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS);
4847 data.f.ts = htonl(ts);
4848 data.f.iseqno = seqno;
4851 data.f.csub = compress_subclass(command);
4853 iax_outputframe(NULL, &data.f, 0, addr, size -
sizeof(
struct ast_iax2_full_hdr));
4855 return ast_sendto(sockfd, &data, size, 0, addr);
4861 if (pvt && ied && (2 < ((
int)
sizeof(ied->buf) - ied->pos))) {
4863 ied->buf[ied->pos++] = 0;
4868 static void resend_with_token(
int callno,
struct iax_frame *f,
const char *newtoken)
4900 (f->
datalen >
sizeof(data))) {
4920 data.ied.pos = ie_data_pos;
4942 remove_by_peercallno(pvt);
4947 send_command(pvt,
AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
4950 static void requirecalltoken_mark_auto(
const char *name,
int subclass)
4955 if (ast_strlen_zero(name)) {
4993 #define CALLTOKEN_HASH_FORMAT "%s%u%d"
4994 #define CALLTOKEN_IE_FORMAT "%u?%s"
4995 struct ast_str *buf = ast_str_alloca(256);
4996 time_t t = time(NULL);
4998 int subclass = uncompress_subclass(fh->
csub);
5001 if (ies->calltoken && !ies->calltokendata) {
5011 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (
unsigned int) t, hash);
5018 }
else if (ies->calltoken && ies->calltokendata) {
5019 char *rec_hash = NULL;
5020 char *rec_ts = NULL;
5021 unsigned int rec_time;
5024 rec_hash = strchr((
char *) ies->calltokendata,
'?');
5027 rec_ts = (
char *) ies->calltokendata;
5031 if (!rec_hash || !rec_ts) {
5033 }
else if (sscanf(rec_ts,
"%u", &rec_time) != 1) {
5042 if (strcmp(hash, rec_hash)) {
5045 }
else if ((t < rec_time) || ((t - rec_time) >= max_calltoken_delay)) {
5046 ast_log(LOG_WARNING,
"Too much delay in IAX2 calltoken timestamp from address %s\n",
ast_sockaddr_stringify(addr));
5052 requirecalltoken_mark_auto(ies->username, subclass);
5057 if (calltoken_required(addr, ies->username, subclass)) {
5058 ast_log(LOG_ERROR,
"Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n",
ast_sockaddr_stringify(addr),
S_OR(ies->username,
"guest"));
5069 send_apathetic_reply(1, ntohs(fh->
scallno), addr, IAX_COMMAND_REJECT, ntohl(fh->
ts), fh->
iseqno + 1, fd, NULL);
5094 char *outkey = NULL;
5096 if (ast_strlen_zero(data))
5099 pds->peer = strsep(&data,
"/");
5100 pds->exten = strsep(&data,
"/");
5101 pds->options = data;
5105 pds->exten = strsep(&data,
"@");
5106 pds->context = data;
5109 if (strchr(pds->peer,
'@')) {
5111 pds->username = strsep(&data,
"@");
5115 if (pds->username) {
5116 data = pds->username;
5117 pds->username = strsep(&data,
":");
5118 pds->password = strsep(&data,
":");
5123 pds->peer = strsep(&data,
":");
5133 if (pds->password && (pds->password[0] ==
'[')) {
5135 if (ast_strlen_zero(outkey)) {
5136 pds->password = NULL;
5137 ast_debug(1,
"Outkey (%s), no secret\n", pds->key);
5139 pds->password = outkey;
5140 ast_debug(1,
"Outkey (%s) and secret (%s)\n", pds->key, pds->password);
5142 }
else if (outkey && (outkey[0] ==
'[')) {
5144 if (ast_strlen_zero(pds->password)) {
5145 ast_debug(1,
"Outkey (%s), no secret\n", pds->key);
5147 ast_debug(1,
"Outkey (%s) and secret (%s)\n", pds->key, pds->password);
5152 static int iax2_call(
struct ast_channel *c,
const char *dest,
int timeout)
5155 char *l=NULL, *n=NULL, *tmpstr;
5157 char *defaultrdest =
"s";
5158 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5163 const char* osp_token_ptr;
5164 unsigned int osp_token_length;
5165 unsigned char osp_block_index;
5166 unsigned int osp_block_length;
5167 unsigned char osp_buffer[256];
5168 char encoded_prefs[32];
5172 ast_log(LOG_WARNING,
"Channel is already in use (%s)?\n", ast_channel_name(c));
5176 memset(&cai, 0,
sizeof(cai));
5177 cai.encmethods = iax2_encryption;
5178 cai.authmethods = iax2_authmethods;
5180 memset(&pds, 0,
sizeof(pds));
5184 if (ast_strlen_zero(pds.peer)) {
5185 ast_log(LOG_WARNING,
"No peer provided in the IAX2 dial string '%s'\n", dest);
5189 pds.exten = defaultrdest;
5191 if (create_addr(pds.peer, c, &addr, &cai)) {
5192 ast_log(LOG_WARNING,
"No address associated with '%s'\n", pds.peer);
5198 if (!cai.encmethods) {
5199 ast_log(LOG_WARNING,
"Encryption forced for call, but not enabled\n");
5200 ast_channel_hangupcause_set(c, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
5203 if (((cai.authmethods & IAX_AUTH_RSA) || (cai.authmethods & IAX_AUTH_MD5) || (cai.authmethods & IAX_AUTH_PLAINTEXT)) &&
5204 ast_strlen_zero(cai.secret) && ast_strlen_zero(pds.password)) {
5205 ast_log(LOG_WARNING,
"Call terminated. Encryption forced but no secret provided\n");
5210 if (!pds.username && !ast_strlen_zero(cai.username))
5211 pds.username = cai.username;
5212 if (!pds.password && !ast_strlen_zero(cai.secret))
5213 pds.password = cai.secret;
5214 if (!pds.key && !ast_strlen_zero(cai.outkey))
5215 pds.key = cai.outkey;
5216 if (!pds.context && !ast_strlen_zero(cai.peercontext))
5217 pds.context = cai.peercontext;
5220 ast_channel_context_set(c, cai.context);
5224 if (
ast_parse_arg(pds.port, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535)) {
5233 memset(&ied, 0,
sizeof(ied));
5238 if (pds.options && strchr(pds.options,
'a')) {
5259 iax_ie_append_short(&ied,
IAX_IE_CALLINGTNS, ast_channel_dialed(c)->transit_network_select);
5265 && ast_channel_connected(c)->ani.number.valid
5266 && ast_channel_connected(c)->ani.number.str) {
5267 iax_ie_append_str(&ied,
IAX_IE_CALLING_ANI, ast_channel_connected(c)->ani.number.str);
5270 if (!ast_strlen_zero(ast_channel_language(c)))
5272 if (!ast_strlen_zero(ast_channel_dialed(c)->
number.str)) {
5275 if (ast_channel_redirecting(c)->from.number.valid
5276 && !ast_strlen_zero(ast_channel_redirecting(c)->from.number.str)) {
5277 iax_ie_append_str(&ied,
IAX_IE_RDNIS, ast_channel_redirecting(c)->from.number.str);
5289 ast_mutex_lock(&iaxsl[callno]);
5291 if (!ast_strlen_zero(ast_channel_context(c)))
5299 iaxs[callno]->adsi = cai.adsi;
5311 iax_ie_append_versioned_uint64(&ied,
IAX_IE_FORMAT2, 0, iax2_tmpfmt);
5314 iax_ie_append_versioned_uint64(&ied,
IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
5315 iax_ie_append_short(&ied,
IAX_IE_ADSICPE, ast_channel_adsicpe(c));
5316 iax_ie_append_int(&ied,
IAX_IE_DATETIME, iax2_datetime(cai.timezone));
5318 if (iaxs[callno]->maxtime) {
5321 iaxs[callno]->
initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
5322 }
else if (autokill) {
5323 iaxs[callno]->
pingtime = autokill / 2;
5324 iaxs[callno]->
initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
5329 if (!ast_strlen_zero(osp_token_ptr)) {
5330 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
5331 osp_block_index = 0;
5332 while (osp_token_length > 0) {
5334 osp_buffer[0] = osp_block_index;
5335 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
5336 iax_ie_append_raw(&ied,
IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
5338 osp_token_ptr += osp_block_length;
5339 osp_token_length -= osp_block_length;
5342 ast_log(LOG_WARNING,
"OSP token is too long\n");
5343 }
else if (iaxdebug)
5344 ast_debug(1,
"OSP token is undefined\n");
5347 iaxs[callno]->
sockfd = cai.sockfd;
5350 if (variablestore) {
5352 ast_debug(1,
"Found an IAX variable store on this channel\n");
5357 ast_debug(1,
"Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
5359 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
5360 snprintf(tmp,
sizeof(tmp),
"%s=%s", ast_var_name(var), ast_var_value(var) + i);
5368 add_empty_calltoken_ie(iaxs[callno], &ied);
5369 send_command(iaxs[callno],
AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
5371 ast_mutex_unlock(&iaxsl[callno]);
5379 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5382 memset(&ied, 0,
sizeof(ied));
5383 ast_mutex_lock(&iaxsl[callno]);
5384 if (callno && iaxs[callno]) {
5385 ast_debug(1,
"We're hanging up %s now...\n", ast_channel_name(c));
5388 iax_ie_append_byte(&ied,
IAX_IE_CAUSECODE, (
unsigned char)ast_channel_hangupcause(c));
5389 if (!iaxs[callno]->error && !alreadygone) {
5391 ast_log(LOG_WARNING,
"No final packet could be sent for callno %d\n", callno);
5393 if (!iaxs[callno]) {
5394 ast_mutex_unlock(&iaxsl[callno]);
5401 if (iaxs[callno] && alreadygone) {
5402 ast_debug(1,
"Really destroying %s now...\n", ast_channel_name(c));
5403 iax2_destroy(callno);
5404 }
else if (iaxs[callno]) {
5405 if (
ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
5406 ast_log(LOG_ERROR,
"Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
5407 iax2_destroy(callno);
5410 }
else if (ast_channel_tech_pvt(c)) {
5415 ast_channel_tech_pvt_set(c, NULL);
5417 ast_mutex_unlock(&iaxsl[callno]);
5418 ast_verb(3,
"Hungup '%s'\n", ast_channel_name(c));
5427 unsigned short callno = pvt->
callno;
5433 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
5444 static int iax2_setoption(
struct ast_channel *c,
int option,
void *data,
int datalen)
5455 case AST_OPTION_OPRMODE:
5459 case AST_OPTION_SECURE_MEDIA:
5461 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5462 ast_mutex_lock(&iaxsl[callno]);
5463 if ((*(
int *) data)) {
5468 ast_mutex_unlock(&iaxsl[callno]);
5482 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5485 ast_mutex_lock(&iaxsl[callno]);
5489 ast_mutex_unlock(&iaxsl[callno]);
5493 ast_mutex_unlock(&iaxsl[callno]);
5495 if (!(h =
ast_malloc(datalen +
sizeof(*h)))) {
5499 h->flag = AST_OPTION_FLAG_REQUEST;
5500 h->option = htons(option);
5501 memcpy(h->data, data, datalen);
5502 res = send_command_locked(PTR_TO_CALLNO(ast_channel_tech_pvt(c)),
AST_FRAME_CONTROL,
5504 datalen +
sizeof(*h), -1);
5516 static int iax2_queryoption(
struct ast_channel *c,
int option,
void *data,
int *datalen)
5520 case AST_OPTION_SECURE_MEDIA:
5522 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5523 ast_mutex_lock(&iaxsl[callno]);
5525 ast_mutex_unlock(&iaxsl[callno]);
5535 ast_debug(1,
"I should never be called!\n");
5539 static int iax2_key_rotate(
const void *vpvt)
5549 ast_mutex_lock(&iaxsl[pvt->
callno]);
5552 snprintf(key,
sizeof(key),
"%lX", (
unsigned long)ast_random());
5555 MD5Update(&md5, (
unsigned char *) key, strlen(key));
5556 MD5Final((
unsigned char *) key, &md5);
5558 IAX_DEBUGDIGEST(
"Sending", key);
5564 build_ecx_key((
unsigned char *) key, pvt);
5566 ast_mutex_unlock(&iaxsl[pvt->
callno]);
5571 #if defined(IAX2_NATIVE_BRIDGING)
5572 static int iax2_start_transfer(
unsigned short callno0,
unsigned short callno1,
int mediaonly)
5577 unsigned int transferid = (
unsigned int)ast_random();
5579 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
5580 ast_debug(1,
"transfers are not supported for encrypted calls at this time\n");
5586 memset(&ied0, 0,
sizeof(ied0));
5588 iax_ie_append_short(&ied0,
IAX_IE_CALLNO, iaxs[callno1]->peercallno);
5591 memset(&ied1, 0,
sizeof(ied1));
5593 iax_ie_append_short(&ied1,
IAX_IE_CALLNO, iaxs[callno0]->peercallno);
5602 iaxs[callno0]->
transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
5603 iaxs[callno1]->
transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
5608 #if defined(IAX2_NATIVE_BRIDGING)
5609 static void lock_both(
unsigned short callno0,
unsigned short callno1)
5611 ast_mutex_lock(&iaxsl[callno0]);
5612 while (ast_mutex_trylock(&iaxsl[callno1])) {
5613 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
5618 #if defined(IAX2_NATIVE_BRIDGING)
5619 static void unlock_both(
unsigned short callno0,
unsigned short callno1)
5621 ast_mutex_unlock(&iaxsl[callno1]);
5622 ast_mutex_unlock(&iaxsl[callno0]);
5626 #if defined(IAX2_NATIVE_BRIDGING)
5633 int transferstarted=0;
5635 unsigned short callno0 = PTR_TO_CALLNO(ast_channel_tech_pvt(c0));
5636 unsigned short callno1 = PTR_TO_CALLNO(ast_channel_tech_pvt(c1));
5637 struct timeval waittimer = {0, 0};
5640 if (timeoutms > 0) {
5641 return AST_BRIDGE_FAILED;
5646 lock_both(callno0, callno1);
5647 if (!iaxs[callno0] || !iaxs[callno1]) {
5648 unlock_both(callno0, callno1);
5649 return AST_BRIDGE_FAILED;
5656 unlock_both(callno0, callno1);
5664 ast_verb(3,
"Can't masquerade, we're different...\n");
5667 ast_mutex_lock(&iaxsl[callno0]);
5669 ast_mutex_unlock(&iaxsl[callno0]);
5672 ast_mutex_lock(&iaxsl[callno1]);
5674 ast_mutex_unlock(&iaxsl[callno1]);
5676 return AST_BRIDGE_FAILED_NOWARN;
5682 ast_verb(3,
"Operating with different codecs [%s] [%s] , can't native bridge...\n",
5687 lock_both(callno0, callno1);
5692 unlock_both(callno0, callno1);
5693 return AST_BRIDGE_FAILED_NOWARN;
5700 ast_log(LOG_WARNING,
"Unable to start the transfer\n");
5701 transferstarted = 1;
5703 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
5713 res = AST_BRIDGE_COMPLETE;
5724 if (timeoutms > -1) {
5725 timeoutms -= (1000 - to);
5731 res = AST_BRIDGE_RETRY;
5735 res = AST_BRIDGE_FAILED;
5744 res = AST_BRIDGE_COMPLETE;
5747 other = (who == c0) ? c1 : c0;
5762 res = AST_BRIDGE_COMPLETE;
5765 if (res == AST_BRIDGE_COMPLETE) {
5773 }
else if (f->
frametype == AST_FRAME_DTMF) {
5779 if (flags & monitored_source) {
5782 res = AST_BRIDGE_COMPLETE;
5794 lock_both(callno0, callno1);
5799 unlock_both(callno0, callno1);
5806 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5811 static int iax2_indicate(
struct ast_channel *c,
int condition,
const void *data,
size_t datalen)
5813 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5818 ast_debug(1,
"Indicating condition %d\n", condition);
5820 ast_mutex_lock(&iaxsl[callno]);
5828 switch (condition) {
5830 if (strcasecmp(pvt->mohinterpret,
"passthrough")) {
5836 if (strcasecmp(pvt->mohinterpret,
"passthrough")) {
5845 ast_debug(2,
"Callno %d: Config blocked sending control frame %d.\n",
5859 ast_mutex_unlock(&iaxsl[callno]);
5864 static int iax2_transfer(
struct ast_channel *c,
const char *dest)
5866 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
5868 char tmp[256], *context;
5871 context = strchr(tmp,
'@');
5879 ast_debug(1,
"Transferring '%s' to '%s'\n", ast_channel_name(c), dest);
5891 while ((peer = ao2_iterator_next(&i))) {
5908 const struct ast_channel *requestor,
unsigned int cachable)
5917 char *peer_name = NULL;
5919 if (!(i = iaxs[callno])) {
5920 ast_log(LOG_WARNING,
"No IAX2 pvt found for callno '%d' !\n", callno);
5925 ast_log(LOG_WARNING,
"No formats specified for call to: IAX2/%s-%d\n",
5935 ast_log(LOG_WARNING,
"No requested formats available for call to: IAX2/%s-%d\n",
5941 if (!ast_strlen_zero(i->
peer)) {
5943 }
else if (!ast_strlen_zero(i->
host)) {
5948 ast_mutex_unlock(&iaxsl[callno]);
5950 if (!ast_strlen_zero(peer_name)) {
5953 tmp = ast_channel_alloc_with_endpoint(1, state, i->
cid_num, i->cid_name,
5954 i->accountcode, i->
exten, i->
context, assignedids, requestor,
5962 i->
exten, i->
context, assignedids, requestor, i->amaflags,
"IAX2/%s-%d",
5966 ast_mutex_lock(&iaxsl[callno]);
5967 if (i != iaxs[callno]) {
5970 ast_mutex_unlock(&iaxsl[callno]);
5971 ast_channel_unlock(tmp);
5973 ast_mutex_lock(&iaxsl[callno]);
5985 if ((callid = iaxs[callno]->callid)) {
5989 ast_channel_tech_set(tmp, &iax2_tech);
5992 ast_channel_nativeformats_set(tmp, native);
5995 ast_channel_set_readformat(tmp, tmpfmt);
5996 ast_channel_set_rawreadformat(tmp, tmpfmt);
5997 ast_channel_set_writeformat(tmp, tmpfmt);
5998 ast_channel_set_rawwriteformat(tmp, tmpfmt);
6003 ast_channel_tech_pvt_set(tmp, CALLNO_TO_PTR(i->
callno));
6006 ast_channel_parkinglot_set(tmp, i->
parkinglot);
6009 if (!ast_strlen_zero(i->
ani)) {
6012 }
else if (!ast_strlen_zero(i->
cid_num)) {
6017 if (!ast_strlen_zero(i->
rdnis)) {
6021 ast_channel_caller(tmp)->
ani2 = i->calling_ani2;
6024 ast_channel_caller(tmp)->
id.
number.
plan = i->calling_ton;
6027 ast_channel_language_set(tmp, i->
language);
6028 if (!ast_strlen_zero(i->accountcode))
6029 ast_channel_accountcode_set(tmp, i->accountcode);
6032 ast_channel_context_set(tmp, i->
context);
6033 ast_channel_exten_set(tmp, i->
exten);
6037 ast_channel_adsicpe_set(tmp, AST_ADSI_UNAVAILABLE);
6047 for (v = i->
vars ; v ; v = v->
next)
6054 ast_debug(1,
"Loading up the channel with IAXVARs\n");
6056 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
6057 if (variablestore && varlist) {
6058 variablestore->
data = varlist;
6059 variablestore->
inheritance = DATASTORE_INHERIT_FOREVER;
6068 ast_log(LOG_ERROR,
"Memory allocation error while processing IAX2 variables\n");
6078 if (variablestore) {
6088 ast_channel_unlock(tmp);
6092 ast_log(LOG_WARNING,
"Unable to start PBX on %s\n", ast_channel_name(tmp));
6094 ast_mutex_unlock(&iaxsl[callno]);
6096 ast_mutex_lock(&iaxsl[callno]);
6105 static unsigned int calc_txpeerstamp(
struct iax2_trunk_peer *tpeer,
int sampms,
struct timeval *now)
6107 unsigned long int mssincetx;
6134 static unsigned int fix_peerts(
struct timeval *
rxtrunktime,
int callno,
unsigned int ts)
6141 iaxs[callno]->
rxcore.tv_usec -= iaxs[callno]->
rxcore.tv_usec % 20000;
6156 struct timeval *delivery = NULL;
6219 else if (adjust > 0)
6239 ast_debug(1,
"predicted timestamp skew (%d) > max (%d), using real ts instead.\n",
6244 int diff = ms % (f->
samples / rate);
6261 if ( (
unsigned int)ms < p->
lastsent )
6269 if (ms <= p->lastsent)
6284 static unsigned int calc_rxstamp(
struct chan_iax2_pvt *p,
unsigned int offset)
6296 ast_debug(1,
"calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %ums\n",
6301 ast_debug(1,
"calc_rxstamp: call=%d: works out as %d.%6.6d\n",
6309 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
6310 jit = (int)((
float)test_jit * ast_random() / (RAND_MAX + 1.0));
6311 if ((
int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
6333 ast_mutex_lock(&tpeer->lock);
6339 if ((tpeer =
ast_calloc(1,
sizeof(*tpeer)))) {
6340 ast_mutex_init(&tpeer->lock);
6344 ast_mutex_lock(&tpeer->lock);
6348 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums,
sizeof(nochecksums));
6373 if (tpeer->trunkdatalen + f->
datalen + 4 >= tpeer->trunkdataalloc) {
6375 if (tpeer->trunkdataalloc < trunkmaxsize) {
6377 ast_mutex_unlock(&tpeer->lock);
6382 tpeer->trunkdata = tmp;
6386 ast_mutex_unlock(&tpeer->lock);
6392 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
6397 mtm->
mini.
ts = htons(0xffff & fr->
ts);
6411 tpeer->trunkdatalen += f->
datalen;
6416 if (tpeer->trunkdatalen + f->
datalen + 4 > trunk_maxmtu)
6417 trunk_maxmtu = tpeer->trunkdatalen + f->
datalen + 4 ;
6422 send_trunk(tpeer, &now);
6426 ast_mutex_unlock(&tpeer->lock);
6433 static void build_rand_pad(
unsigned char *buf, ssize_t len)
6436 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
6437 memcpy(buf, (
unsigned char *) &tmp, (len >
sizeof(tmp)) ?
sizeof(tmp) : len);
6447 for (i = 0; i < 60; i++) {
6459 static void build_encryption_keys(
const unsigned char *digest,
struct chan_iax2_pvt *pvt)
6461 build_ecx_key(digest, pvt);
6462 ast_aes_set_decrypt_key(digest, &pvt->
dcx);
6465 static void build_ecx_key(
const unsigned char *digest,
struct chan_iax2_pvt *pvt)
6471 ast_aes_set_encrypt_key(digest, &pvt->
ecx);
6472 ast_aes_set_decrypt_key(digest, &pvt->
mydcx);
6475 static void memcpy_decrypt(
unsigned char *dst,
const unsigned char *src,
int len,
ast_aes_decrypt_key *dcx)
6481 ast_log(LOG_WARNING,
"len should be multiple of 16, not %d!\n", len);
6483 dst[x] = src[x] ^ 0xff;
6485 unsigned char lastblock[16] = { 0 };
6488 ast_aes_decrypt(src, dst, dcx);
6490 dst[x] ^= lastblock[x];
6491 memcpy(lastblock, src,
sizeof(lastblock));
6499 static void memcpy_encrypt(
unsigned char *dst,
const unsigned char *src,
int len,
ast_aes_encrypt_key *ecx)
6505 ast_log(LOG_WARNING,
"len should be multiple of 16, not %d!\n", len);
6507 dst[x] = src[x] ^ 0xff;
6509 unsigned char curblock[16] = { 0 };
6513 curblock[x] ^= src[x];
6514 ast_aes_encrypt(curblock, dst, ecx);
6515 memcpy(curblock, dst,
sizeof(curblock));
6526 unsigned char *workspace;
6529 memset(f, 0,
sizeof(*f));
6530 if (ntohs(fh->
scallno) & IAX_FLAG_FULL) {
6537 padding = 16 + (workspace[15] & 0x0f);
6539 ast_debug(1,
"Decoding full frame with length %d (padding = %d) (15=%02hhx)\n", *datalen, padding, workspace[15]);
6543 *datalen -= padding;
6562 ast_debug(5,
"Decoding mini with length %d\n", *datalen);
6567 padding = 16 + (workspace[15] & 0x0f);
6570 *datalen -= padding;
6579 unsigned char *workspace;
6581 if (ntohs(fh->
scallno) & IAX_FLAG_FULL) {
6584 ast_debug(1,
"Encoding full frame %d/%d with length %d\n", fh->
type, fh->
csub, *datalen);
6586 padding = 16 + (padding & 0xf);
6587 memcpy(workspace, poo, padding);
6589 workspace[15] &= 0xf0;
6590 workspace[15] |= (padding & 0xf);
6592 ast_debug(1,
"Encoding full frame %d/%d with length %d + %d padding (15=%02hhx)\n", fh->
type, fh->
csub, *datalen, padding, workspace[15]);
6593 *datalen += padding;
6596 memcpy(poo, workspace + *datalen - 32, 32);
6600 ast_debug(5,
"Encoding mini frame with length %d\n", *datalen);
6602 padding = 16 + (padding & 0xf);
6603 memcpy(workspace, poo, padding);
6605 workspace[15] &= 0xf0;
6606 workspace[15] |= (padding & 0x0f);
6607 *datalen += padding;
6610 memcpy(poo, workspace + *datalen - 32, 32);
6621 unsigned char digest[16];
6622 char *tmppw, *stringp;
6626 while ((tmppw = strsep(&stringp,
";"))) {
6628 MD5Update(&md5, (
unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
6629 MD5Update(&md5, (
unsigned char *)tmppw, strlen(tmppw));
6630 MD5Final(digest, &md5);
6631 build_encryption_keys(digest, iaxs[callno]);
6632 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
6639 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
6643 static int iax2_send(
struct chan_iax2_pvt *pvt,
struct ast_frame *f,
unsigned int ts,
int seqno,
int now,
int transfer,
int final)
6653 unsigned char buffer[4096];
6661 frb.fr2.afdatalen =
sizeof(frb.buffer);
6664 ast_log(LOG_WARNING,
"No private structure for packet?\n");
6671 fts = calc_timestamp(pvt, ts, f);
6680 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
6682 IAX_CALLENCRYPTED(pvt) ?
"" :
"not ",
6687 iax2_key_rotate(pvt);
6691 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
6692 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
6710 if (((fts & 0xFFFF8000L) == (pvt->
lastvsent & 0xFFFF8000L)) &&
6735 ast_log(LOG_WARNING,
"Out of memory\n");
6739 iax_frame_wrap(fr, f);
6755 fh->
ts = htonl(fr->
ts);
6769 fh->
csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6));
6809 ast_log(LOG_WARNING,
"Supposed to send packet encrypted, but no key?\n");
6813 res = send_packet(fr);
6815 res = iax2_transmit(fr);
6818 iax2_trunk_queue(pvt, fr);
6831 res = send_packet(fr);
6839 mh->
ts = htons(fr->
ts & 0xFFFF);
6849 ast_log(LOG_WARNING,
"Supposed to send packet encrypted, but no key?\n");
6851 res = send_packet(fr);
6860 int havepattern = 0;
6862 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
6863 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
6872 e->
command =
"iax2 show users [like]";
6874 "Usage: iax2 show users [like <pattern>]\n"
6875 " Lists all known IAX2 users.\n"
6876 " Optional regular expression pattern is used to filter the user list.\n";
6884 if (!strcasecmp(a->argv[3],
"like")) {
6885 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
6886 return CLI_SHOWUSAGE;
6889 return CLI_SHOWUSAGE;
6893 return CLI_SHOWUSAGE;
6896 ast_cli(a->fd, FORMAT,
"Username",
"Secret",
"Authen",
"Def.Context",
"A/C",
"Codec Pref");
6898 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
6899 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
6902 if (!ast_strlen_zero(user->secret)) {
6904 }
else if (!ast_strlen_zero(user->
inkeys)) {
6905 snprintf(auth,
sizeof(auth),
"Key: %-15.15s ", user->
inkeys);
6916 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
6917 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
6939 int unmonitored_peers;
6942 #define PEERS_FORMAT2 "%-15.15s %-40.40s %s %-40.40s %-9s %s %-11s %-32.32s\n"
6943 #define PEERS_FORMAT "%-15.15s %-40.40s %s %-40.40s %-6s%s %s %-11s %-32.32s\n"
6947 char name[256] =
"";
6950 struct ast_str *encmethods = ast_str_alloca(256);
6952 char *tmp_host, *tmp_mask, *tmp_port;
6958 if (!ast_strlen_zero(peer->username)) {
6959 snprintf(name,
sizeof(name),
"%s/%s", peer->name, peer->username);
6964 encmethods_to_str(peer->
encmethods, &encmethods);
6965 retstatus =
peer_status(peer, status,
sizeof(status));
6966 if (retstatus > 0) {
6967 cont->online_peers++;
6968 }
else if (!retstatus) {
6969 cont->offline_peers++;
6971 cont->unmonitored_peers++;
6975 if (cont->peerlist) {
6977 "Event: PeerEntry\r\n%s"
6978 "Channeltype: IAX\r\n",
6980 if (!ast_strlen_zero(peer->username)) {
6982 "ObjectName: %s\r\n"
6983 "ObjectUsername: %s\r\n",
6988 "ObjectName: %s\r\n",
6993 "Event: PeerEntry\r\n%s"
6994 "Channeltype: IAX2\r\n"
6995 "ObjectName: %s\r\n",
7000 "ChanObjectType: peer\r\n"
7001 "IPaddress: %s\r\n",
7003 if (cont->peerlist) {
7017 "Encryption: %s\r\n"
7019 ast_test_flag64(peer,
IAX_DYNAMIC) ?
"yes" :
"no",
7020 ast_test_flag64(peer,
IAX_TRUNK) ?
"yes" :
"no",
7023 if (cont->peerlist) {
7027 "Description: %s\r\n\r\n",
7031 ast_cli(fd, PEERS_FORMAT,
7034 ast_test_flag64(peer,
IAX_DYNAMIC) ?
"(D)" :
"(S)",
7037 ast_test_flag64(peer,
IAX_TRUNK) ?
"(T)" :
" ",
7043 cont->total_peers++;
7046 static int __iax2_show_peers(
int fd,
int *total,
struct mansession *s,
const int argc,
const char *
const argv[])
7051 .registeredonly = 0,
7058 .unmonitored_peers = 0,
7067 if (!strcasecmp(argv[3],
"registered"))
7068 cont.registeredonly = 1;
7070 return RESULT_SHOWUSAGE;
7071 if (!strcasecmp(argv[4],
"like")) {
7072 if (regcomp(&cont.regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
7073 return RESULT_SHOWUSAGE;
7074 cont.havepattern = 1;
7076 return RESULT_SHOWUSAGE;
7079 if (!strcasecmp(argv[3],
"like")) {
7080 if (regcomp(&cont.regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
7081 return RESULT_SHOWUSAGE;
7082 cont.havepattern = 1;
7084 return RESULT_SHOWUSAGE;
7087 if (!strcasecmp(argv[3],
"registered")) {
7088 cont.registeredonly = 1;
7090 return RESULT_SHOWUSAGE;
7096 return RESULT_SHOWUSAGE;
7101 ast_cli(fd, PEERS_FORMAT2,
"Name/Username",
"Host",
" ",
"Mask",
"Port",
" ",
"Status",
"Description");
7105 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
7110 if (cont.havepattern && regexec(&cont.regexbuf, peer->name, 0, NULL, 0)) {
7114 _iax2_show_peers_one(fd, s, &cont, peer);
7120 ast_cli(fd,
"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
7121 cont.total_peers, cont.online_peers, cont.offline_peers, cont.unmonitored_peers);
7124 if (cont.havepattern) {
7125 regfree(&cont.regexbuf);
7129 *total = cont.total_peers;
7132 return RESULT_SUCCESS;
7135 #undef PEERS_FORMAT2
7142 int threadcount = 0, dynamiccount = 0;
7147 e->
command =
"iax2 show threads";
7149 "Usage: iax2 show threads\n"
7150 " Lists status of IAX helper threads\n";
7156 return CLI_SHOWUSAGE;
7158 ast_cli(a->fd,
"IAX2 Thread Information\n");
7160 ast_cli(a->fd,
"Idle Threads:\n");
7163 #ifdef DEBUG_SCHED_MULTITHREAD
7164 ast_cli(a->fd,
"Thread %d: state=%u, update=%d, actions=%d, func='%s'\n",
7165 thread->threadnum, thread->iostate, (
int)(t - thread->checktime), thread->actions, thread->curfunc);
7167 ast_cli(a->fd,
"Thread %d: state=%u, update=%d, actions=%d\n",
7168 thread->threadnum, thread->iostate, (
int)(t - thread->checktime), thread->actions);
7173 ast_cli(a->fd,
"Active Threads:\n");
7176 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
7180 #ifdef DEBUG_SCHED_MULTITHREAD
7181 ast_cli(a->fd,
"Thread %c%d: state=%u, update=%d, actions=%d, func='%s'\n",
7182 type, thread->threadnum, thread->iostate, (
int)(t - thread->checktime), thread->actions, thread->curfunc);
7184 ast_cli(a->fd,
"Thread %c%d: state=%u, update=%d, actions=%d\n",
7185 type, thread->threadnum, thread->iostate, (
int)(t - thread->checktime), thread->actions);
7190 ast_cli(a->fd,
"Dynamic Threads:\n");
7193 #ifdef DEBUG_SCHED_MULTITHREAD
7194 ast_cli(a->fd,
"Thread %d: state=%u, update=%d, actions=%d, func='%s'\n",
7195 thread->threadnum, thread->iostate, (
int)(t - thread->checktime), thread->actions, thread->curfunc);
7197 ast_cli(a->fd,
"Thread %d: state=%u, update=%d, actions=%d\n",
7198 thread->threadnum, thread->iostate, (
int)(t - thread->checktime), thread->actions);
7203 ast_cli(a->fd,
"%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
7213 e->
command =
"iax2 unregister";
7215 "Usage: iax2 unregister <peername>\n"
7216 " Unregister (force expiration) an IAX2 peer from the registry.\n";
7219 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
7223 return CLI_SHOWUSAGE;
7230 peer = ao2_find(peers, a->argv[2],
OBJ_KEY);
7232 expire_registry(peer_ref(peer));
7234 ast_cli(a->fd,
"Peer %s unregistered\n", a->argv[2]);
7236 ast_cli(a->fd,
"Peer %s not found\n", a->argv[2]);
7239 ast_cli(a->fd,
"Peer %s not registered\n", a->argv[2]);
7243 ast_cli(a->fd,
"Peer unknown: %s. Not unregistered\n", a->argv[2]);
7248 static char *complete_iax2_unregister(
const char *line,
const char *word,
int pos,
int state)
7253 int wordlen = strlen(word);
7258 while ((p = ao2_iterator_next(&i))) {
7259 if (!strncasecmp(p->name, word, wordlen) &&
7260 ++which > state && p->
expire > -1) {
7277 e->
command =
"iax2 show peers";
7279 "Usage: iax2 show peers [registered] [like <pattern>]\n"
7280 " Lists all known IAX2 peers.\n"
7281 " Optional 'registered' argument lists only peers with known addresses.\n"
7282 " Optional regular expression pattern is used to filter the peer list.\n";
7288 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
7289 case RESULT_SHOWUSAGE:
7290 return CLI_SHOWUSAGE;
7291 case RESULT_FAILURE:
7298 static int manager_iax2_show_netstats(
struct mansession *s,
const struct message *m)
7300 ast_cli_netstats(s, -1, 0);
7302 return RESULT_SUCCESS;
7308 int *fd = user_data;
7310 ast_cli(*fd,
"%-15.15s %-15d %-15d\n",
7313 (
int) ntohl(header->
datalen));
7322 e->
command =
"iax2 show firmware";
7324 "Usage: iax2 show firmware\n"
7325 " Lists all known IAX firmware images.\n";
7331 if (a->argc != 3 && a->argc != 4)
7332 return CLI_SHOWUSAGE;
7334 ast_cli(a->fd,
"%-15.15s %-15.15s %-15.15s\n",
"Device",
"Version",
"Size");
7336 iax_firmware_traverse(
7337 a->argc == 3 ? NULL : a->argv[3],
7338 firmware_show_callback,
7347 static const char *
const a[] = {
"iax2",
"show",
"peers" };
7349 char idtext[256] =
"";
7352 if (!ast_strlen_zero(
id))
7353 snprintf(idtext,
sizeof(idtext),
"ActionID: %s\r\n",
id);
7358 __iax2_show_peers(-1, &total, s, 3, a);
7372 .registeredonly = 0,
7379 .unmonitored_peers = 0,
7387 if (!ast_strlen_zero(
id)) {
7388 snprintf(cont.idtext,
sizeof(cont.idtext),
"ActionID: %s\r\n",
id);
7394 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
7395 _iax2_show_peers_one(-1, s, &cont, peer);
7402 return RESULT_SUCCESS;
7406 static char *regstate2str(
int regstate)
7409 case REG_STATE_UNREGISTERED:
7410 return "Unregistered";
7411 case REG_STATE_REGSENT:
7412 return "Request Sent";
7413 case REG_STATE_AUTHSENT:
7414 return "Auth. Sent";
7415 case REG_STATE_REGISTERED:
7416 return "Registered";
7417 case REG_STATE_REJECTED:
7419 case REG_STATE_TIMEOUT:
7421 case REG_STATE_NOAUTH:
7422 return "No Authentication";
7430 #define FORMAT2 "%-45.45s %-6.6s %-10.10s %-45.45s %8.8s %s\n"
7431 #define FORMAT "%-45.45s %-6.6s %-10.10s %-45.45s %8d %s\n"
7433 struct iax2_registry *reg = NULL;
7440 e->
command =
"iax2 show registry";
7442 "Usage: iax2 show registry\n"
7443 " Lists all registration requests and status.\n";
7449 return CLI_SHOWUSAGE;
7450 ast_cli(a->fd, FORMAT2,
"Host",
"dnsmgr",
"Username",
"Perceived",
"Refresh",
"State");
7457 ast_cli(a->fd, FORMAT, host,
7458 (reg->
dnsmgr) ?
"Y" :
"N",
7459 reg->username, perceived, reg->
refresh, regstate2str(reg->regstate));
7463 ast_cli(a->fd,
"%d IAX2 registrations.\n", counter);
7469 static int manager_iax2_show_registry(
struct mansession *s,
const struct message *m)
7472 struct iax2_registry *reg = NULL;
7473 char idtext[256] =
"";
7475 char perceived[80] =
"";
7478 if (!ast_strlen_zero(
id))
7479 snprintf(idtext,
sizeof(idtext),
"ActionID: %s\r\n",
id);
7490 "Event: RegistryEntry\r\n"
7493 "DNSmanager: %s\r\n"
7498 "\r\n", idtext, host, (reg->
dnsmgr) ?
"Y" :
"N", reg->username, perceived,
7499 reg->
refresh, regstate2str(reg->regstate));
7513 #define FORMAT2 "%-20.20s %-40.40s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
7514 #define FORMAT "%-20.20s %-40.40s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"
7515 #define FORMATB "%-20.20s %-40.40s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
7518 char first_message[10] = { 0, };
7519 char last_message[10] = { 0, };
7523 e->
command =
"iax2 show channels";
7525 "Usage: iax2 show channels\n"
7526 " Lists all currently active IAX channels.\n";
7533 return CLI_SHOWUSAGE;
7534 ast_cli(a->fd, FORMAT2,
"Channel",
"Peer",
"Username",
"ID (Lo/Rem)",
"Seq (Tx/Rx)",
"Lag",
"Jitter",
"JitBuf",
"Format",
"FirstMsg",
"LastMsg");
7535 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
7536 ast_mutex_lock(&iaxsl[x]);
7538 int lag, jitter, localdelay;
7549 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message,
sizeof(first_message));
7550 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message,
sizeof(last_message));
7552 ast_cli(a->fd, FORMAT,
7553 iaxs[x]->
owner ? ast_channel_name(iaxs[x]->owner) :
"(None)",
7555 S_OR(iaxs[x]->username,
"(None)"),
7556 iaxs[x]->callno, iaxs[x]->peercallno,
7557 iaxs[x]->oseqno, iaxs[x]->iseqno,
7562 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ?
"Tx:" :
"Rx:",
7564 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ?
"Tx:" :
"Rx:",
7568 ast_mutex_unlock(&iaxsl[x]);
7570 ast_cli(a->fd,
"%d active IAX channel%s\n", numchans, (numchans != 1) ?
"s" :
"");
7577 static int ast_cli_netstats(
struct mansession *s,
int fd,
int limit_fmt)
7581 char first_message[10] = { 0, };
7582 char last_message[10] = { 0, };
7583 #define ACN_FORMAT1 "%-24.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
7584 #define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
7585 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
7586 ast_mutex_lock(&iaxsl[x]);
7588 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
7590 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message,
sizeof(first_message));
7591 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message,
sizeof(last_message));
7595 localjitter = jbinfo.
jitter;
7598 locallosspct = jbinfo.
losspct/1000;
7611 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) :
"(None)",
7619 iaxs[x]->frames_received/1000,
7620 iaxs[x]->remote_rr.jitter,
7632 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
7633 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) :
"(None)",
7641 iaxs[x]->frames_received/1000,
7642 iaxs[x]->remote_rr.jitter,
7655 ast_mutex_unlock(&iaxsl[x]);
7667 e->
command =
"iax2 show netstats";
7669 "Usage: iax2 show netstats\n"
7670 " Lists network status for all currently active IAX channels.\n";
7676 return CLI_SHOWUSAGE;
7677 ast_cli(a->fd,
" -------- LOCAL --------------------- -------- REMOTE --------------------\n");
7678 ast_cli(a->fd,
"Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
7679 numchans = ast_cli_netstats(NULL, a->fd, 1);
7680 ast_cli(a->fd,
"%d active IAX channel%s\n", numchans, (numchans != 1) ?
"s" :
"");
7688 e->
command =
"iax2 set debug {on|off|peer}";
7690 "Usage: iax2 set debug {on|off|peer peername}\n"
7691 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
7694 if (a->pos == 4 && !strcasecmp(a->argv[3],
"peer"))
7695 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
7699 if (a->argc < e->
args || a->argc > e->
args + 1)
7700 return CLI_SHOWUSAGE;
7702 if (!strcasecmp(a->argv[3],
"peer")) {
7705 if (a->argc != e->
args + 1)
7706 return CLI_SHOWUSAGE;
7711 ast_cli(a->fd,
"IAX2 peer '%s' does not exist\n", a->argv[e->
args-1]);
7720 }
else if (!strncasecmp(a->argv[3],
"on", 2)) {
7722 ast_cli(a->fd,
"IAX2 Debugging Enabled\n");
7725 memset(&debugaddr, 0,
sizeof(debugaddr));
7726 ast_cli(a->fd,
"IAX2 Debugging Disabled\n");
7735 e->
command =
"iax2 set debug trunk {on|off}";
7737 "Usage: iax2 set debug trunk {on|off}\n"
7738 " Enables/Disables debugging of IAX trunking\n";
7744 if (a->argc != e->
args)
7745 return CLI_SHOWUSAGE;
7747 if (!strncasecmp(a->argv[e->
args - 1],
"on", 2)) {
7749 ast_cli(a->fd,
"IAX2 Trunk Debugging Enabled\n");
7752 ast_cli(a->fd,
"IAX2 Trunk Debugging Disabled\n");
7761 e->
command =
"iax2 set debug jb {on|off}";
7763 "Usage: iax2 set debug jb {on|off}\n"
7764 " Enables/Disables jitterbuffer debugging information\n";
7770 if (a->argc != e->
args)
7771 return CLI_SHOWUSAGE;
7773 if (!strncasecmp(a->argv[e->
args -1],
"on", 2)) {
7774 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
7775 ast_cli(a->fd,
"IAX2 Jitterbuffer Debugging Enabled\n");
7777 jb_setoutput(jb_error_output, jb_warning_output, NULL);
7778 ast_cli(a->fd,
"IAX2 Jitterbuffer Debugging Disabled\n");
7785 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(c));
7787 ast_mutex_lock(&iaxsl[callno]);
7790 if (!iaxs[callno]->error) {
7798 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
7802 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
7804 ast_debug(1,
"Write error: %s\n", strerror(errno));
7808 ast_mutex_unlock(&iaxsl[callno]);
7812 static int __send_command(
struct chan_iax2_pvt *i,
char type,
int command,
unsigned int ts,
const unsigned char *data,
int datalen,
int seqno,
7813 int now,
int transfer,
int final)
7821 f.
src = __FUNCTION__;
7822 f.
data.ptr = (
void *) data;
7828 return iax2_send(i, &f, ts, seqno, now, transfer,
final);
7831 static int send_command(
struct chan_iax2_pvt *i,
char type,
int command,
unsigned int ts,
const unsigned char *data,
int datalen,
int seqno)
7835 ast_debug(2,
"Callno %d: Blocked sending control frame %d.\n",
7839 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
7842 static int send_command_locked(
unsigned short callno,
char type,
int command,
unsigned int ts,
const unsigned char *data,
int datalen,
int seqno)
7845 ast_mutex_lock(&iaxsl[callno]);
7846 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
7847 ast_mutex_unlock(&iaxsl[callno]);
7858 int call_num = i->
callno;
7861 if (!iaxs[call_num])
7863 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
7866 static int send_command_immediate(
struct chan_iax2_pvt *i,
char type,
int command,
unsigned int ts,
const unsigned char *data,
int datalen,
int seqno)
7868 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
7871 static int send_command_transfer(
struct chan_iax2_pvt *i,
char type,
int command,
unsigned int ts,
const unsigned char *data,
int datalen)
7873 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
7876 static int apply_context(
struct iax2_context *con,
const char *context)
7879 if (!strcmp(con->context, context) || !strcmp(con->context,
"*"))
7892 struct iax2_user *user = NULL, *best = NULL;
7894 int gotcapability = 0;
7900 if (ies->called_number)
7902 if (ies->calling_number) {
7908 if (ies->calling_name)
7910 if (ies->calling_ani)
7916 if (ies->called_context)
7922 if (ies->calling_ton > -1)
7923 iaxs[callno]->calling_ton = ies->calling_ton;
7924 if (ies->calling_tns > -1)
7925 iaxs[callno]->calling_tns = ies->calling_tns;
7926 if (ies->calling_pres > -1)
7927 iaxs[callno]->calling_pres = ies->calling_pres;
7928 if (ies->calling_ani2 > -1)
7929 iaxs[callno]->calling_ani2 = ies->calling_ani2;
7934 if (ies->capability) {
7939 version = ies->version;
7942 if (ies->codec_prefs) {
7945 memset(&iaxs[callno]->rprefs, 0,
sizeof(iaxs[callno]->rprefs));
7949 if (!gotcapability) {
7952 if (version > IAX_PROTO_VERSION) {
7953 ast_log(LOG_WARNING,
"Peer '%s' has too new a protocol version (%d) for me\n",
7959 while ((user = ao2_iterator_next(&i))) {
7960 if ((ast_strlen_zero(iaxs[callno]->username) ||
7961 !strcmp(iaxs[callno]->username, user->name))
7962 && (
ast_apply_acl(user->acl, addr,
"IAX2 user ACL: ") == AST_SENSE_ALLOW)
7963 && (ast_strlen_zero(iaxs[callno]->context) ||
7964 apply_context(user->contexts, iaxs[callno]->
context))) {
7965 if (!ast_strlen_zero(iaxs[callno]->username)) {
7971 }
else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->
inkeys)) {
7975 if (bestscore < 4) {
7984 if (bestscore < 3) {
7995 if (bestscore < 2) {
8004 if (bestscore < 1) {
8018 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
8020 if (user && (
ast_apply_acl(user->acl, addr,
"IAX2 user ACL: ") == AST_SENSE_DENY
8021 || (!ast_strlen_zero(iaxs[callno]->context) &&
8022 !apply_context(user->contexts, iaxs[callno]->
context)))) {
8023 user = user_unref(user);
8029 for (v = user->vars ; v ; v = v->
next) {
8030 if ((tmpvar = ast_variable_new(v->
name, v->
value, v->
file))) {
8032 tmpvar->next = iaxs[callno]->
vars;
8033 iaxs[callno]->
vars = tmpvar;
8040 iaxs[callno]->
prefs = user->prefs;
8044 if (ast_strlen_zero(iaxs[callno]->username))
8047 ast_copy_flags64(iaxs[callno], user,
IAX_TRUNK);
8050 if (ast_strlen_zero(iaxs[callno]->context)) {
8060 iaxs[callno]->adsi = user->adsi;
8063 iaxs[callno]->calling_tns = 0;
8064 iaxs[callno]->calling_ton = 0;
8068 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
8069 }
else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
8070 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
8072 if (!ast_strlen_zero(user->accountcode))
8074 if (!ast_strlen_zero(user->mohinterpret))
8076 if (!ast_strlen_zero(user->mohsuggest))
8081 iaxs[callno]->amaflags = user->amaflags;
8082 if (!ast_strlen_zero(user->language))
8086 if (!ast_strlen_zero(user->dbsecret)) {
8087 char *family, *key=NULL;
8090 key = strchr(family,
'/');
8095 if (!key ||
ast_db_get(family, key, buf,
sizeof(buf)))
8096 ast_log(LOG_WARNING,
"Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
8102 user = user_unref(user);
8108 iaxs[callno]->
authmethods = last_authmethod ? last_authmethod : IAX_AUTH_MD5;
8111 if (!ast_strlen_zero(iaxs[callno]->username)) {
8116 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*addr),
IAX_TRUNK);
8120 static int raw_hangup(
struct ast_sockaddr *addr,
unsigned short src,
unsigned short dst,
int sockfd)
8123 fh.
scallno = htons(src | IAX_FLAG_FULL);
8129 fh.
csub = compress_subclass(IAX_COMMAND_INVAL);
8130 iax_outputframe(NULL, &fh, 0, addr, 0);
8133 return ast_sendto(sockfd, &fh,
sizeof(fh), 0, addr);
8136 static void merge_encryption(
struct chan_iax2_pvt *p,
unsigned int enc)
8141 if (!(p->
encmethods & IAX_ENCRYPT_KEYROTATE)){
8160 int res = -1, authreq_restrict = 0;
8164 memset(&ied, 0,
sizeof(ied));
8173 authreq_restrict = 1;
8176 user = user_unref(user);
8181 if (authreq_restrict) {
8182 iax_ie_append_str(&ied,
IAX_IE_CAUSE,
"Unauthenticated call limit reached");
8189 if (p->
authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
8190 snprintf(challenge,
sizeof(challenge),
"%d", (
int)ast_random());
8200 res = send_command(p,
AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
8210 char requeststr[256];
8211 char md5secret[256] =
"";
8212 char secret[256] =
"";
8213 char rsasecret[256] =
"";
8229 user = user_unref(user);
8232 ast_log(LOG_WARNING,
"Call Terminated, incoming call is unencrypted while force encrypt is enabled.\n");
8235 if (!ast_test_flag(&p->
state, IAX_STATE_AUTHENTICATED))
8239 if (ies->md5_result)
8241 if (ies->rsa_result)
8243 if ((p->
authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->
inkeys)) {
8249 ast_log(LOG_ERROR,
"Unable to create a temporary string for parsing stored 'inkeys'\n");
8253 keyn = strsep(&stringp,
":");
8261 ast_log(LOG_WARNING,
"Requested inkey '%s' for RSA authentication does not exist\n", keyn);
8263 keyn = strsep(&stringp,
":");
8266 if (res && authdebug) {
8267 ast_log(LOG_WARNING,
"No RSA public keys on file matched incoming call\n");
8271 unsigned char digest[16];
8272 char *tmppw, *stringp;
8275 while((tmppw = strsep(&stringp,
";"))) {
8278 MD5Update(&md5, (
unsigned char *)tmppw, strlen(tmppw));
8279 MD5Final(digest, &md5);
8282 sprintf(requeststr + (x << 1),
"%02hhx", digest[x]);
8283 if (!strcasecmp(requeststr, md5secret)) {
8287 }
else if (authdebug) {
8288 ast_log(LOG_WARNING,
"MD5 secret mismatch\n");
8292 if (!strcmp(secret, p->
secret)) {
8295 }
else if (authdebug) {
8296 ast_log(LOG_WARNING,
"Plaintext secret mismatch\n");
8305 char requeststr[256] =
"";
8306 char peer[256] =
"";
8307 char md5secret[256] =
"";
8308 char rsasecret[256] =
"";
8309 char secret[256] =
"";
8317 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
8323 if (ies->md5_result)
8325 if (ies->rsa_result)
8328 expire = ies->refresh;
8330 if (ast_strlen_zero(peer)) {
8336 ast_mutex_unlock(&iaxsl[callno]);
8338 ast_mutex_lock(&iaxsl[callno]);
8339 if (!p || !iaxs[callno]) {
8341 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
8353 if (ast_strlen_zero(iaxs[callno]->challenge) &&
8354 !(!ast_strlen_zero(secret) && plaintext)) {
8359 if (authdebug && !p)
8378 if (!ast_strlen_zero(rsasecret) && (p->
authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
8379 if (!ast_strlen_zero(p->
inkeys)) {
8383 ast_log(LOG_ERROR,
"Unable to create a temporary string for parsing stored 'inkeys'\n");
8387 keyn = strsep(&stringp,
":");
8391 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
8394 ast_log(LOG_WARNING,
"requested inkey '%s' does not exist\n", keyn);
8395 keyn = strsep(&stringp,
":");
8400 ast_log(LOG_NOTICE,
"Host %s failed RSA authentication with inkeys '%s'\n", peer, p->
inkeys);
8405 ast_log(LOG_NOTICE,
"Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
8408 }
else if (!ast_strlen_zero(md5secret) && (p->
authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
8410 unsigned char digest[16];
8411 char *tmppw, *stringp;
8415 while((tmppw = strsep(&stringp,
";"))) {
8417 MD5Update(&md5, (
unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
8418 MD5Update(&md5, (
unsigned char *)tmppw, strlen(tmppw));
8419 MD5Final(digest, &md5);
8421 sprintf(requeststr + (x << 1),
"%02hhx", digest[x]);
8422 if (!strcasecmp(requeststr, md5secret))
8426 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
8429 ast_log(LOG_NOTICE,
"Host %s failed MD5 authentication for '%s' (%s != %s)\n",
ast_sockaddr_stringify_addr(addr), p->name, requeststr, md5secret);
8432 }
else if (!ast_strlen_zero(secret) && (p->
authmethods & IAX_AUTH_PLAINTEXT)) {
8434 if (strcmp(secret, p->secret)) {
8439 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
8440 }
else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
8454 if (expire && (expire < iaxs[callno]->expiry)) {
8455 iaxs[callno]->
expiry = expire;
8465 static int authenticate(
const char *challenge,
const char *secret,
const char *keyn,
int authmethods,
struct iax_ie_data *ied,
struct ast_sockaddr *addr,
struct chan_iax2_pvt *pvt)
8469 if (!ast_strlen_zero(keyn)) {
8470 if (!(authmethods & IAX_AUTH_RSA)) {
8471 if (ast_strlen_zero(secret)) {
8472 ast_log(LOG_WARNING,
"Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n",
ast_sockaddr_stringify_addr(addr));
8474 }
else if (ast_strlen_zero(challenge)) {
8481 ast_log(LOG_WARNING,
"Unable to find private key '%s'\n", keyn);
8483 if (
ast_sign(key, (
char*)challenge, sig)) {
8484 ast_log(LOG_WARNING,
"Unable to sign challenge with key\n");
8495 if (pvt && !ast_strlen_zero(secret)) {
8497 unsigned char digest[16];
8500 MD5Update(&md5, (
unsigned char *) challenge, strlen(challenge));
8501 MD5Update(&md5, (
unsigned char *) secret, strlen(secret));
8502 MD5Final(digest, &md5);
8504 build_encryption_keys(digest, pvt);
8509 if (res && !ast_strlen_zero(secret)) {
8510 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
8512 unsigned char digest[16];
8515 MD5Update(&md5, (
unsigned char *)challenge, strlen(challenge));
8516 MD5Update(&md5, (
unsigned char *)secret, strlen(secret));
8517 MD5Final(digest, &md5);
8520 sprintf(digres + (x << 1),
"%02hhx", digest[x]);
8522 build_encryption_keys(digest, pvt);
8527 }
else if (authmethods & IAX_AUTH_PLAINTEXT) {
8548 int authmethods = 0;
8550 uint16_t callno = p->
callno;
8552 memset(&ied, 0,
sizeof(ied));
8558 if (ies->authmethods)
8559 authmethods = ies->authmethods;
8560 if (authmethods & IAX_AUTH_MD5)
8561 merge_encryption(p, ies->encmethods);
8566 if (!ast_strlen_zero(
override) || !ast_strlen_zero(okey)) {
8568 res = authenticate(p->
challenge,
override, okey, authmethods, &ied, addr, p);
8571 while ((peer = ao2_iterator_next(&i))) {
8581 if ((ast_strlen_zero(p->
peer) || !strcmp(p->
peer, peer->name))
8583 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->
username)))
8588 res = authenticate(p->
challenge, peer->secret, peer->
outkey, authmethods, &ied, addr, p);
8601 ast_mutex_unlock(&iaxsl[callno]);
8603 ast_mutex_lock(&iaxsl[callno]);
8604 if (!(p = iaxs[callno])) {
8608 res = authenticate(p->
challenge, peer->secret,peer->
outkey, authmethods, &ied, addr, p);
8612 ast_mutex_lock(&iaxsl[callno]);
8613 if (!(p = iaxs[callno]))
8619 if (!(ies->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT)) && (ies->authmethods & IAX_AUTH_RSA) && ast_strlen_zero(okey)) {
8621 ast_log(LOG_WARNING,
"Call terminated. RSA authentication requires an outkey\n");
8625 if (ies->encmethods) {
8626 if (ast_strlen_zero(p->
secret) &&
8627 ((ies->authmethods & IAX_AUTH_RSA) || (ies->authmethods & IAX_AUTH_MD5) || (ies->authmethods & IAX_AUTH_PLAINTEXT))) {
8628 ast_log(LOG_WARNING,
"Call terminated. Encryption requested by peer but no secret available locally\n");
8633 ast_assert_return(!invalid_key(&p->
ecx), -1);
8634 ast_assert_return(!invalid_key(&p->
dcx), -1);
8637 ast_log(LOG_NOTICE,
"Call initiated without encryption while forceencryption=yes option is set\n");
8645 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
8646 if (variablestore && varlist && p->
owner) {
8647 variablestore->
data = varlist;
8648 variablestore->
inheritance = DATASTORE_INHERIT_FOREVER;
8650 for (var = ies->vars; var; var = var->
next) {
8657 ast_log(LOG_ERROR,
"Memory allocation error while processing IAX2 variables\n");
8668 ast_log(LOG_ERROR,
"Memory allocation error while processing IAX2 variables\n");
8677 res = send_command(p,
AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
8681 static int iax2_do_register(
struct iax2_registry *reg);
8683 static void __iax2_do_register_s(
const void *data)
8685 struct iax2_registry *reg = (
struct iax2_registry *)data;
8688 reg->
addr.ss.ss_family = AST_AF_UNSPEC;
8698 iax2_do_register(reg);
8701 static int iax2_do_register_s(
const void *data)
8703 #ifdef SCHED_MULTITHREADED
8704 if (schedule_action(__iax2_do_register_s, data))
8706 __iax2_do_register_s(data);
8716 memset(&ied, 0,
sizeof(ied));
8721 newcall = ies->callno;
8724 ast_log(LOG_WARNING,
"Invalid transfer request\n");
8733 store_by_transfercallno(pvt);
8737 if (ies->transferid) {
8746 char exten[256] =
"";
8750 if (ies->called_number)
8753 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
8755 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
8757 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
8761 expiry = ies->refresh;
8762 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
8767 if (strcmp(dp->exten, exten))
8771 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
8774 dp->flags |= status;
8775 dp->flags |= matchmore;
8778 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
8779 if (dp->waiters[x] > -1) {
8780 if (write(dp->waiters[x],
"asdf", 4) < 0) {
8791 static int complete_transfer(
int callno,
struct iax_ies *ies)
8799 peercallno = ies->callno;
8801 if (peercallno < 1) {
8802 ast_log(LOG_WARNING,
"Invalid transfer request\n");
8805 remove_by_transfercallno(pvt);
8809 peercnt_remove_by_addr(&pvt->
addr);
8821 remove_by_peercallno(pvt);
8825 store_by_peercallno(pvt);
8836 iax2_frame_free(frame.data);
8842 pvt->
pingtime = DEFAULT_RETRY_TIME;
8852 static void iax2_publish_registry(
const char *username,
const char *domain,
const char *status,
const char *cause)
8860 struct iax2_registry *reg;
8862 char peer[256] =
"";
8865 char ourip[256] =
"<Unspecified>";
8873 if (ies->username) {
8877 refresh = ies->refresh;
8879 if (ies->calling_number) {
8882 reg = iaxs[callno]->
reg;
8884 ast_log(LOG_WARNING,
"Registry acknowledge on unknown registry '%s'\n", peer);
8894 if (ies->msgcount >= 0) {
8895 reg->
messages = ies->msgcount & 0xffff;
8902 (5 * reg->
refresh / 6) * 1000, iax2_do_register_s, reg);
8906 snprintf(msgstatus,
sizeof(msgstatus),
" with %d new and %d old messages waiting", reg->
messages & 0xff, reg->
messages >> 8);
8908 snprintf(msgstatus,
sizeof(msgstatus),
" with %d new messages waiting", reg->
messages);
8910 ast_copy_string(msgstatus,
" with 1 new message waiting",
sizeof(msgstatus));
8912 ast_copy_string(msgstatus,
" with no messages waiting",
sizeof(msgstatus));
8917 ast_verb(3,
"Registered IAX2 to '%s', who sees us as %s%s\n",
ast_sockaddr_stringify(addr), ourip, msgstatus);
8920 reg->regstate = REG_STATE_REGISTERED;
8924 static int iax2_append_register(
const char *hostname,
const char *username,
8925 const char *secret,
const char *porta)
8927 struct iax2_registry *reg;
8929 if (!(reg =
ast_calloc(1,
sizeof(*reg) + strlen(hostname) + 1))) {
8933 reg->
addr.ss.ss_family = AST_AF_UNSPEC;
8940 strcpy(reg->hostname, hostname);
8951 if (!porta && !reg->port) {
8952 reg->port = IAX_DEFAULT_PORTNO;
8954 sscanf(porta,
"%5d", ®->port);
8966 static int iax2_register(
const char *value,
int lineno)
8969 char *username, *hostname, *
secret;
8978 username = strsep(&stringp,
"@");
8979 hostname = strsep(&stringp,
"@");
8982 ast_log(LOG_WARNING,
"Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
8987 username = strsep(&stringp,
":");
8988 secret = strsep(&stringp,
":");
8990 hostname = strsep(&stringp,
":");
8991 porta = strsep(&stringp,
":");
8993 if (porta && !atoi(porta)) {
8994 ast_log(LOG_WARNING,
"%s is not a valid port number at line %d\n", porta, lineno);
8998 return iax2_append_register(hostname, username, secret, porta);
9002 static void register_peer_exten(
struct iax2_peer *peer,
int onoff)
9005 char *stringp, *ext;
9006 if (!ast_strlen_zero(regcontext)) {
9009 while((ext = strsep(&stringp,
"&"))) {
9019 static void prune_peers(
void);
9021 static void unlink_peer(
struct iax2_peer *peer)
9040 static void __expire_registry(
const void *data)
9047 if (peer->
expire == -1) {
9054 ast_debug(1,
"Expiring registration for peer '%s'\n", peer->name);
9056 realtime_update_peer(peer->name, &peer->addr, 0);
9059 "peer_status",
"Unregistered",
9060 "cause",
"Expired");
9063 peercnt_modify((
unsigned char) 0, 0, &peer->addr);
9067 peer->
expiry = min_reg_expire;
9070 register_peer_exten(peer, 0);
9073 iax2_regfunk(peer->name, 0);
9081 static int expire_registry(
const void *data)
9083 #ifdef SCHED_MULTITHREADED
9084 if (schedule_action(__expire_registry, data))
9086 __expire_registry(data);
9090 static void reg_source_db(
struct iax2_peer *p)
9099 expiry = strrchr(data,
':');
9101 ast_log(LOG_NOTICE,
"IAX/Registry astdb entry missing expiry: '%s'\n", data);
9107 ast_log(LOG_NOTICE,
"IAX/Registry astdb host:port invalid - '%s'\n", data);
9111 p->
expiry = atoi(expiry);
9113 ast_verb(3,
"Seeding '%s' at %s for %d\n", p->name,
9116 iax2_poke_peer(p, 0);
9126 p->
expire = iax2_sched_add(sched, (p->
expiry + 10) * 1000, expire_registry, peer_ref(p));
9132 iax2_regfunk(p->name, 1);
9135 register_peer_exten(p, 1);
9155 const char *peer_name;
9162 ast_mutex_unlock(&iaxsl[callno]);
9164 ast_mutex_lock(&iaxsl[callno]);
9165 ast_log(LOG_WARNING,
"No such peer '%s'\n", peer_name);
9168 ast_mutex_lock(&iaxsl[callno]);
9176 realtime_update_peer(peer_name, addr, nowtime);
9178 realtime_update_peer(peer_name, addr, 0);
9184 refresh = min_reg_expire;
9186 if (refresh > max_reg_expire) {
9187 ast_log(LOG_NOTICE,
"Restricting registration for peer '%s' to %d seconds (requested %d)\n",
9188 p->name, max_reg_expire, refresh);
9189 p->
expiry = max_reg_expire;
9190 }
else if (refresh < min_reg_expire) {
9191 ast_log(LOG_NOTICE,
"Restricting registration for peer '%s' to %d seconds (requested %d)\n",
9192 p->name, min_reg_expire, refresh);
9193 p->
expiry = min_reg_expire;
9202 iax2_regfunk(p->name, 1);
9206 peercnt_modify((
unsigned char) 0, 0, &p->addr);
9217 ast_verb(3,
"Registered IAX2 '%s' (%s) at %s\n",
9219 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ?
"AUTHENTICATED" :
"UNAUTHENTICATED",
9223 "peer_status",
"Registered",
9224 "address", str_addr,
9226 register_peer_exten(p, 1);
9229 ast_verb(3,
"Unregistered IAX2 '%s' (%s)\n",
9231 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ?
"AUTHENTICATED" :
"UNAUTHENTICATED");
9234 "peer_status",
"Unregistered");
9235 register_peer_exten(p, 0);
9244 iax2_poke_peer(p, callno);
9249 peercnt_modify((
unsigned char) 1, p->
maxcallno, &p->addr);
9253 if (!iaxs[callno]) {
9269 p->
expire = iax2_sched_add(sched, (p->
expiry + 10) * 1000, expire_registry, peer_ref(p));
9282 if (!ast_strlen_zero(p->
mailbox)) {
9301 msgcount = (old << 8) |
new;
9310 if (iax_firmware_get_version(devtype, &version)) {
9322 static int registry_authrequest(
int callno)
9327 const char *peer_name;
9333 ast_mutex_unlock(&iaxsl[callno]);
9338 ast_mutex_lock(&iaxsl[callno]);
9342 memset(&ied, 0,
sizeof(ied));
9349 sentauthmethod = p ? p->
authmethods : last_authmethod ? last_authmethod : IAX_AUTH_MD5;
9354 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
9356 snprintf(challenge,
sizeof(challenge),
"%d", (
int)ast_random());
9372 struct iax2_registry *reg;
9375 char peer[256] =
"";
9376 char challenge[256] =
"";
9378 int authmethods = 0;
9379 if (ies->authmethods)
9380 authmethods = ies->authmethods;
9385 memset(&ied, 0,
sizeof(ied));
9386 reg = iaxs[callno]->
reg;
9390 ast_log(LOG_WARNING,
"Received unsolicited registry authenticate request from '%s'\n",
ast_sockaddr_stringify(addr));
9393 if (ast_strlen_zero(reg->
secret)) {
9394 ast_log(LOG_NOTICE,
"No secret associated with peer '%s'\n", reg->username);
9395 reg->regstate = REG_STATE_NOAUTH;
9400 if (reg->
secret[0] ==
'[') {
9403 tmpkey[strlen(tmpkey) - 1] =
'\0';
9404 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, addr, NULL);
9406 res = authenticate(challenge, reg->
secret, NULL, authmethods, &ied, addr, NULL);
9408 reg->regstate = REG_STATE_AUTHSENT;
9409 add_empty_calltoken_ie(iaxs[callno], &ied);
9413 ast_log(LOG_WARNING,
"Registry acknowledge on unknown registry '%s'\n", peer);
9415 ast_log(LOG_NOTICE,
"Can't reregister without a reg\n");
9419 static void stop_stuff(
int callno)
9424 static void __auth_reject(
const void *nothing)
9427 int callno = (int)(
long)(nothing);
9429 ast_mutex_lock(&iaxsl[callno]);
9431 memset(&ied, 0,
sizeof(ied));
9433 iax_ie_append_str(&ied,
IAX_IE_CAUSE,
"Registration Refused");
9435 }
else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
9436 iax_ie_append_str(&ied,
IAX_IE_CAUSE,
"No authority found");
9437 iax_ie_append_byte(&ied,
IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
9441 ast_mutex_unlock(&iaxsl[callno]);
9444 static int auth_reject(
const void *data)
9446 int callno = (int)(
long)(data);
9447 ast_mutex_lock(&iaxsl[callno]);
9449 iaxs[callno]->
authid = -1;
9450 ast_mutex_unlock(&iaxsl[callno]);
9451 #ifdef SCHED_MULTITHREADED
9452 if (schedule_action(__auth_reject, data))
9454 __auth_reject(data);
9458 static int auth_fail(
int callno,
int failcode)
9465 iaxs[callno]->
authid = iax2_sched_replace(iaxs[callno]->authid,
9466 sched, 1000, auth_reject, (
void *)(
long)callno);
9468 auth_reject((
void *)(
long)callno);
9473 static void __auto_hangup(
const void *nothing)
9476 int callno = (int)(
long)(nothing);
9478 ast_mutex_lock(&iaxsl[callno]);
9480 memset(&ied, 0,
sizeof(ied));
9485 ast_mutex_unlock(&iaxsl[callno]);
9488 static int auto_hangup(
const void *data)
9490 int callno = (int)(
long)(data);
9491 ast_mutex_lock(&iaxsl[callno]);
9493 iaxs[callno]->
autoid = -1;
9495 ast_mutex_unlock(&iaxsl[callno]);
9496 #ifdef SCHED_MULTITHREADED
9497 if (schedule_action(__auto_hangup, data))
9499 __auto_hangup(data);
9503 static void iax2_dprequest(
struct iax2_dpcache *dp,
int callno)
9507 iaxs[callno]->
autoid = iax2_sched_replace(iaxs[callno]->autoid,
9508 sched, 30000, auto_hangup, (
void *)(
long)callno);
9509 memset(&ied, 0,
sizeof(ied));
9515 static int iax2_vnak(
int callno)
9520 static void vnak_retransmit(
int callno,
int last)
9526 if (((
unsigned char) (f->
oseqno - last) < 128) &&
9533 static void __iax2_poke_peer_s(
const void *data)
9536 iax2_poke_peer(peer, 0);
9540 static int iax2_poke_peer_s(
const void *data)
9544 #ifdef SCHED_MULTITHREADED
9545 if (schedule_action(__iax2_poke_peer_s, data))
9547 __iax2_poke_peer_s(data);
9551 static int send_trunk(
struct iax2_trunk_peer *tpeer,
struct timeval *now)
9560 fr = (
struct iax_frame *)tpeer->trunkdata;
9564 if (tpeer->trunkdatalen) {
9572 mth->
ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
9578 fr->
data = fr->afdata;
9580 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
9581 calls = tpeer->calls;
9583 ast_debug(1,
"Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->
datalen,
ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->
ts));
9586 tpeer->trunkdatalen = 0;
9594 static inline int iax2_trunk_expired(
struct iax2_trunk_peer *tpeer,
struct timeval *now)
9597 if (now->tv_sec > tpeer->
trunkact.tv_sec + 5)
9602 static int timing_read(
int *
id,
int fd,
short events,
void *cbdata)
9604 int res, processed = 0, totalcalls = 0;
9608 if (iaxtrunkdebug) {
9609 ast_verbose(
"Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
9614 ast_log(LOG_ERROR,
"Timer failed acknowledge\n");
9624 ast_mutex_lock(&tpeer->lock);
9627 if (!drop && iax2_trunk_expired(tpeer, &now)) {
9633 res = send_trunk(tpeer, &now);
9635 if (iaxtrunkdebug) {
9636 ast_verbose(
" - Trunk peer (%s) has %d call chunk%s in transit, %u bytes backlogged and has hit a high water mark of %u bytes\n",
9639 (res != 1) ?
"s" :
"",
9640 tpeer->trunkdatalen,
9641 tpeer->trunkdataalloc);
9646 ast_mutex_unlock(&tpeer->lock);
9652 ast_mutex_lock(&drop->lock);
9656 if (drop->trunkdata) {
9657 ast_free(drop->trunkdata);
9658 drop->trunkdata = NULL;
9660 ast_mutex_unlock(&drop->lock);
9661 ast_mutex_destroy(&drop->lock);
9665 if (iaxtrunkdebug) {
9666 ast_verbose(
"Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
9680 static void dp_lookup(
int callno,
const char *context,
const char *callednum,
const char *callerid,
int skiplock)
9682 unsigned short dpstatus = 0;
9686 memset(&ied1, 0,
sizeof(ied1));
9690 dpstatus = IAX_DPSTATUS_EXISTS;
9692 dpstatus = IAX_DPSTATUS_CANEXIST;
9694 dpstatus = IAX_DPSTATUS_NONEXISTENT;
9697 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
9699 dpstatus |= IAX_DPSTATUS_MATCHMORE;
9701 ast_mutex_lock(&iaxsl[callno]);
9709 ast_mutex_unlock(&iaxsl[callno]);
9712 static void *dp_lookup_thread(
void *data)
9716 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
9718 ast_free(dpr->callerid);
9723 static void spawn_dp_lookup(
int callno,
const char *context,
const char *callednum,
const char *callerid)
9725 pthread_t newthread;
9731 dpr->callno = callno;
9736 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
9737 ast_log(LOG_WARNING,
"Unable to start lookup thread!\n");
9741 static int check_provisioning(
struct ast_sockaddr *addr,
int sockfd,
char *si,
unsigned int ver)
9743 unsigned int ourver;
9745 snprintf(rsi,
sizeof(rsi),
"si-%s", si);
9746 if (iax_provision_version(&ourver, rsi, 1))
9748 ast_debug(1,
"Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
9750 iax2_provision(addr, sockfd, NULL, rsi, 1);
9759 memset(iep, 0,
sizeof(*iep));
9784 unsigned int length, offset = 0;
9785 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
9787 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
9788 length = ies->ospblocklength[i];
9795 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
9802 *(full_osptoken + offset) =
'\0';
9803 if (strlen(full_osptoken) != offset) {
9805 *full_osptoken =
'\0';
9811 static void log_jitterstats(
unsigned short callno)
9813 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
9816 ast_mutex_lock(&iaxsl[callno]);
9817 if (iaxs[callno] && iaxs[callno]->owner && ast_channel_name(iaxs[callno]->owner)) {
9820 localjitter = jbinfo.
jitter;
9823 locallosspct = jbinfo.
losspct/1000;
9828 ast_debug(3,
"JB STATS:%s ping=%u ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n",
9829 ast_channel_name(iaxs[callno]->owner),
9830 iaxs[callno]->pingtime,
9838 iaxs[callno]->remote_rr.jitter,
9846 ast_mutex_unlock(&iaxsl[callno]);
9849 static int socket_process(
struct iax2_thread *thread);
9858 ast_mutex_lock(&thread->lock);
9861 ast_mutex_unlock(&thread->lock);
9863 thread->buf = pkt_buf->buf;
9864 thread->buf_len = pkt_buf->len;
9865 thread->buf_size = pkt_buf->len + 1;
9867 socket_process(thread);
9872 ast_mutex_lock(&thread->lock);
9875 ast_mutex_unlock(&thread->lock);
9889 if (!(pkt_buf =
ast_calloc(1,
sizeof(*pkt_buf) + from_here->buf_len)))
9892 pkt_buf->len = from_here->buf_len;
9893 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
9896 ast_mutex_lock(&to_here->lock);
9909 to_here->iostate = IAX_IOSTATE_READY;
9910 ast_cond_signal(&to_here->cond);
9912 ast_mutex_unlock(&to_here->lock);
9915 static int socket_read(
int *
id,
int fd,
short events,
void *cbdata)
9919 static time_t last_errtime = 0;
9922 if (!(thread = find_idle_thread())) {
9924 if (t != last_errtime) {
9926 ast_debug(1,
"Out of idle IAX2 threads for I/O, pausing!\n");
9933 thread->buf_len =
ast_recvfrom(fd, thread->readbuf,
sizeof(thread->readbuf), 0, &thread->ioaddr);
9934 thread->buf_size =
sizeof(thread->readbuf);
9935 thread->buf = thread->readbuf;
9936 if (thread->buf_len < 0) {
9937 if (errno != ECONNREFUSED && errno != EAGAIN)
9938 ast_log(LOG_WARNING,
"Error: %s\n", strerror(errno));
9940 thread->iostate = IAX_IOSTATE_IDLE;
9941 signal_condition(&thread->lock, &thread->cond);
9944 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
9945 thread->iostate = IAX_IOSTATE_IDLE;
9946 signal_condition(&thread->lock, &thread->cond);
9954 if (ntohs(fh->
scallno) & IAX_FLAG_FULL) {
9956 uint16_t callno = ntohs(fh->
scallno) & ~IAX_FLAG_FULL;
9960 if ((cur->
ffinfo.callno == callno) &&
9969 thread->iostate = IAX_IOSTATE_IDLE;
9970 signal_condition(&thread->lock, &thread->cond);
9974 thread->
ffinfo.callno = callno;
9984 thread->iostate = IAX_IOSTATE_READY;
9985 #ifdef DEBUG_SCHED_MULTITHREAD
9986 ast_copy_string(thread->curfunc,
"socket_process",
sizeof(thread->curfunc));
9988 signal_condition(&thread->lock, &thread->cond);
9996 unsigned char metatype;
10003 struct timeval rxtrunktime;
10006 if (packet_len <
sizeof(*meta)) {
10007 ast_log(LOG_WARNING,
"Rejecting packet from '%s' that is flagged as a meta frame but is too short\n",
10015 if (packet_len < (
sizeof(*meta) +
sizeof(*mth))) {
10016 ast_log(LOG_WARNING,
"midget meta trunk packet received (%d of %d min)\n", packet_len,
10017 (
int) (
sizeof(*meta) +
sizeof(*mth)));
10021 ts = ntohl(mth->
ts);
10023 packet_len -= (
sizeof(*meta) +
sizeof(*mth));
10025 tpeer = find_tpeer(addr, sockfd);
10027 ast_log(LOG_WARNING,
"Unable to accept trunked packet from '%s': No matching peer\n",
10035 ast_mutex_unlock(&tpeer->lock);
10036 while (packet_len >=
sizeof(*mte)) {
10038 unsigned short callno, trunked_ts, len;
10042 ptr +=
sizeof(*mtm);
10043 packet_len -=
sizeof(*mtm);
10044 len = ntohs(mtm->len);
10046 trunked_ts = ntohs(mtm->
mini.
ts);
10049 ptr +=
sizeof(*mte);
10050 packet_len -=
sizeof(*mte);
10051 len = ntohs(mte->
len);
10052 callno = ntohs(mte->
callno);
10059 if (len > packet_len)
10061 fr->
callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, addr, NEW_PREVENT, sockfd, 0);
10068 memset(&f, 0,
sizeof(f));
10070 if (!iaxs[fr->
callno]) {
10073 ast_log(LOG_WARNING,
"Received trunked frame before first full voice frame\n");
10084 fr->
ts = (iaxs[fr->
callno]->
last & 0xFFFF0000L) | (trunked_ts & 0xffff);
10086 fr->
ts = fix_peerts(&rxtrunktime, fr->
callno, ts);
10088 if (ast_test_flag(&iaxs[fr->
callno]->
state, IAX_STATE_STARTED)) {
10100 iax_frame_wrap(fr, &f);
10101 duped_fr = iaxfrdup2(fr);
10108 ast_log(LOG_WARNING,
"Datalen < 0?\n");
10111 ast_mutex_unlock(&iaxsl[fr->
callno]);
10119 static int acf_iaxvar_read(
struct ast_channel *chan,
const char *cmd,
char *data,
char *buf,
size_t len)
10126 ast_log(LOG_WARNING,
"No channel was provided to %s function.\n", cmd);
10131 if (!variablestore) {
10135 varlist = variablestore->
data;
10139 if (strcmp(var->name, data) == 0) {
10148 static int acf_iaxvar_write(
struct ast_channel *chan,
const char *cmd,
char *data,
const char *value)
10155 ast_log(LOG_WARNING,
"No channel was provided to %s function.\n", cmd);
10160 if (!variablestore) {
10161 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10162 if (!variablestore) {
10163 ast_log(LOG_ERROR,
"Memory allocation error\n");
10169 ast_log(LOG_ERROR,
"Unable to assign new variable '%s'\n", data);
10174 variablestore->
data = varlist;
10175 variablestore->
inheritance = DATASTORE_INHERIT_FOREVER;
10178 varlist = variablestore->
data;
10182 if (strcmp(var->name, data) == 0) {
10184 ast_var_delete(var);
10189 var = ast_var_assign(data, value);
10193 ast_log(LOG_ERROR,
"Unable to assign new variable '%s'\n", data);
10200 .read = acf_iaxvar_read,
10201 .write = acf_iaxvar_write,
10204 static void set_hangup_source_and_cause(
int callno,
unsigned char causecode)
10206 iax2_lock_owner(callno);
10207 if (iaxs[callno] && iaxs[callno]->owner) {
10211 owner = iaxs[callno]->
owner;
10213 ast_channel_hangupcause_set(owner, causecode);
10217 ast_channel_unlock(owner);
10218 ast_mutex_unlock(&iaxsl[callno]);
10221 ast_mutex_lock(&iaxsl[callno]);
10225 static int socket_process_helper(
struct iax2_thread *thread)
10229 int updatehistory=1;
10230 int new = NEW_PREVENT;
10232 char decrypted = 0;
10251 char host_pref_buf[128];
10252 char caller_pref_buf[128];
10254 char *using_prefs =
"mine";
10258 memset(fr, 0,
sizeof(*fr));
10262 res = thread->buf_len;
10266 if (res <
sizeof(*mh)) {
10267 ast_log(LOG_WARNING,
"midget packet received (%d of %d min)\n", res, (
int)
sizeof(*mh));
10270 if ((vh->
zeros == 0) && (ntohs(vh->
callno) & 0x8000)) {
10271 if (res <
sizeof(*vh)) {
10272 ast_log(LOG_WARNING,
"Rejecting packet from '%s' that is flagged as a video frame but is too short\n",
10278 fr->
callno = find_callno(ntohs(vh->
callno) & ~0x8000, dcallno, &addr,
new, fd, 0);
10280 }
else if ((meta->
zeros == 0) && !(ntohs(meta->
metacmd) & 0x8000))
10281 return socket_process_meta(res, meta, &addr, fd, fr);
10283 #ifdef DEBUG_SUPPORT
10284 if (res >=
sizeof(*fh))
10285 iax_outputframe(NULL, fh, 1, &addr, res -
sizeof(*fh));
10287 if (ntohs(mh->
callno) & IAX_FLAG_FULL) {
10288 if (res <
sizeof(*fh)) {
10289 ast_log(LOG_WARNING,
"Rejecting packet from '%s' that is flagged as a full frame but is too short\n",
10295 dcallno = ntohs(fh->
dcallno) & ~IAX_FLAG_RETRANS;
10302 if ((dcallno != 1) && (fr->
callno = find_callno(ntohs(mh->
callno) & ~IAX_FLAG_FULL, dcallno, &addr, NEW_PREVENT, fd, 1))) {
10303 ast_mutex_lock(&iaxsl[fr->
callno]);
10305 if (decrypt_frame(fr->
callno, fh, &f, &res)) {
10306 ast_log(LOG_NOTICE,
"Packet Decrypt Failed!\n");
10307 ast_mutex_unlock(&iaxsl[fr->
callno]);
10312 ast_mutex_unlock(&iaxsl[fr->
callno]);
10322 if ((fh->
csub >> 6) & 0x1) {
10337 send_apathetic_reply(1, ntohs(fh->
scallno), &addr, IAX_COMMAND_PONG, ntohl(fh->
ts), fh->
iseqno + 1, fd, NULL);
10344 f.
datalen = res -
sizeof(*fh);
10356 memset(&ies, 0,
sizeof(ies));
10362 f.
data.ptr = empty;
10363 memset(&ies, 0,
sizeof(ies));
10368 if (handle_call_token(fh, &ies, &addr, fd)) {
10373 if (ies.calltoken && ies.calltokendata) {
10378 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10387 memset(&ies, 0,
sizeof(ies));
10391 int check_dcallno = 0;
10405 if (!(fr->
callno = find_callno(ntohs(mh->
callno) & ~IAX_FLAG_FULL, dcallno, &addr,
new, fd, check_dcallno))) {
10407 send_apathetic_reply(1, ntohs(fh->scallno), &addr, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10409 send_apathetic_reply(1, ntohs(fh->scallno), &addr,
IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10417 ast_callid mount_callid;
10418 ast_mutex_lock(&iaxsl[fr->
callno]);
10419 if (iaxs[fr->
callno] && ((mount_callid = iax_pvt_callid_get(fr->
callno)))) {
10428 if (ntohs(mh->
callno) & IAX_FLAG_FULL) {
10435 raw_hangup(&addr, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->
callno) & ~IAX_FLAG_FULL,
10439 ast_mutex_unlock(&iaxsl[fr->
callno]);
10445 if (decrypt_frame(fr->
callno, fh, &f, &res)) {
10446 ast_log(LOG_WARNING,
"Packet Decrypt Failed!\n");
10448 ast_mutex_unlock(&iaxsl[fr->
callno]);
10454 #ifdef DEBUG_SUPPORT
10456 iax_outputframe(NULL, fh, 3, &addr, res -
sizeof(*fh));
10461 (fh->csub == IAX_COMMAND_HANGUP
10462 || fh->csub == IAX_COMMAND_REJECT
10466 int data_size =
sizeof(*cause_code);
10467 char subclass[40] =
"";
10470 iax_frame_subclass2str(fh->csub, subclass,
sizeof(subclass));
10476 if (ies.causecode > 9) {
10479 if (ies.causecode > 99) {
10483 data_size += strlen(subclass);
10486 memset(cause_code, 0, data_size);
10490 snprintf(cause_code->
code, data_size -
sizeof(*cause_code) + 1,
"IAX2 %s(%d)", subclass, ies.causecode);
10492 iax2_lock_owner(fr->
callno);
10498 if (!iaxs[fr->
callno]) {
10500 ast_mutex_unlock(&iaxsl[fr->
callno]);
10511 unsigned short new_peercallno;
10513 new_peercallno = (
unsigned short) (ntohs(mh->
callno) & ~IAX_FLAG_FULL);
10516 remove_by_peercallno(iaxs[fr->
callno]);
10519 store_by_peercallno(iaxs[fr->
callno]);
10522 if (ntohs(mh->
callno) & IAX_FLAG_FULL) {
10526 fr->
oseqno = fh->oseqno;
10527 fr->
iseqno = fh->iseqno;
10528 fr->
ts = ntohl(fh->ts);
10531 ast_debug(1,
"Simulating frame ts resync, was %u now %u\n", fr->
ts, fr->
ts + test_resync);
10532 fr->
ts += test_resync;
10536 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10539 f.
subclass == IAX_COMMAND_AUTHREQ ||
10540 f.
subclass == IAX_COMMAND_ACCEPT ||
10541 f.
subclass == IAX_COMMAND_REJECT)) ) )
10564 ast_debug(1,
"Packet arrived out of order (expecting %d, got %d) (frametype = %u, subclass = %d)\n",
10582 ast_mutex_unlock(&iaxsl[fr->
callno]);
10597 if (res < thread->buf_size)
10598 thread->buf[res++] =
'\0';
10600 thread->buf[res - 1] =
'\0';
10609 int call_to_destroy;
10621 ast_debug(1,
"Cancelling transmission of packet %d\n", x);
10622 call_to_destroy = 0;
10629 call_to_destroy = fr->
callno;
10632 if (call_to_destroy) {
10634 ast_debug(1,
"Really destroying %d, having been acked on final message\n", call_to_destroy);
10635 ast_mutex_lock(&iaxsl[call_to_destroy]);
10636 iax2_destroy(call_to_destroy);
10637 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10646 ast_mutex_unlock(&iaxsl[fr->
callno]);
10659 ast_mutex_unlock(&iaxsl[fr->
callno]);
10673 ast_test_flag(&iaxs[fr->
callno]->
state, IAX_STATE_AUTHENTICATED))) {
10675 ast_mutex_unlock(&iaxsl[fr->
callno]);
10685 iax2_lock_owner(fr->
callno);
10686 if (!iaxs[fr->
callno]) {
10688 ast_mutex_unlock(&iaxsl[fr->
callno]);
10693 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10695 if (variablestore && varlist) {
10696 variablestore->
data = varlist;
10697 variablestore->
inheritance = DATASTORE_INHERIT_FOREVER;
10700 for (var = ies.vars; var; var = var->
next) {
10708 ast_log(LOG_ERROR,
"Memory allocation error while processing IAX2 variables\n");
10719 ast_log(LOG_ERROR,
"Memory allocation error while processing IAX2 variables\n");
10720 if (variablestore) {
10727 ast_channel_unlock(c);
10731 ast_debug(1,
"No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10732 for (var = ies.vars; var && var->
next; var = var->
next);
10742 ast_debug(1,
"I have IAX variables, but they were not processed\n");
10757 iax2_lock_owner(fr->
callno);
10763 ast_channel_nativeformats_set(iaxs[fr->
callno]->
owner, native);
10764 if (ast_channel_readformat(iaxs[fr->
callno]->
owner)) {
10772 ast_debug(1,
"Neat, somebody took away the channel at a magical time but i found it!\n");
10776 ast_debug(1,
"I can haz iaxvars, but they is no good. :-(\n");
10779 ast_mutex_unlock(&iaxsl[fr->
callno]);
10811 case IAX_COMMAND_ACK:
10815 if (ast_test_flag(&iaxs[fr->
callno]->
state, IAX_STATE_STARTED)) {
10817 if (ies.musiconhold) {
10818 const char *moh_suggest;
10820 iax2_lock_owner(fr->
callno);
10829 moh_suggest = iaxs[fr->
callno]->mohsuggest;
10836 if (ast_test_flag(&iaxs[fr->
callno]->
state, IAX_STATE_STARTED)) {
10837 iax2_lock_owner(fr->
callno);
10838 if (!iaxs[fr->
callno]) {
10864 memset(&ied1, 0,
sizeof(ied1));
10870 case IAX_COMMAND_NEW:
10872 if (ast_test_flag(&iaxs[fr->
callno]->
state, IAX_STATE_STARTED | IAX_STATE_TBD))
10875 ast_mutex_unlock(&iaxsl[fr->
callno]);
10876 check_provisioning(&addr, fd, ies.serviceident, ies.provver);
10877 ast_mutex_lock(&iaxsl[fr->
callno]);
10878 if (!iaxs[fr->
callno]) {
10886 fr->
callno = new_callno;
10891 if (check_access(fr->
callno, &addr, &ies)) {
10893 auth_fail(fr->
callno, IAX_COMMAND_REJECT);
10895 ast_log(LOG_NOTICE,
"Rejected connect attempt from %s, who was trying to reach '%s@%s'\n",
10901 auth_fail(fr->
callno, IAX_COMMAND_REJECT);
10902 ast_log(LOG_WARNING,
"Rejected connect attempt. No secret present while force encrypt enabled.\n");
10905 if (strcasecmp(iaxs[fr->
callno]->
exten,
"TBD")) {
10906 const char *context, *exten, *cid_num;
10913 ast_mutex_unlock(&iaxsl[fr->
callno]);
10915 ast_mutex_lock(&iaxsl[fr->
callno]);
10917 if (!iaxs[fr->
callno]) {
10923 save_osptoken(fr, &ies);
10925 if (strcmp(iaxs[fr->
callno]->
exten,
"TBD") && !exists) {
10926 memset(&ied0, 0,
sizeof(ied0));
10927 iax_ie_append_str(&ied0,
IAX_IE_CAUSE,
"No such context/extension");
10928 iax_ie_append_byte(&ied0,
IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10930 if (!iaxs[fr->
callno]) {
10934 ast_log(LOG_NOTICE,
"Rejected connect attempt from %s, request '%s@%s' does not exist\n",
10942 using_prefs =
"reqonly";
10944 using_prefs =
"disabled";
10947 memset(&pref, 0,
sizeof(pref));
10948 strcpy(caller_pref_buf,
"disabled");
10949 strcpy(host_pref_buf,
"disabled");
10952 using_prefs =
"mine";
10954 if (ies.codec_prefs)
10960 using_prefs =
"caller";
10975 memset(&ied0, 0,
sizeof(ied0));
10976 iax_ie_append_str(&ied0,
IAX_IE_CAUSE,
"Unable to negotiate codec");
10977 iax_ie_append_byte(&ied0,
IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10979 if (!iaxs[fr->
callno]) {
10988 ast_log(LOG_NOTICE,
"Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10990 iax2_getformatname_multiple(iaxs[fr->
callno]->
peerformat, &peer_form_buf),
10993 ast_log(LOG_NOTICE,
"Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10995 iax2_getformatname_multiple(iaxs[fr->
callno]->
peerformat, &peer_form_buf),
11008 memset(&pref, 0,
sizeof(pref));
11010 strcpy(caller_pref_buf,
"disabled");
11011 strcpy(host_pref_buf,
"disabled");
11014 using_prefs =
"mine";
11021 using_prefs =
"caller";
11034 memset(&ied0, 0,
sizeof(ied0));
11035 iax_ie_append_str(&ied0,
IAX_IE_CAUSE,
"Unable to negotiate codec");
11036 iax_ie_append_byte(&ied0,
IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11039 if (!iaxs[fr->
callno]) {
11043 ast_log(LOG_NOTICE,
"Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11045 iax2_getformatname_multiple(iaxs[fr->
callno]->
peerformat, &peer_form_buf),
11056 memset(&ied1, 0,
sizeof(ied1));
11058 iax_ie_append_versioned_uint64(&ied1,
IAX_IE_FORMAT2, 0, format);
11059 send_command(iaxs[fr->
callno],
AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11061 ast_set_flag(&iaxs[fr->
callno]->
state, IAX_STATE_STARTED);
11062 ast_verb(3,
"Accepting UNAUTHENTICATED call from %s:\n"
11063 "%srequested format = %s,\n"
11064 "%srequested prefs = %s,\n"
11065 "%sactual format = %s,\n"
11066 "%shost prefs = %s,\n"
11067 "%spriority = %s\n",
11083 iax_pvt_callid_new(fr->
callno);
11086 ast_set_flag(&iaxs[fr->
callno]->
state, IAX_STATE_TBD);
11095 merge_encryption(iaxs[fr->
callno], ies.encmethods);
11099 ast_set_flag(&iaxs[fr->
callno]->
state, IAX_STATE_AUTHENTICATED);
11103 if (ast_test_flag(&iaxs[fr->
callno]->
state, IAX_STATE_TBD) &&
11104 !ast_test_flag(&iaxs[fr->
callno]->
state, IAX_STATE_STARTED) && ies.called_number) {
11114 case IAX_COMMAND_HANGUP:
11116 ast_debug(1,
"Immediately destroying %d, having received hangup\n", fr->
callno);
11119 set_hangup_source_and_cause(fr->
callno, ies.causecode);
11120 if (!iaxs[fr->
callno]) {
11127 iax2_destroy(fr->
callno);
11129 case IAX_COMMAND_REJECT:
11132 set_hangup_source_and_cause(fr->
callno, ies.causecode);
11133 if (!iaxs[fr->
callno]) {
11140 ast_log(LOG_WARNING,
"Call rejected by %s: %s\n",
11142 ies.cause ? ies.cause :
"<Unknown>");
11143 ast_debug(1,
"Immediately destroying %d, having received reject\n",
11151 iax2_destroy(fr->
callno);
11155 iax2_lock_owner(fr->
callno);
11156 if (!iaxs[fr->
callno]) {
11165 ast_channel_unlock(owner);
11166 ast_mutex_unlock(&iaxsl[fr->
callno]);
11170 ast_log(LOG_WARNING,
"Blind transfer of '%s' to '%s@%s' failed\n",
11171 ast_channel_name(owner), ies.called_number,
11176 ast_mutex_lock(&iaxsl[fr->
callno]);
11181 case IAX_COMMAND_ACCEPT:
11183 if (ast_test_flag(&iaxs[fr->
callno]->
state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
11188 iax2_destroy(fr->
callno);
11202 memset(&ied0, 0,
sizeof(ied0));
11203 iax_ie_append_str(&ied0,
IAX_IE_CAUSE,
"Unable to negotiate codec");
11204 iax_ie_append_byte(&ied0,
IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11206 if (!iaxs[fr->
callno]) {
11213 ast_log(LOG_NOTICE,
"Rejected call to %s, format %s incompatible with our capability %s.\n",
11215 iax2_getformatname_multiple(iaxs[fr->
callno]->peerformat, &peer_buf),
11216 iax2_getformatname_multiple(iaxs[fr->
callno]->capability, &cap_buf));
11221 ast_set_flag(&iaxs[fr->
callno]->state, IAX_STATE_STARTED);
11222 iax2_lock_owner(fr->
callno);
11223 if (iaxs[fr->
callno] && iaxs[fr->
callno]->owner && native) {
11228 iaxs[fr->
callno]->peerformat, &iaxs[fr->
callno]->rprefs,
11230 ast_channel_nativeformats_set(iaxs[fr->
callno]->owner, native);
11234 if (ast_channel_writeformat(iaxs[fr->
callno]->owner))
11236 if (ast_channel_readformat(iaxs[fr->
callno]->owner))
11238 ast_channel_unlock(iaxs[fr->
callno]->owner);
11241 ao2_cleanup(native);
11247 iax2_dprequest(dp, fr->callno);
11255 case IAX_COMMAND_PING:
11258 construct_rr(iaxs[fr->
callno], &pingied);
11260 send_command(iaxs[fr->
callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->
ts, pingied.buf, pingied.pos, -1);
11263 case IAX_COMMAND_PONG:
11265 iaxs[fr->
callno]->pingtime = calc_timestamp(iaxs[fr->
callno], 0, &f) - fr->
ts;
11270 log_jitterstats(fr->
callno);
11272 if (iaxs[fr->
callno]->peerpoke) {
11274 peer = iaxs[fr->
callno]->peerpoke;
11277 ast_log(LOG_NOTICE,
"Peer '%s' is now REACHABLE! Time: %u\n", peer->name, iaxs[fr->
callno]->pingtime);
11280 "peer_status",
"Reachable",
11286 ast_log(LOG_NOTICE,
"Peer '%s' is now TOO LAGGED (%u ms)!\n", peer->name, iaxs[fr->
callno]->pingtime);
11289 "peer_status",
"Lagged",
11320 iax2_destroy(fr->
callno);
11325 case IAX_COMMAND_LAGRQ:
11326 case IAX_COMMAND_LAGRP:
11331 iax_frame_wrap(fr, &f);
11335 iax2_send(iaxs[fr->
callno], &fr->
af, fr->
ts, -1, 0, 0, 0);
11340 ts = calc_timestamp(iaxs[fr->
callno], 0, &fr->
af);
11341 iaxs[fr->
callno]->lag = ts - fr->
ts;
11343 ast_debug(1,
"Peer %s lag measured as %dms\n",
11347 case IAX_COMMAND_AUTHREQ:
11348 if (ast_test_flag(&iaxs[fr->
callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11349 ast_log(LOG_WARNING,
"Call on %s is already up, can't start on it\n", iaxs[fr->
callno]->owner ? ast_channel_name(iaxs[fr->
callno]->owner) :
"<Unknown>");
11356 ast_log(LOG_WARNING,
11357 "I don't know how to authenticate %s to %s\n",
11362 case IAX_COMMAND_AUTHREP:
11367 if (ast_test_flag(&iaxs[fr->
callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11368 ast_log(LOG_WARNING,
"Call on %s is already up, can't start on it\n", iaxs[fr->
callno]->owner ? ast_channel_name(iaxs[fr->
callno]->owner) :
"<Unknown>");
11371 if (authenticate_verify(iaxs[fr->
callno], &ies)) {
11374 iaxs[fr->
callno]->username);
11375 memset(&ied0, 0,
sizeof(ied0));
11376 auth_fail(fr->
callno, IAX_COMMAND_REJECT);
11379 if (strcasecmp(iaxs[fr->
callno]->exten,
"TBD")) {
11384 if (strcmp(iaxs[fr->
callno]->exten,
"TBD") && !exists) {
11386 ast_log(LOG_WARNING,
"Rejected connect attempt from %s, request '%s@%s' does not exist\n",
11388 iaxs[fr->
callno]->exten,
11389 iaxs[fr->
callno]->context);
11390 memset(&ied0, 0,
sizeof(ied0));
11391 iax_ie_append_str(&ied0,
IAX_IE_CAUSE,
"No such context/extension");
11392 iax_ie_append_byte(&ied0,
IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11394 if (!iaxs[fr->
callno]) {
11401 using_prefs =
"reqonly";
11403 using_prefs =
"disabled";
11405 format = iaxs[fr->
callno]->peerformat & iaxs[fr->
callno]->capability;
11406 memset(&pref, 0,
sizeof(pref));
11407 strcpy(caller_pref_buf,
"disabled");
11408 strcpy(host_pref_buf,
"disabled");
11411 using_prefs =
"mine";
11412 if (ies.codec_prefs)
11416 pref = iaxs[fr->
callno]->rprefs;
11417 using_prefs =
"caller";
11419 pref = iaxs[fr->
callno]->prefs;
11422 pref = iaxs[fr->
callno]->prefs;
11423 format = iax2_codec_choose(&pref, iaxs[fr->
callno]->capability & iaxs[fr->
callno]->peercapability);
11433 ast_debug(1,
"We don't do requested format %s, falling back to peer capability '%s'\n",
11435 iax2_getformatname_multiple(iaxs[fr->
callno]->peercapability, &peer_buf));
11436 format = iaxs[fr->
callno]->peercapability & iaxs[fr->
callno]->capability;
11441 ast_log(LOG_WARNING,
"Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11443 iax2_getformatname_multiple(iaxs[fr->
callno]->peerformat, &peer_form_buf),
11444 iax2_getformatname_multiple(iaxs[fr->
callno]->capability, &cap_buf));
11446 ast_log(LOG_WARNING,
"Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11448 iax2_getformatname_multiple(iaxs[fr->
callno]->peerformat, &peer_form_buf),
11449 iax2_getformatname_multiple(iaxs[fr->
callno]->peercapability, &peer_buf),
11450 iax2_getformatname_multiple(iaxs[fr->
callno]->capability, &cap_buf));
11453 memset(&ied0, 0,
sizeof(ied0));
11454 iax_ie_append_str(&ied0,
IAX_IE_CAUSE,
"Unable to negotiate codec");
11455 iax_ie_append_byte(&ied0,
IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11457 if (!iaxs[fr->
callno]) {
11463 if(!(iaxs[fr->
callno]->peerformat & iaxs[fr->
callno]->capability))
11468 memset(&pref, 0,
sizeof(pref));
11470 ? iaxs[fr->
callno]->peerformat
11472 strcpy(caller_pref_buf,
"disabled");
11473 strcpy(host_pref_buf,
"disabled");
11476 using_prefs =
"mine";
11480 pref = iaxs[fr->
callno]->prefs;
11482 pref = iaxs[fr->
callno]->rprefs;
11483 using_prefs =
"caller";
11485 format = iax2_codec_choose(&pref, iaxs[fr->
callno]->peercapability & iaxs[fr->
callno]->capability);
11495 ast_log(LOG_ERROR,
"No best format in %s???\n",
11496 iax2_getformatname_multiple(iaxs[fr->
callno]->peercapability & iaxs[fr->
callno]->capability, &cap_buf));
11499 ast_log(LOG_WARNING,
"Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11501 iax2_getformatname_multiple(iaxs[fr->
callno]->peerformat, &peer_form_buf),
11502 iax2_getformatname_multiple(iaxs[fr->
callno]->capability, &cap_buf));
11504 ast_log(LOG_WARNING,
"Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11506 iax2_getformatname_multiple(iaxs[fr->
callno]->peerformat, &peer_form_buf),
11507 iax2_getformatname_multiple(iaxs[fr->
callno]->peercapability, &peer_buf),
11508 iax2_getformatname_multiple(iaxs[fr->
callno]->capability, &cap_buf));
11511 memset(&ied0, 0,
sizeof(ied0));
11512 iax_ie_append_str(&ied0,
IAX_IE_CAUSE,
"Unable to negotiate codec");
11513 iax_ie_append_byte(&ied0,
IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11515 if (!iaxs[fr->
callno]) {
11523 memset(&ied1, 0,
sizeof(ied1));
11525 iax_ie_append_versioned_uint64(&ied1,
IAX_IE_FORMAT2, 0, format);
11526 send_command(iaxs[fr->
callno],
AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11527 if (strcmp(iaxs[fr->
callno]->exten,
"TBD")) {
11528 char authmethodnames[AUTH_METHOD_NAMES_BUFSIZE];
11529 ast_set_flag(&iaxs[fr->
callno]->state, IAX_STATE_STARTED);
11530 ast_verb(3,
"Accepting AUTHENTICATED call from %s:\n"
11531 "%srequested auth methods = (%s),\n"
11532 "%sactual auth method = %s,\n"
11533 "%sencrypted = %s,\n"
11534 "%srequested format = %s,\n"
11535 "%srequested prefs = %s,\n"
11536 "%sactual format = %s,\n"
11537 "%shost prefs = %s,\n"
11538 "%spriority = %s\n",
11545 IAX_CALLENCRYPTED(iaxs[fr->
callno]) ?
"yes" :
"no",
11557 ast_set_flag(&iaxs[fr->
callno]->state, IAX_STATE_STARTED);
11559 &iaxs[fr->
callno]->rprefs, NULL, NULL, 1);
11561 iax2_destroy(fr->
callno);
11562 }
else if (ies.vars) {
11567 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11568 if (variablestore && varlist) {
11569 variablestore->
data = varlist;
11570 variablestore->
inheritance = DATASTORE_INHERIT_FOREVER;
11572 ast_debug(1,
"I can haz IAX vars? w00t\n");
11573 for (var = ies.vars; var; var = var->
next) {
11580 ast_log(LOG_ERROR,
"Memory allocation error while processing IAX2 variables\n");
11590 ast_log(LOG_ERROR,
"Memory allocation error while processing IAX2 variables\n");
11598 ast_set_flag(&iaxs[fr->
callno]->state, IAX_STATE_TBD);
11602 goto immediatedial;
11610 if (ast_test_flag(&iaxs[fr->
callno]->state, IAX_STATE_TBD)) {
11611 ast_clear_flag(&iaxs[fr->
callno]->state, IAX_STATE_TBD);
11615 ast_log(LOG_WARNING,
"Rejected dial attempt from %s, request '%s@%s' does not exist\n",
11617 iaxs[fr->
callno]->exten,
11618 iaxs[fr->
callno]->context);
11619 memset(&ied0, 0,
sizeof(ied0));
11620 iax_ie_append_str(&ied0,
IAX_IE_CAUSE,
"No such context/extension");
11621 iax_ie_append_byte(&ied0,
IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11623 if (!iaxs[fr->
callno]) {
11628 ast_set_flag(&iaxs[fr->
callno]->state, IAX_STATE_STARTED);
11629 ast_verb(3,
"Accepting DIAL from %s, formats = %s\n",
11631 iax2_getformatname_multiple(iaxs[fr->
callno]->peerformat, &cap_buf));
11632 ast_set_flag(&iaxs[fr->
callno]->state, IAX_STATE_STARTED);
11635 iaxs[fr->
callno]->peerformat, &iaxs[fr->
callno]->rprefs,
11638 iax2_destroy(fr->
callno);
11639 }
else if (ies.vars) {
11644 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11645 ast_debug(1,
"I can haz IAX vars? w00t\n");
11646 if (variablestore && varlist) {
11647 variablestore->
data = varlist;
11648 variablestore->
inheritance = DATASTORE_INHERIT_FOREVER;
11650 for (var = ies.vars; var; var = var->
next) {
11657 ast_log(LOG_ERROR,
"Memory allocation error while processing IAX2 variables\n");
11667 ast_log(LOG_ERROR,
"Memory allocation error while processing IAX2 variables\n");
11677 case IAX_COMMAND_INVAL:
11678 iaxs[fr->
callno]->error = ENOTCONN;
11679 ast_debug(1,
"Immediately destroying %d, having received INVAL\n", fr->
callno);
11680 iax2_destroy(fr->
callno);
11684 ast_debug(1,
"Received VNAK: resending outstanding frames\n");
11694 if (!iaxs[fr->
callno]) {
11701 if (!iaxs[fr->
callno]) {
11704 if ((ast_strlen_zero(iaxs[fr->
callno]->secret) && ast_strlen_zero(iaxs[fr->
callno]->inkeys)) ||
11705 ast_test_flag(&iaxs[fr->
callno]->state, IAX_STATE_AUTHENTICATED)) {
11711 ast_log(LOG_WARNING,
"Registry error\n");
11713 if (!iaxs[fr->
callno]) {
11717 ast_mutex_unlock(&iaxsl[fr->
callno]);
11718 check_provisioning(&addr, fd, ies.serviceident, ies.provver);
11719 ast_mutex_lock(&iaxsl[fr->
callno]);
11723 registry_authrequest(fr->
callno);
11727 ast_log(LOG_WARNING,
"Registration failure\n");
11731 iax2_destroy(fr->
callno);
11734 if (iaxs[fr->
callno]->reg) {
11736 ast_log(LOG_NOTICE,
"Registration of '%s' rejected: '%s' from: '%s'\n",
11737 iaxs[fr->
callno]->reg->username, ies.cause ? ies.cause :
"<unknown>",
11741 iaxs[fr->
callno]->reg->regstate = REG_STATE_REJECTED;
11745 iax2_destroy(fr->
callno);
11749 if (registry_rerequest(&ies, fr->
callno, &addr)) {
11750 memset(&ied0, 0,
sizeof(ied0));
11751 iax_ie_append_str(&ied0,
IAX_IE_CAUSE,
"No authority found");
11752 iax_ie_append_byte(&ied0,
IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11758 && iaxs[fr->
callno]->bridgecallno
11759 && ast_mutex_trylock(&iaxsl[iaxs[fr->
callno]->bridgecallno])) {
11760 DEADLOCK_AVOIDANCE(&iaxsl[fr->
callno]);
11762 if (!iaxs[fr->
callno]) {
11766 iaxs[fr->
callno]->transferring = TRANSFER_NONE;
11767 ast_verb(3,
"Channel '%s' unable to transfer\n", iaxs[fr->
callno]->owner ? ast_channel_name(iaxs[fr->
callno]->owner) :
"<Unknown>");
11768 memset(&iaxs[fr->
callno]->transfer, 0,
sizeof(iaxs[fr->
callno]->transfer));
11770 if (!iaxs[fr->
callno]->bridgecallno) {
11774 if (iaxs[iaxs[fr->
callno]->bridgecallno]
11775 && iaxs[iaxs[fr->
callno]->bridgecallno]->transferring) {
11776 iaxs[iaxs[fr->
callno]->bridgecallno]->transferring = TRANSFER_NONE;
11779 ast_mutex_unlock(&iaxsl[iaxs[fr->
callno]->bridgecallno]);
11783 && iaxs[fr->
callno]->bridgecallno
11784 && ast_mutex_trylock(&iaxsl[iaxs[fr->
callno]->bridgecallno])) {
11785 DEADLOCK_AVOIDANCE(&iaxsl[fr->
callno]);
11787 if (!iaxs[fr->
callno]) {
11791 if (iaxs[fr->
callno]->transferring == TRANSFER_BEGIN) {
11792 iaxs[fr->
callno]->transferring = TRANSFER_READY;
11793 }
else if (iaxs[fr->
callno]->transferring == TRANSFER_MBEGIN) {
11794 iaxs[fr->
callno]->transferring = TRANSFER_MREADY;
11796 if (iaxs[fr->
callno]->bridgecallno) {
11797 ast_mutex_unlock(&iaxsl[iaxs[fr->
callno]->bridgecallno]);
11801 ast_verb(3,
"Channel '%s' ready to transfer\n", iaxs[fr->
callno]->owner ? ast_channel_name(iaxs[fr->
callno]->owner) :
"<Unknown>");
11803 if (!iaxs[fr->
callno]->bridgecallno) {
11807 if (!iaxs[iaxs[fr->
callno]->bridgecallno]
11808 || (iaxs[iaxs[fr->
callno]->bridgecallno]->transferring != TRANSFER_READY
11809 && iaxs[iaxs[fr->
callno]->bridgecallno]->transferring != TRANSFER_MREADY)) {
11810 ast_mutex_unlock(&iaxsl[iaxs[fr->
callno]->bridgecallno]);
11818 if (iaxs[fr->
callno]->transferring == TRANSFER_MREADY) {
11819 ast_verb(3,
"Attempting media bridge of %s and %s\n", iaxs[fr->
callno]->owner ? ast_channel_name(iaxs[fr->
callno]->owner) :
"<Unknown>",
11820 iaxs[iaxs[fr->
callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->
callno]->bridgecallno]->owner) :
"<Unknown>");
11822 iaxs[iaxs[fr->
callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11823 iaxs[fr->
callno]->transferring = TRANSFER_MEDIA;
11825 memset(&ied0, 0,
sizeof(ied0));
11826 memset(&ied1, 0,
sizeof(ied1));
11827 iax_ie_append_short(&ied0,
IAX_IE_CALLNO, iaxs[iaxs[fr->
callno]->bridgecallno]->peercallno);
11832 ast_verb(3,
"Releasing %s and %s\n", iaxs[fr->
callno]->owner ? ast_channel_name(iaxs[fr->
callno]->owner) :
"<Unknown>",
11833 iaxs[iaxs[fr->
callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->
callno]->bridgecallno]->owner) :
"<Unknown>");
11835 iaxs[iaxs[fr->
callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11836 iaxs[fr->
callno]->transferring = TRANSFER_RELEASED;
11842 stop_stuff(iaxs[fr->
callno]->bridgecallno);
11844 memset(&ied0, 0,
sizeof(ied0));
11845 memset(&ied1, 0,
sizeof(ied1));
11846 iax_ie_append_short(&ied0,
IAX_IE_CALLNO, iaxs[iaxs[fr->
callno]->bridgecallno]->peercallno);
11851 ast_mutex_unlock(&iaxsl[iaxs[fr->
callno]->bridgecallno]);
11854 try_transfer(iaxs[fr->
callno], &ies);
11857 if (iaxs[fr->
callno]->transferring)
11863 complete_transfer(fr->
callno, &ies);
11867 if (iaxs[fr->
callno]->transferring == TRANSFER_READY) {
11875 iaxs[fr->
callno]->transferring = TRANSFER_MEDIAPASS;
11879 if (!IAX_CALLENCRYPTED(iaxs[fr->
callno])) {
11880 ast_log(LOG_WARNING,
11881 "we've been told to rotate our encryption key, "
11882 "but this isn't an encrypted call. bad things will happen.\n"
11887 IAX_DEBUGDIGEST(
"Receiving", ies.challenge);
11889 ast_aes_set_decrypt_key((
unsigned char *) ies.challenge, &iaxs[fr->
callno]->dcx);
11892 complete_dpreply(iaxs[fr->
callno], &ies);
11895 ast_log(LOG_NOTICE,
"Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11903 memset(&ied0, 0,
sizeof(ied0));
11904 res = iax_firmware_append(&ied0, ies.devicetype, ies.fwdesc);
11917 resend_with_token(fr->
callno, cur, (
char *) ies.calltokendata);
11923 memset(&ied0, 0,
sizeof(ied0));
11930 ast_debug(1,
"I can haz IAX vars, but they is no good :-(\n");
11944 ast_mutex_unlock(&iaxsl[fr->
callno]);
11950 }
else if (minivid) {
11952 if (iaxs[fr->
callno]->videoformat > 0) {
11953 if (ntohs(vh->
ts) & 0x8000LL) {
11959 ast_mutex_unlock(&iaxsl[fr->
callno]);
11963 ast_log(LOG_WARNING,
"Received mini frame before first full video frame\n");
11966 ast_mutex_unlock(&iaxsl[fr->
callno]);
11969 f.
datalen = res -
sizeof(*vh);
11971 f.
data.ptr = thread->buf +
sizeof(*vh);
11976 fr->
ts = (iaxs[fr->
callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11979 fr->
ts = (iaxs[fr->
callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11983 if (iaxs[fr->
callno]->voiceformat > 0) {
11987 ast_mutex_unlock(&iaxsl[fr->
callno]);
11991 ast_debug(1,
"Received mini frame before first full voice frame\n");
11994 ast_mutex_unlock(&iaxsl[fr->
callno]);
11999 ast_log(LOG_WARNING,
"Datalen < 0?\n");
12001 ast_mutex_unlock(&iaxsl[fr->
callno]);
12005 f.
data.ptr = thread->buf +
sizeof(*mh);
12010 fr->
ts = (iaxs[fr->
callno]->last & 0xFFFF0000L) | ((ntohs(mh->
ts) + test_resync) & 0xffff);
12013 fr->
ts = (iaxs[fr->
callno]->last & 0xFFFF0000L) | ntohs(mh->
ts);
12019 || !ast_test_flag(&iaxs[fr->
callno]->state, IAX_STATE_STARTED)) {
12021 ast_mutex_unlock(&iaxsl[fr->
callno]);
12028 ast_debug(2,
"Callno %d: Blocked receiving control frame %d.\n",
12031 ast_mutex_unlock(&iaxsl[fr->
callno]);
12039 ast_debug(2,
"Callno %d: Config blocked receiving control frame %d.\n",
12042 ast_mutex_unlock(&iaxsl[fr->
callno]);
12047 iax2_lock_owner(fr->
callno);
12050 ast_channel_hangupcause_set(iaxs[fr->
callno]->owner, AST_CAUSE_BUSY);
12052 ast_channel_hangupcause_set(iaxs[fr->
callno]->owner, AST_CAUSE_CONGESTION);
12054 ast_channel_unlock(iaxs[fr->
callno]->owner);
12069 connected.id.number.presentation = iaxs[fr->
callno]->calling_pres;
12070 connected.id.name.presentation = iaxs[fr->
callno]->calling_pres;
12077 iax2_lock_owner(fr->
callno);
12080 S_COR(connected.id.number.valid, connected.id.number.str,
""),
12081 S_COR(connected.id.name.valid, connected.id.name.str,
""),
12085 ast_channel_unlock(iaxs[fr->
callno]->owner);
12100 ast_frame_byteswap_be(&f);
12103 iax_frame_wrap(fr, &f);
12110 if (iaxdebug && iaxs[fr->
callno]) {
12117 duped_fr = iaxfrdup2(fr);
12132 ast_mutex_unlock(&iaxsl[fr->
callno]);
12136 static int socket_process(
struct iax2_thread *thread)
12138 int res = socket_process_helper(thread);
12146 static void iax2_process_thread_cleanup(
void *data)
12149 ast_mutex_destroy(&thread->lock);
12150 ast_cond_destroy(&thread->cond);
12151 ast_mutex_destroy(&thread->init_lock);
12152 ast_cond_destroy(&thread->init_cond);
12161 struct timeval wait;
12162 struct timespec ts;
12163 int put_into_idle = 0;
12164 int first_time = 1;
12169 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
12170 pthread_cleanup_push(iax2_process_thread_cleanup, data);
12174 ast_mutex_lock(&thread->lock);
12176 if (thread->stop) {
12177 ast_mutex_unlock(&thread->lock);
12183 signal_condition(&thread->init_lock, &thread->init_cond);
12188 if (put_into_idle) {
12189 insert_idle_thread(thread);
12192 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
12196 ts.tv_sec = wait.tv_sec;
12197 ts.tv_nsec = wait.tv_usec * 1000;
12198 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
12201 if (!put_into_idle || thread->stop) {
12202 ast_mutex_unlock(&thread->lock);
12214 ast_mutex_unlock(&thread->lock);
12221 ts.tv_sec = wait.tv_sec;
12222 ts.tv_nsec = wait.tv_usec * 1000;
12223 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
12224 ast_mutex_unlock(&thread->lock);
12229 ast_cond_wait(&thread->cond, &thread->lock);
12235 ast_mutex_unlock(&thread->lock);
12237 if (thread->stop) {
12242 switch (thread->iostate) {
12243 case IAX_IOSTATE_IDLE:
12245 case IAX_IOSTATE_READY:
12247 thread->iostate = IAX_IOSTATE_PROCESSING;
12248 socket_process(thread);
12251 case IAX_IOSTATE_SCHEDREADY:
12253 thread->iostate = IAX_IOSTATE_PROCESSING;
12254 #ifdef SCHED_MULTITHREADED
12255 thread->schedfunc(thread->scheddata);
12272 time(&thread->checktime);
12273 thread->iostate = IAX_IOSTATE_IDLE;
12274 #ifdef DEBUG_SCHED_MULTITHREAD
12275 thread->curfunc[0]=
'\0';
12292 if (!thread->stop) {
12294 pthread_detach(pthread_self());
12300 pthread_cleanup_pop(1);
12304 static int iax2_do_register(
struct iax2_registry *reg)
12308 ast_debug(1,
"Sending registration request for '%s'\n", reg->username);
12321 int callno = reg->
callno;
12322 ast_mutex_lock(&iaxsl[callno]);
12323 iax2_destroy(callno);
12324 ast_mutex_unlock(&iaxsl[callno]);
12329 ast_debug(1,
"Unable to send registration request for '%s' without IP address\n", reg->username);
12332 (5 * reg->
refresh / 6) * 1000, iax2_do_register_s, reg);
12341 ast_debug(3,
"Allocate call number\n");
12343 reg->
callno = find_callno_locked(0, 0, ®->
addr, NEW_FORCE, defaultsockfd, 0);
12345 ast_log(LOG_WARNING,
"Unable to create call for registration\n");
12349 iaxs[reg->
callno]->reg = reg;
12350 ast_mutex_unlock(&iaxsl[reg->
callno]);
12354 (5 * reg->
refresh / 6) * 1000, iax2_do_register_s, reg);
12356 memset(&ied, 0,
sizeof(ied));
12359 add_empty_calltoken_ie(iaxs[reg->
callno], &ied);
12361 reg->regstate = REG_STATE_REGSENT;
12365 static int iax2_provision(
struct ast_sockaddr *end,
int sockfd,
const char *dest,
const char *
template,
int force)
12376 memset(&cai, 0,
sizeof(cai));
12378 ast_debug(1,
"Provisioning '%s' from template '%s'\n", dest,
template);
12380 if (iax_provision_build(&provdata, &sig,
template, force)) {
12381 ast_debug(1,
"No provisioning found for template '%s'\n",
template);
12387 cai.sockfd = sockfd;
12388 }
else if (create_addr(dest, NULL, &addr, &cai))
12392 memset(&ied, 0,
sizeof(ied));
12395 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
12399 if (iaxs[callno]) {
12401 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
12402 sched, 15000, auto_hangup, (
void *)(
long)callno);
12407 ast_mutex_unlock(&iaxsl[callno]);
12412 static char *papp =
"IAX2Provision";
12423 unsigned short callno = PTR_TO_CALLNO(ast_channel_tech_pvt(chan));
12424 if (ast_strlen_zero(data))
12427 opts = strchr(sdata,
'|');
12432 ast_log(LOG_NOTICE,
"Can't provision a non-IAX device!\n");
12436 ast_log(LOG_NOTICE,
"Can't provision something with no IP?\n");
12439 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
12440 ast_verb(3,
"Provisioned IAXY at '%s' with '%s'= %d\n",
12453 e->
command =
"iax2 provision";
12455 "Usage: iax2 provision <host> <template> [forced]\n"
12456 " Provisions the given peer or IP address using a template\n"
12457 " matching either 'template' or '*' if the template is not\n"
12458 " found. If 'forced' is specified, even empty provisioning\n"
12459 " fields will be provisioned as empty fields.\n";
12463 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
12468 return CLI_SHOWUSAGE;
12470 if (!strcasecmp(a->argv[4],
"forced"))
12473 return CLI_SHOWUSAGE;
12475 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
12477 ast_cli(a->fd,
"Unable to find peer/address '%s'\n", a->argv[2]);
12479 ast_cli(a->fd,
"No template (including wildcard) matching '%s'\n", a->argv[3]);
12481 ast_cli(a->fd,
"Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ?
", forced" :
"");
12482 return CLI_SUCCESS;
12485 static void __iax2_poke_noanswer(
const void *data)
12490 if (peer->
lastms > -1) {
12493 ast_log(LOG_NOTICE,
"Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->
lastms);
12496 "peer_status",
"Unreachable",
12501 if ((callno = peer->
callno) > 0) {
12502 ast_mutex_lock(&iaxsl[callno]);
12503 iax2_destroy(callno);
12504 ast_mutex_unlock(&iaxsl[callno]);
12514 static int iax2_poke_noanswer(
const void *data)
12518 #ifdef SCHED_MULTITHREADED
12519 if (schedule_action(__iax2_poke_noanswer, data))
12521 __iax2_poke_noanswer(data);
12526 static int iax2_poke_peer_cb(
void *obj,
void *arg,
int flags)
12530 iax2_poke_peer(peer, 0);
12535 static int iax2_poke_peer(
struct iax2_peer *peer,
int heldcall)
12551 if ((callno = peer->
callno) > 0) {
12552 ast_log(LOG_NOTICE,
"Still have a callno...\n");
12553 ast_mutex_lock(&iaxsl[callno]);
12554 iax2_destroy(callno);
12555 ast_mutex_unlock(&iaxsl[callno]);
12558 ast_mutex_unlock(&iaxsl[heldcall]);
12559 callno = peer->
callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->
sockfd, 0);
12561 ast_mutex_lock(&iaxsl[heldcall]);
12563 ast_log(LOG_WARNING,
"Unable to allocate call for poking peer '%s'\n", peer->name);
12587 poke_timeout = MIN(MAX_RETRY_TIME * 2 + peer->
maxms, peer->
pokefreqok * 5 / 6);
12591 peer->
pokeexpire = iax2_sched_add(sched, poke_timeout, iax2_poke_noanswer, peer_ref(peer));
12597 ast_mutex_lock(&iaxsl[callno]);
12598 if (iaxs[callno]) {
12605 iaxs[callno]->pingtime = peer->
maxms / 8;
12606 iaxs[callno]->peerpoke = peer;
12608 add_empty_calltoken_ie(iaxs[callno], &ied);
12611 ast_mutex_unlock(&iaxsl[callno]);
12637 memset(&pds, 0,
sizeof(pds));
12643 if (ast_strlen_zero(pds.peer)) {
12644 ast_log(LOG_WARNING,
"No peer provided in the IAX2 dial string '%s'\n", data);
12647 memset(&cai, 0,
sizeof(cai));
12648 cai.capability = iax2_capability;
12653 if (create_addr(pds.peer, NULL, &addr, &cai)) {
12654 *cause = AST_CAUSE_UNREGISTERED;
12660 ast_parse_arg(pds.port, PARSE_UINT32 | PARSE_IN_RANGE, &bindport, 0, 65535);
12664 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
12666 ast_log(LOG_WARNING,
"Unable to create call\n");
12667 *cause = AST_CAUSE_CONGESTION;
12673 if (ast_test_flag64(&cai,
IAX_TRUNK)) {
12675 if ((new_callno =
make_trunk(callno, 1)) != -1)
12676 callno = new_callno;
12678 iaxs[callno]->maxtime = cai.maxtime;
12680 iax_pvt_callid_set(callno, callid);
12688 requestor, cai.found);
12690 ast_mutex_unlock(&iaxsl[callno]);
12696 ast_channel_lock(c);
12698 ast_channel_unlock(c);
12719 ast_log(LOG_WARNING,
"Unable to create translator path for %s to %s on %s\n",
12722 ast_channel_name(c));
12729 ao2_ref(best_fmt_native, -1);
12731 ast_channel_nativeformats_set(c, joint);
12733 ast_channel_set_readformat(c, format);
12734 ast_channel_set_writeformat(c, format);
12743 static void *network_thread(
void *ignore)
12752 pthread_testcancel();
12759 if (res < 0 && errno != -EINTR) {
12760 ast_log(LOG_ERROR,
"IAX2 network thread unexpected exit: %s\n", strerror(errno));
12768 static int start_network_thread(
void)
12771 int threadcount = 0;
12773 for (x = 0; x < iaxthreadcount; x++) {
12776 thread->type = IAX_THREAD_TYPE_POOL;
12777 thread->threadnum = ++threadcount;
12778 ast_mutex_init(&thread->lock);
12779 ast_cond_init(&thread->cond, NULL);
12780 ast_mutex_init(&thread->init_lock);
12781 ast_cond_init(&thread->init_cond, NULL);
12783 ast_mutex_lock(&thread->init_lock);
12785 if (ast_pthread_create_background(&thread->threadid, NULL,
iax2_process_thread, thread)) {
12786 ast_log(LOG_WARNING,
"Failed to create new thread!\n");
12787 ast_mutex_destroy(&thread->lock);
12788 ast_cond_destroy(&thread->cond);
12789 ast_mutex_unlock(&thread->init_lock);
12790 ast_mutex_destroy(&thread->init_lock);
12791 ast_cond_destroy(&thread->init_cond);
12797 ast_cond_wait(&thread->init_cond, &thread->init_lock);
12800 ast_mutex_unlock(&thread->init_lock);
12807 if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) {
12808 ast_log(LOG_ERROR,
"Failed to create new thread!\n");
12811 ast_verb(2,
"%d helper threads started\n", threadcount);
12815 static struct iax2_context *build_context(
const char *context)
12825 static int get_auth_methods(
const char *value)
12828 if (strstr(value,
"rsa"))
12829 methods |= IAX_AUTH_RSA;
12830 if (strstr(value,
"md5"))
12831 methods |= IAX_AUTH_MD5;
12832 if (strstr(value,
"plaintext"))
12833 methods |= IAX_AUTH_PLAINTEXT;
12847 sd = socket(addr->ss.ss_family, SOCK_DGRAM, 0);
12849 ast_log(LOG_ERROR,
"Socket: %s\n", strerror(errno));
12854 ast_debug(1,
"Can't bind: %s\n", strerror(errno));
12870 int port = IAX_DEFAULT_PORTNO;
12871 int sockfd = defaultsockfd;
12880 port = atoi(portstr);
12882 port = IAX_DEFAULT_PORTNO;
12885 addr.ss.ss_family = AST_AF_UNSPEC;
12893 if (!(sock = ast_netsock_find(netsock, &addr)))
12894 sock = ast_netsock_find(outsock, &addr);
12896 sockfd = ast_netsock_sockfd(sock);
12902 if (ast_netsock_find(netsock, &addr)) {
12903 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12905 sockfd = ast_netsock_sockfd(sock);
12906 ast_netsock_unref(sock);
12918 if (nonlocal == 1) {
12919 ast_log(LOG_WARNING,
12920 "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12924 }
else if (nonlocal == 2) {
12925 ast_log(LOG_WARNING,
12926 "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12931 ast_debug(1,
"Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12936 static void peer_destructor(
void *obj)
12939 int callno = peer->
callno;
12944 ast_mutex_lock(&iaxsl[callno]);
12945 iax2_destroy(callno);
12946 ast_mutex_unlock(&iaxsl[callno]);
12949 register_peer_exten(peer, 0);
12971 int subscribe_acl_change = 0;
12974 peer = ao2_find(peers, name,
OBJ_KEY);
12975 if (peer && !ast_test_flag64(peer,
IAX_DELME))
12982 oldacl = peer->acl;
12986 }
else if ((peer = ao2_alloc(
sizeof(*peer), peer_destructor))) {
12989 peer->
sockfd = defaultsockfd;
12991 peer = peer_unref(peer);
12993 peer = peer_unref(peer);
13008 peer->
expiry = min_reg_expire;
13010 peer->prefs = prefs_global;
13016 peercnt_modify((
unsigned char) 0, 0, &peer->addr);
13032 if (!strcasecmp(v->
name,
"secret")) {
13034 }
else if (!strcasecmp(v->
name,
"mailbox")) {
13036 }
else if (!strcasecmp(v->
name,
"hasvoicemail")) {
13042 if (strchr(name,
'@')) {
13048 }
else if (!strcasecmp(v->
name,
"mohinterpret")) {
13050 }
else if (!strcasecmp(v->
name,
"mohsuggest")) {
13052 }
else if (!strcasecmp(v->
name,
"dbsecret")) {
13054 }
else if (!strcasecmp(v->
name,
"description")) {
13056 }
else if (!strcasecmp(v->
name,
"trunk")) {
13058 if (ast_test_flag64(peer,
IAX_TRUNK) && !timer) {
13059 ast_log(LOG_WARNING,
"Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
13062 }
else if (!strcasecmp(v->
name,
"auth")) {
13065 ast_log(LOG_WARNING,
"Auth method for peer '%s' is set to deprecated 'plaintext' at line %d of iax.conf\n", peer->name, v->lineno);
13067 }
else if (!strcasecmp(v->
name,
"encryption")) {
13072 }
else if (!strcasecmp(v->
name,
"forceencryption")) {
13081 }
else if (!strcasecmp(v->
name,
"transfer")) {
13082 if (!strcasecmp(v->
value,
"mediaonly")) {
13088 }
else if (!strcasecmp(v->
name,
"jitterbuffer")) {
13090 }
else if (!strcasecmp(v->
name,
"host")) {
13091 if (!strcasecmp(v->
value,
"dynamic")) {
13110 peer->addr.ss.ss_family = AST_AF_UNSPEC;
13113 return peer_unref(peer);
13119 }
else if (!strcasecmp(v->
name,
"defaultip")) {
13121 peer_defaddr_tmp.ss.ss_family = AF_UNSPEC;
13123 return peer_unref(peer);
13127 }
else if (!strcasecmp(v->
name,
"sourceaddress")) {
13129 }
else if (!strcasecmp(v->
name,
"permit") ||
13130 !strcasecmp(v->
name,
"deny") ||
13131 !strcasecmp(v->
name,
"acl")) {
13133 }
else if (!strcasecmp(v->
name,
"mask")) {
13136 }
else if (!strcasecmp(v->
name,
"context")) {
13138 }
else if (!strcasecmp(v->
name,
"regexten")) {
13140 }
else if (!strcasecmp(v->
name,
"peercontext")) {
13142 }
else if (!strcasecmp(v->
name,
"port")) {
13145 bindport = IAX_DEFAULT_PORTNO;
13152 }
else if (!strcasecmp(v->
name,
"username")) {
13154 }
else if (!strcasecmp(v->
name,
"allow")) {
13155 iax2_parse_allow_disallow(&peer->prefs, &peer->
capability, v->
value, 1);
13156 }
else if (!strcasecmp(v->
name,
"disallow")) {
13157 iax2_parse_allow_disallow(&peer->prefs, &peer->
capability, v->
value, 0);
13158 }
else if (!strcasecmp(v->
name,
"callerid")) {
13159 if (!ast_strlen_zero(v->
value)) {
13162 ast_callerid_split(v->
value, name2,
sizeof(name2), num2,
sizeof(num2));
13170 }
else if (!strcasecmp(v->
name,
"fullname")) {
13173 }
else if (!strcasecmp(v->
name,
"cid_number")) {
13176 }
else if (!strcasecmp(v->
name,
"sendani")) {
13178 }
else if (!strcasecmp(v->
name,
"inkeys")) {
13180 }
else if (!strcasecmp(v->
name,
"outkey")) {
13182 }
else if (!strcasecmp(v->
name,
"qualify")) {
13183 if (!strcasecmp(v->
value,
"no")) {
13185 }
else if (!strcasecmp(v->
value,
"yes")) {
13186 peer->
maxms = DEFAULT_MAXMS;
13187 }
else if (sscanf(v->
value,
"%30d", &peer->
maxms) != 1) {
13188 ast_log(LOG_WARNING,
"Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
13191 }
else if (!strcasecmp(v->
name,
"qualifysmoothing")) {
13193 }
else if (!strcasecmp(v->
name,
"qualifyfreqok")) {
13195 ast_log(LOG_WARNING,
"Qualification testing frequency of peer '%s' when OK should a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
13197 }
else if (!strcasecmp(v->
name,
"qualifyfreqnotok")) {
13199 ast_log(LOG_WARNING,
"Qualification testing frequency of peer '%s' when NOT OK should be a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
13201 }
else if (!strcasecmp(v->
name,
"timezone")) {
13203 }
else if (!strcasecmp(v->
name,
"adsi")) {
13205 }
else if (!strcasecmp(v->
name,
"connectedline")) {
13208 }
else if (!strcasecmp(v->
value,
"send")) {
13211 }
else if (!strcasecmp(v->
value,
"receive")) {
13217 }
else if (!strcasecmp(v->
name,
"maxcallnumbers")) {
13219 ast_log(LOG_WARNING,
"maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->
value, v->lineno);
13221 peercnt_modify((
unsigned char) 1, peer->
maxcallno, &peer->addr);
13223 }
else if (!strcasecmp(v->
name,
"requirecalltoken")) {
13227 }
else if (!strcasecmp(v->
value,
"auto")) {
13232 ast_log(LOG_WARNING,
"requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13268 if (subscribe_acl_change) {
13269 acl_change_stasis_subscribe();
13280 free_context(user->contexts);
13297 int oldcurauthreq = 0;
13298 int subscribe_acl_change = 0;
13299 char *varname = NULL, *varval = NULL;
13303 user = ao2_find(users, name,
OBJ_KEY);
13304 if (user && !ast_test_flag64(user,
IAX_DELME))
13311 oldacl = user->acl;
13312 oldcon = user->contexts;
13314 user->contexts = NULL;
13325 memset(user, 0,
sizeof(
struct iax2_user));
13327 user = user_unref(user);
13332 user->prefs = prefs_global;
13333 user->capability = iax2_capability;
13334 user->encmethods = iax2_encryption;
13335 user->authmethods = iax2_authmethods;
13353 if (!strcasecmp(v->
name,
"context")) {
13354 con = build_context(v->
value);
13359 user->contexts = con;
13362 }
else if (!strcasecmp(v->
name,
"permit") ||
13363 !strcasecmp(v->
name,
"deny") ||
13364 !strcasecmp(v->
name,
"acl")) {
13366 }
else if (!strcasecmp(v->
name,
"setvar")) {
13368 if ((varval = strchr(varname,
'='))) {
13371 if ((tmpvar = ast_variable_new(varname, varval,
""))) {
13373 tmpvar->
next = user->vars;
13374 user->vars = tmpvar;
13378 }
else if (!strcasecmp(v->
name,
"allow")) {
13379 iax2_parse_allow_disallow(&user->prefs, &user->capability, v->
value, 1);
13380 }
else if (!strcasecmp(v->
name,
"disallow")) {
13381 iax2_parse_allow_disallow(&user->prefs, &user->capability,v->
value, 0);
13382 }
else if (!strcasecmp(v->
name,
"trunk")) {
13384 if (ast_test_flag64(user,
IAX_TRUNK) && !timer) {
13385 ast_log(LOG_WARNING,
"Unable to support trunking on user '%s' without a timing interface\n", user->name);
13388 }
else if (!strcasecmp(v->
name,
"auth")) {
13389 user->authmethods = get_auth_methods(v->
value);
13390 if (user->authmethods & IAX_AUTH_PLAINTEXT) {
13391 ast_log(LOG_WARNING,
"Auth method for user '%s' is set to deprecated 'plaintext' at line %d of iax.conf\n", user->name, v->lineno);
13393 }
else if (!strcasecmp(v->
name,
"encryption")) {
13394 user->encmethods |= get_encrypt_methods(v->
value);
13395 if (!user->encmethods) {
13398 }
else if (!strcasecmp(v->
name,
"forceencryption")) {
13402 user->encmethods |= get_encrypt_methods(v->
value);
13403 if (user->encmethods) {
13407 }
else if (!strcasecmp(v->
name,
"transfer")) {
13408 if (!strcasecmp(v->
value,
"mediaonly")) {
13414 }
else if (!strcasecmp(v->
name,
"codecpriority")) {
13415 if(!strcasecmp(v->
value,
"caller"))
13417 else if(!strcasecmp(v->
value,
"disabled"))
13419 else if(!strcasecmp(v->
value,
"reqonly")) {
13423 }
else if (!strcasecmp(v->
name,
"immediate")) {
13425 }
else if (!strcasecmp(v->
name,
"jitterbuffer")) {
13427 }
else if (!strcasecmp(v->
name,
"dbsecret")) {
13429 }
else if (!strcasecmp(v->
name,
"secret")) {
13430 if (!ast_strlen_zero(user->secret)) {
13436 }
else if (!strcasecmp(v->
name,
"callerid")) {
13437 if (!ast_strlen_zero(v->
value) && strcasecmp(v->
value,
"asreceived")) {
13440 ast_callerid_split(v->
value, name2,
sizeof(name2), num2,
sizeof(num2));
13449 }
else if (!strcasecmp(v->
name,
"fullname")) {
13450 if (!ast_strlen_zero(v->
value)) {
13455 if (ast_strlen_zero(user->cid_num))
13458 }
else if (!strcasecmp(v->
name,
"cid_number")) {
13459 if (!ast_strlen_zero(v->
value)) {
13464 if (ast_strlen_zero(user->cid_name))
13467 }
else if (!strcasecmp(v->
name,
"accountcode")) {
13469 }
else if (!strcasecmp(v->
name,
"mohinterpret")) {
13471 }
else if (!strcasecmp(v->
name,
"mohsuggest")) {
13473 }
else if (!strcasecmp(v->
name,
"parkinglot")) {
13475 }
else if (!strcasecmp(v->
name,
"language")) {
13477 }
else if (!strcasecmp(v->
name,
"amaflags")) {
13480 ast_log(LOG_WARNING,
"Invalid AMA Flags: %s at line %d\n", v->
value, v->lineno);
13482 user->amaflags = format;
13484 }
else if (!strcasecmp(v->
name,
"inkeys")) {
13486 }
else if (!strcasecmp(v->
name,
"maxauthreq")) {
13490 }
else if (!strcasecmp(v->
name,
"adsi")) {
13492 }
else if (!strcasecmp(v->
name,
"connectedline")) {
13495 }
else if (!strcasecmp(v->
value,
"send")) {
13498 }
else if (!strcasecmp(v->
value,
"receive")) {
13504 }
else if (!strcasecmp(v->
name,
"requirecalltoken")) {
13508 }
else if (!strcasecmp(v->
value,
"auto")) {
13513 ast_log(LOG_WARNING,
"requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13523 if (!user->authmethods) {
13524 if (!ast_strlen_zero(user->secret)) {
13525 user->authmethods = IAX_AUTH_MD5;
13526 if (!ast_strlen_zero(user->
inkeys))
13527 user->authmethods |= IAX_AUTH_RSA;
13528 }
else if (!ast_strlen_zero(user->
inkeys)) {
13529 user->authmethods = IAX_AUTH_RSA;
13531 user->authmethods = IAX_AUTH_MD5;
13541 free_context(oldcon);
13544 if (subscribe_acl_change) {
13545 acl_change_stasis_subscribe();
13551 static int peer_delme_cb(
void *obj,
void *arg,
int flags)
13560 static int user_delme_cb(
void *obj,
void *arg,
int flags)
13571 struct iax2_registry *reg;
13581 int callno = reg->
callno;
13582 ast_mutex_lock(&iaxsl[callno]);
13583 if (iaxs[callno]) {
13584 iaxs[
callno]->reg = NULL;
13585 iax2_destroy(callno);
13587 ast_mutex_unlock(&iaxsl[callno]);
13598 static void prune_users(
void)
13604 while ((user = ao2_iterator_next(&i))) {
13614 static void prune_peers(
void)
13620 while ((peer = ao2_iterator_next(&i))) {
13629 static void set_config_destroy(
void)
13631 strcpy(accountcode,
"");
13632 strcpy(language,
"");
13633 strcpy(mohinterpret,
"");
13634 strcpy(mohsuggest,
"");
13653 const char *tosval;
13655 int portno = IAX_DEFAULT_PORTNO;
13658 int subscribe_network_change = 1;
13669 ast_log(LOG_ERROR,
"Unable to load config %s\n", config_file);
13671 }
else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13673 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13677 if ((cfg =
ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13678 ast_log(LOG_ERROR,
"Config file %s is in an invalid format. Aborting.\n", config_file);
13684 ast_log(LOG_ERROR,
"Unable to load config %s again\n", config_file);
13687 }
else if (cfg == CONFIG_STATUS_FILEINVALID) {
13688 ast_log(LOG_ERROR,
"Config file %s is in an invalid format. Aborting.\n", config_file);
13692 if ((ucfg =
ast_config_load(
"users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13693 ast_log(LOG_ERROR,
"Config file users.conf is in an invalid format. Aborting.\n");
13700 set_config_destroy();
13709 memset(&globalflags, 0,
sizeof(globalflags));
13717 default_parkinglot[0] =
'\0';
13722 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13723 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13728 iax2_authmethods = 0;
13730 v = ast_variable_browse(cfg,
"general");
13733 tosval = ast_variable_retrieve(cfg,
"general",
"tos");
13736 ast_log(LOG_WARNING,
"Invalid tos value, refer to QoS documentation\n");
13739 tosval = ast_variable_retrieve(cfg,
"general",
"cos");
13742 ast_log(LOG_WARNING,
"Invalid cos value, refer to QoS documentation\n");
13745 if (!strcasecmp(v->
name,
"bindport")) {
13747 ast_log(LOG_NOTICE,
"Ignoring bindport on reload\n");
13749 else if (
ast_parse_arg(v->
value, PARSE_UINT32 | PARSE_IN_RANGE, &portno, 1024, 65535)) {
13750 portno = IAX_DEFAULT_PORTNO;
13752 }
else if (!strcasecmp(v->
name,
"pingtime")){
13753 ping_time = atoi(v->
value);
13755 else if (!strcasecmp(v->
name,
"iaxthreadcount")) {
13757 if (atoi(v->
value) != iaxthreadcount)
13758 ast_log(LOG_NOTICE,
"Ignoring any changes to iaxthreadcount during reload\n");
13760 iaxthreadcount = atoi(v->
value);
13761 if (iaxthreadcount < 1) {
13762 ast_log(LOG_NOTICE,
"iaxthreadcount must be at least 1.\n");
13763 iaxthreadcount = 1;
13764 }
else if (iaxthreadcount > 256) {
13765 ast_log(LOG_NOTICE,
"limiting iaxthreadcount to 256\n");
13766 iaxthreadcount = 256;
13769 }
else if (!strcasecmp(v->
name,
"iaxmaxthreadcount")) {
13772 iaxmaxthreadcount = atoi(v->
value);
13775 iaxmaxthreadcount = atoi(v->
value);
13776 if (iaxmaxthreadcount < 0) {
13777 ast_log(LOG_NOTICE,
"iaxmaxthreadcount must be at least 0.\n");
13778 iaxmaxthreadcount = 0;
13779 }
else if (iaxmaxthreadcount > 256) {
13780 ast_log(LOG_NOTICE,
"Limiting iaxmaxthreadcount to 256\n");
13781 iaxmaxthreadcount = 256;
13784 }
else if (!strcasecmp(v->
name,
"nochecksums")) {
13792 ast_log(LOG_WARNING,
"Disabling RTP checksums is not supported on this operating system!\n");
13795 else if (!strcasecmp(v->
name,
"maxjitterbuffer"))
13796 maxjitterbuffer = atoi(v->
value);
13797 else if (!strcasecmp(v->
name,
"resyncthreshold"))
13798 resyncthreshold = atoi(v->
value);
13799 else if (!strcasecmp(v->
name,
"maxjitterinterps"))
13800 maxjitterinterps = atoi(v->
value);
13801 else if (!strcasecmp(v->
name,
"jittertargetextra"))
13802 jittertargetextra = atoi(v->
value);
13803 else if (!strcasecmp(v->
name,
"lagrqtime"))
13804 lagrq_time = atoi(v->
value);
13805 else if (!strcasecmp(v->
name,
"maxregexpire"))
13806 max_reg_expire = atoi(v->
value);
13807 else if (!strcasecmp(v->
name,
"minregexpire"))
13808 min_reg_expire = atoi(v->
value);
13809 else if (!strcasecmp(v->
name,
"bindaddr")) {
13811 ast_log(LOG_NOTICE,
"Ignoring bindaddr on reload\n");
13822 if (!(ns = ast_netsock_bindaddr(netsock, io, &bindaddr, qos.tos, qos.cos, socket_read, NULL))) {
13823 ast_log(LOG_WARNING,
"Unable to apply binding to '%s' at line %d\n", v->
value, v->lineno);
13827 if (defaultsockfd < 0) {
13828 defaultsockfd = ast_netsock_sockfd(ns);
13830 ast_netsock_unref(ns);
13834 ast_log(LOG_WARNING,
"Invalid address '%s' specified, at line %d\n", v->
value, v->lineno);
13837 }
else if (!strcasecmp(v->
name,
"auth")) {
13838 iax2_authmethods = get_auth_methods(v->
value);
13839 if (iax2_authmethods & IAX_AUTH_PLAINTEXT) {
13840 ast_log(LOG_WARNING,
"Default auth method is set to deprecated 'plaintext' at line %d of iax.conf\n", v->lineno);
13842 }
else if (!strcasecmp(v->
name,
"authdebug")) {
13844 }
else if (!strcasecmp(v->
name,
"encryption")) {
13845 iax2_encryption |= get_encrypt_methods(v->
value);
13846 if (!iax2_encryption) {
13849 }
else if (!strcasecmp(v->
name,
"forceencryption")) {
13853 iax2_encryption |= get_encrypt_methods(v->
value);
13854 if (iax2_encryption) {
13858 }
else if (!strcasecmp(v->
name,
"transfer")) {
13859 if (!strcasecmp(v->
value,
"mediaonly")) {
13865 }
else if (!strcasecmp(v->
name,
"codecpriority")) {
13866 if(!strcasecmp(v->
value,
"caller"))
13868 else if(!strcasecmp(v->
value,
"disabled"))
13870 else if(!strcasecmp(v->
value,
"reqonly")) {
13874 }
else if (!strcasecmp(v->
name,
"jitterbuffer"))
13876 else if (!strcasecmp(v->
name,
"delayreject"))
13878 else if (!strcasecmp(v->
name,
"allowfwdownload"))
13880 else if (!strcasecmp(v->
name,
"rtcachefriends"))
13882 else if (!strcasecmp(v->
name,
"rtignoreregexpire"))
13884 else if (!strcasecmp(v->
name,
"rtupdate"))
13886 else if (!strcasecmp(v->
name,
"rtsavesysname"))
13888 else if (!strcasecmp(v->
name,
"trunktimestamps"))
13890 else if (!strcasecmp(v->
name,
"rtautoclear")) {
13891 int i = atoi(v->
value);
13893 global_rtautoclear = i;
13897 }
else if (!strcasecmp(v->
name,
"trunkfreq")) {
13898 trunkfreq = atoi(v->
value);
13899 if (trunkfreq < 10) {
13900 ast_log(LOG_NOTICE,
"trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13902 }
else if (trunkfreq > 1000) {
13903 ast_log(LOG_NOTICE,
"trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13909 }
else if (!strcasecmp(v->
name,
"trunkmtu")) {
13910 mtuv = atoi(v->
value);
13913 else if (mtuv >= 172 && mtuv < 4000)
13916 ast_log(LOG_NOTICE,
"trunkmtu value out of bounds (%d) at line %d\n",
13918 }
else if (!strcasecmp(v->
name,
"trunkmaxsize")) {
13919 trunkmaxsize = atoi(v->
value);
13920 if (trunkmaxsize == 0)
13922 }
else if (!strcasecmp(v->
name,
"autokill")) {
13923 if (sscanf(v->
value,
"%30d", &x) == 1) {
13927 ast_log(LOG_NOTICE,
"Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13929 autokill = DEFAULT_MAXMS;
13933 }
else if (!strcasecmp(v->
name,
"bandwidth")) {
13934 if (!strcasecmp(v->
value,
"low")) {
13936 IAX_CAPABILITY_LOWBANDWIDTH);
13937 }
else if (!strcasecmp(v->
value,
"medium")) {
13939 IAX_CAPABILITY_MEDBANDWIDTH);
13940 }
else if (!strcasecmp(v->
value,
"high")) {
13942 IAX_CAPABILITY_FULLBANDWIDTH);
13944 ast_log(LOG_WARNING,
"bandwidth must be either low, medium, or high\n");
13946 }
else if (!strcasecmp(v->
name,
"allow")) {
13947 iax2_parse_allow_disallow(&prefs_new, &capability, v->
value, 1);
13948 }
else if (!strcasecmp(v->
name,
"disallow")) {
13949 iax2_parse_allow_disallow(&prefs_new, &capability, v->
value, 0);
13950 }
else if (!strcasecmp(v->
name,
"register")) {
13951 iax2_register(v->
value, v->lineno);
13952 }
else if (!strcasecmp(v->
name,
"iaxcompat")) {
13954 }
else if (!strcasecmp(v->
name,
"regcontext")) {
13958 }
else if (!strcasecmp(v->
name,
"tos")) {
13960 ast_log(LOG_WARNING,
"Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13961 }
else if (!strcasecmp(v->
name,
"cos")) {
13963 ast_log(LOG_WARNING,
"Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13964 }
else if (!strcasecmp(v->
name,
"parkinglot")) {
13966 }
else if (!strcasecmp(v->
name,
"accountcode")) {
13968 }
else if (!strcasecmp(v->
name,
"mohinterpret")) {
13970 }
else if (!strcasecmp(v->
name,
"mohsuggest")) {
13972 }
else if (!strcasecmp(v->
name,
"amaflags")) {
13975 ast_log(LOG_WARNING,
"Invalid AMA Flags: %s at line %d\n", v->
value, v->lineno);
13979 }
else if (!strcasecmp(v->
name,
"language")) {
13981 }
else if (!strcasecmp(v->
name,
"maxauthreq")) {
13982 maxauthreq = atoi(v->
value);
13983 if (maxauthreq < 0)
13985 }
else if (!strcasecmp(v->
name,
"adsi")) {
13987 }
else if (!strcasecmp(v->
name,
"srvlookup")) {
13989 }
else if (!strcasecmp(v->
name,
"connectedline")) {
13992 }
else if (!strcasecmp(v->
value,
"send")) {
13995 }
else if (!strcasecmp(v->
value,
"receive")) {
14001 }
else if (!strcasecmp(v->
name,
"maxcallnumbers")) {
14002 if (sscanf(v->
value,
"%10hu", &global_maxcallno) != 1) {
14003 ast_log(LOG_WARNING,
"maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->
value, v->lineno);
14005 }
else if (!strcasecmp(v->
name,
"maxcallnumbers_nonvalidated")) {
14006 if (sscanf(v->
value,
"%10hu", &global_maxcallno_nonval) != 1) {
14007 ast_log(LOG_WARNING,
"maxcallnumbers_nonvalidated must be set to a valid number. %s is not valid at line %d.\n", v->
value, v->lineno);
14009 }
else if (!strcasecmp(v->
name,
"calltokenoptional")) {
14010 if (add_calltoken_ignore(v->
value)) {
14011 ast_log(LOG_WARNING,
"Invalid calltokenoptional address range - '%s' line %d\n", v->
value, v->lineno);
14014 }
else if (!strcasecmp(v->
name,
"calltokenexpiration")) {
14016 sscanf(v->
value,
"%u", &temp);
14018 ast_log(LOG_WARNING,
"Invalid calltokenexpiration value %s. Should be integer greater than 0.\n", v->
value);
14020 max_calltoken_delay = temp;
14022 }
else if (!strcasecmp(v->
name,
"subscribe_network_change_event")) {
14024 subscribe_network_change = 1;
14026 subscribe_network_change = 0;
14028 ast_log(LOG_WARNING,
"subscribe_network_change_event value %s is not valid at line %d.\n", v->
value, v->lineno);
14030 }
else if (!strcasecmp(v->
name,
"shrinkcallerid")) {
14036 ast_log(LOG_WARNING,
"shrinkcallerid value %s is not valid at line %d.\n", v->
value, v->lineno);
14043 if (subscribe_network_change) {
14044 network_change_stasis_subscribe();
14046 network_change_stasis_unsubscribe();
14049 if (defaultsockfd < 0) {
14053 if (!(ns = ast_netsock_bindaddr(netsock, io, &bindaddr, qos.tos, qos.cos, socket_read, NULL))) {
14054 ast_log(LOG_ERROR,
"Unable to create network socket: %s\n", strerror(errno));
14057 defaultsockfd = ast_netsock_sockfd(ns);
14058 ast_netsock_unref(ns);
14062 ast_netsock_release(outsock);
14063 outsock = ast_netsock_list_alloc();
14065 ast_log(LOG_ERROR,
"Could not allocate outsock list.\n");
14068 ast_netsock_init(outsock);
14071 if (min_reg_expire > max_reg_expire) {
14072 ast_log(LOG_WARNING,
"Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
14073 min_reg_expire, max_reg_expire, max_reg_expire);
14074 min_reg_expire = max_reg_expire;
14076 prefs_global = prefs_new;
14077 iax2_capability = capability;
14082 int genregisteriax;
14083 const char *hasiax, *registeriax;
14085 genhasiax =
ast_true(ast_variable_retrieve(ucfg,
"general",
"hasiax"));
14086 genregisteriax =
ast_true(ast_variable_retrieve(ucfg,
"general",
"registeriax"));
14087 gen = ast_variable_browse(ucfg,
"general");
14090 if (strcasecmp(cat,
"general")) {
14091 hasiax = ast_variable_retrieve(ucfg, cat,
"hasiax");
14092 registeriax = ast_variable_retrieve(ucfg, cat,
"registeriax");
14093 if (
ast_true(hasiax) || (!hasiax && genhasiax)) {
14095 user =
build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
14098 user = user_unref(user);
14100 peer =
build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
14103 reg_source_db(peer);
14106 peer = peer_unref(peer);
14109 if (
ast_true(registeriax) || (!registeriax && genregisteriax)) {
14111 const char *host = ast_variable_retrieve(ucfg, cat,
"host");
14112 const char *username = ast_variable_retrieve(ucfg, cat,
"username");
14113 const char *secret = ast_variable_retrieve(ucfg, cat,
"secret");
14115 host = ast_variable_retrieve(ucfg,
"general",
"host");
14117 username = ast_variable_retrieve(ucfg,
"general",
"username");
14119 secret = ast_variable_retrieve(ucfg,
"general",
"secret");
14120 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
14121 if (!ast_strlen_zero(secret))
14122 snprintf(tmp,
sizeof(tmp),
"%s:%s@%s", username, secret, host);
14124 snprintf(tmp,
sizeof(tmp),
"%s@%s", username, host);
14125 iax2_register(tmp, 0);
14136 if (strcasecmp(cat,
"general")) {
14137 utype = ast_variable_retrieve(cfg, cat,
"type");
14138 if (!strcasecmp(cat,
"callnumberlimits")) {
14139 build_callno_limits(ast_variable_browse(cfg, cat));
14140 }
else if (utype) {
14141 if (!strcasecmp(utype,
"user") || !strcasecmp(utype,
"friend")) {
14142 user =
build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
14145 user = user_unref(user);
14148 if (!strcasecmp(utype,
"peer") || !strcasecmp(utype,
"friend")) {
14149 peer =
build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
14152 reg_source_db(peer);
14154 peer = peer_unref(peer);
14156 }
else if (strcasecmp(utype,
"user")) {
14157 ast_log(LOG_WARNING,
"Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
14160 ast_log(LOG_WARNING,
"Section '%s' lacks type\n", cat);
14168 static void poke_all_peers(
void)
14174 while ((peer = ao2_iterator_next(&i))) {
14175 iax2_poke_peer(peer, 0);
14180 static int reload_config(
int forced_reload)
14182 static const char config[] =
"iax.conf";
14183 struct iax2_registry *reg;
14185 if (
set_config(config, 1, forced_reload) > 0) {
14191 trunk_timed = trunk_untimed = 0;
14193 memset(&debugaddr,
'\0',
sizeof(debugaddr));
14197 iax2_do_register(reg);
14204 iax_firmware_reload();
14205 iax_provision_reload(1);
14217 "Usage: iax2 reload\n"
14218 " Reloads IAX configuration from iax.conf\n";
14226 return CLI_SUCCESS;
14229 static int reload(
void)
14231 return reload_config(0);
14234 static int cache_get_callno_locked(
const char *data)
14244 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14247 if (!ast_mutex_trylock(&iaxsl[x])) {
14248 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
14250 ast_mutex_unlock(&iaxsl[x]);
14256 memset(&cai, 0,
sizeof(cai));
14257 memset(&ied, 0,
sizeof(ied));
14258 memset(&pds, 0,
sizeof(pds));
14263 if (ast_strlen_zero(pds.peer)) {
14264 ast_log(LOG_WARNING,
"No peer provided in the IAX2 dial string '%s'\n", data);
14269 if (create_addr(pds.peer, NULL, &addr, &cai))
14272 ast_debug(1,
"peer: %s, username: %s, password: %s, context: %s\n",
14273 pds.peer, pds.username, pds.password, pds.context);
14275 callno = find_callno_locked(0, 0, &addr, NEW_FORCE, cai.sockfd, 0);
14277 ast_log(LOG_WARNING,
"Unable to create call\n");
14282 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
14293 iax_ie_append_int(&ied,
IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
14301 add_empty_calltoken_ie(iaxs[callno], &ied);
14302 send_command(iaxs[callno],
AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
14307 static struct iax2_dpcache *find_cache(
struct ast_channel *chan,
const char *data,
const char *context,
const char *exten,
int priority)
14311 int x, com[2], timeout, doabort, callno;
14317 ast_log(LOG_WARNING,
"DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
14322 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
14330 if ((callno = cache_get_callno_locked(data)) < 0) {
14331 ast_log(LOG_WARNING,
"Unable to generate call for '%s'\n", data);
14335 ast_mutex_unlock(&iaxsl[callno]);
14341 dp->orig = dp->expiry;
14343 dp->expiry.tv_sec += iaxdefaultdpcache;
14345 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
14346 dp->waiters[x] = -1;
14351 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
14352 iax2_dprequest(dp, callno);
14353 ast_mutex_unlock(&iaxsl[callno]);
14362 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14364 if (dp->waiters[x] < 0)
14367 if (x >= ARRAY_LEN(dp->waiters)) {
14368 ast_log(LOG_WARNING,
"No more waiter positions available\n");
14372 ast_log(LOG_WARNING,
"Unable to create pipe for comm\n");
14375 dp->waiters[x] = com[1];
14377 timeout = iaxdefaulttimeout * 1000;
14384 pfd.events = POLLIN;
14387 res = ast_poll(&pfd, 1, timeout);
14389 ast_log(LOG_WARNING,
"poll returned < 0: %s\n", strerror(errno));
14391 }
else if (!pfd.revents) {
14392 ast_log(LOG_WARNING,
"Timeout waiting for %s exten %s\n", data, exten);
14400 dp->waiters[x] = -1;
14416 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
14417 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14418 if (dp->waiters[x] > -1) {
14419 if (write(dp->waiters[x],
"asdf", 4) < 0) {
14420 ast_log(LOG_WARNING,
"write() failed: %s\n", strerror(errno));
14432 static int iax2_exists(
struct ast_channel *chan,
const char *context,
const char *exten,
int priority,
const char *callerid,
const char *data)
14437 ast_log(LOG_NOTICE,
"iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid :
"<unknown>", data);
14439 if ((priority != 1) && (priority != 2))
14443 if ((dp = find_cache(chan, data, context, exten, priority))) {
14447 ast_log(LOG_WARNING,
"Unable to make DP cache\n");
14455 static int iax2_canmatch(
struct ast_channel *chan,
const char *context,
const char *exten,
int priority,
const char *callerid,
const char *data)
14460 ast_log(LOG_NOTICE,
"iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid :
"<unknown>", data);
14462 if ((priority != 1) && (priority != 2))
14466 if ((dp = find_cache(chan, data, context, exten, priority))) {
14470 ast_log(LOG_WARNING,
"Unable to make DP cache\n");
14478 static int iax2_matchmore(
struct ast_channel *chan,
const char *context,
const char *exten,
int priority,
const char *callerid,
const char *data)
14483 ast_log(LOG_NOTICE,
"iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid :
"<unknown>", data);
14485 if ((priority != 1) && (priority != 2))
14489 if ((dp = find_cache(chan, data, context, exten, priority))) {
14493 ast_log(LOG_WARNING,
"Unable to make DP cache\n");
14501 static int iax2_exec(
struct ast_channel *chan,
const char *context,
const char *exten,
int priority,
const char *callerid,
const char *data)
14509 ast_log(LOG_NOTICE,
"iax2_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s, newstack: %d\n", context, exten, priority, callerid ? callerid :
"<unknown>", data, newstack);
14511 if (priority == 2) {
14520 }
else if (priority != 1)
14524 if ((dp = find_cache(chan, data, context, exten, priority))) {
14527 ncontext = strchr(odata,
'/');
14531 snprintf(req,
sizeof(req),
"IAX2/%s/%s@%s", odata, exten, ncontext);
14533 snprintf(req,
sizeof(req),
"IAX2/%s/%s", odata, exten);
14535 ast_verb(3,
"Executing Dial('%s')\n", req);
14538 ast_log(LOG_WARNING,
"Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
14547 ast_log(LOG_WARNING,
"No dial application registered\n");
14552 static int function_iaxpeer(
struct ast_channel *chan,
const char *cmd,
char *data,
char *buf,
size_t len)
14555 char *peername, *colname;
14560 if (!strcmp(peername,
"CURRENTCHANNEL")) {
14565 callno = PTR_TO_CALLNO(ast_channel_tech_pvt(chan));
14570 if ((colname = strchr(peername,
',')))
14578 if (!strcasecmp(colname,
"ip")) {
14580 }
else if (!strcasecmp(colname,
"status")) {
14582 }
else if (!strcasecmp(colname,
"mailbox")) {
14584 }
else if (!strcasecmp(colname,
"context")) {
14586 }
else if (!strcasecmp(colname,
"expire")) {
14587 snprintf(buf, len,
"%d", peer->
expire);
14588 }
else if (!strcasecmp(colname,
"dynamic")) {
14590 }
else if (!strcasecmp(colname,
"callerid_name")) {
14592 }
else if (!strcasecmp(colname,
"callerid_num")) {
14594 }
else if (!strcasecmp(colname,
"codecs")) {
14597 iax2_getformatname_multiple(peer->
capability, &codec_buf);
14599 }
else if (!strncasecmp(colname,
"codec[", 6)) {
14600 char *codecnum, *ptr;
14604 codecnum = colname + 5;
14607 if ((ptr = strchr(codecnum,
']'))) {
14626 .read = function_iaxpeer,
14629 static int acf_channel_read(
struct ast_channel *chan,
const char *funcname,
char *args,
char *buf,
size_t buflen)
14636 ast_log(LOG_ERROR,
"This function requires a valid IAX2 channel\n");
14640 callno = PTR_TO_CALLNO(ast_channel_tech_pvt(chan));
14641 ast_mutex_lock(&iaxsl[callno]);
14642 if (!(pvt = iaxs[callno])) {
14643 ast_mutex_unlock(&iaxsl[callno]);
14647 if (!strcasecmp(args,
"osptoken")) {
14649 }
else if (!strcasecmp(args,
"peerip")) {
14651 }
else if (!strcasecmp(args,
"peername")) {
14653 }
else if (!strcasecmp(args,
"secure_signaling") || !strcasecmp(args,
"secure_media")) {
14654 snprintf(buf, buflen,
"%s", IAX_CALLENCRYPTED(pvt) ?
"1" :
"");
14659 ast_mutex_unlock(&iaxsl[callno]);
14672 memset(&pds, 0,
sizeof(pds));
14675 if (ast_strlen_zero(pds.peer)) {
14676 ast_log(LOG_WARNING,
"No peer provided in the IAX2 dial string '%s'\n", data);
14680 ast_debug(3,
"Checking device state for device %s\n", pds.peer);
14688 ast_debug(3,
"Found peer. What's device state of %s? addr=%s, defaddr=%s maxms=%d, lastms=%d\n",
14708 .description =
"IAX Remote Dialplan Switch",
14716 AST_CLI_DEFINE(handle_cli_iax2_provision,
"Provision an IAX device"),
14717 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime,
"Prune a cached realtime lookup"),
14718 AST_CLI_DEFINE(handle_cli_iax2_reload,
"Reload IAX configuration"),
14720 AST_CLI_DEFINE(handle_cli_iax2_set_debug,
"Enable/Disable IAX debugging"),
14721 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk,
"Enable/Disable IAX trunk debugging"),
14722 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb,
"Enable/Disable IAX jitterbuffer debugging"),
14723 AST_CLI_DEFINE(handle_cli_iax2_show_cache,
"Display IAX cached dialplan"),
14724 AST_CLI_DEFINE(handle_cli_iax2_show_channels,
"List active IAX channels"),
14725 AST_CLI_DEFINE(handle_cli_iax2_show_firmware,
"List available IAX firmware"),
14726 AST_CLI_DEFINE(handle_cli_iax2_show_netstats,
"List active IAX channel netstats"),
14728 AST_CLI_DEFINE(handle_cli_iax2_show_peers,
"List defined IAX peers"),
14729 AST_CLI_DEFINE(handle_cli_iax2_show_registry,
"Display IAX registration status"),
14730 AST_CLI_DEFINE(handle_cli_iax2_show_stats,
"Display IAX statistics"),
14731 AST_CLI_DEFINE(handle_cli_iax2_show_threads,
"Display IAX helper thread info"),
14732 AST_CLI_DEFINE(handle_cli_iax2_show_users,
"List defined IAX users"),
14733 AST_CLI_DEFINE(handle_cli_iax2_test_losspct,
"Set IAX2 incoming frame loss percentage"),
14734 AST_CLI_DEFINE(handle_cli_iax2_unregister,
"Unregister (force expiration) an IAX2 peer from the registry"),
14735 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits,
"Show current entries in IP call number limit table"),
14737 AST_CLI_DEFINE(handle_cli_iax2_test_jitter,
"Simulates jitter for testing"),
14738 AST_CLI_DEFINE(handle_cli_iax2_test_late,
"Test the receipt of a late frame"),
14739 AST_CLI_DEFINE(handle_cli_iax2_test_resync,
"Test a resync in received timestamps"),
14743 static void cleanup_thread_list(
void *head)
14746 struct iax2_thread_list *list_head = head;
14751 pthread_t thread_id = thread->threadid;
14754 signal_condition(&thread->lock, &thread->cond);
14757 pthread_join(thread_id, NULL);
14763 static int __unload_module(
void)
14767 network_change_stasis_unsubscribe();
14768 acl_change_stasis_unsubscribe();
14779 if (netthreadid != AST_PTHREADT_NULL) {
14780 pthread_cancel(netthreadid);
14781 pthread_kill(netthreadid, SIGURG);
14782 pthread_join(netthreadid, NULL);
14785 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14796 ast_netsock_release(netsock);
14797 ast_netsock_release(outsock);
14798 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14812 iax_provision_unload();
14813 iax_firmware_unload();
14815 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14816 ast_mutex_destroy(&iaxsl[x]);
14821 ao2_ref(iax_peercallno_pvts, -1);
14822 ao2_ref(iax_transfercallno_pvts, -1);
14824 ao2_ref(calltoken_ignores, -1);
14844 static int unload_module(
void)
14848 return __unload_module();
14851 static int peer_set_sock_cb(
void *obj,
void *arg,
int flags)
14856 peer->
sockfd = defaultsockfd;
14861 static int pvt_hash_cb(
const void *obj,
const int flags)
14868 static int pvt_cmp_cb(
void *obj,
void *arg,
int flags)
14875 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14879 static int transfercallno_pvt_hash_cb(
const void *obj,
const int flags)
14886 static int transfercallno_pvt_cmp_cb(
void *obj,
void *arg,
int flags)
14893 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14897 static int load_objects(
void)
14899 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14900 peercnts = callno_limits = calltoken_ignores = NULL;
14905 goto container_fail;
14911 goto container_fail;
14915 IAX_MAX_CALLS, pvt_hash_cb, NULL, pvt_cmp_cb);
14916 if (!iax_peercallno_pvts) {
14917 goto container_fail;
14921 IAX_MAX_CALLS, transfercallno_pvt_hash_cb, NULL, transfercallno_pvt_cmp_cb);
14922 if (!iax_transfercallno_pvts) {
14923 goto container_fail;
14927 peercnt_hash_cb, NULL, peercnt_cmp_cb);
14929 goto container_fail;
14934 if (!callno_limits) {
14935 goto container_fail;
14940 if (!calltoken_ignores) {
14941 goto container_fail;
14944 if (create_callno_pools()) {
14945 goto container_fail;
14949 if (!transmit_processor) {
14950 goto container_fail;
14962 if (iax_peercallno_pvts) {
14963 ao2_ref(iax_peercallno_pvts, -1);
14965 if (iax_transfercallno_pvts) {
14966 ao2_ref(iax_transfercallno_pvts, -1);
14971 if (callno_limits) {
14974 if (calltoken_ignores) {
14975 ao2_ref(calltoken_ignores, -1);
14992 static const char config[] =
"iax.conf";
14994 struct iax2_registry *reg = NULL;
15001 if (load_objects()) {
15007 memset(iaxs, 0,
sizeof(iaxs));
15009 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
15010 ast_mutex_init(&iaxsl[x]);
15014 ast_log(LOG_ERROR,
"Failed to create scheduler thread\n");
15029 ast_log(LOG_ERROR,
"Failed to create I/O context\n");
15037 if (!(netsock = ast_netsock_list_alloc())) {
15038 ast_log(LOG_ERROR,
"Failed to create netsock list\n");
15046 ast_netsock_init(netsock);
15048 outsock = ast_netsock_list_alloc();
15050 ast_log(LOG_ERROR,
"Could not allocate outsock list.\n");
15058 ast_netsock_init(outsock);
15060 randomcalltokendata = ast_random();
15062 iax_set_output(iax_debug_output);
15063 iax_set_error(iax_error_output);
15064 jb_setoutput(jb_error_output, jb_warning_output, NULL);
15092 ast_log(LOG_ERROR,
"Unable to register channel class %s\n",
"IAX2");
15098 ast_log(LOG_ERROR,
"Unable to register IAX switch\n");
15101 if (start_network_thread()) {
15102 ast_log(LOG_ERROR,
"Unable to start network thread\n");
15106 ast_verb(2,
"IAX Ready and Listening\n");
15111 iax2_do_register(reg);
15118 iax_firmware_reload();
15119 iax_provision_reload(0);
15121 ast_realtime_require_field(
"iaxpeers",
"name", RQ_CHAR, 10,
"ipaddr", RQ_CHAR, 15,
"port", RQ_UINTEGER2, 5,
"regseconds", RQ_UINTEGER2, 6, SENTINEL);
15123 network_change_stasis_subscribe();
15128 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,
"Inter Asterisk eXchange (Ver 2)",
15129 .support_level = AST_MODULE_SUPPORT_CORE,
15131 .unload = unload_module,
15134 .requires =
"dnsmgr",
15135 .optional_modules =
"res_crypto",
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)]
chan_iax2_pvt structure locks
int ast_sched_start_thread(struct ast_sched_context *con)
Start a thread for processing scheduler entries.
struct ast_variable * next
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
Require call token validation after a successful registration using call token validation occurs...
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
static int load_module(void)
Load the module.
static uint16_t global_maxcallno_nonval
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
int presentation
Q.931 encoded presentation-indicator encoded field.
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
#define IAX_IE_IAX_UNKNOWN
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
const ast_string_field secret
const ast_string_field rdnis
Main Channel structure associated with a channel.
struct timeval lasttxtime
static int iax2_ack_registry(struct iax_ies *ies, struct ast_sockaddr *addr, int callno)
Acknowledgment received for OUR registration.
void ast_sched_clean_by_callback(struct ast_sched_context *con, ast_sched_cb match, ast_sched_cb cleanup_cb)
Clean all scheduled events with matching callback.
#define IAX_RTSAVE_SYSNAME
char * str
Subscriber phone number (Malloced)
#define IAX_TRUNKTIMESTAMPS
ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
Wrapper around sendto(2) that uses ast_sockaddr.
#define IAX_IE_CAPABILITY2
Security Event Reporting API.
#define AST_LIST_LOCK(head)
Locks a list.
Asterisk locking-related definitions:
void astman_append(struct mansession *s, const char *fmt,...)
static int make_trunk(unsigned short callno, int locked)
#define IAX_IE_CALLINGTNS
const ast_string_field osptoken
Asterisk main include file. File version handling, generic pbx functions.
void * ast_mwi_unsubscribe(struct ast_mwi_subscriber *sub)
Unsubscribe from the stasis topic and MWI.
#define ast_realloc(p, len)
A wrapper for realloc()
struct stasis_topic * ast_system_topic(void)
A Stasis Message Bus API topic which publishes messages regarding system changes. ...
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
const ast_string_field cid_num
char * str
Subscriber phone number (Malloced)
char chan_name[AST_CHANNEL_NAME]
static struct iax2_peer * find_peer(const char *name, int realtime)
const ast_string_field exten
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
static int iax2_predestroy(int callno)
#define AST_OPTION_TXGAIN
unsigned char calltoken_ie_len
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *p_result,...)
The argument parsing routine.
const ast_string_field dnid
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
static void handle_deferred_full_frames(struct iax2_thread *thread)
Handle any deferred full frames for this thread.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
static struct iax2_peer * realtime_peer(const char *peername, struct ast_sockaddr *addr)
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
struct ast_party_id id
Connected party ID.
static struct ao2_container * iax_peercallno_pvts
Another container of iax2_pvt structures.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define ast_channel_unref(c)
Decrease channel reference count.
struct iax2_registry * reg
struct ast_endpoint * ast_endpoint_create(const char *tech, const char *resource)
Create an endpoint struct.
static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
part of the IAX2 dial plan switch interface
const ast_string_field description
Support for translation of data formats. translate.c.
#define IAX_SHRINKCALLERID
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_party_name name
Subscriber name.
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
#define IAX_META_TRUNK_MINI
struct ast_variable * vars
static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Part of the IAX2 Switch interface.
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
iax2_format peercapability
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
const char * iax2_getformatname(iax2_format format)
iax2 wrapper function for ast_getformatname
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
descriptor for a cli entry.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
static int iax2_queue_frame(int callno, struct ast_frame *f)
Queue a frame to a call's owning asterisk channel.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
AST_JSON_INT_T ast_json_int_t
Primarily used to cast when packing to an "I" type.
enum iax_transfer_state transferring
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary...
Provide cryptographic signature routines.
int ast_unload_realtime(const char *family)
Release any resources cached for a realtime family.
unsigned char semirand[32]
#define IAX_ENCRYPT_KEYROTATE
struct iax2_codec_pref rprefs
#define IAX_FORCE_ENCRYPT
const ast_string_field inkeys
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
#define IAX_DEFAULT_REG_EXPIRE
#define IAX_DELAYPBXSTART
#define IAX_LINGER_TIMEOUT
static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Execute IAX2 dialplan switch.
Structure for variables, used for configurations and for channel variables.
static pj_pool_t * pool
Global memory pool for configuration and timers.
#define IAX_IE_MD5_RESULT
const ast_string_field challenge
#define MAX_TIMESTAMP_SKEW
unsigned short bridgecallno
struct ast_variable * iaxvars
#define IAX_IE_FIRMWAREVER
enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now)
queue a frame
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
return a reference to a taskprocessor, create one if it does not exist
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
static struct stasis_subscription * network_change_sub
const ast_string_field language
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
Structure to pass both assignedid values to channel drivers.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
struct stasis_message_type * ast_named_acl_change_type(void)
a stasis_message_type for changes against a named ACL or the set of all named ACLs ...
Structure for a data store type.
ast_channel_state
ast_channel states
struct ast_timer * ast_timer_open(void)
Open a timer.
static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
unsigned char semirand[32]
uint64_t iax2_codec_pref_from_bitfield(struct iax2_codec_pref *pref, uint64_t bitfield)
Create codec preference list from the given bitfield formats.
char * str
Subscriber name (Malloced)
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
void ast_unregister_switch(struct ast_switch *sw)
Unregister an alternative switch.
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
static struct @114 frame_queue[IAX_MAX_CALLS]
a list of frames that may need to be retransmitted
void iax2_codec_pref_remove_missing(struct iax2_codec_pref *pref, uint64_t bitfield)
Removes format from the pref list that aren't in the bitfield.
#define IAX_CODEC_NOPREFS
Background DNS update manager.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
unsigned short transfercallno
void iax2_codec_pref_prepend(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing, int only_if_existing)
Prepend an audio codec to a preference list, removing it first if it was already there.
ast_control_frame_type
Internal control frame subtype field values.
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define IAX_IE_AUTOANSWER
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
struct ast_dnsmgr_entry * dnsmgr
void ast_endpoint_set_state(struct ast_endpoint *endpoint, enum ast_endpoint_state state)
Updates the state of the given endpoint.
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Wrapper for an ast_acl linked list.
#define IAX_CODEC_USER_FIRST
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
#define ast_strdup(str)
A wrapper for strdup()
Structure for a data store object.
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
static int iax2_devicestate(const char *data)
Part of the device state notification system —.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
calltoken_peer_enum
Call token validation settings.
enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl)
get a frame for time now (receiver's time) return value is one of JB_OK: You've got frame! JB_DROP: H...
I/O Management (derived from Cheops-NG)
static void send_signaling(struct chan_iax2_pvt *pvt)
This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.
static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
callno_entry callno_entry
int ast_dnsmgr_refresh(struct ast_dnsmgr_entry *entry)
Force a refresh of a dnsmgr entry.
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
static struct iax2_user * build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
Create in-memory user structure from configuration.
list of users found in the config file
Structure used to handle a large number of boolean flags == used only in app_dial?
int ast_unregister_application(const char *app)
Unregister an application.
static int update_registry(struct ast_sockaddr *addr, int callno, char *devtype, int fd, unsigned short refresh)
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
void ast_free_ptr(void *ptr)
free() wrapper
Socket address structure.
int iax2_codec_pref_best_bitfield2cap(uint64_t bitfield, struct iax2_codec_pref *prefs, struct ast_format_cap *cap)
Convert a bitfield to a format capabilities structure in the "best" order.
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
int ast_update_realtime(const char *family, const char *keyfield, const char *lookup,...) attribute_sentinel
Update realtime configuration.
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
callback to display iax peers in manager format
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
const ast_string_field inkeys
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
#define IAX_IE_CALLING_NUMBER
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
ast_aes_decrypt_key mydcx
int ast_translator_best_choice(struct ast_format_cap *dst_cap, struct ast_format_cap *src_cap, struct ast_format **dst_fmt_out, struct ast_format **src_fmt_out)
Chooses the best translation path.
Implementation of the IAX2 protocol.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
const ast_string_field parkinglot
static struct ao2_container * iax_transfercallno_pvts
Another container of iax2_pvt structures.
#define IAX_IE_CALLING_ANI
int ast_context_remove_extension(const char *context, const char *extension, int priority, const char *registrar)
Simply remove extension from context.
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
#define IAX_META_TRUNK_SUPERMINI
int args
This gets set in ast_cli_register()
int AST_OPTIONAL_API_NAME() ast_check_signature(struct ast_key *key, const char *msg, const char *sig)
base64 decode then sent to __ast_check_signature_bin
int ast_context_destroy_by_name(const char *context, const char *registrar)
Destroy a context by name.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
Queue the last read full frame for processing by a certain thread.
#define IAX_IE_ENCRYPTION
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
#define AST_MAX_ACCOUNT_CODE
static int register_verify(int callno, struct ast_sockaddr *addr, struct iax_ies *ies)
Verify inbound registration.
jitterbuf * jb_new(void)
new jitterbuf
enum ama_flags ast_channel_string2amaflag(const char *flag)
Convert a string to a detail record AMA flag.
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Custom localtime functions for multiple timezones.
uint64_t iax2_codec_pref_order_value_to_format_bitfield(int order_value)
Convert an iax2_codec_pref order value into a format bitfield.
internal representation of ACL entries In principle user applications would have no need for this...
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
struct ast_party_id id
Caller party ID.
static char * ast_sockaddr_stringify_port(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return a port only.
Configuration File Parser.
static const char config_file[]
int ast_get_time_t(const char *src, time_t *dst, time_t _default, int *consumed)
Parse a time (integer) string.
char * ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes)
Strip leading/trailing whitespace and quotes from a string.
static int global_max_trunk_mtu
static struct iax2_peer * build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
Create peer structure based on configuration.
long jb_next(jitterbuf *jb)
when is the next frame due out, in receiver's time (0=EMPTY) This value may change as frames are adde...
#define MAX_TRUNK_MTU
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516...
int ast_callid_threadassoc_remove(void)
Removes callid from thread storage of the calling thread.
static void * iax2_process_thread(void *data)
static void cleanup(void)
Clean up any old apps that we don't need any more.
#define ast_config_load(filename, flags)
Load a config file.
int ast_devstate_changed(enum ast_device_state state, enum ast_devstate_cache cachable, const char *fmt,...)
Tells Asterisk the State for Device is changed.
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
enum ast_transfer_result ast_bridge_transfer_blind(int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
Blind transfer target to the extension and context provided.
struct ast_party_id ani
Automatic Number Identification (ANI)
General Asterisk PBX channel definitions.
int ast_realtime_require_field(const char *family,...) attribute_sentinel
Inform realtime what fields that may be stored.
struct timeval txtrunktime
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
#define IAX_IE_CALLINGANI2
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it's bridge.
Asterisk file paths, configured in asterisk.conf.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
void io_context_destroy(struct io_context *ioc)
Destroys a context.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
static int iax2_lock_callno_unless_destroyed(int callno)
Acquire the iaxsl[callno] if call exists and not having ongoing hangup.
#define AST_OPTION_RELAXDTMF
int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
Replace a variable in the given list with a new value.
void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
Free a DNS manager entry.
static int peer_hash_cb(const void *obj, const int flags)
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
#define ast_strdupa(s)
duplicate a string in memory from the stack
int iax2_codec_pref_to_cap(struct iax2_codec_pref *pref, struct ast_format_cap *cap)
Convert a preference structure to a capabilities structure.
static struct call_number_pool callno_pool_trunk
Data structure associated with a custom dialplan function.
Access Control of various sorts.
IAX Firmware Support header file.
void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause)
Publish a channel driver outgoing registration message.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Global IO variables are now in a struct in order to be made threadsafe.
#define IAX_RTCACHEFRIENDS
#define AST_MAX_EXTENSION
unsigned short peercallno
Scheduler Routines (derived from cheops)
const ast_string_field zonetag
#define AST_STRING_FIELD(name)
Declare a string field.
struct stasis_cache * ast_mwi_state_cache(void)
Backend cache for ast_mwi_topic_cached().
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Asterisk internal frame definitions.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
#define IAX_IE_CALLING_NAME
In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
const ast_string_field regexten
const ast_string_field username
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
#define IAX_IE_PROVISIONING
Require call token validation.
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
static struct ao2_container * calltoken_ignores
static struct stasis_rest_handlers events
REST handler for /api-docs/events.json.
int ast_atomic_dec_and_test(volatile int *p)
decrement *p by 1 and return true if the variable has reached 0.
int AST_OPTIONAL_API_NAME() ast_sign(struct ast_key *key, char *msg, char *sig)
wrapper for __ast_sign_bin then base64 encode it
unsigned int ast_codec_samples_count(struct ast_frame *frame)
Get the number of samples contained within a frame.
void ast_channel_amaflags_set(struct ast_channel *chan, enum ama_flags value)
Default calltoken required unless the ip is in the ignorelist.
A set of macros to manage forward-linked lists.
#define ast_malloc(len)
A wrapper for malloc()
#define ast_debug(level,...)
Log a DEBUG message.
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
static int iax2_queue_unhold(int callno)
Queue an unhold frame on the ast_channel owner.
static int authenticate_reply(struct chan_iax2_pvt *p, struct ast_sockaddr *addr, struct iax_ies *ies, const char *override, const char *okey)
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
int ast_sockaddr_hash(const struct ast_sockaddr *addr)
Computes a hash value from the address. The port is ignored.
Core PBX routines and definitions.
int ast_sockaddr_apply_netmask(const struct ast_sockaddr *addr, const struct ast_sockaddr *netmask, struct ast_sockaddr *result)
Apply a netmask to an address and store the result in a separate structure.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
list of actions registered
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
static int __do_deliver(void *data)
#define IAX_RECVCONNECTEDLINE
enum calltoken_peer_enum calltoken_required
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
peer_status: Report Peer status in character string
void ast_sha1_hash(char *output, const char *input)
Produces SHA1 hash based on input string.
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
jitterbuf: an application-independent jitterbuffer jitterbuf.c
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
static int iax2_queue_hangup(int callno)
Queue a hangup frame on the ast_channel owner.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
ast_aes_decrypt_key mydcx
#define IAX_IE_CALLED_NUMBER
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
int ast_connected_line_parse_data(const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
Parse connected line indication frame data.
const ast_string_field outkey
IAX2 Provisioning protocol.
#define AST_OPTION_DIGIT_DETECT
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
#define IAX_MAX_OSPBLOCK_SIZE
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Implementation of Inter-Asterisk eXchange, version 2 parser.c parser.h chan_iax2.c.
Support for dynamic strings.
#define AST_OPTION_RXGAIN
const ast_string_field parkinglot
#define ao2_unlink(container, obj)
Remove an object from a container.
const ast_string_field peer
int iax2_codec_pref_string(struct iax2_codec_pref *pref, char *buf, size_t size)
Dump audio codec preference list into a string.
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
static struct chan_iax2_pvt * iaxs[IAX_MAX_CALLS]
an array of iax2 pvt structures
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
static char * handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Show one peer in detail.
enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
set jitterbuf conf
static struct ast_netsock_list * outsock
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
#define IAX_IE_AUTHMETHODS
struct iax2_peer * peerpoke
struct ast_mwi_subscriber * mwi_event_sub
struct stasis_message_type * ast_endpoint_state_type(void)
Message type for endpoint state changes.
int ani2
Automatic Number Identification 2 (Info Digits)
const ast_string_field inkeys
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
Connected Line/Party information.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
const ast_string_field name
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
ssize_t ast_recvfrom(int sockfd, void *buf, size_t len, int flags, struct ast_sockaddr *src_addr)
Wrapper around recvfrom(2) that uses struct ast_sockaddr.
Do not require call token validation.
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
void iax2_codec_pref_append(struct iax2_codec_pref *pref, struct ast_format *format, unsigned int framing)
Append a audio codec to a preference list, removing it first if it was already there.
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
#define ast_module_ref(mod)
Hold a reference to the module.
#define IAX_ALLOWFWDOWNLOAD
struct ast_format_cap * capabilities
const ast_string_field ani
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsoc...
const ast_string_field host
static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
callback to display iax peers in manager
#define IAX_TRANSFERMEDIA
void stasis_subscription_cb_noop(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Stasis subscription callback function that does nothing.
struct iax2_thread::@125 ffinfo
static void parse_dial_string(char *data, struct parsed_dial_string *pds)
Parses an IAX dial string into its component parts.
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
union ast_frame::@224 data
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
#define ast_calloc(num, len)
A wrapper for calloc()
#define AST_OPTION_SECURE_SIGNALING
static int user_hash_cb(const void *obj, const int flags)
struct ast_endpoint * endpoint
#define AST_OPTION_AUDIO_MODE
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
#define IAX_IE_CODEC_PREFS
int ast_register_switch(struct ast_switch *sw)
Register an alternative dialplan switch.
static int set_config(const char *config_file, int reload, int forced)
Load configuration.
unsigned int frame_ending
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
#define IAX_RTIGNOREREGEXPIRE
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
static void user_destructor(void *obj)
Free all memory associated with a user.
Module has failed to load, may be in an inconsistent state.
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
const ast_string_field cid_num
An API for managing task processing threads that can be shared across modules.
int ast_db_get(const char *family, const char *key, char *value, int valuelen)
Get key value specified by family/key.
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
int(* ast_sched_cb)(const void *data)
scheduler callback
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
structure to hold users read from users.conf
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Structure used to handle boolean flags.
void ast_channel_callid_set(struct ast_channel *chan, ast_callid value)
static int user_cmp_cb(void *obj, void *arg, int flags)
const ast_string_field context
#define ast_module_unref(mod)
Release a reference to the module.
int ast_get_ip_or_srv(struct ast_sockaddr *addr, const char *hostname, const char *service)
Get the IP address given a hostname and optional service.
static const char * auth_method_labels[]
Name of effective auth method.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
void ast_endpoint_blob_publish(struct ast_endpoint *endpoint, struct stasis_message_type *type, struct ast_json *blob)
Creates and publishes a ast_endpoint_blob message.
struct ast_frame ast_null_frame
static char * handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Set trunk MTU from CLI.
#define IAX_IE_CALLINGTON
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
char order[IAX2_CODEC_PREF_SIZE]
int transit_network_select
Transit Network Select.
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
A ast_taskprocessor structure is a singleton by name.
#define IAX_IE_CALLINGPRES
int ast_taskprocessor_push(struct ast_taskprocessor *tps, int(*task_exe)(void *datap), void *datap) attribute_warn_unused_result
Push a task into the specified taskprocessor queue and signal the taskprocessor thread.
struct iax2_thread::@126 full_frames
#define AST_OPTION_FAX_DETECT
static struct stasis_subscription * acl_change_sub
#define ast_channel_ref(c)
Increase channel reference count.
int ast_add_extension(const char *context, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add and extension to an extension context.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Standard Command Line Interface.
int ast_sched_replace(int old_id, struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
replace a scheduler entry
int ast_db_del(const char *family, const char *key)
Delete entry in astdb.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
Add a rule to an ACL struct.
int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service)
Allocate and initialize a DNS manager entry.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
ast_app: A registered application
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
#define IAX_IE_RR_DROPPED
ast_callid ast_create_callid(void)
factory function to create a new uniquely identifying callid.
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats)
get jitterbuf info: only "statistics" may be valid
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
struct ast_channel * owner
struct ast_party_dialed::@206 number
Dialed/Called number.
const ast_string_field mailbox
static int check_srcaddr(struct ast_sockaddr *addr)
Check if address can be used as packet source.
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
#define DEFAULT_TRUNKDATA
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
struct ast_dnsmgr_entry * dnsmgr
Data structure associated with a single frame of data.
struct iax2_codec_pref prefs
Internal Asterisk hangup causes.
static int authenticate_request(int call_num)
static void delete_users(void)
Delete all users.
struct stasis_message * stasis_cache_get(struct stasis_cache *cache, struct stasis_message_type *type, const char *id)
Retrieve an item from the cache for the ast_eid_default entity.
#define IAX_IE_RSA_RESULT
static char * auth_method_names(int authmethods, char *restrict buf)
Get names of all auth methods.
Abstract JSON element (object, array, string, int, ...).
struct ast_key *AST_OPTIONAL_API_NAME() ast_key_get(const char *kname, int ktype)
return the ast_key structure for name
static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
All frames other than that of type AST_FRAME_IAX must be held until we have received a destination ca...
#define AST_OPTION_TONE_VERIFY
int ast_dnsmgr_changed(struct ast_dnsmgr_entry *entry)
Check is see if a dnsmgr entry has changed.
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
const ast_string_field cid_name
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
#define IAX_IE_CALLED_CONTEXT
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
enum ast_frame_type frametype
#define IAX_IE_APPARENT_ADDR
static struct ast_channel * ast_iax2_new(int callno, int state, iax2_format capability, struct iax2_codec_pref *prefs, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, unsigned int cachable)
Create new call, interface with the PBX core.
const ast_string_field parkinglot
static struct call_number_pool callno_pool
static int __find_callno(unsigned short callno, unsigned short dcallno, struct ast_sockaddr *addr, int new, int sockfd, int return_locked, int check_dcallno)
unsigned char valid
TRUE if the name information is valid/present.
void jb_destroy(jitterbuf *jb)
destroy jitterbuf
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
Media Format Bitfield Compatibility API.
#define IAX_SENDCONNECTEDLINE
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
struct ast_format * format
void ast_callid_strnprint(char *buffer, size_t buffer_size, ast_callid callid)
copy a string representation of the callid into a target string
static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
Part of the IAX2 switch interface.
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
static int iax2_prov_app(struct ast_channel *chan, const char *data)
const ast_string_field context
#define IAX_IE_TRANSFERID
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s...
struct timeval rxtrunktime
The structure that contains MWI state.
struct ast_app * pbx_findapp(const char *app)
Look up an application.
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
void ast_endpoint_shutdown(struct ast_endpoint *endpoint)
Shutsdown an ast_endpoint.
#define ASTERISK_GPL_KEY
The text the key() function should return.
void iax2_codec_pref_convert(struct iax2_codec_pref *pref, char *buf, size_t size, int right)
Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string...
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
static struct iax2_user * realtime_user(const char *username, struct ast_sockaddr *addr)
Asterisk module definitions.
struct ast_format * iax2_codec_pref_index(struct iax2_codec_pref *pref, int idx, struct ast_format **result)
Codec located at a particular place in the preference index.
static int iax2_queue_hold(int callno, const char *musicclass)
Queue a hold frame on the ast_channel owner.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
unconditionally get frames from jitterbuf until empty
struct ast_mwi_subscriber * ast_mwi_subscribe_pool(const char *mailbox, stasis_subscription_cb callback, void *data)
Add an MWI state subscriber, and stasis subscription to the mailbox.
enum calltoken_peer_enum calltoken_required
static struct ast_flags globalflags
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Persistent data storage (akin to *doze registry)
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
static struct ao2_container * callno_limits
unsigned char valid
TRUE if the number information is valid/present.
static int peer_cmp_cb(void *obj, void *arg, int flags)
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel. ...
struct ast_sockaddr transfer
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
#define ast_custom_function_register(acf)
Register a custom function.
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
#define IAX_IE_CAPABILITY
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
Timing source management.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
const ast_string_field peercontext
Structure for mutex and tracking information.
int ast_app_inboxcount(const char *mailboxes, int *newmsgs, int *oldmsgs)
Determine number of new/old messages in a mailbox.
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
struct ast_sockaddr defaddr
void ast_copy_ha(const struct ast_ha *from, struct ast_ha *to)
Copy the contents of one HA to another.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
void jb_reset(jitterbuf *jb)
reset jitterbuf
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
static struct ao2_container * peercnts
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
struct ast_party_number number
Subscriber phone number.
#define ao2_link(container, obj)
Add an object to a container.
struct io_context * io_context_create(void)
Creates a context Create a context for I/O operations Basically mallocs an IO structure and sets up s...