00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "asterisk.h"
00037
00038 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 132783 $")
00039
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <sys/types.h>
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <string.h>
00054 #include <strings.h>
00055 #include <errno.h>
00056 #include <unistd.h>
00057 #include <netdb.h>
00058 #include <fcntl.h>
00059 #include <sys/stat.h>
00060 #include <regex.h>
00061
00062 #ifdef HAVE_ZAPTEL
00063 #include <sys/ioctl.h>
00064 #include <zaptel/zaptel.h>
00065 #endif
00066
00067 #include "asterisk/lock.h"
00068 #include "asterisk/frame.h"
00069 #include "asterisk/channel.h"
00070 #include "asterisk/logger.h"
00071 #include "asterisk/module.h"
00072 #include "asterisk/pbx.h"
00073 #include "asterisk/sched.h"
00074 #include "asterisk/io.h"
00075 #include "asterisk/config.h"
00076 #include "asterisk/options.h"
00077 #include "asterisk/cli.h"
00078 #include "asterisk/translate.h"
00079 #include "asterisk/md5.h"
00080 #include "asterisk/cdr.h"
00081 #include "asterisk/crypto.h"
00082 #include "asterisk/acl.h"
00083 #include "asterisk/manager.h"
00084 #include "asterisk/callerid.h"
00085 #include "asterisk/app.h"
00086 #include "asterisk/astdb.h"
00087 #include "asterisk/musiconhold.h"
00088 #include "asterisk/features.h"
00089 #include "asterisk/utils.h"
00090 #include "asterisk/causes.h"
00091 #include "asterisk/localtime.h"
00092 #include "asterisk/aes.h"
00093 #include "asterisk/dnsmgr.h"
00094 #include "asterisk/devicestate.h"
00095 #include "asterisk/netsock.h"
00096 #include "asterisk/stringfields.h"
00097 #include "asterisk/linkedlists.h"
00098 #include "asterisk/astobj2.h"
00099
00100 #include "iax2.h"
00101 #include "iax2-parser.h"
00102 #include "iax2-provision.h"
00103 #include "jitterbuf.h"
00104
00105
00106
00107 #define SCHED_MULTITHREADED
00108
00109
00110
00111 #define DEBUG_SCHED_MULTITHREAD
00112
00113 #ifndef IPTOS_MINCOST
00114 #define IPTOS_MINCOST 0x02
00115 #endif
00116
00117 #ifdef SO_NO_CHECK
00118 static int nochecksums = 0;
00119 #endif
00120
00121
00122 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00123 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00124
00125 #define DEFAULT_THREAD_COUNT 10
00126 #define DEFAULT_MAX_THREAD_COUNT 100
00127 #define DEFAULT_RETRY_TIME 1000
00128 #define MEMORY_SIZE 100
00129 #define DEFAULT_DROP 3
00130
00131 #define DEBUG_SUPPORT
00132
00133 #define MIN_REUSE_TIME 60
00134
00135
00136 #define GAMMA (0.01)
00137
00138 static struct ast_codec_pref prefs;
00139
00140 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00141
00142 static char context[80] = "default";
00143
00144 static char language[MAX_LANGUAGE] = "";
00145 static char regcontext[AST_MAX_CONTEXT] = "";
00146
00147 static int maxauthreq = 3;
00148 static int max_retries = 4;
00149 static int ping_time = 21;
00150 static int lagrq_time = 10;
00151 static int maxjitterbuffer=1000;
00152 static int resyncthreshold=1000;
00153 static int maxjitterinterps=10;
00154 static int trunkfreq = 20;
00155 static int authdebug = 1;
00156 static int autokill = 0;
00157 static int iaxcompat = 0;
00158
00159 static int iaxdefaultdpcache=10 * 60;
00160
00161 static int iaxdefaulttimeout = 5;
00162
00163 static unsigned int tos = 0;
00164
00165 static int min_reg_expire;
00166 static int max_reg_expire;
00167
00168 static int timingfd = -1;
00169
00170 static struct ast_netsock_list *netsock;
00171 static struct ast_netsock_list *outsock;
00172 static int defaultsockfd = -1;
00173
00174 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00175
00176
00177 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00178
00179 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00180 ~AST_FORMAT_SLINEAR & \
00181 ~AST_FORMAT_ULAW & \
00182 ~AST_FORMAT_ALAW & \
00183 ~AST_FORMAT_G722)
00184
00185 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00186 ~AST_FORMAT_G726 & \
00187 ~AST_FORMAT_G726_AAL2 & \
00188 ~AST_FORMAT_ADPCM)
00189
00190 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00191 ~AST_FORMAT_G723_1)
00192
00193
00194 #define DEFAULT_MAXMS 2000
00195 #define DEFAULT_FREQ_OK 60 * 1000
00196 #define DEFAULT_FREQ_NOTOK 10 * 1000
00197
00198 static struct io_context *io;
00199 static struct sched_context *sched;
00200
00201 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00202
00203 static int iaxdebug = 0;
00204
00205 static int iaxtrunkdebug = 0;
00206
00207 static int test_losspct = 0;
00208 #ifdef IAXTESTS
00209 static int test_late = 0;
00210 static int test_resync = 0;
00211 static int test_jit = 0;
00212 static int test_jitpct = 0;
00213 #endif
00214
00215 static char accountcode[AST_MAX_ACCOUNT_CODE];
00216 static char mohinterpret[MAX_MUSICCLASS];
00217 static char mohsuggest[MAX_MUSICCLASS];
00218 static int amaflags = 0;
00219 static int adsi = 0;
00220 static int delayreject = 0;
00221 static int iax2_encryption = 0;
00222
00223 static struct ast_flags globalflags = { 0 };
00224
00225 static pthread_t netthreadid = AST_PTHREADT_NULL;
00226 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00227 AST_MUTEX_DEFINE_STATIC(sched_lock);
00228 static ast_cond_t sched_cond;
00229
00230 enum {
00231 IAX_STATE_STARTED = (1 << 0),
00232 IAX_STATE_AUTHENTICATED = (1 << 1),
00233 IAX_STATE_TBD = (1 << 2),
00234 IAX_STATE_UNCHANGED = (1 << 3),
00235 } iax2_state;
00236
00237 struct iax2_context {
00238 char context[AST_MAX_CONTEXT];
00239 struct iax2_context *next;
00240 };
00241
00242 enum {
00243 IAX_HASCALLERID = (1 << 0),
00244 IAX_DELME = (1 << 1),
00245 IAX_TEMPONLY = (1 << 2),
00246 IAX_TRUNK = (1 << 3),
00247 IAX_NOTRANSFER = (1 << 4),
00248 IAX_USEJITTERBUF = (1 << 5),
00249 IAX_DYNAMIC = (1 << 6),
00250 IAX_SENDANI = (1 << 7),
00251
00252 IAX_ALREADYGONE = (1 << 9),
00253 IAX_PROVISION = (1 << 10),
00254 IAX_QUELCH = (1 << 11),
00255 IAX_ENCRYPTED = (1 << 12),
00256 IAX_KEYPOPULATED = (1 << 13),
00257 IAX_CODEC_USER_FIRST = (1 << 14),
00258 IAX_CODEC_NOPREFS = (1 << 15),
00259 IAX_CODEC_NOCAP = (1 << 16),
00260 IAX_RTCACHEFRIENDS = (1 << 17),
00261 IAX_RTUPDATE = (1 << 18),
00262 IAX_RTAUTOCLEAR = (1 << 19),
00263 IAX_FORCEJITTERBUF = (1 << 20),
00264 IAX_RTIGNOREREGEXPIRE = (1 << 21),
00265 IAX_TRUNKTIMESTAMPS = (1 << 22),
00266 IAX_TRANSFERMEDIA = (1 << 23),
00267 IAX_MAXAUTHREQ = (1 << 24),
00268 IAX_DELAYPBXSTART = (1 << 25),
00269
00270
00271 IAX_ALLOWFWDOWNLOAD = (1 << 26),
00272 } iax2_flags;
00273
00274 static int global_rtautoclear = 120;
00275
00276 static int reload_config(void);
00277 static int iax2_reload(int fd, int argc, char *argv[]);
00278
00279
00280 struct iax2_user {
00281 AST_DECLARE_STRING_FIELDS(
00282 AST_STRING_FIELD(name);
00283 AST_STRING_FIELD(secret);
00284 AST_STRING_FIELD(dbsecret);
00285 AST_STRING_FIELD(accountcode);
00286 AST_STRING_FIELD(mohinterpret);
00287 AST_STRING_FIELD(mohsuggest);
00288 AST_STRING_FIELD(inkeys);
00289 AST_STRING_FIELD(language);
00290 AST_STRING_FIELD(cid_num);
00291 AST_STRING_FIELD(cid_name);
00292 );
00293
00294 int authmethods;
00295 int encmethods;
00296 int amaflags;
00297 int adsi;
00298 unsigned int flags;
00299 int capability;
00300 int maxauthreq;
00301 int curauthreq;
00302 struct ast_codec_pref prefs;
00303 struct ast_ha *ha;
00304 struct iax2_context *contexts;
00305 struct ast_variable *vars;
00306 };
00307
00308 struct iax2_peer {
00309 AST_DECLARE_STRING_FIELDS(
00310 AST_STRING_FIELD(name);
00311 AST_STRING_FIELD(username);
00312 AST_STRING_FIELD(secret);
00313 AST_STRING_FIELD(dbsecret);
00314 AST_STRING_FIELD(outkey);
00315
00316 AST_STRING_FIELD(regexten);
00317 AST_STRING_FIELD(context);
00318 AST_STRING_FIELD(peercontext);
00319 AST_STRING_FIELD(mailbox);
00320 AST_STRING_FIELD(mohinterpret);
00321 AST_STRING_FIELD(mohsuggest);
00322 AST_STRING_FIELD(inkeys);
00323
00324 AST_STRING_FIELD(cid_num);
00325 AST_STRING_FIELD(cid_name);
00326 AST_STRING_FIELD(zonetag);
00327 );
00328 struct ast_codec_pref prefs;
00329 struct ast_dnsmgr_entry *dnsmgr;
00330 struct sockaddr_in addr;
00331 int formats;
00332 int sockfd;
00333 struct in_addr mask;
00334 int adsi;
00335 unsigned int flags;
00336
00337
00338 struct sockaddr_in defaddr;
00339 int authmethods;
00340 int encmethods;
00341
00342 int expire;
00343 int expiry;
00344 int capability;
00345
00346
00347 int callno;
00348 int pokeexpire;
00349 int lastms;
00350 int maxms;
00351
00352 int pokefreqok;
00353 int pokefreqnotok;
00354 int historicms;
00355 int smoothing;
00356
00357 struct ast_ha *ha;
00358 };
00359
00360 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00361
00362 static struct iax2_trunk_peer {
00363 ast_mutex_t lock;
00364 int sockfd;
00365 struct sockaddr_in addr;
00366 struct timeval txtrunktime;
00367 struct timeval rxtrunktime;
00368 struct timeval lasttxtime;
00369 struct timeval trunkact;
00370 unsigned int lastsent;
00371
00372 unsigned char *trunkdata;
00373 unsigned int trunkdatalen;
00374 unsigned int trunkdataalloc;
00375 struct iax2_trunk_peer *next;
00376 int trunkerror;
00377 int calls;
00378 } *tpeers = NULL;
00379
00380 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00381
00382 struct iax_firmware {
00383 struct iax_firmware *next;
00384 int fd;
00385 int mmaplen;
00386 int dead;
00387 struct ast_iax2_firmware_header *fwh;
00388 unsigned char *buf;
00389 };
00390
00391 enum iax_reg_state {
00392 REG_STATE_UNREGISTERED = 0,
00393 REG_STATE_REGSENT,
00394 REG_STATE_AUTHSENT,
00395 REG_STATE_REGISTERED,
00396 REG_STATE_REJECTED,
00397 REG_STATE_TIMEOUT,
00398 REG_STATE_NOAUTH
00399 };
00400
00401 enum iax_transfer_state {
00402 TRANSFER_NONE = 0,
00403 TRANSFER_BEGIN,
00404 TRANSFER_READY,
00405 TRANSFER_RELEASED,
00406 TRANSFER_PASSTHROUGH,
00407 TRANSFER_MBEGIN,
00408 TRANSFER_MREADY,
00409 TRANSFER_MRELEASED,
00410 TRANSFER_MPASSTHROUGH,
00411 TRANSFER_MEDIA,
00412 TRANSFER_MEDIAPASS
00413 };
00414
00415 struct iax2_registry {
00416 struct sockaddr_in addr;
00417 char username[80];
00418 char secret[80];
00419 char random[80];
00420 int expire;
00421 int refresh;
00422 enum iax_reg_state regstate;
00423 int messages;
00424 int callno;
00425 struct sockaddr_in us;
00426 struct ast_dnsmgr_entry *dnsmgr;
00427 AST_LIST_ENTRY(iax2_registry) entry;
00428 };
00429
00430 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00431
00432
00433 #define MIN_RETRY_TIME 100
00434 #define MAX_RETRY_TIME 10000
00435
00436 #define MAX_JITTER_BUFFER 50
00437 #define MIN_JITTER_BUFFER 10
00438
00439 #define DEFAULT_TRUNKDATA 640 * 10
00440 #define MAX_TRUNKDATA 640 * 200
00441
00442 #define MAX_TIMESTAMP_SKEW 160
00443
00444
00445 #define TS_GAP_FOR_JB_RESYNC 5000
00446
00447 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00448 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00449 static int iaxdynamicthreadcount = 0;
00450 static int iaxactivethreadcount = 0;
00451
00452 struct iax_rr {
00453 int jitter;
00454 int losspct;
00455 int losscnt;
00456 int packets;
00457 int delay;
00458 int dropped;
00459 int ooo;
00460 };
00461
00462 struct chan_iax2_pvt {
00463
00464 int sockfd;
00465
00466 int voiceformat;
00467
00468 int videoformat;
00469
00470 int svoiceformat;
00471
00472 int svideoformat;
00473
00474 int capability;
00475
00476 unsigned int last;
00477
00478 unsigned int lastsent;
00479
00480 unsigned int lastvsent;
00481
00482 unsigned int nextpred;
00483
00484 int notsilenttx;
00485
00486 unsigned int pingtime;
00487
00488 int maxtime;
00489
00490 struct sockaddr_in addr;
00491
00492 struct ast_codec_pref prefs;
00493
00494 struct ast_codec_pref rprefs;
00495
00496 unsigned short callno;
00497
00498 unsigned short peercallno;
00499
00500
00501
00502 int chosenformat;
00503
00504 int peerformat;
00505
00506 int peercapability;
00507
00508 struct timeval offset;
00509
00510 struct timeval rxcore;
00511
00512 jitterbuf *jb;
00513
00514 int jbid;
00515
00516 int lag;
00517
00518 int error;
00519
00520 struct ast_channel *owner;
00521
00522 struct ast_flags state;
00523
00524 int expiry;
00525
00526 unsigned char oseqno;
00527
00528 unsigned char rseqno;
00529
00530 unsigned char iseqno;
00531
00532 unsigned char aseqno;
00533
00534 AST_DECLARE_STRING_FIELDS(
00535
00536 AST_STRING_FIELD(peer);
00537
00538 AST_STRING_FIELD(context);
00539
00540 AST_STRING_FIELD(cid_num);
00541 AST_STRING_FIELD(cid_name);
00542
00543 AST_STRING_FIELD(ani);
00544
00545 AST_STRING_FIELD(dnid);
00546
00547 AST_STRING_FIELD(rdnis);
00548
00549 AST_STRING_FIELD(exten);
00550
00551 AST_STRING_FIELD(username);
00552
00553 AST_STRING_FIELD(secret);
00554
00555 AST_STRING_FIELD(challenge);
00556
00557 AST_STRING_FIELD(inkeys);
00558
00559 AST_STRING_FIELD(outkey);
00560
00561 AST_STRING_FIELD(language);
00562
00563 AST_STRING_FIELD(host);
00564
00565 AST_STRING_FIELD(dproot);
00566 AST_STRING_FIELD(accountcode);
00567 AST_STRING_FIELD(mohinterpret);
00568 AST_STRING_FIELD(mohsuggest);
00569 );
00570
00571
00572 int authmethods;
00573
00574 int encmethods;
00575
00576 aes_encrypt_ctx ecx;
00577
00578 aes_decrypt_ctx dcx;
00579
00580 unsigned char semirand[32];
00581
00582 struct iax2_registry *reg;
00583
00584 struct iax2_peer *peerpoke;
00585
00586 unsigned int flags;
00587 int adsi;
00588
00589
00590 enum iax_transfer_state transferring;
00591
00592 int transferid;
00593
00594 struct sockaddr_in transfer;
00595
00596 unsigned short transfercallno;
00597
00598 aes_encrypt_ctx tdcx;
00599
00600
00601 int peeradsicpe;
00602
00603
00604 unsigned short bridgecallno;
00605
00606 int pingid;
00607 int lagid;
00608 int autoid;
00609 int authid;
00610 int authfail;
00611 int initid;
00612 int calling_ton;
00613 int calling_tns;
00614 int calling_pres;
00615 int amaflags;
00616 struct iax2_dpcache *dpentries;
00617 struct ast_variable *vars;
00618
00619 struct iax_rr remote_rr;
00620
00621 int min;
00622
00623 int frames_dropped;
00624
00625 int frames_received;
00626 };
00627
00628 static struct ast_iax2_queue {
00629 AST_LIST_HEAD(, iax_frame) queue;
00630 int count;
00631 } iaxq;
00632
00633
00634
00635
00636
00637
00638
00639
00640 #ifdef LOW_MEMORY
00641 #define MAX_PEER_BUCKETS 1
00642
00643 #else
00644 #define MAX_PEER_BUCKETS 1
00645
00646 #endif
00647 static struct ao2_container *peers;
00648
00649 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00650 static struct ao2_container *users;
00651
00652 static struct ast_firmware_list {
00653 struct iax_firmware *wares;
00654 ast_mutex_t lock;
00655 } waresl;
00656
00657
00658 #define CACHE_FLAG_EXISTS (1 << 0)
00659
00660 #define CACHE_FLAG_NONEXISTENT (1 << 1)
00661
00662 #define CACHE_FLAG_CANEXIST (1 << 2)
00663
00664 #define CACHE_FLAG_PENDING (1 << 3)
00665
00666 #define CACHE_FLAG_TIMEOUT (1 << 4)
00667
00668 #define CACHE_FLAG_TRANSMITTED (1 << 5)
00669
00670 #define CACHE_FLAG_UNKNOWN (1 << 6)
00671
00672 #define CACHE_FLAG_MATCHMORE (1 << 7)
00673
00674 static struct iax2_dpcache {
00675 char peercontext[AST_MAX_CONTEXT];
00676 char exten[AST_MAX_EXTENSION];
00677 struct timeval orig;
00678 struct timeval expiry;
00679 int flags;
00680 unsigned short callno;
00681 int waiters[256];
00682 struct iax2_dpcache *next;
00683 struct iax2_dpcache *peer;
00684 } *dpcache;
00685
00686 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00687
00688 static void reg_source_db(struct iax2_peer *p);
00689 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00690
00691 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00692
00693 #define IAX_IOSTATE_IDLE 0
00694 #define IAX_IOSTATE_READY 1
00695 #define IAX_IOSTATE_PROCESSING 2
00696 #define IAX_IOSTATE_SCHEDREADY 3
00697
00698 #define IAX_TYPE_POOL 1
00699 #define IAX_TYPE_DYNAMIC 2
00700
00701 struct iax2_pkt_buf {
00702 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00703 size_t len;
00704 unsigned char buf[1];
00705 };
00706
00707 struct iax2_thread {
00708 AST_LIST_ENTRY(iax2_thread) list;
00709 int type;
00710 int iostate;
00711 #ifdef SCHED_MULTITHREADED
00712 void (*schedfunc)(const void *);
00713 const void *scheddata;
00714 #endif
00715 #ifdef DEBUG_SCHED_MULTITHREAD
00716 char curfunc[80];
00717 #endif
00718 int actions;
00719 pthread_t threadid;
00720 int threadnum;
00721 struct sockaddr_in iosin;
00722 unsigned char readbuf[4096];
00723 unsigned char *buf;
00724 ssize_t buf_len;
00725 size_t buf_size;
00726 int iofd;
00727 time_t checktime;
00728 ast_mutex_t lock;
00729 ast_cond_t cond;
00730 unsigned int ready_for_signal:1;
00731
00732
00733
00734
00735 struct {
00736 unsigned short callno;
00737 struct sockaddr_in sin;
00738 unsigned char type;
00739 unsigned char csub;
00740 } ffinfo;
00741
00742
00743
00744 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00745 };
00746
00747
00748 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00749 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00750 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00751
00752 static void *iax2_process_thread(void *data);
00753
00754 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00755 {
00756 ast_mutex_lock(lock);
00757 ast_cond_signal(cond);
00758 ast_mutex_unlock(lock);
00759 }
00760
00761 static void iax_debug_output(const char *data)
00762 {
00763 if (iaxdebug)
00764 ast_verbose("%s", data);
00765 }
00766
00767 static void iax_error_output(const char *data)
00768 {
00769 ast_log(LOG_WARNING, "%s", data);
00770 }
00771
00772 static void jb_error_output(const char *fmt, ...)
00773 {
00774 va_list args;
00775 char buf[1024];
00776
00777 va_start(args, fmt);
00778 vsnprintf(buf, 1024, fmt, args);
00779 va_end(args);
00780
00781 ast_log(LOG_ERROR, buf);
00782 }
00783
00784 static void jb_warning_output(const char *fmt, ...)
00785 {
00786 va_list args;
00787 char buf[1024];
00788
00789 va_start(args, fmt);
00790 vsnprintf(buf, 1024, fmt, args);
00791 va_end(args);
00792
00793 ast_log(LOG_WARNING, buf);
00794 }
00795
00796 static void jb_debug_output(const char *fmt, ...)
00797 {
00798 va_list args;
00799 char buf[1024];
00800
00801 va_start(args, fmt);
00802 vsnprintf(buf, 1024, fmt, args);
00803 va_end(args);
00804
00805 ast_verbose(buf);
00806 }
00807
00808
00809 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00810 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00811 static struct timeval lastused[ARRAY_LEN(iaxs)];
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 static struct ao2_container *iax_peercallno_pvts;
00823
00824
00825
00826 #define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2
00827
00828 static int maxtrunkcall = TRUNK_CALL_START;
00829 static int maxnontrunkcall = 1;
00830
00831 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
00832 static int expire_registry(const void *data);
00833 static int iax2_answer(struct ast_channel *c);
00834 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00835 static int iax2_devicestate(void *data);
00836 static int iax2_digit_begin(struct ast_channel *c, char digit);
00837 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00838 static int iax2_do_register(struct iax2_registry *reg);
00839 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00840 static int iax2_hangup(struct ast_channel *c);
00841 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00842 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00843 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00844 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00845 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00846 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00847 static int iax2_sendtext(struct ast_channel *c, const char *text);
00848 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00849 static int iax2_transfer(struct ast_channel *c, const char *dest);
00850 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00851 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00852 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00853 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00854 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00855 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00856 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00857 static struct ast_frame *iax2_read(struct ast_channel *c);
00858 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00859 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00860 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00861 static void prune_peers(void);
00862
00863 static const struct ast_channel_tech iax2_tech = {
00864 .type = "IAX2",
00865 .description = tdesc,
00866 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00867 .properties = AST_CHAN_TP_WANTSJITTER,
00868 .requester = iax2_request,
00869 .devicestate = iax2_devicestate,
00870 .send_digit_begin = iax2_digit_begin,
00871 .send_digit_end = iax2_digit_end,
00872 .send_text = iax2_sendtext,
00873 .send_image = iax2_sendimage,
00874 .send_html = iax2_sendhtml,
00875 .call = iax2_call,
00876 .hangup = iax2_hangup,
00877 .answer = iax2_answer,
00878 .read = iax2_read,
00879 .write = iax2_write,
00880 .write_video = iax2_write,
00881 .indicate = iax2_indicate,
00882 .setoption = iax2_setoption,
00883 .bridge = iax2_bridge,
00884 .transfer = iax2_transfer,
00885 .fixup = iax2_fixup,
00886 };
00887
00888
00889
00890
00891 static void insert_idle_thread(struct iax2_thread *thread)
00892 {
00893 if (thread->type == IAX_TYPE_DYNAMIC) {
00894 AST_LIST_LOCK(&dynamic_list);
00895 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00896 AST_LIST_UNLOCK(&dynamic_list);
00897 } else {
00898 AST_LIST_LOCK(&idle_list);
00899 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00900 AST_LIST_UNLOCK(&idle_list);
00901 }
00902
00903 return;
00904 }
00905
00906 static struct iax2_thread *find_idle_thread(void)
00907 {
00908 pthread_attr_t attr;
00909 struct iax2_thread *thread = NULL;
00910
00911
00912 AST_LIST_LOCK(&idle_list);
00913 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00914 AST_LIST_UNLOCK(&idle_list);
00915
00916
00917 if (thread == NULL) {
00918 AST_LIST_LOCK(&dynamic_list);
00919 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00920
00921 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00922
00923 if ((thread = ast_calloc(1, sizeof(*thread)))) {
00924 thread->threadnum = iaxdynamicthreadcount;
00925 thread->type = IAX_TYPE_DYNAMIC;
00926 ast_mutex_init(&thread->lock);
00927 ast_cond_init(&thread->cond, NULL);
00928 pthread_attr_init(&attr);
00929 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00930 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00931 free(thread);
00932 thread = NULL;
00933 } else {
00934
00935 iaxdynamicthreadcount++;
00936
00937
00938 while (!thread->ready_for_signal)
00939 usleep(1);
00940 }
00941 }
00942 }
00943 AST_LIST_UNLOCK(&dynamic_list);
00944 }
00945
00946
00947
00948 if (thread)
00949 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00950
00951 return thread;
00952 }
00953
00954 #ifdef SCHED_MULTITHREADED
00955 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00956 {
00957 struct iax2_thread *thread = NULL;
00958 static time_t lasterror;
00959 static time_t t;
00960
00961 thread = find_idle_thread();
00962
00963 if (thread != NULL) {
00964 thread->schedfunc = func;
00965 thread->scheddata = data;
00966 thread->iostate = IAX_IOSTATE_SCHEDREADY;
00967 #ifdef DEBUG_SCHED_MULTITHREAD
00968 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00969 #endif
00970 signal_condition(&thread->lock, &thread->cond);
00971 return 0;
00972 }
00973 time(&t);
00974 if (t != lasterror && option_debug)
00975 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00976 lasterror = t;
00977
00978 return -1;
00979 }
00980 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00981 #endif
00982
00983 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00984 {
00985 int res;
00986
00987 res = ast_sched_add(con, when, callback, data);
00988 signal_condition(&sched_lock, &sched_cond);
00989
00990 return res;
00991 }
00992
00993 static int send_ping(const void *data);
00994
00995 static void __send_ping(const void *data)
00996 {
00997 int callno = (long) data;
00998
00999 ast_mutex_lock(&iaxsl[callno]);
01000
01001 while (iaxs[callno] && iaxs[callno]->pingid != -1) {
01002 if (iaxs[callno]->peercallno) {
01003 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01004 }
01005 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01006 break;
01007 }
01008
01009 ast_mutex_unlock(&iaxsl[callno]);
01010 }
01011
01012 static int send_ping(const void *data)
01013 {
01014 #ifdef SCHED_MULTITHREADED
01015 if (schedule_action(__send_ping, data))
01016 #endif
01017 __send_ping(data);
01018 return 0;
01019 }
01020
01021 static int get_encrypt_methods(const char *s)
01022 {
01023 int e;
01024 if (!strcasecmp(s, "aes128"))
01025 e = IAX_ENCRYPT_AES128;
01026 else if (ast_true(s))
01027 e = IAX_ENCRYPT_AES128;
01028 else
01029 e = 0;
01030 return e;
01031 }
01032
01033 static int send_lagrq(const void *data);
01034
01035 static void __send_lagrq(const void *data)
01036 {
01037 int callno = (long) data;
01038
01039 ast_mutex_lock(&iaxsl[callno]);
01040
01041 while (iaxs[callno] && iaxs[callno]->lagid > -1) {
01042 if (iaxs[callno]->peercallno) {
01043 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01044 }
01045 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01046 break;
01047 }
01048
01049 ast_mutex_unlock(&iaxsl[callno]);
01050 }
01051
01052 static int send_lagrq(const void *data)
01053 {
01054 #ifdef SCHED_MULTITHREADED
01055 if (schedule_action(__send_lagrq, data))
01056 #endif
01057 __send_lagrq(data);
01058 return 0;
01059 }
01060
01061 static unsigned char compress_subclass(int subclass)
01062 {
01063 int x;
01064 int power=-1;
01065
01066 if (subclass < IAX_FLAG_SC_LOG)
01067 return subclass;
01068
01069 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01070 if (subclass & (1 << x)) {
01071 if (power > -1) {
01072 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01073 return 0;
01074 } else
01075 power = x;
01076 }
01077 }
01078 return power | IAX_FLAG_SC_LOG;
01079 }
01080
01081 static int uncompress_subclass(unsigned char csub)
01082 {
01083
01084 if (csub & IAX_FLAG_SC_LOG) {
01085
01086 if (csub == 0xff)
01087 return -1;
01088 else
01089 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01090 }
01091 else
01092 return csub;
01093 }
01094
01095
01096
01097
01098 static int peer_hash_cb(const void *obj, const int flags)
01099 {
01100 const struct iax2_peer *peer = obj;
01101
01102 return ast_str_hash(peer->name);
01103 }
01104
01105
01106
01107
01108 static int peer_cmp_cb(void *obj, void *arg, int flags)
01109 {
01110 struct iax2_peer *peer = obj, *peer2 = arg;
01111
01112 return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01113 }
01114
01115
01116
01117
01118 static int user_hash_cb(const void *obj, const int flags)
01119 {
01120 const struct iax2_user *user = obj;
01121
01122 return ast_str_hash(user->name);
01123 }
01124
01125
01126
01127
01128 static int user_cmp_cb(void *obj, void *arg, int flags)
01129 {
01130 struct iax2_user *user = obj, *user2 = arg;
01131
01132 return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
01133 }
01134
01135
01136
01137
01138
01139 static struct iax2_peer *find_peer(const char *name, int realtime)
01140 {
01141 struct iax2_peer *peer = NULL;
01142 struct iax2_peer tmp_peer = {
01143 .name = name,
01144 };
01145
01146 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01147
01148
01149 if(!peer && realtime)
01150 peer = realtime_peer(name, NULL);
01151
01152 return peer;
01153 }
01154
01155 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01156 {
01157 ao2_ref(peer, +1);
01158 return peer;
01159 }
01160
01161 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01162 {
01163 ao2_ref(peer, -1);
01164 return NULL;
01165 }
01166
01167 static inline struct iax2_user *user_ref(struct iax2_user *user)
01168 {
01169 ao2_ref(user, +1);
01170 return user;
01171 }
01172
01173 static inline struct iax2_user *user_unref(struct iax2_user *user)
01174 {
01175 ao2_ref(user, -1);
01176 return NULL;
01177 }
01178
01179 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01180 {
01181 struct iax2_peer *peer = NULL;
01182 int res = 0;
01183 struct ao2_iterator i;
01184
01185 i = ao2_iterator_init(peers, 0);
01186 while ((peer = ao2_iterator_next(&i))) {
01187 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01188 (peer->addr.sin_port == sin.sin_port)) {
01189 ast_copy_string(host, peer->name, len);
01190 peer_unref(peer);
01191 res = 1;
01192 break;
01193 }
01194 peer_unref(peer);
01195 }
01196
01197 if (!peer) {
01198 peer = realtime_peer(NULL, &sin);
01199 if (peer) {
01200 ast_copy_string(host, peer->name, len);
01201 peer_unref(peer);
01202 res = 1;
01203 }
01204 }
01205
01206 return res;
01207 }
01208
01209 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01210 {
01211
01212 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01213 struct iax2_user *user;
01214 struct iax2_user tmp_user = {
01215 .name = pvt->username,
01216 };
01217
01218 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01219 if (user) {
01220 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01221 user = user_unref(user);
01222 }
01223
01224 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01225 }
01226
01227
01228 AST_SCHED_DEL(sched, pvt->pingid);
01229 AST_SCHED_DEL(sched, pvt->lagid);
01230 AST_SCHED_DEL(sched, pvt->autoid);
01231 AST_SCHED_DEL(sched, pvt->authid);
01232 AST_SCHED_DEL(sched, pvt->initid);
01233 AST_SCHED_DEL(sched, pvt->jbid);
01234 }
01235
01236 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01237 {
01238 if (!pvt->peercallno) {
01239 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01240 return;
01241 }
01242
01243 ao2_link(iax_peercallno_pvts, pvt);
01244 }
01245
01246 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01247 {
01248 if (!pvt->peercallno) {
01249 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01250 return;
01251 }
01252
01253 ao2_unlink(iax_peercallno_pvts, pvt);
01254 }
01255
01256 static void update_max_trunk(void)
01257 {
01258 int max = TRUNK_CALL_START;
01259 int x;
01260
01261
01262 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01263 if (iaxs[x]) {
01264 max = x + 1;
01265 }
01266 }
01267
01268 maxtrunkcall = max;
01269 if (option_debug && iaxdebug)
01270 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01271 }
01272
01273 static void iax2_frame_free(struct iax_frame *fr)
01274 {
01275 AST_SCHED_DEL(sched, fr->retrans);
01276 iax_frame_free(fr);
01277 }
01278
01279 static void iax2_destroy(int callno)
01280 {
01281 struct chan_iax2_pvt *pvt;
01282 struct ast_channel *owner;
01283
01284 retry:
01285 pvt = iaxs[callno];
01286 gettimeofday(&lastused[callno], NULL);
01287
01288 owner = pvt ? pvt->owner : NULL;
01289
01290 if (owner) {
01291 if (ast_mutex_trylock(&owner->lock)) {
01292 if (option_debug > 2)
01293 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01294 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01295 goto retry;
01296 }
01297 }
01298 if (!owner) {
01299 iaxs[callno] = NULL;
01300 }
01301
01302 if (pvt) {
01303 if (!owner) {
01304 pvt->owner = NULL;
01305 } else {
01306
01307
01308
01309 ast_queue_hangup(owner);
01310 }
01311
01312 if (pvt->peercallno) {
01313 remove_by_peercallno(pvt);
01314 }
01315
01316 if (!owner) {
01317 ao2_ref(pvt, -1);
01318 pvt = NULL;
01319 }
01320 }
01321
01322 if (owner) {
01323 ast_mutex_unlock(&owner->lock);
01324 }
01325
01326 if (callno & 0x4000) {
01327 update_max_trunk();
01328 }
01329 }
01330
01331 static void pvt_destructor(void *obj)
01332 {
01333 struct chan_iax2_pvt *pvt = obj;
01334 struct iax_frame *cur = NULL;
01335
01336 iax2_destroy_helper(pvt);
01337
01338
01339 ast_set_flag(pvt, IAX_ALREADYGONE);
01340
01341 AST_LIST_LOCK(&iaxq.queue);
01342 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01343
01344 if (cur->callno == pvt->callno) {
01345 cur->retries = -1;
01346 }
01347 }
01348 AST_LIST_UNLOCK(&iaxq.queue);
01349
01350 if (pvt->reg) {
01351 pvt->reg->callno = 0;
01352 }
01353
01354 if (!pvt->owner) {
01355 jb_frame frame;
01356 if (pvt->vars) {
01357 ast_variables_destroy(pvt->vars);
01358 pvt->vars = NULL;
01359 }
01360
01361 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01362 iax2_frame_free(frame.data);
01363 }
01364
01365 jb_destroy(pvt->jb);
01366 ast_string_field_free_memory(pvt);
01367 }
01368 }
01369
01370 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01371 {
01372 struct chan_iax2_pvt *tmp;
01373 jb_conf jbconf;
01374
01375 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01376 return NULL;
01377 }
01378
01379 if (ast_string_field_init(tmp, 32)) {
01380 ao2_ref(tmp, -1);
01381 tmp = NULL;
01382 return NULL;
01383 }
01384
01385 tmp->prefs = prefs;
01386 tmp->callno = 0;
01387 tmp->peercallno = 0;
01388 tmp->transfercallno = 0;
01389 tmp->bridgecallno = 0;
01390 tmp->pingid = -1;
01391 tmp->lagid = -1;
01392 tmp->autoid = -1;
01393 tmp->authid = -1;
01394 tmp->initid = -1;
01395
01396 ast_string_field_set(tmp,exten, "s");
01397 ast_string_field_set(tmp,host, host);
01398
01399 tmp->jb = jb_new();
01400 tmp->jbid = -1;
01401 jbconf.max_jitterbuf = maxjitterbuffer;
01402 jbconf.resync_threshold = resyncthreshold;
01403 jbconf.max_contig_interp = maxjitterinterps;
01404 jb_setconf(tmp->jb,&jbconf);
01405
01406 return tmp;
01407 }
01408
01409 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01410 {
01411 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01412 if (new) {
01413 size_t afdatalen = new->afdatalen;
01414 memcpy(new, fr, sizeof(*new));
01415 iax_frame_wrap(new, &fr->af);
01416 new->afdatalen = afdatalen;
01417 new->data = NULL;
01418 new->datalen = 0;
01419 new->direction = DIRECTION_INGRESS;
01420 new->retrans = -1;
01421 }
01422 return new;
01423 }
01424
01425 #define NEW_PREVENT 0
01426 #define NEW_ALLOW 1
01427 #define NEW_FORCE 2
01428
01429 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01430 {
01431 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01432 (cur->addr.sin_port == sin->sin_port)) {
01433
01434 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01435 (check_dcallno ? dcallno == cur->callno : 1) ) {
01436
01437 return 1;
01438 }
01439 }
01440 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01441 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01442
01443 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01444 return 1;
01445 }
01446 return 0;
01447 }
01448
01449 static void update_max_nontrunk(void)
01450 {
01451 int max = 1;
01452 int x;
01453
01454 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01455 if (iaxs[x])
01456 max = x + 1;
01457 }
01458 maxnontrunkcall = max;
01459 if (option_debug && iaxdebug)
01460 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01461 }
01462
01463 static int make_trunk(unsigned short callno, int locked)
01464 {
01465 int x;
01466 int res= 0;
01467 struct timeval now;
01468 if (iaxs[callno]->oseqno) {
01469 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01470 return -1;
01471 }
01472 if (callno & TRUNK_CALL_START) {
01473 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01474 return -1;
01475 }
01476 gettimeofday(&now, NULL);
01477 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01478 ast_mutex_lock(&iaxsl[x]);
01479 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01480 iaxs[x] = iaxs[callno];
01481 iaxs[x]->callno = x;
01482 iaxs[callno] = NULL;
01483
01484 AST_SCHED_DEL(sched, iaxs[x]->pingid);
01485 AST_SCHED_DEL(sched, iaxs[x]->lagid);
01486 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01487 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01488 if (locked)
01489 ast_mutex_unlock(&iaxsl[callno]);
01490 res = x;
01491 if (!locked)
01492 ast_mutex_unlock(&iaxsl[x]);
01493 break;
01494 }
01495 ast_mutex_unlock(&iaxsl[x]);
01496 }
01497 if (x >= ARRAY_LEN(iaxs) - 1) {
01498 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01499 return -1;
01500 }
01501 if (option_debug)
01502 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01503
01504 update_max_trunk();
01505 update_max_nontrunk();
01506 return res;
01507 }
01508
01509
01510
01511
01512 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01513 {
01514 int res = 0;
01515 int x;
01516 struct timeval now;
01517 char host[80];
01518
01519 if (new <= NEW_ALLOW) {
01520 if (callno) {
01521 struct chan_iax2_pvt *pvt;
01522 struct chan_iax2_pvt tmp_pvt = {
01523 .callno = dcallno,
01524 .peercallno = callno,
01525
01526 .frames_received = check_dcallno,
01527 };
01528
01529 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01530
01531 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01532 if (return_locked) {
01533 ast_mutex_lock(&iaxsl[pvt->callno]);
01534 }
01535 res = pvt->callno;
01536 ao2_ref(pvt, -1);
01537 pvt = NULL;
01538 return res;
01539 }
01540 }
01541
01542
01543 for (x = 1; !res && x < maxnontrunkcall; x++) {
01544 ast_mutex_lock(&iaxsl[x]);
01545 if (iaxs[x]) {
01546
01547 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01548 res = x;
01549 }
01550 }
01551 if (!res || !return_locked)
01552 ast_mutex_unlock(&iaxsl[x]);
01553 }
01554 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01555 ast_mutex_lock(&iaxsl[x]);
01556 if (iaxs[x]) {
01557
01558 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01559 res = x;
01560 }
01561 }
01562 if (!res || !return_locked)
01563 ast_mutex_unlock(&iaxsl[x]);
01564 }
01565 }
01566 if (!res && (new >= NEW_ALLOW)) {
01567 int start, found = 0;
01568
01569
01570
01571
01572
01573
01574
01575 if (!iax2_getpeername(*sin, host, sizeof(host)))
01576 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01577
01578 now = ast_tvnow();
01579 start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01580 for (x = start; 1; x++) {
01581 if (x == TRUNK_CALL_START) {
01582 x = 1;
01583 continue;
01584 }
01585
01586
01587 ast_mutex_lock(&iaxsl[x]);
01588 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01589 found = 1;
01590 break;
01591 }
01592 ast_mutex_unlock(&iaxsl[x]);
01593
01594 if (x == start - 1) {
01595 break;
01596 }
01597 }
01598
01599 if (x == start - 1 && !found) {
01600 ast_log(LOG_WARNING, "No more space\n");
01601 return 0;
01602 }
01603 iaxs[x] = new_iax(sin, host);
01604 update_max_nontrunk();
01605 if (iaxs[x]) {
01606 if (option_debug && iaxdebug)
01607 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01608 iaxs[x]->sockfd = sockfd;
01609 iaxs[x]->addr.sin_port = sin->sin_port;
01610 iaxs[x]->addr.sin_family = sin->sin_family;
01611 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01612 iaxs[x]->peercallno = callno;
01613 iaxs[x]->callno = x;
01614 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01615 iaxs[x]->expiry = min_reg_expire;
01616 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01617 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01618 iaxs[x]->amaflags = amaflags;
01619 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01620
01621 ast_string_field_set(iaxs[x], accountcode, accountcode);
01622 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01623 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01624
01625 if (iaxs[x]->peercallno) {
01626 store_by_peercallno(iaxs[x]);
01627 }
01628 } else {
01629 ast_log(LOG_WARNING, "Out of resources\n");
01630 ast_mutex_unlock(&iaxsl[x]);
01631 return 0;
01632 }
01633 if (!return_locked)
01634 ast_mutex_unlock(&iaxsl[x]);
01635 res = x;
01636 }
01637 return res;
01638 }
01639
01640 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01641
01642 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01643 }
01644
01645 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01646
01647 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01648 }
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660 static int iax2_queue_frame(int callno, struct ast_frame *f)
01661 {
01662 for (;;) {
01663 if (iaxs[callno] && iaxs[callno]->owner) {
01664 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01665
01666 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01667 } else {
01668 ast_queue_frame(iaxs[callno]->owner, f);
01669 ast_mutex_unlock(&iaxs[callno]->owner->lock);
01670 break;
01671 }
01672 } else
01673 break;
01674 }
01675 return 0;
01676 }
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691 static int iax2_queue_hangup(int callno)
01692 {
01693 for (;;) {
01694 if (iaxs[callno] && iaxs[callno]->owner) {
01695 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01696
01697 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01698 } else {
01699 ast_queue_hangup(iaxs[callno]->owner);
01700 ast_mutex_unlock(&iaxs[callno]->owner->lock);
01701 break;
01702 }
01703 } else
01704 break;
01705 }
01706 return 0;
01707 }
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722 static int iax2_queue_control_data(int callno,
01723 enum ast_control_frame_type control, const void *data, size_t datalen)
01724 {
01725 for (;;) {
01726 if (iaxs[callno] && iaxs[callno]->owner) {
01727 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01728
01729 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01730 } else {
01731 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01732 ast_mutex_unlock(&iaxs[callno]->owner->lock);
01733 break;
01734 }
01735 } else
01736 break;
01737 }
01738 return 0;
01739 }
01740 static void destroy_firmware(struct iax_firmware *cur)
01741 {
01742
01743 if (cur->fwh) {
01744 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01745 }
01746 close(cur->fd);
01747 free(cur);
01748 }
01749
01750 static int try_firmware(char *s)
01751 {
01752 struct stat stbuf;
01753 struct iax_firmware *cur;
01754 int ifd;
01755 int fd;
01756 int res;
01757
01758 struct ast_iax2_firmware_header *fwh, fwh2;
01759 struct MD5Context md5;
01760 unsigned char sum[16];
01761 unsigned char buf[1024];
01762 int len, chunk;
01763 char *s2;
01764 char *last;
01765 s2 = alloca(strlen(s) + 100);
01766 if (!s2) {
01767 ast_log(LOG_WARNING, "Alloca failed!\n");
01768 return -1;
01769 }
01770 last = strrchr(s, '/');
01771 if (last)
01772 last++;
01773 else
01774 last = s;
01775 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01776 res = stat(s, &stbuf);
01777 if (res < 0) {
01778 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01779 return -1;
01780 }
01781
01782 if (S_ISDIR(stbuf.st_mode))
01783 return -1;
01784 ifd = open(s, O_RDONLY);
01785 if (ifd < 0) {
01786 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01787 return -1;
01788 }
01789 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01790 if (fd < 0) {
01791 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01792 close(ifd);
01793 return -1;
01794 }
01795
01796 unlink(s2);
01797
01798
01799 len = stbuf.st_size;
01800 while(len) {
01801 chunk = len;
01802 if (chunk > sizeof(buf))
01803 chunk = sizeof(buf);
01804 res = read(ifd, buf, chunk);
01805 if (res != chunk) {
01806 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01807 close(ifd);
01808 close(fd);
01809 return -1;
01810 }
01811 res = write(fd, buf, chunk);
01812 if (res != chunk) {
01813 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01814 close(ifd);
01815 close(fd);
01816 return -1;
01817 }
01818 len -= chunk;
01819 }
01820 close(ifd);
01821
01822 lseek(fd, 0, SEEK_SET);
01823 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01824 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01825 close(fd);
01826 return -1;
01827 }
01828 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01829 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01830 close(fd);
01831 return -1;
01832 }
01833 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01834 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01835 close(fd);
01836 return -1;
01837 }
01838 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01839 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01840 close(fd);
01841 return -1;
01842 }
01843 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
01844 if (fwh == (void *) -1) {
01845 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01846 close(fd);
01847 return -1;
01848 }
01849 MD5Init(&md5);
01850 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01851 MD5Final(sum, &md5);
01852 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01853 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01854 munmap((void*)fwh, stbuf.st_size);
01855 close(fd);
01856 return -1;
01857 }
01858 cur = waresl.wares;
01859 while(cur) {
01860 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01861
01862 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01863
01864 break;
01865
01866
01867 munmap((void*)fwh, stbuf.st_size);
01868 close(fd);
01869 return 0;
01870 }
01871 cur = cur->next;
01872 }
01873 if (!cur) {
01874
01875 if ((cur = ast_calloc(1, sizeof(*cur)))) {
01876 cur->fd = -1;
01877 cur->next = waresl.wares;
01878 waresl.wares = cur;
01879 }
01880 }
01881 if (cur) {
01882 if (cur->fwh) {
01883 munmap((void*)cur->fwh, cur->mmaplen);
01884 }
01885 if (cur->fd > -1)
01886 close(cur->fd);
01887 cur->fwh = fwh;
01888 cur->fd = fd;
01889 cur->mmaplen = stbuf.st_size;
01890 cur->dead = 0;
01891 }
01892 return 0;
01893 }
01894
01895 static int iax_check_version(char *dev)
01896 {
01897 int res = 0;
01898 struct iax_firmware *cur;
01899 if (!ast_strlen_zero(dev)) {
01900 ast_mutex_lock(&waresl.lock);
01901 cur = waresl.wares;
01902 while(cur) {
01903 if (!strcmp(dev, (char *)cur->fwh->devname)) {
01904 res = ntohs(cur->fwh->version);
01905 break;
01906 }
01907 cur = cur->next;
01908 }
01909 ast_mutex_unlock(&waresl.lock);
01910 }
01911 return res;
01912 }
01913
01914 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01915 {
01916 int res = -1;
01917 unsigned int bs = desc & 0xff;
01918 unsigned int start = (desc >> 8) & 0xffffff;
01919 unsigned int bytes;
01920 struct iax_firmware *cur;
01921 if (!ast_strlen_zero((char *)dev) && bs) {
01922 start *= bs;
01923 ast_mutex_lock(&waresl.lock);
01924 cur = waresl.wares;
01925 while(cur) {
01926 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01927 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01928 if (start < ntohl(cur->fwh->datalen)) {
01929 bytes = ntohl(cur->fwh->datalen) - start;
01930 if (bytes > bs)
01931 bytes = bs;
01932 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01933 } else {
01934 bytes = 0;
01935 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01936 }
01937 if (bytes == bs)
01938 res = 0;
01939 else
01940 res = 1;
01941 break;
01942 }
01943 cur = cur->next;
01944 }
01945 ast_mutex_unlock(&waresl.lock);
01946 }
01947 return res;
01948 }
01949
01950
01951 static void reload_firmware(int unload)
01952 {
01953 struct iax_firmware *cur, *curl, *curp;
01954 DIR *fwd;
01955 struct dirent *de;
01956 char dir[256];
01957 char fn[256];
01958
01959 ast_mutex_lock(&waresl.lock);
01960 cur = waresl.wares;
01961 while(cur) {
01962 cur->dead = 1;
01963 cur = cur->next;
01964 }
01965
01966
01967 if (!unload) {
01968 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01969 fwd = opendir(dir);
01970 if (fwd) {
01971 while((de = readdir(fwd))) {
01972 if (de->d_name[0] != '.') {
01973 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01974 if (!try_firmware(fn)) {
01975 if (option_verbose > 1)
01976 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01977 }
01978 }
01979 }
01980 closedir(fwd);
01981 } else
01982 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01983 }
01984
01985
01986 cur = waresl.wares;
01987 curp = NULL;
01988 while(cur) {
01989 curl = cur;
01990 cur = cur->next;
01991 if (curl->dead) {
01992 if (curp) {
01993 curp->next = cur;
01994 } else {
01995 waresl.wares = cur;
01996 }
01997 destroy_firmware(curl);
01998 } else {
01999 curp = cur;
02000 }
02001 }
02002 ast_mutex_unlock(&waresl.lock);
02003 }
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013 static int __do_deliver(void *data)
02014 {
02015
02016
02017 struct iax_frame *fr = data;
02018 fr->retrans = -1;
02019 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02020 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02021 iax2_queue_frame(fr->callno, &fr->af);
02022
02023 iax2_frame_free(fr);
02024
02025 return 0;
02026 }
02027
02028 static int handle_error(void)
02029 {
02030
02031
02032
02033 #if 0
02034 struct sockaddr_in *sin;
02035 int res;
02036 struct msghdr m;
02037 struct sock_extended_err e;
02038 m.msg_name = NULL;
02039 m.msg_namelen = 0;
02040 m.msg_iov = NULL;
02041 m.msg_control = &e;
02042 m.msg_controllen = sizeof(e);
02043 m.msg_flags = 0;
02044 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02045 if (res < 0)
02046 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02047 else {
02048 if (m.msg_controllen) {
02049 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02050 if (sin)
02051 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02052 else
02053 ast_log(LOG_WARNING, "No address detected??\n");
02054 } else {
02055 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02056 }
02057 }
02058 #endif
02059 return 0;
02060 }
02061
02062 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02063 {
02064 int res;
02065 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02066 sizeof(*sin));
02067 if (res < 0) {
02068 if (option_debug)
02069 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02070 handle_error();
02071 } else
02072 res = 0;
02073 return res;
02074 }
02075
02076 static int send_packet(struct iax_frame *f)
02077 {
02078 int res;
02079 int callno = f->callno;
02080
02081
02082 if (!callno || !iaxs[callno] || iaxs[callno]->error)
02083 return -1;
02084
02085
02086 if (option_debug > 2 && iaxdebug)
02087 ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
02088 if (f->transfer) {
02089 if (iaxdebug)
02090 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02091 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02092 sizeof(iaxs[callno]->transfer));
02093 } else {
02094 if (iaxdebug)
02095 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02096 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02097 sizeof(iaxs[callno]->addr));
02098 }
02099 if (res < 0) {
02100 if (option_debug && iaxdebug)
02101 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02102 handle_error();
02103 } else
02104 res = 0;
02105 return res;
02106 }
02107
02108
02109
02110
02111
02112 static int iax2_predestroy(int callno)
02113 {
02114 struct ast_channel *c;
02115 struct chan_iax2_pvt *pvt = iaxs[callno];
02116
02117 if (!pvt)
02118 return -1;
02119 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02120 iax2_destroy_helper(pvt);
02121 ast_set_flag(pvt, IAX_ALREADYGONE);
02122 }
02123 c = pvt->owner;
02124 if (c) {
02125 c->tech_pvt = NULL;
02126 iax2_queue_hangup(callno);
02127 pvt->owner = NULL;
02128 ast_module_unref(ast_module_info->self);
02129 }
02130 return 0;
02131 }
02132
02133 static int update_packet(struct iax_frame *f)
02134 {
02135
02136 struct ast_iax2_full_hdr *fh = f->data;
02137
02138 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02139
02140 f->iseqno = iaxs[f->callno]->iseqno;
02141 fh->iseqno = f->iseqno;
02142 return 0;
02143 }
02144
02145 static int attempt_transmit(const void *data);
02146 static void __attempt_transmit(const void *data)
02147 {
02148
02149
02150 struct iax_frame *f = (struct iax_frame *)data;
02151 int freeme=0;
02152 int callno = f->callno;
02153
02154 if (callno)
02155 ast_mutex_lock(&iaxsl[callno]);
02156 if (callno && iaxs[callno]) {
02157 if ((f->retries < 0) ||
02158 (f->retries >= max_retries) ) {
02159
02160 if (f->retries >= max_retries) {
02161 if (f->transfer) {
02162
02163 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02164 } else if (f->final) {
02165 if (f->final)
02166 iax2_destroy(callno);
02167 } else {
02168 if (iaxs[callno]->owner)
02169 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
02170 iaxs[callno]->error = ETIMEDOUT;
02171 if (iaxs[callno]->owner) {
02172 struct ast_frame fr = { 0, };
02173
02174 fr.frametype = AST_FRAME_CONTROL;
02175 fr.subclass = AST_CONTROL_HANGUP;
02176 iax2_queue_frame(callno, &fr);
02177
02178 if (iaxs[callno] && iaxs[callno]->owner)
02179 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02180 } else {
02181 if (iaxs[callno]->reg) {
02182 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02183 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02184 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02185 }
02186 iax2_destroy(callno);
02187 }
02188 }
02189
02190 }
02191 freeme++;
02192 } else {
02193
02194 update_packet(f);
02195
02196 send_packet(f);
02197 f->retries++;
02198
02199 f->retrytime *= 10;
02200 if (f->retrytime > MAX_RETRY_TIME)
02201 f->retrytime = MAX_RETRY_TIME;
02202
02203 if (f->transfer && (f->retrytime > 1000))
02204 f->retrytime = 1000;
02205 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02206 }
02207 } else {
02208
02209 f->retries = -1;
02210 freeme++;
02211 }
02212 if (callno)
02213 ast_mutex_unlock(&iaxsl[callno]);
02214
02215 if (freeme) {
02216
02217 AST_LIST_LOCK(&iaxq.queue);
02218 AST_LIST_REMOVE(&iaxq.queue, f, list);
02219 iaxq.count--;
02220 AST_LIST_UNLOCK(&iaxq.queue);
02221 f->retrans = -1;
02222
02223 iax2_frame_free(f);
02224 }
02225 }
02226
02227 static int attempt_transmit(const void *data)
02228 {
02229 #ifdef SCHED_MULTITHREADED
02230 if (schedule_action(__attempt_transmit, data))
02231 #endif
02232 __attempt_transmit(data);
02233 return 0;
02234 }
02235
02236 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02237 {
02238 struct iax2_peer *peer;
02239
02240 if (argc != 4)
02241 return RESULT_SHOWUSAGE;
02242 if (!strcmp(argv[3],"all")) {
02243 reload_config();
02244 ast_cli(fd, "OK cache is flushed.\n");
02245 } else if ((peer = find_peer(argv[3], 0))) {
02246 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02247 ast_set_flag(peer, IAX_RTAUTOCLEAR);
02248 expire_registry(peer_ref(peer));
02249 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02250 } else {
02251 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02252 }
02253 peer_unref(peer);
02254 } else {
02255 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02256 }
02257
02258 return RESULT_SUCCESS;
02259 }
02260
02261 static int iax2_test_losspct(int fd, int argc, char *argv[])
02262 {
02263 if (argc != 4)
02264 return RESULT_SHOWUSAGE;
02265
02266 test_losspct = atoi(argv[3]);
02267
02268 return RESULT_SUCCESS;
02269 }
02270
02271 #ifdef IAXTESTS
02272 static int iax2_test_late(int fd, int argc, char *argv[])
02273 {
02274 if (argc != 4)
02275 return RESULT_SHOWUSAGE;
02276
02277 test_late = atoi(argv[3]);
02278
02279 return RESULT_SUCCESS;
02280 }
02281
02282 static int iax2_test_resync(int fd, int argc, char *argv[])
02283 {
02284 if (argc != 4)
02285 return RESULT_SHOWUSAGE;
02286
02287 test_resync = atoi(argv[3]);
02288
02289 return RESULT_SUCCESS;
02290 }
02291
02292 static int iax2_test_jitter(int fd, int argc, char *argv[])
02293 {
02294 if (argc < 4 || argc > 5)
02295 return RESULT_SHOWUSAGE;
02296
02297 test_jit = atoi(argv[3]);
02298 if (argc == 5)
02299 test_jitpct = atoi(argv[4]);
02300
02301 return RESULT_SUCCESS;
02302 }
02303 #endif
02304
02305
02306
02307 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02308 {
02309 int res = 0;
02310 if (peer->maxms) {
02311 if (peer->lastms < 0) {
02312 ast_copy_string(status, "UNREACHABLE", statuslen);
02313 } else if (peer->lastms > peer->maxms) {
02314 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02315 res = 1;
02316 } else if (peer->lastms) {
02317 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02318 res = 1;
02319 } else {
02320 ast_copy_string(status, "UNKNOWN", statuslen);
02321 }
02322 } else {
02323 ast_copy_string(status, "Unmonitored", statuslen);
02324 res = -1;
02325 }
02326 return res;
02327 }
02328
02329
02330 static int iax2_show_peer(int fd, int argc, char *argv[])
02331 {
02332 char status[30];
02333 char cbuf[256];
02334 struct iax2_peer *peer;
02335 char codec_buf[512];
02336 int x = 0, codec = 0, load_realtime = 0;
02337
02338 if (argc < 4)
02339 return RESULT_SHOWUSAGE;
02340
02341 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02342
02343 peer = find_peer(argv[3], load_realtime);
02344 if (peer) {
02345 ast_cli(fd,"\n\n");
02346 ast_cli(fd, " * Name : %s\n", peer->name);
02347 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02348 ast_cli(fd, " Context : %s\n", peer->context);
02349 ast_cli(fd, " Mailbox : %s\n", peer->mailbox);
02350 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02351 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02352 ast_cli(fd, " Expire : %d\n", peer->expire);
02353 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No"));
02354 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
02355 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02356 ast_cli(fd, " Username : %s\n", peer->username);
02357 ast_cli(fd, " Codecs : ");
02358 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02359 ast_cli(fd, "%s\n", codec_buf);
02360
02361 ast_cli(fd, " Codec Order : (");
02362 for(x = 0; x < 32 ; x++) {
02363 codec = ast_codec_pref_index(&peer->prefs,x);
02364 if(!codec)
02365 break;
02366 ast_cli(fd, "%s", ast_getformatname(codec));
02367 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02368 ast_cli(fd, "|");
02369 }
02370
02371 if (!x)
02372 ast_cli(fd, "none");
02373 ast_cli(fd, ")\n");
02374
02375 ast_cli(fd, " Status : ");
02376 peer_status(peer, status, sizeof(status));
02377 ast_cli(fd, "%s\n",status);
02378 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02379 ast_cli(fd,"\n");
02380 peer_unref(peer);
02381 } else {
02382 ast_cli(fd,"Peer %s not found.\n", argv[3]);
02383 ast_cli(fd,"\n");
02384 }
02385
02386 return RESULT_SUCCESS;
02387 }
02388
02389 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02390 {
02391 int which = 0;
02392 struct iax2_peer *peer;
02393 char *res = NULL;
02394 int wordlen = strlen(word);
02395 struct ao2_iterator i;
02396
02397
02398 if (pos != 3)
02399 return NULL;
02400
02401 i = ao2_iterator_init(peers, 0);
02402 while ((peer = ao2_iterator_next(&i))) {
02403 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02404 res = ast_strdup(peer->name);
02405 peer_unref(peer);
02406 break;
02407 }
02408 peer_unref(peer);
02409 }
02410
02411 return res;
02412 }
02413
02414 static int iax2_show_stats(int fd, int argc, char *argv[])
02415 {
02416 struct iax_frame *cur;
02417 int cnt = 0, dead=0, final=0;
02418
02419 if (argc != 3)
02420 return RESULT_SHOWUSAGE;
02421
02422 AST_LIST_LOCK(&iaxq.queue);
02423 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02424 if (cur->retries < 0)
02425 dead++;
02426 if (cur->final)
02427 final++;
02428 cnt++;
02429 }
02430 AST_LIST_UNLOCK(&iaxq.queue);
02431
02432 ast_cli(fd, " IAX Statistics\n");
02433 ast_cli(fd, "---------------------\n");
02434 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02435 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02436
02437 return RESULT_SUCCESS;
02438 }
02439
02440 static int iax2_show_cache(int fd, int argc, char *argv[])
02441 {
02442 struct iax2_dpcache *dp;
02443 char tmp[1024], *pc;
02444 int s;
02445 int x,y;
02446 struct timeval tv;
02447 gettimeofday(&tv, NULL);
02448 ast_mutex_lock(&dpcache_lock);
02449 dp = dpcache;
02450 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02451 while(dp) {
02452 s = dp->expiry.tv_sec - tv.tv_sec;
02453 tmp[0] = '\0';
02454 if (dp->flags & CACHE_FLAG_EXISTS)
02455 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02456 if (dp->flags & CACHE_FLAG_NONEXISTENT)
02457 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02458 if (dp->flags & CACHE_FLAG_CANEXIST)
02459 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02460 if (dp->flags & CACHE_FLAG_PENDING)
02461 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02462 if (dp->flags & CACHE_FLAG_TIMEOUT)
02463 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02464 if (dp->flags & CACHE_FLAG_TRANSMITTED)
02465 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02466 if (dp->flags & CACHE_FLAG_MATCHMORE)
02467 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02468 if (dp->flags & CACHE_FLAG_UNKNOWN)
02469 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02470
02471 if (!ast_strlen_zero(tmp))
02472 tmp[strlen(tmp) - 1] = '\0';
02473 else
02474 ast_copy_string(tmp, "(none)", sizeof(tmp));
02475 y=0;
02476 pc = strchr(dp->peercontext, '@');
02477 if (!pc)
02478 pc = dp->peercontext;
02479 else
02480 pc++;
02481 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02482 if (dp->waiters[x] > -1)
02483 y++;
02484 if (s > 0)
02485 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02486 else
02487 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02488 dp = dp->next;
02489 }
02490 ast_mutex_unlock(&dpcache_lock);
02491 return RESULT_SUCCESS;
02492 }
02493
02494 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02495
02496 static void unwrap_timestamp(struct iax_frame *fr)
02497 {
02498 int x;
02499
02500 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02501 x = fr->ts - iaxs[fr->callno]->last;
02502 if (x < -50000) {
02503
02504
02505
02506
02507 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02508 if (option_debug && iaxdebug)
02509 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02510 }
02511 if (x > 50000) {
02512
02513
02514
02515
02516 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02517 if (option_debug && iaxdebug)
02518 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02519 }
02520 }
02521 }
02522
02523 static int get_from_jb(const void *p);
02524
02525 static void update_jbsched(struct chan_iax2_pvt *pvt)
02526 {
02527 int when;
02528
02529 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02530
02531 when = jb_next(pvt->jb) - when;
02532
02533 AST_SCHED_DEL(sched, pvt->jbid);
02534
02535 if(when <= 0) {
02536
02537 when = 1;
02538 }
02539
02540 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02541 }
02542
02543 static void __get_from_jb(const void *p)
02544 {
02545 int callno = PTR_TO_CALLNO(p);
02546 struct chan_iax2_pvt *pvt = NULL;
02547 struct iax_frame *fr;
02548 jb_frame frame;
02549 int ret;
02550 long now;
02551 long next;
02552 struct timeval tv;
02553
02554
02555 ast_mutex_lock(&iaxsl[callno]);
02556 pvt = iaxs[callno];
02557 if (!pvt) {
02558
02559 ast_mutex_unlock(&iaxsl[callno]);
02560 return;
02561 }
02562
02563 pvt->jbid = -1;
02564
02565 gettimeofday(&tv,NULL);
02566
02567
02568
02569 tv.tv_usec += 1000;
02570
02571 now = ast_tvdiff_ms(tv, pvt->rxcore);
02572
02573 if(now >= (next = jb_next(pvt->jb))) {
02574 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02575 switch(ret) {
02576 case JB_OK:
02577 fr = frame.data;
02578 __do_deliver(fr);
02579
02580 pvt = iaxs[callno];
02581 break;
02582 case JB_INTERP:
02583 {
02584 struct ast_frame af = { 0, };
02585
02586
02587 af.frametype = AST_FRAME_VOICE;
02588 af.subclass = pvt->voiceformat;
02589 af.samples = frame.ms * 8;
02590 af.src = "IAX2 JB interpolation";
02591 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02592 af.offset = AST_FRIENDLY_OFFSET;
02593
02594
02595
02596 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02597 iax2_queue_frame(callno, &af);
02598
02599 pvt = iaxs[callno];
02600 }
02601 }
02602 break;
02603 case JB_DROP:
02604 iax2_frame_free(frame.data);
02605 break;
02606 case JB_NOFRAME:
02607 case JB_EMPTY:
02608
02609 break;
02610 default:
02611
02612 break;
02613 }
02614 }
02615 if (pvt)
02616 update_jbsched(pvt);
02617 ast_mutex_unlock(&iaxsl[callno]);
02618 }
02619
02620 static int get_from_jb(const void *data)
02621 {
02622 #ifdef SCHED_MULTITHREADED
02623 if (schedule_action(__get_from_jb, data))
02624 #endif
02625 __get_from_jb(data);
02626 return 0;
02627 }
02628
02629
02630
02631
02632
02633
02634
02635 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02636 {
02637 int type, len;
02638 int ret;
02639 int needfree = 0;
02640 struct ast_channel *owner = NULL;
02641 struct ast_channel *bridge = NULL;
02642
02643
02644 unwrap_timestamp(fr);
02645
02646
02647 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02648 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02649 else {
02650 #if 0
02651 if (option_debug)
02652 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02653 #endif
02654 fr->af.delivery = ast_tv(0,0);
02655 }
02656
02657 type = JB_TYPE_CONTROL;
02658 len = 0;
02659
02660 if(fr->af.frametype == AST_FRAME_VOICE) {
02661 type = JB_TYPE_VOICE;
02662 len = ast_codec_get_samples(&fr->af) / 8;
02663 } else if(fr->af.frametype == AST_FRAME_CNG) {
02664 type = JB_TYPE_SILENCE;
02665 }
02666
02667 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02668 if (tsout)
02669 *tsout = fr->ts;
02670 __do_deliver(fr);
02671 return -1;
02672 }
02673
02674 if ((owner = iaxs[fr->callno]->owner))
02675 bridge = ast_bridged_channel(owner);
02676
02677
02678
02679 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02680 jb_frame frame;
02681
02682
02683 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02684 __do_deliver(frame.data);
02685
02686 if (!iaxs[fr->callno])
02687 return -1;
02688 }
02689
02690 jb_reset(iaxs[fr->callno]->jb);
02691
02692 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02693
02694
02695 if (tsout)
02696 *tsout = fr->ts;
02697 __do_deliver(fr);
02698 return -1;
02699 }
02700
02701
02702
02703 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02704 calc_rxstamp(iaxs[fr->callno],fr->ts));
02705 if (ret == JB_DROP) {
02706 needfree++;
02707 } else if (ret == JB_SCHED) {
02708 update_jbsched(iaxs[fr->callno]);
02709 }
02710 if (tsout)
02711 *tsout = fr->ts;
02712 if (needfree) {
02713
02714 iax2_frame_free(fr);
02715 return -1;
02716 }
02717 return 0;
02718 }
02719
02720 static int iax2_transmit(struct iax_frame *fr)
02721 {
02722
02723
02724
02725 fr->sentyet = 0;
02726 AST_LIST_LOCK(&iaxq.queue);
02727 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02728 iaxq.count++;
02729 AST_LIST_UNLOCK(&iaxq.queue);
02730
02731 if (netthreadid != AST_PTHREADT_NULL)
02732 pthread_kill(netthreadid, SIGURG);
02733 signal_condition(&sched_lock, &sched_cond);
02734 return 0;
02735 }
02736
02737
02738
02739 static int iax2_digit_begin(struct ast_channel *c, char digit)
02740 {
02741 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02742 }
02743
02744 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02745 {
02746 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02747 }
02748
02749 static int iax2_sendtext(struct ast_channel *c, const char *text)
02750 {
02751
02752 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02753 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02754 }
02755
02756 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02757 {
02758 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02759 }
02760
02761 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02762 {
02763 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02764 }
02765
02766 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02767 {
02768 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02769 ast_mutex_lock(&iaxsl[callno]);
02770 if (iaxs[callno])
02771 iaxs[callno]->owner = newchan;
02772 else
02773 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02774 ast_mutex_unlock(&iaxsl[callno]);
02775 return 0;
02776 }
02777
02778
02779
02780
02781
02782 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02783 {
02784 struct ast_variable *var = NULL;
02785 struct ast_variable *tmp;
02786 struct iax2_peer *peer=NULL;
02787 time_t regseconds = 0, nowtime;
02788 int dynamic=0;
02789
02790 if (peername) {
02791 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02792 if (!var && sin)
02793 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02794 } else if (sin) {
02795 char porta[25];
02796 sprintf(porta, "%d", ntohs(sin->sin_port));
02797 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02798 if (var) {
02799
02800 for (tmp = var; tmp; tmp = tmp->next) {
02801 if (!strcasecmp(tmp->name, "name"))
02802 peername = tmp->value;
02803 }
02804 }
02805 }
02806 if (!var && peername) {
02807 var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02808
02809
02810
02811
02812
02813
02814 if (var && sin) {
02815 for (tmp = var; tmp; tmp = tmp->next) {
02816 if (!strcasecmp(tmp->name, "host")) {
02817 struct ast_hostent ahp;
02818 struct hostent *hp;
02819 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02820
02821 ast_variables_destroy(var);
02822 var = NULL;
02823 }
02824 break;
02825 }
02826 }
02827 }
02828 }
02829 if (!var)
02830 return NULL;
02831
02832 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02833
02834 if (!peer) {
02835 ast_variables_destroy(var);
02836 return NULL;
02837 }
02838
02839 for (tmp = var; tmp; tmp = tmp->next) {
02840
02841 if (!strcasecmp(tmp->name, "type")) {
02842 if (strcasecmp(tmp->value, "friend") &&
02843 strcasecmp(tmp->value, "peer")) {
02844
02845 peer = peer_unref(peer);
02846 break;
02847 }
02848 } else if (!strcasecmp(tmp->name, "regseconds")) {
02849 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
02850 } else if (!strcasecmp(tmp->name, "ipaddr")) {
02851 inet_aton(tmp->value, &(peer->addr.sin_addr));
02852 } else if (!strcasecmp(tmp->name, "port")) {
02853 peer->addr.sin_port = htons(atoi(tmp->value));
02854 } else if (!strcasecmp(tmp->name, "host")) {
02855 if (!strcasecmp(tmp->value, "dynamic"))
02856 dynamic = 1;
02857 }
02858 }
02859
02860 ast_variables_destroy(var);
02861
02862 if (!peer)
02863 return NULL;
02864
02865 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02866 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02867 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02868 if (peer->expire > -1) {
02869 if (!ast_sched_del(sched, peer->expire)) {
02870 peer->expire = -1;
02871 peer_unref(peer);
02872 }
02873 }
02874 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
02875 if (peer->expire == -1)
02876 peer_unref(peer);
02877 }
02878 ao2_link(peers, peer);
02879 if (ast_test_flag(peer, IAX_DYNAMIC))
02880 reg_source_db(peer);
02881 } else {
02882 ast_set_flag(peer, IAX_TEMPONLY);
02883 }
02884
02885 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02886 time(&nowtime);
02887 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02888 memset(&peer->addr, 0, sizeof(peer->addr));
02889 realtime_update_peer(peer->name, &peer->addr, 0);
02890 if (option_debug)
02891 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02892 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02893 }
02894 else {
02895 if (option_debug)
02896 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02897 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02898 }
02899 }
02900
02901 return peer;
02902 }
02903
02904 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
02905 {
02906 struct ast_variable *var;
02907 struct ast_variable *tmp;
02908 struct iax2_user *user=NULL;
02909
02910 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
02911 if (!var)
02912 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02913 if (!var && sin) {
02914 char porta[6];
02915 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
02916 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02917 if (!var)
02918 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02919 }
02920 if (!var) {
02921 var = ast_load_realtime("iaxusers", "name", username, NULL);
02922
02923
02924
02925
02926
02927
02928 if (var) {
02929 for (tmp = var; tmp; tmp = tmp->next) {
02930 if (!strcasecmp(tmp->name, "host")) {
02931 struct ast_hostent ahp;
02932 struct hostent *hp;
02933 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02934
02935 ast_variables_destroy(var);
02936 var = NULL;
02937 }
02938 break;
02939 }
02940 }
02941 }
02942 }
02943 if (!var)
02944 return NULL;
02945
02946 tmp = var;
02947 while(tmp) {
02948
02949 if (!strcasecmp(tmp->name, "type")) {
02950 if (strcasecmp(tmp->value, "friend") &&
02951 strcasecmp(tmp->value, "user")) {
02952 return NULL;
02953 }
02954 }
02955 tmp = tmp->next;
02956 }
02957
02958 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02959
02960 ast_variables_destroy(var);
02961
02962 if (!user)
02963 return NULL;
02964
02965 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02966 ast_set_flag(user, IAX_RTCACHEFRIENDS);
02967 ao2_link(users, user);
02968 } else {
02969 ast_set_flag(user, IAX_TEMPONLY);
02970 }
02971
02972 return user;
02973 }
02974
02975 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02976 {
02977 char port[10];
02978 char regseconds[20];
02979
02980 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02981 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02982 ast_update_realtime("iaxpeers", "name", peername,
02983 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
02984 "regseconds", regseconds, NULL);
02985 }
02986
02987 struct create_addr_info {
02988 int capability;
02989 unsigned int flags;
02990 int maxtime;
02991 int encmethods;
02992 int found;
02993 int sockfd;
02994 int adsi;
02995 char username[80];
02996 char secret[80];
02997 char outkey[80];
02998 char timezone[80];
02999 char prefs[32];
03000 char context[AST_MAX_CONTEXT];
03001 char peercontext[AST_MAX_CONTEXT];
03002 char mohinterpret[MAX_MUSICCLASS];
03003 char mohsuggest[MAX_MUSICCLASS];
03004 };
03005
03006 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03007 {
03008 struct ast_hostent ahp;
03009 struct hostent *hp;
03010 struct iax2_peer *peer;
03011 int res = -1;
03012 struct ast_codec_pref ourprefs;
03013
03014 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03015 cai->sockfd = defaultsockfd;
03016 cai->maxtime = 0;
03017 sin->sin_family = AF_INET;
03018
03019 if (!(peer = find_peer(peername, 1))) {
03020 cai->found = 0;
03021
03022 hp = ast_gethostbyname(peername, &ahp);
03023 if (hp) {
03024 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03025 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03026
03027
03028 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03029 if (c)
03030 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03031 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03032 return 0;
03033 } else {
03034 ast_log(LOG_WARNING, "No such host: %s\n", peername);
03035 return -1;
03036 }
03037 }
03038
03039 cai->found = 1;
03040
03041
03042 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03043 goto return_unref;
03044
03045
03046 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03047 goto return_unref;
03048
03049 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03050 cai->maxtime = peer->maxms;
03051 cai->capability = peer->capability;
03052 cai->encmethods = peer->encmethods;
03053 cai->sockfd = peer->sockfd;
03054 cai->adsi = peer->adsi;
03055 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03056
03057 if (c) {
03058 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03059 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03060 }
03061 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03062 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03063 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03064 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03065 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03066 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03067 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03068 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03069 if (ast_strlen_zero(peer->dbsecret)) {
03070 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03071 } else {
03072 char *family;
03073 char *key = NULL;
03074
03075 family = ast_strdupa(peer->dbsecret);
03076 key = strchr(family, '/');
03077 if (key)
03078 *key++ = '\0';
03079 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03080 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03081 goto return_unref;
03082 }
03083 }
03084
03085 if (peer->addr.sin_addr.s_addr) {
03086 sin->sin_addr = peer->addr.sin_addr;
03087 sin->sin_port = peer->addr.sin_port;
03088 } else {
03089 sin->sin_addr = peer->defaddr.sin_addr;
03090 sin->sin_port = peer->defaddr.sin_port;
03091 }
03092
03093 res = 0;
03094
03095 return_unref:
03096 peer_unref(peer);
03097
03098 return res;
03099 }
03100
03101 static void __auto_congest(const void *nothing)
03102 {
03103 int callno = PTR_TO_CALLNO(nothing);
03104 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03105 ast_mutex_lock(&iaxsl[callno]);
03106 if (iaxs[callno]) {
03107 iaxs[callno]->initid = -1;
03108 iax2_queue_frame(callno, &f);
03109 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03110 }
03111 ast_mutex_unlock(&iaxsl[callno]);
03112 }
03113
03114 static int auto_congest(const void *data)
03115 {
03116 #ifdef SCHED_MULTITHREADED
03117 if (schedule_action(__auto_congest, data))
03118 #endif
03119 __auto_congest(data);
03120 return 0;
03121 }
03122
03123 static unsigned int iax2_datetime(const char *tz)
03124 {
03125 time_t t;
03126 struct tm tm;
03127 unsigned int tmp;
03128 time(&t);
03129 if (!ast_strlen_zero(tz))
03130 ast_localtime(&t, &tm, tz);
03131 else
03132 ast_localtime(&t, &tm, NULL);
03133 tmp = (tm.tm_sec >> 1) & 0x1f;
03134 tmp |= (tm.tm_min & 0x3f) << 5;
03135 tmp |= (tm.tm_hour & 0x1f) << 11;
03136 tmp |= (tm.tm_mday & 0x1f) << 16;
03137 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
03138 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
03139 return tmp;
03140 }
03141
03142 struct parsed_dial_string {
03143 char *username;
03144 char *password;
03145 char *key;
03146 char *peer;
03147 char *port;
03148 char *exten;
03149 char *context;
03150 char *options;
03151 };
03152
03153 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03154 {
03155 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03156 .ts = htonl(ts), .iseqno = seqno, .oseqno = seqno, .type = AST_FRAME_IAX,
03157 .csub = compress_subclass(command) };
03158
03159 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03160 }
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03181 {
03182 if (ast_strlen_zero(data))
03183 return;
03184
03185 pds->peer = strsep(&data, "/");
03186 pds->exten = strsep(&data, "/");
03187 pds->options = data;
03188
03189 if (pds->exten) {
03190 data = pds->exten;
03191 pds->exten = strsep(&data, "@");
03192 pds->context = data;
03193 }
03194
03195 if (strchr(pds->peer, '@')) {
03196 data = pds->peer;
03197 pds->username = strsep(&data, "@");
03198 pds->peer = data;
03199 }
03200
03201 if (pds->username) {
03202 data = pds->username;
03203 pds->username = strsep(&data, ":");
03204 pds->password = data;
03205 }
03206
03207 data = pds->peer;
03208 pds->peer = strsep(&data, ":");
03209 pds->port = data;
03210
03211
03212
03213
03214 if (pds->password && (pds->password[0] == '[')) {
03215 pds->key = ast_strip_quoted(pds->password, "[", "]");
03216 pds->password = NULL;
03217 }
03218 }
03219
03220 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03221 {
03222 struct sockaddr_in sin;
03223 char *l=NULL, *n=NULL, *tmpstr;
03224 struct iax_ie_data ied;
03225 char *defaultrdest = "s";
03226 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03227 struct parsed_dial_string pds;
03228 struct create_addr_info cai;
03229
03230 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03231 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03232 return -1;
03233 }
03234
03235 memset(&cai, 0, sizeof(cai));
03236 cai.encmethods = iax2_encryption;
03237
03238 memset(&pds, 0, sizeof(pds));
03239 tmpstr = ast_strdupa(dest);
03240 parse_dial_string(tmpstr, &pds);
03241
03242 if (ast_strlen_zero(pds.peer)) {
03243 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03244 return -1;
03245 }
03246
03247 if (!pds.exten) {
03248 pds.exten = defaultrdest;
03249 }
03250
03251 if (create_addr(pds.peer, c, &sin, &cai)) {
03252 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03253 return -1;
03254 }
03255
03256 if (!pds.username && !ast_strlen_zero(cai.username))
03257 pds.username = cai.username;
03258 if (!pds.password && !ast_strlen_zero(cai.secret))
03259 pds.password = cai.secret;
03260 if (!pds.key && !ast_strlen_zero(cai.outkey))
03261 pds.key = cai.outkey;
03262 if (!pds.context && !ast_strlen_zero(cai.peercontext))
03263 pds.context = cai.peercontext;
03264
03265
03266 ast_copy_string(c->context, cai.context, sizeof(c->context));
03267
03268 if (pds.port)
03269 sin.sin_port = htons(atoi(pds.port));
03270
03271 l = c->cid.cid_num;
03272 n = c->cid.cid_name;
03273
03274
03275 memset(&ied, 0, sizeof(ied));
03276
03277
03278 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03279 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03280 if (pds.options && strchr(pds.options, 'a')) {
03281
03282 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03283 }
03284
03285 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03286
03287 if (l) {
03288 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03289 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03290 } else {
03291 if (n)
03292 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03293 else
03294 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03295 }
03296
03297 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03298 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03299
03300 if (n)
03301 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03302 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03303 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03304
03305 if (!ast_strlen_zero(c->language))
03306 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03307 if (!ast_strlen_zero(c->cid.cid_dnid))
03308 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03309 if (!ast_strlen_zero(c->cid.cid_rdnis))
03310 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03311
03312 if (pds.context)
03313 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03314
03315 if (pds.username)
03316 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03317
03318 if (cai.encmethods)
03319 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03320
03321 ast_mutex_lock(&iaxsl[callno]);
03322
03323 if (!ast_strlen_zero(c->context))
03324 ast_string_field_set(iaxs[callno], context, c->context);
03325
03326 if (pds.username)
03327 ast_string_field_set(iaxs[callno], username, pds.username);
03328
03329 iaxs[callno]->encmethods = cai.encmethods;
03330
03331 iaxs[callno]->adsi = cai.adsi;
03332
03333 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03334 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03335
03336 if (pds.key)
03337 ast_string_field_set(iaxs[callno], outkey, pds.key);
03338 if (pds.password)
03339 ast_string_field_set(iaxs[callno], secret, pds.password);
03340
03341 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03342 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03343 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03344 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03345
03346 if (iaxs[callno]->maxtime) {
03347
03348 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03349 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03350 } else if (autokill) {
03351 iaxs[callno]->pingtime = autokill / 2;
03352 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03353 }
03354
03355
03356 iaxs[callno]->sockfd = cai.sockfd;
03357
03358
03359 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03360
03361 ast_mutex_unlock(&iaxsl[callno]);
03362 ast_setstate(c, AST_STATE_RINGING);
03363
03364 return 0;
03365 }
03366
03367 static int iax2_hangup(struct ast_channel *c)
03368 {
03369 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03370 int alreadygone;
03371 struct iax_ie_data ied;
03372 memset(&ied, 0, sizeof(ied));
03373 ast_mutex_lock(&iaxsl[callno]);
03374 if (callno && iaxs[callno]) {
03375 if (option_debug)
03376 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
03377 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03378
03379 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03380 if (!iaxs[callno]->error && !alreadygone) {
03381 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03382 if (!iaxs[callno]) {
03383 ast_mutex_unlock(&iaxsl[callno]);
03384 return 0;
03385 }
03386 }
03387
03388 iax2_predestroy(callno);
03389
03390 if (alreadygone && iaxs[callno]) {
03391 if (option_debug)
03392 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03393 iax2_destroy(callno);
03394 }
03395 }
03396 ast_mutex_unlock(&iaxsl[callno]);
03397 if (option_verbose > 2)
03398 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03399 return 0;
03400 }
03401
03402 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03403 {
03404 struct ast_option_header *h;
03405 int res;
03406
03407 switch (option) {
03408 case AST_OPTION_TXGAIN:
03409 case AST_OPTION_RXGAIN:
03410
03411 errno = ENOSYS;
03412 return -1;
03413 default:
03414 if (!(h = ast_malloc(datalen + sizeof(*h))))
03415 return -1;
03416
03417 h->flag = AST_OPTION_FLAG_REQUEST;
03418 h->option = htons(option);
03419 memcpy(h->data, data, datalen);
03420 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03421 AST_CONTROL_OPTION, 0, (unsigned char *) h,
03422 datalen + sizeof(*h), -1);
03423 free(h);
03424 return res;
03425 }
03426 }
03427
03428 static struct ast_frame *iax2_read(struct ast_channel *c)
03429 {
03430 ast_log(LOG_NOTICE, "I should never be called!\n");
03431 return &ast_null_frame;
03432 }
03433
03434 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03435 {
03436 int res;
03437 struct iax_ie_data ied0;
03438 struct iax_ie_data ied1;
03439 unsigned int transferid = (unsigned int)ast_random();
03440 memset(&ied0, 0, sizeof(ied0));
03441 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03442 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03443 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03444
03445 memset(&ied1, 0, sizeof(ied1));
03446 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03447 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03448 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03449
03450 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03451 if (res)
03452 return -1;
03453 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03454 if (res)
03455 return -1;
03456 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03457 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03458 return 0;
03459 }
03460
03461 static void lock_both(unsigned short callno0, unsigned short callno1)
03462 {
03463 ast_mutex_lock(&iaxsl[callno0]);
03464 while (ast_mutex_trylock(&iaxsl[callno1])) {
03465 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03466 }
03467 }
03468
03469 static void unlock_both(unsigned short callno0, unsigned short callno1)
03470 {
03471 ast_mutex_unlock(&iaxsl[callno1]);
03472 ast_mutex_unlock(&iaxsl[callno0]);
03473 }
03474
03475 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
03476 {
03477 struct ast_channel *cs[3];
03478 struct ast_channel *who, *other;
03479 int to = -1;
03480 int res = -1;
03481 int transferstarted=0;
03482 struct ast_frame *f;
03483 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03484 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03485 struct timeval waittimer = {0, 0}, tv;
03486
03487 lock_both(callno0, callno1);
03488 if (!iaxs[callno0] || !iaxs[callno1]) {
03489 unlock_both(callno0, callno1);
03490 return AST_BRIDGE_FAILED;
03491 }
03492
03493 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03494 iaxs[callno0]->bridgecallno = callno1;
03495 iaxs[callno1]->bridgecallno = callno0;
03496 }
03497 unlock_both(callno0, callno1);
03498
03499
03500 cs[0] = c0;
03501 cs[1] = c1;
03502 for (;;) {
03503
03504 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03505 if (option_verbose > 2)
03506 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03507
03508 if (c0->tech == &iax2_tech) {
03509 ast_mutex_lock(&iaxsl[callno0]);
03510 iaxs[callno0]->bridgecallno = 0;
03511 ast_mutex_unlock(&iaxsl[callno0]);
03512 }
03513 if (c1->tech == &iax2_tech) {
03514 ast_mutex_lock(&iaxsl[callno1]);
03515 iaxs[callno1]->bridgecallno = 0;
03516 ast_mutex_unlock(&iaxsl[callno1]);
03517 }
03518 return AST_BRIDGE_FAILED_NOWARN;
03519 }
03520 if (c0->nativeformats != c1->nativeformats) {
03521 if (option_verbose > 2) {
03522 char buf0[255];
03523 char buf1[255];
03524 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03525 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03526 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03527 }
03528
03529 lock_both(callno0, callno1);
03530 if (iaxs[callno0])
03531 iaxs[callno0]->bridgecallno = 0;
03532 if (iaxs[callno1])
03533 iaxs[callno1]->bridgecallno = 0;
03534 unlock_both(callno0, callno1);
03535 return AST_BRIDGE_FAILED_NOWARN;
03536 }
03537
03538 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03539
03540 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03541 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03542 ast_log(LOG_WARNING, "Unable to start the transfer\n");
03543 transferstarted = 1;
03544 }
03545 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03546
03547 gettimeofday(&tv, NULL);
03548 if (ast_tvzero(waittimer)) {
03549 waittimer = tv;
03550 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03551 c0->_softhangup |= AST_SOFTHANGUP_DEV;
03552 c1->_softhangup |= AST_SOFTHANGUP_DEV;
03553 *fo = NULL;
03554 *rc = c0;
03555 res = AST_BRIDGE_COMPLETE;
03556 break;
03557 }
03558 }
03559 to = 1000;
03560 who = ast_waitfor_n(cs, 2, &to);
03561 if (timeoutms > -1) {
03562 timeoutms -= (1000 - to);
03563 if (timeoutms < 0)
03564 timeoutms = 0;
03565 }
03566 if (!who) {
03567 if (!timeoutms) {
03568 res = AST_BRIDGE_RETRY;
03569 break;
03570 }
03571 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03572 res = AST_BRIDGE_FAILED;
03573 break;
03574 }
03575 continue;
03576 }
03577 f = ast_read(who);
03578 if (!f) {
03579 *fo = NULL;
03580 *rc = who;
03581 res = AST_BRIDGE_COMPLETE;
03582 break;
03583 }
03584 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03585 *fo = f;
03586 *rc = who;
03587 res = AST_BRIDGE_COMPLETE;
03588 break;
03589 }
03590 other = (who == c0) ? c1 : c0;
03591 if ((f->frametype == AST_FRAME_VOICE) ||
03592 (f->frametype == AST_FRAME_TEXT) ||
03593 (f->frametype == AST_FRAME_VIDEO) ||
03594 (f->frametype == AST_FRAME_IMAGE) ||
03595 (f->frametype == AST_FRAME_DTMF)) {
03596
03597
03598
03599 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03600 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03601 *rc = who;
03602 *fo = f;
03603 res = AST_BRIDGE_COMPLETE;
03604
03605 break;
03606 }
03607
03608 ast_write(other, f);
03609 }
03610 ast_frfree(f);
03611
03612 cs[2] = cs[0];
03613 cs[0] = cs[1];
03614 cs[1] = cs[2];
03615 }
03616 lock_both(callno0, callno1);
03617 if(iaxs[callno0])
03618 iaxs[callno0]->bridgecallno = 0;
03619 if(iaxs[callno1])
03620 iaxs[callno1]->bridgecallno = 0;
03621 unlock_both(callno0, callno1);
03622 return res;
03623 }
03624
03625 static int iax2_answer(struct ast_channel *c)
03626 {
03627 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03628 if (option_debug)
03629 ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03630 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03631 }
03632
03633 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03634 {
03635 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03636 struct chan_iax2_pvt *pvt;
03637 int res = 0;
03638
03639 if (option_debug && iaxdebug)
03640 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03641
03642 ast_mutex_lock(&iaxsl[callno]);
03643 pvt = iaxs[callno];
03644
03645 if (!pvt->peercallno) {
03646
03647 int count = 10;
03648 while (count-- && pvt && !pvt->peercallno) {
03649 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03650 pvt = iaxs[callno];
03651 }
03652 if (!pvt->peercallno) {
03653 res = -1;
03654 goto done;
03655 }
03656 }
03657
03658 switch (condition) {
03659 case AST_CONTROL_HOLD:
03660 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03661 ast_moh_start(c, data, pvt->mohinterpret);
03662 goto done;
03663 }
03664 break;
03665 case AST_CONTROL_UNHOLD:
03666 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03667 ast_moh_stop(c);
03668 goto done;
03669 }
03670 }
03671
03672 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03673
03674 done:
03675 ast_mutex_unlock(&iaxsl[callno]);
03676
03677 return res;
03678 }
03679
03680 static int iax2_transfer(struct ast_channel *c, const char *dest)
03681 {
03682 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03683 struct iax_ie_data ied;
03684 char tmp[256], *context;
03685 ast_copy_string(tmp, dest, sizeof(tmp));
03686 context = strchr(tmp, '@');
03687 if (context) {
03688 *context = '\0';
03689 context++;
03690 }
03691 memset(&ied, 0, sizeof(ied));
03692 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03693 if (context)
03694 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03695 if (option_debug)
03696 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03697 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03698 }
03699
03700 static int iax2_getpeertrunk(struct sockaddr_in sin)
03701 {
03702 struct iax2_peer *peer;
03703 int res = 0;
03704 struct ao2_iterator i;
03705
03706 i = ao2_iterator_init(peers, 0);
03707 while ((peer = ao2_iterator_next(&i))) {
03708 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03709 (peer->addr.sin_port == sin.sin_port)) {
03710 res = ast_test_flag(peer, IAX_TRUNK);
03711 peer_unref(peer);
03712 break;
03713 }
03714 peer_unref(peer);
03715 }
03716
03717 return res;
03718 }
03719
03720
03721 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03722 {
03723 struct ast_channel *tmp;
03724 struct chan_iax2_pvt *i;
03725 struct ast_variable *v = NULL;
03726
03727 if (!(i = iaxs[callno])) {
03728 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03729 return NULL;
03730 }
03731
03732
03733 ast_mutex_unlock(&iaxsl[callno]);
03734 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
03735 ast_mutex_lock(&iaxsl[callno]);
03736 if (!iaxs[callno]) {
03737 if (tmp) {
03738 ast_channel_free(tmp);
03739 }
03740 ast_mutex_unlock(&iaxsl[callno]);
03741 return NULL;
03742 }
03743
03744 if (!tmp)
03745 return NULL;
03746 tmp->tech = &iax2_tech;
03747
03748 tmp->nativeformats = capability;
03749 tmp->readformat = ast_best_codec(capability);
03750 tmp->writeformat = ast_best_codec(capability);
03751 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03752
03753
03754
03755 if (!ast_strlen_zero(i->ani))
03756 tmp->cid.cid_ani = ast_strdup(i->ani);
03757 else
03758 tmp->cid.cid_ani = ast_strdup(i->cid_num);
03759 tmp->cid.cid_dnid = ast_strdup(i->dnid);
03760 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03761 tmp->cid.cid_pres = i->calling_pres;
03762 tmp->cid.cid_ton = i->calling_ton;
03763 tmp->cid.cid_tns = i->calling_tns;
03764 if (!ast_strlen_zero(i->language))
03765 ast_string_field_set(tmp, language, i->language);
03766 if (!ast_strlen_zero(i->accountcode))
03767 ast_string_field_set(tmp, accountcode, i->accountcode);
03768 if (i->amaflags)
03769 tmp->amaflags = i->amaflags;
03770 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03771 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03772 if (i->adsi)
03773 tmp->adsicpe = i->peeradsicpe;
03774 else
03775 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03776 i->owner = tmp;
03777 i->capability = capability;
03778
03779 for (v = i->vars ; v ; v = v->next)
03780 pbx_builtin_setvar_helper(tmp, v->name, v->value);
03781
03782 if (state != AST_STATE_DOWN) {
03783 if (ast_pbx_start(tmp)) {
03784 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03785 ast_hangup(tmp);
03786 i->owner = NULL;
03787 return NULL;
03788 }
03789 }
03790
03791 ast_module_ref(ast_module_info->self);
03792
03793 return tmp;
03794 }
03795
03796 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03797 {
03798 unsigned long int mssincetx;
03799 long int ms, pred;
03800
03801 tpeer->trunkact = *tv;
03802 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03803 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03804
03805 tpeer->txtrunktime = *tv;
03806 tpeer->lastsent = 999999;
03807 }
03808
03809 tpeer->lasttxtime = *tv;
03810
03811
03812 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03813
03814 pred = tpeer->lastsent + sampms;
03815 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03816 ms = pred;
03817
03818
03819 if (ms == tpeer->lastsent)
03820 ms = tpeer->lastsent + 1;
03821 tpeer->lastsent = ms;
03822 return ms;
03823 }
03824
03825 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03826 {
03827 long ms;
03828 if (ast_tvzero(iaxs[callno]->rxcore)) {
03829
03830 gettimeofday(&iaxs[callno]->rxcore, NULL);
03831
03832 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03833 }
03834
03835 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03836
03837 return ms + ts;
03838 }
03839
03840 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03841 {
03842 int ms;
03843 int voice = 0;
03844 int genuine = 0;
03845 int adjust;
03846 struct timeval *delivery = NULL;
03847
03848
03849
03850
03851
03852
03853
03854
03855 if (f) {
03856 if (f->frametype == AST_FRAME_VOICE) {
03857 voice = 1;
03858 delivery = &f->delivery;
03859 } else if (f->frametype == AST_FRAME_IAX) {
03860 genuine = 1;
03861 } else if (f->frametype == AST_FRAME_CNG) {
03862 p->notsilenttx = 0;
03863 }
03864 }
03865 if (ast_tvzero(p->offset)) {
03866 gettimeofday(&p->offset, NULL);
03867
03868 p->offset.tv_usec -= p->offset.tv_usec % 20000;
03869 }
03870
03871 if (ts)
03872 return ts;
03873
03874 if (delivery && !ast_tvzero(*delivery)) {
03875 ms = ast_tvdiff_ms(*delivery, p->offset);
03876 if (option_debug > 2 && iaxdebug)
03877 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03878 } else {
03879 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03880 if (ms < 0)
03881 ms = 0;
03882 if (voice) {
03883
03884 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901
03902
03903 adjust = (ms - p->nextpred);
03904 if (adjust < 0)
03905 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03906 else if (adjust > 0)
03907 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03908
03909 if (!p->nextpred) {
03910 p->nextpred = ms;
03911 if (p->nextpred <= p->lastsent)
03912 p->nextpred = p->lastsent + 3;
03913 }
03914 ms = p->nextpred;
03915 } else {
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03926 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03927 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03928
03929 if (f->samples >= 8)
03930 {
03931 int diff = ms % (f->samples / 8);
03932 if (diff)
03933 ms += f->samples/8 - diff;
03934 }
03935
03936 p->nextpred = ms;
03937 p->notsilenttx = 1;
03938 }
03939 } else if ( f->frametype == AST_FRAME_VIDEO ) {
03940
03941
03942
03943
03944
03945
03946
03947
03948 if ( (unsigned int)ms < p->lastsent )
03949 ms = p->lastsent;
03950 } else {
03951
03952
03953 if (genuine) {
03954
03955 if (ms <= p->lastsent)
03956 ms = p->lastsent + 3;
03957 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03958
03959 ms = p->lastsent + 3;
03960 }
03961 }
03962 }
03963 p->lastsent = ms;
03964 if (voice)
03965 p->nextpred = p->nextpred + f->samples / 8;
03966 return ms;
03967 }
03968
03969 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03970 {
03971
03972
03973 int ms;
03974 #ifdef IAXTESTS
03975 int jit;
03976 #endif
03977
03978 if (ast_tvzero(p->rxcore)) {
03979 p->rxcore = ast_tvnow();
03980 if (option_debug && iaxdebug)
03981 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03982 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03983 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03984 #if 1
03985 if (option_debug && iaxdebug)
03986 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03987 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03988 #endif
03989 }
03990
03991 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03992 #ifdef IAXTESTS
03993 if (test_jit) {
03994 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
03995 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
03996 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
03997 jit = -jit;
03998 ms += jit;
03999 }
04000 }
04001 if (test_late) {
04002 ms += test_late;
04003 test_late = 0;
04004 }
04005 #endif
04006 return ms;
04007 }
04008
04009 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04010 {
04011 struct iax2_trunk_peer *tpeer;
04012
04013
04014 ast_mutex_lock(&tpeerlock);
04015 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04016
04017 if (!inaddrcmp(&tpeer->addr, sin)) {
04018 ast_mutex_lock(&tpeer->lock);
04019 break;
04020 }
04021 }
04022 if (!tpeer) {
04023 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04024 ast_mutex_init(&tpeer->lock);
04025 tpeer->lastsent = 9999;
04026 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04027 tpeer->trunkact = ast_tvnow();
04028 ast_mutex_lock(&tpeer->lock);
04029 tpeer->next = tpeers;
04030 tpeer->sockfd = fd;
04031 tpeers = tpeer;
04032 #ifdef SO_NO_CHECK
04033 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04034 #endif
04035 if (option_debug)
04036 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04037 }
04038 }
04039 ast_mutex_unlock(&tpeerlock);
04040 return tpeer;
04041 }
04042
04043 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04044 {
04045 struct ast_frame *f;
04046 struct iax2_trunk_peer *tpeer;
04047 void *tmp, *ptr;
04048 struct ast_iax2_meta_trunk_entry *met;
04049 struct ast_iax2_meta_trunk_mini *mtm;
04050
04051 f = &fr->af;
04052 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04053 if (tpeer) {
04054 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04055
04056 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04057 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04058 ast_mutex_unlock(&tpeer->lock);
04059 return -1;
04060 }
04061
04062 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04063 tpeer->trunkdata = tmp;
04064 if (option_debug)
04065 ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
04066 } else {
04067 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04068 ast_mutex_unlock(&tpeer->lock);
04069 return -1;
04070 }
04071 }
04072
04073
04074 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04075 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04076 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04077 mtm->len = htons(f->datalen);
04078 mtm->mini.callno = htons(pvt->callno);
04079 mtm->mini.ts = htons(0xffff & fr->ts);
04080 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04081 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04082 } else {
04083 met = (struct ast_iax2_meta_trunk_entry *)ptr;
04084
04085 met->callno = htons(pvt->callno);
04086 met->len = htons(f->datalen);
04087
04088 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04089 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04090 }
04091
04092 memcpy(ptr, f->data, f->datalen);
04093 tpeer->trunkdatalen += f->datalen;
04094
04095 tpeer->calls++;
04096 ast_mutex_unlock(&tpeer->lock);
04097 }
04098 return 0;
04099 }
04100
04101 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
04102 {
04103 aes_encrypt_key128(digest, ecx);
04104 aes_decrypt_key128(digest, dcx);
04105 }
04106
04107 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04108 {
04109 #if 0
04110
04111 int x;
04112 if (len % 16)
04113 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04114 for (x=0;x<len;x++)
04115 dst[x] = src[x] ^ 0xff;
04116 #else
04117 unsigned char lastblock[16] = { 0 };
04118 int x;
04119 while(len > 0) {
04120 aes_decrypt(src, dst, dcx);
04121 for (x=0;x<16;x++)
04122 dst[x] ^= lastblock[x];
04123 memcpy(lastblock, src, sizeof(lastblock));
04124 dst += 16;
04125 src += 16;
04126 len -= 16;
04127 }
04128 #endif
04129 }
04130
04131 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04132 {
04133 #if 0
04134
04135 int x;
04136 if (len % 16)
04137 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04138 for (x=0;x<len;x++)
04139 dst[x] = src[x] ^ 0xff;
04140 #else
04141 unsigned char curblock[16] = { 0 };
04142 int x;
04143 while(len > 0) {
04144 for (x=0;x<16;x++)
04145 curblock[x] ^= src[x];
04146 aes_encrypt(curblock, dst, ecx);
04147 memcpy(curblock, dst, sizeof(curblock));
04148 dst += 16;
04149 src += 16;
04150 len -= 16;
04151 }
04152 #endif
04153 }
04154
04155 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04156 {
04157 int padding;
04158 unsigned char *workspace;
04159
04160 workspace = alloca(*datalen);
04161 memset(f, 0, sizeof(*f));
04162 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04163 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04164 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04165 return -1;
04166
04167 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04168
04169 padding = 16 + (workspace[15] & 0xf);
04170 if (option_debug && iaxdebug)
04171 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04172 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04173 return -1;
04174
04175 *datalen -= padding;
04176 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04177 f->frametype = fh->type;
04178 if (f->frametype == AST_FRAME_VIDEO) {
04179 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04180 } else {
04181 f->subclass = uncompress_subclass(fh->csub);
04182 }
04183 } else {
04184 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04185 if (option_debug && iaxdebug)
04186 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04187 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04188 return -1;
04189
04190 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04191 padding = 16 + (workspace[15] & 0x0f);
04192 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04193 return -1;
04194 *datalen -= padding;
04195 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04196 }
04197 return 0;
04198 }
04199
04200 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04201 {
04202 int padding;
04203 unsigned char *workspace;
04204 workspace = alloca(*datalen + 32);
04205 if (!workspace)
04206 return -1;
04207 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04208 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04209 if (option_debug && iaxdebug)
04210 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04211 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04212 padding = 16 + (padding & 0xf);
04213 memcpy(workspace, poo, padding);
04214 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04215 workspace[15] &= 0xf0;
04216 workspace[15] |= (padding & 0xf);
04217 if (option_debug && iaxdebug)
04218 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
04219 *datalen += padding;
04220 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04221 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04222 memcpy(poo, workspace + *datalen - 32, 32);
04223 } else {
04224 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04225 if (option_debug && iaxdebug)
04226 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04227 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04228 padding = 16 + (padding & 0xf);
04229 memcpy(workspace, poo, padding);
04230 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04231 workspace[15] &= 0xf0;
04232 workspace[15] |= (padding & 0x0f);
04233 *datalen += padding;
04234 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04235 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04236 memcpy(poo, workspace + *datalen - 32, 32);
04237 }
04238 return 0;
04239 }
04240
04241 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04242 {
04243 int res=-1;
04244 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04245
04246 struct MD5Context md5;
04247 unsigned char digest[16];
04248 char *tmppw, *stringp;
04249
04250 tmppw = ast_strdupa(iaxs[callno]->secret);
04251 stringp = tmppw;
04252 while ((tmppw = strsep(&stringp, ";"))) {
04253 MD5Init(&md5);
04254 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04255 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04256 MD5Final(digest, &md5);
04257 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04258 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04259 if (!res) {
04260 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04261 break;
04262 }
04263 }
04264 } else
04265 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04266 return res;
04267 }
04268
04269 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04270 {
04271
04272
04273
04274 struct ast_iax2_full_hdr *fh;
04275 struct ast_iax2_mini_hdr *mh;
04276 struct ast_iax2_video_hdr *vh;
04277 struct {
04278 struct iax_frame fr2;
04279 unsigned char buffer[4096];
04280 } frb;
04281 struct iax_frame *fr;
04282 int res;
04283 int sendmini=0;
04284 unsigned int lastsent;
04285 unsigned int fts;
04286
04287 frb.fr2.afdatalen = sizeof(frb.buffer);
04288
04289 if (!pvt) {
04290 ast_log(LOG_WARNING, "No private structure for packet?\n");
04291 return -1;
04292 }
04293
04294 lastsent = pvt->lastsent;
04295
04296
04297 fts = calc_timestamp(pvt, ts, f);
04298
04299
04300
04301
04302 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04303 return 0;
04304
04305
04306 if ((ast_test_flag(pvt, IAX_TRUNK) ||
04307 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04308 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04309 &&
04310 (f->frametype == AST_FRAME_VOICE)
04311 &&
04312 (f->subclass == pvt->svoiceformat)
04313 ) {
04314
04315 now = 1;
04316
04317 sendmini = 1;
04318 }
04319 if ( f->frametype == AST_FRAME_VIDEO ) {
04320
04321
04322
04323
04324
04325 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04326 ((f->subclass & ~0x1) == pvt->svideoformat)
04327 ) {
04328 now = 1;
04329 sendmini = 1;
04330 } else {
04331 now = 0;
04332 sendmini = 0;
04333 }
04334 pvt->lastvsent = fts;
04335 }
04336
04337 if (now) {
04338 fr = &frb.fr2;
04339 } else
04340 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
04341 if (!fr) {
04342 ast_log(LOG_WARNING, "Out of memory\n");
04343 return -1;
04344 }
04345
04346 iax_frame_wrap(fr, f);
04347
04348 fr->ts = fts;
04349 fr->callno = pvt->callno;
04350 fr->transfer = transfer;
04351 fr->final = final;
04352 if (!sendmini) {
04353
04354 if (seqno > -1)
04355 fr->oseqno = seqno;
04356 else
04357 fr->oseqno = pvt->oseqno++;
04358 fr->iseqno = pvt->iseqno;
04359 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04360 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04361 fh->ts = htonl(fr->ts);
04362 fh->oseqno = fr->oseqno;
04363 if (transfer) {
04364 fh->iseqno = 0;
04365 } else
04366 fh->iseqno = fr->iseqno;
04367
04368 if (!transfer)
04369 pvt->aseqno = fr->iseqno;
04370 fh->type = fr->af.frametype & 0xFF;
04371 if (fr->af.frametype == AST_FRAME_VIDEO)
04372 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04373 else
04374 fh->csub = compress_subclass(fr->af.subclass);
04375 if (transfer) {
04376 fr->dcallno = pvt->transfercallno;
04377 } else
04378 fr->dcallno = pvt->peercallno;
04379 fh->dcallno = htons(fr->dcallno);
04380 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04381 fr->data = fh;
04382 fr->retries = 0;
04383
04384 fr->retrytime = pvt->pingtime * 2;
04385 if (fr->retrytime < MIN_RETRY_TIME)
04386 fr->retrytime = MIN_RETRY_TIME;
04387 if (fr->retrytime > MAX_RETRY_TIME)
04388 fr->retrytime = MAX_RETRY_TIME;
04389
04390 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04391 fr->retries = -1;
04392 else if (f->frametype == AST_FRAME_VOICE)
04393 pvt->svoiceformat = f->subclass;
04394 else if (f->frametype == AST_FRAME_VIDEO)
04395 pvt->svideoformat = f->subclass & ~0x1;
04396 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04397 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04398 if (iaxdebug) {
04399 if (fr->transfer)
04400 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04401 else
04402 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04403 }
04404 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04405 } else
04406 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04407 }
04408
04409 if (now) {
04410 res = send_packet(fr);
04411 } else
04412 res = iax2_transmit(fr);
04413 } else {
04414 if (ast_test_flag(pvt, IAX_TRUNK)) {
04415 iax2_trunk_queue(pvt, fr);
04416 res = 0;
04417 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04418
04419 fr->oseqno = -1;
04420 fr->iseqno = -1;
04421 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04422 vh->zeros = 0;
04423 vh->callno = htons(0x8000 | fr->callno);
04424 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04425 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04426 fr->data = vh;
04427 fr->retries = -1;
04428 res = send_packet(fr);
04429 } else {
04430
04431 fr->oseqno = -1;
04432 fr->iseqno = -1;
04433
04434 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04435 mh->callno = htons(fr->callno);
04436 mh->ts = htons(fr->ts & 0xFFFF);
04437 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04438 fr->data = mh;
04439 fr->retries = -1;
04440 if (pvt->transferring == TRANSFER_MEDIAPASS)
04441 fr->transfer = 1;
04442 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04443 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04444 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04445 } else
04446 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04447 }
04448 res = send_packet(fr);
04449 }
04450 }
04451 return res;
04452 }
04453
04454 static int iax2_show_users(int fd, int argc, char *argv[])
04455 {
04456 regex_t regexbuf;
04457 int havepattern = 0;
04458
04459 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
04460 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
04461
04462 struct iax2_user *user = NULL;
04463 char auth[90];
04464 char *pstr = "";
04465 struct ao2_iterator i;
04466
04467 switch (argc) {
04468 case 5:
04469 if (!strcasecmp(argv[3], "like")) {
04470 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04471 return RESULT_SHOWUSAGE;
04472 havepattern = 1;
04473 } else
04474 return RESULT_SHOWUSAGE;
04475 case 3:
04476 break;
04477 default:
04478 return RESULT_SHOWUSAGE;
04479 }
04480
04481 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04482 i = ao2_iterator_init(users, 0);
04483 for (user = ao2_iterator_next(&i); user;
04484 user_unref(user), user = ao2_iterator_next(&i)) {
04485 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
04486 continue;
04487
04488 if (!ast_strlen_zero(user->secret)) {
04489 ast_copy_string(auth,user->secret,sizeof(auth));
04490 } else if (!ast_strlen_zero(user->inkeys)) {
04491 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04492 } else
04493 ast_copy_string(auth, "-no secret-", sizeof(auth));
04494
04495 if(ast_test_flag(user,IAX_CODEC_NOCAP))
04496 pstr = "REQ Only";
04497 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04498 pstr = "Disabled";
04499 else
04500 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04501
04502 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods,
04503 user->contexts ? user->contexts->context : context,
04504 user->ha ? "Yes" : "No", pstr);
04505 }
04506
04507 if (havepattern)
04508 regfree(®exbuf);
04509
04510 return RESULT_SUCCESS;
04511 #undef FORMAT
04512 #undef FORMAT2
04513 }
04514
04515 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04516 {
04517 regex_t regexbuf;
04518 int havepattern = 0;
04519 int total_peers = 0;
04520 int online_peers = 0;
04521 int offline_peers = 0;
04522 int unmonitored_peers = 0;
04523 struct ao2_iterator i;
04524
04525 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
04526 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
04527
04528 struct iax2_peer *peer = NULL;
04529 char name[256];
04530 int registeredonly=0;
04531 char *term = manager ? "\r\n" : "\n";
04532
04533 switch (argc) {
04534 case 6:
04535 if (!strcasecmp(argv[3], "registered"))
04536 registeredonly = 1;
04537 else
04538 return RESULT_SHOWUSAGE;
04539 if (!strcasecmp(argv[4], "like")) {
04540 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04541 return RESULT_SHOWUSAGE;
04542 havepattern = 1;
04543 } else
04544 return RESULT_SHOWUSAGE;
04545 break;
04546 case 5:
04547 if (!strcasecmp(argv[3], "like")) {
04548 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04549 return RESULT_SHOWUSAGE;
04550 havepattern = 1;
04551 } else
04552 return RESULT_SHOWUSAGE;
04553 break;
04554 case 4:
04555 if (!strcasecmp(argv[3], "registered"))
04556 registeredonly = 1;
04557 else
04558 return RESULT_SHOWUSAGE;
04559 break;
04560 case 3:
04561 break;
04562 default:
04563 return RESULT_SHOWUSAGE;
04564 }
04565
04566
04567 if (s)
04568 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
04569 else
04570 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
04571
04572 i = ao2_iterator_init(peers, 0);
04573 for (peer = ao2_iterator_next(&i); peer;
04574 peer_unref(peer), peer = ao2_iterator_next(&i)) {
04575 char nm[20];
04576 char status[20];
04577 char srch[2000];
04578 int retstatus;
04579
04580 if (registeredonly && !peer->addr.sin_addr.s_addr)
04581 continue;
04582 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
04583 continue;
04584
04585 if (!ast_strlen_zero(peer->username))
04586 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04587 else
04588 ast_copy_string(name, peer->name, sizeof(name));
04589
04590 retstatus = peer_status(peer, status, sizeof(status));
04591 if (retstatus > 0)
04592 online_peers++;
04593 else if (!retstatus)
04594 offline_peers++;
04595 else
04596 unmonitored_peers++;
04597
04598 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04599
04600 snprintf(srch, sizeof(srch), FORMAT, name,
04601 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04602 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04603 nm,
04604 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04605 peer->encmethods ? "(E)" : " ", status, term);
04606
04607 if (s)
04608 astman_append(s, FORMAT, name,
04609 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04610 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04611 nm,
04612 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04613 peer->encmethods ? "(E)" : " ", status, term);
04614 else
04615 ast_cli(fd, FORMAT, name,
04616 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04617 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04618 nm,
04619 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04620 peer->encmethods ? "(E)" : " ", status, term);
04621 total_peers++;
04622 }
04623
04624 if (s)
04625 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04626 else
04627 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04628
04629 if (havepattern)
04630 regfree(®exbuf);
04631
04632 return RESULT_SUCCESS;
04633 #undef FORMAT
04634 #undef FORMAT2
04635 }
04636
04637 static int iax2_show_threads(int fd, int argc, char *argv[])
04638 {
04639 struct iax2_thread *thread = NULL;
04640 time_t t;
04641 int threadcount = 0, dynamiccount = 0;
04642 char type;
04643
04644 if (argc != 3)
04645 return RESULT_SHOWUSAGE;
04646
04647 ast_cli(fd, "IAX2 Thread Information\n");
04648 time(&t);
04649 ast_cli(fd, "Idle Threads:\n");
04650 AST_LIST_LOCK(&idle_list);
04651 AST_LIST_TRAVERSE(&idle_list, thread, list) {
04652 #ifdef DEBUG_SCHED_MULTITHREAD
04653 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04654 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04655 #else
04656 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04657 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04658 #endif
04659 threadcount++;
04660 }
04661 AST_LIST_UNLOCK(&idle_list);
04662 ast_cli(fd, "Active Threads:\n");
04663 AST_LIST_LOCK(&active_list);
04664 AST_LIST_TRAVERSE(&active_list, thread, list) {
04665 if (thread->type == IAX_TYPE_DYNAMIC)
04666 type = 'D';
04667 else
04668 type = 'P';
04669 #ifdef DEBUG_SCHED_MULTITHREAD
04670 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n",
04671 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04672 #else
04673 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
04674 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04675 #endif
04676 threadcount++;
04677 }
04678 AST_LIST_UNLOCK(&active_list);
04679 ast_cli(fd, "Dynamic Threads:\n");
04680 AST_LIST_LOCK(&dynamic_list);
04681 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04682 #ifdef DEBUG_SCHED_MULTITHREAD
04683 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04684 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04685 #else
04686 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04687 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04688 #endif
04689 dynamiccount++;
04690 }
04691 AST_LIST_UNLOCK(&dynamic_list);
04692 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04693 return RESULT_SUCCESS;
04694 }
04695
04696 static int iax2_show_peers(int fd, int argc, char *argv[])
04697 {
04698 return __iax2_show_peers(0, fd, NULL, argc, argv);
04699 }
04700 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04701 {
04702 ast_cli_netstats(s, -1, 0);
04703 astman_append(s, "\r\n");
04704 return RESULT_SUCCESS;
04705 }
04706
04707 static int iax2_show_firmware(int fd, int argc, char *argv[])
04708 {
04709 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
04710 #if !defined(__FreeBSD__)
04711 #define FORMAT "%-15.15s %-15d %-15d\n"
04712 #else
04713 #define FORMAT "%-15.15s %-15d %-15d\n"
04714 #endif
04715 struct iax_firmware *cur;
04716 if ((argc != 3) && (argc != 4))
04717 return RESULT_SHOWUSAGE;
04718 ast_mutex_lock(&waresl.lock);
04719
04720 ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04721 for (cur = waresl.wares;cur;cur = cur->next) {
04722 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname)))
04723 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04724 (int)ntohl(cur->fwh->datalen));
04725 }
04726 ast_mutex_unlock(&waresl.lock);
04727 return RESULT_SUCCESS;
04728 #undef FORMAT
04729 #undef FORMAT2
04730 }
04731
04732
04733 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04734 {
04735 char *a[] = { "iax2", "show", "users" };
04736 int ret;
04737 const char *id = astman_get_header(m,"ActionID");
04738
04739 if (!ast_strlen_zero(id))
04740 astman_append(s, "ActionID: %s\r\n",id);
04741 ret = __iax2_show_peers(1, -1, s, 3, a );
04742 astman_append(s, "\r\n\r\n" );
04743 return ret;
04744 }
04745
04746 static char *regstate2str(int regstate)
04747 {
04748 switch(regstate) {
04749 case REG_STATE_UNREGISTERED:
04750 return "Unregistered";
04751 case REG_STATE_REGSENT:
04752 return "Request Sent";
04753 case REG_STATE_AUTHSENT:
04754 return "Auth. Sent";
04755 case REG_STATE_REGISTERED:
04756 return "Registered";
04757 case REG_STATE_REJECTED:
04758 return "Rejected";
04759 case REG_STATE_TIMEOUT:
04760 return "Timeout";
04761 case REG_STATE_NOAUTH:
04762 return "No Authentication";
04763 default:
04764 return "Unknown";
04765 }
04766 }
04767
04768 static int iax2_show_registry(int fd, int argc, char *argv[])
04769 {
04770 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
04771 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
04772 struct iax2_registry *reg = NULL;
04773
04774 char host[80];
04775 char perceived[80];
04776 if (argc != 3)
04777 return RESULT_SHOWUSAGE;
04778 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04779 AST_LIST_LOCK(®istrations);
04780 AST_LIST_TRAVERSE(®istrations, reg, entry) {
04781 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04782 if (reg->us.sin_addr.s_addr)
04783 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04784 else
04785 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04786 ast_cli(fd, FORMAT, host,
04787 (reg->dnsmgr) ? "Y" : "N",
04788 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04789 }
04790 AST_LIST_UNLOCK(®istrations);
04791 return RESULT_SUCCESS;
04792 #undef FORMAT
04793 #undef FORMAT2
04794 }
04795
04796 static int iax2_show_channels(int fd, int argc, char *argv[])
04797 {
04798 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
04799 #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n"
04800 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
04801 int x;
04802 int numchans = 0;
04803
04804 if (argc != 3)
04805 return RESULT_SHOWUSAGE;
04806 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04807 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04808 ast_mutex_lock(&iaxsl[x]);
04809 if (iaxs[x]) {
04810 int lag, jitter, localdelay;
04811 jb_info jbinfo;
04812
04813 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04814 jb_getinfo(iaxs[x]->jb, &jbinfo);
04815 jitter = jbinfo.jitter;
04816 localdelay = jbinfo.current - jbinfo.min;
04817 } else {
04818 jitter = -1;
04819 localdelay = 0;
04820 }
04821 lag = iaxs[x]->remote_rr.delay;
04822 ast_cli(fd, FORMAT,
04823 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04824 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
04825 S_OR(iaxs[x]->username, "(None)"),
04826 iaxs[x]->callno, iaxs[x]->peercallno,
04827 iaxs[x]->oseqno, iaxs[x]->iseqno,
04828 lag,
04829 jitter,
04830 localdelay,
04831 ast_getformatname(iaxs[x]->voiceformat) );
04832 numchans++;
04833 }
04834 ast_mutex_unlock(&iaxsl[x]);
04835 }
04836 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04837 return RESULT_SUCCESS;
04838 #undef FORMAT
04839 #undef FORMAT2
04840 #undef FORMATB
04841 }
04842
04843 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04844 {
04845 int x;
04846 int numchans = 0;
04847 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04848 ast_mutex_lock(&iaxsl[x]);
04849 if (iaxs[x]) {
04850 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04851 char *fmt;
04852 jb_info jbinfo;
04853
04854 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04855 jb_getinfo(iaxs[x]->jb, &jbinfo);
04856 localjitter = jbinfo.jitter;
04857 localdelay = jbinfo.current - jbinfo.min;
04858 locallost = jbinfo.frames_lost;
04859 locallosspct = jbinfo.losspct/1000;
04860 localdropped = jbinfo.frames_dropped;
04861 localooo = jbinfo.frames_ooo;
04862 } else {
04863 localjitter = -1;
04864 localdelay = 0;
04865 locallost = -1;
04866 locallosspct = -1;
04867 localdropped = 0;
04868 localooo = -1;
04869 }
04870 if (limit_fmt)
04871 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04872 else
04873 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04874 if (s)
04875
04876 astman_append(s, fmt,
04877 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04878 iaxs[x]->pingtime,
04879 localjitter,
04880 localdelay,
04881 locallost,
04882 locallosspct,
04883 localdropped,
04884 localooo,
04885 iaxs[x]->frames_received/1000,
04886 iaxs[x]->remote_rr.jitter,
04887 iaxs[x]->remote_rr.delay,
04888 iaxs[x]->remote_rr.losscnt,
04889 iaxs[x]->remote_rr.losspct,
04890 iaxs[x]->remote_rr.dropped,
04891 iaxs[x]->remote_rr.ooo,
04892 iaxs[x]->remote_rr.packets/1000);
04893 else
04894 ast_cli(fd, fmt,
04895 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04896 iaxs[x]->pingtime,
04897 localjitter,
04898 localdelay,
04899 locallost,
04900 locallosspct,
04901 localdropped,
04902 localooo,
04903 iaxs[x]->frames_received/1000,
04904 iaxs[x]->remote_rr.jitter,
04905 iaxs[x]->remote_rr.delay,
04906 iaxs[x]->remote_rr.losscnt,
04907 iaxs[x]->remote_rr.losspct,
04908 iaxs[x]->remote_rr.dropped,
04909 iaxs[x]->remote_rr.ooo,
04910 iaxs[x]->remote_rr.packets/1000
04911 );
04912 numchans++;
04913 }
04914 ast_mutex_unlock(&iaxsl[x]);
04915 }
04916 return numchans;
04917 }
04918
04919 static int iax2_show_netstats(int fd, int argc, char *argv[])
04920 {
04921 int numchans = 0;
04922 if (argc != 3)
04923 return RESULT_SHOWUSAGE;
04924 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
04925 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n");
04926 numchans = ast_cli_netstats(NULL, fd, 1);
04927 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04928 return RESULT_SUCCESS;
04929 }
04930
04931 static int iax2_do_debug(int fd, int argc, char *argv[])
04932 {
04933 if (argc < 2 || argc > 3)
04934 return RESULT_SHOWUSAGE;
04935 iaxdebug = 1;
04936 ast_cli(fd, "IAX2 Debugging Enabled\n");
04937 return RESULT_SUCCESS;
04938 }
04939
04940 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04941 {
04942 if (argc < 3 || argc > 4)
04943 return RESULT_SHOWUSAGE;
04944 iaxtrunkdebug = 1;
04945 ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04946 return RESULT_SUCCESS;
04947 }
04948
04949 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04950 {
04951 if (argc < 3 || argc > 4)
04952 return RESULT_SHOWUSAGE;
04953 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04954 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04955 return RESULT_SUCCESS;
04956 }
04957
04958 static int iax2_no_debug(int fd, int argc, char *argv[])
04959 {
04960 if (argc < 3 || argc > 4)
04961 return RESULT_SHOWUSAGE;
04962 iaxdebug = 0;
04963 ast_cli(fd, "IAX2 Debugging Disabled\n");
04964 return RESULT_SUCCESS;
04965 }
04966
04967 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04968 {
04969 if (argc < 4 || argc > 5)
04970 return RESULT_SHOWUSAGE;
04971 iaxtrunkdebug = 0;
04972 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04973 return RESULT_SUCCESS;
04974 }
04975
04976 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04977 {
04978 if (argc < 4 || argc > 5)
04979 return RESULT_SHOWUSAGE;
04980 jb_setoutput(jb_error_output, jb_warning_output, NULL);
04981 jb_debug_output("\n");
04982 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04983 return RESULT_SUCCESS;
04984 }
04985
04986 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
04987 {
04988 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04989 int res = -1;
04990 ast_mutex_lock(&iaxsl[callno]);
04991 if (iaxs[callno]) {
04992
04993 if (!iaxs[callno]->error) {
04994 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04995 res = 0;
04996
04997 else if (f->frametype == AST_FRAME_NULL)
04998 res = 0;
04999 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05000 res = 0;
05001 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05002 res = 0;
05003 else
05004
05005 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05006 } else {
05007 if (option_debug)
05008 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05009 }
05010 }
05011
05012 ast_mutex_unlock(&iaxsl[callno]);
05013 return res;
05014 }
05015
05016 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
05017 int now, int transfer, int final)
05018 {
05019 struct ast_frame f = { 0, };
05020
05021 f.frametype = type;
05022 f.subclass = command;
05023 f.datalen = datalen;
05024 f.src = __FUNCTION__;
05025 f.data = (void *) data;
05026
05027 return iax2_send(i, &f, ts, seqno, now, transfer, final);
05028 }
05029
05030 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05031 {
05032 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05033 }
05034
05035 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05036 {
05037 int res;
05038 ast_mutex_lock(&iaxsl[callno]);
05039 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05040 ast_mutex_unlock(&iaxsl[callno]);
05041 return res;
05042 }
05043
05044
05045
05046
05047
05048
05049 static int send_command_final(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05050 {
05051 int call_num = i->callno;
05052
05053 iax2_predestroy(i->callno);
05054 if (!iaxs[call_num])
05055 return -1;
05056 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05057 }
05058
05059 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)
05060 {
05061 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05062 }
05063
05064 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05065 {
05066 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05067 }
05068
05069 static int apply_context(struct iax2_context *con, const char *context)
05070 {
05071 while(con) {
05072 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05073 return -1;
05074 con = con->next;
05075 }
05076 return 0;
05077 }
05078
05079
05080 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05081 {
05082
05083 int res = -1;
05084 int version = 2;
05085 struct iax2_user *user = NULL, *best = NULL;
05086 int bestscore = 0;
05087 int gotcapability = 0;
05088 struct ast_variable *v = NULL, *tmpvar = NULL;
05089 struct ao2_iterator i;
05090
05091 if (!iaxs[callno])
05092 return res;
05093 if (ies->called_number)
05094 ast_string_field_set(iaxs[callno], exten, ies->called_number);
05095 if (ies->calling_number) {
05096 ast_shrink_phone_number(ies->calling_number);
05097 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05098 }
05099 if (ies->calling_name)
05100 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05101 if (ies->calling_ani)
05102 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05103 if (ies->dnid)
05104 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05105 if (ies->rdnis)
05106 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05107 if (ies->called_context)
05108 ast_string_field_set(iaxs[callno], context, ies->called_context);
05109 if (ies->language)
05110 ast_string_field_set(iaxs[callno], language, ies->language);
05111 if (ies->username)
05112 ast_string_field_set(iaxs[callno], username, ies->username);
05113 if (ies->calling_ton > -1)
05114 iaxs[callno]->calling_ton = ies->calling_ton;
05115 if (ies->calling_tns > -1)
05116 iaxs[callno]->calling_tns = ies->calling_tns;
05117 if (ies->calling_pres > -1)
05118 iaxs[callno]->calling_pres = ies->calling_pres;
05119 if (ies->format)
05120 iaxs[callno]->peerformat = ies->format;
05121 if (ies->adsicpe)
05122 iaxs[callno]->peeradsicpe = ies->adsicpe;
05123 if (ies->capability) {
05124 gotcapability = 1;
05125 iaxs[callno]->peercapability = ies->capability;
05126 }
05127 if (ies->version)
05128 version = ies->version;
05129
05130
05131 if(ies->codec_prefs) {
05132 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05133 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05134 }
05135
05136 if (!gotcapability)
05137 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05138 if (version > IAX_PROTO_VERSION) {
05139 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
05140 ast_inet_ntoa(sin->sin_addr), version);
05141 return res;
05142 }
05143
05144 i = ao2_iterator_init(users, 0);
05145 while ((user = ao2_iterator_next(&i))) {
05146 if ((ast_strlen_zero(iaxs[callno]->username) ||
05147 !strcmp(iaxs[callno]->username, user->name))
05148 && ast_apply_ha(user->ha, sin)
05149 && (ast_strlen_zero(iaxs[callno]->context) ||
05150 apply_context(user->contexts, iaxs[callno]->context))) {
05151 if (!ast_strlen_zero(iaxs[callno]->username)) {
05152
05153 if (best)
05154 user_unref(best);
05155 best = user;
05156 break;
05157 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05158
05159 if (user->ha) {
05160
05161 if (bestscore < 4) {
05162 bestscore = 4;
05163 if (best)
05164 user_unref(best);
05165 best = user;
05166 continue;
05167 }
05168 } else {
05169
05170 if (bestscore < 3) {
05171 bestscore = 3;
05172 if (best)
05173 user_unref(best);
05174 best = user;
05175 continue;
05176 }
05177 }
05178 } else {
05179 if (user->ha) {
05180
05181 if (bestscore < 2) {
05182 bestscore = 2;
05183 if (best)
05184 user_unref(best);
05185 best = user;
05186 continue;
05187 }
05188 } else {
05189
05190 if (bestscore < 1) {
05191 bestscore = 1;
05192 if (best)
05193 user_unref(best);
05194 best = user;
05195 continue;
05196 }
05197 }
05198 }
05199 }
05200 user_unref(user);
05201 }
05202 user = best;
05203 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05204 user = realtime_user(iaxs[callno]->username, sin);
05205 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
05206 !apply_context(user->contexts, iaxs[callno]->context)) {
05207 user = user_unref(user);
05208 }
05209 }
05210 if (user) {
05211
05212
05213 for (v = user->vars ; v ; v = v->next) {
05214 if((tmpvar = ast_variable_new(v->name, v->value))) {
05215 tmpvar->next = iaxs[callno]->vars;
05216 iaxs[callno]->vars = tmpvar;
05217 }
05218 }
05219
05220 if (user->maxauthreq > 0)
05221 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05222 iaxs[callno]->prefs = user->prefs;
05223 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05224 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05225 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05226 iaxs[callno]->encmethods = user->encmethods;
05227
05228 if (ast_strlen_zero(iaxs[callno]->username))
05229 ast_string_field_set(iaxs[callno], username, user->name);
05230
05231 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05232 iaxs[callno]->capability = user->capability;
05233
05234 if (ast_strlen_zero(iaxs[callno]->context)) {
05235 if (user->contexts)
05236 ast_string_field_set(iaxs[callno], context, user->contexts->context);
05237 else
05238 ast_string_field_set(iaxs[callno], context, context);
05239 }
05240
05241 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05242
05243 iaxs[callno]->authmethods = user->authmethods;
05244 iaxs[callno]->adsi = user->adsi;
05245
05246 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
05247 if (ast_test_flag(user, IAX_HASCALLERID)) {
05248 iaxs[callno]->calling_tns = 0;
05249 iaxs[callno]->calling_ton = 0;
05250 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05251 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05252 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05253 }
05254 if (ast_strlen_zero(iaxs[callno]->ani))
05255 ast_string_field_set(iaxs[callno], ani, user->cid_num);
05256 } else {
05257 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05258 }
05259 if (!ast_strlen_zero(user->accountcode))
05260 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05261 if (!ast_strlen_zero(user->mohinterpret))
05262 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05263 if (!ast_strlen_zero(user->mohsuggest))
05264 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05265 if (user->amaflags)
05266 iaxs[callno]->amaflags = user->amaflags;
05267 if (!ast_strlen_zero(user->language))
05268 ast_string_field_set(iaxs[callno], language, user->language);
05269 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
05270
05271 if (!ast_strlen_zero(user->dbsecret)) {
05272 char *family, *key=NULL;
05273 char buf[80];
05274 family = ast_strdupa(user->dbsecret);
05275 key = strchr(family, '/');
05276 if (key) {
05277 *key = '\0';
05278 key++;
05279 }
05280 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05281 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05282 else
05283 ast_string_field_set(iaxs[callno], secret, buf);
05284 } else
05285 ast_string_field_set(iaxs[callno], secret, user->secret);
05286 res = 0;
05287 user = user_unref(user);
05288 }
05289 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
05290 return res;
05291 }
05292
05293 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05294 {
05295 struct ast_iax2_full_hdr fh;
05296 fh.scallno = htons(src | IAX_FLAG_FULL);
05297 fh.dcallno = htons(dst);
05298 fh.ts = 0;
05299 fh.oseqno = 0;
05300 fh.iseqno = 0;
05301 fh.type = AST_FRAME_IAX;
05302 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05303 if (iaxdebug)
05304 iax_showframe(NULL, &fh, 0, sin, 0);
05305 if (option_debug)
05306 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05307 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05308 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05309 }
05310
05311 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05312 {
05313
05314 p->encmethods &= enc;
05315 if (p->encmethods) {
05316 if (p->encmethods & IAX_ENCRYPT_AES128)
05317 p->encmethods = IAX_ENCRYPT_AES128;
05318 else
05319 p->encmethods = 0;
05320 }
05321 }
05322
05323
05324
05325
05326
05327
05328
05329 static int authenticate_request(int call_num)
05330 {
05331 struct iax_ie_data ied;
05332 int res = -1, authreq_restrict = 0;
05333 char challenge[10];
05334 struct chan_iax2_pvt *p = iaxs[call_num];
05335
05336 memset(&ied, 0, sizeof(ied));
05337
05338
05339 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05340 struct iax2_user *user, tmp_user = {
05341 .name = p->username,
05342 };
05343
05344 user = ao2_find(users, &tmp_user, OBJ_POINTER);
05345 if (user) {
05346 if (user->curauthreq == user->maxauthreq)
05347 authreq_restrict = 1;
05348 else
05349 user->curauthreq++;
05350 user = user_unref(user);
05351 }
05352 }
05353
05354
05355 if (authreq_restrict) {
05356 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05357 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05358 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05359 return 0;
05360 }
05361
05362 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05363 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05364 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05365 ast_string_field_set(p, challenge, challenge);
05366
05367 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05368 }
05369 if (p->encmethods)
05370 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05371
05372 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05373
05374 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05375
05376 if (p->encmethods)
05377 ast_set_flag(p, IAX_ENCRYPTED);
05378
05379 return res;
05380 }
05381
05382 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05383 {
05384 char requeststr[256];
05385 char md5secret[256] = "";
05386 char secret[256] = "";
05387 char rsasecret[256] = "";
05388 int res = -1;
05389 int x;
05390 struct iax2_user *user, tmp_user = {
05391 .name = p->username,
05392 };
05393
05394 user = ao2_find(users, &tmp_user, OBJ_POINTER);
05395 if (user) {
05396 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05397 ast_atomic_fetchadd_int(&user->curauthreq, -1);
05398 ast_clear_flag(p, IAX_MAXAUTHREQ);
05399 }
05400 ast_string_field_set(p, host, user->name);
05401 user = user_unref(user);
05402 }
05403
05404 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05405 return res;
05406 if (ies->password)
05407 ast_copy_string(secret, ies->password, sizeof(secret));
05408 if (ies->md5_result)
05409 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05410 if (ies->rsa_result)
05411 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05412 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05413 struct ast_key *key;
05414 char *keyn;
05415 char tmpkey[256];
05416 char *stringp=NULL;
05417 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05418 stringp=tmpkey;
05419 keyn = strsep(&stringp, ":");
05420 while(keyn) {
05421 key = ast_key_get(keyn, AST_KEY_PUBLIC);
05422 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05423 res = 0;
05424 break;
05425 } else if (!key)
05426 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05427 keyn = strsep(&stringp, ":");
05428 }
05429 } else if (p->authmethods & IAX_AUTH_MD5) {
05430 struct MD5Context md5;
05431 unsigned char digest[16];
05432 char *tmppw, *stringp;
05433
05434 tmppw = ast_strdupa(p->secret);
05435 stringp = tmppw;
05436 while((tmppw = strsep(&stringp, ";"))) {
05437 MD5Init(&md5);
05438 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05439 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05440 MD5Final(digest, &md5);
05441
05442 for (x=0;x<16;x++)
05443 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
05444 if (!strcasecmp(requeststr, md5secret)) {
05445 res = 0;
05446 break;
05447 }
05448 }
05449 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05450 if (!strcmp(secret, p->secret))
05451 res = 0;
05452 }
05453 return res;
05454 }
05455
05456
05457 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05458 {
05459 char requeststr[256] = "";
05460 char peer[256] = "";
05461 char md5secret[256] = "";
05462 char rsasecret[256] = "";
05463 char secret[256] = "";
05464 struct iax2_peer *p = NULL;
05465 struct ast_key *key;
05466 char *keyn;
05467 int x;
05468 int expire = 0;
05469 int res = -1;
05470
05471 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05472
05473 if (ies->username)
05474 ast_copy_string(peer, ies->username, sizeof(peer));
05475 if (ies->password)
05476 ast_copy_string(secret, ies->password, sizeof(secret));
05477 if (ies->md5_result)
05478 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05479 if (ies->rsa_result)
05480 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05481 if (ies->refresh)
05482 expire = ies->refresh;
05483
05484 if (ast_strlen_zero(peer)) {
05485 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05486 return -1;
05487 }
05488
05489
05490 ast_mutex_unlock(&iaxsl[callno]);
05491 p = find_peer(peer, 1);
05492 ast_mutex_lock(&iaxsl[callno]);
05493 if (!p || !iaxs[callno]) {
05494 if (authdebug && !p)
05495 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05496 goto return_unref;
05497 }
05498
05499 if (!ast_test_flag(p, IAX_DYNAMIC)) {
05500 if (authdebug)
05501 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05502 goto return_unref;
05503 }
05504
05505 if (!ast_apply_ha(p->ha, sin)) {
05506 if (authdebug)
05507 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05508 goto return_unref;
05509 }
05510 if (!inaddrcmp(&p->addr, sin))
05511 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05512 ast_string_field_set(iaxs[callno], secret, p->secret);
05513 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05514
05515 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05516 if (!ast_strlen_zero(p->inkeys)) {
05517 char tmpkeys[256];
05518 char *stringp=NULL;
05519 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05520 stringp=tmpkeys;
05521 keyn = strsep(&stringp, ":");
05522 while(keyn) {
05523 key = ast_key_get(keyn, AST_KEY_PUBLIC);
05524 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05525 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05526 break;
05527 } else if (!key)
05528 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05529 keyn = strsep(&stringp, ":");
05530 }
05531 if (!keyn) {
05532 if (authdebug)
05533 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05534 goto return_unref;
05535 }
05536 } else {
05537 if (authdebug)
05538 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05539 goto return_unref;
05540 }
05541 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05542 struct MD5Context md5;
05543 unsigned char digest[16];
05544 char *tmppw, *stringp;
05545
05546 tmppw = ast_strdupa(p->secret);
05547 stringp = tmppw;
05548 while((tmppw = strsep(&stringp, ";"))) {
05549 MD5Init(&md5);
05550 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05551 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05552 MD5Final(digest, &md5);
05553 for (x=0;x<16;x++)
05554 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
05555 if (!strcasecmp(requeststr, md5secret))
05556 break;
05557 }
05558 if (tmppw) {
05559 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05560 } else {
05561 if (authdebug)
05562 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05563 goto return_unref;
05564 }
05565 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05566
05567 if (strcmp(secret, p->secret)) {
05568 if (authdebug)
05569 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05570 goto return_unref;
05571 } else
05572 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05573 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05574 if (authdebug)
05575 ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05576 goto return_unref;
05577 }
05578 ast_string_field_set(iaxs[callno], peer, peer);
05579
05580 if (expire && (expire < iaxs[callno]->expiry))
05581 iaxs[callno]->expiry = expire;
05582
05583 ast_device_state_changed("IAX2/%s", p->name);
05584
05585 res = 0;
05586
05587 return_unref:
05588 if (p)
05589 peer_unref(p);
05590
05591 return res;
05592 }
05593
05594 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
05595 {
05596 int res = -1;
05597 int x;
05598 if (!ast_strlen_zero(keyn)) {
05599 if (!(authmethods & IAX_AUTH_RSA)) {
05600 if (ast_strlen_zero(secret))
05601 ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr));
05602 } else if (ast_strlen_zero(challenge)) {
05603 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05604 } else {
05605 char sig[256];
05606 struct ast_key *key;
05607 key = ast_key_get(keyn, AST_KEY_PRIVATE);
05608 if (!key) {
05609 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05610 } else {
05611 if (ast_sign(key, (char*)challenge, sig)) {
05612 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05613 res = -1;
05614 } else {
05615 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05616 res = 0;
05617 }
05618 }
05619 }
05620 }
05621
05622 if (res && !ast_strlen_zero(secret)) {
05623 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05624 struct MD5Context md5;
05625 unsigned char digest[16];
05626 char digres[128];
05627 MD5Init(&md5);
05628 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05629 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05630 MD5Final(digest, &md5);
05631
05632 for (x=0;x<16;x++)
05633 sprintf(digres + (x << 1), "%2.2x", digest[x]);
05634 if (ecx && dcx)
05635 build_enc_keys(digest, ecx, dcx);
05636 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05637 res = 0;
05638 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05639 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05640 res = 0;
05641 } else
05642 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05643 }
05644 return res;
05645 }
05646
05647
05648
05649
05650
05651 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05652 {
05653 struct iax2_peer *peer = NULL;
05654
05655 int res = -1;
05656 int authmethods = 0;
05657 struct iax_ie_data ied;
05658 uint16_t callno = p->callno;
05659
05660 memset(&ied, 0, sizeof(ied));
05661
05662 if (ies->username)
05663 ast_string_field_set(p, username, ies->username);
05664 if (ies->challenge)
05665 ast_string_field_set(p, challenge, ies->challenge);
05666 if (ies->authmethods)
05667 authmethods = ies->authmethods;
05668 if (authmethods & IAX_AUTH_MD5)
05669 merge_encryption(p, ies->encmethods);
05670 else
05671 p->encmethods = 0;
05672
05673
05674 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05675
05676 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05677 } else {
05678 struct ao2_iterator i = ao2_iterator_init(peers, 0);
05679 while ((peer = ao2_iterator_next(&i))) {
05680 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
05681
05682 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05683
05684 && (!peer->addr.sin_addr.s_addr || ((sin->sin_addr.s_addr & peer->mask.s_addr) == (peer->addr.sin_addr.s_addr & peer->mask.s_addr)))
05685
05686 ) {
05687 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05688 if (!res) {
05689 peer_unref(peer);
05690 break;
05691 }
05692 }
05693 peer_unref(peer);
05694 }
05695 if (!peer) {
05696
05697
05698 const char *peer_name = ast_strdupa(p->peer);
05699 ast_mutex_unlock(&iaxsl[callno]);
05700 if ((peer = realtime_peer(peer_name, NULL))) {
05701 ast_mutex_lock(&iaxsl[callno]);
05702 if (!(p = iaxs[callno])) {
05703 peer_unref(peer);
05704 return -1;
05705 }
05706 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05707 peer_unref(peer);
05708 }
05709 if (!peer) {
05710 ast_mutex_lock(&iaxsl[callno]);
05711 if (!(p = iaxs[callno]))
05712 return -1;
05713 }
05714 }
05715 }
05716 if (ies->encmethods)
05717 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05718 if (!res)
05719 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05720 return res;
05721 }
05722
05723 static int iax2_do_register(struct iax2_registry *reg);
05724
05725 static void __iax2_do_register_s(const void *data)
05726 {
05727 struct iax2_registry *reg = (struct iax2_registry *)data;
05728 reg->expire = -1;
05729 iax2_do_register(reg);
05730 }
05731
05732 static int iax2_do_register_s(const void *data)
05733 {
05734 #ifdef SCHED_MULTITHREADED
05735 if (schedule_action(__iax2_do_register_s, data))
05736 #endif
05737 __iax2_do_register_s(data);
05738 return 0;
05739 }
05740
05741 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05742 {
05743 int newcall = 0;
05744 char newip[256];
05745 struct iax_ie_data ied;
05746 struct sockaddr_in new;
05747
05748
05749 memset(&ied, 0, sizeof(ied));
05750 if (ies->apparent_addr)
05751 bcopy(ies->apparent_addr, &new, sizeof(new));
05752 if (ies->callno)
05753 newcall = ies->callno;
05754 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05755 ast_log(LOG_WARNING, "Invalid transfer request\n");
05756 return -1;
05757 }
05758 pvt->transfercallno = newcall;
05759 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05760 inet_aton(newip, &pvt->transfer.sin_addr);
05761 pvt->transfer.sin_family = AF_INET;
05762 pvt->transferring = TRANSFER_BEGIN;
05763 pvt->transferid = ies->transferid;
05764 if (ies->transferid)
05765 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05766 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05767 return 0;
05768 }
05769
05770 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05771 {
05772 char exten[256] = "";
05773 int status = CACHE_FLAG_UNKNOWN;
05774 int expiry = iaxdefaultdpcache;
05775 int x;
05776 int matchmore = 0;
05777 struct iax2_dpcache *dp, *prev;
05778
05779 if (ies->called_number)
05780 ast_copy_string(exten, ies->called_number, sizeof(exten));
05781
05782 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05783 status = CACHE_FLAG_EXISTS;
05784 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05785 status = CACHE_FLAG_CANEXIST;
05786 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05787 status = CACHE_FLAG_NONEXISTENT;
05788
05789 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05790
05791 }
05792 if (ies->refresh)
05793 expiry = ies->refresh;
05794 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05795 matchmore = CACHE_FLAG_MATCHMORE;
05796 ast_mutex_lock(&dpcache_lock);
05797 prev = NULL;
05798 dp = pvt->dpentries;
05799 while(dp) {
05800 if (!strcmp(dp->exten, exten)) {
05801
05802 if (prev)
05803 prev->peer = dp->peer;
05804 else
05805 pvt->dpentries = dp->peer;
05806 dp->peer = NULL;
05807 dp->callno = 0;
05808 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05809 if (dp->flags & CACHE_FLAG_PENDING) {
05810 dp->flags &= ~CACHE_FLAG_PENDING;
05811 dp->flags |= status;
05812 dp->flags |= matchmore;
05813 }
05814
05815 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05816 if (dp->waiters[x] > -1)
05817 write(dp->waiters[x], "asdf", 4);
05818 }
05819 prev = dp;
05820 dp = dp->peer;
05821 }
05822 ast_mutex_unlock(&dpcache_lock);
05823 return 0;
05824 }
05825
05826 static int complete_transfer(int callno, struct iax_ies *ies)
05827 {
05828 int peercallno = 0;
05829 struct chan_iax2_pvt *pvt = iaxs[callno];
05830 struct iax_frame *cur;
05831 jb_frame frame;
05832
05833 if (ies->callno)
05834 peercallno = ies->callno;
05835
05836 if (peercallno < 1) {
05837 ast_log(LOG_WARNING, "Invalid transfer request\n");
05838 return -1;
05839 }
05840 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05841 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05842
05843 pvt->oseqno = 0;
05844 pvt->rseqno = 0;
05845 pvt->iseqno = 0;
05846 pvt->aseqno = 0;
05847
05848 if (pvt->peercallno) {
05849 remove_by_peercallno(pvt);
05850 }
05851 pvt->peercallno = peercallno;
05852 store_by_peercallno(pvt);
05853
05854 pvt->transferring = TRANSFER_NONE;
05855 pvt->svoiceformat = -1;
05856 pvt->voiceformat = 0;
05857 pvt->svideoformat = -1;
05858 pvt->videoformat = 0;
05859 pvt->transfercallno = -1;
05860 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05861 memset(&pvt->offset, 0, sizeof(pvt->offset));
05862
05863 while(jb_getall(pvt->jb,&frame) == JB_OK)
05864 iax2_frame_free(frame.data);
05865 jb_reset(pvt->jb);
05866 pvt->lag = 0;
05867 pvt->last = 0;
05868 pvt->lastsent = 0;
05869 pvt->nextpred = 0;
05870 pvt->pingtime = DEFAULT_RETRY_TIME;
05871 AST_LIST_LOCK(&iaxq.queue);
05872 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05873
05874
05875
05876 if (callno == cur->callno)
05877 cur->retries = -1;
05878 }
05879 AST_LIST_UNLOCK(&iaxq.queue);
05880 return 0;
05881 }
05882
05883
05884 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05885 {
05886 struct iax2_registry *reg;
05887
05888 char peer[256] = "";
05889 char msgstatus[60];
05890 int refresh = 60;
05891 char ourip[256] = "<Unspecified>";
05892 struct sockaddr_in oldus;
05893 struct sockaddr_in us;
05894 int oldmsgs;
05895
05896 memset(&us, 0, sizeof(us));
05897 if (ies->apparent_addr)
05898 bcopy(ies->apparent_addr, &us, sizeof(us));
05899 if (ies->username)
05900 ast_copy_string(peer, ies->username, sizeof(peer));
05901 if (ies->refresh)
05902 refresh = ies->refresh;
05903 if (ies->calling_number) {
05904
05905 }
05906 reg = iaxs[callno]->reg;
05907 if (!reg) {
05908 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05909 return -1;
05910 }
05911 memcpy(&oldus, ®->us, sizeof(oldus));
05912 oldmsgs = reg->messages;
05913 if (inaddrcmp(®->addr, sin)) {
05914 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05915 return -1;
05916 }
05917 memcpy(®->us, &us, sizeof(reg->us));
05918 if (ies->msgcount >= 0)
05919 reg->messages = ies->msgcount & 0xffff;
05920
05921
05922
05923 reg->refresh = refresh;
05924 AST_SCHED_DEL(sched, reg->expire);
05925 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05926 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
05927 if (option_verbose > 2) {
05928 if (reg->messages > 255)
05929 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05930 else if (reg->messages > 1)
05931 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05932 else if (reg->messages > 0)
05933 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05934 else
05935 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05936 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05937 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05938 }
05939 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05940 }
05941 reg->regstate = REG_STATE_REGISTERED;
05942 return 0;
05943 }
05944
05945 static int iax2_register(char *value, int lineno)
05946 {
05947 struct iax2_registry *reg;
05948 char copy[256];
05949 char *username, *hostname, *secret;
05950 char *porta;
05951 char *stringp=NULL;
05952
05953 if (!value)
05954 return -1;
05955 ast_copy_string(copy, value, sizeof(copy));
05956 stringp=copy;
05957 username = strsep(&stringp, "@");
05958 hostname = strsep(&stringp, "@");
05959 if (!hostname) {
05960 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
05961 return -1;
05962 }
05963 stringp=username;
05964 username = strsep(&stringp, ":");
05965 secret = strsep(&stringp, ":");
05966 stringp=hostname;
05967 hostname = strsep(&stringp, ":");
05968 porta = strsep(&stringp, ":");
05969
05970 if (porta && !atoi(porta)) {
05971 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05972 return -1;
05973 }
05974 if (!(reg = ast_calloc(1, sizeof(*reg))))
05975 return -1;
05976 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) {
05977 free(reg);
05978 return -1;
05979 }
05980 ast_copy_string(reg->username, username, sizeof(reg->username));
05981 if (secret)
05982 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05983 reg->expire = -1;
05984 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05985 reg->addr.sin_family = AF_INET;
05986 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05987 AST_LIST_LOCK(®istrations);
05988 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
05989 AST_LIST_UNLOCK(®istrations);
05990
05991 return 0;
05992 }
05993
05994 static void register_peer_exten(struct iax2_peer *peer, int onoff)
05995 {
05996 char multi[256];
05997 char *stringp, *ext;
05998 if (!ast_strlen_zero(regcontext)) {
05999 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06000 stringp = multi;
06001 while((ext = strsep(&stringp, "&"))) {
06002 if (onoff) {
06003 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06004 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06005 "Noop", ast_strdup(peer->name), ast_free, "IAX2");
06006 } else
06007 ast_context_remove_extension(regcontext, ext, 1, NULL);
06008 }
06009 }
06010 }
06011 static void prune_peers(void);
06012
06013 static void unlink_peer(struct iax2_peer *peer)
06014 {
06015 if (peer->expire > -1) {
06016 if (!ast_sched_del(sched, peer->expire)) {
06017 peer->expire = -1;
06018 peer_unref(peer);
06019 }
06020 }
06021
06022 if (peer->pokeexpire > -1) {
06023 if (!ast_sched_del(sched, peer->pokeexpire)) {
06024 peer->pokeexpire = -1;
06025 peer_unref(peer);
06026 }
06027 }
06028
06029 ao2_unlink(peers, peer);
06030 }
06031
06032 static void __expire_registry(const void *data)
06033 {
06034 struct iax2_peer *peer = (struct iax2_peer *) data;
06035
06036 if (!peer)
06037 return;
06038
06039 peer->expire = -1;
06040
06041 if (option_debug)
06042 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06043 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06044 realtime_update_peer(peer->name, &peer->addr, 0);
06045 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06046
06047 memset(&peer->addr, 0, sizeof(peer->addr));
06048
06049 peer->expiry = min_reg_expire;
06050 if (!ast_test_flag(peer, IAX_TEMPONLY))
06051 ast_db_del("IAX/Registry", peer->name);
06052 register_peer_exten(peer, 0);
06053 ast_device_state_changed("IAX2/%s", peer->name);
06054 if (iax2_regfunk)
06055 iax2_regfunk(peer->name, 0);
06056
06057 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06058 unlink_peer(peer);
06059
06060 peer_unref(peer);
06061 }
06062
06063 static int expire_registry(const void *data)
06064 {
06065 #ifdef SCHED_MULTITHREADED
06066 if (schedule_action(__expire_registry, data))
06067 #endif
06068 __expire_registry(data);
06069 return 0;
06070 }
06071
06072 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06073
06074 static void reg_source_db(struct iax2_peer *p)
06075 {
06076 char data[80];
06077 struct in_addr in;
06078 char *c, *d;
06079 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06080 c = strchr(data, ':');
06081 if (c) {
06082 *c = '\0';
06083 c++;
06084 if (inet_aton(data, &in)) {
06085 d = strchr(c, ':');
06086 if (d) {
06087 *d = '\0';
06088 d++;
06089 if (option_verbose > 2)
06090 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name,
06091 ast_inet_ntoa(in), atoi(c), atoi(d));
06092 iax2_poke_peer(p, 0);
06093 p->expiry = atoi(d);
06094 memset(&p->addr, 0, sizeof(p->addr));
06095 p->addr.sin_family = AF_INET;
06096 p->addr.sin_addr = in;
06097 p->addr.sin_port = htons(atoi(c));
06098 if (p->expire > -1) {
06099 if (!ast_sched_del(sched, p->expire)) {
06100 p->expire = -1;
06101 peer_unref(p);
06102 }
06103 }
06104 ast_device_state_changed("IAX2/%s", p->name);
06105 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06106 if (p->expire == -1)
06107 peer_unref(p);
06108 if (iax2_regfunk)
06109 iax2_regfunk(p->name, 1);
06110 register_peer_exten(p, 1);
06111 }
06112
06113 }
06114 }
06115 }
06116 }
06117
06118
06119
06120
06121
06122
06123
06124 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06125 {
06126
06127 struct iax_ie_data ied;
06128 struct iax2_peer *p;
06129 int msgcount;
06130 char data[80];
06131 int version;
06132 const char *peer_name;
06133 int res = -1;
06134
06135 memset(&ied, 0, sizeof(ied));
06136
06137 peer_name = ast_strdupa(iaxs[callno]->peer);
06138
06139
06140 ast_mutex_unlock(&iaxsl[callno]);
06141 if (!(p = find_peer(peer_name, 1))) {
06142 ast_mutex_lock(&iaxsl[callno]);
06143 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06144 return -1;
06145 }
06146 ast_mutex_lock(&iaxsl[callno]);
06147 if (!iaxs[callno])
06148 goto return_unref;
06149
06150 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06151 if (sin->sin_addr.s_addr) {
06152 time_t nowtime;
06153 time(&nowtime);
06154 realtime_update_peer(peer_name, sin, nowtime);
06155 } else {
06156 realtime_update_peer(peer_name, sin, 0);
06157 }
06158 }
06159 if (inaddrcmp(&p->addr, sin)) {
06160 if (iax2_regfunk)
06161 iax2_regfunk(p->name, 1);
06162
06163 memcpy(&p->addr, sin, sizeof(p->addr));
06164 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06165 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06166 ast_db_put("IAX/Registry", p->name, data);
06167 if (option_verbose > 2)
06168 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
06169 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06170 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06171 register_peer_exten(p, 1);
06172 ast_device_state_changed("IAX2/%s", p->name);
06173 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06174 if (option_verbose > 2)
06175 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name,
06176 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06177 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06178 register_peer_exten(p, 0);
06179 ast_db_del("IAX/Registry", p->name);
06180 ast_device_state_changed("IAX2/%s", p->name);
06181 }
06182
06183
06184 iax2_poke_peer(p, callno);
06185 }
06186
06187
06188 if (!iaxs[callno]) {
06189 res = 0;
06190 goto return_unref;
06191 }
06192
06193
06194 p->sockfd = fd;
06195
06196 if (p->expire > -1) {
06197 if (!ast_sched_del(sched, p->expire)) {
06198 p->expire = -1;
06199 peer_unref(p);
06200 }
06201 }
06202
06203 if (!refresh)
06204 refresh = min_reg_expire;
06205 if (refresh > max_reg_expire) {
06206 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06207 p->name, max_reg_expire, refresh);
06208 p->expiry = max_reg_expire;
06209 } else if (refresh < min_reg_expire) {
06210 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06211 p->name, min_reg_expire, refresh);
06212 p->expiry = min_reg_expire;
06213 } else {
06214 p->expiry = refresh;
06215 }
06216 if (p->expiry && sin->sin_addr.s_addr) {
06217 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06218 if (p->expire == -1)
06219 peer_unref(p);
06220 }
06221 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06222 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06223 if (sin->sin_addr.s_addr) {
06224 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06225 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06226 if (!ast_strlen_zero(p->mailbox)) {
06227 int new, old;
06228 ast_app_inboxcount(p->mailbox, &new, &old);
06229 if (new > 255)
06230 new = 255;
06231 if (old > 255)
06232 old = 255;
06233 msgcount = (old << 8) | new;
06234 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06235 }
06236 if (ast_test_flag(p, IAX_HASCALLERID)) {
06237 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06238 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06239 }
06240 }
06241 version = iax_check_version(devtype);
06242 if (version)
06243 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06244
06245 res = 0;
06246
06247 return_unref:
06248 peer_unref(p);
06249
06250 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06251 }
06252
06253 static int registry_authrequest(int callno)
06254 {
06255 struct iax_ie_data ied;
06256 struct iax2_peer *p;
06257 char challenge[10];
06258 const char *peer_name;
06259 int res = -1;
06260
06261 peer_name = ast_strdupa(iaxs[callno]->peer);
06262
06263
06264 ast_mutex_unlock(&iaxsl[callno]);
06265 p = find_peer(peer_name, 1);
06266 ast_mutex_lock(&iaxsl[callno]);
06267 if (!iaxs[callno])
06268 goto return_unref;
06269 if (!p) {
06270 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06271 goto return_unref;
06272 }
06273
06274 memset(&ied, 0, sizeof(ied));
06275 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06276 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06277
06278 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06279 ast_string_field_set(iaxs[callno], challenge, challenge);
06280 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06281 }
06282 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06283
06284 res = 0;
06285
06286 return_unref:
06287 peer_unref(p);
06288
06289 return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
06290 }
06291
06292 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06293 {
06294 struct iax2_registry *reg;
06295
06296 struct iax_ie_data ied;
06297 char peer[256] = "";
06298 char challenge[256] = "";
06299 int res;
06300 int authmethods = 0;
06301 if (ies->authmethods)
06302 authmethods = ies->authmethods;
06303 if (ies->username)
06304 ast_copy_string(peer, ies->username, sizeof(peer));
06305 if (ies->challenge)
06306 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06307 memset(&ied, 0, sizeof(ied));
06308 reg = iaxs[callno]->reg;
06309 if (reg) {
06310 if (inaddrcmp(®->addr, sin)) {
06311 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06312 return -1;
06313 }
06314 if (ast_strlen_zero(reg->secret)) {
06315 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06316 reg->regstate = REG_STATE_NOAUTH;
06317 return -1;
06318 }
06319 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06320 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06321 if (reg->secret[0] == '[') {
06322 char tmpkey[256];
06323 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06324 tmpkey[strlen(tmpkey) - 1] = '\0';
06325 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06326 } else
06327 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06328 if (!res) {
06329 reg->regstate = REG_STATE_AUTHSENT;
06330 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06331 } else
06332 return -1;
06333 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06334 } else
06335 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06336 return -1;
06337 }
06338
06339 static void stop_stuff(int callno)
06340 {
06341 iax2_destroy_helper(iaxs[callno]);
06342 }
06343
06344 static void __auth_reject(const void *nothing)
06345 {
06346
06347 int callno = (int)(long)(nothing);
06348 struct iax_ie_data ied;
06349 ast_mutex_lock(&iaxsl[callno]);
06350 if (iaxs[callno]) {
06351 memset(&ied, 0, sizeof(ied));
06352 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06353 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06354 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06355 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06356 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06357 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06358 }
06359 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06360 }
06361 ast_mutex_unlock(&iaxsl[callno]);
06362 }
06363
06364 static int auth_reject(const void *data)
06365 {
06366 int callno = (int)(long)(data);
06367 ast_mutex_lock(&iaxsl[callno]);
06368 if (iaxs[callno])
06369 iaxs[callno]->authid = -1;
06370 ast_mutex_unlock(&iaxsl[callno]);
06371 #ifdef SCHED_MULTITHREADED
06372 if (schedule_action(__auth_reject, data))
06373 #endif
06374 __auth_reject(data);
06375 return 0;
06376 }
06377
06378 static int auth_fail(int callno, int failcode)
06379 {
06380
06381
06382 if (iaxs[callno]) {
06383 iaxs[callno]->authfail = failcode;
06384 if (delayreject) {
06385 AST_SCHED_DEL(sched, iaxs[callno]->authid);
06386 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06387 } else
06388 auth_reject((void *)(long)callno);
06389 }
06390 return 0;
06391 }
06392
06393 static void __auto_hangup(const void *nothing)
06394 {
06395
06396 int callno = (int)(long)(nothing);
06397 struct iax_ie_data ied;
06398 ast_mutex_lock(&iaxsl[callno]);
06399 if (iaxs[callno]) {
06400 memset(&ied, 0, sizeof(ied));
06401 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06402 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06403 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06404 }
06405 ast_mutex_unlock(&iaxsl[callno]);
06406 }
06407
06408 static int auto_hangup(const void *data)
06409 {
06410 int callno = (int)(long)(data);
06411 ast_mutex_lock(&iaxsl[callno]);
06412 if (iaxs[callno]) {
06413 iaxs[callno]->autoid = -1;
06414 }
06415 ast_mutex_unlock(&iaxsl[callno]);
06416 #ifdef SCHED_MULTITHREADED
06417 if (schedule_action(__auto_hangup, data))
06418 #endif
06419 __auto_hangup(data);
06420 return 0;
06421 }
06422
06423 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06424 {
06425 struct iax_ie_data ied;
06426
06427 AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06428 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06429 memset(&ied, 0, sizeof(ied));
06430 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06431 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06432 dp->flags |= CACHE_FLAG_TRANSMITTED;
06433 }
06434
06435 static int iax2_vnak(int callno)
06436 {
06437 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06438 }
06439
06440 static void vnak_retransmit(int callno, int last)
06441 {
06442 struct iax_frame *f;
06443
06444 AST_LIST_LOCK(&iaxq.queue);
06445 AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06446
06447 if ((f->callno == callno) && iaxs[f->callno] &&
06448 ((unsigned char ) (f->oseqno - last) < 128) &&
06449 (f->retries >= 0)) {
06450 send_packet(f);
06451 }
06452 }
06453 AST_LIST_UNLOCK(&iaxq.queue);
06454 }
06455
06456 static void __iax2_poke_peer_s(const void *data)
06457 {
06458 struct iax2_peer *peer = (struct iax2_peer *)data;
06459 iax2_poke_peer(peer, 0);
06460 peer_unref(peer);
06461 }
06462
06463 static int iax2_poke_peer_s(const void *data)
06464 {
06465 struct iax2_peer *peer = (struct iax2_peer *)data;
06466 peer->pokeexpire = -1;
06467 #ifdef SCHED_MULTITHREADED
06468 if (schedule_action(__iax2_poke_peer_s, data))
06469 #endif
06470 __iax2_poke_peer_s(data);
06471 return 0;
06472 }
06473
06474 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06475 {
06476 int res = 0;
06477 struct iax_frame *fr;
06478 struct ast_iax2_meta_hdr *meta;
06479 struct ast_iax2_meta_trunk_hdr *mth;
06480 int calls = 0;
06481
06482
06483 fr = (struct iax_frame *)tpeer->trunkdata;
06484
06485 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06486 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06487 if (tpeer->trunkdatalen) {
06488
06489 meta->zeros = 0;
06490 meta->metacmd = IAX_META_TRUNK;
06491 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06492 meta->cmddata = IAX_META_TRUNK_MINI;
06493 else
06494 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06495 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06496
06497 fr->direction = DIRECTION_OUTGRESS;
06498 fr->retrans = -1;
06499 fr->transfer = 0;
06500
06501 fr->data = fr->afdata;
06502 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06503 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06504 calls = tpeer->calls;
06505 #if 0
06506 if (option_debug)
06507 ast_log(LOG_DEBUG, "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));
06508 #endif
06509
06510 tpeer->trunkdatalen = 0;
06511 tpeer->calls = 0;
06512 }
06513 if (res < 0)
06514 return res;
06515 return calls;
06516 }
06517
06518 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06519 {
06520
06521 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
06522 return 1;
06523 return 0;
06524 }
06525
06526 static int timing_read(int *id, int fd, short events, void *cbdata)
06527 {
06528 char buf[1024];
06529 int res;
06530 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06531 int processed = 0;
06532 int totalcalls = 0;
06533 #ifdef ZT_TIMERACK
06534 int x = 1;
06535 #endif
06536 struct timeval now;
06537 if (iaxtrunkdebug)
06538 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06539 gettimeofday(&now, NULL);
06540 if (events & AST_IO_PRI) {
06541 #ifdef ZT_TIMERACK
06542
06543 if (ioctl(fd, ZT_TIMERACK, &x)) {
06544 ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n");
06545 usleep(1);
06546 return -1;
06547 }
06548 #endif
06549 } else {
06550
06551 res = read(fd, buf, sizeof(buf));
06552 if (res < 1) {
06553 ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06554 return 1;
06555 }
06556 }
06557
06558 ast_mutex_lock(&tpeerlock);
06559 tpeer = tpeers;
06560 while(tpeer) {
06561 processed++;
06562 res = 0;
06563 ast_mutex_lock(&tpeer->lock);
06564
06565
06566 if (!drop && iax2_trunk_expired(tpeer, &now)) {
06567
06568
06569 if (prev)
06570 prev->next = tpeer->next;
06571 else
06572 tpeers = tpeer->next;
06573 drop = tpeer;
06574 } else {
06575 res = send_trunk(tpeer, &now);
06576 if (iaxtrunkdebug)
06577 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
06578 }
06579 totalcalls += res;
06580 res = 0;
06581 ast_mutex_unlock(&tpeer->lock);
06582 prev = tpeer;
06583 tpeer = tpeer->next;
06584 }
06585 ast_mutex_unlock(&tpeerlock);
06586 if (drop) {
06587 ast_mutex_lock(&drop->lock);
06588
06589
06590 if (option_debug)
06591 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06592 if (drop->trunkdata) {
06593 free(drop->trunkdata);
06594 drop->trunkdata = NULL;
06595 }
06596 ast_mutex_unlock(&drop->lock);
06597 ast_mutex_destroy(&drop->lock);
06598 free(drop);
06599
06600 }
06601 if (iaxtrunkdebug)
06602 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06603 iaxtrunkdebug =0;
06604 return 1;
06605 }
06606
06607 struct dpreq_data {
06608 int callno;
06609 char context[AST_MAX_EXTENSION];
06610 char callednum[AST_MAX_EXTENSION];
06611 char *callerid;
06612 };
06613
06614 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06615 {
06616 unsigned short dpstatus = 0;
06617 struct iax_ie_data ied1;
06618 int mm;
06619
06620 memset(&ied1, 0, sizeof(ied1));
06621 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06622
06623 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06624 dpstatus = IAX_DPSTATUS_EXISTS;
06625 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06626 dpstatus = IAX_DPSTATUS_CANEXIST;
06627 } else {
06628 dpstatus = IAX_DPSTATUS_NONEXISTENT;
06629 }
06630 if (ast_ignore_pattern(context, callednum))
06631 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06632 if (mm)
06633 dpstatus |= IAX_DPSTATUS_MATCHMORE;
06634 if (!skiplock)
06635 ast_mutex_lock(&iaxsl[callno]);
06636 if (iaxs[callno]) {
06637 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06638 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06639 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06640 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06641 }
06642 if (!skiplock)
06643 ast_mutex_unlock(&iaxsl[callno]);
06644 }
06645
06646 static void *dp_lookup_thread(void *data)
06647 {
06648
06649 struct dpreq_data *dpr = data;
06650 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06651 if (dpr->callerid)
06652 free(dpr->callerid);
06653 free(dpr);
06654 return NULL;
06655 }
06656
06657 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06658 {
06659 pthread_t newthread;
06660 struct dpreq_data *dpr;
06661 pthread_attr_t attr;
06662
06663 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06664 return;
06665
06666 pthread_attr_init(&attr);
06667 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06668
06669 dpr->callno = callno;
06670 ast_copy_string(dpr->context, context, sizeof(dpr->context));
06671 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06672 if (callerid)
06673 dpr->callerid = ast_strdup(callerid);
06674 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06675 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06676 }
06677
06678 pthread_attr_destroy(&attr);
06679 }
06680
06681 struct iax_dual {
06682 struct ast_channel *chan1;
06683 struct ast_channel *chan2;
06684 };
06685
06686 static void *iax_park_thread(void *stuff)
06687 {
06688 struct ast_channel *chan1, *chan2;
06689 struct iax_dual *d;
06690 struct ast_frame *f;
06691 int ext;
06692 int res;
06693 d = stuff;
06694 chan1 = d->chan1;
06695 chan2 = d->chan2;
06696 free(d);
06697 f = ast_read(chan1);
06698 if (f)
06699 ast_frfree(f);
06700 res = ast_park_call(chan1, chan2, 0, &ext);
06701 ast_hangup(chan2);
06702 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06703 return NULL;
06704 }
06705
06706 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06707 {
06708 struct iax_dual *d;
06709 struct ast_channel *chan1m, *chan2m;
06710 pthread_t th;
06711 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06712 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06713 if (chan2m && chan1m) {
06714
06715 chan1m->readformat = chan1->readformat;
06716 chan1m->writeformat = chan1->writeformat;
06717 ast_channel_masquerade(chan1m, chan1);
06718
06719 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06720 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06721 chan1m->priority = chan1->priority;
06722
06723
06724
06725
06726 chan2m->readformat = chan2->readformat;
06727 chan2m->writeformat = chan2->writeformat;
06728 ast_channel_masquerade(chan2m, chan2);
06729
06730 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06731 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06732 chan2m->priority = chan2->priority;
06733 if (ast_do_masquerade(chan2m)) {
06734 ast_log(LOG_WARNING, "Masquerade failed :(\n");
06735 ast_hangup(chan2m);
06736 return -1;
06737 }
06738 } else {
06739 if (chan1m)
06740 ast_hangup(chan1m);
06741 if (chan2m)
06742 ast_hangup(chan2m);
06743 return -1;
06744 }
06745 if ((d = ast_calloc(1, sizeof(*d)))) {
06746 pthread_attr_t attr;
06747
06748 pthread_attr_init(&attr);
06749 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06750
06751 d->chan1 = chan1m;
06752 d->chan2 = chan2m;
06753 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06754 pthread_attr_destroy(&attr);
06755 return 0;
06756 }
06757 pthread_attr_destroy(&attr);
06758 free(d);
06759 }
06760 return -1;
06761 }
06762
06763
06764 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06765
06766 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06767 {
06768 unsigned int ourver;
06769 char rsi[80];
06770 snprintf(rsi, sizeof(rsi), "si-%s", si);
06771 if (iax_provision_version(&ourver, rsi, 1))
06772 return 0;
06773 if (option_debug)
06774 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06775 if (ourver != ver)
06776 iax2_provision(sin, sockfd, NULL, rsi, 1);
06777 return 0;
06778 }
06779
06780 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
06781 {
06782 jb_info stats;
06783 jb_getinfo(pvt->jb, &stats);
06784
06785 memset(iep, 0, sizeof(*iep));
06786
06787 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06788 if(stats.frames_in == 0) stats.frames_in = 1;
06789 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06790 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06791 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06792 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06793 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06794 }
06795
06796 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
06797 {
06798 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06799 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06800 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06801 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06802 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06803 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06804 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06805 }
06806
06807 static int socket_process(struct iax2_thread *thread);
06808
06809
06810
06811
06812 static void handle_deferred_full_frames(struct iax2_thread *thread)
06813 {
06814 struct iax2_pkt_buf *pkt_buf;
06815
06816 ast_mutex_lock(&thread->lock);
06817
06818 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06819 ast_mutex_unlock(&thread->lock);
06820
06821 thread->buf = pkt_buf->buf;
06822 thread->buf_len = pkt_buf->len;
06823 thread->buf_size = pkt_buf->len + 1;
06824
06825 socket_process(thread);
06826
06827 thread->buf = NULL;
06828 ast_free(pkt_buf);
06829
06830 ast_mutex_lock(&thread->lock);
06831 }
06832
06833 ast_mutex_unlock(&thread->lock);
06834 }
06835
06836
06837
06838
06839
06840
06841
06842 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06843 {
06844 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06845 struct ast_iax2_full_hdr *fh, *cur_fh;
06846
06847 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06848 return;
06849
06850 pkt_buf->len = from_here->buf_len;
06851 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06852
06853 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06854 ast_mutex_lock(&to_here->lock);
06855 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06856 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06857 if (fh->oseqno < cur_fh->oseqno) {
06858 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06859 break;
06860 }
06861 }
06862 AST_LIST_TRAVERSE_SAFE_END
06863
06864 if (!cur_pkt_buf)
06865 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06866
06867 ast_mutex_unlock(&to_here->lock);
06868 }
06869
06870 static int socket_read(int *id, int fd, short events, void *cbdata)
06871 {
06872 struct iax2_thread *thread;
06873 socklen_t len;
06874 time_t t;
06875 static time_t last_errtime = 0;
06876 struct ast_iax2_full_hdr *fh;
06877
06878 if (!(thread = find_idle_thread())) {
06879 time(&t);
06880 if (t != last_errtime && option_debug)
06881 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
06882 last_errtime = t;
06883 usleep(1);
06884 return 1;
06885 }
06886
06887 len = sizeof(thread->iosin);
06888 thread->iofd = fd;
06889 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06890 thread->buf_size = sizeof(thread->readbuf);
06891 thread->buf = thread->readbuf;
06892 if (thread->buf_len < 0) {
06893 if (errno != ECONNREFUSED && errno != EAGAIN)
06894 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06895 handle_error();
06896 thread->iostate = IAX_IOSTATE_IDLE;
06897 signal_condition(&thread->lock, &thread->cond);
06898 return 1;
06899 }
06900 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
06901 thread->iostate = IAX_IOSTATE_IDLE;
06902 signal_condition(&thread->lock, &thread->cond);
06903 return 1;
06904 }
06905
06906
06907
06908
06909 fh = (struct ast_iax2_full_hdr *) thread->buf;
06910 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06911 struct iax2_thread *cur = NULL;
06912 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06913
06914 AST_LIST_LOCK(&active_list);
06915 AST_LIST_TRAVERSE(&active_list, cur, list) {
06916 if ((cur->ffinfo.callno == callno) &&
06917 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06918 break;
06919 }
06920 if (cur) {
06921
06922
06923 defer_full_frame(thread, cur);
06924 AST_LIST_UNLOCK(&active_list);
06925 thread->iostate = IAX_IOSTATE_IDLE;
06926 signal_condition(&thread->lock, &thread->cond);
06927 return 1;
06928 } else {
06929
06930 thread->ffinfo.callno = callno;
06931 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
06932 thread->ffinfo.type = fh->type;
06933 thread->ffinfo.csub = fh->csub;
06934 }
06935 AST_LIST_UNLOCK(&active_list);
06936 }
06937
06938
06939 thread->iostate = IAX_IOSTATE_READY;
06940 #ifdef DEBUG_SCHED_MULTITHREAD
06941 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
06942 #endif
06943 signal_condition(&thread->lock, &thread->cond);
06944
06945 return 1;
06946 }
06947
06948 static int socket_process(struct iax2_thread *thread)
06949 {
06950 struct sockaddr_in sin;
06951 int res;
06952 int updatehistory=1;
06953 int new = NEW_PREVENT;
06954 void *ptr;
06955 int dcallno = 0;
06956 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
06957 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
06958 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
06959 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
06960 struct ast_iax2_meta_trunk_hdr *mth;
06961 struct ast_iax2_meta_trunk_entry *mte;
06962 struct ast_iax2_meta_trunk_mini *mtm;
06963 struct iax_frame *fr;
06964 struct iax_frame *cur;
06965 struct ast_frame f = { 0, };
06966 struct ast_channel *c;
06967 struct iax2_dpcache *dp;
06968 struct iax2_peer *peer;
06969 struct iax2_trunk_peer *tpeer;
06970 struct timeval rxtrunktime;
06971 struct iax_ies ies;
06972 struct iax_ie_data ied0, ied1;
06973 int format;
06974 int fd;
06975 int exists;
06976 int minivid = 0;
06977 unsigned int ts;
06978 char empty[32]="";
06979 struct iax_frame *duped_fr;
06980 char host_pref_buf[128];
06981 char caller_pref_buf[128];
06982 struct ast_codec_pref pref;
06983 char *using_prefs = "mine";
06984
06985
06986 fr = alloca(sizeof(*fr) + 4096);
06987 memset(fr, 0, sizeof(*fr));
06988 fr->afdatalen = 4096;
06989
06990
06991 res = thread->buf_len;
06992 fd = thread->iofd;
06993 memcpy(&sin, &thread->iosin, sizeof(sin));
06994
06995 if (res < sizeof(*mh)) {
06996 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
06997 return 1;
06998 }
06999 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07000 if (res < sizeof(*vh)) {
07001 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07002 return 1;
07003 }
07004
07005
07006 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07007 minivid = 1;
07008 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07009 unsigned char metatype;
07010
07011 if (res < sizeof(*meta)) {
07012 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07013 return 1;
07014 }
07015
07016
07017 switch(meta->metacmd) {
07018 case IAX_META_TRUNK:
07019 if (res < (sizeof(*meta) + sizeof(*mth))) {
07020 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07021 sizeof(*meta) + sizeof(*mth));
07022 return 1;
07023 }
07024 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07025 ts = ntohl(mth->ts);
07026 metatype = meta->cmddata;
07027 res -= (sizeof(*meta) + sizeof(*mth));
07028 ptr = mth->data;
07029 tpeer = find_tpeer(&sin, fd);
07030 if (!tpeer) {
07031 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07032 return 1;
07033 }
07034 tpeer->trunkact = ast_tvnow();
07035 if (!ts || ast_tvzero(tpeer->rxtrunktime))
07036 tpeer->rxtrunktime = tpeer->trunkact;
07037 rxtrunktime = tpeer->rxtrunktime;
07038 ast_mutex_unlock(&tpeer->lock);
07039 while(res >= sizeof(*mte)) {
07040
07041 unsigned short callno, trunked_ts, len;
07042
07043 if (metatype == IAX_META_TRUNK_MINI) {
07044 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07045 ptr += sizeof(*mtm);
07046 res -= sizeof(*mtm);
07047 len = ntohs(mtm->len);
07048 callno = ntohs(mtm->mini.callno);
07049 trunked_ts = ntohs(mtm->mini.ts);
07050 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07051 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07052 ptr += sizeof(*mte);
07053 res -= sizeof(*mte);
07054 len = ntohs(mte->len);
07055 callno = ntohs(mte->callno);
07056 trunked_ts = 0;
07057 } else {
07058 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07059 break;
07060 }
07061
07062 if (len > res)
07063 break;
07064 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07065 if (fr->callno) {
07066
07067
07068
07069 memset(&f, 0, sizeof(f));
07070 f.frametype = AST_FRAME_VOICE;
07071 if (iaxs[fr->callno]) {
07072 if (iaxs[fr->callno]->voiceformat > 0) {
07073 f.subclass = iaxs[fr->callno]->voiceformat;
07074 f.datalen = len;
07075 if (f.datalen >= 0) {
07076 if (f.datalen)
07077 f.data = ptr;
07078 if(trunked_ts) {
07079 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07080 } else
07081 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07082
07083 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07084
07085 f.src = "IAX2";
07086 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
07087 f.samples = ast_codec_get_samples(&f);
07088 iax_frame_wrap(fr, &f);
07089 duped_fr = iaxfrdup2(fr);
07090 if (duped_fr) {
07091 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07092 }
07093
07094 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07095 iaxs[fr->callno]->last = fr->ts;
07096 #if 1
07097 if (option_debug && iaxdebug)
07098 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07099 #endif
07100 }
07101 }
07102 } else {
07103 ast_log(LOG_WARNING, "Datalen < 0?\n");
07104 }
07105 } else {
07106 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
07107 iax2_vnak(fr->callno);
07108 }
07109 }
07110 ast_mutex_unlock(&iaxsl[fr->callno]);
07111 }
07112 ptr += len;
07113 res -= len;
07114 }
07115
07116 }
07117 return 1;
07118 }
07119
07120 #ifdef DEBUG_SUPPORT
07121 if (iaxdebug && (res >= sizeof(*fh)))
07122 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07123 #endif
07124 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07125 if (res < sizeof(*fh)) {
07126 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07127 return 1;
07128 }
07129
07130
07131 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07132
07133 f.frametype = fh->type;
07134 if (f.frametype == AST_FRAME_VIDEO) {
07135 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07136 } else {
07137 f.subclass = uncompress_subclass(fh->csub);
07138 }
07139
07140
07141 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07142
07143 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno);
07144 return 1;
07145 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07146
07147 return 1;
07148 }
07149
07150 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07151 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07152 (f.subclass == IAX_COMMAND_REGREL)))
07153 new = NEW_ALLOW;
07154 } else {
07155
07156 f.frametype = AST_FRAME_NULL;
07157 f.subclass = 0;
07158 }
07159
07160 if (!fr->callno) {
07161 int check_dcallno = 0;
07162
07163
07164
07165
07166
07167
07168
07169
07170
07171
07172
07173
07174
07175 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07176 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07177 }
07178
07179 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07180 }
07181
07182 if (fr->callno > 0)
07183 ast_mutex_lock(&iaxsl[fr->callno]);
07184
07185 if (!fr->callno || !iaxs[fr->callno]) {
07186
07187
07188 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07189
07190 if (((f.subclass != IAX_COMMAND_INVAL) &&
07191 (f.subclass != IAX_COMMAND_TXCNT) &&
07192 (f.subclass != IAX_COMMAND_TXACC) &&
07193 (f.subclass != IAX_COMMAND_FWDOWNL))||
07194 (f.frametype != AST_FRAME_IAX))
07195 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07196 fd);
07197 }
07198 if (fr->callno > 0)
07199 ast_mutex_unlock(&iaxsl[fr->callno]);
07200 return 1;
07201 }
07202 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07203 if (decrypt_frame(fr->callno, fh, &f, &res)) {
07204 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07205 ast_mutex_unlock(&iaxsl[fr->callno]);
07206 return 1;
07207 }
07208 #ifdef DEBUG_SUPPORT
07209 else if (iaxdebug)
07210 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07211 #endif
07212 }
07213
07214
07215 iaxs[fr->callno]->frames_received++;
07216
07217 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07218 f.subclass != IAX_COMMAND_TXCNT &&
07219 f.subclass != IAX_COMMAND_TXACC) {
07220 unsigned short new_peercallno;
07221
07222 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07223 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07224 if (iaxs[fr->callno]->peercallno) {
07225 remove_by_peercallno(iaxs[fr->callno]);
07226 }
07227 iaxs[fr->callno]->peercallno = new_peercallno;
07228 store_by_peercallno(iaxs[fr->callno]);
07229 }
07230 }
07231 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07232 if (option_debug && iaxdebug)
07233 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07234
07235 fr->oseqno = fh->oseqno;
07236 fr->iseqno = fh->iseqno;
07237 fr->ts = ntohl(fh->ts);
07238 #ifdef IAXTESTS
07239 if (test_resync) {
07240 if (option_debug)
07241 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07242 fr->ts += test_resync;
07243 }
07244 #endif
07245 #if 0
07246 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07247 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07248 (f.subclass == IAX_COMMAND_NEW ||
07249 f.subclass == IAX_COMMAND_AUTHREQ ||
07250 f.subclass == IAX_COMMAND_ACCEPT ||
07251 f.subclass == IAX_COMMAND_REJECT)) ) )
07252 #endif
07253 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07254 updatehistory = 0;
07255 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07256 (iaxs[fr->callno]->iseqno ||
07257 ((f.subclass != IAX_COMMAND_TXCNT) &&
07258 (f.subclass != IAX_COMMAND_TXREADY) &&
07259 (f.subclass != IAX_COMMAND_TXREL) &&
07260 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
07261 (f.subclass != IAX_COMMAND_TXACC)) ||
07262 (f.frametype != AST_FRAME_IAX))) {
07263 if (
07264 ((f.subclass != IAX_COMMAND_ACK) &&
07265 (f.subclass != IAX_COMMAND_INVAL) &&
07266 (f.subclass != IAX_COMMAND_TXCNT) &&
07267 (f.subclass != IAX_COMMAND_TXREADY) &&
07268 (f.subclass != IAX_COMMAND_TXREL) &&
07269 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
07270 (f.subclass != IAX_COMMAND_TXACC) &&
07271 (f.subclass != IAX_COMMAND_VNAK)) ||
07272 (f.frametype != AST_FRAME_IAX)) {
07273
07274 if (option_debug)
07275 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
07276 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07277
07278
07279 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07280
07281 if ((f.frametype != AST_FRAME_IAX) ||
07282 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07283 if (option_debug)
07284 ast_log(LOG_DEBUG, "Acking anyway\n");
07285
07286
07287 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07288 }
07289 } else {
07290
07291 iax2_vnak(fr->callno);
07292 }
07293 ast_mutex_unlock(&iaxsl[fr->callno]);
07294 return 1;
07295 }
07296 } else {
07297
07298 if (((f.subclass != IAX_COMMAND_ACK) &&
07299 (f.subclass != IAX_COMMAND_INVAL) &&
07300 (f.subclass != IAX_COMMAND_TXCNT) &&
07301 (f.subclass != IAX_COMMAND_TXACC) &&
07302 (f.subclass != IAX_COMMAND_VNAK)) ||
07303 (f.frametype != AST_FRAME_IAX))
07304 iaxs[fr->callno]->iseqno++;
07305 }
07306
07307 if (res < sizeof(*fh)) {
07308 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07309 ast_mutex_unlock(&iaxsl[fr->callno]);
07310 return 1;
07311 }
07312
07313 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07314 if (res < thread->buf_size)
07315 thread->buf[res++] = '\0';
07316 else
07317 thread->buf[res - 1] = '\0';
07318 }
07319 f.datalen = res - sizeof(*fh);
07320
07321
07322
07323 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
07324 ((f.subclass != IAX_COMMAND_INVAL) ||
07325 (f.frametype != AST_FRAME_IAX))) {
07326 unsigned char x;
07327 int call_to_destroy;
07328
07329
07330
07331 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07332 if (fr->iseqno == x)
07333 break;
07334 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07335
07336
07337 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07338
07339 if (option_debug && iaxdebug)
07340 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07341 call_to_destroy = 0;
07342 AST_LIST_LOCK(&iaxq.queue);
07343 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07344
07345 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07346 cur->retries = -1;
07347
07348 if (cur->final)
07349 call_to_destroy = fr->callno;
07350 }
07351 }
07352 AST_LIST_UNLOCK(&iaxq.queue);
07353 if (call_to_destroy) {
07354 if (iaxdebug && option_debug)
07355 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07356 ast_mutex_lock(&iaxsl[call_to_destroy]);
07357 iax2_destroy(call_to_destroy);
07358 ast_mutex_unlock(&iaxsl[call_to_destroy]);
07359 }
07360 }
07361
07362 if (iaxs[fr->callno])
07363 iaxs[fr->callno]->rseqno = fr->iseqno;
07364 else {
07365
07366 ast_mutex_unlock(&iaxsl[fr->callno]);
07367 return 1;
07368 }
07369 } else if (option_debug)
07370 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07371 }
07372 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
07373 ((f.frametype != AST_FRAME_IAX) ||
07374 ((f.subclass != IAX_COMMAND_TXACC) &&
07375 (f.subclass != IAX_COMMAND_TXCNT)))) {
07376
07377 ast_mutex_unlock(&iaxsl[fr->callno]);
07378 return 1;
07379 }
07380
07381 if (f.datalen) {
07382 if (f.frametype == AST_FRAME_IAX) {
07383 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07384 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07385 ast_mutex_unlock(&iaxsl[fr->callno]);
07386 return 1;
07387 }
07388 f.data = NULL;
07389 f.datalen = 0;
07390 } else
07391 f.data = thread->buf + sizeof(*fh);
07392 } else {
07393 if (f.frametype == AST_FRAME_IAX)
07394 f.data = NULL;
07395 else
07396 f.data = empty;
07397 memset(&ies, 0, sizeof(ies));
07398 }
07399
07400
07401
07402
07403 if ((f.frametype == AST_FRAME_VOICE) ||
07404 (f.frametype == AST_FRAME_VIDEO) ||
07405 (f.frametype == AST_FRAME_IAX)) {
07406 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07407 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07408 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07409 ast_mutex_unlock(&iaxsl[fr->callno]);
07410 return 1;
07411 }
07412 }
07413 }
07414
07415 if (f.frametype == AST_FRAME_VOICE) {
07416 if (f.subclass != iaxs[fr->callno]->voiceformat) {
07417 iaxs[fr->callno]->voiceformat = f.subclass;
07418 if (option_debug)
07419 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07420 if (iaxs[fr->callno]->owner) {
07421 int orignative;
07422 retryowner:
07423 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07424 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07425 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07426 }
07427 if (iaxs[fr->callno]) {
07428 if (iaxs[fr->callno]->owner) {
07429 orignative = iaxs[fr->callno]->owner->nativeformats;
07430 iaxs[fr->callno]->owner->nativeformats = f.subclass;
07431 if (iaxs[fr->callno]->owner->readformat)
07432 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07433 iaxs[fr->callno]->owner->nativeformats = orignative;
07434 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07435 }
07436 } else {
07437 if (option_debug)
07438 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07439 ast_mutex_unlock(&iaxsl[fr->callno]);
07440 return 1;
07441 }
07442 }
07443 }
07444 }
07445 if (f.frametype == AST_FRAME_VIDEO) {
07446 if (f.subclass != iaxs[fr->callno]->videoformat) {
07447 if (option_debug)
07448 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07449 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07450 }
07451 }
07452 if (f.frametype == AST_FRAME_IAX) {
07453 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07454
07455 if (option_debug && iaxdebug)
07456 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07457
07458
07459 if (iaxs[fr->callno]->last < fr->ts &&
07460 f.subclass != IAX_COMMAND_ACK &&
07461 f.subclass != IAX_COMMAND_PONG &&
07462 f.subclass != IAX_COMMAND_LAGRP) {
07463 iaxs[fr->callno]->last = fr->ts;
07464 if (option_debug && iaxdebug)
07465 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07466 }
07467
07468 switch(f.subclass) {
07469 case IAX_COMMAND_ACK:
07470
07471 break;
07472 case IAX_COMMAND_QUELCH:
07473 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07474
07475 if (iaxs[fr->callno]->owner) {
07476 manager_event(EVENT_FLAG_CALL, "Hold",
07477 "Channel: %s\r\n"
07478 "Uniqueid: %s\r\n",
07479 iaxs[fr->callno]->owner->name,
07480 iaxs[fr->callno]->owner->uniqueid);
07481 }
07482
07483 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07484 if (ies.musiconhold) {
07485 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07486 const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07487 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
07488 S_OR(mohsuggest, NULL),
07489 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07490 if (!iaxs[fr->callno]) {
07491 ast_mutex_unlock(&iaxsl[fr->callno]);
07492 return 1;
07493 }
07494 }
07495 }
07496 }
07497 break;
07498 case IAX_COMMAND_UNQUELCH:
07499 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07500
07501 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07502 manager_event(EVENT_FLAG_CALL, "Unhold",
07503 "Channel: %s\r\n"
07504 "Uniqueid: %s\r\n",
07505 iaxs[fr->callno]->owner->name,
07506 iaxs[fr->callno]->owner->uniqueid);
07507 }
07508
07509 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07510 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07511 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07512 if (!iaxs[fr->callno]) {
07513 ast_mutex_unlock(&iaxsl[fr->callno]);
07514 return 1;
07515 }
07516 }
07517 }
07518 break;
07519 case IAX_COMMAND_TXACC:
07520 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07521
07522 AST_LIST_LOCK(&iaxq.queue);
07523 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07524
07525 if ((fr->callno == cur->callno) && (cur->transfer))
07526 cur->retries = -1;
07527 }
07528 AST_LIST_UNLOCK(&iaxq.queue);
07529 memset(&ied1, 0, sizeof(ied1));
07530 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07531 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07532 iaxs[fr->callno]->transferring = TRANSFER_READY;
07533 }
07534 break;
07535 case IAX_COMMAND_NEW:
07536
07537 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07538 break;
07539 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07540 ast_mutex_unlock(&iaxsl[fr->callno]);
07541 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07542 ast_mutex_lock(&iaxsl[fr->callno]);
07543 if (!iaxs[fr->callno]) {
07544 ast_mutex_unlock(&iaxsl[fr->callno]);
07545 return 1;
07546 }
07547 }
07548
07549 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07550 int new_callno;
07551 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07552 fr->callno = new_callno;
07553 }
07554
07555 if (delayreject)
07556 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07557 if (check_access(fr->callno, &sin, &ies)) {
07558
07559 auth_fail(fr->callno, IAX_COMMAND_REJECT);
07560 if (authdebug)
07561 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
07562 break;
07563 }
07564 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07565 const char *context, *exten, *cid_num;
07566
07567 context = ast_strdupa(iaxs[fr->callno]->context);
07568 exten = ast_strdupa(iaxs[fr->callno]->exten);
07569 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07570
07571
07572 ast_mutex_unlock(&iaxsl[fr->callno]);
07573 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07574 ast_mutex_lock(&iaxsl[fr->callno]);
07575
07576 if (!iaxs[fr->callno]) {
07577 ast_mutex_unlock(&iaxsl[fr->callno]);
07578 return 1;
07579 }
07580 } else
07581 exists = 0;
07582 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07583 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07584 memset(&ied0, 0, sizeof(ied0));
07585 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07586 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07587 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07588 if (!iaxs[fr->callno]) {
07589 ast_mutex_unlock(&iaxsl[fr->callno]);
07590 return 1;
07591 }
07592 if (authdebug)
07593 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
07594 } else {
07595
07596
07597 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07598 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07599 using_prefs = "reqonly";
07600 } else {
07601 using_prefs = "disabled";
07602 }
07603 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07604 memset(&pref, 0, sizeof(pref));
07605 strcpy(caller_pref_buf, "disabled");
07606 strcpy(host_pref_buf, "disabled");
07607 } else {
07608 using_prefs = "mine";
07609
07610 if (ies.codec_prefs)
07611 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07612 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07613
07614 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07615 pref = iaxs[fr->callno]->rprefs;
07616 using_prefs = "caller";
07617 } else {
07618 pref = iaxs[fr->callno]->prefs;
07619 }
07620 } else
07621 pref = iaxs[fr->callno]->prefs;
07622
07623 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07624 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07625 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07626 }
07627 if (!format) {
07628 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07629 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07630 if (!format) {
07631 memset(&ied0, 0, sizeof(ied0));
07632 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07633 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07634 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07635 if (!iaxs[fr->callno]) {
07636 ast_mutex_unlock(&iaxsl[fr->callno]);
07637 return 1;
07638 }
07639 if (authdebug) {
07640 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07641 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
07642 else
07643 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
07644 }
07645 } else {
07646
07647 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07648 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07649 format = 0;
07650 } else {
07651 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07652 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07653 memset(&pref, 0, sizeof(pref));
07654 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07655 strcpy(caller_pref_buf,"disabled");
07656 strcpy(host_pref_buf,"disabled");
07657 } else {
07658 using_prefs = "mine";
07659 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07660
07661 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07662 pref = iaxs[fr->callno]->prefs;
07663 } else {
07664 pref = iaxs[fr->callno]->rprefs;
07665 using_prefs = "caller";
07666 }
07667 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07668
07669 } else
07670 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07671 }
07672 }
07673
07674 if (!format) {
07675 memset(&ied0, 0, sizeof(ied0));
07676 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07677 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07678 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07679 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07680 if (!iaxs[fr->callno]) {
07681 ast_mutex_unlock(&iaxsl[fr->callno]);
07682 return 1;
07683 }
07684 if (authdebug)
07685 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
07686 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07687 break;
07688 }
07689 }
07690 }
07691 if (format) {
07692
07693 memset(&ied1, 0, sizeof(ied1));
07694 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07695 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07696 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07697 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07698 if (option_verbose > 2)
07699 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07700 "%srequested format = %s,\n"
07701 "%srequested prefs = %s,\n"
07702 "%sactual format = %s,\n"
07703 "%shost prefs = %s,\n"
07704 "%spriority = %s\n",
07705 ast_inet_ntoa(sin.sin_addr),
07706 VERBOSE_PREFIX_4,
07707 ast_getformatname(iaxs[fr->callno]->peerformat),
07708 VERBOSE_PREFIX_4,
07709 caller_pref_buf,
07710 VERBOSE_PREFIX_4,
07711 ast_getformatname(format),
07712 VERBOSE_PREFIX_4,
07713 host_pref_buf,
07714 VERBOSE_PREFIX_4,
07715 using_prefs);
07716
07717 iaxs[fr->callno]->chosenformat = format;
07718 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07719 } else {
07720 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07721
07722 if (option_verbose > 2)
07723 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07724 }
07725 }
07726 }
07727 break;
07728 }
07729 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07730 merge_encryption(iaxs[fr->callno],ies.encmethods);
07731 else
07732 iaxs[fr->callno]->encmethods = 0;
07733 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07734 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07735 if (!iaxs[fr->callno]) {
07736 ast_mutex_unlock(&iaxsl[fr->callno]);
07737 return 1;
07738 }
07739 break;
07740 case IAX_COMMAND_DPREQ:
07741
07742 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07743 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07744 if (iaxcompat) {
07745
07746 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07747 } else {
07748
07749 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07750 }
07751 }
07752 break;
07753 case IAX_COMMAND_HANGUP:
07754 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07755 if (option_debug)
07756 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07757
07758 if (ies.causecode && iaxs[fr->callno]->owner)
07759 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07760
07761 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07762 iax2_destroy(fr->callno);
07763 break;
07764 case IAX_COMMAND_REJECT:
07765
07766 if (ies.causecode && iaxs[fr->callno]->owner)
07767 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07768
07769 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07770 if (iaxs[fr->callno]->owner && authdebug)
07771 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07772 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07773 ies.cause ? ies.cause : "<Unknown>");
07774 if (option_debug)
07775 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07776 fr->callno);
07777 }
07778
07779 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07780 fr->ts, NULL, 0, fr->iseqno);
07781 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07782 iaxs[fr->callno]->error = EPERM;
07783 iax2_destroy(fr->callno);
07784 break;
07785 case IAX_COMMAND_TRANSFER:
07786 {
07787 struct ast_channel *bridged_chan;
07788
07789 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
07790
07791
07792 ast_mutex_unlock(&iaxsl[fr->callno]);
07793 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
07794 ast_mutex_lock(&iaxsl[fr->callno]);
07795 if (!iaxs[fr->callno]) {
07796 ast_mutex_unlock(&iaxsl[fr->callno]);
07797 return 1;
07798 }
07799
07800 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07801 if (!strcmp(ies.called_number, ast_parking_ext())) {
07802 if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) {
07803 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
07804 } else {
07805 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
07806 }
07807 } else {
07808 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
07809 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
07810 ies.called_number, iaxs[fr->callno]->context);
07811 else
07812 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
07813 ies.called_number, iaxs[fr->callno]->context);
07814 }
07815 } else
07816 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07817
07818 break;
07819 }
07820 case IAX_COMMAND_ACCEPT:
07821
07822 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07823 break;
07824 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07825
07826 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07827 iax2_destroy(fr->callno);
07828 break;
07829 }
07830 if (ies.format) {
07831 iaxs[fr->callno]->peerformat = ies.format;
07832 } else {
07833 if (iaxs[fr->callno]->owner)
07834 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07835 else
07836 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07837 }
07838 if (option_verbose > 2)
07839 ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
07840 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07841 memset(&ied0, 0, sizeof(ied0));
07842 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07843 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07844 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07845 if (!iaxs[fr->callno]) {
07846 ast_mutex_unlock(&iaxsl[fr->callno]);
07847 return 1;
07848 }
07849 if (authdebug)
07850 ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
07851 } else {
07852 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07853 if (iaxs[fr->callno]->owner) {
07854
07855 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07856 if (option_verbose > 2)
07857 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07858 retryowner2:
07859 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07860 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07861 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07862 }
07863
07864 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07865
07866 if (iaxs[fr->callno]->owner->writeformat)
07867 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
07868 if (iaxs[fr->callno]->owner->readformat)
07869 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07870 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07871 }
07872 }
07873 }
07874 if (iaxs[fr->callno]) {
07875 ast_mutex_lock(&dpcache_lock);
07876 dp = iaxs[fr->callno]->dpentries;
07877 while(dp) {
07878 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07879 iax2_dprequest(dp, fr->callno);
07880 }
07881 dp = dp->peer;
07882 }
07883 ast_mutex_unlock(&dpcache_lock);
07884 }
07885 break;
07886 case IAX_COMMAND_POKE:
07887
07888 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07889 if (!iaxs[fr->callno]) {
07890 ast_mutex_unlock(&iaxsl[fr->callno]);
07891 return 1;
07892 }
07893 break;
07894 case IAX_COMMAND_PING:
07895 {
07896 struct iax_ie_data pingied;
07897 construct_rr(iaxs[fr->callno], &pingied);
07898
07899 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07900 }
07901 break;
07902 case IAX_COMMAND_PONG:
07903
07904 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07905
07906 save_rr(fr, &ies);
07907
07908 if (iaxs[fr->callno]->peerpoke) {
07909 peer = iaxs[fr->callno]->peerpoke;
07910 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
07911 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07912 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07913 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
07914 ast_device_state_changed("IAX2/%s", peer->name);
07915 }
07916 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07917 if (iaxs[fr->callno]->pingtime > peer->maxms) {
07918 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07919 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
07920 ast_device_state_changed("IAX2/%s", peer->name);
07921 }
07922 }
07923 peer->lastms = iaxs[fr->callno]->pingtime;
07924 if (peer->smoothing && (peer->lastms > -1))
07925 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07926 else if (peer->smoothing && peer->lastms < 0)
07927 peer->historicms = (0 + peer->historicms) / 2;
07928 else
07929 peer->historicms = iaxs[fr->callno]->pingtime;
07930
07931
07932 if (peer->pokeexpire > -1) {
07933 if (!ast_sched_del(sched, peer->pokeexpire)) {
07934 peer_unref(peer);
07935 peer->pokeexpire = -1;
07936 }
07937 }
07938
07939 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
07940 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
07941 else
07942 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
07943 if (peer->pokeexpire == -1)
07944 peer_unref(peer);
07945
07946 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07947
07948 iax2_destroy(fr->callno);
07949 peer->callno = 0;
07950 if (option_debug)
07951 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
07952 }
07953 break;
07954 case IAX_COMMAND_LAGRQ:
07955 case IAX_COMMAND_LAGRP:
07956 f.src = "LAGRQ";
07957 f.mallocd = 0;
07958 f.offset = 0;
07959 f.samples = 0;
07960 iax_frame_wrap(fr, &f);
07961 if(f.subclass == IAX_COMMAND_LAGRQ) {
07962
07963 fr->af.subclass = IAX_COMMAND_LAGRP;
07964 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07965 } else {
07966
07967 unsigned int ts;
07968
07969 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07970 iaxs[fr->callno]->lag = ts - fr->ts;
07971 if (option_debug && iaxdebug)
07972 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07973 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07974 }
07975 break;
07976 case IAX_COMMAND_AUTHREQ:
07977 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07978 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07979 break;
07980 }
07981 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07982 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
07983 .subclass = AST_CONTROL_HANGUP,
07984 };
07985 ast_log(LOG_WARNING,
07986 "I don't know how to authenticate %s to %s\n",
07987 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
07988 iax2_queue_frame(fr->callno, &hangup_fr);
07989 }
07990 if (!iaxs[fr->callno]) {
07991 ast_mutex_unlock(&iaxsl[fr->callno]);
07992 return 1;
07993 }
07994 break;
07995 case IAX_COMMAND_AUTHREP:
07996
07997 if (delayreject)
07998 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07999
08000 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08001 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08002 break;
08003 }
08004 if (authenticate_verify(iaxs[fr->callno], &ies)) {
08005 if (authdebug)
08006 ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username);
08007 memset(&ied0, 0, sizeof(ied0));
08008 auth_fail(fr->callno, IAX_COMMAND_REJECT);
08009 break;
08010 }
08011 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08012
08013 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08014 } else
08015 exists = 0;
08016 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08017 if (authdebug)
08018 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
08019 memset(&ied0, 0, sizeof(ied0));
08020 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08021 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08022 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08023 if (!iaxs[fr->callno]) {
08024 ast_mutex_unlock(&iaxsl[fr->callno]);
08025 return 1;
08026 }
08027 } else {
08028
08029 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08030 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08031 using_prefs = "reqonly";
08032 } else {
08033 using_prefs = "disabled";
08034 }
08035 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08036 memset(&pref, 0, sizeof(pref));
08037 strcpy(caller_pref_buf, "disabled");
08038 strcpy(host_pref_buf, "disabled");
08039 } else {
08040 using_prefs = "mine";
08041 if (ies.codec_prefs)
08042 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08043 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08044 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08045 pref = iaxs[fr->callno]->rprefs;
08046 using_prefs = "caller";
08047 } else {
08048 pref = iaxs[fr->callno]->prefs;
08049 }
08050 } else
08051 pref = iaxs[fr->callno]->prefs;
08052
08053 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08054 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08055 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08056 }
08057 if (!format) {
08058 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08059 if (option_debug)
08060 ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
08061 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08062 }
08063 if (!format) {
08064 if (authdebug) {
08065 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08066 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
08067 else
08068 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
08069 }
08070 memset(&ied0, 0, sizeof(ied0));
08071 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08072 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08073 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08074 if (!iaxs[fr->callno]) {
08075 ast_mutex_unlock(&iaxsl[fr->callno]);
08076 return 1;
08077 }
08078 } else {
08079
08080 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08081 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08082 format = 0;
08083 } else {
08084 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08085 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08086 memset(&pref, 0, sizeof(pref));
08087 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08088 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08089 strcpy(caller_pref_buf,"disabled");
08090 strcpy(host_pref_buf,"disabled");
08091 } else {
08092 using_prefs = "mine";
08093 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08094
08095 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08096 pref = iaxs[fr->callno]->prefs;
08097 } else {
08098 pref = iaxs[fr->callno]->rprefs;
08099 using_prefs = "caller";
08100 }
08101 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08102 } else
08103 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08104 }
08105 }
08106 if (!format) {
08107 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08108 if (authdebug) {
08109 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08110 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
08111 else
08112 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
08113 }
08114 memset(&ied0, 0, sizeof(ied0));
08115 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08116 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08117 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08118 if (!iaxs[fr->callno]) {
08119 ast_mutex_unlock(&iaxsl[fr->callno]);
08120 return 1;
08121 }
08122 }
08123 }
08124 }
08125 if (format) {
08126
08127 memset(&ied1, 0, sizeof(ied1));
08128 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08129 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08130 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08131 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08132 if (option_verbose > 2)
08133 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08134 "%srequested format = %s,\n"
08135 "%srequested prefs = %s,\n"
08136 "%sactual format = %s,\n"
08137 "%shost prefs = %s,\n"
08138 "%spriority = %s\n",
08139 ast_inet_ntoa(sin.sin_addr),
08140 VERBOSE_PREFIX_4,
08141 ast_getformatname(iaxs[fr->callno]->peerformat),
08142 VERBOSE_PREFIX_4,
08143 caller_pref_buf,
08144 VERBOSE_PREFIX_4,
08145 ast_getformatname(format),
08146 VERBOSE_PREFIX_4,
08147 host_pref_buf,
08148 VERBOSE_PREFIX_4,
08149 using_prefs);
08150
08151 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08152 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08153 iax2_destroy(fr->callno);
08154 } else {
08155 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08156
08157 if (option_verbose > 2)
08158 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08159 }
08160 }
08161 }
08162 break;
08163 case IAX_COMMAND_DIAL:
08164 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08165 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08166 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08167 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08168 if (authdebug)
08169 ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
08170 memset(&ied0, 0, sizeof(ied0));
08171 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08172 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08173 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08174 if (!iaxs[fr->callno]) {
08175 ast_mutex_unlock(&iaxsl[fr->callno]);
08176 return 1;
08177 }
08178 } else {
08179 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08180 if (option_verbose > 2)
08181 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08182 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08183 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08184 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08185 iax2_destroy(fr->callno);
08186 }
08187 }
08188 break;
08189 case IAX_COMMAND_INVAL:
08190 iaxs[fr->callno]->error = ENOTCONN;
08191 if (option_debug)
08192 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08193 iax2_destroy(fr->callno);
08194 if (option_debug)
08195 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08196 break;
08197 case IAX_COMMAND_VNAK:
08198 if (option_debug)
08199 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08200
08201 vnak_retransmit(fr->callno, fr->iseqno);
08202 break;
08203 case IAX_COMMAND_REGREQ:
08204 case IAX_COMMAND_REGREL:
08205
08206 if (delayreject)
08207 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08208 if (register_verify(fr->callno, &sin, &ies)) {
08209 if (!iaxs[fr->callno]) {
08210 ast_mutex_unlock(&iaxsl[fr->callno]);
08211 return 1;
08212 }
08213
08214 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08215 break;
08216 }
08217 if (!iaxs[fr->callno]) {
08218 ast_mutex_unlock(&iaxsl[fr->callno]);
08219 return 1;
08220 }
08221 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
08222 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
08223 if (f.subclass == IAX_COMMAND_REGREL)
08224 memset(&sin, 0, sizeof(sin));
08225 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08226 ast_log(LOG_WARNING, "Registry error\n");
08227 if (!iaxs[fr->callno]) {
08228 ast_mutex_unlock(&iaxsl[fr->callno]);
08229 return 1;
08230 }
08231 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08232 ast_mutex_unlock(&iaxsl[fr->callno]);
08233 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08234 ast_mutex_lock(&iaxsl[fr->callno]);
08235 if (!iaxs[fr->callno]) {
08236 ast_mutex_unlock(&iaxsl[fr->callno]);
08237 return 1;
08238 }
08239 }
08240 break;
08241 }
08242 registry_authrequest(fr->callno);
08243 if (!iaxs[fr->callno]) {
08244 ast_mutex_unlock(&iaxsl[fr->callno]);
08245 return 1;
08246 }
08247 break;
08248 case IAX_COMMAND_REGACK:
08249 if (iax2_ack_registry(&ies, &sin, fr->callno))
08250 ast_log(LOG_WARNING, "Registration failure\n");
08251
08252 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08253 iax2_destroy(fr->callno);
08254 break;
08255 case IAX_COMMAND_REGREJ:
08256 if (iaxs[fr->callno]->reg) {
08257 if (authdebug) {
08258 ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(sin.sin_addr));
08259 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
08260 }
08261 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08262 }
08263
08264 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08265 iax2_destroy(fr->callno);
08266 break;
08267 case IAX_COMMAND_REGAUTH:
08268
08269 if (registry_rerequest(&ies, fr->callno, &sin)) {
08270 memset(&ied0, 0, sizeof(ied0));
08271 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08272 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08273 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08274 if (!iaxs[fr->callno]) {
08275 ast_mutex_unlock(&iaxsl[fr->callno]);
08276 return 1;
08277 }
08278 }
08279 break;
08280 case IAX_COMMAND_TXREJ:
08281 iaxs[fr->callno]->transferring = 0;
08282 if (option_verbose > 2)
08283 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08284 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08285 if (iaxs[fr->callno]->bridgecallno) {
08286 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08287 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08288 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08289 }
08290 }
08291 break;
08292 case IAX_COMMAND_TXREADY:
08293 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08294 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08295 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08296 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08297 else
08298 iaxs[fr->callno]->transferring = TRANSFER_READY;
08299 if (option_verbose > 2)
08300 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08301 if (iaxs[fr->callno]->bridgecallno) {
08302 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08303 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08304
08305 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08306 if (option_verbose > 2)
08307 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08308 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08309
08310 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08311 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08312
08313 memset(&ied0, 0, sizeof(ied0));
08314 memset(&ied1, 0, sizeof(ied1));
08315 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08316 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08317 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08318 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08319 } else {
08320 if (option_verbose > 2)
08321 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08322 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08323
08324 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08325 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08326 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08327 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08328
08329
08330 stop_stuff(fr->callno);
08331 stop_stuff(iaxs[fr->callno]->bridgecallno);
08332
08333 memset(&ied0, 0, sizeof(ied0));
08334 memset(&ied1, 0, sizeof(ied1));
08335 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08336 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08337 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08338 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08339 }
08340
08341 }
08342 }
08343 }
08344 break;
08345 case IAX_COMMAND_TXREQ:
08346 try_transfer(iaxs[fr->callno], &ies);
08347 break;
08348 case IAX_COMMAND_TXCNT:
08349 if (iaxs[fr->callno]->transferring)
08350 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08351 break;
08352 case IAX_COMMAND_TXREL:
08353
08354 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08355 complete_transfer(fr->callno, &ies);
08356 stop_stuff(fr->callno);
08357 break;
08358 case IAX_COMMAND_TXMEDIA:
08359 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08360 AST_LIST_LOCK(&iaxq.queue);
08361 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08362
08363 if ((fr->callno == cur->callno) && (cur->transfer)) {
08364 cur->retries = -1;
08365 }
08366 }
08367 AST_LIST_UNLOCK(&iaxq.queue);
08368
08369 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08370 }
08371 break;
08372 case IAX_COMMAND_DPREP:
08373 complete_dpreply(iaxs[fr->callno], &ies);
08374 break;
08375 case IAX_COMMAND_UNSUPPORT:
08376 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08377 break;
08378 case IAX_COMMAND_FWDOWNL:
08379
08380 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08381 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08382 break;
08383 }
08384 memset(&ied0, 0, sizeof(ied0));
08385 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08386 if (res < 0)
08387 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08388 else if (res > 0)
08389 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08390 else
08391 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08392 if (!iaxs[fr->callno]) {
08393 ast_mutex_unlock(&iaxsl[fr->callno]);
08394 return 1;
08395 }
08396 break;
08397 default:
08398 if (option_debug)
08399 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08400 memset(&ied0, 0, sizeof(ied0));
08401 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08402 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08403 }
08404
08405 if ((f.subclass != IAX_COMMAND_ACK) &&
08406 (f.subclass != IAX_COMMAND_TXCNT) &&
08407 (f.subclass != IAX_COMMAND_TXACC) &&
08408 (f.subclass != IAX_COMMAND_INVAL) &&
08409 (f.subclass != IAX_COMMAND_VNAK)) {
08410 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08411 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08412 }
08413 ast_mutex_unlock(&iaxsl[fr->callno]);
08414 return 1;
08415 }
08416
08417 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08418 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08419 } else if (minivid) {
08420 f.frametype = AST_FRAME_VIDEO;
08421 if (iaxs[fr->callno]->videoformat > 0)
08422 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08423 else {
08424 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
08425 iax2_vnak(fr->callno);
08426 ast_mutex_unlock(&iaxsl[fr->callno]);
08427 return 1;
08428 }
08429 f.datalen = res - sizeof(*vh);
08430 if (f.datalen)
08431 f.data = thread->buf + sizeof(*vh);
08432 else
08433 f.data = NULL;
08434 #ifdef IAXTESTS
08435 if (test_resync) {
08436 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08437 } else
08438 #endif
08439 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08440 } else {
08441
08442 f.frametype = AST_FRAME_VOICE;
08443 if (iaxs[fr->callno]->voiceformat > 0)
08444 f.subclass = iaxs[fr->callno]->voiceformat;
08445 else {
08446 if (option_debug)
08447 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08448 iax2_vnak(fr->callno);
08449 ast_mutex_unlock(&iaxsl[fr->callno]);
08450 return 1;
08451 }
08452 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08453 if (f.datalen < 0) {
08454 ast_log(LOG_WARNING, "Datalen < 0?\n");
08455 ast_mutex_unlock(&iaxsl[fr->callno]);
08456 return 1;
08457 }
08458 if (f.datalen)
08459 f.data = thread->buf + sizeof(*mh);
08460 else
08461 f.data = NULL;
08462 #ifdef IAXTESTS
08463 if (test_resync) {
08464 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08465 } else
08466 #endif
08467 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08468
08469 }
08470
08471 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08472 ast_mutex_unlock(&iaxsl[fr->callno]);
08473 return 1;
08474 }
08475
08476 f.src = "IAX2";
08477 f.mallocd = 0;
08478 f.offset = 0;
08479 f.len = 0;
08480 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08481 f.samples = ast_codec_get_samples(&f);
08482
08483 if (f.subclass == AST_FORMAT_SLINEAR)
08484 ast_frame_byteswap_be(&f);
08485 } else
08486 f.samples = 0;
08487 iax_frame_wrap(fr, &f);
08488
08489
08490 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08491
08492 fr->outoforder = 0;
08493 } else {
08494 if (option_debug && iaxdebug && iaxs[fr->callno])
08495 ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
08496 fr->outoforder = -1;
08497 }
08498 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08499 duped_fr = iaxfrdup2(fr);
08500 if (duped_fr) {
08501 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08502 }
08503 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08504 iaxs[fr->callno]->last = fr->ts;
08505 #if 1
08506 if (option_debug && iaxdebug)
08507 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08508 #endif
08509 }
08510
08511
08512 ast_mutex_unlock(&iaxsl[fr->callno]);
08513 return 1;
08514 }
08515
08516
08517 static void iax2_process_thread_cleanup(void *data)
08518 {
08519 struct iax2_thread *thread = data;
08520 ast_mutex_destroy(&thread->lock);
08521 ast_cond_destroy(&thread->cond);
08522 free(thread);
08523 ast_atomic_dec_and_test(&iaxactivethreadcount);
08524 }
08525
08526 static void *iax2_process_thread(void *data)
08527 {
08528 struct iax2_thread *thread = data;
08529 struct timeval tv;
08530 struct timespec ts;
08531 int put_into_idle = 0;
08532
08533 ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08534 pthread_cleanup_push(iax2_process_thread_cleanup, data);
08535 for(;;) {
08536
08537 ast_mutex_lock(&thread->lock);
08538
08539
08540 thread->ready_for_signal = 1;
08541
08542
08543 if (put_into_idle)
08544 insert_idle_thread(thread);
08545
08546 if (thread->type == IAX_TYPE_DYNAMIC) {
08547 struct iax2_thread *t = NULL;
08548
08549 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08550 ts.tv_sec = tv.tv_sec;
08551 ts.tv_nsec = tv.tv_usec * 1000;
08552 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08553
08554
08555 if (!put_into_idle) {
08556 ast_mutex_unlock(&thread->lock);
08557 break;
08558 }
08559 AST_LIST_LOCK(&dynamic_list);
08560
08561 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08562 iaxdynamicthreadcount--;
08563 AST_LIST_UNLOCK(&dynamic_list);
08564 if (t) {
08565
08566
08567
08568 ast_mutex_unlock(&thread->lock);
08569 break;
08570 }
08571
08572
08573
08574 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08575 ts.tv_sec = tv.tv_sec;
08576 ts.tv_nsec = tv.tv_usec * 1000;
08577 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08578 {
08579 ast_mutex_unlock(&thread->lock);
08580 break;
08581 }
08582 }
08583 } else {
08584 ast_cond_wait(&thread->cond, &thread->lock);
08585 }
08586
08587
08588 put_into_idle = 1;
08589
08590 ast_mutex_unlock(&thread->lock);
08591
08592 if (thread->iostate == IAX_IOSTATE_IDLE)
08593 continue;
08594
08595
08596 AST_LIST_LOCK(&active_list);
08597 AST_LIST_INSERT_HEAD(&active_list, thread, list);
08598 AST_LIST_UNLOCK(&active_list);
08599
08600
08601 switch(thread->iostate) {
08602 case IAX_IOSTATE_READY:
08603 thread->actions++;
08604 thread->iostate = IAX_IOSTATE_PROCESSING;
08605 socket_process(thread);
08606 handle_deferred_full_frames(thread);
08607 break;
08608 case IAX_IOSTATE_SCHEDREADY:
08609 thread->actions++;
08610 thread->iostate = IAX_IOSTATE_PROCESSING;
08611 #ifdef SCHED_MULTITHREADED
08612 thread->schedfunc(thread->scheddata);
08613 #endif
08614 break;
08615 }
08616 time(&thread->checktime);
08617 thread->iostate = IAX_IOSTATE_IDLE;
08618 #ifdef DEBUG_SCHED_MULTITHREAD
08619 thread->curfunc[0]='\0';
08620 #endif
08621
08622
08623 AST_LIST_LOCK(&active_list);
08624 AST_LIST_REMOVE(&active_list, thread, list);
08625 AST_LIST_UNLOCK(&active_list);
08626
08627
08628 handle_deferred_full_frames(thread);
08629 }
08630
08631
08632
08633
08634
08635 AST_LIST_LOCK(&idle_list);
08636 AST_LIST_REMOVE(&idle_list, thread, list);
08637 AST_LIST_UNLOCK(&idle_list);
08638
08639 AST_LIST_LOCK(&dynamic_list);
08640 AST_LIST_REMOVE(&dynamic_list, thread, list);
08641 AST_LIST_UNLOCK(&dynamic_list);
08642
08643
08644
08645
08646 pthread_cleanup_pop(1);
08647
08648 return NULL;
08649 }
08650
08651 static int iax2_do_register(struct iax2_registry *reg)
08652 {
08653 struct iax_ie_data ied;
08654 if (option_debug && iaxdebug)
08655 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08656
08657 if (reg->dnsmgr &&
08658 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08659
08660 ast_dnsmgr_refresh(reg->dnsmgr);
08661 }
08662
08663
08664
08665
08666
08667 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08668 ast_mutex_lock(&iaxsl[reg->callno]);
08669 iax2_destroy(reg->callno);
08670 ast_mutex_unlock(&iaxsl[reg->callno]);
08671 reg->callno = 0;
08672 }
08673 if (!reg->addr.sin_addr.s_addr) {
08674 if (option_debug && iaxdebug)
08675 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08676
08677 AST_SCHED_DEL(sched, reg->expire);
08678 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08679 return -1;
08680 }
08681
08682 if (!reg->callno) {
08683 if (option_debug)
08684 ast_log(LOG_DEBUG, "Allocate call number\n");
08685 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
08686 if (reg->callno < 1) {
08687 ast_log(LOG_WARNING, "Unable to create call for registration\n");
08688 return -1;
08689 } else if (option_debug)
08690 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08691 iaxs[reg->callno]->reg = reg;
08692 ast_mutex_unlock(&iaxsl[reg->callno]);
08693 }
08694
08695 AST_SCHED_DEL(sched, reg->expire);
08696
08697 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08698
08699 memset(&ied, 0, sizeof(ied));
08700 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08701 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08702 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08703 reg->regstate = REG_STATE_REGSENT;
08704 return 0;
08705 }
08706
08707 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08708 {
08709 if (pos != 3)
08710 return NULL;
08711 return iax_prov_complete_template(line, word, pos, state);
08712 }
08713
08714 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08715 {
08716
08717
08718 struct iax_ie_data provdata;
08719 struct iax_ie_data ied;
08720 unsigned int sig;
08721 struct sockaddr_in sin;
08722 int callno;
08723 struct create_addr_info cai;
08724
08725 memset(&cai, 0, sizeof(cai));
08726
08727 if (option_debug)
08728 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08729
08730 if (iax_provision_build(&provdata, &sig, template, force)) {
08731 if (option_debug)
08732 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08733 return 0;
08734 }
08735
08736 if (end) {
08737 memcpy(&sin, end, sizeof(sin));
08738 cai.sockfd = sockfd;
08739 } else if (create_addr(dest, NULL, &sin, &cai))
08740 return -1;
08741
08742
08743 memset(&ied, 0, sizeof(ied));
08744 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08745
08746 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08747 if (!callno)
08748 return -1;
08749
08750 if (iaxs[callno]) {
08751
08752 AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08753 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08754 ast_set_flag(iaxs[callno], IAX_PROVISION);
08755
08756 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08757 }
08758 ast_mutex_unlock(&iaxsl[callno]);
08759
08760 return 1;
08761 }
08762
08763 static char *papp = "IAX2Provision";
08764 static char *psyn = "Provision a calling IAXy with a given template";
08765 static char *pdescrip =
08766 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08767 "the calling entity is in fact an IAXy) with the given template or\n"
08768 "default if one is not specified. Returns -1 on error or 0 on success.\n";
08769
08770
08771
08772
08773 static int iax2_prov_app(struct ast_channel *chan, void *data)
08774 {
08775 int res;
08776 char *sdata;
08777 char *opts;
08778 int force =0;
08779 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08780 if (ast_strlen_zero(data))
08781 data = "default";
08782 sdata = ast_strdupa(data);
08783 opts = strchr(sdata, '|');
08784 if (opts)
08785 *opts='\0';
08786
08787 if (chan->tech != &iax2_tech) {
08788 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08789 return -1;
08790 }
08791 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08792 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08793 return -1;
08794 }
08795 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08796 if (option_verbose > 2)
08797 ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n",
08798 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08799 sdata, res);
08800 return res;
08801 }
08802
08803
08804 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08805 {
08806 int force = 0;
08807 int res;
08808 if (argc < 4)
08809 return RESULT_SHOWUSAGE;
08810 if ((argc > 4)) {
08811 if (!strcasecmp(argv[4], "forced"))
08812 force = 1;
08813 else
08814 return RESULT_SHOWUSAGE;
08815 }
08816 res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08817 if (res < 0)
08818 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08819 else if (res < 1)
08820 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08821 else
08822 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08823 return RESULT_SUCCESS;
08824 }
08825
08826 static void __iax2_poke_noanswer(const void *data)
08827 {
08828 struct iax2_peer *peer = (struct iax2_peer *)data;
08829 int callno;
08830
08831 if (peer->lastms > -1) {
08832 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08833 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08834 ast_device_state_changed("IAX2/%s", peer->name);
08835 }
08836 if ((callno = peer->callno) > 0) {
08837 ast_mutex_lock(&iaxsl[callno]);
08838 iax2_destroy(callno);
08839 ast_mutex_unlock(&iaxsl[callno]);
08840 }
08841 peer->callno = 0;
08842 peer->lastms = -1;
08843
08844 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08845 if (peer->pokeexpire == -1)
08846 peer_unref(peer);
08847 }
08848
08849 static int iax2_poke_noanswer(const void *data)
08850 {
08851 struct iax2_peer *peer = (struct iax2_peer *)data;
08852 peer->pokeexpire = -1;
08853 #ifdef SCHED_MULTITHREADED
08854 if (schedule_action(__iax2_poke_noanswer, data))
08855 #endif
08856 __iax2_poke_noanswer(data);
08857 peer_unref(peer);
08858 return 0;
08859 }
08860
08861 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
08862 {
08863 struct iax2_peer *peer = obj;
08864
08865 iax2_poke_peer(peer, 0);
08866
08867 return 0;
08868 }
08869
08870 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08871 {
08872 int callno;
08873 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
08874
08875
08876 peer->lastms = 0;
08877 peer->historicms = 0;
08878 peer->pokeexpire = -1;
08879 peer->callno = 0;
08880 return 0;
08881 }
08882
08883
08884 if ((callno = peer->callno) > 0) {
08885 ast_log(LOG_NOTICE, "Still have a callno...\n");
08886 ast_mutex_lock(&iaxsl[callno]);
08887 iax2_destroy(callno);
08888 ast_mutex_unlock(&iaxsl[callno]);
08889 }
08890 if (heldcall)
08891 ast_mutex_unlock(&iaxsl[heldcall]);
08892 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
08893 if (heldcall)
08894 ast_mutex_lock(&iaxsl[heldcall]);
08895 if (peer->callno < 1) {
08896 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08897 return -1;
08898 }
08899
08900
08901 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08902 iaxs[peer->callno]->peerpoke = peer;
08903
08904
08905 if (peer->pokeexpire > -1) {
08906 if (!ast_sched_del(sched, peer->pokeexpire)) {
08907 peer->pokeexpire = -1;
08908 peer_unref(peer);
08909 }
08910 }
08911
08912
08913
08914 if (peer->lastms < 0) {
08915 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
08916 } else
08917 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
08918
08919 if (peer->pokeexpire == -1)
08920 peer_unref(peer);
08921
08922
08923 ast_mutex_lock(&iaxsl[callno]);
08924 if (iaxs[callno]) {
08925 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08926 }
08927 ast_mutex_unlock(&iaxsl[callno]);
08928
08929 return 0;
08930 }
08931
08932 static void free_context(struct iax2_context *con)
08933 {
08934 struct iax2_context *conl;
08935 while(con) {
08936 conl = con;
08937 con = con->next;
08938 free(conl);
08939 }
08940 }
08941
08942 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
08943 {
08944 int callno;
08945 int res;
08946 int fmt, native;
08947 struct sockaddr_in sin;
08948 struct ast_channel *c;
08949 struct parsed_dial_string pds;
08950 struct create_addr_info cai;
08951 char *tmpstr;
08952
08953 memset(&pds, 0, sizeof(pds));
08954 tmpstr = ast_strdupa(data);
08955 parse_dial_string(tmpstr, &pds);
08956
08957 if (ast_strlen_zero(pds.peer)) {
08958 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
08959 return NULL;
08960 }
08961
08962 memset(&cai, 0, sizeof(cai));
08963 cai.capability = iax2_capability;
08964
08965 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08966
08967
08968 if (create_addr(pds.peer, NULL, &sin, &cai)) {
08969 *cause = AST_CAUSE_UNREGISTERED;
08970 return NULL;
08971 }
08972
08973 if (pds.port)
08974 sin.sin_port = htons(atoi(pds.port));
08975
08976 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08977 if (callno < 1) {
08978 ast_log(LOG_WARNING, "Unable to create call\n");
08979 *cause = AST_CAUSE_CONGESTION;
08980 return NULL;
08981 }
08982
08983
08984 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08985 if (ast_test_flag(&cai, IAX_TRUNK)) {
08986 int new_callno;
08987 if ((new_callno = make_trunk(callno, 1)) != -1)
08988 callno = new_callno;
08989 }
08990 iaxs[callno]->maxtime = cai.maxtime;
08991 if (cai.found)
08992 ast_string_field_set(iaxs[callno], host, pds.peer);
08993
08994 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08995
08996 ast_mutex_unlock(&iaxsl[callno]);
08997
08998 if (c) {
08999
09000 if (c->nativeformats & format)
09001 c->nativeformats &= format;
09002 else {
09003 native = c->nativeformats;
09004 fmt = format;
09005 res = ast_translator_best_choice(&fmt, &native);
09006 if (res < 0) {
09007 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09008 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09009 ast_hangup(c);
09010 return NULL;
09011 }
09012 c->nativeformats = native;
09013 }
09014 c->readformat = ast_best_codec(c->nativeformats);
09015 c->writeformat = c->readformat;
09016 }
09017
09018 return c;
09019 }
09020
09021 static void *sched_thread(void *ignore)
09022 {
09023 int count;
09024 int res;
09025 struct timeval tv;
09026 struct timespec ts;
09027
09028 for (;;) {
09029 res = ast_sched_wait(sched);
09030 if ((res > 1000) || (res < 0))
09031 res = 1000;
09032 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
09033 ts.tv_sec = tv.tv_sec;
09034 ts.tv_nsec = tv.tv_usec * 1000;
09035
09036 pthread_testcancel();
09037 ast_mutex_lock(&sched_lock);
09038 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09039 ast_mutex_unlock(&sched_lock);
09040 pthread_testcancel();
09041
09042 count = ast_sched_runq(sched);
09043 if (option_debug && count >= 20)
09044 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09045 }
09046 return NULL;
09047 }
09048
09049 static void *network_thread(void *ignore)
09050 {
09051
09052
09053 int res, count, wakeup;
09054 struct iax_frame *f;
09055
09056 if (timingfd > -1)
09057 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09058
09059 for(;;) {
09060 pthread_testcancel();
09061
09062
09063
09064 AST_LIST_LOCK(&iaxq.queue);
09065 count = 0;
09066 wakeup = -1;
09067 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09068 if (f->sentyet)
09069 continue;
09070
09071
09072 if (ast_mutex_trylock(&iaxsl[f->callno])) {
09073 wakeup = 1;
09074 continue;
09075 }
09076
09077 f->sentyet++;
09078
09079 if (iaxs[f->callno]) {
09080 send_packet(f);
09081 count++;
09082 }
09083
09084 ast_mutex_unlock(&iaxsl[f->callno]);
09085
09086 if (f->retries < 0) {
09087
09088 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09089 iaxq.count--;
09090
09091 iax_frame_free(f);
09092 } else {
09093
09094 f->retries++;
09095 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09096 }
09097 }
09098 AST_LIST_TRAVERSE_SAFE_END
09099 AST_LIST_UNLOCK(&iaxq.queue);
09100
09101 pthread_testcancel();
09102
09103 if (option_debug && count >= 20)
09104 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09105
09106
09107 res = ast_io_wait(io, wakeup);
09108 if (res >= 0) {
09109 if (option_debug && res >= 20)
09110 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09111 }
09112 }
09113 return NULL;
09114 }
09115
09116 static int start_network_thread(void)
09117 {
09118 pthread_attr_t attr;
09119 int threadcount = 0;
09120 int x;
09121 for (x = 0; x < iaxthreadcount; x++) {
09122 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09123 if (thread) {
09124 thread->type = IAX_TYPE_POOL;
09125 thread->threadnum = ++threadcount;
09126 ast_mutex_init(&thread->lock);
09127 ast_cond_init(&thread->cond, NULL);
09128 pthread_attr_init(&attr);
09129 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
09130 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09131 ast_log(LOG_WARNING, "Failed to create new thread!\n");
09132 free(thread);
09133 thread = NULL;
09134 }
09135 AST_LIST_LOCK(&idle_list);
09136 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09137 AST_LIST_UNLOCK(&idle_list);
09138 }
09139 }
09140 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09141 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09142 if (option_verbose > 1)
09143 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
09144 return 0;
09145 }
09146
09147 static struct iax2_context *build_context(char *context)
09148 {
09149 struct iax2_context *con;
09150
09151 if ((con = ast_calloc(1, sizeof(*con))))
09152 ast_copy_string(con->context, context, sizeof(con->context));
09153
09154 return con;
09155 }
09156
09157 static int get_auth_methods(char *value)
09158 {
09159 int methods = 0;
09160 if (strstr(value, "rsa"))
09161 methods |= IAX_AUTH_RSA;
09162 if (strstr(value, "md5"))
09163 methods |= IAX_AUTH_MD5;
09164 if (strstr(value, "plaintext"))
09165 methods |= IAX_AUTH_PLAINTEXT;
09166 return methods;
09167 }
09168
09169
09170
09171
09172
09173 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09174 {
09175 int sd;
09176 int res;
09177
09178 sd = socket(AF_INET, SOCK_DGRAM, 0);
09179 if (sd < 0) {
09180 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09181 return -1;
09182 }
09183
09184 res = bind(sd, sa, salen);
09185 if (res < 0) {
09186 if (option_debug)
09187 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09188 close(sd);
09189 return 1;
09190 }
09191
09192 close(sd);
09193 return 0;
09194 }
09195
09196
09197
09198
09199 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09200 {
09201 struct sockaddr_in sin;
09202 int nonlocal = 1;
09203 int port = IAX_DEFAULT_PORTNO;
09204 int sockfd = defaultsockfd;
09205 char *tmp;
09206 char *addr;
09207 char *portstr;
09208
09209 if (!(tmp = ast_strdupa(srcaddr)))
09210 return -1;
09211
09212 addr = strsep(&tmp, ":");
09213 portstr = tmp;
09214
09215 if (portstr) {
09216 port = atoi(portstr);
09217 if (port < 1)
09218 port = IAX_DEFAULT_PORTNO;
09219 }
09220
09221 if (!ast_get_ip(&sin, addr)) {
09222 struct ast_netsock *sock;
09223 int res;
09224
09225 sin.sin_port = 0;
09226 sin.sin_family = AF_INET;
09227 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09228 if (res == 0) {
09229
09230 sin.sin_port = htons(port);
09231 if (!(sock = ast_netsock_find(netsock, &sin)))
09232 sock = ast_netsock_find(outsock, &sin);
09233 if (sock) {
09234 sockfd = ast_netsock_sockfd(sock);
09235 nonlocal = 0;
09236 } else {
09237 unsigned int orig_saddr = sin.sin_addr.s_addr;
09238
09239 sin.sin_addr.s_addr = INADDR_ANY;
09240 if (ast_netsock_find(netsock, &sin)) {
09241 sin.sin_addr.s_addr = orig_saddr;
09242 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09243 if (sock) {
09244 sockfd = ast_netsock_sockfd(sock);
09245 ast_netsock_unref(sock);
09246 nonlocal = 0;
09247 } else {
09248 nonlocal = 2;
09249 }
09250 }
09251 }
09252 }
09253 }
09254
09255 peer->sockfd = sockfd;
09256
09257 if (nonlocal == 1) {
09258 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09259 srcaddr, peer->name);
09260 return -1;
09261 } else if (nonlocal == 2) {
09262 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09263 srcaddr, peer->name);
09264 return -1;
09265 } else {
09266 if (option_debug)
09267 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09268 return 0;
09269 }
09270 }
09271
09272 static void peer_destructor(void *obj)
09273 {
09274 struct iax2_peer *peer = obj;
09275
09276 ast_free_ha(peer->ha);
09277
09278 if (peer->callno > 0) {
09279 ast_mutex_lock(&iaxsl[peer->callno]);
09280 iax2_destroy(peer->callno);
09281 ast_mutex_unlock(&iaxsl[peer->callno]);
09282 }
09283
09284 register_peer_exten(peer, 0);
09285
09286 if (peer->dnsmgr)
09287 ast_dnsmgr_release(peer->dnsmgr);
09288
09289 ast_string_field_free_memory(peer);
09290 }
09291
09292
09293 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09294 {
09295 struct iax2_peer *peer = NULL;
09296 struct ast_ha *oldha = NULL;
09297 int maskfound=0;
09298 int found=0;
09299 int firstpass=1;
09300 struct iax2_peer tmp_peer = {
09301 .name = name,
09302 };
09303
09304 if (!temponly) {
09305 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09306 if (peer && !ast_test_flag(peer, IAX_DELME))
09307 firstpass = 0;
09308 }
09309
09310 if (peer) {
09311 found++;
09312 if (firstpass) {
09313 oldha = peer->ha;
09314 peer->ha = NULL;
09315 }
09316 unlink_peer(peer);
09317 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09318 peer->expire = -1;
09319 peer->pokeexpire = -1;
09320 peer->sockfd = defaultsockfd;
09321 if (ast_string_field_init(peer, 32))
09322 peer = peer_unref(peer);
09323 }
09324
09325 if (peer) {
09326 if (firstpass) {
09327 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09328 peer->encmethods = iax2_encryption;
09329 peer->adsi = adsi;
09330 ast_string_field_set(peer,secret,"");
09331 if (!found) {
09332 ast_string_field_set(peer, name, name);
09333 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09334 peer->expiry = min_reg_expire;
09335 }
09336 peer->prefs = prefs;
09337 peer->capability = iax2_capability;
09338 peer->smoothing = 0;
09339 peer->pokefreqok = DEFAULT_FREQ_OK;
09340 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09341 ast_string_field_set(peer,context,"");
09342 ast_string_field_set(peer,peercontext,"");
09343 ast_clear_flag(peer, IAX_HASCALLERID);
09344 ast_string_field_set(peer, cid_name, "");
09345 ast_string_field_set(peer, cid_num, "");
09346 }
09347
09348 if (!v) {
09349 v = alt;
09350 alt = NULL;
09351 }
09352 while(v) {
09353 if (!strcasecmp(v->name, "secret")) {
09354 ast_string_field_set(peer, secret, v->value);
09355 } else if (!strcasecmp(v->name, "mailbox")) {
09356 ast_string_field_set(peer, mailbox, v->value);
09357 } else if (!strcasecmp(v->name, "mohinterpret")) {
09358 ast_string_field_set(peer, mohinterpret, v->value);
09359 } else if (!strcasecmp(v->name, "mohsuggest")) {
09360 ast_string_field_set(peer, mohsuggest, v->value);
09361 } else if (!strcasecmp(v->name, "dbsecret")) {
09362 ast_string_field_set(peer, dbsecret, v->value);
09363 } else if (!strcasecmp(v->name, "trunk")) {
09364 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
09365 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09366 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
09367 ast_clear_flag(peer, IAX_TRUNK);
09368 }
09369 } else if (!strcasecmp(v->name, "auth")) {
09370 peer->authmethods = get_auth_methods(v->value);
09371 } else if (!strcasecmp(v->name, "encryption")) {
09372 peer->encmethods = get_encrypt_methods(v->value);
09373 } else if (!strcasecmp(v->name, "notransfer")) {
09374 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09375 ast_clear_flag(peer, IAX_TRANSFERMEDIA);
09376 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER);
09377 } else if (!strcasecmp(v->name, "transfer")) {
09378 if (!strcasecmp(v->value, "mediaonly")) {
09379 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
09380 } else if (ast_true(v->value)) {
09381 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09382 } else
09383 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09384 } else if (!strcasecmp(v->name, "jitterbuffer")) {
09385 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
09386 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09387 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
09388 } else if (!strcasecmp(v->name, "host")) {
09389 if (!strcasecmp(v->value, "dynamic")) {
09390
09391 ast_set_flag(peer, IAX_DYNAMIC);
09392 if (!found) {
09393
09394
09395 memset(&peer->addr.sin_addr, 0, 4);
09396 if (peer->addr.sin_port) {
09397
09398 peer->defaddr.sin_port = peer->addr.sin_port;
09399 peer->addr.sin_port = 0;
09400 }
09401 }
09402 } else {
09403
09404 AST_SCHED_DEL(sched, peer->expire);
09405 ast_clear_flag(peer, IAX_DYNAMIC);
09406 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09407 return peer_unref(peer);
09408 if (!peer->addr.sin_port)
09409 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09410 }
09411 if (!maskfound)
09412 inet_aton("255.255.255.255", &peer->mask);
09413 } else if (!strcasecmp(v->name, "defaultip")) {
09414 if (ast_get_ip(&peer->defaddr, v->value))
09415 return peer_unref(peer);
09416 } else if (!strcasecmp(v->name, "sourceaddress")) {
09417 peer_set_srcaddr(peer, v->value);
09418 } else if (!strcasecmp(v->name, "permit") ||
09419 !strcasecmp(v->name, "deny")) {
09420 peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09421 } else if (!strcasecmp(v->name, "mask")) {
09422 maskfound++;
09423 inet_aton(v->value, &peer->mask);
09424 } else if (!strcasecmp(v->name, "context")) {
09425 ast_string_field_set(peer, context, v->value);
09426 } else if (!strcasecmp(v->name, "regexten")) {
09427 ast_string_field_set(peer, regexten, v->value);
09428 } else if (!strcasecmp(v->name, "peercontext")) {
09429 ast_string_field_set(peer, peercontext, v->value);
09430 } else if (!strcasecmp(v->name, "port")) {
09431 if (ast_test_flag(peer, IAX_DYNAMIC))
09432 peer->defaddr.sin_port = htons(atoi(v->value));
09433 else
09434 peer->addr.sin_port = htons(atoi(v->value));
09435 } else if (!strcasecmp(v->name, "username")) {
09436 ast_string_field_set(peer, username, v->value);
09437 } else if (!strcasecmp(v->name, "allow")) {
09438 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09439 } else if (!strcasecmp(v->name, "disallow")) {
09440 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09441 } else if (!strcasecmp(v->name, "callerid")) {
09442 if (!ast_strlen_zero(v->value)) {
09443 char name2[80];
09444 char num2[80];
09445 ast_callerid_split(v->value, name2, 80, num2, 80);
09446 ast_string_field_set(peer, cid_name, name2);
09447 ast_string_field_set(peer, cid_num, num2);
09448 ast_set_flag(peer, IAX_HASCALLERID);
09449 } else {
09450 ast_clear_flag(peer, IAX_HASCALLERID);
09451 ast_string_field_set(peer, cid_name, "");
09452 ast_string_field_set(peer, cid_num, "");
09453 }
09454 } else if (!strcasecmp(v->name, "fullname")) {
09455 if (!ast_strlen_zero(v->value)) {
09456 ast_string_field_set(peer, cid_name, v->value);
09457 ast_set_flag(peer, IAX_HASCALLERID);
09458 } else {
09459 ast_string_field_set(peer, cid_name, "");
09460 if (ast_strlen_zero(peer->cid_num))
09461 ast_clear_flag(peer, IAX_HASCALLERID);
09462 }
09463 } else if (!strcasecmp(v->name, "cid_number")) {
09464 if (!ast_strlen_zero(v->value)) {
09465 ast_string_field_set(peer, cid_num, v->value);
09466 ast_set_flag(peer, IAX_HASCALLERID);
09467 } else {
09468 ast_string_field_set(peer, cid_num, "");
09469 if (ast_strlen_zero(peer->cid_name))
09470 ast_clear_flag(peer, IAX_HASCALLERID);
09471 }
09472 } else if (!strcasecmp(v->name, "sendani")) {
09473 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
09474 } else if (!strcasecmp(v->name, "inkeys")) {
09475 ast_string_field_set(peer, inkeys, v->value);
09476 } else if (!strcasecmp(v->name, "outkey")) {
09477 ast_string_field_set(peer, outkey, v->value);
09478 } else if (!strcasecmp(v->name, "qualify")) {
09479 if (!strcasecmp(v->value, "no")) {
09480 peer->maxms = 0;
09481 } else if (!strcasecmp(v->value, "yes")) {
09482 peer->maxms = DEFAULT_MAXMS;
09483 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09484 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);
09485 peer->maxms = 0;
09486 }
09487 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09488 peer->smoothing = ast_true(v->value);
09489 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09490 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09491 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);
09492 }
09493 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09494 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09495 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);
09496 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09497 } else if (!strcasecmp(v->name, "timezone")) {
09498 ast_string_field_set(peer, zonetag, v->value);
09499 } else if (!strcasecmp(v->name, "adsi")) {
09500 peer->adsi = ast_true(v->value);
09501 }
09502
09503 v = v->next;
09504 if (!v) {
09505 v = alt;
09506 alt = NULL;
09507 }
09508 }
09509 if (!peer->authmethods)
09510 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09511 ast_clear_flag(peer, IAX_DELME);
09512
09513 peer->addr.sin_family = AF_INET;
09514 }
09515 if (oldha)
09516 ast_free_ha(oldha);
09517 return peer;
09518 }
09519
09520 static void user_destructor(void *obj)
09521 {
09522 struct iax2_user *user = obj;
09523
09524 ast_free_ha(user->ha);
09525 free_context(user->contexts);
09526 if(user->vars) {
09527 ast_variables_destroy(user->vars);
09528 user->vars = NULL;
09529 }
09530 ast_string_field_free_memory(user);
09531 }
09532
09533
09534 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09535 {
09536 struct iax2_user *user = NULL;
09537 struct iax2_context *con, *conl = NULL;
09538 struct ast_ha *oldha = NULL;
09539 struct iax2_context *oldcon = NULL;
09540 int format;
09541 int firstpass=1;
09542 int oldcurauthreq = 0;
09543 char *varname = NULL, *varval = NULL;
09544 struct ast_variable *tmpvar = NULL;
09545 struct iax2_user tmp_user = {
09546 .name = name,
09547 };
09548
09549 if (!temponly) {
09550 user = ao2_find(users, &tmp_user, OBJ_POINTER);
09551 if (user && !ast_test_flag(user, IAX_DELME))
09552 firstpass = 0;
09553 }
09554
09555 if (user) {
09556 if (firstpass) {
09557 oldcurauthreq = user->curauthreq;
09558 oldha = user->ha;
09559 oldcon = user->contexts;
09560 user->ha = NULL;
09561 user->contexts = NULL;
09562 }
09563
09564 ao2_unlink(users, user);
09565 } else {
09566 user = ao2_alloc(sizeof(*user), user_destructor);
09567 }
09568
09569 if (user) {
09570 if (firstpass) {
09571 ast_string_field_free_memory(user);
09572 memset(user, 0, sizeof(struct iax2_user));
09573 if (ast_string_field_init(user, 32)) {
09574 user = user_unref(user);
09575 goto cleanup;
09576 }
09577 user->maxauthreq = maxauthreq;
09578 user->curauthreq = oldcurauthreq;
09579 user->prefs = prefs;
09580 user->capability = iax2_capability;
09581 user->encmethods = iax2_encryption;
09582 user->adsi = adsi;
09583 ast_string_field_set(user, name, name);
09584 ast_string_field_set(user, language, language);
09585 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
09586 ast_clear_flag(user, IAX_HASCALLERID);
09587 ast_string_field_set(user, cid_name, "");
09588 ast_string_field_set(user, cid_num, "");
09589 }
09590 if (!v) {
09591 v = alt;
09592 alt = NULL;
09593 }
09594 while(v) {
09595 if (!strcasecmp(v->name, "context")) {
09596 con = build_context(v->value);
09597 if (con) {
09598 if (conl)
09599 conl->next = con;
09600 else
09601 user->contexts = con;
09602 conl = con;
09603 }
09604 } else if (!strcasecmp(v->name, "permit") ||
09605 !strcasecmp(v->name, "deny")) {
09606 user->ha = ast_append_ha(v->name, v->value, user->ha);
09607 } else if (!strcasecmp(v->name, "setvar")) {
09608 varname = ast_strdupa(v->value);
09609 if (varname && (varval = strchr(varname,'='))) {
09610 *varval = '\0';
09611 varval++;
09612 if((tmpvar = ast_variable_new(varname, varval))) {
09613 tmpvar->next = user->vars;
09614 user->vars = tmpvar;
09615 }
09616 }
09617 } else if (!strcasecmp(v->name, "allow")) {
09618 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09619 } else if (!strcasecmp(v->name, "disallow")) {
09620 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09621 } else if (!strcasecmp(v->name, "trunk")) {
09622 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
09623 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09624 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
09625 ast_clear_flag(user, IAX_TRUNK);
09626 }
09627 } else if (!strcasecmp(v->name, "auth")) {
09628 user->authmethods = get_auth_methods(v->value);
09629 } else if (!strcasecmp(v->name, "encryption")) {
09630 user->encmethods = get_encrypt_methods(v->value);
09631 } else if (!strcasecmp(v->name, "notransfer")) {
09632 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09633 ast_clear_flag(user, IAX_TRANSFERMEDIA);
09634 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER);
09635 } else if (!strcasecmp(v->name, "transfer")) {
09636 if (!strcasecmp(v->value, "mediaonly")) {
09637 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
09638 } else if (ast_true(v->value)) {
09639 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09640 } else
09641 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09642 } else if (!strcasecmp(v->name, "codecpriority")) {
09643 if(!strcasecmp(v->value, "caller"))
09644 ast_set_flag(user, IAX_CODEC_USER_FIRST);
09645 else if(!strcasecmp(v->value, "disabled"))
09646 ast_set_flag(user, IAX_CODEC_NOPREFS);
09647 else if(!strcasecmp(v->value, "reqonly")) {
09648 ast_set_flag(user, IAX_CODEC_NOCAP);
09649 ast_set_flag(user, IAX_CODEC_NOPREFS);
09650 }
09651 } else if (!strcasecmp(v->name, "jitterbuffer")) {
09652 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09653 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09654 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09655 } else if (!strcasecmp(v->name, "dbsecret")) {
09656 ast_string_field_set(user, dbsecret, v->value);
09657 } else if (!strcasecmp(v->name, "secret")) {
09658 if (!ast_strlen_zero(user->secret)) {
09659 char *old = ast_strdupa(user->secret);
09660
09661 ast_string_field_build(user, secret, "%s;%s", old, v->value);
09662 } else
09663 ast_string_field_set(user, secret, v->value);
09664 } else if (!strcasecmp(v->name, "callerid")) {
09665 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09666 char name2[80];
09667 char num2[80];
09668 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09669 ast_string_field_set(user, cid_name, name2);
09670 ast_string_field_set(user, cid_num, num2);
09671 ast_set_flag(user, IAX_HASCALLERID);
09672 } else {
09673 ast_clear_flag(user, IAX_HASCALLERID);
09674 ast_string_field_set(user, cid_name, "");
09675 ast_string_field_set(user, cid_num, "");
09676 }
09677 } else if (!strcasecmp(v->name, "fullname")) {
09678 if (!ast_strlen_zero(v->value)) {
09679 ast_string_field_set(user, cid_name, v->value);
09680 ast_set_flag(user, IAX_HASCALLERID);
09681 } else {
09682 ast_string_field_set(user, cid_name, "");
09683 if (ast_strlen_zero(user->cid_num))
09684 ast_clear_flag(user, IAX_HASCALLERID);
09685 }
09686 } else if (!strcasecmp(v->name, "cid_number")) {
09687 if (!ast_strlen_zero(v->value)) {
09688 ast_string_field_set(user, cid_num, v->value);
09689 ast_set_flag(user, IAX_HASCALLERID);
09690 } else {
09691 ast_string_field_set(user, cid_num, "");
09692 if (ast_strlen_zero(user->cid_name))
09693 ast_clear_flag(user, IAX_HASCALLERID);
09694 }
09695 } else if (!strcasecmp(v->name, "accountcode")) {
09696 ast_string_field_set(user, accountcode, v->value);
09697 } else if (!strcasecmp(v->name, "mohinterpret")) {
09698 ast_string_field_set(user, mohinterpret, v->value);
09699 } else if (!strcasecmp(v->name, "mohsuggest")) {
09700 ast_string_field_set(user, mohsuggest, v->value);
09701 } else if (!strcasecmp(v->name, "language")) {
09702 ast_string_field_set(user, language, v->value);
09703 } else if (!strcasecmp(v->name, "amaflags")) {
09704 format = ast_cdr_amaflags2int(v->value);
09705 if (format < 0) {
09706 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09707 } else {
09708 user->amaflags = format;
09709 }
09710 } else if (!strcasecmp(v->name, "inkeys")) {
09711 ast_string_field_set(user, inkeys, v->value);
09712 } else if (!strcasecmp(v->name, "maxauthreq")) {
09713 user->maxauthreq = atoi(v->value);
09714 if (user->maxauthreq < 0)
09715 user->maxauthreq = 0;
09716 } else if (!strcasecmp(v->name, "adsi")) {
09717 user->adsi = ast_true(v->value);
09718 }
09719
09720 v = v->next;
09721 if (!v) {
09722 v = alt;
09723 alt = NULL;
09724 }
09725 }
09726 if (!user->authmethods) {
09727 if (!ast_strlen_zero(user->secret)) {
09728 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09729 if (!ast_strlen_zero(user->inkeys))
09730 user->authmethods |= IAX_AUTH_RSA;
09731 } else if (!ast_strlen_zero(user->inkeys)) {
09732 user->authmethods = IAX_AUTH_RSA;
09733 } else {
09734 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09735 }
09736 }
09737 ast_clear_flag(user, IAX_DELME);
09738 }
09739 cleanup:
09740 if (oldha)
09741 ast_free_ha(oldha);
09742 if (oldcon)
09743 free_context(oldcon);
09744 return user;
09745 }
09746
09747 static int peer_delme_cb(void *obj, void *arg, int flags)
09748 {
09749 struct iax2_peer *peer = obj;
09750
09751 ast_set_flag(peer, IAX_DELME);
09752
09753 return 0;
09754 }
09755
09756 static int user_delme_cb(void *obj, void *arg, int flags)
09757 {
09758 struct iax2_user *user = obj;
09759
09760 ast_set_flag(user, IAX_DELME);
09761
09762 return 0;
09763 }
09764
09765 static void delete_users(void)
09766 {
09767 struct iax2_registry *reg;
09768
09769 ao2_callback(users, 0, user_delme_cb, NULL);
09770
09771 AST_LIST_LOCK(®istrations);
09772 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
09773 ast_sched_del(sched, reg->expire);
09774 if (reg->callno) {
09775 ast_mutex_lock(&iaxsl[reg->callno]);
09776 if (iaxs[reg->callno]) {
09777 iaxs[reg->callno]->reg = NULL;
09778 iax2_destroy(reg->callno);
09779 }
09780 ast_mutex_unlock(&iaxsl[reg->callno]);
09781 }
09782 if (reg->dnsmgr)
09783 ast_dnsmgr_release(reg->dnsmgr);
09784 free(reg);
09785 }
09786 AST_LIST_UNLOCK(®istrations);
09787
09788 ao2_callback(peers, 0, peer_delme_cb, NULL);
09789 }
09790
09791 static void prune_users(void)
09792 {
09793 struct iax2_user *user;
09794 struct ao2_iterator i;
09795
09796 i = ao2_iterator_init(users, 0);
09797 while ((user = ao2_iterator_next(&i))) {
09798 if (ast_test_flag(user, IAX_DELME))
09799 ao2_unlink(users, user);
09800 user_unref(user);
09801 }
09802 }
09803
09804
09805 static void prune_peers(void)
09806 {
09807 struct iax2_peer *peer;
09808 struct ao2_iterator i;
09809
09810 i = ao2_iterator_init(peers, 0);
09811 while ((peer = ao2_iterator_next(&i))) {
09812 if (ast_test_flag(peer, IAX_DELME))
09813 unlink_peer(peer);
09814 peer_unref(peer);
09815 }
09816 }
09817
09818 static void set_timing(void)
09819 {
09820 #ifdef HAVE_ZAPTEL
09821 int bs = trunkfreq * 8;
09822 if (timingfd > -1) {
09823 if (
09824 #ifdef ZT_TIMERACK
09825 ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09826 #endif
09827 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09828 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09829 }
09830 #endif
09831 }
09832
09833 static void set_config_destroy(void)
09834 {
09835 strcpy(accountcode, "");
09836 strcpy(language, "");
09837 strcpy(mohinterpret, "default");
09838 strcpy(mohsuggest, "");
09839 amaflags = 0;
09840 delayreject = 0;
09841 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
09842 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
09843 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
09844 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
09845 delete_users();
09846 }
09847
09848
09849 static int set_config(char *config_file, int reload)
09850 {
09851 struct ast_config *cfg, *ucfg;
09852 int capability=iax2_capability;
09853 struct ast_variable *v;
09854 char *cat;
09855 const char *utype;
09856 const char *tosval;
09857 int format;
09858 int portno = IAX_DEFAULT_PORTNO;
09859 int x;
09860 struct iax2_user *user;
09861 struct iax2_peer *peer;
09862 struct ast_netsock *ns;
09863 #if 0
09864 static unsigned short int last_port=0;
09865 #endif
09866
09867 cfg = ast_config_load(config_file);
09868
09869 if (!cfg) {
09870 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09871 return -1;
09872 }
09873
09874 if (reload) {
09875 set_config_destroy();
09876 }
09877
09878
09879 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09880
09881
09882 memset(&globalflags, 0, sizeof(globalflags));
09883 ast_set_flag(&globalflags, IAX_RTUPDATE);
09884
09885 #ifdef SO_NO_CHECK
09886 nochecksums = 0;
09887 #endif
09888
09889 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09890 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09891
09892 maxauthreq = 3;
09893
09894 v = ast_variable_browse(cfg, "general");
09895
09896
09897 tosval = ast_variable_retrieve(cfg, "general", "tos");
09898 if (tosval) {
09899 if (ast_str2tos(tosval, &tos))
09900 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09901 }
09902 while(v) {
09903 if (!strcasecmp(v->name, "bindport")){
09904 if (reload)
09905 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09906 else
09907 portno = atoi(v->value);
09908 } else if (!strcasecmp(v->name, "pingtime"))
09909 ping_time = atoi(v->value);
09910 else if (!strcasecmp(v->name, "iaxthreadcount")) {
09911 if (reload) {
09912 if (atoi(v->value) != iaxthreadcount)
09913 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09914 } else {
09915 iaxthreadcount = atoi(v->value);
09916 if (iaxthreadcount < 1) {
09917 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09918 iaxthreadcount = 1;
09919 } else if (iaxthreadcount > 256) {
09920 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09921 iaxthreadcount = 256;
09922 }
09923 }
09924 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09925 if (reload) {
09926 AST_LIST_LOCK(&dynamic_list);
09927 iaxmaxthreadcount = atoi(v->value);
09928 AST_LIST_UNLOCK(&dynamic_list);
09929 } else {
09930 iaxmaxthreadcount = atoi(v->value);
09931 if (iaxmaxthreadcount < 0) {
09932 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09933 iaxmaxthreadcount = 0;
09934 } else if (iaxmaxthreadcount > 256) {
09935 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09936 iaxmaxthreadcount = 256;
09937 }
09938 }
09939 } else if (!strcasecmp(v->name, "nochecksums")) {
09940 #ifdef SO_NO_CHECK
09941 if (ast_true(v->value))
09942 nochecksums = 1;
09943 else
09944 nochecksums = 0;
09945 #else
09946 if (ast_true(v->value))
09947 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
09948 #endif
09949 }
09950 else if (!strcasecmp(v->name, "maxjitterbuffer"))
09951 maxjitterbuffer = atoi(v->value);
09952 else if (!strcasecmp(v->name, "resyncthreshold"))
09953 resyncthreshold = atoi(v->value);
09954 else if (!strcasecmp(v->name, "maxjitterinterps"))
09955 maxjitterinterps = atoi(v->value);
09956 else if (!strcasecmp(v->name, "lagrqtime"))
09957 lagrq_time = atoi(v->value);
09958 else if (!strcasecmp(v->name, "maxregexpire"))
09959 max_reg_expire = atoi(v->value);
09960 else if (!strcasecmp(v->name, "minregexpire"))
09961 min_reg_expire = atoi(v->value);
09962 else if (!strcasecmp(v->name, "bindaddr")) {
09963 if (reload) {
09964 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
09965 } else {
09966 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
09967 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
09968 } else {
09969 if (option_verbose > 1) {
09970 if (strchr(v->value, ':'))
09971 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
09972 else
09973 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
09974 }
09975 if (defaultsockfd < 0)
09976 defaultsockfd = ast_netsock_sockfd(ns);
09977 ast_netsock_unref(ns);
09978 }
09979 }
09980 } else if (!strcasecmp(v->name, "authdebug"))
09981 authdebug = ast_true(v->value);
09982 else if (!strcasecmp(v->name, "encryption"))
09983 iax2_encryption = get_encrypt_methods(v->value);
09984 else if (!strcasecmp(v->name, "notransfer")) {
09985 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09986 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
09987 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);
09988 } else if (!strcasecmp(v->name, "transfer")) {
09989 if (!strcasecmp(v->value, "mediaonly")) {
09990 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
09991 } else if (ast_true(v->value)) {
09992 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09993 } else
09994 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09995 } else if (!strcasecmp(v->name, "codecpriority")) {
09996 if(!strcasecmp(v->value, "caller"))
09997 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
09998 else if(!strcasecmp(v->value, "disabled"))
09999 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10000 else if(!strcasecmp(v->value, "reqonly")) {
10001 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10002 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10003 }
10004 } else if (!strcasecmp(v->name, "jitterbuffer"))
10005 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
10006 else if (!strcasecmp(v->name, "forcejitterbuffer"))
10007 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
10008 else if (!strcasecmp(v->name, "delayreject"))
10009 delayreject = ast_true(v->value);
10010 else if (!strcasecmp(v->name, "allowfwdownload"))
10011 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10012 else if (!strcasecmp(v->name, "rtcachefriends"))
10013 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
10014 else if (!strcasecmp(v->name, "rtignoreregexpire"))
10015 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
10016 else if (!strcasecmp(v->name, "rtupdate"))
10017 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10018 else if (!strcasecmp(v->name, "trunktimestamps"))
10019 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10020 else if (!strcasecmp(v->name, "rtautoclear")) {
10021 int i = atoi(v->value);
10022 if(i > 0)
10023 global_rtautoclear = i;
10024 else
10025 i = 0;
10026 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
10027 } else if (!strcasecmp(v->name, "trunkfreq")) {
10028 trunkfreq = atoi(v->value);
10029 if (trunkfreq < 10)
10030 trunkfreq = 10;
10031 } else if (!strcasecmp(v->name, "autokill")) {
10032 if (sscanf(v->value, "%d", &x) == 1) {
10033 if (x >= 0)
10034 autokill = x;
10035 else
10036 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10037 } else if (ast_true(v->value)) {
10038 autokill = DEFAULT_MAXMS;
10039 } else {
10040 autokill = 0;
10041 }
10042 } else if (!strcasecmp(v->name, "bandwidth")) {
10043 if (!strcasecmp(v->value, "low")) {
10044 capability = IAX_CAPABILITY_LOWBANDWIDTH;
10045 } else if (!strcasecmp(v->value, "medium")) {
10046 capability = IAX_CAPABILITY_MEDBANDWIDTH;
10047 } else if (!strcasecmp(v->value, "high")) {
10048 capability = IAX_CAPABILITY_FULLBANDWIDTH;
10049 } else
10050 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10051 } else if (!strcasecmp(v->name, "allow")) {
10052 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10053 } else if (!strcasecmp(v->name, "disallow")) {
10054 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10055 } else if (!strcasecmp(v->name, "register")) {
10056 iax2_register(v->value, v->lineno);
10057 } else if (!strcasecmp(v->name, "iaxcompat")) {
10058 iaxcompat = ast_true(v->value);
10059 } else if (!strcasecmp(v->name, "regcontext")) {
10060 ast_copy_string(regcontext, v->value, sizeof(regcontext));
10061
10062 if (!ast_context_find(regcontext))
10063 ast_context_create(NULL, regcontext, "IAX2");
10064 } else if (!strcasecmp(v->name, "tos")) {
10065 if (ast_str2tos(v->value, &tos))
10066 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10067 } else if (!strcasecmp(v->name, "accountcode")) {
10068 ast_copy_string(accountcode, v->value, sizeof(accountcode));
10069 } else if (!strcasecmp(v->name, "mohinterpret")) {
10070 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
10071 } else if (!strcasecmp(v->name, "mohsuggest")) {
10072 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
10073 } else if (!strcasecmp(v->name, "amaflags")) {
10074 format = ast_cdr_amaflags2int(v->value);
10075 if (format < 0) {
10076 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10077 } else {
10078 amaflags = format;
10079 }
10080 } else if (!strcasecmp(v->name, "language")) {
10081 ast_copy_string(language, v->value, sizeof(language));
10082 } else if (!strcasecmp(v->name, "maxauthreq")) {
10083 maxauthreq = atoi(v->value);
10084 if (maxauthreq < 0)
10085 maxauthreq = 0;
10086 } else if (!strcasecmp(v->name, "adsi")) {
10087 adsi = ast_true(v->value);
10088 }
10089
10090 v = v->next;
10091 }
10092
10093 if (defaultsockfd < 0) {
10094 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10095 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10096 } else {
10097 if (option_verbose > 1)
10098 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10099 defaultsockfd = ast_netsock_sockfd(ns);
10100 ast_netsock_unref(ns);
10101 }
10102 }
10103 if (reload) {
10104 ast_netsock_release(outsock);
10105 outsock = ast_netsock_list_alloc();
10106 if (!outsock) {
10107 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10108 return -1;
10109 }
10110 ast_netsock_init(outsock);
10111 }
10112
10113 if (min_reg_expire > max_reg_expire) {
10114 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10115 min_reg_expire, max_reg_expire, max_reg_expire);
10116 min_reg_expire = max_reg_expire;
10117 }
10118 iax2_capability = capability;
10119
10120 ucfg = ast_config_load("users.conf");
10121 if (ucfg) {
10122 struct ast_variable *gen;
10123 int genhasiax;
10124 int genregisteriax;
10125 const char *hasiax, *registeriax;
10126
10127 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10128 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10129 gen = ast_variable_browse(ucfg, "general");
10130 cat = ast_category_browse(ucfg, NULL);
10131 while (cat) {
10132 if (strcasecmp(cat, "general")) {
10133 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10134 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10135 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10136
10137 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10138 if (user) {
10139 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10140 user = user_unref(user);
10141 }
10142 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10143 if (peer) {
10144 if (ast_test_flag(peer, IAX_DYNAMIC))
10145 reg_source_db(peer);
10146 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10147 peer = peer_unref(peer);
10148 }
10149 }
10150 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10151 char tmp[256];
10152 const char *host = ast_variable_retrieve(ucfg, cat, "host");
10153 const char *username = ast_variable_retrieve(ucfg, cat, "username");
10154 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10155 if (!host)
10156 host = ast_variable_retrieve(ucfg, "general", "host");
10157 if (!username)
10158 username = ast_variable_retrieve(ucfg, "general", "username");
10159 if (!secret)
10160 secret = ast_variable_retrieve(ucfg, "general", "secret");
10161 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10162 if (!ast_strlen_zero(secret))
10163 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10164 else
10165 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10166 iax2_register(tmp, 0);
10167 }
10168 }
10169 }
10170 cat = ast_category_browse(ucfg, cat);
10171 }
10172 ast_config_destroy(ucfg);
10173 }
10174
10175 cat = ast_category_browse(cfg, NULL);
10176 while(cat) {
10177 if (strcasecmp(cat, "general")) {
10178 utype = ast_variable_retrieve(cfg, cat, "type");
10179 if (utype) {
10180 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10181 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10182 if (user) {
10183 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10184 user = user_unref(user);
10185 }
10186 }
10187 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10188 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10189 if (peer) {
10190 if (ast_test_flag(peer, IAX_DYNAMIC))
10191 reg_source_db(peer);
10192 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10193 peer = peer_unref(peer);
10194 }
10195 } else if (strcasecmp(utype, "user")) {
10196 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10197 }
10198 } else
10199 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10200 }
10201 cat = ast_category_browse(cfg, cat);
10202 }
10203 ast_config_destroy(cfg);
10204 set_timing();
10205 return 1;
10206 }
10207
10208 static void poke_all_peers(void)
10209 {
10210 struct ao2_iterator i;
10211 struct iax2_peer *peer;
10212
10213 i = ao2_iterator_init(peers, 0);
10214 while ((peer = ao2_iterator_next(&i))) {
10215 iax2_poke_peer(peer, 0);
10216 peer_unref(peer);
10217 }
10218 }
10219 static int reload_config(void)
10220 {
10221 char *config = "iax.conf";
10222 struct iax2_registry *reg;
10223
10224 if (set_config(config, 1) > 0) {
10225 prune_peers();
10226 prune_users();
10227 AST_LIST_LOCK(®istrations);
10228 AST_LIST_TRAVERSE(®istrations, reg, entry)
10229 iax2_do_register(reg);
10230 AST_LIST_UNLOCK(®istrations);
10231
10232 poke_all_peers();
10233 }
10234 reload_firmware(0);
10235 iax_provision_reload();
10236
10237 return 0;
10238 }
10239
10240 static int iax2_reload(int fd, int argc, char *argv[])
10241 {
10242 return reload_config();
10243 }
10244
10245 static int reload(void)
10246 {
10247 return reload_config();
10248 }
10249
10250 static int cache_get_callno_locked(const char *data)
10251 {
10252 struct sockaddr_in sin;
10253 int x;
10254 int callno;
10255 struct iax_ie_data ied;
10256 struct create_addr_info cai;
10257 struct parsed_dial_string pds;
10258 char *tmpstr;
10259
10260 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10261
10262
10263 if (!ast_mutex_trylock(&iaxsl[x])) {
10264 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10265 return x;
10266 ast_mutex_unlock(&iaxsl[x]);
10267 }
10268 }
10269
10270
10271
10272 memset(&cai, 0, sizeof(cai));
10273 memset(&ied, 0, sizeof(ied));
10274 memset(&pds, 0, sizeof(pds));
10275
10276 tmpstr = ast_strdupa(data);
10277 parse_dial_string(tmpstr, &pds);
10278
10279 if (ast_strlen_zero(pds.peer)) {
10280 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10281 return -1;
10282 }
10283
10284
10285 if (create_addr(pds.peer, NULL, &sin, &cai))
10286 return -1;
10287
10288 if (option_debug)
10289 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10290 pds.peer, pds.username, pds.password, pds.context);
10291
10292 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10293 if (callno < 1) {
10294 ast_log(LOG_WARNING, "Unable to create call\n");
10295 return -1;
10296 }
10297
10298 ast_string_field_set(iaxs[callno], dproot, data);
10299 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10300
10301 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10302 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10303
10304
10305
10306 if (pds.exten)
10307 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10308 if (pds.username)
10309 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10310 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10311 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10312
10313 if (pds.password)
10314 ast_string_field_set(iaxs[callno], secret, pds.password);
10315 if (pds.key)
10316 ast_string_field_set(iaxs[callno], outkey, pds.key);
10317
10318 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10319
10320 return callno;
10321 }
10322
10323 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10324 {
10325 struct iax2_dpcache *dp, *prev = NULL, *next;
10326 struct timeval tv;
10327 int x;
10328 int com[2];
10329 int timeout;
10330 int old=0;
10331 int outfd;
10332 int abort;
10333 int callno;
10334 struct ast_channel *c;
10335 struct ast_frame *f;
10336 gettimeofday(&tv, NULL);
10337 dp = dpcache;
10338 while(dp) {
10339 next = dp->next;
10340
10341 if (ast_tvcmp(tv, dp->expiry) > 0) {
10342
10343 if (prev)
10344 prev->next = dp->next;
10345 else
10346 dpcache = dp->next;
10347 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10348
10349 free(dp);
10350 } else {
10351 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = %p callno = %d)\n", dp->flags, dp->peer, dp->callno);
10352 }
10353 dp = next;
10354 continue;
10355 }
10356
10357 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
10358 break;
10359 prev = dp;
10360 dp = next;
10361 }
10362 if (!dp) {
10363
10364
10365 callno = cache_get_callno_locked(data);
10366 if (callno < 0) {
10367 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10368 return NULL;
10369 }
10370 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10371 ast_mutex_unlock(&iaxsl[callno]);
10372 return NULL;
10373 }
10374 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10375 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10376 gettimeofday(&dp->expiry, NULL);
10377 dp->orig = dp->expiry;
10378
10379 dp->expiry.tv_sec += iaxdefaultdpcache;
10380 dp->next = dpcache;
10381 dp->flags = CACHE_FLAG_PENDING;
10382 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10383 dp->waiters[x] = -1;
10384 dpcache = dp;
10385 dp->peer = iaxs[callno]->dpentries;
10386 iaxs[callno]->dpentries = dp;
10387
10388 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10389 iax2_dprequest(dp, callno);
10390 ast_mutex_unlock(&iaxsl[callno]);
10391 }
10392
10393 if (dp->flags & CACHE_FLAG_PENDING) {
10394
10395
10396 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10397
10398 if (dp->waiters[x] < 0)
10399 break;
10400 }
10401 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10402 ast_log(LOG_WARNING, "No more waiter positions available\n");
10403 return NULL;
10404 }
10405 if (pipe(com)) {
10406 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10407 return NULL;
10408 }
10409 dp->waiters[x] = com[1];
10410
10411 timeout = iaxdefaulttimeout * 1000;
10412
10413 ast_mutex_unlock(&dpcache_lock);
10414
10415 if (chan)
10416 old = ast_channel_defer_dtmf(chan);
10417 abort = 0;
10418 while(timeout) {
10419 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10420 if (outfd > -1) {
10421 break;
10422 }
10423 if (c) {
10424 f = ast_read(c);
10425 if (f)
10426 ast_frfree(f);
10427 else {
10428
10429 break;
10430 abort = 1;
10431 }
10432 }
10433 }
10434 if (!timeout) {
10435 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10436 }
10437 ast_mutex_lock(&dpcache_lock);
10438 dp->waiters[x] = -1;
10439 close(com[1]);
10440 close(com[0]);
10441 if (abort) {
10442
10443
10444 if (!old && chan)
10445 ast_channel_undefer_dtmf(chan);
10446 return NULL;
10447 }
10448 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10449
10450 if (dp->flags & CACHE_FLAG_PENDING) {
10451
10452
10453 dp->flags &= ~CACHE_FLAG_PENDING;
10454 dp->flags |= CACHE_FLAG_TIMEOUT;
10455
10456
10457 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10458 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10459 if (dp->waiters[x] > -1)
10460 write(dp->waiters[x], "asdf", 4);
10461 }
10462 }
10463
10464 if (!old && chan)
10465 ast_channel_undefer_dtmf(chan);
10466 }
10467 return dp;
10468 }
10469
10470
10471 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10472 {
10473 struct iax2_dpcache *dp;
10474 int res = 0;
10475 #if 0
10476 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10477 #endif
10478 if ((priority != 1) && (priority != 2))
10479 return 0;
10480 ast_mutex_lock(&dpcache_lock);
10481 dp = find_cache(chan, data, context, exten, priority);
10482 if (dp) {
10483 if (dp->flags & CACHE_FLAG_EXISTS)
10484 res= 1;
10485 }
10486 ast_mutex_unlock(&dpcache_lock);
10487 if (!dp) {
10488 ast_log(LOG_WARNING, "Unable to make DP cache\n");
10489 }
10490 return res;
10491 }
10492
10493
10494 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10495 {
10496 int res = 0;
10497 struct iax2_dpcache *dp;
10498 #if 0
10499 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10500 #endif
10501 if ((priority != 1) && (priority != 2))
10502 return 0;
10503 ast_mutex_lock(&dpcache_lock);
10504 dp = find_cache(chan, data, context, exten, priority);
10505 if (dp) {
10506 if (dp->flags & CACHE_FLAG_CANEXIST)
10507 res= 1;
10508 }
10509 ast_mutex_unlock(&dpcache_lock);
10510 if (!dp) {
10511 ast_log(LOG_WARNING, "Unable to make DP cache\n");
10512 }
10513 return res;
10514 }
10515
10516
10517 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10518 {
10519 int res = 0;
10520 struct iax2_dpcache *dp;
10521 #if 0
10522 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10523 #endif
10524 if ((priority != 1) && (priority != 2))
10525 return 0;
10526 ast_mutex_lock(&dpcache_lock);
10527 dp = find_cache(chan, data, context, exten, priority);
10528 if (dp) {
10529 if (dp->flags & CACHE_FLAG_MATCHMORE)
10530 res= 1;
10531 }
10532 ast_mutex_unlock(&dpcache_lock);
10533 if (!dp) {
10534 ast_log(LOG_WARNING, "Unable to make DP cache\n");
10535 }
10536 return res;
10537 }
10538
10539
10540 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10541 {
10542 char odata[256];
10543 char req[256];
10544 char *ncontext;
10545 struct iax2_dpcache *dp;
10546 struct ast_app *dial;
10547 #if 0
10548 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);
10549 #endif
10550 if (priority == 2) {
10551
10552 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10553 if (dialstatus) {
10554 dial = pbx_findapp(dialstatus);
10555 if (dial)
10556 pbx_exec(chan, dial, "");
10557 }
10558 return -1;
10559 } else if (priority != 1)
10560 return -1;
10561 ast_mutex_lock(&dpcache_lock);
10562 dp = find_cache(chan, data, context, exten, priority);
10563 if (dp) {
10564 if (dp->flags & CACHE_FLAG_EXISTS) {
10565 ast_copy_string(odata, data, sizeof(odata));
10566 ncontext = strchr(odata, '/');
10567 if (ncontext) {
10568 *ncontext = '\0';
10569 ncontext++;
10570 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10571 } else {
10572 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10573 }
10574 if (option_verbose > 2)
10575 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10576 } else {
10577 ast_mutex_unlock(&dpcache_lock);
10578 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10579 return -1;
10580 }
10581 }
10582 ast_mutex_unlock(&dpcache_lock);
10583 dial = pbx_findapp("Dial");
10584 if (dial) {
10585 return pbx_exec(chan, dial, req);
10586 } else {
10587 ast_log(LOG_WARNING, "No dial application registered\n");
10588 }
10589 return -1;
10590 }
10591
10592 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10593 {
10594 struct iax2_peer *peer;
10595 char *peername, *colname;
10596
10597 peername = ast_strdupa(data);
10598
10599
10600 if (!strcmp(peername,"CURRENTCHANNEL")) {
10601 unsigned short callno;
10602 if (chan->tech != &iax2_tech)
10603 return -1;
10604 callno = PTR_TO_CALLNO(chan->tech_pvt);
10605 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10606 return 0;
10607 }
10608
10609 if ((colname = strchr(peername, ':')))
10610 *colname++ = '\0';
10611 else if ((colname = strchr(peername, '|')))
10612 *colname++ = '\0';
10613 else
10614 colname = "ip";
10615
10616 if (!(peer = find_peer(peername, 1)))
10617 return -1;
10618
10619 if (!strcasecmp(colname, "ip")) {
10620 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10621 } else if (!strcasecmp(colname, "status")) {
10622 peer_status(peer, buf, len);
10623 } else if (!strcasecmp(colname, "mailbox")) {
10624 ast_copy_string(buf, peer->mailbox, len);
10625 } else if (!strcasecmp(colname, "context")) {
10626 ast_copy_string(buf, peer->context, len);
10627 } else if (!strcasecmp(colname, "expire")) {
10628 snprintf(buf, len, "%d", peer->expire);
10629 } else if (!strcasecmp(colname, "dynamic")) {
10630 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10631 } else if (!strcasecmp(colname, "callerid_name")) {
10632 ast_copy_string(buf, peer->cid_name, len);
10633 } else if (!strcasecmp(colname, "callerid_num")) {
10634 ast_copy_string(buf, peer->cid_num, len);
10635 } else if (!strcasecmp(colname, "codecs")) {
10636 ast_getformatname_multiple(buf, len -1, peer->capability);
10637 } else if (!strncasecmp(colname, "codec[", 6)) {
10638 char *codecnum, *ptr;
10639 int index = 0, codec = 0;
10640
10641 codecnum = strchr(colname, '[');
10642 *codecnum = '\0';
10643 codecnum++;
10644 if ((ptr = strchr(codecnum, ']'))) {
10645 *ptr = '\0';
10646 }
10647 index = atoi(codecnum);
10648 if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10649 ast_copy_string(buf, ast_getformatname(codec), len);
10650 }
10651 }
10652
10653 peer_unref(peer);
10654
10655 return 0;
10656 }
10657
10658 struct ast_custom_function iaxpeer_function = {
10659 .name = "IAXPEER",
10660 .synopsis = "Gets IAX peer information",
10661 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10662 .read = function_iaxpeer,
10663 .desc = "If peername specified, valid items are:\n"
10664 "- ip (default) The IP address.\n"
10665 "- status The peer's status (if qualify=yes)\n"
10666 "- mailbox The configured mailbox.\n"
10667 "- context The configured context.\n"
10668 "- expire The epoch time of the next expire.\n"
10669 "- dynamic Is it dynamic? (yes/no).\n"
10670 "- callerid_name The configured Caller ID name.\n"
10671 "- callerid_num The configured Caller ID number.\n"
10672 "- codecs The configured codecs.\n"
10673 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
10674 "\n"
10675 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10676 "\n"
10677 };
10678
10679
10680
10681 static int iax2_devicestate(void *data)
10682 {
10683 struct parsed_dial_string pds;
10684 char *tmp = ast_strdupa(data);
10685 struct iax2_peer *p;
10686 int res = AST_DEVICE_INVALID;
10687
10688 memset(&pds, 0, sizeof(pds));
10689 parse_dial_string(tmp, &pds);
10690
10691 if (ast_strlen_zero(pds.peer)) {
10692 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10693 return res;
10694 }
10695
10696 if (option_debug > 2)
10697 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10698
10699
10700 if (!(p = find_peer(pds.peer, 1)))
10701 return res;
10702
10703 res = AST_DEVICE_UNAVAILABLE;
10704 if (option_debug > 2)
10705 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10706 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10707
10708 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10709 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10710
10711
10712 if (p->historicms == 0 || p->historicms <= p->maxms)
10713
10714 res = AST_DEVICE_UNKNOWN;
10715 }
10716
10717 peer_unref(p);
10718
10719 return res;
10720 }
10721
10722 static struct ast_switch iax2_switch =
10723 {
10724 name: "IAX2",
10725 description: "IAX Remote Dialplan Switch",
10726 exists: iax2_exists,
10727 canmatch: iax2_canmatch,
10728 exec: iax2_exec,
10729 matchmore: iax2_matchmore,
10730 };
10731
10732 static char show_stats_usage[] =
10733 "Usage: iax2 show stats\n"
10734 " Display statistics on IAX channel driver.\n";
10735
10736 static char show_cache_usage[] =
10737 "Usage: iax2 show cache\n"
10738 " Display currently cached IAX Dialplan results.\n";
10739
10740 static char show_peer_usage[] =
10741 "Usage: iax2 show peer <name>\n"
10742 " Display details on specific IAX peer\n";
10743
10744 static char prune_realtime_usage[] =
10745 "Usage: iax2 prune realtime [<peername>|all]\n"
10746 " Prunes object(s) from the cache\n";
10747
10748 static char iax2_reload_usage[] =
10749 "Usage: iax2 reload\n"
10750 " Reloads IAX configuration from iax.conf\n";
10751
10752 static char show_prov_usage[] =
10753 "Usage: iax2 provision <host> <template> [forced]\n"
10754 " Provisions the given peer or IP address using a template\n"
10755 " matching either 'template' or '*' if the template is not\n"
10756 " found. If 'forced' is specified, even empty provisioning\n"
10757 " fields will be provisioned as empty fields.\n";
10758
10759 static char show_users_usage[] =
10760 "Usage: iax2 show users [like <pattern>]\n"
10761 " Lists all known IAX2 users.\n"
10762 " Optional regular expression pattern is used to filter the user list.\n";
10763
10764 static char show_channels_usage[] =
10765 "Usage: iax2 show channels\n"
10766 " Lists all currently active IAX channels.\n";
10767
10768 static char show_netstats_usage[] =
10769 "Usage: iax2 show netstats\n"
10770 " Lists network status for all currently active IAX channels.\n";
10771
10772 static char show_threads_usage[] =
10773 "Usage: iax2 show threads\n"
10774 " Lists status of IAX helper threads\n";
10775
10776 static char show_peers_usage[] =
10777 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10778 " Lists all known IAX2 peers.\n"
10779 " Optional 'registered' argument lists only peers with known addresses.\n"
10780 " Optional regular expression pattern is used to filter the peer list.\n";
10781
10782 static char show_firmware_usage[] =
10783 "Usage: iax2 show firmware\n"
10784 " Lists all known IAX firmware images.\n";
10785
10786 static char show_reg_usage[] =
10787 "Usage: iax2 show registry\n"
10788 " Lists all registration requests and status.\n";
10789
10790 static char debug_usage[] =
10791 "Usage: iax2 set debug\n"
10792 " Enables dumping of IAX packets for debugging purposes\n";
10793
10794 static char no_debug_usage[] =
10795 "Usage: iax2 set debug off\n"
10796 " Disables dumping of IAX packets for debugging purposes\n";
10797
10798 static char debug_trunk_usage[] =
10799 "Usage: iax2 set debug trunk\n"
10800 " Requests current status of IAX trunking\n";
10801
10802 static char no_debug_trunk_usage[] =
10803 "Usage: iax2 set debug trunk off\n"
10804 " Requests current status of IAX trunking\n";
10805
10806 static char debug_jb_usage[] =
10807 "Usage: iax2 set debug jb\n"
10808 " Enables jitterbuffer debugging information\n";
10809
10810 static char no_debug_jb_usage[] =
10811 "Usage: iax2 set debug jb off\n"
10812 " Disables jitterbuffer debugging information\n";
10813
10814 static char iax2_test_losspct_usage[] =
10815 "Usage: iax2 test losspct <percentage>\n"
10816 " For testing, throws away <percentage> percent of incoming packets\n";
10817
10818 #ifdef IAXTESTS
10819 static char iax2_test_late_usage[] =
10820 "Usage: iax2 test late <ms>\n"
10821 " For testing, count the next frame as <ms> ms late\n";
10822
10823 static char iax2_test_resync_usage[] =
10824 "Usage: iax2 test resync <ms>\n"
10825 " For testing, adjust all future frames by <ms> ms\n";
10826
10827 static char iax2_test_jitter_usage[] =
10828 "Usage: iax2 test jitter <ms> <pct>\n"
10829 " For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10830 #endif
10831
10832 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10833 { "iax2", "trunk", "debug", NULL },
10834 iax2_do_trunk_debug, NULL,
10835 NULL };
10836
10837 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10838 { "iax2", "jb", "debug", NULL },
10839 iax2_do_jb_debug, NULL,
10840 NULL };
10841
10842 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10843 { "iax2", "no", "debug", NULL },
10844 iax2_no_debug, NULL,
10845 NULL };
10846
10847 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10848 { "iax2", "no", "trunk", "debug", NULL },
10849 iax2_no_trunk_debug, NULL,
10850 NULL };
10851
10852 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10853 { "iax2", "no", "jb", "debug", NULL },
10854 iax2_no_jb_debug, NULL,
10855 NULL };
10856
10857 static struct ast_cli_entry cli_iax2[] = {
10858 { { "iax2", "show", "cache", NULL },
10859 iax2_show_cache, "Display IAX cached dialplan",
10860 show_cache_usage, NULL, },
10861
10862 { { "iax2", "show", "channels", NULL },
10863 iax2_show_channels, "List active IAX channels",
10864 show_channels_usage, NULL, },
10865
10866 { { "iax2", "show", "firmware", NULL },
10867 iax2_show_firmware, "List available IAX firmwares",
10868 show_firmware_usage, NULL, },
10869
10870 { { "iax2", "show", "netstats", NULL },
10871 iax2_show_netstats, "List active IAX channel netstats",
10872 show_netstats_usage, NULL, },
10873
10874 { { "iax2", "show", "peers", NULL },
10875 iax2_show_peers, "List defined IAX peers",
10876 show_peers_usage, NULL, },
10877
10878 { { "iax2", "show", "registry", NULL },
10879 iax2_show_registry, "Display IAX registration status",
10880 show_reg_usage, NULL, },
10881
10882 { { "iax2", "show", "stats", NULL },
10883 iax2_show_stats, "Display IAX statistics",
10884 show_stats_usage, NULL, },
10885
10886 { { "iax2", "show", "threads", NULL },
10887 iax2_show_threads, "Display IAX helper thread info",
10888 show_threads_usage, NULL, },
10889
10890 { { "iax2", "show", "users", NULL },
10891 iax2_show_users, "List defined IAX users",
10892 show_users_usage, NULL, },
10893
10894 { { "iax2", "prune", "realtime", NULL },
10895 iax2_prune_realtime, "Prune a cached realtime lookup",
10896 prune_realtime_usage, complete_iax2_show_peer },
10897
10898 { { "iax2", "reload", NULL },
10899 iax2_reload, "Reload IAX configuration",
10900 iax2_reload_usage },
10901
10902 { { "iax2", "show", "peer", NULL },
10903 iax2_show_peer, "Show details on specific IAX peer",
10904 show_peer_usage, complete_iax2_show_peer },
10905
10906 { { "iax2", "set", "debug", NULL },
10907 iax2_do_debug, "Enable IAX debugging",
10908 debug_usage },
10909
10910 { { "iax2", "set", "debug", "trunk", NULL },
10911 iax2_do_trunk_debug, "Enable IAX trunk debugging",
10912 debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10913
10914 { { "iax2", "set", "debug", "jb", NULL },
10915 iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10916 debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10917
10918 { { "iax2", "set", "debug", "off", NULL },
10919 iax2_no_debug, "Disable IAX debugging",
10920 no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10921
10922 { { "iax2", "set", "debug", "trunk", "off", NULL },
10923 iax2_no_trunk_debug, "Disable IAX trunk debugging",
10924 no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10925
10926 { { "iax2", "set", "debug", "jb", "off", NULL },
10927 iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10928 no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10929
10930 { { "iax2", "test", "losspct", NULL },
10931 iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10932 iax2_test_losspct_usage },
10933
10934 { { "iax2", "provision", NULL },
10935 iax2_prov_cmd, "Provision an IAX device",
10936 show_prov_usage, iax2_prov_complete_template_3rd },
10937
10938 #ifdef IAXTESTS
10939 { { "iax2", "test", "late", NULL },
10940 iax2_test_late, "Test the receipt of a late frame",
10941 iax2_test_late_usage },
10942
10943 { { "iax2", "test", "resync", NULL },
10944 iax2_test_resync, "Test a resync in received timestamps",
10945 iax2_test_resync_usage },
10946
10947 { { "iax2", "test", "jitter", NULL },
10948 iax2_test_jitter, "Simulates jitter for testing",
10949 iax2_test_jitter_usage },
10950 #endif
10951 };
10952
10953 static int __unload_module(void)
10954 {
10955 struct iax2_thread *thread = NULL;
10956 int x;
10957
10958
10959
10960
10961
10962 if (netthreadid != AST_PTHREADT_NULL) {
10963 AST_LIST_LOCK(&iaxq.queue);
10964 ast_mutex_lock(&sched_lock);
10965 pthread_cancel(netthreadid);
10966 ast_cond_signal(&sched_cond);
10967 ast_mutex_unlock(&sched_lock);
10968 AST_LIST_UNLOCK(&iaxq.queue);
10969 pthread_join(netthreadid, NULL);
10970 }
10971 if (schedthreadid != AST_PTHREADT_NULL) {
10972 ast_mutex_lock(&sched_lock);
10973 pthread_cancel(schedthreadid);
10974 ast_cond_signal(&sched_cond);
10975 ast_mutex_unlock(&sched_lock);
10976 pthread_join(schedthreadid, NULL);
10977 }
10978
10979
10980 AST_LIST_LOCK(&idle_list);
10981 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
10982 AST_LIST_REMOVE_CURRENT(&idle_list, list);
10983 pthread_cancel(thread->threadid);
10984 }
10985 AST_LIST_TRAVERSE_SAFE_END
10986 AST_LIST_UNLOCK(&idle_list);
10987
10988 AST_LIST_LOCK(&active_list);
10989 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
10990 AST_LIST_REMOVE_CURRENT(&active_list, list);
10991 pthread_cancel(thread->threadid);
10992 }
10993 AST_LIST_TRAVERSE_SAFE_END
10994 AST_LIST_UNLOCK(&active_list);
10995
10996 AST_LIST_LOCK(&dynamic_list);
10997 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
10998 AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
10999 pthread_cancel(thread->threadid);
11000 }
11001 AST_LIST_TRAVERSE_SAFE_END
11002 AST_LIST_UNLOCK(&dynamic_list);
11003
11004 AST_LIST_HEAD_DESTROY(&iaxq.queue);
11005
11006
11007 while(0 < iaxactivethreadcount)
11008 usleep(10000);
11009
11010 ast_netsock_release(netsock);
11011 ast_netsock_release(outsock);
11012 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11013 if (iaxs[x]) {
11014 iax2_destroy(x);
11015 }
11016 }
11017 ast_manager_unregister( "IAXpeers" );
11018 ast_manager_unregister( "IAXnetstats" );
11019 ast_unregister_application(papp);
11020 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11021 ast_unregister_switch(&iax2_switch);
11022 ast_channel_unregister(&iax2_tech);
11023 delete_users();
11024 iax_provision_unload();
11025 sched_context_destroy(sched);
11026 reload_firmware(1);
11027
11028 ast_mutex_destroy(&waresl.lock);
11029
11030 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11031 ast_mutex_destroy(&iaxsl[x]);
11032 }
11033
11034 ao2_ref(peers, -1);
11035 ao2_ref(users, -1);
11036 ao2_ref(iax_peercallno_pvts, -1);
11037
11038 return 0;
11039 }
11040
11041 static int unload_module(void)
11042 {
11043 ast_custom_function_unregister(&iaxpeer_function);
11044 return __unload_module();
11045 }
11046
11047 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11048 {
11049 struct iax2_peer *peer = obj;
11050
11051 if (peer->sockfd < 0)
11052 peer->sockfd = defaultsockfd;
11053
11054 return 0;
11055 }
11056
11057 static int pvt_hash_cb(const void *obj, const int flags)
11058 {
11059 const struct chan_iax2_pvt *pvt = obj;
11060
11061 return pvt->peercallno;
11062 }
11063
11064 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11065 {
11066 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11067
11068
11069
11070
11071 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
11072 pvt2->frames_received) ? CMP_MATCH : 0;
11073 }
11074
11075
11076 static int load_module(void)
11077 {
11078 char *config = "iax.conf";
11079 int res = 0;
11080 int x;
11081 struct iax2_registry *reg = NULL;
11082
11083 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11084 if (!peers)
11085 return AST_MODULE_LOAD_FAILURE;
11086 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11087 if (!users) {
11088 ao2_ref(peers, -1);
11089 return AST_MODULE_LOAD_FAILURE;
11090 }
11091 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11092 if (!iax_peercallno_pvts) {
11093 ao2_ref(peers, -1);
11094 ao2_ref(users, -1);
11095 return AST_MODULE_LOAD_FAILURE;
11096 }
11097
11098 ast_custom_function_register(&iaxpeer_function);
11099
11100 iax_set_output(iax_debug_output);
11101 iax_set_error(iax_error_output);
11102 jb_setoutput(jb_error_output, jb_warning_output, NULL);
11103
11104 #ifdef HAVE_ZAPTEL
11105 #ifdef ZT_TIMERACK
11106 timingfd = open("/dev/zap/timer", O_RDWR);
11107 if (timingfd < 0)
11108 #endif
11109 timingfd = open("/dev/zap/pseudo", O_RDWR);
11110 if (timingfd < 0)
11111 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11112 #endif
11113
11114 memset(iaxs, 0, sizeof(iaxs));
11115
11116 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11117 ast_mutex_init(&iaxsl[x]);
11118 }
11119
11120 ast_cond_init(&sched_cond, NULL);
11121
11122 io = io_context_create();
11123 sched = sched_context_create();
11124
11125 if (!io || !sched) {
11126 ast_log(LOG_ERROR, "Out of memory\n");
11127 return -1;
11128 }
11129
11130 netsock = ast_netsock_list_alloc();
11131 if (!netsock) {
11132 ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11133 return -1;
11134 }
11135 ast_netsock_init(netsock);
11136
11137 outsock = ast_netsock_list_alloc();
11138 if (!outsock) {
11139 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11140 return -1;
11141 }
11142 ast_netsock_init(outsock);
11143
11144 ast_mutex_init(&waresl.lock);
11145
11146 AST_LIST_HEAD_INIT(&iaxq.queue);
11147
11148 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11149
11150 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11151
11152 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11153 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11154
11155 if(set_config(config, 0) == -1)
11156 return AST_MODULE_LOAD_DECLINE;
11157
11158 if (ast_channel_register(&iax2_tech)) {
11159 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11160 __unload_module();
11161 return -1;
11162 }
11163
11164 if (ast_register_switch(&iax2_switch))
11165 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11166
11167 res = start_network_thread();
11168 if (!res) {
11169 if (option_verbose > 1)
11170 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11171 } else {
11172 ast_log(LOG_ERROR, "Unable to start network thread\n");
11173 ast_netsock_release(netsock);
11174 ast_netsock_release(outsock);
11175 }
11176
11177 AST_LIST_LOCK(®istrations);
11178 AST_LIST_TRAVERSE(®istrations, reg, entry)
11179 iax2_do_register(reg);
11180 AST_LIST_UNLOCK(®istrations);
11181
11182 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11183 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11184
11185 reload_firmware(0);
11186 iax_provision_reload();
11187 return res;
11188 }
11189
11190 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11191 .load = load_module,
11192 .unload = unload_module,
11193 .reload = reload,
11194 );