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