00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "asterisk.h"
00037
00038 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 216015 $")
00039
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <sys/types.h>
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <string.h>
00054 #include <strings.h>
00055 #include <errno.h>
00056 #include <unistd.h>
00057 #include <netdb.h>
00058 #include <fcntl.h>
00059 #include <sys/stat.h>
00060 #include <regex.h>
00061
00062 #if defined(HAVE_ZAPTEL) || defined (HAVE_DAHDI)
00063 #include <sys/ioctl.h>
00064 #include "asterisk/dahdi_compat.h"
00065 #endif
00066
00067 #include "asterisk/lock.h"
00068 #include "asterisk/frame.h"
00069 #include "asterisk/channel.h"
00070 #include "asterisk/logger.h"
00071 #include "asterisk/module.h"
00072 #include "asterisk/pbx.h"
00073 #include "asterisk/sched.h"
00074 #include "asterisk/io.h"
00075 #include "asterisk/config.h"
00076 #include "asterisk/options.h"
00077 #include "asterisk/cli.h"
00078 #include "asterisk/translate.h"
00079 #include "asterisk/md5.h"
00080 #include "asterisk/cdr.h"
00081 #include "asterisk/crypto.h"
00082 #include "asterisk/acl.h"
00083 #include "asterisk/manager.h"
00084 #include "asterisk/callerid.h"
00085 #include "asterisk/app.h"
00086 #include "asterisk/astdb.h"
00087 #include "asterisk/musiconhold.h"
00088 #include "asterisk/features.h"
00089 #include "asterisk/utils.h"
00090 #include "asterisk/causes.h"
00091 #include "asterisk/localtime.h"
00092 #include "asterisk/aes.h"
00093 #include "asterisk/dnsmgr.h"
00094 #include "asterisk/devicestate.h"
00095 #include "asterisk/netsock.h"
00096 #include "asterisk/stringfields.h"
00097 #include "asterisk/linkedlists.h"
00098 #include "asterisk/astobj2.h"
00099
00100 #include "iax2.h"
00101 #include "iax2-parser.h"
00102 #include "iax2-provision.h"
00103 #include "jitterbuf.h"
00104
00105
00106
00107 #define SCHED_MULTITHREADED
00108
00109
00110
00111 #define DEBUG_SCHED_MULTITHREAD
00112
00113 #ifndef IPTOS_MINCOST
00114 #define IPTOS_MINCOST 0x02
00115 #endif
00116
00117 #ifdef SO_NO_CHECK
00118 static int nochecksums = 0;
00119 #endif
00120
00121
00122 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00123 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00124
00125 #define DEFAULT_THREAD_COUNT 10
00126 #define DEFAULT_MAX_THREAD_COUNT 100
00127 #define DEFAULT_RETRY_TIME 1000
00128 #define MEMORY_SIZE 100
00129 #define DEFAULT_DROP 3
00130
00131 #define DEBUG_SUPPORT
00132
00133 #define MIN_REUSE_TIME 60
00134
00135
00136 #define GAMMA (0.01)
00137
00138 static struct ast_codec_pref prefs;
00139
00140 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00141
00142 static char context[80] = "default";
00143
00144 static char language[MAX_LANGUAGE] = "";
00145 static char regcontext[AST_MAX_CONTEXT] = "";
00146
00147 static int maxauthreq = 3;
00148 static int max_retries = 4;
00149 static int ping_time = 21;
00150 static int lagrq_time = 10;
00151 static int maxjitterbuffer=1000;
00152 static int resyncthreshold=1000;
00153 static int maxjitterinterps=10;
00154 static int trunkfreq = 20;
00155 static int authdebug = 1;
00156 static int autokill = 0;
00157 static int iaxcompat = 0;
00158 static int last_authmethod = 0;
00159
00160 static int iaxdefaultdpcache=10 * 60;
00161
00162 static int iaxdefaulttimeout = 5;
00163
00164 static unsigned int tos = 0;
00165
00166 static int min_reg_expire;
00167 static int max_reg_expire;
00168
00169 static int timingfd = -1;
00170
00171 static struct ast_netsock_list *netsock;
00172 static struct ast_netsock_list *outsock;
00173 static int defaultsockfd = -1;
00174
00175 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00176
00177
00178 #define IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)
00179
00180 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00181 ~AST_FORMAT_SLINEAR & \
00182 ~AST_FORMAT_ULAW & \
00183 ~AST_FORMAT_ALAW & \
00184 ~AST_FORMAT_G722)
00185
00186 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00187 ~AST_FORMAT_G726 & \
00188 ~AST_FORMAT_G726_AAL2 & \
00189 ~AST_FORMAT_ADPCM)
00190
00191 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00192 ~AST_FORMAT_G723_1)
00193
00194
00195 #define DEFAULT_MAXMS 2000
00196 #define DEFAULT_FREQ_OK 60 * 1000
00197 #define DEFAULT_FREQ_NOTOK 10 * 1000
00198
00199 static struct io_context *io;
00200 static struct sched_context *sched;
00201
00202 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00203
00204 static int iaxdebug = 0;
00205
00206 static int iaxtrunkdebug = 0;
00207
00208 static int test_losspct = 0;
00209 #ifdef IAXTESTS
00210 static int test_late = 0;
00211 static int test_resync = 0;
00212 static int test_jit = 0;
00213 static int test_jitpct = 0;
00214 #endif
00215
00216 static char accountcode[AST_MAX_ACCOUNT_CODE];
00217 static char mohinterpret[MAX_MUSICCLASS];
00218 static char mohsuggest[MAX_MUSICCLASS];
00219 static int amaflags = 0;
00220 static int adsi = 0;
00221 static int delayreject = 0;
00222 static int iax2_encryption = 0;
00223
00224 static struct ast_flags globalflags = { 0 };
00225
00226 static pthread_t netthreadid = AST_PTHREADT_NULL;
00227 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00228 AST_MUTEX_DEFINE_STATIC(sched_lock);
00229 static ast_cond_t sched_cond;
00230
00231 enum {
00232 IAX_STATE_STARTED = (1 << 0),
00233 IAX_STATE_AUTHENTICATED = (1 << 1),
00234 IAX_STATE_TBD = (1 << 2),
00235 } iax2_state;
00236
00237 struct iax2_context {
00238 char context[AST_MAX_CONTEXT];
00239 struct iax2_context *next;
00240 };
00241
00242 enum {
00243 IAX_HASCALLERID = (1 << 0),
00244 IAX_DELME = (1 << 1),
00245 IAX_TEMPONLY = (1 << 2),
00246 IAX_TRUNK = (1 << 3),
00247 IAX_NOTRANSFER = (1 << 4),
00248 IAX_USEJITTERBUF = (1 << 5),
00249 IAX_DYNAMIC = (1 << 6),
00250 IAX_SENDANI = (1 << 7),
00251
00252 IAX_ALREADYGONE = (1 << 9),
00253 IAX_PROVISION = (1 << 10),
00254 IAX_QUELCH = (1 << 11),
00255 IAX_ENCRYPTED = (1 << 12),
00256 IAX_KEYPOPULATED = (1 << 13),
00257 IAX_CODEC_USER_FIRST = (1 << 14),
00258 IAX_CODEC_NOPREFS = (1 << 15),
00259 IAX_CODEC_NOCAP = (1 << 16),
00260 IAX_RTCACHEFRIENDS = (1 << 17),
00261 IAX_RTUPDATE = (1 << 18),
00262 IAX_RTAUTOCLEAR = (1 << 19),
00263 IAX_FORCEJITTERBUF = (1 << 20),
00264 IAX_RTIGNOREREGEXPIRE = (1 << 21),
00265 IAX_TRUNKTIMESTAMPS = (1 << 22),
00266 IAX_TRANSFERMEDIA = (1 << 23),
00267 IAX_MAXAUTHREQ = (1 << 24),
00268 IAX_DELAYPBXSTART = (1 << 25),
00269
00270
00271 IAX_ALLOWFWDOWNLOAD = (1 << 26),
00272 } iax2_flags;
00273
00274 static int global_rtautoclear = 120;
00275
00276 static int reload_config(void);
00277 static int iax2_reload(int fd, int argc, char *argv[]);
00278
00279
00280
00281
00282 enum calltoken_peer_enum {
00283
00284 CALLTOKEN_DEFAULT = 0,
00285
00286 CALLTOKEN_YES = 1,
00287
00288
00289 CALLTOKEN_AUTO = 2,
00290
00291 CALLTOKEN_NO = 3,
00292 };
00293
00294 struct iax2_user {
00295 AST_DECLARE_STRING_FIELDS(
00296 AST_STRING_FIELD(name);
00297 AST_STRING_FIELD(secret);
00298 AST_STRING_FIELD(dbsecret);
00299 AST_STRING_FIELD(accountcode);
00300 AST_STRING_FIELD(mohinterpret);
00301 AST_STRING_FIELD(mohsuggest);
00302 AST_STRING_FIELD(inkeys);
00303 AST_STRING_FIELD(language);
00304 AST_STRING_FIELD(cid_num);
00305 AST_STRING_FIELD(cid_name);
00306 );
00307
00308 int authmethods;
00309 int encmethods;
00310 int amaflags;
00311 int adsi;
00312 unsigned int flags;
00313 int capability;
00314 int maxauthreq;
00315 int curauthreq;
00316 struct ast_codec_pref prefs;
00317 struct ast_ha *ha;
00318 struct iax2_context *contexts;
00319 struct ast_variable *vars;
00320 enum calltoken_peer_enum calltoken_required;
00321 };
00322
00323 struct iax2_peer {
00324 AST_DECLARE_STRING_FIELDS(
00325 AST_STRING_FIELD(name);
00326 AST_STRING_FIELD(username);
00327 AST_STRING_FIELD(secret);
00328 AST_STRING_FIELD(dbsecret);
00329 AST_STRING_FIELD(outkey);
00330
00331 AST_STRING_FIELD(regexten);
00332 AST_STRING_FIELD(context);
00333 AST_STRING_FIELD(peercontext);
00334 AST_STRING_FIELD(mailbox);
00335 AST_STRING_FIELD(mohinterpret);
00336 AST_STRING_FIELD(mohsuggest);
00337 AST_STRING_FIELD(inkeys);
00338
00339 AST_STRING_FIELD(cid_num);
00340 AST_STRING_FIELD(cid_name);
00341 AST_STRING_FIELD(zonetag);
00342 );
00343 struct ast_codec_pref prefs;
00344 struct ast_dnsmgr_entry *dnsmgr;
00345 struct sockaddr_in addr;
00346 int formats;
00347 int sockfd;
00348 struct in_addr mask;
00349 int adsi;
00350 unsigned int flags;
00351
00352
00353 struct sockaddr_in defaddr;
00354 int authmethods;
00355 int encmethods;
00356
00357 int expire;
00358 int expiry;
00359 int capability;
00360
00361
00362 int callno;
00363 int pokeexpire;
00364 int lastms;
00365 int maxms;
00366
00367 int pokefreqok;
00368 int pokefreqnotok;
00369 int historicms;
00370 int smoothing;
00371 uint16_t maxcallno;
00372
00373 struct ast_ha *ha;
00374 enum calltoken_peer_enum calltoken_required;
00375 };
00376
00377 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00378
00379 static struct iax2_trunk_peer {
00380 ast_mutex_t lock;
00381 int sockfd;
00382 struct sockaddr_in addr;
00383 struct timeval txtrunktime;
00384 struct timeval rxtrunktime;
00385 struct timeval lasttxtime;
00386 struct timeval trunkact;
00387 unsigned int lastsent;
00388
00389 unsigned char *trunkdata;
00390 unsigned int trunkdatalen;
00391 unsigned int trunkdataalloc;
00392 struct iax2_trunk_peer *next;
00393 int trunkerror;
00394 int calls;
00395 } *tpeers = NULL;
00396
00397 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00398
00399 struct iax_firmware {
00400 struct iax_firmware *next;
00401 int fd;
00402 int mmaplen;
00403 int dead;
00404 struct ast_iax2_firmware_header *fwh;
00405 unsigned char *buf;
00406 };
00407
00408 enum iax_reg_state {
00409 REG_STATE_UNREGISTERED = 0,
00410 REG_STATE_REGSENT,
00411 REG_STATE_AUTHSENT,
00412 REG_STATE_REGISTERED,
00413 REG_STATE_REJECTED,
00414 REG_STATE_TIMEOUT,
00415 REG_STATE_NOAUTH
00416 };
00417
00418 enum iax_transfer_state {
00419 TRANSFER_NONE = 0,
00420 TRANSFER_BEGIN,
00421 TRANSFER_READY,
00422 TRANSFER_RELEASED,
00423 TRANSFER_PASSTHROUGH,
00424 TRANSFER_MBEGIN,
00425 TRANSFER_MREADY,
00426 TRANSFER_MRELEASED,
00427 TRANSFER_MPASSTHROUGH,
00428 TRANSFER_MEDIA,
00429 TRANSFER_MEDIAPASS
00430 };
00431
00432 struct iax2_registry {
00433 struct sockaddr_in addr;
00434 char username[80];
00435 char secret[80];
00436 char random[80];
00437 int expire;
00438 int refresh;
00439 enum iax_reg_state regstate;
00440 int messages;
00441 int callno;
00442 struct sockaddr_in us;
00443 struct ast_dnsmgr_entry *dnsmgr;
00444 AST_LIST_ENTRY(iax2_registry) entry;
00445 };
00446
00447 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00448
00449
00450 #define MIN_RETRY_TIME 100
00451 #define MAX_RETRY_TIME 10000
00452
00453 #define MAX_JITTER_BUFFER 50
00454 #define MIN_JITTER_BUFFER 10
00455
00456 #define DEFAULT_TRUNKDATA 640 * 10
00457 #define MAX_TRUNKDATA 640 * 200
00458
00459 #define MAX_TIMESTAMP_SKEW 160
00460
00461
00462 #define TS_GAP_FOR_JB_RESYNC 5000
00463
00464
00465 #define MARK_IAX_SUBCLASS_TX 0x8000
00466
00467 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00468 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00469 static int iaxdynamicthreadcount = 0;
00470 static int iaxdynamicthreadnum = 0;
00471 static int iaxactivethreadcount = 0;
00472
00473 struct iax_rr {
00474 int jitter;
00475 int losspct;
00476 int losscnt;
00477 int packets;
00478 int delay;
00479 int dropped;
00480 int ooo;
00481 };
00482
00483 struct chan_iax2_pvt {
00484
00485 int sockfd;
00486
00487 int voiceformat;
00488
00489 int videoformat;
00490
00491 int svoiceformat;
00492
00493 int svideoformat;
00494
00495 int capability;
00496
00497 unsigned int last;
00498
00499 unsigned int lastsent;
00500
00501 unsigned int lastvsent;
00502
00503 unsigned int nextpred;
00504
00505 int first_iax_message;
00506
00507 int last_iax_message;
00508
00509 int notsilenttx;
00510
00511 unsigned int pingtime;
00512
00513 int maxtime;
00514
00515 struct sockaddr_in addr;
00516
00517 struct ast_codec_pref prefs;
00518
00519 struct ast_codec_pref rprefs;
00520
00521 unsigned short callno;
00522
00523 struct callno_entry *callno_entry;
00524
00525 unsigned short peercallno;
00526
00527
00528
00529 int chosenformat;
00530
00531 int peerformat;
00532
00533 int peercapability;
00534
00535 struct timeval offset;
00536
00537 struct timeval rxcore;
00538
00539 jitterbuf *jb;
00540
00541 int jbid;
00542
00543 int lag;
00544
00545 int error;
00546
00547 struct ast_channel *owner;
00548
00549 struct ast_flags state;
00550
00551 int expiry;
00552
00553 unsigned char oseqno;
00554
00555 unsigned char rseqno;
00556
00557 unsigned char iseqno;
00558
00559 unsigned char aseqno;
00560
00561 AST_DECLARE_STRING_FIELDS(
00562
00563 AST_STRING_FIELD(peer);
00564
00565 AST_STRING_FIELD(context);
00566
00567 AST_STRING_FIELD(cid_num);
00568 AST_STRING_FIELD(cid_name);
00569
00570 AST_STRING_FIELD(ani);
00571
00572 AST_STRING_FIELD(dnid);
00573
00574 AST_STRING_FIELD(rdnis);
00575
00576 AST_STRING_FIELD(exten);
00577
00578 AST_STRING_FIELD(username);
00579
00580 AST_STRING_FIELD(secret);
00581
00582 AST_STRING_FIELD(challenge);
00583
00584 AST_STRING_FIELD(inkeys);
00585
00586 AST_STRING_FIELD(outkey);
00587
00588 AST_STRING_FIELD(language);
00589
00590 AST_STRING_FIELD(host);
00591
00592 AST_STRING_FIELD(dproot);
00593 AST_STRING_FIELD(accountcode);
00594 AST_STRING_FIELD(mohinterpret);
00595 AST_STRING_FIELD(mohsuggest);
00596 );
00597
00598 int authrej;
00599
00600 int authmethods;
00601
00602 int encmethods;
00603
00604 aes_encrypt_ctx ecx;
00605
00606 aes_decrypt_ctx mydcx;
00607
00608 aes_decrypt_ctx dcx;
00609
00610 unsigned char semirand[32];
00611
00612 struct iax2_registry *reg;
00613
00614 struct iax2_peer *peerpoke;
00615
00616 unsigned int flags;
00617 int adsi;
00618
00619
00620 enum iax_transfer_state transferring;
00621
00622 int transferid;
00623
00624 struct sockaddr_in transfer;
00625
00626 unsigned short transfercallno;
00627
00628 aes_encrypt_ctx tdcx;
00629
00630
00631 int peeradsicpe;
00632
00633
00634 unsigned short bridgecallno;
00635
00636 int pingid;
00637 int lagid;
00638 int autoid;
00639 int authid;
00640 int authfail;
00641 int initid;
00642 int calling_ton;
00643 int calling_tns;
00644 int calling_pres;
00645 int amaflags;
00646 struct iax2_dpcache *dpentries;
00647 struct ast_variable *vars;
00648
00649 struct iax_rr remote_rr;
00650
00651 int min;
00652
00653 int frames_dropped;
00654
00655 int frames_received;
00656
00657 unsigned char calltoken_ie_len;
00658 };
00659
00660
00661 static struct ao2_container *callno_pool;
00662
00663
00664 static struct ao2_container *callno_pool_trunk;
00665
00666 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00667
00668 static struct ast_iax2_queue {
00669 AST_LIST_HEAD(, iax_frame) queue;
00670 int count;
00671 } iaxq;
00672
00673 static int randomcalltokendata;
00674
00675 static const time_t MAX_CALLTOKEN_DELAY = 10;
00676
00677
00678
00679
00680
00681
00682
00683
00684 #ifdef LOW_MEMORY
00685 #define MAX_PEER_BUCKETS 1
00686
00687 #else
00688 #define MAX_PEER_BUCKETS 1
00689
00690 #endif
00691 static struct ao2_container *peers;
00692
00693 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00694 static struct ao2_container *users;
00695
00696
00697
00698 static struct ao2_container *peercnts;
00699
00700
00701 static struct ao2_container *callno_limits;
00702
00703
00704 static struct ao2_container *calltoken_ignores;
00705
00706 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00707
00708 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00709
00710 static uint16_t global_maxcallno;
00711
00712
00713 static uint16_t global_maxcallno_nonval;
00714
00715 static uint16_t total_nonval_callno_used = 0;
00716
00717
00718
00719 struct peercnt {
00720
00721 unsigned long addr;
00722
00723 uint16_t cur;
00724
00725 uint16_t limit;
00726
00727
00728 unsigned char reg;
00729 };
00730
00731
00732 struct addr_range {
00733
00734 struct ast_ha ha;
00735
00736 uint16_t limit;
00737
00738 unsigned char delme;
00739 };
00740
00741 struct callno_entry {
00742
00743 uint16_t callno;
00744
00745 unsigned char validated;
00746 };
00747
00748 static struct ast_firmware_list {
00749 struct iax_firmware *wares;
00750 ast_mutex_t lock;
00751 } waresl;
00752
00753
00754 #define CACHE_FLAG_EXISTS (1 << 0)
00755
00756 #define CACHE_FLAG_NONEXISTENT (1 << 1)
00757
00758 #define CACHE_FLAG_CANEXIST (1 << 2)
00759
00760 #define CACHE_FLAG_PENDING (1 << 3)
00761
00762 #define CACHE_FLAG_TIMEOUT (1 << 4)
00763
00764 #define CACHE_FLAG_TRANSMITTED (1 << 5)
00765
00766 #define CACHE_FLAG_UNKNOWN (1 << 6)
00767
00768 #define CACHE_FLAG_MATCHMORE (1 << 7)
00769
00770 static struct iax2_dpcache {
00771 char peercontext[AST_MAX_CONTEXT];
00772 char exten[AST_MAX_EXTENSION];
00773 struct timeval orig;
00774 struct timeval expiry;
00775 int flags;
00776 unsigned short callno;
00777 int waiters[256];
00778 struct iax2_dpcache *next;
00779 struct iax2_dpcache *peer;
00780 } *dpcache;
00781
00782 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00783
00784 static void reg_source_db(struct iax2_peer *p);
00785 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00786
00787 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00788
00789 #define IAX_IOSTATE_IDLE 0
00790 #define IAX_IOSTATE_READY 1
00791 #define IAX_IOSTATE_PROCESSING 2
00792 #define IAX_IOSTATE_SCHEDREADY 3
00793
00794 #define IAX_TYPE_POOL 1
00795 #define IAX_TYPE_DYNAMIC 2
00796
00797 struct iax2_pkt_buf {
00798 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00799 size_t len;
00800 unsigned char buf[1];
00801 };
00802
00803 struct iax2_thread {
00804 AST_LIST_ENTRY(iax2_thread) list;
00805 int type;
00806 int iostate;
00807 #ifdef SCHED_MULTITHREADED
00808 void (*schedfunc)(const void *);
00809 const void *scheddata;
00810 #endif
00811 #ifdef DEBUG_SCHED_MULTITHREAD
00812 char curfunc[80];
00813 #endif
00814 int actions;
00815 pthread_t threadid;
00816 int threadnum;
00817 struct sockaddr_in iosin;
00818 unsigned char readbuf[4096];
00819 unsigned char *buf;
00820 ssize_t buf_len;
00821 size_t buf_size;
00822 int iofd;
00823 time_t checktime;
00824 ast_mutex_t lock;
00825 ast_cond_t cond;
00826 unsigned int ready_for_signal:1;
00827
00828
00829
00830
00831 struct {
00832 unsigned short callno;
00833 struct sockaddr_in sin;
00834 unsigned char type;
00835 unsigned char csub;
00836 } ffinfo;
00837
00838
00839
00840 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00841 };
00842
00843
00844 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00845 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00846 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00847
00848 static void *iax2_process_thread(void *data);
00849
00850 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00851 {
00852 ast_mutex_lock(lock);
00853 ast_cond_signal(cond);
00854 ast_mutex_unlock(lock);
00855 }
00856
00857 static void iax_debug_output(const char *data)
00858 {
00859 if (iaxdebug)
00860 ast_verbose("%s", data);
00861 }
00862
00863 static void iax_error_output(const char *data)
00864 {
00865 ast_log(LOG_WARNING, "%s", data);
00866 }
00867
00868 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
00869 {
00870 va_list args;
00871 char buf[1024];
00872
00873 va_start(args, fmt);
00874 vsnprintf(buf, 1024, fmt, args);
00875 va_end(args);
00876
00877 ast_log(LOG_ERROR, "%s", buf);
00878 }
00879
00880 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
00881 {
00882 va_list args;
00883 char buf[1024];
00884
00885 va_start(args, fmt);
00886 vsnprintf(buf, 1024, fmt, args);
00887 va_end(args);
00888
00889 ast_log(LOG_WARNING, "%s", buf);
00890 }
00891
00892 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
00893 {
00894 va_list args;
00895 char buf[1024];
00896
00897 va_start(args, fmt);
00898 vsnprintf(buf, 1024, fmt, args);
00899 va_end(args);
00900
00901 ast_verbose("%s", buf);
00902 }
00903
00904
00905 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00906 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 static struct ao2_container *iax_peercallno_pvts;
00918
00919
00920
00921
00922
00923
00924 static struct ao2_container *iax_transfercallno_pvts;
00925
00926
00927
00928 #define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2
00929
00930 static int maxtrunkcall = TRUNK_CALL_START;
00931 static int maxnontrunkcall = 1;
00932
00933 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);
00934 static int expire_registry(const void *data);
00935 static int iax2_answer(struct ast_channel *c);
00936 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00937 static int iax2_devicestate(void *data);
00938 static int iax2_digit_begin(struct ast_channel *c, char digit);
00939 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00940 static int iax2_do_register(struct iax2_registry *reg);
00941 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00942 static int iax2_hangup(struct ast_channel *c);
00943 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00944 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00945 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00946 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00947 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00948 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00949 static int iax2_sendtext(struct ast_channel *c, const char *text);
00950 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00951 static int iax2_transfer(struct ast_channel *c, const char *dest);
00952 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00953 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00954 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00955 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00956 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00957 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00958 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00959 static struct ast_frame *iax2_read(struct ast_channel *c);
00960 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00961 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00962 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00963 static void prune_peers(void);
00964 static void prune_users(void);
00965 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
00966 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
00967 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
00968 static void build_rand_pad(unsigned char *buf, ssize_t len);
00969 static struct callno_entry *get_unused_callno(int trunk, int validated);
00970 static int replace_callno(const void *obj);
00971 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
00972
00973 static const struct ast_channel_tech iax2_tech = {
00974 .type = "IAX2",
00975 .description = tdesc,
00976 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00977 .properties = AST_CHAN_TP_WANTSJITTER,
00978 .requester = iax2_request,
00979 .devicestate = iax2_devicestate,
00980 .send_digit_begin = iax2_digit_begin,
00981 .send_digit_end = iax2_digit_end,
00982 .send_text = iax2_sendtext,
00983 .send_image = iax2_sendimage,
00984 .send_html = iax2_sendhtml,
00985 .call = iax2_call,
00986 .hangup = iax2_hangup,
00987 .answer = iax2_answer,
00988 .read = iax2_read,
00989 .write = iax2_write,
00990 .write_video = iax2_write,
00991 .indicate = iax2_indicate,
00992 .setoption = iax2_setoption,
00993 .bridge = iax2_bridge,
00994 .transfer = iax2_transfer,
00995 .fixup = iax2_fixup,
00996 };
00997
00998
00999
01000
01001 static void insert_idle_thread(struct iax2_thread *thread)
01002 {
01003 if (thread->type == IAX_TYPE_DYNAMIC) {
01004 AST_LIST_LOCK(&dynamic_list);
01005 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01006 AST_LIST_UNLOCK(&dynamic_list);
01007 } else {
01008 AST_LIST_LOCK(&idle_list);
01009 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01010 AST_LIST_UNLOCK(&idle_list);
01011 }
01012
01013 return;
01014 }
01015
01016 static struct iax2_thread *find_idle_thread(void)
01017 {
01018 pthread_attr_t attr;
01019 struct iax2_thread *thread = NULL;
01020
01021
01022 AST_LIST_LOCK(&idle_list);
01023 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01024 AST_LIST_UNLOCK(&idle_list);
01025
01026
01027 if (thread == NULL) {
01028 AST_LIST_LOCK(&dynamic_list);
01029 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01030
01031 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
01032
01033 if ((thread = ast_calloc(1, sizeof(*thread)))) {
01034 thread->threadnum = iaxdynamicthreadnum++;
01035 thread->type = IAX_TYPE_DYNAMIC;
01036 ast_mutex_init(&thread->lock);
01037 ast_cond_init(&thread->cond, NULL);
01038 pthread_attr_init(&attr);
01039 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
01040 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
01041 free(thread);
01042 thread = NULL;
01043 } else {
01044
01045 iaxdynamicthreadcount++;
01046
01047
01048 while (!thread->ready_for_signal)
01049 usleep(1);
01050 }
01051 }
01052 }
01053 AST_LIST_UNLOCK(&dynamic_list);
01054 }
01055
01056
01057
01058 if (thread)
01059 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01060
01061 return thread;
01062 }
01063
01064 #ifdef SCHED_MULTITHREADED
01065 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01066 {
01067 struct iax2_thread *thread = NULL;
01068 static time_t lasterror;
01069 static time_t t;
01070
01071 thread = find_idle_thread();
01072
01073 if (thread != NULL) {
01074 thread->schedfunc = func;
01075 thread->scheddata = data;
01076 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01077 #ifdef DEBUG_SCHED_MULTITHREAD
01078 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01079 #endif
01080 signal_condition(&thread->lock, &thread->cond);
01081 return 0;
01082 }
01083 time(&t);
01084 if (t != lasterror && option_debug)
01085 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
01086 lasterror = t;
01087
01088 return -1;
01089 }
01090 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01091 #endif
01092
01093 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01094 {
01095 int res;
01096
01097 ast_mutex_lock(&sched_lock);
01098 res = ast_sched_add(con, when, callback, data);
01099 ast_cond_signal(&sched_cond);
01100 ast_mutex_unlock(&sched_lock);
01101
01102 return res;
01103 }
01104
01105 static int send_ping(const void *data);
01106
01107 static void __send_ping(const void *data)
01108 {
01109 int callno = (long) data;
01110
01111 ast_mutex_lock(&iaxsl[callno]);
01112
01113 if (iaxs[callno]) {
01114 if (iaxs[callno]->peercallno) {
01115 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01116 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01117 } else {
01118
01119 iaxs[callno]->pingid = -1;
01120 }
01121 } else if (option_debug > 0) {
01122 ast_log(LOG_DEBUG, "I was supposed to send a PING with callno %d, but no such call exists (and I cannot remove pingid, either).\n", callno);
01123 }
01124
01125 ast_mutex_unlock(&iaxsl[callno]);
01126 }
01127
01128 static int send_ping(const void *data)
01129 {
01130 #ifdef SCHED_MULTITHREADED
01131 if (schedule_action(__send_ping, data))
01132 #endif
01133 __send_ping(data);
01134
01135 return 0;
01136 }
01137
01138 static int get_encrypt_methods(const char *s)
01139 {
01140 int e;
01141 if (!strcasecmp(s, "aes128"))
01142 e = IAX_ENCRYPT_AES128;
01143 else if (ast_true(s))
01144 e = IAX_ENCRYPT_AES128;
01145 else
01146 e = 0;
01147 return e;
01148 }
01149
01150 static int send_lagrq(const void *data);
01151
01152 static void __send_lagrq(const void *data)
01153 {
01154 int callno = (long) data;
01155
01156 ast_mutex_lock(&iaxsl[callno]);
01157
01158 if (iaxs[callno]) {
01159 if (iaxs[callno]->peercallno) {
01160 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01161 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01162 } else {
01163
01164 iaxs[callno]->lagid = -1;
01165 }
01166 } else {
01167 ast_log(LOG_WARNING, "I was supposed to send a LAGRQ with callno %d, but no such call exists (and I cannot remove lagid, either).\n", callno);
01168 }
01169
01170 ast_mutex_unlock(&iaxsl[callno]);
01171 }
01172
01173 static int send_lagrq(const void *data)
01174 {
01175 #ifdef SCHED_MULTITHREADED
01176 if (schedule_action(__send_lagrq, data))
01177 #endif
01178 __send_lagrq(data);
01179
01180 return 0;
01181 }
01182
01183 static unsigned char compress_subclass(int subclass)
01184 {
01185 int x;
01186 int power=-1;
01187
01188 if (subclass < IAX_FLAG_SC_LOG)
01189 return subclass;
01190
01191 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01192 if (subclass & (1 << x)) {
01193 if (power > -1) {
01194 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01195 return 0;
01196 } else
01197 power = x;
01198 }
01199 }
01200 return power | IAX_FLAG_SC_LOG;
01201 }
01202
01203 static int uncompress_subclass(unsigned char csub)
01204 {
01205
01206 if (csub & IAX_FLAG_SC_LOG) {
01207
01208 if (csub == 0xff)
01209 return -1;
01210 else
01211 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01212 }
01213 else
01214 return csub;
01215 }
01216
01217
01218
01219
01220 static int peer_hash_cb(const void *obj, const int flags)
01221 {
01222 const struct iax2_peer *peer = obj;
01223
01224 return ast_str_hash(peer->name);
01225 }
01226
01227
01228
01229
01230 static int peer_cmp_cb(void *obj, void *arg, int flags)
01231 {
01232 struct iax2_peer *peer = obj, *peer2 = arg;
01233
01234 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01235 }
01236
01237
01238
01239
01240 static int user_hash_cb(const void *obj, const int flags)
01241 {
01242 const struct iax2_user *user = obj;
01243
01244 return ast_str_hash(user->name);
01245 }
01246
01247
01248
01249
01250 static int user_cmp_cb(void *obj, void *arg, int flags)
01251 {
01252 struct iax2_user *user = obj, *user2 = arg;
01253
01254 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01255 }
01256
01257
01258
01259
01260
01261 static struct iax2_peer *find_peer(const char *name, int realtime)
01262 {
01263 struct iax2_peer *peer = NULL;
01264 struct iax2_peer tmp_peer = {
01265 .name = name,
01266 };
01267
01268 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01269
01270
01271 if(!peer && realtime)
01272 peer = realtime_peer(name, NULL);
01273
01274 return peer;
01275 }
01276
01277 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01278 {
01279 ao2_ref(peer, +1);
01280 return peer;
01281 }
01282
01283 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01284 {
01285 ao2_ref(peer, -1);
01286 return NULL;
01287 }
01288
01289 static struct iax2_user *find_user(const char *name)
01290 {
01291 struct iax2_user tmp_user = {
01292 .name = name,
01293 };
01294
01295 return ao2_find(users, &tmp_user, OBJ_POINTER);
01296 }
01297
01298 static inline struct iax2_user *user_ref(struct iax2_user *user)
01299 {
01300 ao2_ref(user, +1);
01301 return user;
01302 }
01303
01304 static inline struct iax2_user *user_unref(struct iax2_user *user)
01305 {
01306 ao2_ref(user, -1);
01307 return NULL;
01308 }
01309
01310 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01311 {
01312 struct iax2_peer *peer = NULL;
01313 int res = 0;
01314 struct ao2_iterator i;
01315
01316 i = ao2_iterator_init(peers, 0);
01317 while ((peer = ao2_iterator_next(&i))) {
01318 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01319 (peer->addr.sin_port == sin.sin_port)) {
01320 ast_copy_string(host, peer->name, len);
01321 peer_unref(peer);
01322 res = 1;
01323 break;
01324 }
01325 peer_unref(peer);
01326 }
01327
01328 if (!peer) {
01329 peer = realtime_peer(NULL, &sin);
01330 if (peer) {
01331 ast_copy_string(host, peer->name, len);
01332 peer_unref(peer);
01333 res = 1;
01334 }
01335 }
01336
01337 return res;
01338 }
01339
01340 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01341 {
01342
01343 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01344 struct iax2_user *user;
01345 struct iax2_user tmp_user = {
01346 .name = pvt->username,
01347 };
01348
01349 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01350 if (user) {
01351 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01352 user = user_unref(user);
01353 }
01354
01355 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01356 }
01357
01358
01359 AST_SCHED_DEL(sched, pvt->pingid);
01360 AST_SCHED_DEL(sched, pvt->lagid);
01361 AST_SCHED_DEL(sched, pvt->autoid);
01362 AST_SCHED_DEL(sched, pvt->authid);
01363 AST_SCHED_DEL(sched, pvt->initid);
01364 AST_SCHED_DEL(sched, pvt->jbid);
01365 }
01366
01367 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01368 {
01369 if (!pvt->transfercallno) {
01370 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01371 return;
01372 }
01373
01374 ao2_link(iax_transfercallno_pvts, pvt);
01375 }
01376
01377 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01378 {
01379 if (!pvt->transfercallno) {
01380 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01381 return;
01382 }
01383
01384 ao2_unlink(iax_transfercallno_pvts, pvt);
01385 }
01386 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01387 {
01388 if (!pvt->peercallno) {
01389 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01390 return;
01391 }
01392
01393 ao2_link(iax_peercallno_pvts, pvt);
01394 }
01395
01396 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01397 {
01398 if (!pvt->peercallno) {
01399 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01400 return;
01401 }
01402
01403 ao2_unlink(iax_peercallno_pvts, pvt);
01404 }
01405
01406 static void update_max_trunk(void)
01407 {
01408 int max = TRUNK_CALL_START;
01409 int x;
01410
01411
01412 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01413 if (iaxs[x]) {
01414 max = x + 1;
01415 }
01416 }
01417
01418 maxtrunkcall = max;
01419 if (option_debug && iaxdebug)
01420 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01421 }
01422
01423 static void iax2_frame_free(struct iax_frame *fr)
01424 {
01425 AST_SCHED_DEL(sched, fr->retrans);
01426 iax_frame_free(fr);
01427 }
01428
01429 static void iax2_destroy(int callno)
01430 {
01431 struct chan_iax2_pvt *pvt;
01432 struct ast_channel *owner;
01433
01434 retry:
01435 pvt = iaxs[callno];
01436
01437 owner = pvt ? pvt->owner : NULL;
01438
01439 if (owner) {
01440 if (ast_mutex_trylock(&owner->lock)) {
01441 if (option_debug > 2)
01442 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01443 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01444 goto retry;
01445 }
01446 }
01447
01448
01449
01450
01451 if (!owner && pvt) {
01452 ao2_ref(pvt, +1);
01453 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]);
01454 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]);
01455 ao2_ref(pvt, -1);
01456 if (iaxs[callno]) {
01457 iaxs[callno] = NULL;
01458 } else {
01459 pvt = NULL;
01460 }
01461 }
01462
01463 if (pvt) {
01464 if (!owner) {
01465 pvt->owner = NULL;
01466 } else {
01467
01468
01469
01470 ast_queue_hangup(owner);
01471 }
01472
01473 if (pvt->peercallno) {
01474 remove_by_peercallno(pvt);
01475 }
01476
01477 if (pvt->transfercallno) {
01478 remove_by_transfercallno(pvt);
01479 }
01480
01481 if (!owner) {
01482 ao2_ref(pvt, -1);
01483 pvt = NULL;
01484 }
01485 }
01486
01487 if (owner) {
01488 ast_mutex_unlock(&owner->lock);
01489 }
01490
01491 if (callno & 0x4000) {
01492 update_max_trunk();
01493 }
01494 }
01495
01496 static int scheduled_destroy(const void *vid)
01497 {
01498 short callno = PTR_TO_CALLNO(vid);
01499 ast_mutex_lock(&iaxsl[callno]);
01500 if (iaxs[callno]) {
01501 if (option_debug) {
01502 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01503 }
01504 iax2_destroy(callno);
01505 }
01506 ast_mutex_unlock(&iaxsl[callno]);
01507 return 0;
01508 }
01509
01510 static void pvt_destructor(void *obj)
01511 {
01512 struct chan_iax2_pvt *pvt = obj;
01513 struct iax_frame *cur = NULL;
01514
01515 iax2_destroy_helper(pvt);
01516 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01517 pvt->callno_entry = NULL;
01518
01519
01520 ast_set_flag(pvt, IAX_ALREADYGONE);
01521
01522 AST_LIST_LOCK(&iaxq.queue);
01523 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01524
01525 if (cur->callno == pvt->callno) {
01526 cur->retries = -1;
01527 }
01528 }
01529 AST_LIST_UNLOCK(&iaxq.queue);
01530
01531 if (pvt->reg) {
01532 pvt->reg->callno = 0;
01533 }
01534
01535 if (!pvt->owner) {
01536 jb_frame frame;
01537 if (pvt->vars) {
01538 ast_variables_destroy(pvt->vars);
01539 pvt->vars = NULL;
01540 }
01541
01542 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01543 iax2_frame_free(frame.data);
01544 }
01545
01546 jb_destroy(pvt->jb);
01547 ast_string_field_free_memory(pvt);
01548 }
01549 }
01550
01551 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01552 {
01553 struct chan_iax2_pvt *tmp;
01554 jb_conf jbconf;
01555
01556 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01557 return NULL;
01558 }
01559
01560 if (ast_string_field_init(tmp, 32)) {
01561 ao2_ref(tmp, -1);
01562 tmp = NULL;
01563 return NULL;
01564 }
01565
01566 tmp->prefs = prefs;
01567 tmp->callno = 0;
01568 tmp->peercallno = 0;
01569 tmp->transfercallno = 0;
01570 tmp->bridgecallno = 0;
01571 tmp->pingid = -1;
01572 tmp->lagid = -1;
01573 tmp->autoid = -1;
01574 tmp->authid = -1;
01575 tmp->initid = -1;
01576
01577 ast_string_field_set(tmp,exten, "s");
01578 ast_string_field_set(tmp,host, host);
01579
01580 tmp->jb = jb_new();
01581 tmp->jbid = -1;
01582 jbconf.max_jitterbuf = maxjitterbuffer;
01583 jbconf.resync_threshold = resyncthreshold;
01584 jbconf.max_contig_interp = maxjitterinterps;
01585 jb_setconf(tmp->jb,&jbconf);
01586
01587 return tmp;
01588 }
01589
01590 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01591 {
01592 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01593 if (new) {
01594 size_t afdatalen = new->afdatalen;
01595 memcpy(new, fr, sizeof(*new));
01596 iax_frame_wrap(new, &fr->af);
01597 new->afdatalen = afdatalen;
01598 new->data = NULL;
01599 new->datalen = 0;
01600 new->direction = DIRECTION_INGRESS;
01601 new->retrans = -1;
01602 }
01603 return new;
01604 }
01605
01606
01607
01608 enum {
01609
01610 NEW_PREVENT = 0,
01611
01612 NEW_ALLOW = 1,
01613
01614 NEW_FORCE = 2,
01615
01616
01617 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01618 };
01619
01620 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01621 {
01622 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01623 (cur->addr.sin_port == sin->sin_port)) {
01624
01625 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01626 (check_dcallno ? dcallno == cur->callno : 1) ) {
01627
01628 return 1;
01629 }
01630 }
01631 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01632 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01633
01634 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01635 return 1;
01636 }
01637 return 0;
01638 }
01639
01640 static void update_max_nontrunk(void)
01641 {
01642 int max = 1;
01643 int x;
01644
01645 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01646 if (iaxs[x])
01647 max = x + 1;
01648 }
01649 maxnontrunkcall = max;
01650 if (option_debug && iaxdebug)
01651 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01652 }
01653
01654 static int make_trunk(unsigned short callno, int locked)
01655 {
01656 int x;
01657 int res= 0;
01658 struct callno_entry *callno_entry;
01659 if (iaxs[callno]->oseqno) {
01660 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01661 return -1;
01662 }
01663 if (callno & TRUNK_CALL_START) {
01664 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01665 return -1;
01666 }
01667 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
01668 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01669 return -1;
01670 }
01671
01672 x = callno_entry->callno;
01673 ast_mutex_lock(&iaxsl[x]);
01674
01675
01676
01677
01678
01679 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01680 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01681 iaxs[x] = iaxs[callno];
01682 iaxs[x]->callno = x;
01683
01684
01685
01686 if (iaxs[x]->callno_entry) {
01687 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
01688 }
01689 iaxs[x]->callno_entry = callno_entry;
01690
01691 iaxs[callno] = NULL;
01692
01693 iaxs[x]->pingid = iax2_sched_add(sched,
01694 ping_time * 1000, send_ping, (void *)(long)x);
01695 iaxs[x]->lagid = iax2_sched_add(sched,
01696 lagrq_time * 1000, send_lagrq, (void *)(long)x);
01697
01698 if (locked)
01699 ast_mutex_unlock(&iaxsl[callno]);
01700 res = x;
01701 if (!locked)
01702 ast_mutex_unlock(&iaxsl[x]);
01703
01704 if (option_debug)
01705 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01706
01707 update_max_trunk();
01708 update_max_nontrunk();
01709 return res;
01710 }
01711
01712 static int addr_range_delme_cb(void *obj, void *arg, int flags)
01713 {
01714 struct addr_range *lim = obj;
01715 lim->delme = 1;
01716 return 0;
01717 }
01718
01719 static int addr_range_hash_cb(const void *obj, const int flags)
01720 {
01721 const struct addr_range *lim = obj;
01722 return abs((int) lim->ha.netaddr.s_addr);
01723 }
01724
01725 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
01726 {
01727 struct addr_range *lim1 = obj, *lim2 = arg;
01728 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
01729 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
01730 CMP_MATCH | CMP_STOP : 0;
01731 }
01732
01733 static int peercnt_hash_cb(const void *obj, const int flags)
01734 {
01735 const struct peercnt *peercnt = obj;
01736 return abs((int) peercnt->addr);
01737 }
01738
01739 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
01740 {
01741 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
01742 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
01743 }
01744
01745 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
01746 {
01747 struct addr_range *addr_range = obj;
01748 struct sockaddr_in *sin = arg;
01749
01750 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
01751 return CMP_MATCH | CMP_STOP;
01752 }
01753 return 0;
01754 }
01755
01756
01757
01758
01759
01760
01761 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
01762 {
01763 struct addr_range *addr_range;
01764 struct iax2_peer *peer = NULL;
01765 struct iax2_user *user = NULL;
01766
01767 const char *find = S_OR(name, "guest");
01768 int res = 1;
01769 int optional = 0;
01770 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
01771
01772
01773
01774
01775
01776
01777
01778 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
01779 ao2_ref(addr_range, -1);
01780 optional = 1;
01781 }
01782
01783
01784 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
01785 calltoken_required = user->calltoken_required;
01786 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 1))) {
01787 calltoken_required = peer->calltoken_required;
01788 }
01789
01790 if (peer) {
01791 peer_unref(peer);
01792 }
01793 if (user) {
01794 user_unref(user);
01795 }
01796 if (option_debug) {
01797 ast_log(LOG_DEBUG, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required);
01798 }
01799 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
01800 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
01801 res = 0;
01802 }
01803
01804 return res;
01805 }
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817 static void set_peercnt_limit(struct peercnt *peercnt)
01818 {
01819 uint16_t limit = global_maxcallno;
01820 struct addr_range *addr_range;
01821 struct sockaddr_in sin = {
01822 .sin_addr.s_addr = peercnt->addr,
01823 };
01824
01825
01826 if (peercnt->reg && peercnt->limit) {
01827 return;
01828 }
01829
01830 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
01831 limit = addr_range->limit;
01832 if (option_debug) {
01833 ast_log(LOG_NOTICE, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
01834 }
01835 ao2_ref(addr_range, -1);
01836 }
01837
01838 peercnt->limit = limit;
01839 }
01840
01841
01842
01843
01844
01845 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
01846 {
01847 struct peercnt *peercnt = obj;
01848
01849 set_peercnt_limit(peercnt);
01850 if (option_debug) {
01851 ast_log(LOG_NOTICE, "Reset limits for peercnts table\n");
01852 }
01853 return 0;
01854 }
01855
01856
01857
01858
01859
01860 static int prune_addr_range_cb(void *obj, void *arg, int flags)
01861 {
01862 struct addr_range *addr_range = obj;
01863
01864 return addr_range->delme ? CMP_MATCH : 0;
01865 }
01866
01867
01868
01869
01870
01871 static void peercnt_modify(unsigned char reg, uint16_t limit, struct sockaddr_in *sin)
01872 {
01873
01874 struct peercnt *peercnt;
01875 struct peercnt tmp = {
01876 .addr = sin->sin_addr.s_addr,
01877 };
01878
01879 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
01880 peercnt->reg = reg;
01881 if (limit) {
01882 peercnt->limit = limit;
01883 } else {
01884 set_peercnt_limit(peercnt);
01885 }
01886 if (option_debug) {
01887 ast_log(LOG_NOTICE, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg);
01888 }
01889 ao2_ref(peercnt, -1);
01890 }
01891 }
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901 static int peercnt_add(struct sockaddr_in *sin)
01902 {
01903 struct peercnt *peercnt;
01904 unsigned long addr = sin->sin_addr.s_addr;
01905 int res = 0;
01906 struct peercnt tmp = {
01907 .addr = addr,
01908 };
01909
01910
01911
01912
01913
01914
01915
01916 ao2_lock(peercnts);
01917 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
01918 ao2_lock(peercnt);
01919 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
01920 ao2_lock(peercnt);
01921
01922 peercnt->addr = addr;
01923 set_peercnt_limit(peercnt);
01924
01925
01926 ao2_link(peercnts, peercnt);
01927 } else {
01928 ao2_unlock(peercnts);
01929 return -1;
01930 }
01931
01932
01933 if (peercnt->limit > peercnt->cur) {
01934 peercnt->cur++;
01935 if (option_debug) {
01936 ast_log(LOG_NOTICE, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
01937 }
01938 } else {
01939 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
01940 res = -1;
01941 }
01942
01943
01944 ao2_unlock(peercnt);
01945 ao2_unlock(peercnts);
01946 ao2_ref(peercnt, -1);
01947
01948 return res;
01949 }
01950
01951
01952
01953
01954
01955 static void peercnt_remove(struct peercnt *peercnt)
01956 {
01957 struct sockaddr_in sin = {
01958 .sin_addr.s_addr = peercnt->addr,
01959 };
01960
01961 if (peercnt) {
01962
01963
01964
01965 ao2_lock(peercnts);
01966 peercnt->cur--;
01967 if (option_debug) {
01968 ast_log(LOG_NOTICE, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
01969 }
01970
01971 if (peercnt->cur == 0) {
01972 ao2_unlink(peercnts, peercnt);
01973 }
01974 ao2_unlock(peercnts);
01975 }
01976 }
01977
01978
01979
01980
01981
01982 static int peercnt_remove_cb(const void *obj)
01983 {
01984 struct peercnt *peercnt = (struct peercnt *) obj;
01985
01986 peercnt_remove(peercnt);
01987 ao2_ref(peercnt, -1);
01988
01989 return 0;
01990 }
01991
01992
01993
01994
01995
01996 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
01997 {
01998 struct peercnt *peercnt;
01999 struct peercnt tmp = {
02000 .addr = sin->sin_addr.s_addr,
02001 };
02002
02003 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02004 peercnt_remove(peercnt);
02005 ao2_ref(peercnt, -1);
02006 }
02007 return 0;
02008 }
02009
02010
02011
02012
02013
02014 static void build_callno_limits(struct ast_variable *v)
02015 {
02016 struct addr_range *addr_range = NULL;
02017 struct addr_range tmp;
02018 struct ast_ha *ha;
02019 int limit;
02020 int found;
02021
02022 for (; v; v = v->next) {
02023 limit = -1;
02024 found = 0;
02025 ha = ast_append_ha("permit", v->name, NULL);
02026
02027
02028 if (!ha) {
02029 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02030 continue;
02031 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02032 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02033 ast_free_ha(ha);
02034 continue;
02035 }
02036
02037 ast_copy_ha(ha, &tmp.ha);
02038
02039 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02040 ao2_lock(addr_range);
02041 found = 1;
02042 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02043 ast_free_ha(ha);
02044 return;
02045 }
02046
02047
02048 ast_copy_ha(ha, &addr_range->ha);
02049 ast_free_ha(ha);
02050 addr_range->limit = limit;
02051 addr_range->delme = 0;
02052
02053
02054 if (found) {
02055 ao2_unlock(addr_range);
02056 } else {
02057 ao2_link(callno_limits, addr_range);
02058 }
02059 ao2_ref(addr_range, -1);
02060 }
02061 }
02062
02063
02064
02065
02066
02067 static int add_calltoken_ignore(const char *addr)
02068 {
02069 struct addr_range tmp;
02070 struct addr_range *addr_range = NULL;
02071 struct ast_ha *ha = NULL;
02072
02073 if (ast_strlen_zero(addr)) {
02074 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02075 return -1;
02076 }
02077
02078 ha = ast_append_ha("permit", addr, NULL);
02079
02080
02081 if (!ha) {
02082 ast_log(LOG_WARNING, "Error creating calltokenoptional entry %s\n", addr);
02083 return -1;
02084 }
02085
02086 ast_copy_ha(ha, &tmp.ha);
02087
02088 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02089 ao2_lock(addr_range);
02090 addr_range->delme = 0;
02091 ao2_unlock(addr_range);
02092 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02093
02094 ast_copy_ha(ha, &addr_range->ha);
02095 ao2_link(calltoken_ignores, addr_range);
02096 } else {
02097 ast_free_ha(ha);
02098 return -1;
02099 }
02100
02101 ast_free_ha(ha);
02102 ao2_ref(addr_range, -1);
02103
02104 return 0;
02105 }
02106
02107 static int iax2_show_callnumber_usage(int fd, int argc, char *argv[])
02108 {
02109 struct ao2_iterator i;
02110 struct peercnt *peercnt;
02111 struct sockaddr_in sin;
02112 int found = 0;
02113
02114 if (argc < 4 || argc > 5)
02115 return RESULT_SHOWUSAGE;
02116
02117 ast_cli(fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02118 i = ao2_iterator_init(peercnts, 0);
02119 while ((peercnt = ao2_iterator_next(&i))) {
02120 sin.sin_addr.s_addr = peercnt->addr;
02121 if (argc == 5 && (!strcasecmp(argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02122 ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02123 found = 1;
02124 break;
02125 } else {
02126 ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02127 }
02128 ao2_ref(peercnt, -1);
02129 }
02130 if (argc == 4) {
02131 ast_cli(fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
02132 } else if (argc == 5 && !found) {
02133 ast_cli(fd, "No callnumber table entries for %s found\n", argv[4] );
02134 }
02135 return RESULT_SUCCESS;
02136 }
02137
02138 static struct callno_entry *get_unused_callno(int trunk, int validated)
02139 {
02140 struct callno_entry *callno_entry = NULL;
02141 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02142 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02143
02144 return NULL;
02145 }
02146
02147
02148
02149 ao2_lock(callno_pool);
02150
02151
02152
02153
02154 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02155 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02156 ao2_unlock(callno_pool);
02157 return NULL;
02158 }
02159
02160
02161
02162 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02163
02164 if (callno_entry) {
02165 callno_entry->validated = validated;
02166 if (!validated) {
02167 total_nonval_callno_used++;
02168 }
02169 }
02170
02171 ao2_unlock(callno_pool);
02172 return callno_entry;
02173 }
02174
02175 static int replace_callno(const void *obj)
02176 {
02177 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02178
02179
02180
02181 ao2_lock(callno_pool);
02182
02183 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02184 total_nonval_callno_used--;
02185 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02186 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02187 }
02188
02189 if (callno_entry->callno < TRUNK_CALL_START) {
02190 ao2_link(callno_pool, callno_entry);
02191 } else {
02192 ao2_link(callno_pool_trunk, callno_entry);
02193 }
02194 ao2_ref(callno_entry, -1);
02195
02196 ao2_unlock(callno_pool);
02197 return 0;
02198 }
02199
02200 static int callno_hash(const void *obj, const int flags)
02201 {
02202 return abs(ast_random());
02203 }
02204
02205 static int create_callno_pools(void)
02206 {
02207 uint16_t i;
02208
02209 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02210 return -1;
02211 }
02212
02213 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02214 return -1;
02215 }
02216
02217
02218 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02219 struct callno_entry *callno_entry;
02220
02221 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02222 return -1;
02223 }
02224
02225 callno_entry->callno = i;
02226
02227 if (i < TRUNK_CALL_START) {
02228 ao2_link(callno_pool, callno_entry);
02229 } else {
02230 ao2_link(callno_pool_trunk, callno_entry);
02231 }
02232
02233 ao2_ref(callno_entry, -1);
02234 }
02235
02236 return 0;
02237 }
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02248 {
02249 int i;
02250 struct peercnt *peercnt;
02251 struct peercnt tmp = {
02252 .addr = sin->sin_addr.s_addr,
02253 };
02254
02255 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02256
02257 if (option_debug) {
02258 ast_log(LOG_NOTICE, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02259 }
02260 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02261 if (i == -1) {
02262 ao2_ref(peercnt, -1);
02263 }
02264 }
02265
02266 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02267 }
02268
02269
02270
02271
02272
02273
02274
02275
02276 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02277 {
02278 if (frametype != AST_FRAME_IAX) {
02279 return 0;
02280 }
02281 switch (subclass) {
02282 case IAX_COMMAND_NEW:
02283 case IAX_COMMAND_REGREQ:
02284 case IAX_COMMAND_FWDOWNL:
02285 case IAX_COMMAND_REGREL:
02286 return 1;
02287 case IAX_COMMAND_POKE:
02288 if (!inbound) {
02289 return 1;
02290 }
02291 break;
02292 }
02293 return 0;
02294 }
02295
02296
02297
02298
02299 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02300 {
02301 int res = 0;
02302 int x;
02303
02304
02305 int validated = (new > NEW_ALLOW) ? 1 : 0;
02306 char host[80];
02307
02308 if (new <= NEW_ALLOW) {
02309 if (callno) {
02310 struct chan_iax2_pvt *pvt;
02311 struct chan_iax2_pvt tmp_pvt = {
02312 .callno = dcallno,
02313 .peercallno = callno,
02314 .transfercallno = callno,
02315
02316 .frames_received = check_dcallno,
02317 };
02318
02319 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02320
02321 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02322 if (return_locked) {
02323 ast_mutex_lock(&iaxsl[pvt->callno]);
02324 }
02325 res = pvt->callno;
02326 ao2_ref(pvt, -1);
02327 pvt = NULL;
02328 return res;
02329 }
02330
02331 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02332 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr));
02333 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02334 if (return_locked) {
02335 ast_mutex_lock(&iaxsl[pvt->callno]);
02336 }
02337 res = pvt->callno;
02338 ao2_ref(pvt, -1);
02339 pvt = NULL;
02340 return res;
02341 }
02342 }
02343
02344
02345 if (dcallno) {
02346 ast_mutex_lock(&iaxsl[dcallno]);
02347 }
02348 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02349 iaxs[dcallno]->peercallno = callno;
02350 res = dcallno;
02351 store_by_peercallno(iaxs[dcallno]);
02352 if (!res || !return_locked) {
02353 ast_mutex_unlock(&iaxsl[dcallno]);
02354 }
02355 return res;
02356 }
02357 if (dcallno) {
02358 ast_mutex_unlock(&iaxsl[dcallno]);
02359 }
02360 #ifdef IAX_OLD_FIND
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372 for (x = 1; !res && x < maxnontrunkcall; x++) {
02373 ast_mutex_lock(&iaxsl[x]);
02374 if (iaxs[x]) {
02375
02376 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02377 res = x;
02378 }
02379 }
02380 if (!res || !return_locked)
02381 ast_mutex_unlock(&iaxsl[x]);
02382 }
02383
02384 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02385 ast_mutex_lock(&iaxsl[x]);
02386 if (iaxs[x]) {
02387
02388 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02389 res = x;
02390 }
02391 }
02392 if (!res || !return_locked)
02393 ast_mutex_unlock(&iaxsl[x]);
02394 }
02395
02396 if (res) {
02397 ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res);
02398 }
02399 #endif
02400 }
02401 if (!res && (new >= NEW_ALLOW)) {
02402 struct callno_entry *callno_entry;
02403
02404
02405
02406
02407
02408
02409 if (!iax2_getpeername(*sin, host, sizeof(host)))
02410 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02411
02412 if (peercnt_add(sin)) {
02413
02414
02415 return 0;
02416 }
02417
02418 if (!(callno_entry = get_unused_callno(0, validated))) {
02419
02420
02421 peercnt_remove_by_addr(sin);
02422 ast_log(LOG_WARNING, "No more space\n");
02423 return 0;
02424 }
02425 x = callno_entry->callno;
02426 ast_mutex_lock(&iaxsl[x]);
02427
02428 iaxs[x] = new_iax(sin, host);
02429 update_max_nontrunk();
02430 if (iaxs[x]) {
02431 if (option_debug && iaxdebug)
02432 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
02433 iaxs[x]->callno_entry = callno_entry;
02434 iaxs[x]->sockfd = sockfd;
02435 iaxs[x]->addr.sin_port = sin->sin_port;
02436 iaxs[x]->addr.sin_family = sin->sin_family;
02437 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02438 iaxs[x]->peercallno = callno;
02439 iaxs[x]->callno = x;
02440 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02441 iaxs[x]->expiry = min_reg_expire;
02442 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02443 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02444 iaxs[x]->amaflags = amaflags;
02445 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02446
02447 ast_string_field_set(iaxs[x], accountcode, accountcode);
02448 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02449 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02450
02451 if (iaxs[x]->peercallno) {
02452 store_by_peercallno(iaxs[x]);
02453 }
02454 } else {
02455 ast_log(LOG_WARNING, "Out of resources\n");
02456 ast_mutex_unlock(&iaxsl[x]);
02457 replace_callno(callno_entry);
02458 return 0;
02459 }
02460 if (!return_locked)
02461 ast_mutex_unlock(&iaxsl[x]);
02462 res = x;
02463 }
02464 return res;
02465 }
02466
02467 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02468
02469 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02470 }
02471
02472 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02473
02474 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02475 }
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487 static int iax2_queue_frame(int callno, struct ast_frame *f)
02488 {
02489 for (;;) {
02490 if (iaxs[callno] && iaxs[callno]->owner) {
02491 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
02492
02493 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02494 } else {
02495 ast_queue_frame(iaxs[callno]->owner, f);
02496 ast_mutex_unlock(&iaxs[callno]->owner->lock);
02497 break;
02498 }
02499 } else
02500 break;
02501 }
02502 return 0;
02503 }
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518 static int iax2_queue_hangup(int callno)
02519 {
02520 for (;;) {
02521 if (iaxs[callno] && iaxs[callno]->owner) {
02522 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
02523
02524 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02525 } else {
02526 ast_queue_hangup(iaxs[callno]->owner);
02527 ast_mutex_unlock(&iaxs[callno]->owner->lock);
02528 break;
02529 }
02530 } else
02531 break;
02532 }
02533 return 0;
02534 }
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549 static int iax2_queue_control_data(int callno,
02550 enum ast_control_frame_type control, const void *data, size_t datalen)
02551 {
02552 for (;;) {
02553 if (iaxs[callno] && iaxs[callno]->owner) {
02554 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
02555
02556 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02557 } else {
02558 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02559 ast_mutex_unlock(&iaxs[callno]->owner->lock);
02560 break;
02561 }
02562 } else
02563 break;
02564 }
02565 return 0;
02566 }
02567 static void destroy_firmware(struct iax_firmware *cur)
02568 {
02569
02570 if (cur->fwh) {
02571 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02572 }
02573 close(cur->fd);
02574 free(cur);
02575 }
02576
02577 static int try_firmware(char *s)
02578 {
02579 struct stat stbuf;
02580 struct iax_firmware *cur;
02581 int ifd;
02582 int fd;
02583 int res;
02584
02585 struct ast_iax2_firmware_header *fwh, fwh2;
02586 struct MD5Context md5;
02587 unsigned char sum[16];
02588 unsigned char buf[1024];
02589 int len, chunk;
02590 char *s2;
02591 char *last;
02592 s2 = alloca(strlen(s) + 100);
02593 if (!s2) {
02594 ast_log(LOG_WARNING, "Alloca failed!\n");
02595 return -1;
02596 }
02597 last = strrchr(s, '/');
02598 if (last)
02599 last++;
02600 else
02601 last = s;
02602 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02603 res = stat(s, &stbuf);
02604 if (res < 0) {
02605 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02606 return -1;
02607 }
02608
02609 if (S_ISDIR(stbuf.st_mode))
02610 return -1;
02611 ifd = open(s, O_RDONLY);
02612 if (ifd < 0) {
02613 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02614 return -1;
02615 }
02616 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
02617 if (fd < 0) {
02618 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02619 close(ifd);
02620 return -1;
02621 }
02622
02623 unlink(s2);
02624
02625
02626 len = stbuf.st_size;
02627 while(len) {
02628 chunk = len;
02629 if (chunk > sizeof(buf))
02630 chunk = sizeof(buf);
02631 res = read(ifd, buf, chunk);
02632 if (res != chunk) {
02633 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02634 close(ifd);
02635 close(fd);
02636 return -1;
02637 }
02638 res = write(fd, buf, chunk);
02639 if (res != chunk) {
02640 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02641 close(ifd);
02642 close(fd);
02643 return -1;
02644 }
02645 len -= chunk;
02646 }
02647 close(ifd);
02648
02649 lseek(fd, 0, SEEK_SET);
02650 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02651 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02652 close(fd);
02653 return -1;
02654 }
02655 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02656 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02657 close(fd);
02658 return -1;
02659 }
02660 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02661 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02662 close(fd);
02663 return -1;
02664 }
02665 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02666 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02667 close(fd);
02668 return -1;
02669 }
02670 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
02671 if (fwh == MAP_FAILED) {
02672 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02673 close(fd);
02674 return -1;
02675 }
02676 MD5Init(&md5);
02677 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02678 MD5Final(sum, &md5);
02679 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02680 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02681 munmap((void*)fwh, stbuf.st_size);
02682 close(fd);
02683 return -1;
02684 }
02685 cur = waresl.wares;
02686 while(cur) {
02687 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02688
02689 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02690
02691 break;
02692
02693
02694 munmap((void*)fwh, stbuf.st_size);
02695 close(fd);
02696 return 0;
02697 }
02698 cur = cur->next;
02699 }
02700 if (!cur) {
02701
02702 if ((cur = ast_calloc(1, sizeof(*cur)))) {
02703 cur->fd = -1;
02704 cur->next = waresl.wares;
02705 waresl.wares = cur;
02706 }
02707 }
02708 if (cur) {
02709 if (cur->fwh) {
02710 munmap((void*)cur->fwh, cur->mmaplen);
02711 }
02712 if (cur->fd > -1)
02713 close(cur->fd);
02714 cur->fwh = fwh;
02715 cur->fd = fd;
02716 cur->mmaplen = stbuf.st_size;
02717 cur->dead = 0;
02718 }
02719 return 0;
02720 }
02721
02722 static int iax_check_version(char *dev)
02723 {
02724 int res = 0;
02725 struct iax_firmware *cur;
02726 if (!ast_strlen_zero(dev)) {
02727 ast_mutex_lock(&waresl.lock);
02728 cur = waresl.wares;
02729 while(cur) {
02730 if (!strcmp(dev, (char *)cur->fwh->devname)) {
02731 res = ntohs(cur->fwh->version);
02732 break;
02733 }
02734 cur = cur->next;
02735 }
02736 ast_mutex_unlock(&waresl.lock);
02737 }
02738 return res;
02739 }
02740
02741 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
02742 {
02743 int res = -1;
02744 unsigned int bs = desc & 0xff;
02745 unsigned int start = (desc >> 8) & 0xffffff;
02746 unsigned int bytes;
02747 struct iax_firmware *cur;
02748 if (!ast_strlen_zero((char *)dev) && bs) {
02749 start *= bs;
02750 ast_mutex_lock(&waresl.lock);
02751 cur = waresl.wares;
02752 while(cur) {
02753 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
02754 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02755 if (start < ntohl(cur->fwh->datalen)) {
02756 bytes = ntohl(cur->fwh->datalen) - start;
02757 if (bytes > bs)
02758 bytes = bs;
02759 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02760 } else {
02761 bytes = 0;
02762 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02763 }
02764 if (bytes == bs)
02765 res = 0;
02766 else
02767 res = 1;
02768 break;
02769 }
02770 cur = cur->next;
02771 }
02772 ast_mutex_unlock(&waresl.lock);
02773 }
02774 return res;
02775 }
02776
02777
02778 static void reload_firmware(int unload)
02779 {
02780 struct iax_firmware *cur, *curl, *curp;
02781 DIR *fwd;
02782 struct dirent *de;
02783 char dir[256];
02784 char fn[256];
02785
02786 ast_mutex_lock(&waresl.lock);
02787 cur = waresl.wares;
02788 while(cur) {
02789 cur->dead = 1;
02790 cur = cur->next;
02791 }
02792
02793
02794 if (!unload) {
02795 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
02796 fwd = opendir(dir);
02797 if (fwd) {
02798 while((de = readdir(fwd))) {
02799 if (de->d_name[0] != '.') {
02800 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02801 if (!try_firmware(fn)) {
02802 if (option_verbose > 1)
02803 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
02804 }
02805 }
02806 }
02807 closedir(fwd);
02808 } else
02809 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02810 }
02811
02812
02813 cur = waresl.wares;
02814 curp = NULL;
02815 while(cur) {
02816 curl = cur;
02817 cur = cur->next;
02818 if (curl->dead) {
02819 if (curp) {
02820 curp->next = cur;
02821 } else {
02822 waresl.wares = cur;
02823 }
02824 destroy_firmware(curl);
02825 } else {
02826 curp = cur;
02827 }
02828 }
02829 ast_mutex_unlock(&waresl.lock);
02830 }
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840 static int __do_deliver(void *data)
02841 {
02842
02843
02844 struct iax_frame *fr = data;
02845 fr->retrans = -1;
02846 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02847 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02848 iax2_queue_frame(fr->callno, &fr->af);
02849
02850 iax2_frame_free(fr);
02851
02852 return 0;
02853 }
02854
02855 static int handle_error(void)
02856 {
02857
02858
02859
02860 #if 0
02861 struct sockaddr_in *sin;
02862 int res;
02863 struct msghdr m;
02864 struct sock_extended_err e;
02865 m.msg_name = NULL;
02866 m.msg_namelen = 0;
02867 m.msg_iov = NULL;
02868 m.msg_control = &e;
02869 m.msg_controllen = sizeof(e);
02870 m.msg_flags = 0;
02871 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02872 if (res < 0)
02873 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02874 else {
02875 if (m.msg_controllen) {
02876 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02877 if (sin)
02878 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02879 else
02880 ast_log(LOG_WARNING, "No address detected??\n");
02881 } else {
02882 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02883 }
02884 }
02885 #endif
02886 return 0;
02887 }
02888
02889 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02890 {
02891 int res;
02892 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02893 sizeof(*sin));
02894 if (res < 0) {
02895 if (option_debug)
02896 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02897 handle_error();
02898 } else
02899 res = 0;
02900 return res;
02901 }
02902
02903 static int send_packet(struct iax_frame *f)
02904 {
02905 int res;
02906 int callno = f->callno;
02907
02908
02909 if (!callno || !iaxs[callno] || iaxs[callno]->error)
02910 return -1;
02911
02912
02913 if (option_debug > 2 && iaxdebug)
02914 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));
02915 if (f->transfer) {
02916 if (iaxdebug)
02917 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02918 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02919 sizeof(iaxs[callno]->transfer));
02920 } else {
02921 if (iaxdebug)
02922 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02923 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02924 sizeof(iaxs[callno]->addr));
02925 }
02926 if (res < 0) {
02927 if (option_debug && iaxdebug)
02928 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02929 handle_error();
02930 } else
02931 res = 0;
02932 return res;
02933 }
02934
02935
02936
02937
02938
02939 static int iax2_predestroy(int callno)
02940 {
02941 struct ast_channel *c;
02942 struct chan_iax2_pvt *pvt = iaxs[callno];
02943
02944 if (!pvt)
02945 return -1;
02946 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02947 iax2_destroy_helper(pvt);
02948 ast_set_flag(pvt, IAX_ALREADYGONE);
02949 }
02950 c = pvt->owner;
02951 if (c) {
02952 c->tech_pvt = NULL;
02953 iax2_queue_hangup(callno);
02954 pvt->owner = NULL;
02955 ast_module_unref(ast_module_info->self);
02956 }
02957 return 0;
02958 }
02959
02960 static int update_packet(struct iax_frame *f)
02961 {
02962
02963 struct ast_iax2_full_hdr *fh = f->data;
02964 struct ast_frame af;
02965
02966
02967 if (f->encmethods) {
02968 decode_frame(&f->mydcx, fh, &af, &f->datalen);
02969 }
02970
02971 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02972
02973 f->iseqno = iaxs[f->callno]->iseqno;
02974 fh->iseqno = f->iseqno;
02975
02976
02977 if (f->encmethods) {
02978
02979
02980 build_rand_pad(f->semirand, sizeof(f->semirand));
02981 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
02982 }
02983 return 0;
02984 }
02985
02986 static int attempt_transmit(const void *data);
02987 static void __attempt_transmit(const void *data)
02988 {
02989
02990
02991 struct iax_frame *f = (struct iax_frame *)data;
02992 int freeme=0;
02993 int callno = f->callno;
02994
02995 if (callno)
02996 ast_mutex_lock(&iaxsl[callno]);
02997 if (callno && iaxs[callno]) {
02998 if ((f->retries < 0) ||
02999 (f->retries >= max_retries) ) {
03000
03001 if (f->retries >= max_retries) {
03002 if (f->transfer) {
03003
03004 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03005 } else if (f->final) {
03006 if (f->final)
03007 iax2_destroy(callno);
03008 } else {
03009 if (iaxs[callno]->owner)
03010 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);
03011 iaxs[callno]->error = ETIMEDOUT;
03012 if (iaxs[callno]->owner) {
03013 struct ast_frame fr = { 0, };
03014
03015 fr.frametype = AST_FRAME_CONTROL;
03016 fr.subclass = AST_CONTROL_HANGUP;
03017 iax2_queue_frame(callno, &fr);
03018
03019 if (iaxs[callno] && iaxs[callno]->owner)
03020 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03021 } else {
03022 if (iaxs[callno]->reg) {
03023 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03024 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03025 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03026 }
03027 iax2_destroy(callno);
03028 }
03029 }
03030
03031 }
03032 freeme++;
03033 } else {
03034
03035 update_packet(f);
03036
03037 send_packet(f);
03038 f->retries++;
03039
03040 f->retrytime *= 10;
03041 if (f->retrytime > MAX_RETRY_TIME)
03042 f->retrytime = MAX_RETRY_TIME;
03043
03044 if (f->transfer && (f->retrytime > 1000))
03045 f->retrytime = 1000;
03046 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03047 }
03048 } else {
03049
03050 f->retries = -1;
03051 freeme++;
03052 }
03053 if (callno)
03054 ast_mutex_unlock(&iaxsl[callno]);
03055
03056 if (freeme) {
03057
03058 AST_LIST_LOCK(&iaxq.queue);
03059 AST_LIST_REMOVE(&iaxq.queue, f, list);
03060 iaxq.count--;
03061 AST_LIST_UNLOCK(&iaxq.queue);
03062 f->retrans = -1;
03063
03064 iax2_frame_free(f);
03065 }
03066 }
03067
03068 static int attempt_transmit(const void *data)
03069 {
03070 #ifdef SCHED_MULTITHREADED
03071 if (schedule_action(__attempt_transmit, data))
03072 #endif
03073 __attempt_transmit(data);
03074 return 0;
03075 }
03076
03077 static int iax2_prune_realtime(int fd, int argc, char *argv[])
03078 {
03079 struct iax2_peer *peer = NULL;
03080 struct iax2_user *user = NULL;
03081
03082 if (argc != 4)
03083 return RESULT_SHOWUSAGE;
03084 if (!strcmp(argv[3],"all")) {
03085 prune_users();
03086 prune_peers();
03087 ast_cli(fd, "OK cache is flushed.\n");
03088 return RESULT_SUCCESS;
03089 }
03090 peer = find_peer(argv[3], 0);
03091 user = find_user(argv[3]);
03092 if (peer || user) {
03093 if (peer) {
03094 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
03095 ast_set_flag(peer, IAX_RTAUTOCLEAR);
03096 expire_registry(peer_ref(peer));
03097 ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]);
03098 } else {
03099 ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]);
03100 }
03101 peer_unref(peer);
03102 }
03103 if (user) {
03104 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
03105 ast_set_flag(user, IAX_RTAUTOCLEAR);
03106 ast_cli(fd, "User %s was removed from the cache.\n", argv[3]);
03107 } else {
03108 ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]);
03109 }
03110 ao2_unlink(users,user);
03111 user_unref(user);
03112 }
03113 } else {
03114 ast_cli(fd, "%s was not found in the cache.\n", argv[3]);
03115 }
03116
03117 return RESULT_SUCCESS;
03118 }
03119
03120 static int iax2_test_losspct(int fd, int argc, char *argv[])
03121 {
03122 if (argc != 4)
03123 return RESULT_SHOWUSAGE;
03124
03125 test_losspct = atoi(argv[3]);
03126
03127 return RESULT_SUCCESS;
03128 }
03129
03130 #ifdef IAXTESTS
03131 static int iax2_test_late(int fd, int argc, char *argv[])
03132 {
03133 if (argc != 4)
03134 return RESULT_SHOWUSAGE;
03135
03136 test_late = atoi(argv[3]);
03137
03138 return RESULT_SUCCESS;
03139 }
03140
03141 static int iax2_test_resync(int fd, int argc, char *argv[])
03142 {
03143 if (argc != 4)
03144 return RESULT_SHOWUSAGE;
03145
03146 test_resync = atoi(argv[3]);
03147
03148 return RESULT_SUCCESS;
03149 }
03150
03151 static int iax2_test_jitter(int fd, int argc, char *argv[])
03152 {
03153 if (argc < 4 || argc > 5)
03154 return RESULT_SHOWUSAGE;
03155
03156 test_jit = atoi(argv[3]);
03157 if (argc == 5)
03158 test_jitpct = atoi(argv[4]);
03159
03160 return RESULT_SUCCESS;
03161 }
03162 #endif
03163
03164
03165
03166 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03167 {
03168 int res = 0;
03169 if (peer->maxms) {
03170 if (peer->lastms < 0) {
03171 ast_copy_string(status, "UNREACHABLE", statuslen);
03172 } else if (peer->lastms > peer->maxms) {
03173 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03174 res = 1;
03175 } else if (peer->lastms) {
03176 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03177 res = 1;
03178 } else {
03179 ast_copy_string(status, "UNKNOWN", statuslen);
03180 }
03181 } else {
03182 ast_copy_string(status, "Unmonitored", statuslen);
03183 res = -1;
03184 }
03185 return res;
03186 }
03187
03188
03189 static int iax2_show_peer(int fd, int argc, char *argv[])
03190 {
03191 char status[30];
03192 char cbuf[256];
03193 struct iax2_peer *peer;
03194 char codec_buf[512];
03195 int x = 0, codec = 0, load_realtime = 0;
03196
03197 if (argc < 4)
03198 return RESULT_SHOWUSAGE;
03199
03200 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
03201
03202 peer = find_peer(argv[3], load_realtime);
03203 if (peer) {
03204 ast_cli(fd,"\n\n");
03205 ast_cli(fd, " * Name : %s\n", peer->name);
03206 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
03207 ast_cli(fd, " Context : %s\n", peer->context);
03208 ast_cli(fd, " Mailbox : %s\n", peer->mailbox);
03209 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
03210 ast_cli(fd, " Callnum limit: %d\n", peer->maxcallno);
03211 ast_cli(fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03212
03213
03214 ast_cli(fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
03215 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03216 ast_cli(fd, " Expire : %d\n", peer->expire);
03217 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No"));
03218 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));
03219 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03220 ast_cli(fd, " Username : %s\n", peer->username);
03221 ast_cli(fd, " Codecs : ");
03222 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03223 ast_cli(fd, "%s\n", codec_buf);
03224
03225 ast_cli(fd, " Codec Order : (");
03226 for(x = 0; x < 32 ; x++) {
03227 codec = ast_codec_pref_index(&peer->prefs,x);
03228 if(!codec)
03229 break;
03230 ast_cli(fd, "%s", ast_getformatname(codec));
03231 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03232 ast_cli(fd, "|");
03233 }
03234
03235 if (!x)
03236 ast_cli(fd, "none");
03237 ast_cli(fd, ")\n");
03238
03239 ast_cli(fd, " Status : ");
03240 peer_status(peer, status, sizeof(status));
03241 ast_cli(fd, "%s\n",status);
03242 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
03243 ast_cli(fd,"\n");
03244 peer_unref(peer);
03245 } else {
03246 ast_cli(fd,"Peer %s not found.\n", argv[3]);
03247 ast_cli(fd,"\n");
03248 }
03249
03250 return RESULT_SUCCESS;
03251 }
03252
03253 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
03254 {
03255 int which = 0;
03256 struct iax2_peer *peer;
03257 char *res = NULL;
03258 int wordlen = strlen(word);
03259 struct ao2_iterator i;
03260
03261
03262 if (pos != 3)
03263 return NULL;
03264
03265 i = ao2_iterator_init(peers, 0);
03266 while ((peer = ao2_iterator_next(&i))) {
03267 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
03268 res = ast_strdup(peer->name);
03269 peer_unref(peer);
03270 break;
03271 }
03272 peer_unref(peer);
03273 }
03274
03275 return res;
03276 }
03277
03278 static int iax2_show_stats(int fd, int argc, char *argv[])
03279 {
03280 struct iax_frame *cur;
03281 int cnt = 0, dead=0, final=0;
03282
03283 if (argc != 3)
03284 return RESULT_SHOWUSAGE;
03285
03286 AST_LIST_LOCK(&iaxq.queue);
03287 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
03288 if (cur->retries < 0)
03289 dead++;
03290 if (cur->final)
03291 final++;
03292 cnt++;
03293 }
03294 AST_LIST_UNLOCK(&iaxq.queue);
03295
03296 ast_cli(fd, " IAX Statistics\n");
03297 ast_cli(fd, "---------------------\n");
03298 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03299 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03300
03301 return RESULT_SUCCESS;
03302 }
03303
03304 static int iax2_show_cache(int fd, int argc, char *argv[])
03305 {
03306 struct iax2_dpcache *dp;
03307 char tmp[1024], *pc;
03308 int s;
03309 int x,y;
03310 struct timeval tv;
03311 gettimeofday(&tv, NULL);
03312 ast_mutex_lock(&dpcache_lock);
03313 dp = dpcache;
03314 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03315 while(dp) {
03316 s = dp->expiry.tv_sec - tv.tv_sec;
03317 tmp[0] = '\0';
03318 if (dp->flags & CACHE_FLAG_EXISTS)
03319 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03320 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03321 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03322 if (dp->flags & CACHE_FLAG_CANEXIST)
03323 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03324 if (dp->flags & CACHE_FLAG_PENDING)
03325 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03326 if (dp->flags & CACHE_FLAG_TIMEOUT)
03327 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03328 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03329 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03330 if (dp->flags & CACHE_FLAG_MATCHMORE)
03331 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03332 if (dp->flags & CACHE_FLAG_UNKNOWN)
03333 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03334
03335 if (!ast_strlen_zero(tmp))
03336 tmp[strlen(tmp) - 1] = '\0';
03337 else
03338 ast_copy_string(tmp, "(none)", sizeof(tmp));
03339 y=0;
03340 pc = strchr(dp->peercontext, '@');
03341 if (!pc)
03342 pc = dp->peercontext;
03343 else
03344 pc++;
03345 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
03346 if (dp->waiters[x] > -1)
03347 y++;
03348 if (s > 0)
03349 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03350 else
03351 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03352 dp = dp->next;
03353 }
03354 ast_mutex_unlock(&dpcache_lock);
03355 return RESULT_SUCCESS;
03356 }
03357
03358 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03359
03360 static void unwrap_timestamp(struct iax_frame *fr)
03361 {
03362
03363
03364 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03365 const int lower_mask = (1 << ts_shift) - 1;
03366 const int upper_mask = ~lower_mask;
03367 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03368
03369 if ( (fr->ts & upper_mask) == last_upper ) {
03370 const int x = fr->ts - iaxs[fr->callno]->last;
03371 const int threshold = (ts_shift == 15) ? 25000 : 50000;
03372
03373 if (x < -threshold) {
03374
03375
03376
03377
03378 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
03379 if (option_debug && iaxdebug)
03380 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
03381 } else if (x > threshold) {
03382
03383
03384
03385
03386 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03387 if (option_debug && iaxdebug)
03388 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
03389 }
03390 }
03391 }
03392
03393 static int get_from_jb(const void *p);
03394
03395 static void update_jbsched(struct chan_iax2_pvt *pvt)
03396 {
03397 int when;
03398
03399 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03400
03401 when = jb_next(pvt->jb) - when;
03402
03403 AST_SCHED_DEL(sched, pvt->jbid);
03404
03405 if(when <= 0) {
03406
03407 when = 1;
03408 }
03409
03410 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
03411 }
03412
03413 static void __get_from_jb(const void *p)
03414 {
03415 int callno = PTR_TO_CALLNO(p);
03416 struct chan_iax2_pvt *pvt = NULL;
03417 struct iax_frame *fr;
03418 jb_frame frame;
03419 int ret;
03420 long now;
03421 long next;
03422 struct timeval tv;
03423
03424
03425 ast_mutex_lock(&iaxsl[callno]);
03426 pvt = iaxs[callno];
03427 if (!pvt) {
03428
03429 ast_mutex_unlock(&iaxsl[callno]);
03430 return;
03431 }
03432
03433 pvt->jbid = -1;
03434
03435 gettimeofday(&tv,NULL);
03436
03437
03438
03439 tv.tv_usec += 1000;
03440
03441 now = ast_tvdiff_ms(tv, pvt->rxcore);
03442
03443 if(now >= (next = jb_next(pvt->jb))) {
03444 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
03445 switch(ret) {
03446 case JB_OK:
03447 fr = frame.data;
03448 __do_deliver(fr);
03449
03450 pvt = iaxs[callno];
03451 break;
03452 case JB_INTERP:
03453 {
03454 struct ast_frame af = { 0, };
03455
03456
03457 af.frametype = AST_FRAME_VOICE;
03458 af.subclass = pvt->voiceformat;
03459 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03460 af.src = "IAX2 JB interpolation";
03461 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03462 af.offset = AST_FRIENDLY_OFFSET;
03463
03464
03465
03466 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03467 iax2_queue_frame(callno, &af);
03468
03469 pvt = iaxs[callno];
03470 }
03471 }
03472 break;
03473 case JB_DROP:
03474 iax2_frame_free(frame.data);
03475 break;
03476 case JB_NOFRAME:
03477 case JB_EMPTY:
03478
03479 break;
03480 default:
03481
03482 break;
03483 }
03484 }
03485 if (pvt)
03486 update_jbsched(pvt);
03487 ast_mutex_unlock(&iaxsl[callno]);
03488 }
03489
03490 static int get_from_jb(const void *data)
03491 {
03492 #ifdef SCHED_MULTITHREADED
03493 if (schedule_action(__get_from_jb, data))
03494 #endif
03495 __get_from_jb(data);
03496 return 0;
03497 }
03498
03499
03500
03501
03502
03503
03504
03505 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03506 {
03507 int type, len;
03508 int ret;
03509 int needfree = 0;
03510 struct ast_channel *owner = NULL;
03511 struct ast_channel *bridge = NULL;
03512
03513
03514 unwrap_timestamp(fr);
03515
03516
03517 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03518 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03519 else {
03520 #if 0
03521 if (option_debug)
03522 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03523 #endif
03524 fr->af.delivery = ast_tv(0,0);
03525 }
03526
03527 type = JB_TYPE_CONTROL;
03528 len = 0;
03529
03530 if(fr->af.frametype == AST_FRAME_VOICE) {
03531 type = JB_TYPE_VOICE;
03532 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
03533 } else if(fr->af.frametype == AST_FRAME_CNG) {
03534 type = JB_TYPE_SILENCE;
03535 }
03536
03537 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03538 if (tsout)
03539 *tsout = fr->ts;
03540 __do_deliver(fr);
03541 return -1;
03542 }
03543
03544 if ((owner = iaxs[fr->callno]->owner))
03545 bridge = ast_bridged_channel(owner);
03546
03547
03548
03549 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03550 jb_frame frame;
03551
03552
03553 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03554 __do_deliver(frame.data);
03555
03556 if (!iaxs[fr->callno])
03557 return -1;
03558 }
03559
03560 jb_reset(iaxs[fr->callno]->jb);
03561
03562 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03563
03564
03565 if (tsout)
03566 *tsout = fr->ts;
03567 __do_deliver(fr);
03568 return -1;
03569 }
03570
03571
03572
03573 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03574 calc_rxstamp(iaxs[fr->callno],fr->ts));
03575 if (ret == JB_DROP) {
03576 needfree++;
03577 } else if (ret == JB_SCHED) {
03578 update_jbsched(iaxs[fr->callno]);
03579 }
03580 if (tsout)
03581 *tsout = fr->ts;
03582 if (needfree) {
03583
03584 iax2_frame_free(fr);
03585 return -1;
03586 }
03587 return 0;
03588 }
03589
03590 static int iax2_transmit(struct iax_frame *fr)
03591 {
03592
03593
03594
03595 fr->sentyet = 0;
03596 AST_LIST_LOCK(&iaxq.queue);
03597 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
03598 iaxq.count++;
03599 AST_LIST_UNLOCK(&iaxq.queue);
03600
03601 if (netthreadid != AST_PTHREADT_NULL)
03602 pthread_kill(netthreadid, SIGURG);
03603 signal_condition(&sched_lock, &sched_cond);
03604 return 0;
03605 }
03606
03607
03608
03609 static int iax2_digit_begin(struct ast_channel *c, char digit)
03610 {
03611 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03612 }
03613
03614 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
03615 {
03616 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03617 }
03618
03619 static int iax2_sendtext(struct ast_channel *c, const char *text)
03620 {
03621
03622 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03623 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03624 }
03625
03626 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
03627 {
03628 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
03629 }
03630
03631 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
03632 {
03633 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03634 }
03635
03636 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
03637 {
03638 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
03639 ast_mutex_lock(&iaxsl[callno]);
03640 if (iaxs[callno])
03641 iaxs[callno]->owner = newchan;
03642 else
03643 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
03644 ast_mutex_unlock(&iaxsl[callno]);
03645 return 0;
03646 }
03647
03648
03649
03650
03651
03652 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
03653 {
03654 struct ast_variable *var = NULL;
03655 struct ast_variable *tmp;
03656 struct iax2_peer *peer=NULL;
03657 time_t regseconds = 0, nowtime;
03658 int dynamic=0;
03659
03660 if (peername) {
03661 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
03662 if (!var && sin)
03663 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03664 } else if (sin) {
03665 char porta[25];
03666 sprintf(porta, "%d", ntohs(sin->sin_port));
03667 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03668 if (var) {
03669
03670 for (tmp = var; tmp; tmp = tmp->next) {
03671 if (!strcasecmp(tmp->name, "name"))
03672 peername = tmp->value;
03673 }
03674 }
03675 }
03676 if (!var && peername) {
03677 var = ast_load_realtime("iaxpeers", "name", peername, NULL);
03678
03679
03680
03681
03682
03683
03684 if (var && sin) {
03685 for (tmp = var; tmp; tmp = tmp->next) {
03686 if (!strcasecmp(tmp->name, "host")) {
03687 struct ast_hostent ahp;
03688 struct hostent *hp;
03689 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03690
03691 ast_variables_destroy(var);
03692 var = NULL;
03693 }
03694 break;
03695 }
03696 }
03697 }
03698 }
03699 if (!var)
03700 return NULL;
03701
03702 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
03703
03704 if (!peer) {
03705 ast_variables_destroy(var);
03706 return NULL;
03707 }
03708
03709 for (tmp = var; tmp; tmp = tmp->next) {
03710
03711 if (!strcasecmp(tmp->name, "type")) {
03712 if (strcasecmp(tmp->value, "friend") &&
03713 strcasecmp(tmp->value, "peer")) {
03714
03715 peer = peer_unref(peer);
03716 break;
03717 }
03718 } else if (!strcasecmp(tmp->name, "regseconds")) {
03719 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
03720 } else if (!strcasecmp(tmp->name, "ipaddr")) {
03721 inet_aton(tmp->value, &(peer->addr.sin_addr));
03722 } else if (!strcasecmp(tmp->name, "port")) {
03723 peer->addr.sin_port = htons(atoi(tmp->value));
03724 } else if (!strcasecmp(tmp->name, "host")) {
03725 if (!strcasecmp(tmp->value, "dynamic"))
03726 dynamic = 1;
03727 }
03728 }
03729
03730 ast_variables_destroy(var);
03731
03732 if (!peer)
03733 return NULL;
03734
03735 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03736 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
03737 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
03738 if (peer->expire > -1) {
03739 if (!ast_sched_del(sched, peer->expire)) {
03740 peer->expire = -1;
03741 peer_unref(peer);
03742 }
03743 }
03744 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
03745 if (peer->expire == -1)
03746 peer_unref(peer);
03747 }
03748 ao2_link(peers, peer);
03749 if (ast_test_flag(peer, IAX_DYNAMIC))
03750 reg_source_db(peer);
03751 } else {
03752 ast_set_flag(peer, IAX_TEMPONLY);
03753 }
03754
03755 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
03756 time(&nowtime);
03757 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
03758 memset(&peer->addr, 0, sizeof(peer->addr));
03759 realtime_update_peer(peer->name, &peer->addr, 0);
03760 if (option_debug)
03761 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
03762 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03763 }
03764 else {
03765 if (option_debug)
03766 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
03767 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03768 }
03769 }
03770
03771 return peer;
03772 }
03773
03774 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
03775 {
03776 struct ast_variable *var;
03777 struct ast_variable *tmp;
03778 struct iax2_user *user=NULL;
03779
03780 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
03781 if (!var)
03782 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03783 if (!var && sin) {
03784 char porta[6];
03785 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
03786 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03787 if (!var)
03788 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03789 }
03790 if (!var) {
03791 var = ast_load_realtime("iaxusers", "name", username, NULL);
03792
03793
03794
03795
03796
03797
03798 if (var) {
03799 for (tmp = var; tmp; tmp = tmp->next) {
03800 if (!strcasecmp(tmp->name, "host")) {
03801 struct ast_hostent ahp;
03802 struct hostent *hp;
03803 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03804
03805 ast_variables_destroy(var);
03806 var = NULL;
03807 }
03808 break;
03809 }
03810 }
03811 }
03812 }
03813 if (!var)
03814 return NULL;
03815
03816 tmp = var;
03817 while(tmp) {
03818
03819 if (!strcasecmp(tmp->name, "type")) {
03820 if (strcasecmp(tmp->value, "friend") &&
03821 strcasecmp(tmp->value, "user")) {
03822 return NULL;
03823 }
03824 }
03825 tmp = tmp->next;
03826 }
03827
03828 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03829
03830 ast_variables_destroy(var);
03831
03832 if (!user)
03833 return NULL;
03834
03835 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03836 ast_set_flag(user, IAX_RTCACHEFRIENDS);
03837 ao2_link(users, user);
03838 } else {
03839 ast_set_flag(user, IAX_TEMPONLY);
03840 }
03841
03842 return user;
03843 }
03844
03845 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
03846 {
03847 char port[10];
03848 char regseconds[20];
03849
03850 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03851 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03852 ast_update_realtime("iaxpeers", "name", peername,
03853 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
03854 "regseconds", regseconds, NULL);
03855 }
03856
03857 struct create_addr_info {
03858 int capability;
03859 unsigned int flags;
03860 int maxtime;
03861 int encmethods;
03862 int found;
03863 int sockfd;
03864 int adsi;
03865 char username[80];
03866 char secret[80];
03867 char outkey[80];
03868 char timezone[80];
03869 char prefs[32];
03870 char context[AST_MAX_CONTEXT];
03871 char peercontext[AST_MAX_CONTEXT];
03872 char mohinterpret[MAX_MUSICCLASS];
03873 char mohsuggest[MAX_MUSICCLASS];
03874 };
03875
03876 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03877 {
03878 struct ast_hostent ahp;
03879 struct hostent *hp;
03880 struct iax2_peer *peer;
03881 int res = -1;
03882 struct ast_codec_pref ourprefs;
03883
03884 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03885 cai->sockfd = defaultsockfd;
03886 cai->maxtime = 0;
03887 sin->sin_family = AF_INET;
03888
03889 if (!(peer = find_peer(peername, 1))) {
03890 cai->found = 0;
03891
03892 hp = ast_gethostbyname(peername, &ahp);
03893 if (hp) {
03894 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03895 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03896
03897
03898 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03899 if (c)
03900 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03901 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03902 return 0;
03903 } else {
03904 ast_log(LOG_WARNING, "No such host: %s\n", peername);
03905 return -1;
03906 }
03907 }
03908
03909 cai->found = 1;
03910
03911
03912 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03913 goto return_unref;
03914
03915
03916 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03917 goto return_unref;
03918
03919 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03920 cai->maxtime = peer->maxms;
03921 cai->capability = peer->capability;
03922 cai->encmethods = peer->encmethods;
03923 cai->sockfd = peer->sockfd;
03924 cai->adsi = peer->adsi;
03925 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03926
03927 if (c) {
03928 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03929 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03930 }
03931 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03932 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03933 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03934 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03935 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03936 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03937 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03938 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03939 if (ast_strlen_zero(peer->dbsecret)) {
03940 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03941 } else {
03942 char *family;
03943 char *key = NULL;
03944
03945 family = ast_strdupa(peer->dbsecret);
03946 key = strchr(family, '/');
03947 if (key)
03948 *key++ = '\0';
03949 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03950 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03951 goto return_unref;
03952 }
03953 }
03954
03955 if (peer->addr.sin_addr.s_addr) {
03956 sin->sin_addr = peer->addr.sin_addr;
03957 sin->sin_port = peer->addr.sin_port;
03958 } else {
03959 sin->sin_addr = peer->defaddr.sin_addr;
03960 sin->sin_port = peer->defaddr.sin_port;
03961 }
03962
03963 res = 0;
03964
03965 return_unref:
03966 peer_unref(peer);
03967
03968 return res;
03969 }
03970
03971 static void __auto_congest(const void *nothing)
03972 {
03973 int callno = PTR_TO_CALLNO(nothing);
03974 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03975 ast_mutex_lock(&iaxsl[callno]);
03976 if (iaxs[callno]) {
03977 iaxs[callno]->initid = -1;
03978 iax2_queue_frame(callno, &f);
03979 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03980 }
03981 ast_mutex_unlock(&iaxsl[callno]);
03982 }
03983
03984 static int auto_congest(const void *data)
03985 {
03986 #ifdef SCHED_MULTITHREADED
03987 if (schedule_action(__auto_congest, data))
03988 #endif
03989 __auto_congest(data);
03990 return 0;
03991 }
03992
03993 static unsigned int iax2_datetime(const char *tz)
03994 {
03995 time_t t;
03996 struct tm tm;
03997 unsigned int tmp;
03998 time(&t);
03999 if (!ast_strlen_zero(tz))
04000 ast_localtime(&t, &tm, tz);
04001 else
04002 ast_localtime(&t, &tm, NULL);
04003 tmp = (tm.tm_sec >> 1) & 0x1f;
04004 tmp |= (tm.tm_min & 0x3f) << 5;
04005 tmp |= (tm.tm_hour & 0x1f) << 11;
04006 tmp |= (tm.tm_mday & 0x1f) << 16;
04007 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04008 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04009 return tmp;
04010 }
04011
04012 struct parsed_dial_string {
04013 char *username;
04014 char *password;
04015 char *key;
04016 char *peer;
04017 char *port;
04018 char *exten;
04019 char *context;
04020 char *options;
04021 };
04022
04023 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04024 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04025 int sockfd, struct iax_ie_data *ied)
04026 {
04027 struct {
04028 struct ast_iax2_full_hdr f;
04029 struct iax_ie_data ied;
04030 } data;
04031 size_t size = sizeof(struct ast_iax2_full_hdr);
04032
04033 if (ied) {
04034 size += ied->pos;
04035 memcpy(&data.ied, ied->buf, ied->pos);
04036 }
04037
04038 data.f.scallno = htons(0x8000 | callno);
04039 data.f.dcallno = htons(dcallno);
04040 data.f.ts = htonl(ts);
04041 data.f.iseqno = seqno;
04042 data.f.oseqno = 0;
04043 data.f.type = AST_FRAME_IAX;
04044 data.f.csub = compress_subclass(command);
04045
04046 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04047 }
04048
04049 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04050 {
04051
04052 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04053 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04054 ied->buf[ied->pos++] = 0;
04055 pvt->calltoken_ie_len = 2;
04056 }
04057 }
04058
04059 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04060 {
04061 struct chan_iax2_pvt *pvt = iaxs[callno];
04062 int frametype = f->af.frametype;
04063 int subclass = f->af.subclass;
04064 struct {
04065 struct ast_iax2_full_hdr fh;
04066 struct iax_ie_data ied;
04067 } data = {
04068 .ied.buf = { 0 },
04069 .ied.pos = 0,
04070 };
04071
04072 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04073
04074 if (!pvt) {
04075 return;
04076 }
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088
04089 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04090 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04091 (f->datalen > sizeof(data))) {
04092
04093 return;
04094 }
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108
04109
04110 memcpy(&data, f->data, f->datalen);
04111 data.ied.pos = ie_data_pos;
04112
04113
04114
04115 data.ied.pos -= pvt->calltoken_ie_len;
04116 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04117
04118
04119 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04120
04121
04122 AST_LIST_LOCK(&iaxq.queue);
04123 AST_LIST_REMOVE(&iaxq.queue, f, list);
04124 AST_LIST_UNLOCK(&iaxq.queue);
04125
04126
04127 iax2_frame_free(f);
04128
04129
04130 pvt->oseqno = 0;
04131 pvt->rseqno = 0;
04132 pvt->iseqno = 0;
04133 pvt->aseqno = 0;
04134 if (pvt->peercallno) {
04135 remove_by_peercallno(pvt);
04136 pvt->peercallno = 0;
04137 }
04138
04139
04140 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04141 }
04142
04143 static void requirecalltoken_mark_auto(const char *name, int subclass)
04144 {
04145 struct iax2_user *user = NULL;
04146 struct iax2_peer *peer = NULL;
04147
04148 if (ast_strlen_zero(name)) {
04149 return;
04150 }
04151
04152 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04153 user->calltoken_required = CALLTOKEN_YES;
04154 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04155 peer->calltoken_required = CALLTOKEN_YES;
04156 }
04157
04158 if (peer) {
04159 peer_unref(peer);
04160 }
04161 if (user) {
04162 user_unref(user);
04163 }
04164 }
04165
04166
04167
04168
04169
04170
04171
04172
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04184 struct sockaddr_in *sin, int fd)
04185 {
04186 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04187 #define CALLTOKEN_IE_FORMAT "%u?%s"
04188 char buf[256] = { 0 };
04189 time_t t = time(NULL);
04190 char hash[41];
04191 int subclass = uncompress_subclass(fh->csub);
04192
04193
04194 if (ies->calltoken && !ies->calltokendata) {
04195 struct iax_ie_data ied = {
04196 .buf = { 0 },
04197 .pos = 0,
04198 };
04199
04200
04201 snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04202 ast_sha1_hash(hash, buf);
04203
04204 snprintf(buf, sizeof(buf), CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04205 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, buf);
04206 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04207
04208 return 1;
04209
04210
04211 } else if (ies->calltoken && ies->calltokendata) {
04212 char *rec_hash = NULL;
04213 char *rec_ts = NULL;
04214 unsigned int rec_time;
04215
04216
04217 rec_hash = strchr((char *) ies->calltokendata, '?');
04218 if (rec_hash) {
04219 *rec_hash++ = '\0';
04220 rec_ts = (char *) ies->calltokendata;
04221 }
04222
04223
04224 if (!rec_hash || !rec_ts) {
04225 goto reject;
04226 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04227 goto reject;
04228 }
04229
04230
04231 snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04232 ast_sha1_hash(hash, buf);
04233
04234
04235 if (strcmp(hash, rec_hash)) {
04236 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04237 goto reject;
04238 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04239 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04240 goto reject;
04241 }
04242
04243
04244
04245 requirecalltoken_mark_auto(ies->username, subclass);
04246 return 0;
04247
04248
04249 } else {
04250 if (calltoken_required(sin, ies->username, subclass)) {
04251 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenignore list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), ies->username);
04252 goto reject;
04253 }
04254 return 0;
04255 }
04256
04257 reject:
04258
04259 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04260 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04261 } else {
04262 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04263 }
04264
04265 return 1;
04266 }
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04287 {
04288 if (ast_strlen_zero(data))
04289 return;
04290
04291 pds->peer = strsep(&data, "/");
04292 pds->exten = strsep(&data, "/");
04293 pds->options = data;
04294
04295 if (pds->exten) {
04296 data = pds->exten;
04297 pds->exten = strsep(&data, "@");
04298 pds->context = data;
04299 }
04300
04301 if (strchr(pds->peer, '@')) {
04302 data = pds->peer;
04303 pds->username = strsep(&data, "@");
04304 pds->peer = data;
04305 }
04306
04307 if (pds->username) {
04308 data = pds->username;
04309 pds->username = strsep(&data, ":");
04310 pds->password = data;
04311 }
04312
04313 data = pds->peer;
04314 pds->peer = strsep(&data, ":");
04315 pds->port = data;
04316
04317
04318
04319
04320 if (pds->password && (pds->password[0] == '[')) {
04321 pds->key = ast_strip_quoted(pds->password, "[", "]");
04322 pds->password = NULL;
04323 }
04324 }
04325
04326 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04327 {
04328 struct sockaddr_in sin;
04329 char *l=NULL, *n=NULL, *tmpstr;
04330 struct iax_ie_data ied;
04331 char *defaultrdest = "s";
04332 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04333 struct parsed_dial_string pds;
04334 struct create_addr_info cai;
04335
04336 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
04337 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
04338 return -1;
04339 }
04340
04341 memset(&cai, 0, sizeof(cai));
04342 cai.encmethods = iax2_encryption;
04343
04344 memset(&pds, 0, sizeof(pds));
04345 tmpstr = ast_strdupa(dest);
04346 parse_dial_string(tmpstr, &pds);
04347
04348 if (ast_strlen_zero(pds.peer)) {
04349 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
04350 return -1;
04351 }
04352
04353 if (!pds.exten) {
04354 pds.exten = defaultrdest;
04355 }
04356
04357 if (create_addr(pds.peer, c, &sin, &cai)) {
04358 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
04359 return -1;
04360 }
04361
04362 if (!pds.username && !ast_strlen_zero(cai.username))
04363 pds.username = cai.username;
04364 if (!pds.password && !ast_strlen_zero(cai.secret))
04365 pds.password = cai.secret;
04366 if (!pds.key && !ast_strlen_zero(cai.outkey))
04367 pds.key = cai.outkey;
04368 if (!pds.context && !ast_strlen_zero(cai.peercontext))
04369 pds.context = cai.peercontext;
04370
04371
04372 ast_copy_string(c->context, cai.context, sizeof(c->context));
04373
04374 if (pds.port)
04375 sin.sin_port = htons(atoi(pds.port));
04376
04377 l = c->cid.cid_num;
04378 n = c->cid.cid_name;
04379
04380
04381 memset(&ied, 0, sizeof(ied));
04382
04383
04384 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
04385 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
04386 if (pds.options && strchr(pds.options, 'a')) {
04387
04388 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
04389 }
04390
04391 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
04392
04393 if (l) {
04394 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
04395 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04396 } else {
04397 if (n)
04398 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04399 else
04400 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
04401 }
04402
04403 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
04404 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
04405
04406 if (n)
04407 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
04408 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
04409 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
04410
04411 if (!ast_strlen_zero(c->language))
04412 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
04413 if (!ast_strlen_zero(c->cid.cid_dnid))
04414 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
04415 if (!ast_strlen_zero(c->cid.cid_rdnis))
04416 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
04417
04418 if (pds.context)
04419 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
04420
04421 if (pds.username)
04422 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
04423
04424 if (cai.encmethods)
04425 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
04426
04427 ast_mutex_lock(&iaxsl[callno]);
04428
04429 if (!ast_strlen_zero(c->context))
04430 ast_string_field_set(iaxs[callno], context, c->context);
04431
04432 if (pds.username)
04433 ast_string_field_set(iaxs[callno], username, pds.username);
04434
04435 iaxs[callno]->encmethods = cai.encmethods;
04436
04437 iaxs[callno]->adsi = cai.adsi;
04438
04439 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
04440 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
04441
04442 if (pds.key)
04443 ast_string_field_set(iaxs[callno], outkey, pds.key);
04444 if (pds.password)
04445 ast_string_field_set(iaxs[callno], secret, pds.password);
04446
04447 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
04448 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
04449 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
04450 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
04451
04452 if (iaxs[callno]->maxtime) {
04453
04454 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
04455 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
04456 } else if (autokill) {
04457 iaxs[callno]->pingtime = autokill / 2;
04458 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
04459 }
04460
04461
04462 iaxs[callno]->sockfd = cai.sockfd;
04463
04464
04465 add_empty_calltoken_ie(iaxs[callno], &ied);
04466 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
04467
04468 ast_mutex_unlock(&iaxsl[callno]);
04469 ast_setstate(c, AST_STATE_RINGING);
04470
04471 return 0;
04472 }
04473
04474 static int iax2_hangup(struct ast_channel *c)
04475 {
04476 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04477 struct iax_ie_data ied;
04478 int alreadygone;
04479 memset(&ied, 0, sizeof(ied));
04480 ast_mutex_lock(&iaxsl[callno]);
04481 if (callno && iaxs[callno]) {
04482 if (option_debug)
04483 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
04484 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
04485
04486 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
04487 if (!iaxs[callno]->error && !alreadygone) {
04488 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
04489 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
04490 }
04491 if (!iaxs[callno]) {
04492 ast_mutex_unlock(&iaxsl[callno]);
04493 return 0;
04494 }
04495 }
04496
04497 iax2_predestroy(callno);
04498
04499 if (iaxs[callno] && alreadygone) {
04500 if (option_debug)
04501 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
04502 iax2_destroy(callno);
04503 } else if (iaxs[callno]) {
04504 iax2_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno));
04505 }
04506 } else if (c->tech_pvt) {
04507
04508
04509
04510
04511 c->tech_pvt = NULL;
04512 }
04513 ast_mutex_unlock(&iaxsl[callno]);
04514 if (option_verbose > 2)
04515 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
04516 return 0;
04517 }
04518
04519
04520
04521
04522 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
04523 {
04524 unsigned short callno = pvt->callno;
04525
04526 if (!pvt->peercallno) {
04527
04528 int count = 10;
04529 while (count-- && pvt && !pvt->peercallno) {
04530 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
04531 pvt = iaxs[callno];
04532 }
04533 if (!pvt->peercallno) {
04534 return -1;
04535 }
04536 }
04537
04538 return 0;
04539 }
04540
04541 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
04542 {
04543 struct ast_option_header *h;
04544 int res;
04545
04546 switch (option) {
04547 case AST_OPTION_TXGAIN:
04548 case AST_OPTION_RXGAIN:
04549
04550 errno = ENOSYS;
04551 return -1;
04552 default:
04553 {
04554 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04555 struct chan_iax2_pvt *pvt;
04556
04557 ast_mutex_lock(&iaxsl[callno]);
04558 pvt = iaxs[callno];
04559
04560 if (wait_for_peercallno(pvt)) {
04561 ast_mutex_unlock(&iaxsl[callno]);
04562 return -1;
04563 }
04564
04565 ast_mutex_unlock(&iaxsl[callno]);
04566
04567 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
04568 return -1;
04569 }
04570
04571 h->flag = AST_OPTION_FLAG_REQUEST;
04572 h->option = htons(option);
04573 memcpy(h->data, data, datalen);
04574 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
04575 AST_CONTROL_OPTION, 0, (unsigned char *) h,
04576 datalen + sizeof(*h), -1);
04577 free(h);
04578 return res;
04579 }
04580 }
04581 }
04582
04583 static struct ast_frame *iax2_read(struct ast_channel *c)
04584 {
04585 ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n");
04586 return NULL;
04587 }
04588
04589 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
04590 {
04591 int res;
04592 struct iax_ie_data ied0;
04593 struct iax_ie_data ied1;
04594 unsigned int transferid = (unsigned int)ast_random();
04595 memset(&ied0, 0, sizeof(ied0));
04596 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
04597 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
04598 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
04599
04600 memset(&ied1, 0, sizeof(ied1));
04601 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
04602 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
04603 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
04604
04605 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
04606 if (res)
04607 return -1;
04608 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
04609 if (res)
04610 return -1;
04611 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04612 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04613 return 0;
04614 }
04615
04616 static void lock_both(unsigned short callno0, unsigned short callno1)
04617 {
04618 ast_mutex_lock(&iaxsl[callno0]);
04619 while (ast_mutex_trylock(&iaxsl[callno1])) {
04620 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
04621 }
04622 }
04623
04624 static void unlock_both(unsigned short callno0, unsigned short callno1)
04625 {
04626 ast_mutex_unlock(&iaxsl[callno1]);
04627 ast_mutex_unlock(&iaxsl[callno0]);
04628 }
04629
04630 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)
04631 {
04632 struct ast_channel *cs[3];
04633 struct ast_channel *who, *other;
04634 int to = -1;
04635 int res = -1;
04636 int transferstarted=0;
04637 struct ast_frame *f;
04638 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
04639 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
04640 struct timeval waittimer = {0, 0}, tv;
04641
04642 lock_both(callno0, callno1);
04643 if (!iaxs[callno0] || !iaxs[callno1]) {
04644 unlock_both(callno0, callno1);
04645 return AST_BRIDGE_FAILED;
04646 }
04647
04648 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
04649 iaxs[callno0]->bridgecallno = callno1;
04650 iaxs[callno1]->bridgecallno = callno0;
04651 }
04652
04653 if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) {
04654 transferstarted = 1;
04655 }
04656 unlock_both(callno0, callno1);
04657
04658
04659 cs[0] = c0;
04660 cs[1] = c1;
04661 for (;;) {
04662
04663 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
04664 if (option_verbose > 2)
04665 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
04666
04667 if (c0->tech == &iax2_tech) {
04668 ast_mutex_lock(&iaxsl[callno0]);
04669 iaxs[callno0]->bridgecallno = 0;
04670 ast_mutex_unlock(&iaxsl[callno0]);
04671 }
04672 if (c1->tech == &iax2_tech) {
04673 ast_mutex_lock(&iaxsl[callno1]);
04674 iaxs[callno1]->bridgecallno = 0;
04675 ast_mutex_unlock(&iaxsl[callno1]);
04676 }
04677 return AST_BRIDGE_FAILED_NOWARN;
04678 }
04679 if (c0->nativeformats != c1->nativeformats) {
04680 if (option_verbose > 2) {
04681 char buf0[255];
04682 char buf1[255];
04683 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
04684 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
04685 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
04686 }
04687
04688 lock_both(callno0, callno1);
04689 if (iaxs[callno0])
04690 iaxs[callno0]->bridgecallno = 0;
04691 if (iaxs[callno1])
04692 iaxs[callno1]->bridgecallno = 0;
04693 unlock_both(callno0, callno1);
04694 return AST_BRIDGE_FAILED_NOWARN;
04695 }
04696
04697 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
04698
04699 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
04700 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
04701 ast_log(LOG_WARNING, "Unable to start the transfer\n");
04702 transferstarted = 1;
04703 }
04704 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
04705
04706 gettimeofday(&tv, NULL);
04707 if (ast_tvzero(waittimer)) {
04708 waittimer = tv;
04709 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
04710 c0->_softhangup |= AST_SOFTHANGUP_DEV;
04711 c1->_softhangup |= AST_SOFTHANGUP_DEV;
04712 *fo = NULL;
04713 *rc = c0;
04714 res = AST_BRIDGE_COMPLETE;
04715 break;
04716 }
04717 }
04718 to = 1000;
04719 who = ast_waitfor_n(cs, 2, &to);
04720 if (timeoutms > -1) {
04721 timeoutms -= (1000 - to);
04722 if (timeoutms < 0)
04723 timeoutms = 0;
04724 }
04725 if (!who) {
04726 if (!timeoutms) {
04727 res = AST_BRIDGE_RETRY;
04728 break;
04729 }
04730 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
04731 res = AST_BRIDGE_FAILED;
04732 break;
04733 }
04734 continue;
04735 }
04736 f = ast_read(who);
04737 if (!f) {
04738 *fo = NULL;
04739 *rc = who;
04740 res = AST_BRIDGE_COMPLETE;
04741 break;
04742 }
04743 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
04744 *fo = f;
04745 *rc = who;
04746 res = AST_BRIDGE_COMPLETE;
04747 break;
04748 }
04749 other = (who == c0) ? c1 : c0;
04750 if ((f->frametype == AST_FRAME_VOICE) ||
04751 (f->frametype == AST_FRAME_TEXT) ||
04752 (f->frametype == AST_FRAME_VIDEO) ||
04753 (f->frametype == AST_FRAME_IMAGE) ||
04754 (f->frametype == AST_FRAME_DTMF) ||
04755 (f->frametype == AST_FRAME_CONTROL)) {
04756
04757
04758
04759 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
04760 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
04761 *rc = who;
04762 *fo = f;
04763 res = AST_BRIDGE_COMPLETE;
04764
04765 break;
04766 }
04767
04768 ast_write(other, f);
04769 }
04770 ast_frfree(f);
04771
04772 cs[2] = cs[0];
04773 cs[0] = cs[1];
04774 cs[1] = cs[2];
04775 }
04776 lock_both(callno0, callno1);
04777 if(iaxs[callno0])
04778 iaxs[callno0]->bridgecallno = 0;
04779 if(iaxs[callno1])
04780 iaxs[callno1]->bridgecallno = 0;
04781 unlock_both(callno0, callno1);
04782 return res;
04783 }
04784
04785 static int iax2_answer(struct ast_channel *c)
04786 {
04787 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04788 if (option_debug)
04789 ast_log(LOG_DEBUG, "Answering IAX2 call\n");
04790 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
04791 }
04792
04793 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
04794 {
04795 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04796 struct chan_iax2_pvt *pvt;
04797 int res = 0;
04798
04799 if (option_debug && iaxdebug)
04800 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
04801
04802 ast_mutex_lock(&iaxsl[callno]);
04803 pvt = iaxs[callno];
04804
04805 if (wait_for_peercallno(pvt)) {
04806 res = -1;
04807 goto done;
04808 }
04809
04810 switch (condition) {
04811 case AST_CONTROL_HOLD:
04812 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04813 ast_moh_start(c, data, pvt->mohinterpret);
04814 goto done;
04815 }
04816 break;
04817 case AST_CONTROL_UNHOLD:
04818 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04819 ast_moh_stop(c);
04820 goto done;
04821 }
04822 }
04823
04824 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
04825
04826 done:
04827 ast_mutex_unlock(&iaxsl[callno]);
04828
04829 return res;
04830 }
04831
04832 static int iax2_transfer(struct ast_channel *c, const char *dest)
04833 {
04834 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04835 struct iax_ie_data ied;
04836 char tmp[256], *context;
04837 ast_copy_string(tmp, dest, sizeof(tmp));
04838 context = strchr(tmp, '@');
04839 if (context) {
04840 *context = '\0';
04841 context++;
04842 }
04843 memset(&ied, 0, sizeof(ied));
04844 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
04845 if (context)
04846 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
04847 if (option_debug)
04848 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
04849 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
04850 }
04851
04852 static int iax2_getpeertrunk(struct sockaddr_in sin)
04853 {
04854 struct iax2_peer *peer;
04855 int res = 0;
04856 struct ao2_iterator i;
04857
04858 i = ao2_iterator_init(peers, 0);
04859 while ((peer = ao2_iterator_next(&i))) {
04860 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
04861 (peer->addr.sin_port == sin.sin_port)) {
04862 res = ast_test_flag(peer, IAX_TRUNK);
04863 peer_unref(peer);
04864 break;
04865 }
04866 peer_unref(peer);
04867 }
04868
04869 return res;
04870 }
04871
04872
04873 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
04874 {
04875 struct ast_channel *tmp;
04876 struct chan_iax2_pvt *i;
04877 struct ast_variable *v = NULL;
04878
04879 if (!(i = iaxs[callno])) {
04880 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
04881 return NULL;
04882 }
04883
04884
04885 ast_mutex_unlock(&iaxsl[callno]);
04886 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);
04887 ast_mutex_lock(&iaxsl[callno]);
04888 if (i != iaxs[callno]) {
04889 if (tmp) {
04890
04891 ast_mutex_unlock(&iaxsl[callno]);
04892 ast_channel_free(tmp);
04893 ast_mutex_lock(&iaxsl[callno]);
04894 }
04895 return NULL;
04896 }
04897
04898 if (!tmp)
04899 return NULL;
04900 tmp->tech = &iax2_tech;
04901
04902 tmp->nativeformats = capability;
04903 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
04904 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
04905 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
04906
04907
04908
04909 if (!ast_strlen_zero(i->ani))
04910 tmp->cid.cid_ani = ast_strdup(i->ani);
04911 else
04912 tmp->cid.cid_ani = ast_strdup(i->cid_num);
04913 tmp->cid.cid_dnid = ast_strdup(i->dnid);
04914 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04915 tmp->cid.cid_pres = i->calling_pres;
04916 tmp->cid.cid_ton = i->calling_ton;
04917 tmp->cid.cid_tns = i->calling_tns;
04918 if (!ast_strlen_zero(i->language))
04919 ast_string_field_set(tmp, language, i->language);
04920 if (!ast_strlen_zero(i->accountcode))
04921 ast_string_field_set(tmp, accountcode, i->accountcode);
04922 if (i->amaflags)
04923 tmp->amaflags = i->amaflags;
04924 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04925 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
04926 if (i->adsi)
04927 tmp->adsicpe = i->peeradsicpe;
04928 else
04929 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04930 i->owner = tmp;
04931 i->capability = capability;
04932
04933 for (v = i->vars ; v ; v = v->next)
04934 pbx_builtin_setvar_helper(tmp, v->name, v->value);
04935
04936 if (state != AST_STATE_DOWN) {
04937 if (ast_pbx_start(tmp)) {
04938 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04939 ast_hangup(tmp);
04940 i->owner = NULL;
04941 return NULL;
04942 }
04943 }
04944
04945 ast_module_ref(ast_module_info->self);
04946
04947 return tmp;
04948 }
04949
04950 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
04951 {
04952 unsigned long int mssincetx;
04953 long int ms, pred;
04954
04955 tpeer->trunkact = *tv;
04956 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
04957 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
04958
04959 tpeer->txtrunktime = *tv;
04960 tpeer->lastsent = 999999;
04961 }
04962
04963 tpeer->lasttxtime = *tv;
04964
04965
04966 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
04967
04968 pred = tpeer->lastsent + sampms;
04969 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
04970 ms = pred;
04971
04972
04973 if (ms == tpeer->lastsent)
04974 ms = tpeer->lastsent + 1;
04975 tpeer->lastsent = ms;
04976 return ms;
04977 }
04978
04979 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
04980 {
04981 long ms;
04982 if (ast_tvzero(iaxs[callno]->rxcore)) {
04983
04984 gettimeofday(&iaxs[callno]->rxcore, NULL);
04985
04986 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
04987 }
04988
04989 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
04990
04991 return ms + ts;
04992 }
04993
04994 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
04995 {
04996 int ms;
04997 int voice = 0;
04998 int genuine = 0;
04999 int adjust;
05000 int rate = ast_format_rate(f->subclass) / 1000;
05001 struct timeval *delivery = NULL;
05002
05003
05004
05005
05006
05007
05008
05009
05010 if (f) {
05011 if (f->frametype == AST_FRAME_VOICE) {
05012 voice = 1;
05013 delivery = &f->delivery;
05014 } else if (f->frametype == AST_FRAME_IAX) {
05015 genuine = 1;
05016 } else if (f->frametype == AST_FRAME_CNG) {
05017 p->notsilenttx = 0;
05018 }
05019 }
05020 if (ast_tvzero(p->offset)) {
05021 gettimeofday(&p->offset, NULL);
05022
05023 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05024 }
05025
05026 if (ts)
05027 return ts;
05028
05029 if (delivery && !ast_tvzero(*delivery)) {
05030 ms = ast_tvdiff_ms(*delivery, p->offset);
05031 if (ms < 0) {
05032 ms = 0;
05033 }
05034 if (option_debug > 2 && iaxdebug)
05035 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05036 } else {
05037 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05038 if (ms < 0)
05039 ms = 0;
05040 if (voice) {
05041
05042 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05043
05044
05045
05046
05047
05048
05049
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060
05061 adjust = (ms - p->nextpred);
05062 if (adjust < 0)
05063 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05064 else if (adjust > 0)
05065 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05066
05067 if (!p->nextpred) {
05068 p->nextpred = ms;
05069 if (p->nextpred <= p->lastsent)
05070 p->nextpred = p->lastsent + 3;
05071 }
05072 ms = p->nextpred;
05073 } else {
05074
05075
05076
05077
05078
05079
05080
05081
05082
05083 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05084 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05085 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05086
05087 if (f->samples >= rate)
05088 {
05089 int diff = ms % (f->samples / rate);
05090 if (diff)
05091 ms += f->samples/rate - diff;
05092 }
05093
05094 p->nextpred = ms;
05095 p->notsilenttx = 1;
05096 }
05097 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05098
05099
05100
05101
05102
05103
05104
05105
05106 if ( (unsigned int)ms < p->lastsent )
05107 ms = p->lastsent;
05108 } else {
05109
05110
05111 if (genuine) {
05112
05113 if (ms <= p->lastsent)
05114 ms = p->lastsent + 3;
05115 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05116
05117 ms = p->lastsent + 3;
05118 }
05119 }
05120 }
05121 p->lastsent = ms;
05122 if (voice)
05123 p->nextpred = p->nextpred + f->samples / rate;
05124 return ms;
05125 }
05126
05127 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05128 {
05129
05130
05131 int ms;
05132 #ifdef IAXTESTS
05133 int jit;
05134 #endif
05135
05136 if (ast_tvzero(p->rxcore)) {
05137 p->rxcore = ast_tvnow();
05138 if (option_debug && iaxdebug)
05139 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05140 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05141 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05142 #if 1
05143 if (option_debug && iaxdebug)
05144 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05145 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05146 #endif
05147 }
05148
05149 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05150 #ifdef IAXTESTS
05151 if (test_jit) {
05152 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05153 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05154 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05155 jit = -jit;
05156 ms += jit;
05157 }
05158 }
05159 if (test_late) {
05160 ms += test_late;
05161 test_late = 0;
05162 }
05163 #endif
05164 return ms;
05165 }
05166
05167 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
05168 {
05169 struct iax2_trunk_peer *tpeer;
05170
05171
05172 ast_mutex_lock(&tpeerlock);
05173 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
05174
05175 if (!inaddrcmp(&tpeer->addr, sin)) {
05176 ast_mutex_lock(&tpeer->lock);
05177 break;
05178 }
05179 }
05180 if (!tpeer) {
05181 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
05182 ast_mutex_init(&tpeer->lock);
05183 tpeer->lastsent = 9999;
05184 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
05185 tpeer->trunkact = ast_tvnow();
05186 ast_mutex_lock(&tpeer->lock);
05187 tpeer->next = tpeers;
05188 tpeer->sockfd = fd;
05189 tpeers = tpeer;
05190 #ifdef SO_NO_CHECK
05191 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
05192 #endif
05193 if (option_debug)
05194 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05195 }
05196 }
05197 ast_mutex_unlock(&tpeerlock);
05198 return tpeer;
05199 }
05200
05201 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
05202 {
05203 struct ast_frame *f;
05204 struct iax2_trunk_peer *tpeer;
05205 void *tmp, *ptr;
05206 struct ast_iax2_meta_trunk_entry *met;
05207 struct ast_iax2_meta_trunk_mini *mtm;
05208
05209 f = &fr->af;
05210 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
05211 if (tpeer) {
05212 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
05213
05214 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
05215 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
05216 ast_mutex_unlock(&tpeer->lock);
05217 return -1;
05218 }
05219
05220 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
05221 tpeer->trunkdata = tmp;
05222 if (option_debug)
05223 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);
05224 } else {
05225 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));
05226 ast_mutex_unlock(&tpeer->lock);
05227 return -1;
05228 }
05229 }
05230
05231
05232 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
05233 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
05234 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
05235 mtm->len = htons(f->datalen);
05236 mtm->mini.callno = htons(pvt->callno);
05237 mtm->mini.ts = htons(0xffff & fr->ts);
05238 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
05239 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
05240 } else {
05241 met = (struct ast_iax2_meta_trunk_entry *)ptr;
05242
05243 met->callno = htons(pvt->callno);
05244 met->len = htons(f->datalen);
05245
05246 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
05247 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
05248 }
05249
05250 memcpy(ptr, f->data, f->datalen);
05251 tpeer->trunkdatalen += f->datalen;
05252
05253 tpeer->calls++;
05254 ast_mutex_unlock(&tpeer->lock);
05255 }
05256 return 0;
05257 }
05258
05259
05260
05261 static void build_rand_pad(unsigned char *buf, ssize_t len)
05262 {
05263 long tmp;
05264 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05265 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05266 buf += sizeof(tmp);
05267 len -= sizeof(tmp);
05268 }
05269 }
05270
05271 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05272 {
05273 build_ecx_key(digest, pvt);
05274 aes_decrypt_key128(digest, &pvt->dcx);
05275 }
05276
05277 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05278 {
05279
05280
05281
05282 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05283 aes_encrypt_key128(digest, &pvt->ecx);
05284 aes_decrypt_key128(digest, &pvt->mydcx);
05285 }
05286
05287 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
05288 {
05289 #if 0
05290
05291 int x;
05292 if (len % 16)
05293 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05294 for (x=0;x<len;x++)
05295 dst[x] = src[x] ^ 0xff;
05296 #else
05297 unsigned char lastblock[16] = { 0 };
05298 int x;
05299 while(len > 0) {
05300 aes_decrypt(src, dst, dcx);
05301 for (x=0;x<16;x++)
05302 dst[x] ^= lastblock[x];
05303 memcpy(lastblock, src, sizeof(lastblock));
05304 dst += 16;
05305 src += 16;
05306 len -= 16;
05307 }
05308 #endif
05309 }
05310
05311 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
05312 {
05313 #if 0
05314
05315 int x;
05316 if (len % 16)
05317 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05318 for (x=0;x<len;x++)
05319 dst[x] = src[x] ^ 0xff;
05320 #else
05321 unsigned char curblock[16] = { 0 };
05322 int x;
05323 while(len > 0) {
05324 for (x=0;x<16;x++)
05325 curblock[x] ^= src[x];
05326 aes_encrypt(curblock, dst, ecx);
05327 memcpy(curblock, dst, sizeof(curblock));
05328 dst += 16;
05329 src += 16;
05330 len -= 16;
05331 }
05332 #endif
05333 }
05334
05335 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05336 {
05337 int padding;
05338 unsigned char *workspace;
05339
05340 workspace = alloca(*datalen);
05341 memset(f, 0, sizeof(*f));
05342 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05343 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05344 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
05345 return -1;
05346
05347 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
05348
05349 padding = 16 + (workspace[15] & 0x0f);
05350 if (option_debug && iaxdebug)
05351 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
05352 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
05353 return -1;
05354
05355 *datalen -= padding;
05356 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05357 f->frametype = fh->type;
05358 if (f->frametype == AST_FRAME_VIDEO) {
05359 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
05360 } else {
05361 f->subclass = uncompress_subclass(fh->csub);
05362 }
05363 } else {
05364 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05365 if (option_debug && iaxdebug)
05366 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
05367 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
05368 return -1;
05369
05370 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
05371 padding = 16 + (workspace[15] & 0x0f);
05372 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
05373 return -1;
05374 *datalen -= padding;
05375 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05376 }
05377 return 0;
05378 }
05379
05380 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
05381 {
05382 int padding;
05383 unsigned char *workspace;
05384 workspace = alloca(*datalen + 32);
05385 if (!workspace)
05386 return -1;
05387 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05388 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05389 if (option_debug && iaxdebug)
05390 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
05391 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
05392 padding = 16 + (padding & 0xf);
05393 memcpy(workspace, poo, padding);
05394 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05395 workspace[15] &= 0xf0;
05396 workspace[15] |= (padding & 0xf);
05397 if (option_debug && iaxdebug)
05398 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]);
05399 *datalen += padding;
05400 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
05401 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
05402 memcpy(poo, workspace + *datalen - 32, 32);
05403 } else {
05404 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05405 if (option_debug && iaxdebug)
05406 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
05407 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
05408 padding = 16 + (padding & 0xf);
05409 memcpy(workspace, poo, padding);
05410 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05411 workspace[15] &= 0xf0;
05412 workspace[15] |= (padding & 0x0f);
05413 *datalen += padding;
05414 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
05415 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
05416 memcpy(poo, workspace + *datalen - 32, 32);
05417 }
05418 return 0;
05419 }
05420
05421 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05422 {
05423 int res=-1;
05424 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
05425
05426 struct MD5Context md5;
05427 unsigned char digest[16];
05428 char *tmppw, *stringp;
05429
05430 tmppw = ast_strdupa(iaxs[callno]->secret);
05431 stringp = tmppw;
05432 while ((tmppw = strsep(&stringp, ";"))) {
05433 MD5Init(&md5);
05434 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05435 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05436 MD5Final(digest, &md5);
05437 build_encryption_keys(digest, iaxs[callno]);
05438 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05439 if (!res) {
05440 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
05441 break;
05442 }
05443 }
05444 } else
05445 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05446 return res;
05447 }
05448
05449 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
05450 {
05451
05452
05453
05454 struct ast_iax2_full_hdr *fh;
05455 struct ast_iax2_mini_hdr *mh;
05456 struct ast_iax2_video_hdr *vh;
05457 struct {
05458 struct iax_frame fr2;
05459 unsigned char buffer[4096];
05460 } frb;
05461 struct iax_frame *fr;
05462 int res;
05463 int sendmini=0;
05464 unsigned int lastsent;
05465 unsigned int fts;
05466
05467 frb.fr2.afdatalen = sizeof(frb.buffer);
05468
05469 if (!pvt) {
05470 ast_log(LOG_WARNING, "No private structure for packet?\n");
05471 return -1;
05472 }
05473
05474 lastsent = pvt->lastsent;
05475
05476
05477 fts = calc_timestamp(pvt, ts, f);
05478
05479
05480
05481
05482 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
05483 return 0;
05484
05485
05486 if ((ast_test_flag(pvt, IAX_TRUNK) ||
05487 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
05488 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
05489 &&
05490 (f->frametype == AST_FRAME_VOICE)
05491 &&
05492 (f->subclass == pvt->svoiceformat)
05493 ) {
05494
05495 now = 1;
05496
05497 sendmini = 1;
05498 }
05499 if ( f->frametype == AST_FRAME_VIDEO ) {
05500
05501
05502
05503
05504
05505 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
05506 ((f->subclass & ~0x1) == pvt->svideoformat)
05507 ) {
05508 now = 1;
05509 sendmini = 1;
05510 } else {
05511 now = 0;
05512 sendmini = 0;
05513 }
05514 pvt->lastvsent = fts;
05515 }
05516 if (f->frametype == AST_FRAME_IAX) {
05517
05518 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
05519 if (!pvt->first_iax_message) {
05520 pvt->first_iax_message = pvt->last_iax_message;
05521 }
05522 }
05523
05524 if (now) {
05525 fr = &frb.fr2;
05526 } else
05527 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));
05528 if (!fr) {
05529 ast_log(LOG_WARNING, "Out of memory\n");
05530 return -1;
05531 }
05532
05533 iax_frame_wrap(fr, f);
05534
05535 fr->ts = fts;
05536 fr->callno = pvt->callno;
05537 fr->transfer = transfer;
05538 fr->final = final;
05539 fr->encmethods = 0;
05540 if (!sendmini) {
05541
05542 if (seqno > -1)
05543 fr->oseqno = seqno;
05544 else
05545 fr->oseqno = pvt->oseqno++;
05546 fr->iseqno = pvt->iseqno;
05547 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
05548 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
05549 fh->ts = htonl(fr->ts);
05550 fh->oseqno = fr->oseqno;
05551 if (transfer) {
05552 fh->iseqno = 0;
05553 } else
05554 fh->iseqno = fr->iseqno;
05555
05556 if (!transfer)
05557 pvt->aseqno = fr->iseqno;
05558 fh->type = fr->af.frametype & 0xFF;
05559 if (fr->af.frametype == AST_FRAME_VIDEO)
05560 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
05561 else
05562 fh->csub = compress_subclass(fr->af.subclass);
05563 if (transfer) {
05564 fr->dcallno = pvt->transfercallno;
05565 } else
05566 fr->dcallno = pvt->peercallno;
05567 fh->dcallno = htons(fr->dcallno);
05568 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
05569 fr->data = fh;
05570 fr->retries = 0;
05571
05572 fr->retrytime = pvt->pingtime * 2;
05573 if (fr->retrytime < MIN_RETRY_TIME)
05574 fr->retrytime = MIN_RETRY_TIME;
05575 if (fr->retrytime > MAX_RETRY_TIME)
05576 fr->retrytime = MAX_RETRY_TIME;
05577
05578 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
05579 fr->retries = -1;
05580 else if (f->frametype == AST_FRAME_VOICE)
05581 pvt->svoiceformat = f->subclass;
05582 else if (f->frametype == AST_FRAME_VIDEO)
05583 pvt->svideoformat = f->subclass & ~0x1;
05584 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05585 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05586 if (iaxdebug) {
05587 if (fr->transfer)
05588 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05589 else
05590 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05591 }
05592 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
05593 fr->encmethods = pvt->encmethods;
05594 fr->ecx = pvt->ecx;
05595 fr->mydcx = pvt->mydcx;
05596 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
05597 } else
05598 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05599 }
05600
05601 if (now) {
05602 res = send_packet(fr);
05603 } else
05604 res = iax2_transmit(fr);
05605 } else {
05606 if (ast_test_flag(pvt, IAX_TRUNK)) {
05607 iax2_trunk_queue(pvt, fr);
05608 res = 0;
05609 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
05610
05611 fr->oseqno = -1;
05612 fr->iseqno = -1;
05613 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
05614 vh->zeros = 0;
05615 vh->callno = htons(0x8000 | fr->callno);
05616 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
05617 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
05618 fr->data = vh;
05619 fr->retries = -1;
05620 res = send_packet(fr);
05621 } else {
05622
05623 fr->oseqno = -1;
05624 fr->iseqno = -1;
05625
05626 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
05627 mh->callno = htons(fr->callno);
05628 mh->ts = htons(fr->ts & 0xFFFF);
05629 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
05630 fr->data = mh;
05631 fr->retries = -1;
05632 if (pvt->transferring == TRANSFER_MEDIAPASS)
05633 fr->transfer = 1;
05634 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05635 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05636 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
05637 } else
05638 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05639 }
05640 res = send_packet(fr);
05641 }
05642 }
05643 return res;
05644 }
05645
05646 static int iax2_show_users(int fd, int argc, char *argv[])
05647 {
05648 regex_t regexbuf;
05649 int havepattern = 0;
05650
05651 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
05652 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
05653
05654 struct iax2_user *user = NULL;
05655 char auth[90];
05656 char *pstr = "";
05657 struct ao2_iterator i;
05658
05659 switch (argc) {
05660 case 5:
05661 if (!strcasecmp(argv[3], "like")) {
05662 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
05663 return RESULT_SHOWUSAGE;
05664 havepattern = 1;
05665 } else
05666 return RESULT_SHOWUSAGE;
05667 case 3:
05668 break;
05669 default:
05670 return RESULT_SHOWUSAGE;
05671 }
05672
05673 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
05674 i = ao2_iterator_init(users, 0);
05675 for (user = ao2_iterator_next(&i); user;
05676 user_unref(user), user = ao2_iterator_next(&i)) {
05677 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
05678 continue;
05679
05680 if (!ast_strlen_zero(user->secret)) {
05681 ast_copy_string(auth,user->secret,sizeof(auth));
05682 } else if (!ast_strlen_zero(user->inkeys)) {
05683 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
05684 } else
05685 ast_copy_string(auth, "-no secret-", sizeof(auth));
05686
05687 if(ast_test_flag(user,IAX_CODEC_NOCAP))
05688 pstr = "REQ Only";
05689 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
05690 pstr = "Disabled";
05691 else
05692 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
05693
05694 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods,
05695 user->contexts ? user->contexts->context : context,
05696 user->ha ? "Yes" : "No", pstr);
05697 }
05698
05699 if (havepattern)
05700 regfree(®exbuf);
05701
05702 return RESULT_SUCCESS;
05703 #undef FORMAT
05704 #undef FORMAT2
05705 }
05706
05707 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
05708 {
05709 regex_t regexbuf;
05710 int havepattern = 0;
05711 int total_peers = 0;
05712 int online_peers = 0;
05713 int offline_peers = 0;
05714 int unmonitored_peers = 0;
05715 struct ao2_iterator i;
05716
05717 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
05718 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
05719
05720 struct iax2_peer *peer = NULL;
05721 char name[256];
05722 int registeredonly=0;
05723 char *term = manager ? "\r\n" : "\n";
05724
05725 switch (argc) {
05726 case 6:
05727 if (!strcasecmp(argv[3], "registered"))
05728 registeredonly = 1;
05729 else
05730 return RESULT_SHOWUSAGE;
05731 if (!strcasecmp(argv[4], "like")) {
05732 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
05733 return RESULT_SHOWUSAGE;
05734 havepattern = 1;
05735 } else
05736 return RESULT_SHOWUSAGE;
05737 break;
05738 case 5:
05739 if (!strcasecmp(argv[3], "like")) {
05740 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
05741 return RESULT_SHOWUSAGE;
05742 havepattern = 1;
05743 } else
05744 return RESULT_SHOWUSAGE;
05745 break;
05746 case 4:
05747 if (!strcasecmp(argv[3], "registered"))
05748 registeredonly = 1;
05749 else
05750 return RESULT_SHOWUSAGE;
05751 break;
05752 case 3:
05753 break;
05754 default:
05755 return RESULT_SHOWUSAGE;
05756 }
05757
05758
05759 if (s)
05760 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
05761 else
05762 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
05763
05764 i = ao2_iterator_init(peers, 0);
05765 for (peer = ao2_iterator_next(&i); peer;
05766 peer_unref(peer), peer = ao2_iterator_next(&i)) {
05767 char nm[20];
05768 char status[20];
05769 char srch[2000];
05770 int retstatus;
05771
05772 if (registeredonly && !peer->addr.sin_addr.s_addr)
05773 continue;
05774 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
05775 continue;
05776
05777 if (!ast_strlen_zero(peer->username))
05778 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
05779 else
05780 ast_copy_string(name, peer->name, sizeof(name));
05781
05782 retstatus = peer_status(peer, status, sizeof(status));
05783 if (retstatus > 0)
05784 online_peers++;
05785 else if (!retstatus)
05786 offline_peers++;
05787 else
05788 unmonitored_peers++;
05789
05790 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05791
05792 snprintf(srch, sizeof(srch), FORMAT, name,
05793 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05794 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05795 nm,
05796 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
05797 peer->encmethods ? "(E)" : " ", status, term);
05798
05799 if (s)
05800 astman_append(s, FORMAT, name,
05801 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
05802 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05803 nm,
05804 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
05805 peer->encmethods ? "(E)" : " ", status, term);
05806 else
05807 ast_cli(fd, FORMAT, name,
05808 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05809 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05810 nm,
05811 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
05812 peer->encmethods ? "(E)" : " ", status, term);
05813 total_peers++;
05814 }
05815
05816 if (s)
05817 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
05818 else
05819 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
05820
05821 if (havepattern)
05822 regfree(®exbuf);
05823
05824 return RESULT_SUCCESS;
05825 #undef FORMAT
05826 #undef FORMAT2
05827 }
05828
05829 static int iax2_show_threads(int fd, int argc, char *argv[])
05830 {
05831 struct iax2_thread *thread = NULL;
05832 time_t t;
05833 int threadcount = 0, dynamiccount = 0;
05834 char type;
05835
05836 if (argc != 3)
05837 return RESULT_SHOWUSAGE;
05838
05839 ast_cli(fd, "IAX2 Thread Information\n");
05840 time(&t);
05841 ast_cli(fd, "Idle Threads:\n");
05842 AST_LIST_LOCK(&idle_list);
05843 AST_LIST_TRAVERSE(&idle_list, thread, list) {
05844 #ifdef DEBUG_SCHED_MULTITHREAD
05845 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
05846 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05847 #else
05848 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
05849 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05850 #endif
05851 threadcount++;
05852 }
05853 AST_LIST_UNLOCK(&idle_list);
05854 ast_cli(fd, "Active Threads:\n");
05855 AST_LIST_LOCK(&active_list);
05856 AST_LIST_TRAVERSE(&active_list, thread, list) {
05857 if (thread->type == IAX_TYPE_DYNAMIC)
05858 type = 'D';
05859 else
05860 type = 'P';
05861 #ifdef DEBUG_SCHED_MULTITHREAD
05862 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n",
05863 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05864 #else
05865 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
05866 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05867 #endif
05868 threadcount++;
05869 }
05870 AST_LIST_UNLOCK(&active_list);
05871 ast_cli(fd, "Dynamic Threads:\n");
05872 AST_LIST_LOCK(&dynamic_list);
05873 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
05874 #ifdef DEBUG_SCHED_MULTITHREAD
05875 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
05876 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05877 #else
05878 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
05879 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05880 #endif
05881 dynamiccount++;
05882 }
05883 AST_LIST_UNLOCK(&dynamic_list);
05884 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
05885 return RESULT_SUCCESS;
05886 }
05887
05888 static int iax2_show_peers(int fd, int argc, char *argv[])
05889 {
05890 return __iax2_show_peers(0, fd, NULL, argc, argv);
05891 }
05892 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
05893 {
05894 ast_cli_netstats(s, -1, 0);
05895 astman_append(s, "\r\n");
05896 return RESULT_SUCCESS;
05897 }
05898
05899 static int iax2_show_firmware(int fd, int argc, char *argv[])
05900 {
05901 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
05902 #if !defined(__FreeBSD__)
05903 #define FORMAT "%-15.15s %-15d %-15d\n"
05904 #else
05905 #define FORMAT "%-15.15s %-15d %-15d\n"
05906 #endif
05907 struct iax_firmware *cur;
05908 if ((argc != 3) && (argc != 4))
05909 return RESULT_SHOWUSAGE;
05910 ast_mutex_lock(&waresl.lock);
05911
05912 ast_cli(fd, FORMAT2, "Device", "Version", "Size");
05913 for (cur = waresl.wares;cur;cur = cur->next) {
05914 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname)))
05915 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
05916 (int)ntohl(cur->fwh->datalen));
05917 }
05918 ast_mutex_unlock(&waresl.lock);
05919 return RESULT_SUCCESS;
05920 #undef FORMAT
05921 #undef FORMAT2
05922 }
05923
05924
05925 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
05926 {
05927 char *a[] = { "iax2", "show", "users" };
05928 int ret;
05929 const char *id = astman_get_header(m,"ActionID");
05930
05931 if (!ast_strlen_zero(id))
05932 astman_append(s, "ActionID: %s\r\n",id);
05933 ret = __iax2_show_peers(1, -1, s, 3, a );
05934 astman_append(s, "\r\n\r\n" );
05935 return ret;
05936 }
05937
05938 static char *regstate2str(int regstate)
05939 {
05940 switch(regstate) {
05941 case REG_STATE_UNREGISTERED:
05942 return "Unregistered";
05943 case REG_STATE_REGSENT:
05944 return "Request Sent";
05945 case REG_STATE_AUTHSENT:
05946 return "Auth. Sent";
05947 case REG_STATE_REGISTERED:
05948 return "Registered";
05949 case REG_STATE_REJECTED:
05950 return "Rejected";
05951 case REG_STATE_TIMEOUT:
05952 return "Timeout";
05953 case REG_STATE_NOAUTH:
05954 return "No Authentication";
05955 default:
05956 return "Unknown";
05957 }
05958 }
05959
05960 static int iax2_show_registry(int fd, int argc, char *argv[])
05961 {
05962 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
05963 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
05964 struct iax2_registry *reg = NULL;
05965
05966 char host[80];
05967 char perceived[80];
05968 if (argc != 3)
05969 return RESULT_SHOWUSAGE;
05970 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
05971 AST_LIST_LOCK(®istrations);
05972 AST_LIST_TRAVERSE(®istrations, reg, entry) {
05973 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
05974 if (reg->us.sin_addr.s_addr)
05975 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05976 else
05977 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
05978 ast_cli(fd, FORMAT, host,
05979 (reg->dnsmgr) ? "Y" : "N",
05980 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
05981 }
05982 AST_LIST_UNLOCK(®istrations);
05983 return RESULT_SUCCESS;
05984 #undef FORMAT
05985 #undef FORMAT2
05986 }
05987
05988 static int iax2_show_channels(int fd, int argc, char *argv[])
05989 {
05990 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
05991 #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"
05992 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
05993 int x;
05994 int numchans = 0;
05995 int usedchans = 0;
05996 char first_message[10] = { 0, };
05997 char last_message[10] = { 0, };
05998
05999 if (argc != 3)
06000 return RESULT_SHOWUSAGE;
06001 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
06002 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06003 ast_mutex_lock(&iaxsl[x]);
06004 if (iaxs[x]) {
06005 int lag, jitter, localdelay;
06006 jb_info jbinfo;
06007 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06008 jb_getinfo(iaxs[x]->jb, &jbinfo);
06009 jitter = jbinfo.jitter;
06010 localdelay = jbinfo.current - jbinfo.min;
06011 } else {
06012 jitter = -1;
06013 localdelay = 0;
06014 }
06015
06016 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06017 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06018 lag = iaxs[x]->remote_rr.delay;
06019 ast_cli(fd, FORMAT,
06020 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06021 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
06022 S_OR(iaxs[x]->username, "(None)"),
06023 iaxs[x]->callno, iaxs[x]->peercallno,
06024 iaxs[x]->oseqno, iaxs[x]->iseqno,
06025 lag,
06026 jitter,
06027 localdelay,
06028 ast_getformatname(iaxs[x]->voiceformat),
06029 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06030 first_message,
06031 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06032 last_message);
06033 numchans++;
06034 if (iaxs[x]->owner) {
06035 usedchans++;
06036 }
06037 }
06038 ast_mutex_unlock(&iaxsl[x]);
06039 }
06040 ast_cli(fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : "");
06041 ast_cli(fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : "");
06042 return RESULT_SUCCESS;
06043 #undef FORMAT
06044 #undef FORMAT2
06045 #undef FORMATB
06046 }
06047
06048 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
06049 {
06050 int x;
06051 int numchans = 0;
06052 char first_message[10] = { 0, };
06053 char last_message[10] = { 0, };
06054 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06055 ast_mutex_lock(&iaxsl[x]);
06056 if (iaxs[x]) {
06057 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06058 char *fmt;
06059 jb_info jbinfo;
06060
06061 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06062 jb_getinfo(iaxs[x]->jb, &jbinfo);
06063 localjitter = jbinfo.jitter;
06064 localdelay = jbinfo.current - jbinfo.min;
06065 locallost = jbinfo.frames_lost;
06066 locallosspct = jbinfo.losspct/1000;
06067 localdropped = jbinfo.frames_dropped;
06068 localooo = jbinfo.frames_ooo;
06069 } else {
06070 localjitter = -1;
06071 localdelay = 0;
06072 locallost = -1;
06073 locallosspct = -1;
06074 localdropped = 0;
06075 localooo = -1;
06076 }
06077 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06078 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06079 if (limit_fmt)
06080 fmt = "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n";
06081 else
06082 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n";
06083 if (s)
06084
06085 astman_append(s, fmt,
06086 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06087 iaxs[x]->pingtime,
06088 localjitter,
06089 localdelay,
06090 locallost,
06091 locallosspct,
06092 localdropped,
06093 localooo,
06094 iaxs[x]->frames_received/1000,
06095 iaxs[x]->remote_rr.jitter,
06096 iaxs[x]->remote_rr.delay,
06097 iaxs[x]->remote_rr.losscnt,
06098 iaxs[x]->remote_rr.losspct,
06099 iaxs[x]->remote_rr.dropped,
06100 iaxs[x]->remote_rr.ooo,
06101 iaxs[x]->remote_rr.packets/1000,
06102 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06103 first_message,
06104 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06105 last_message);
06106 else
06107 ast_cli(fd, fmt,
06108 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06109 iaxs[x]->pingtime,
06110 localjitter,
06111 localdelay,
06112 locallost,
06113 locallosspct,
06114 localdropped,
06115 localooo,
06116 iaxs[x]->frames_received/1000,
06117 iaxs[x]->remote_rr.jitter,
06118 iaxs[x]->remote_rr.delay,
06119 iaxs[x]->remote_rr.losscnt,
06120 iaxs[x]->remote_rr.losspct,
06121 iaxs[x]->remote_rr.dropped,
06122 iaxs[x]->remote_rr.ooo,
06123 iaxs[x]->remote_rr.packets/1000,
06124 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06125 first_message,
06126 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06127 last_message);
06128 numchans++;
06129 }
06130 ast_mutex_unlock(&iaxsl[x]);
06131 }
06132 return numchans;
06133 }
06134
06135 static int iax2_show_netstats(int fd, int argc, char *argv[])
06136 {
06137 int numchans = 0;
06138 if (argc != 3)
06139 return RESULT_SHOWUSAGE;
06140 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
06141 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
06142 numchans = ast_cli_netstats(NULL, fd, 1);
06143 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06144 return RESULT_SUCCESS;
06145 }
06146
06147 static int iax2_do_debug(int fd, int argc, char *argv[])
06148 {
06149 if (argc < 2 || argc > 3)
06150 return RESULT_SHOWUSAGE;
06151 iaxdebug = 1;
06152 ast_cli(fd, "IAX2 Debugging Enabled\n");
06153 return RESULT_SUCCESS;
06154 }
06155
06156 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
06157 {
06158 if (argc < 3 || argc > 4)
06159 return RESULT_SHOWUSAGE;
06160 iaxtrunkdebug = 1;
06161 ast_cli(fd, "IAX2 Trunk Debug Requested\n");
06162 return RESULT_SUCCESS;
06163 }
06164
06165 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
06166 {
06167 if (argc < 3 || argc > 4)
06168 return RESULT_SHOWUSAGE;
06169 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
06170 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
06171 return RESULT_SUCCESS;
06172 }
06173
06174 static int iax2_no_debug(int fd, int argc, char *argv[])
06175 {
06176 if (argc < 3 || argc > 4)
06177 return RESULT_SHOWUSAGE;
06178 iaxdebug = 0;
06179 ast_cli(fd, "IAX2 Debugging Disabled\n");
06180 return RESULT_SUCCESS;
06181 }
06182
06183 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
06184 {
06185 if (argc < 4 || argc > 5)
06186 return RESULT_SHOWUSAGE;
06187 iaxtrunkdebug = 0;
06188 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
06189 return RESULT_SUCCESS;
06190 }
06191
06192 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
06193 {
06194 if (argc < 4 || argc > 5)
06195 return RESULT_SHOWUSAGE;
06196 jb_setoutput(jb_error_output, jb_warning_output, NULL);
06197 jb_debug_output("\n");
06198 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
06199 return RESULT_SUCCESS;
06200 }
06201
06202 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
06203 {
06204 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
06205 int res = -1;
06206 ast_mutex_lock(&iaxsl[callno]);
06207 if (iaxs[callno]) {
06208
06209 if (!iaxs[callno]->error) {
06210 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
06211 res = 0;
06212
06213 else if (f->frametype == AST_FRAME_NULL)
06214 res = 0;
06215 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
06216 res = 0;
06217 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
06218 res = 0;
06219 else
06220
06221 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
06222 } else {
06223 if (option_debug)
06224 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
06225 }
06226 }
06227
06228 ast_mutex_unlock(&iaxsl[callno]);
06229 return res;
06230 }
06231
06232 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
06233 int now, int transfer, int final)
06234 {
06235 struct ast_frame f = { 0, };
06236
06237 f.frametype = type;
06238 f.subclass = command;
06239 f.datalen = datalen;
06240 f.src = __FUNCTION__;
06241 f.data = (void *) data;
06242
06243 return iax2_send(i, &f, ts, seqno, now, transfer, final);
06244 }
06245
06246 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
06247 {
06248 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
06249 }
06250
06251 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
06252 {
06253 int res;
06254 ast_mutex_lock(&iaxsl[callno]);
06255 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
06256 ast_mutex_unlock(&iaxsl[callno]);
06257 return res;
06258 }
06259
06260
06261
06262
06263
06264
06265 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)
06266 {
06267 int call_num = i->callno;
06268
06269 iax2_predestroy(i->callno);
06270 if (!iaxs[call_num])
06271 return -1;
06272 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
06273 }
06274
06275 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)
06276 {
06277 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
06278 }
06279
06280 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
06281 {
06282 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
06283 }
06284
06285 static int apply_context(struct iax2_context *con, const char *context)
06286 {
06287 while(con) {
06288 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
06289 return -1;
06290 con = con->next;
06291 }
06292 return 0;
06293 }
06294
06295
06296 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06297 {
06298
06299 int res = -1;
06300 int version = 2;
06301 struct iax2_user *user = NULL, *best = NULL;
06302 int bestscore = 0;
06303 int gotcapability = 0;
06304 struct ast_variable *v = NULL, *tmpvar = NULL;
06305 struct ao2_iterator i;
06306
06307 if (!iaxs[callno])
06308 return res;
06309 if (ies->called_number)
06310 ast_string_field_set(iaxs[callno], exten, ies->called_number);
06311 if (ies->calling_number) {
06312 ast_shrink_phone_number(ies->calling_number);
06313 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
06314 }
06315 if (ies->calling_name)
06316 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
06317 if (ies->calling_ani)
06318 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
06319 if (ies->dnid)
06320 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
06321 if (ies->rdnis)
06322 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
06323 if (ies->called_context)
06324 ast_string_field_set(iaxs[callno], context, ies->called_context);
06325 if (ies->language)
06326 ast_string_field_set(iaxs[callno], language, ies->language);
06327 if (ies->username)
06328 ast_string_field_set(iaxs[callno], username, ies->username);
06329 if (ies->calling_ton > -1)
06330 iaxs[callno]->calling_ton = ies->calling_ton;
06331 if (ies->calling_tns > -1)
06332 iaxs[callno]->calling_tns = ies->calling_tns;
06333 if (ies->calling_pres > -1)
06334 iaxs[callno]->calling_pres = ies->calling_pres;
06335 if (ies->format)
06336 iaxs[callno]->peerformat = ies->format;
06337 if (ies->adsicpe)
06338 iaxs[callno]->peeradsicpe = ies->adsicpe;
06339 if (ies->capability) {
06340 gotcapability = 1;
06341 iaxs[callno]->peercapability = ies->capability;
06342 }
06343 if (ies->version)
06344 version = ies->version;
06345
06346
06347 if(ies->codec_prefs) {
06348 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
06349 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
06350 }
06351
06352 if (!gotcapability)
06353 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
06354 if (version > IAX_PROTO_VERSION) {
06355 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
06356 ast_inet_ntoa(sin->sin_addr), version);
06357 return res;
06358 }
06359
06360 i = ao2_iterator_init(users, 0);
06361 while ((user = ao2_iterator_next(&i))) {
06362 if ((ast_strlen_zero(iaxs[callno]->username) ||
06363 !strcmp(iaxs[callno]->username, user->name))
06364 && ast_apply_ha(user->ha, sin)
06365 && (ast_strlen_zero(iaxs[callno]->context) ||
06366 apply_context(user->contexts, iaxs[callno]->context))) {
06367 if (!ast_strlen_zero(iaxs[callno]->username)) {
06368
06369 if (best)
06370 user_unref(best);
06371 best = user;
06372 break;
06373 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
06374
06375 if (user->ha) {
06376
06377 if (bestscore < 4) {
06378 bestscore = 4;
06379 if (best)
06380 user_unref(best);
06381 best = user;
06382 continue;
06383 }
06384 } else {
06385
06386 if (bestscore < 3) {
06387 bestscore = 3;
06388 if (best)
06389 user_unref(best);
06390 best = user;
06391 continue;
06392 }
06393 }
06394 } else {
06395 if (user->ha) {
06396
06397 if (bestscore < 2) {
06398 bestscore = 2;
06399 if (best)
06400 user_unref(best);
06401 best = user;
06402 continue;
06403 }
06404 } else {
06405
06406 if (bestscore < 1) {
06407 bestscore = 1;
06408 if (best)
06409 user_unref(best);
06410 best = user;
06411 continue;
06412 }
06413 }
06414 }
06415 }
06416 user_unref(user);
06417 }
06418 user = best;
06419 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
06420 user = realtime_user(iaxs[callno]->username, sin);
06421 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
06422 !apply_context(user->contexts, iaxs[callno]->context)) {
06423 user = user_unref(user);
06424 }
06425 }
06426 if (user) {
06427
06428
06429 for (v = user->vars ; v ; v = v->next) {
06430 if((tmpvar = ast_variable_new(v->name, v->value))) {
06431 tmpvar->next = iaxs[callno]->vars;
06432 iaxs[callno]->vars = tmpvar;
06433 }
06434 }
06435
06436 if (user->maxauthreq > 0)
06437 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
06438 iaxs[callno]->prefs = user->prefs;
06439 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
06440 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
06441 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
06442 iaxs[callno]->encmethods = user->encmethods;
06443
06444 if (ast_strlen_zero(iaxs[callno]->username))
06445 ast_string_field_set(iaxs[callno], username, user->name);
06446
06447 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
06448 iaxs[callno]->capability = user->capability;
06449
06450 if (ast_strlen_zero(iaxs[callno]->context)) {
06451 if (user->contexts)
06452 ast_string_field_set(iaxs[callno], context, user->contexts->context);
06453 else
06454 ast_string_field_set(iaxs[callno], context, context);
06455 }
06456
06457 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
06458
06459 iaxs[callno]->authmethods = user->authmethods;
06460 iaxs[callno]->adsi = user->adsi;
06461
06462 if (ast_test_flag(user, IAX_HASCALLERID)) {
06463 iaxs[callno]->calling_tns = 0;
06464 iaxs[callno]->calling_ton = 0;
06465 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
06466 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
06467 ast_string_field_set(iaxs[callno], ani, user->cid_num);
06468 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
06469 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
06470 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
06471 }
06472 if (!ast_strlen_zero(user->accountcode))
06473 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
06474 if (!ast_strlen_zero(user->mohinterpret))
06475 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
06476 if (!ast_strlen_zero(user->mohsuggest))
06477 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
06478 if (user->amaflags)
06479 iaxs[callno]->amaflags = user->amaflags;
06480 if (!ast_strlen_zero(user->language))
06481 ast_string_field_set(iaxs[callno], language, user->language);
06482 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
06483
06484 if (!ast_strlen_zero(user->dbsecret)) {
06485 char *family, *key=NULL;
06486 char buf[80];
06487 family = ast_strdupa(user->dbsecret);
06488 key = strchr(family, '/');
06489 if (key) {
06490 *key = '\0';
06491 key++;
06492 }
06493 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
06494 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
06495 else
06496 ast_string_field_set(iaxs[callno], secret, buf);
06497 } else
06498 ast_string_field_set(iaxs[callno], secret, user->secret);
06499 res = 0;
06500 user = user_unref(user);
06501 } else {
06502
06503
06504
06505
06506 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06507 ast_string_field_set(iaxs[callno], secret, "badsecret");
06508 iaxs[callno]->authrej = 1;
06509 if (!ast_strlen_zero(iaxs[callno]->username)) {
06510
06511 res = 0;
06512 }
06513 }
06514 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
06515 return res;
06516 }
06517
06518 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
06519 {
06520 struct ast_iax2_full_hdr fh;
06521 fh.scallno = htons(src | IAX_FLAG_FULL);
06522 fh.dcallno = htons(dst);
06523 fh.ts = 0;
06524 fh.oseqno = 0;
06525 fh.iseqno = 0;
06526 fh.type = AST_FRAME_IAX;
06527 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
06528 if (iaxdebug)
06529 iax_showframe(NULL, &fh, 0, sin, 0);
06530 if (option_debug)
06531 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
06532 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
06533 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
06534 }
06535
06536 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
06537 {
06538
06539 p->encmethods &= enc;
06540 if (p->encmethods) {
06541 if (p->encmethods & IAX_ENCRYPT_AES128)
06542 p->encmethods = IAX_ENCRYPT_AES128;
06543 else
06544 p->encmethods = 0;
06545 }
06546 }
06547
06548
06549
06550
06551
06552
06553
06554 static int authenticate_request(int call_num)
06555 {
06556 struct iax_ie_data ied;
06557 int res = -1, authreq_restrict = 0;
06558 char challenge[10];
06559 struct chan_iax2_pvt *p = iaxs[call_num];
06560
06561 memset(&ied, 0, sizeof(ied));
06562
06563
06564 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06565 struct iax2_user *user, tmp_user = {
06566 .name = p->username,
06567 };
06568
06569 user = ao2_find(users, &tmp_user, OBJ_POINTER);
06570 if (user) {
06571 if (user->curauthreq == user->maxauthreq)
06572 authreq_restrict = 1;
06573 else
06574 user->curauthreq++;
06575 user = user_unref(user);
06576 }
06577 }
06578
06579
06580 if (authreq_restrict) {
06581 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
06582 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
06583 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
06584 return 0;
06585 }
06586
06587 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06588 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
06589 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06590 ast_string_field_set(p, challenge, challenge);
06591
06592 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
06593 }
06594 if (p->encmethods)
06595 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
06596
06597 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
06598
06599 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
06600
06601 if (p->encmethods)
06602 ast_set_flag(p, IAX_ENCRYPTED);
06603
06604 return res;
06605 }
06606
06607 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
06608 {
06609 char requeststr[256];
06610 char md5secret[256] = "";
06611 char secret[256] = "";
06612 char rsasecret[256] = "";
06613 int res = -1;
06614 int x;
06615 struct iax2_user *user, tmp_user = {
06616 .name = p->username,
06617 };
06618
06619 if (p->authrej) {
06620 return res;
06621 }
06622 user = ao2_find(users, &tmp_user, OBJ_POINTER);
06623 if (user) {
06624 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06625 ast_atomic_fetchadd_int(&user->curauthreq, -1);
06626 ast_clear_flag(p, IAX_MAXAUTHREQ);
06627 }
06628 ast_string_field_set(p, host, user->name);
06629 user = user_unref(user);
06630 }
06631
06632 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
06633 return res;
06634 if (ies->password)
06635 ast_copy_string(secret, ies->password, sizeof(secret));
06636 if (ies->md5_result)
06637 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06638 if (ies->rsa_result)
06639 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06640 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
06641 struct ast_key *key;
06642 char *keyn;
06643 char tmpkey[256];
06644 char *stringp=NULL;
06645 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
06646 stringp=tmpkey;
06647 keyn = strsep(&stringp, ":");
06648 while(keyn) {
06649 key = ast_key_get(keyn, AST_KEY_PUBLIC);
06650 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
06651 res = 0;
06652 break;
06653 } else if (!key)
06654 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
06655 keyn = strsep(&stringp, ":");
06656 }
06657 } else if (p->authmethods & IAX_AUTH_MD5) {
06658 struct MD5Context md5;
06659 unsigned char digest[16];
06660 char *tmppw, *stringp;
06661
06662 tmppw = ast_strdupa(p->secret);
06663 stringp = tmppw;
06664 while((tmppw = strsep(&stringp, ";"))) {
06665 MD5Init(&md5);
06666 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
06667 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06668 MD5Final(digest, &md5);
06669
06670 for (x=0;x<16;x++)
06671 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
06672 if (!strcasecmp(requeststr, md5secret)) {
06673 res = 0;
06674 break;
06675 }
06676 }
06677 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
06678 if (!strcmp(secret, p->secret))
06679 res = 0;
06680 }
06681 return res;
06682 }
06683
06684
06685 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06686 {
06687 char requeststr[256] = "";
06688 char peer[256] = "";
06689 char md5secret[256] = "";
06690 char rsasecret[256] = "";
06691 char secret[256] = "";
06692 struct iax2_peer *p = NULL;
06693 struct ast_key *key;
06694 char *keyn;
06695 int x;
06696 int expire = 0;
06697 int res = -1;
06698
06699 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06700
06701 if (ies->username)
06702 ast_copy_string(peer, ies->username, sizeof(peer));
06703 if (ies->password)
06704 ast_copy_string(secret, ies->password, sizeof(secret));
06705 if (ies->md5_result)
06706 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06707 if (ies->rsa_result)
06708 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06709 if (ies->refresh)
06710 expire = ies->refresh;
06711
06712 if (ast_strlen_zero(peer)) {
06713 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
06714 return -1;
06715 }
06716
06717
06718 ast_mutex_unlock(&iaxsl[callno]);
06719 p = find_peer(peer, 1);
06720 ast_mutex_lock(&iaxsl[callno]);
06721 if (!p || !iaxs[callno]) {
06722 if (iaxs[callno]) {
06723 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
06724
06725 ast_string_field_set(iaxs[callno], secret, "badsecret");
06726
06727
06728
06729
06730
06731
06732
06733
06734
06735
06736 if (ast_strlen_zero(iaxs[callno]->challenge) &&
06737 !(!ast_strlen_zero(secret) && plaintext)) {
06738
06739 res = 0;
06740 }
06741 }
06742 if (authdebug && !p)
06743 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06744
06745 goto return_unref;
06746 }
06747
06748 if (!ast_test_flag(p, IAX_DYNAMIC)) {
06749 if (authdebug)
06750 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06751 goto return_unref;
06752 }
06753
06754 if (!ast_apply_ha(p->ha, sin)) {
06755 if (authdebug)
06756 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06757 goto return_unref;
06758 }
06759 ast_string_field_set(iaxs[callno], secret, p->secret);
06760 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
06761
06762 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06763 if (!ast_strlen_zero(p->inkeys)) {
06764 char tmpkeys[256];
06765 char *stringp=NULL;
06766 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
06767 stringp=tmpkeys;
06768 keyn = strsep(&stringp, ":");
06769 while(keyn) {
06770 key = ast_key_get(keyn, AST_KEY_PUBLIC);
06771 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
06772 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06773 break;
06774 } else if (!key)
06775 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
06776 keyn = strsep(&stringp, ":");
06777 }
06778 if (!keyn) {
06779 if (authdebug)
06780 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
06781 goto return_unref;
06782 }
06783 } else {
06784 if (authdebug)
06785 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
06786 goto return_unref;
06787 }
06788 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06789 struct MD5Context md5;
06790 unsigned char digest[16];
06791 char *tmppw, *stringp;
06792
06793 tmppw = ast_strdupa(p->secret);
06794 stringp = tmppw;
06795 while((tmppw = strsep(&stringp, ";"))) {
06796 MD5Init(&md5);
06797 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06798 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06799 MD5Final(digest, &md5);
06800 for (x=0;x<16;x++)
06801 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
06802 if (!strcasecmp(requeststr, md5secret))
06803 break;
06804 }
06805 if (tmppw) {
06806 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06807 } else {
06808 if (authdebug)
06809 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
06810 goto return_unref;
06811 }
06812 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
06813
06814 if (strcmp(secret, p->secret)) {
06815 if (authdebug)
06816 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06817 goto return_unref;
06818 } else
06819 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06820 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
06821
06822 goto return_unref;
06823 }
06824 ast_device_state_changed("IAX2/%s", p->name);
06825
06826
06827 res = 0;
06828 return_unref:
06829
06830 if (iaxs[callno]) {
06831 ast_string_field_set(iaxs[callno], peer, peer);
06832
06833
06834 if (expire && (expire < iaxs[callno]->expiry)) {
06835 iaxs[callno]->expiry = expire;
06836 }
06837 }
06838
06839 if (p) {
06840 peer_unref(p);
06841 }
06842 return res;
06843 }
06844
06845 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
06846 {
06847 int res = -1;
06848 int x;
06849 if (!ast_strlen_zero(keyn)) {
06850 if (!(authmethods & IAX_AUTH_RSA)) {
06851 if (ast_strlen_zero(secret))
06852 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));
06853 } else if (ast_strlen_zero(challenge)) {
06854 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
06855 } else {
06856 char sig[256];
06857 struct ast_key *key;
06858 key = ast_key_get(keyn, AST_KEY_PRIVATE);
06859 if (!key) {
06860 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
06861 } else {
06862 if (ast_sign(key, (char*)challenge, sig)) {
06863 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
06864 res = -1;
06865 } else {
06866 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
06867 res = 0;
06868 }
06869 }
06870 }
06871 }
06872
06873 if (res && !ast_strlen_zero(secret)) {
06874 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
06875 struct MD5Context md5;
06876 unsigned char digest[16];
06877 char digres[128];
06878 MD5Init(&md5);
06879 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
06880 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
06881 MD5Final(digest, &md5);
06882
06883 for (x=0;x<16;x++)
06884 sprintf(digres + (x << 1), "%2.2x", digest[x]);
06885 if (pvt) {
06886 build_encryption_keys(digest, pvt);
06887 }
06888 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
06889 res = 0;
06890 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
06891 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
06892 res = 0;
06893 } else
06894 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
06895 }
06896 return res;
06897 }
06898
06899
06900
06901
06902
06903 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
06904 {
06905 struct iax2_peer *peer = NULL;
06906
06907 int res = -1;
06908 int authmethods = 0;
06909 struct iax_ie_data ied;
06910 uint16_t callno = p->callno;
06911
06912 memset(&ied, 0, sizeof(ied));
06913
06914 if (ies->username)
06915 ast_string_field_set(p, username, ies->username);
06916 if (ies->challenge)
06917 ast_string_field_set(p, challenge, ies->challenge);
06918 if (ies->authmethods)
06919 authmethods = ies->authmethods;
06920 if (authmethods & IAX_AUTH_MD5)
06921 merge_encryption(p, ies->encmethods);
06922 else
06923 p->encmethods = 0;
06924
06925
06926 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
06927
06928 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
06929 } else {
06930 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06931 while ((peer = ao2_iterator_next(&i))) {
06932 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
06933
06934 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
06935
06936 && (!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)))
06937
06938 ) {
06939 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
06940 if (!res) {
06941 peer_unref(peer);
06942 break;
06943 }
06944 }
06945 peer_unref(peer);
06946 }
06947 if (!peer) {
06948
06949
06950 const char *peer_name = ast_strdupa(p->peer);
06951 ast_mutex_unlock(&iaxsl[callno]);
06952 if ((peer = realtime_peer(peer_name, NULL))) {
06953 ast_mutex_lock(&iaxsl[callno]);
06954 if (!(p = iaxs[callno])) {
06955 peer_unref(peer);
06956 return -1;
06957 }
06958 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
06959 peer_unref(peer);
06960 }
06961 if (!peer) {
06962 ast_mutex_lock(&iaxsl[callno]);
06963 if (!(p = iaxs[callno]))
06964 return -1;
06965 }
06966 }
06967 }
06968 if (ies->encmethods)
06969 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
06970 if (!res)
06971 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
06972 return res;
06973 }
06974
06975 static int iax2_do_register(struct iax2_registry *reg);
06976
06977 static void __iax2_do_register_s(const void *data)
06978 {
06979 struct iax2_registry *reg = (struct iax2_registry *)data;
06980 reg->expire = -1;
06981 iax2_do_register(reg);
06982 }
06983
06984 static int iax2_do_register_s(const void *data)
06985 {
06986 #ifdef SCHED_MULTITHREADED
06987 if (schedule_action(__iax2_do_register_s, data))
06988 #endif
06989 __iax2_do_register_s(data);
06990 return 0;
06991 }
06992
06993 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06994 {
06995 int newcall = 0;
06996 char newip[256];
06997 struct iax_ie_data ied;
06998 struct sockaddr_in new;
06999
07000
07001 memset(&ied, 0, sizeof(ied));
07002 if (ies->apparent_addr)
07003 bcopy(ies->apparent_addr, &new, sizeof(new));
07004 if (ies->callno)
07005 newcall = ies->callno;
07006 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
07007 ast_log(LOG_WARNING, "Invalid transfer request\n");
07008 return -1;
07009 }
07010 pvt->transfercallno = newcall;
07011 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
07012 inet_aton(newip, &pvt->transfer.sin_addr);
07013 pvt->transfer.sin_family = AF_INET;
07014 pvt->transferring = TRANSFER_BEGIN;
07015 pvt->transferid = ies->transferid;
07016 store_by_transfercallno(pvt);
07017 if (ies->transferid)
07018 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
07019 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
07020 return 0;
07021 }
07022
07023 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07024 {
07025 char exten[256] = "";
07026 int status = CACHE_FLAG_UNKNOWN;
07027 int expiry = iaxdefaultdpcache;
07028 int x;
07029 int matchmore = 0;
07030 struct iax2_dpcache *dp, *prev;
07031
07032 if (ies->called_number)
07033 ast_copy_string(exten, ies->called_number, sizeof(exten));
07034
07035 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
07036 status = CACHE_FLAG_EXISTS;
07037 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
07038 status = CACHE_FLAG_CANEXIST;
07039 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
07040 status = CACHE_FLAG_NONEXISTENT;
07041
07042 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
07043
07044 }
07045 if (ies->refresh)
07046 expiry = ies->refresh;
07047 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
07048 matchmore = CACHE_FLAG_MATCHMORE;
07049 ast_mutex_lock(&dpcache_lock);
07050 prev = NULL;
07051 dp = pvt->dpentries;
07052 while(dp) {
07053 if (!strcmp(dp->exten, exten)) {
07054
07055 if (prev)
07056 prev->peer = dp->peer;
07057 else
07058 pvt->dpentries = dp->peer;
07059 dp->peer = NULL;
07060 dp->callno = 0;
07061 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
07062 if (dp->flags & CACHE_FLAG_PENDING) {
07063 dp->flags &= ~CACHE_FLAG_PENDING;
07064 dp->flags |= status;
07065 dp->flags |= matchmore;
07066 }
07067
07068 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
07069 if (dp->waiters[x] > -1) {
07070 if (write(dp->waiters[x], "asdf", 4) < 0) {
07071 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
07072 }
07073 }
07074 }
07075 }
07076 prev = dp;
07077 dp = dp->peer;
07078 }
07079 ast_mutex_unlock(&dpcache_lock);
07080 return 0;
07081 }
07082
07083 static int complete_transfer(int callno, struct iax_ies *ies)
07084 {
07085 int peercallno = 0;
07086 struct chan_iax2_pvt *pvt = iaxs[callno];
07087 struct iax_frame *cur;
07088 jb_frame frame;
07089
07090 if (ies->callno)
07091 peercallno = ies->callno;
07092
07093 if (peercallno < 1) {
07094 ast_log(LOG_WARNING, "Invalid transfer request\n");
07095 return -1;
07096 }
07097 remove_by_transfercallno(pvt);
07098
07099
07100
07101 peercnt_remove_by_addr(&pvt->addr);
07102 peercnt_add(&pvt->transfer);
07103
07104 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
07105 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
07106
07107 pvt->oseqno = 0;
07108 pvt->rseqno = 0;
07109 pvt->iseqno = 0;
07110 pvt->aseqno = 0;
07111
07112 if (pvt->peercallno) {
07113 remove_by_peercallno(pvt);
07114 }
07115 pvt->peercallno = peercallno;
07116
07117 store_by_peercallno(pvt);
07118 pvt->transferring = TRANSFER_NONE;
07119 pvt->svoiceformat = -1;
07120 pvt->voiceformat = 0;
07121 pvt->svideoformat = -1;
07122 pvt->videoformat = 0;
07123 pvt->transfercallno = -1;
07124 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
07125 memset(&pvt->offset, 0, sizeof(pvt->offset));
07126
07127 while(jb_getall(pvt->jb,&frame) == JB_OK)
07128 iax2_frame_free(frame.data);
07129 jb_reset(pvt->jb);
07130 pvt->lag = 0;
07131 pvt->last = 0;
07132 pvt->lastsent = 0;
07133 pvt->nextpred = 0;
07134 pvt->pingtime = DEFAULT_RETRY_TIME;
07135 AST_LIST_LOCK(&iaxq.queue);
07136 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07137
07138
07139
07140 if (callno == cur->callno)
07141 cur->retries = -1;
07142 }
07143 AST_LIST_UNLOCK(&iaxq.queue);
07144 return 0;
07145 }
07146
07147
07148 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
07149 {
07150 struct iax2_registry *reg;
07151
07152 char peer[256] = "";
07153 char msgstatus[60];
07154 int refresh = 60;
07155 char ourip[256] = "<Unspecified>";
07156 struct sockaddr_in oldus;
07157 struct sockaddr_in us;
07158 int oldmsgs;
07159
07160 memset(&us, 0, sizeof(us));
07161 if (ies->apparent_addr)
07162 bcopy(ies->apparent_addr, &us, sizeof(us));
07163 if (ies->username)
07164 ast_copy_string(peer, ies->username, sizeof(peer));
07165 if (ies->refresh)
07166 refresh = ies->refresh;
07167 if (ies->calling_number) {
07168
07169 }
07170 reg = iaxs[callno]->reg;
07171 if (!reg) {
07172 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
07173 return -1;
07174 }
07175 memcpy(&oldus, ®->us, sizeof(oldus));
07176 oldmsgs = reg->messages;
07177 if (inaddrcmp(®->addr, sin)) {
07178 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07179 return -1;
07180 }
07181 memcpy(®->us, &us, sizeof(reg->us));
07182 if (ies->msgcount >= 0)
07183 reg->messages = ies->msgcount & 0xffff;
07184
07185
07186
07187 reg->refresh = refresh;
07188 AST_SCHED_DEL(sched, reg->expire);
07189 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07190 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
07191 if (option_verbose > 2) {
07192 if (reg->messages > 255)
07193 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
07194 else if (reg->messages > 1)
07195 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
07196 else if (reg->messages > 0)
07197 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
07198 else
07199 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
07200 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07201 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
07202 }
07203 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
07204 }
07205 reg->regstate = REG_STATE_REGISTERED;
07206 return 0;
07207 }
07208
07209 static int iax2_register(char *value, int lineno)
07210 {
07211 struct iax2_registry *reg;
07212 char copy[256];
07213 char *username, *hostname, *secret;
07214 char *porta;
07215 char *stringp=NULL;
07216
07217 if (!value)
07218 return -1;
07219 ast_copy_string(copy, value, sizeof(copy));
07220 stringp=copy;
07221 username = strsep(&stringp, "@");
07222 hostname = strsep(&stringp, "@");
07223 if (!hostname) {
07224 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
07225 return -1;
07226 }
07227 stringp=username;
07228 username = strsep(&stringp, ":");
07229 secret = strsep(&stringp, ":");
07230 stringp=hostname;
07231 hostname = strsep(&stringp, ":");
07232 porta = strsep(&stringp, ":");
07233
07234 if (porta && !atoi(porta)) {
07235 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
07236 return -1;
07237 }
07238 if (!(reg = ast_calloc(1, sizeof(*reg))))
07239 return -1;
07240 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) {
07241 free(reg);
07242 return -1;
07243 }
07244 ast_copy_string(reg->username, username, sizeof(reg->username));
07245 if (secret)
07246 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
07247 reg->expire = -1;
07248 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
07249 reg->addr.sin_family = AF_INET;
07250 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
07251 AST_LIST_LOCK(®istrations);
07252 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
07253 AST_LIST_UNLOCK(®istrations);
07254
07255 return 0;
07256 }
07257
07258 static void register_peer_exten(struct iax2_peer *peer, int onoff)
07259 {
07260 char multi[256];
07261 char *stringp, *ext;
07262 if (!ast_strlen_zero(regcontext)) {
07263 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
07264 stringp = multi;
07265 while((ext = strsep(&stringp, "&"))) {
07266 if (onoff) {
07267 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
07268 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
07269 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
07270 } else
07271 ast_context_remove_extension(regcontext, ext, 1, NULL);
07272 }
07273 }
07274 }
07275 static void prune_peers(void);
07276
07277 static void unlink_peer(struct iax2_peer *peer)
07278 {
07279 if (peer->expire > -1) {
07280 if (!ast_sched_del(sched, peer->expire)) {
07281 peer->expire = -1;
07282 peer_unref(peer);
07283 }
07284 }
07285
07286 if (peer->pokeexpire > -1) {
07287 if (!ast_sched_del(sched, peer->pokeexpire)) {
07288 peer->pokeexpire = -1;
07289 peer_unref(peer);
07290 }
07291 }
07292
07293 ao2_unlink(peers, peer);
07294 }
07295
07296 static void __expire_registry(const void *data)
07297 {
07298 struct iax2_peer *peer = (struct iax2_peer *) data;
07299
07300 if (!peer)
07301 return;
07302
07303 peer->expire = -1;
07304
07305 if (option_debug)
07306 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
07307 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
07308 realtime_update_peer(peer->name, &peer->addr, 0);
07309 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07310
07311 peercnt_modify(0, 0, &peer->addr);
07312
07313 memset(&peer->addr, 0, sizeof(peer->addr));
07314
07315 peer->expiry = min_reg_expire;
07316 if (!ast_test_flag(peer, IAX_TEMPONLY))
07317 ast_db_del("IAX/Registry", peer->name);
07318 register_peer_exten(peer, 0);
07319 ast_device_state_changed("IAX2/%s", peer->name);
07320 if (iax2_regfunk)
07321 iax2_regfunk(peer->name, 0);
07322
07323 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
07324 unlink_peer(peer);
07325
07326 peer_unref(peer);
07327 }
07328
07329 static int expire_registry(const void *data)
07330 {
07331 #ifdef SCHED_MULTITHREADED
07332 if (schedule_action(__expire_registry, data))
07333 #endif
07334 __expire_registry(data);
07335 return 0;
07336 }
07337
07338 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
07339
07340 static void reg_source_db(struct iax2_peer *p)
07341 {
07342 char data[80];
07343 struct in_addr in;
07344 char *c, *d;
07345 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
07346 c = strchr(data, ':');
07347 if (c) {
07348 *c = '\0';
07349 c++;
07350 if (inet_aton(data, &in)) {
07351 d = strchr(c, ':');
07352 if (d) {
07353 *d = '\0';
07354 d++;
07355 if (option_verbose > 2)
07356 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name,
07357 ast_inet_ntoa(in), atoi(c), atoi(d));
07358 iax2_poke_peer(p, 0);
07359 p->expiry = atoi(d);
07360 memset(&p->addr, 0, sizeof(p->addr));
07361 p->addr.sin_family = AF_INET;
07362 p->addr.sin_addr = in;
07363 p->addr.sin_port = htons(atoi(c));
07364 if (p->expire > -1) {
07365 if (!ast_sched_del(sched, p->expire)) {
07366 p->expire = -1;
07367 peer_unref(p);
07368 }
07369 }
07370 ast_device_state_changed("IAX2/%s", p->name);
07371 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07372 if (p->expire == -1)
07373 peer_unref(p);
07374 if (iax2_regfunk)
07375 iax2_regfunk(p->name, 1);
07376 register_peer_exten(p, 1);
07377 }
07378
07379 }
07380 }
07381 }
07382 }
07383
07384
07385
07386
07387
07388
07389
07390 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
07391 {
07392
07393 struct iax_ie_data ied;
07394 struct iax2_peer *p;
07395 int msgcount;
07396 char data[80];
07397 int version;
07398 const char *peer_name;
07399 int res = -1;
07400
07401 memset(&ied, 0, sizeof(ied));
07402
07403 peer_name = ast_strdupa(iaxs[callno]->peer);
07404
07405
07406 ast_mutex_unlock(&iaxsl[callno]);
07407 if (!(p = find_peer(peer_name, 1))) {
07408 ast_mutex_lock(&iaxsl[callno]);
07409 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
07410 return -1;
07411 }
07412 ast_mutex_lock(&iaxsl[callno]);
07413 if (!iaxs[callno])
07414 goto return_unref;
07415
07416 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
07417 if (sin->sin_addr.s_addr) {
07418 time_t nowtime;
07419 time(&nowtime);
07420 realtime_update_peer(peer_name, sin, nowtime);
07421 } else {
07422 realtime_update_peer(peer_name, sin, 0);
07423 }
07424 }
07425 if (inaddrcmp(&p->addr, sin)) {
07426 if (iax2_regfunk)
07427 iax2_regfunk(p->name, 1);
07428
07429
07430 peercnt_modify(0, 0, &p->addr);
07431
07432
07433 memcpy(&p->addr, sin, sizeof(p->addr));
07434
07435 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
07436 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
07437 ast_db_put("IAX/Registry", p->name, data);
07438 if (option_verbose > 2)
07439 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
07440 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
07441 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
07442 register_peer_exten(p, 1);
07443 ast_device_state_changed("IAX2/%s", p->name);
07444 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
07445 if (option_verbose > 2)
07446 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name,
07447 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
07448 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
07449 register_peer_exten(p, 0);
07450 ast_db_del("IAX/Registry", p->name);
07451 ast_device_state_changed("IAX2/%s", p->name);
07452 }
07453
07454
07455 iax2_poke_peer(p, callno);
07456 }
07457
07458
07459 if (p->maxcallno) {
07460 peercnt_modify(1, p->maxcallno, &p->addr);
07461 }
07462
07463
07464 if (!iaxs[callno]) {
07465 res = -1;
07466 goto return_unref;
07467 }
07468
07469
07470 p->sockfd = fd;
07471
07472 if (p->expire > -1) {
07473 if (!ast_sched_del(sched, p->expire)) {
07474 p->expire = -1;
07475 peer_unref(p);
07476 }
07477 }
07478
07479 if (!refresh)
07480 refresh = min_reg_expire;
07481 if (refresh > max_reg_expire) {
07482 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07483 p->name, max_reg_expire, refresh);
07484 p->expiry = max_reg_expire;
07485 } else if (refresh < min_reg_expire) {
07486 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07487 p->name, min_reg_expire, refresh);
07488 p->expiry = min_reg_expire;
07489 } else {
07490 p->expiry = refresh;
07491 }
07492 if (p->expiry && sin->sin_addr.s_addr) {
07493 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07494 if (p->expire == -1)
07495 peer_unref(p);
07496 }
07497 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
07498 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
07499 if (sin->sin_addr.s_addr) {
07500 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
07501 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
07502 if (!ast_strlen_zero(p->mailbox)) {
07503 int new, old;
07504 ast_app_inboxcount(p->mailbox, &new, &old);
07505 if (new > 255)
07506 new = 255;
07507 if (old > 255)
07508 old = 255;
07509 msgcount = (old << 8) | new;
07510 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
07511 }
07512 if (ast_test_flag(p, IAX_HASCALLERID)) {
07513 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
07514 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
07515 }
07516 }
07517 version = iax_check_version(devtype);
07518 if (version)
07519 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
07520
07521 res = 0;
07522
07523 return_unref:
07524 peer_unref(p);
07525
07526 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
07527 }
07528
07529 static int registry_authrequest(int callno)
07530 {
07531 struct iax_ie_data ied;
07532 struct iax2_peer *p;
07533 char challenge[10];
07534 const char *peer_name;
07535 int sentauthmethod;
07536
07537 peer_name = ast_strdupa(iaxs[callno]->peer);
07538
07539
07540 ast_mutex_unlock(&iaxsl[callno]);
07541 if ((p = find_peer(peer_name, 1))) {
07542 last_authmethod = p->authmethods;
07543 }
07544
07545 ast_mutex_lock(&iaxsl[callno]);
07546 if (!iaxs[callno])
07547 goto return_unref;
07548
07549 memset(&ied, 0, sizeof(ied));
07550
07551
07552
07553
07554
07555
07556 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07557 if (!p) {
07558 iaxs[callno]->authmethods = sentauthmethod;
07559 }
07560 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
07561 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
07562
07563 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07564 ast_string_field_set(iaxs[callno], challenge, challenge);
07565 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
07566 }
07567 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
07568
07569 return_unref:
07570 if (p) {
07571 peer_unref(p);
07572 }
07573
07574 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
07575 }
07576
07577 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
07578 {
07579 struct iax2_registry *reg;
07580
07581 struct iax_ie_data ied;
07582 char peer[256] = "";
07583 char challenge[256] = "";
07584 int res;
07585 int authmethods = 0;
07586 if (ies->authmethods)
07587 authmethods = ies->authmethods;
07588 if (ies->username)
07589 ast_copy_string(peer, ies->username, sizeof(peer));
07590 if (ies->challenge)
07591 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
07592 memset(&ied, 0, sizeof(ied));
07593 reg = iaxs[callno]->reg;
07594 if (reg) {
07595 if (inaddrcmp(®->addr, sin)) {
07596 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07597 return -1;
07598 }
07599 if (ast_strlen_zero(reg->secret)) {
07600 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
07601 reg->regstate = REG_STATE_NOAUTH;
07602 return -1;
07603 }
07604 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07605 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07606 if (reg->secret[0] == '[') {
07607 char tmpkey[256];
07608 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
07609 tmpkey[strlen(tmpkey) - 1] = '\0';
07610 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
07611 } else
07612 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
07613 if (!res) {
07614 reg->regstate = REG_STATE_AUTHSENT;
07615 add_empty_calltoken_ie(iaxs[callno], &ied);
07616 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07617 } else
07618 return -1;
07619 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
07620 } else
07621 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
07622 return -1;
07623 }
07624
07625 static void stop_stuff(int callno)
07626 {
07627 iax2_destroy_helper(iaxs[callno]);
07628 }
07629
07630 static void __auth_reject(const void *nothing)
07631 {
07632
07633 int callno = (int)(long)(nothing);
07634 struct iax_ie_data ied;
07635 ast_mutex_lock(&iaxsl[callno]);
07636 if (iaxs[callno]) {
07637 memset(&ied, 0, sizeof(ied));
07638 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
07639 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
07640 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
07641 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
07642 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
07643 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07644 }
07645 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
07646 }
07647 ast_mutex_unlock(&iaxsl[callno]);
07648 }
07649
07650 static int auth_reject(const void *data)
07651 {
07652 int callno = (int)(long)(data);
07653 ast_mutex_lock(&iaxsl[callno]);
07654 if (iaxs[callno])
07655 iaxs[callno]->authid = -1;
07656 ast_mutex_unlock(&iaxsl[callno]);
07657 #ifdef SCHED_MULTITHREADED
07658 if (schedule_action(__auth_reject, data))
07659 #endif
07660 __auth_reject(data);
07661 return 0;
07662 }
07663
07664 static int auth_fail(int callno, int failcode)
07665 {
07666
07667
07668 if (iaxs[callno]) {
07669 iaxs[callno]->authfail = failcode;
07670 if (delayreject) {
07671 AST_SCHED_DEL(sched, iaxs[callno]->authid);
07672 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
07673 } else
07674 auth_reject((void *)(long)callno);
07675 }
07676 return 0;
07677 }
07678
07679 static void __auto_hangup(const void *nothing)
07680 {
07681
07682 int callno = (int)(long)(nothing);
07683 struct iax_ie_data ied;
07684 ast_mutex_lock(&iaxsl[callno]);
07685 if (iaxs[callno]) {
07686 memset(&ied, 0, sizeof(ied));
07687 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
07688 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
07689 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
07690 }
07691 ast_mutex_unlock(&iaxsl[callno]);
07692 }
07693
07694 static int auto_hangup(const void *data)
07695 {
07696 int callno = (int)(long)(data);
07697 ast_mutex_lock(&iaxsl[callno]);
07698 if (iaxs[callno]) {
07699 iaxs[callno]->autoid = -1;
07700 }
07701 ast_mutex_unlock(&iaxsl[callno]);
07702 #ifdef SCHED_MULTITHREADED
07703 if (schedule_action(__auto_hangup, data))
07704 #endif
07705 __auto_hangup(data);
07706 return 0;
07707 }
07708
07709 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
07710 {
07711 struct iax_ie_data ied;
07712
07713 AST_SCHED_DEL(sched, iaxs[callno]->autoid);
07714 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
07715 memset(&ied, 0, sizeof(ied));
07716 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
07717 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
07718 dp->flags |= CACHE_FLAG_TRANSMITTED;
07719 }
07720
07721 static int iax2_vnak(int callno)
07722 {
07723 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
07724 }
07725
07726 static void vnak_retransmit(int callno, int last)
07727 {
07728 struct iax_frame *f;
07729
07730 AST_LIST_LOCK(&iaxq.queue);
07731 AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
07732
07733 if ((f->callno == callno) && iaxs[f->callno] &&
07734 ((unsigned char ) (f->oseqno - last) < 128) &&
07735 (f->retries >= 0)) {
07736 send_packet(f);
07737 }
07738 }
07739 AST_LIST_UNLOCK(&iaxq.queue);
07740 }
07741
07742 static void __iax2_poke_peer_s(const void *data)
07743 {
07744 struct iax2_peer *peer = (struct iax2_peer *)data;
07745 iax2_poke_peer(peer, 0);
07746 peer_unref(peer);
07747 }
07748
07749 static int iax2_poke_peer_s(const void *data)
07750 {
07751 struct iax2_peer *peer = (struct iax2_peer *)data;
07752 peer->pokeexpire = -1;
07753 #ifdef SCHED_MULTITHREADED
07754 if (schedule_action(__iax2_poke_peer_s, data))
07755 #endif
07756 __iax2_poke_peer_s(data);
07757 return 0;
07758 }
07759
07760 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
07761 {
07762 int res = 0;
07763 struct iax_frame *fr;
07764 struct ast_iax2_meta_hdr *meta;
07765 struct ast_iax2_meta_trunk_hdr *mth;
07766 int calls = 0;
07767
07768
07769 fr = (struct iax_frame *)tpeer->trunkdata;
07770
07771 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
07772 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
07773 if (tpeer->trunkdatalen) {
07774
07775 meta->zeros = 0;
07776 meta->metacmd = IAX_META_TRUNK;
07777 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
07778 meta->cmddata = IAX_META_TRUNK_MINI;
07779 else
07780 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
07781 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
07782
07783 fr->direction = DIRECTION_OUTGRESS;
07784 fr->retrans = -1;
07785 fr->transfer = 0;
07786
07787 fr->data = fr->afdata;
07788 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
07789 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
07790 calls = tpeer->calls;
07791 #if 0
07792 if (option_debug)
07793 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));
07794 #endif
07795
07796 tpeer->trunkdatalen = 0;
07797 tpeer->calls = 0;
07798 }
07799 if (res < 0)
07800 return res;
07801 return calls;
07802 }
07803
07804 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
07805 {
07806
07807 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
07808 return 1;
07809 return 0;
07810 }
07811
07812 static int timing_read(int *id, int fd, short events, void *cbdata)
07813 {
07814 char buf[1024];
07815 int res;
07816 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
07817 int processed = 0;
07818 int totalcalls = 0;
07819 #ifdef DAHDI_TIMERACK
07820 int x = 1;
07821 #endif
07822 struct timeval now;
07823 if (iaxtrunkdebug)
07824 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
07825 gettimeofday(&now, NULL);
07826 if (events & AST_IO_PRI) {
07827 #ifdef DAHDI_TIMERACK
07828
07829 if (ioctl(fd, DAHDI_TIMERACK, &x)) {
07830 ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n");
07831 usleep(1);
07832 return -1;
07833 }
07834 #endif
07835 } else {
07836
07837 res = read(fd, buf, sizeof(buf));
07838 if (res < 1) {
07839 ast_log(LOG_WARNING, "Unable to read from timing fd\n");
07840 return 1;
07841 }
07842 }
07843
07844 ast_mutex_lock(&tpeerlock);
07845 tpeer = tpeers;
07846 while(tpeer) {
07847 processed++;
07848 res = 0;
07849 ast_mutex_lock(&tpeer->lock);
07850
07851
07852 if (!drop && iax2_trunk_expired(tpeer, &now)) {
07853
07854
07855 if (prev)
07856 prev->next = tpeer->next;
07857 else
07858 tpeers = tpeer->next;
07859 drop = tpeer;
07860 } else {
07861 res = send_trunk(tpeer, &now);
07862 if (iaxtrunkdebug)
07863 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);
07864 }
07865 totalcalls += res;
07866 res = 0;
07867 ast_mutex_unlock(&tpeer->lock);
07868 prev = tpeer;
07869 tpeer = tpeer->next;
07870 }
07871 ast_mutex_unlock(&tpeerlock);
07872 if (drop) {
07873 ast_mutex_lock(&drop->lock);
07874
07875
07876 if (option_debug)
07877 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
07878 if (drop->trunkdata) {
07879 free(drop->trunkdata);
07880 drop->trunkdata = NULL;
07881 }
07882 ast_mutex_unlock(&drop->lock);
07883 ast_mutex_destroy(&drop->lock);
07884 free(drop);
07885
07886 }
07887 if (iaxtrunkdebug)
07888 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
07889 iaxtrunkdebug =0;
07890 return 1;
07891 }
07892
07893 struct dpreq_data {
07894 int callno;
07895 char context[AST_MAX_EXTENSION];
07896 char callednum[AST_MAX_EXTENSION];
07897 char *callerid;
07898 };
07899
07900 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
07901 {
07902 unsigned short dpstatus = 0;
07903 struct iax_ie_data ied1;
07904 int mm;
07905
07906 memset(&ied1, 0, sizeof(ied1));
07907 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
07908
07909 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
07910 dpstatus = IAX_DPSTATUS_EXISTS;
07911 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
07912 dpstatus = IAX_DPSTATUS_CANEXIST;
07913 } else {
07914 dpstatus = IAX_DPSTATUS_NONEXISTENT;
07915 }
07916 if (ast_ignore_pattern(context, callednum))
07917 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
07918 if (mm)
07919 dpstatus |= IAX_DPSTATUS_MATCHMORE;
07920 if (!skiplock)
07921 ast_mutex_lock(&iaxsl[callno]);
07922 if (iaxs[callno]) {
07923 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
07924 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
07925 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
07926 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
07927 }
07928 if (!skiplock)
07929 ast_mutex_unlock(&iaxsl[callno]);
07930 }
07931
07932 static void *dp_lookup_thread(void *data)
07933 {
07934
07935 struct dpreq_data *dpr = data;
07936 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
07937 if (dpr->callerid)
07938 free(dpr->callerid);
07939 free(dpr);
07940 return NULL;
07941 }
07942
07943 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
07944 {
07945 pthread_t newthread;
07946 struct dpreq_data *dpr;
07947 pthread_attr_t attr;
07948
07949 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
07950 return;
07951
07952 pthread_attr_init(&attr);
07953 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
07954
07955 dpr->callno = callno;
07956 ast_copy_string(dpr->context, context, sizeof(dpr->context));
07957 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
07958 if (callerid)
07959 dpr->callerid = ast_strdup(callerid);
07960 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
07961 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
07962 }
07963
07964 pthread_attr_destroy(&attr);
07965 }
07966
07967 struct iax_dual {
07968 struct ast_channel *chan1;
07969 struct ast_channel *chan2;
07970 };
07971
07972 static void *iax_park_thread(void *stuff)
07973 {
07974 struct ast_channel *chan1, *chan2;
07975 struct iax_dual *d;
07976 struct ast_frame *f;
07977 int ext;
07978 int res;
07979 d = stuff;
07980 chan1 = d->chan1;
07981 chan2 = d->chan2;
07982 free(d);
07983 f = ast_read(chan1);
07984 if (f)
07985 ast_frfree(f);
07986 res = ast_park_call(chan1, chan2, 0, &ext);
07987 ast_hangup(chan2);
07988 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
07989 return NULL;
07990 }
07991
07992 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
07993 {
07994 struct iax_dual *d;
07995 struct ast_channel *chan1m, *chan2m;
07996 pthread_t th;
07997 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
07998 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
07999 if (chan2m && chan1m) {
08000
08001 chan1m->readformat = chan1->readformat;
08002 chan1m->writeformat = chan1->writeformat;
08003 ast_channel_masquerade(chan1m, chan1);
08004
08005 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
08006 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
08007 chan1m->priority = chan1->priority;
08008
08009
08010
08011
08012 chan2m->readformat = chan2->readformat;
08013 chan2m->writeformat = chan2->writeformat;
08014 ast_channel_masquerade(chan2m, chan2);
08015
08016 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
08017 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
08018 chan2m->priority = chan2->priority;
08019 if (ast_do_masquerade(chan2m)) {
08020 ast_log(LOG_WARNING, "Masquerade failed :(\n");
08021 ast_hangup(chan2m);
08022 return -1;
08023 }
08024 } else {
08025 if (chan1m)
08026 ast_hangup(chan1m);
08027 if (chan2m)
08028 ast_hangup(chan2m);
08029 return -1;
08030 }
08031 if ((d = ast_calloc(1, sizeof(*d)))) {
08032 pthread_attr_t attr;
08033
08034 pthread_attr_init(&attr);
08035 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08036
08037 d->chan1 = chan1m;
08038 d->chan2 = chan2m;
08039 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
08040 pthread_attr_destroy(&attr);
08041 return 0;
08042 }
08043 pthread_attr_destroy(&attr);
08044 free(d);
08045 }
08046 return -1;
08047 }
08048
08049
08050 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
08051
08052 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
08053 {
08054 unsigned int ourver;
08055 char rsi[80];
08056 snprintf(rsi, sizeof(rsi), "si-%s", si);
08057 if (iax_provision_version(&ourver, rsi, 1))
08058 return 0;
08059 if (option_debug)
08060 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
08061 if (ourver != ver)
08062 iax2_provision(sin, sockfd, NULL, rsi, 1);
08063 return 0;
08064 }
08065
08066 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
08067 {
08068 jb_info stats;
08069 jb_getinfo(pvt->jb, &stats);
08070
08071 memset(iep, 0, sizeof(*iep));
08072
08073 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
08074 if(stats.frames_in == 0) stats.frames_in = 1;
08075 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
08076 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
08077 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
08078 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
08079 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
08080 }
08081
08082 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
08083 {
08084 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
08085 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
08086 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
08087 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
08088 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
08089 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
08090 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
08091 }
08092
08093 static int socket_process(struct iax2_thread *thread);
08094
08095
08096
08097
08098 static void handle_deferred_full_frames(struct iax2_thread *thread)
08099 {
08100 struct iax2_pkt_buf *pkt_buf;
08101
08102 ast_mutex_lock(&thread->lock);
08103
08104 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
08105 ast_mutex_unlock(&thread->lock);
08106
08107 thread->buf = pkt_buf->buf;
08108 thread->buf_len = pkt_buf->len;
08109 thread->buf_size = pkt_buf->len + 1;
08110
08111 socket_process(thread);
08112
08113 thread->buf = NULL;
08114 ast_free(pkt_buf);
08115
08116 ast_mutex_lock(&thread->lock);
08117 }
08118
08119 ast_mutex_unlock(&thread->lock);
08120 }
08121
08122
08123
08124
08125
08126
08127
08128 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
08129 {
08130 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
08131 struct ast_iax2_full_hdr *fh, *cur_fh;
08132
08133 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
08134 return;
08135
08136 pkt_buf->len = from_here->buf_len;
08137 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
08138
08139 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
08140 ast_mutex_lock(&to_here->lock);
08141 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
08142 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
08143 if (fh->oseqno < cur_fh->oseqno) {
08144 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
08145 break;
08146 }
08147 }
08148 AST_LIST_TRAVERSE_SAFE_END
08149
08150 if (!cur_pkt_buf)
08151 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
08152
08153 ast_mutex_unlock(&to_here->lock);
08154 }
08155
08156 static int socket_read(int *id, int fd, short events, void *cbdata)
08157 {
08158 struct iax2_thread *thread;
08159 socklen_t len;
08160 time_t t;
08161 static time_t last_errtime = 0;
08162 struct ast_iax2_full_hdr *fh;
08163
08164 if (!(thread = find_idle_thread())) {
08165 time(&t);
08166 if (t != last_errtime && option_debug)
08167 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
08168 last_errtime = t;
08169 usleep(1);
08170 return 1;
08171 }
08172
08173 len = sizeof(thread->iosin);
08174 thread->iofd = fd;
08175 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
08176 thread->buf_size = sizeof(thread->readbuf);
08177 thread->buf = thread->readbuf;
08178 if (thread->buf_len < 0) {
08179 if (errno != ECONNREFUSED && errno != EAGAIN)
08180 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
08181 handle_error();
08182 thread->iostate = IAX_IOSTATE_IDLE;
08183 signal_condition(&thread->lock, &thread->cond);
08184 return 1;
08185 }
08186 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
08187 thread->iostate = IAX_IOSTATE_IDLE;
08188 signal_condition(&thread->lock, &thread->cond);
08189 return 1;
08190 }
08191
08192
08193
08194
08195 fh = (struct ast_iax2_full_hdr *) thread->buf;
08196 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
08197 struct iax2_thread *cur = NULL;
08198 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
08199
08200 AST_LIST_LOCK(&active_list);
08201 AST_LIST_TRAVERSE(&active_list, cur, list) {
08202 if ((cur->ffinfo.callno == callno) &&
08203 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
08204 break;
08205 }
08206 if (cur) {
08207
08208
08209 defer_full_frame(thread, cur);
08210 AST_LIST_UNLOCK(&active_list);
08211 thread->iostate = IAX_IOSTATE_IDLE;
08212 signal_condition(&thread->lock, &thread->cond);
08213 return 1;
08214 } else {
08215
08216 thread->ffinfo.callno = callno;
08217 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
08218 thread->ffinfo.type = fh->type;
08219 thread->ffinfo.csub = fh->csub;
08220 }
08221 AST_LIST_UNLOCK(&active_list);
08222 }
08223
08224
08225 thread->iostate = IAX_IOSTATE_READY;
08226 #ifdef DEBUG_SCHED_MULTITHREAD
08227 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
08228 #endif
08229 signal_condition(&thread->lock, &thread->cond);
08230
08231 return 1;
08232 }
08233
08234 static int socket_process(struct iax2_thread *thread)
08235 {
08236 struct sockaddr_in sin;
08237 int res;
08238 int updatehistory=1;
08239 int new = NEW_PREVENT;
08240 void *ptr;
08241 int dcallno = 0;
08242 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
08243 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
08244 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
08245 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
08246 struct ast_iax2_meta_trunk_hdr *mth;
08247 struct ast_iax2_meta_trunk_entry *mte;
08248 struct ast_iax2_meta_trunk_mini *mtm;
08249 struct iax_frame *fr;
08250 struct iax_frame *cur;
08251 struct ast_frame f = { 0, };
08252 struct ast_channel *c;
08253 struct iax2_dpcache *dp;
08254 struct iax2_peer *peer;
08255 struct iax2_trunk_peer *tpeer;
08256 struct timeval rxtrunktime;
08257 struct iax_ies ies;
08258 struct iax_ie_data ied0, ied1;
08259 int format;
08260 int fd;
08261 int exists;
08262 int minivid = 0;
08263 unsigned int ts;
08264 char empty[32]="";
08265 struct iax_frame *duped_fr;
08266 char host_pref_buf[128];
08267 char caller_pref_buf[128];
08268 struct ast_codec_pref pref;
08269 char *using_prefs = "mine";
08270
08271
08272 fr = alloca(sizeof(*fr) + 4096);
08273 memset(fr, 0, sizeof(*fr));
08274 fr->afdatalen = 4096;
08275
08276
08277 res = thread->buf_len;
08278 fd = thread->iofd;
08279 memcpy(&sin, &thread->iosin, sizeof(sin));
08280
08281 if (res < sizeof(*mh)) {
08282 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
08283 return 1;
08284 }
08285 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
08286 if (res < sizeof(*vh)) {
08287 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));
08288 return 1;
08289 }
08290
08291
08292 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
08293 minivid = 1;
08294 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
08295 unsigned char metatype;
08296
08297 if (res < sizeof(*meta)) {
08298 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));
08299 return 1;
08300 }
08301
08302
08303 switch(meta->metacmd) {
08304 case IAX_META_TRUNK:
08305 if (res < (sizeof(*meta) + sizeof(*mth))) {
08306 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
08307 sizeof(*meta) + sizeof(*mth));
08308 return 1;
08309 }
08310 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
08311 ts = ntohl(mth->ts);
08312 metatype = meta->cmddata;
08313 res -= (sizeof(*meta) + sizeof(*mth));
08314 ptr = mth->data;
08315 tpeer = find_tpeer(&sin, fd);
08316 if (!tpeer) {
08317 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));
08318 return 1;
08319 }
08320 tpeer->trunkact = ast_tvnow();
08321 if (!ts || ast_tvzero(tpeer->rxtrunktime))
08322 tpeer->rxtrunktime = tpeer->trunkact;
08323 rxtrunktime = tpeer->rxtrunktime;
08324 ast_mutex_unlock(&tpeer->lock);
08325 while(res >= sizeof(*mte)) {
08326
08327 unsigned short callno, trunked_ts, len;
08328
08329 if (metatype == IAX_META_TRUNK_MINI) {
08330 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
08331 ptr += sizeof(*mtm);
08332 res -= sizeof(*mtm);
08333 len = ntohs(mtm->len);
08334 callno = ntohs(mtm->mini.callno);
08335 trunked_ts = ntohs(mtm->mini.ts);
08336 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
08337 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
08338 ptr += sizeof(*mte);
08339 res -= sizeof(*mte);
08340 len = ntohs(mte->len);
08341 callno = ntohs(mte->callno);
08342 trunked_ts = 0;
08343 } else {
08344 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
08345 break;
08346 }
08347
08348 if (len > res)
08349 break;
08350 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
08351 if (fr->callno) {
08352
08353
08354
08355 memset(&f, 0, sizeof(f));
08356 f.frametype = AST_FRAME_VOICE;
08357 if (iaxs[fr->callno]) {
08358 if (iaxs[fr->callno]->voiceformat > 0) {
08359 f.subclass = iaxs[fr->callno]->voiceformat;
08360 f.datalen = len;
08361 if (f.datalen >= 0) {
08362 if (f.datalen)
08363 f.data = ptr;
08364 if(trunked_ts) {
08365 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
08366 } else
08367 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
08368
08369 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08370
08371 f.src = "IAX2";
08372 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
08373 f.samples = ast_codec_get_samples(&f);
08374 iax_frame_wrap(fr, &f);
08375 duped_fr = iaxfrdup2(fr);
08376 if (duped_fr) {
08377 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
08378 }
08379
08380 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08381 iaxs[fr->callno]->last = fr->ts;
08382 #if 1
08383 if (option_debug && iaxdebug)
08384 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08385 #endif
08386 }
08387 }
08388 } else {
08389 ast_log(LOG_WARNING, "Datalen < 0?\n");
08390 }
08391 } else {
08392 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
08393 iax2_vnak(fr->callno);
08394 }
08395 }
08396 ast_mutex_unlock(&iaxsl[fr->callno]);
08397 }
08398 ptr += len;
08399 res -= len;
08400 }
08401
08402 }
08403 return 1;
08404 }
08405
08406 #ifdef DEBUG_SUPPORT
08407 if (iaxdebug && (res >= sizeof(*fh)))
08408 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
08409 #endif
08410 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08411 if (res < sizeof(*fh)) {
08412 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));
08413 return 1;
08414 }
08415
08416
08417 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
08418
08419 f.frametype = fh->type;
08420 if (f.frametype == AST_FRAME_VIDEO) {
08421 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
08422 } else {
08423 f.subclass = uncompress_subclass(fh->csub);
08424 }
08425
08426
08427 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
08428
08429 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
08430 return 1;
08431 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
08432
08433 return 1;
08434 }
08435
08436 f.datalen = res - sizeof(*fh);
08437 if (f.datalen) {
08438 if (f.frametype == AST_FRAME_IAX) {
08439 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
08440 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
08441 ast_mutex_unlock(&iaxsl[fr->callno]);
08442 return 1;
08443 }
08444 f.data = NULL;
08445 f.datalen = 0;
08446 } else {
08447 f.data = thread->buf + sizeof(*fh);
08448 memset(&ies, 0, sizeof(ies));
08449 }
08450 } else {
08451 if (f.frametype == AST_FRAME_IAX)
08452 f.data = NULL;
08453 else
08454 f.data = empty;
08455 memset(&ies, 0, sizeof(ies));
08456 }
08457
08458 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) {
08459
08460 if (handle_call_token(fh, &ies, &sin, fd)) {
08461 return 1;
08462 }
08463
08464 if (ies.calltoken && ies.calltokendata) {
08465
08466
08467
08468
08469 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
08470 } else {
08471 new = NEW_ALLOW;
08472 }
08473 }
08474 } else {
08475
08476 f.frametype = AST_FRAME_NULL;
08477 f.subclass = 0;
08478 }
08479
08480 if (!fr->callno) {
08481 int check_dcallno = 0;
08482
08483
08484
08485
08486
08487
08488
08489
08490
08491
08492
08493
08494
08495 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08496 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
08497 }
08498
08499 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
08500 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) {
08501 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
08502 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) {
08503 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
08504 }
08505 return 1;
08506 }
08507 }
08508
08509 if (fr->callno > 0)
08510 ast_mutex_lock(&iaxsl[fr->callno]);
08511
08512 if (!fr->callno || !iaxs[fr->callno]) {
08513
08514
08515 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08516
08517 if (((f.subclass != IAX_COMMAND_INVAL) &&
08518 (f.subclass != IAX_COMMAND_TXCNT) &&
08519 (f.subclass != IAX_COMMAND_TXACC) &&
08520 (f.subclass != IAX_COMMAND_FWDOWNL))||
08521 (f.frametype != AST_FRAME_IAX))
08522 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
08523 fd);
08524 }
08525 if (fr->callno > 0)
08526 ast_mutex_unlock(&iaxsl[fr->callno]);
08527 return 1;
08528 }
08529 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
08530 if (decrypt_frame(fr->callno, fh, &f, &res)) {
08531 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
08532 ast_mutex_unlock(&iaxsl[fr->callno]);
08533 return 1;
08534 }
08535 #ifdef DEBUG_SUPPORT
08536 else if (iaxdebug)
08537 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
08538 #endif
08539 }
08540
08541
08542 iaxs[fr->callno]->frames_received++;
08543
08544 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
08545 f.subclass != IAX_COMMAND_TXCNT &&
08546 f.subclass != IAX_COMMAND_TXACC) {
08547 unsigned short new_peercallno;
08548
08549 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
08550 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
08551 if (iaxs[fr->callno]->peercallno) {
08552 remove_by_peercallno(iaxs[fr->callno]);
08553 }
08554 iaxs[fr->callno]->peercallno = new_peercallno;
08555 store_by_peercallno(iaxs[fr->callno]);
08556 }
08557 }
08558 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08559 if (option_debug && iaxdebug)
08560 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
08561
08562 fr->oseqno = fh->oseqno;
08563 fr->iseqno = fh->iseqno;
08564 fr->ts = ntohl(fh->ts);
08565 #ifdef IAXTESTS
08566 if (test_resync) {
08567 if (option_debug)
08568 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
08569 fr->ts += test_resync;
08570 }
08571 #endif
08572 #if 0
08573 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
08574 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
08575 (f.subclass == IAX_COMMAND_NEW ||
08576 f.subclass == IAX_COMMAND_AUTHREQ ||
08577 f.subclass == IAX_COMMAND_ACCEPT ||
08578 f.subclass == IAX_COMMAND_REJECT)) ) )
08579 #endif
08580 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
08581 updatehistory = 0;
08582 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
08583 (iaxs[fr->callno]->iseqno ||
08584 ((f.subclass != IAX_COMMAND_TXCNT) &&
08585 (f.subclass != IAX_COMMAND_TXREADY) &&
08586 (f.subclass != IAX_COMMAND_TXREL) &&
08587 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
08588 (f.subclass != IAX_COMMAND_TXACC)) ||
08589 (f.frametype != AST_FRAME_IAX))) {
08590 if (
08591 ((f.subclass != IAX_COMMAND_ACK) &&
08592 (f.subclass != IAX_COMMAND_INVAL) &&
08593 (f.subclass != IAX_COMMAND_TXCNT) &&
08594 (f.subclass != IAX_COMMAND_TXREADY) &&
08595 (f.subclass != IAX_COMMAND_TXREL) &&
08596 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
08597 (f.subclass != IAX_COMMAND_TXACC) &&
08598 (f.subclass != IAX_COMMAND_VNAK)) ||
08599 (f.frametype != AST_FRAME_IAX)) {
08600
08601 if (option_debug)
08602 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
08603 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
08604
08605
08606 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
08607
08608 if ((f.frametype != AST_FRAME_IAX) ||
08609 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
08610 if (option_debug)
08611 ast_log(LOG_DEBUG, "Acking anyway\n");
08612
08613
08614 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08615 }
08616 } else {
08617
08618 iax2_vnak(fr->callno);
08619 }
08620 ast_mutex_unlock(&iaxsl[fr->callno]);
08621 return 1;
08622 }
08623 } else {
08624
08625 if (((f.subclass != IAX_COMMAND_ACK) &&
08626 (f.subclass != IAX_COMMAND_INVAL) &&
08627 (f.subclass != IAX_COMMAND_TXCNT) &&
08628 (f.subclass != IAX_COMMAND_TXACC) &&
08629 (f.subclass != IAX_COMMAND_VNAK)) ||
08630 (f.frametype != AST_FRAME_IAX))
08631 iaxs[fr->callno]->iseqno++;
08632 }
08633
08634 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
08635 if (res < thread->buf_size)
08636 thread->buf[res++] = '\0';
08637 else
08638 thread->buf[res - 1] = '\0';
08639 }
08640
08641
08642
08643 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
08644 ((f.subclass != IAX_COMMAND_INVAL) ||
08645 (f.frametype != AST_FRAME_IAX))) {
08646 unsigned char x;
08647 int call_to_destroy;
08648
08649
08650
08651 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
08652 if (fr->iseqno == x)
08653 break;
08654 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
08655
08656
08657 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
08658
08659 if (option_debug && iaxdebug)
08660 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
08661 call_to_destroy = 0;
08662 AST_LIST_LOCK(&iaxq.queue);
08663 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08664
08665 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
08666 cur->retries = -1;
08667
08668 if (cur->final)
08669 call_to_destroy = fr->callno;
08670 }
08671 }
08672 AST_LIST_UNLOCK(&iaxq.queue);
08673 if (call_to_destroy) {
08674 if (iaxdebug && option_debug)
08675 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
08676 ast_mutex_lock(&iaxsl[call_to_destroy]);
08677 iax2_destroy(call_to_destroy);
08678 ast_mutex_unlock(&iaxsl[call_to_destroy]);
08679 }
08680 }
08681
08682 if (iaxs[fr->callno])
08683 iaxs[fr->callno]->rseqno = fr->iseqno;
08684 else {
08685
08686 ast_mutex_unlock(&iaxsl[fr->callno]);
08687 return 1;
08688 }
08689 } else if (option_debug)
08690 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
08691 }
08692 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
08693 ((f.frametype != AST_FRAME_IAX) ||
08694 ((f.subclass != IAX_COMMAND_TXACC) &&
08695 (f.subclass != IAX_COMMAND_TXCNT)))) {
08696
08697 ast_mutex_unlock(&iaxsl[fr->callno]);
08698 return 1;
08699 }
08700
08701
08702
08703
08704 if ((f.frametype == AST_FRAME_VOICE) ||
08705 (f.frametype == AST_FRAME_VIDEO) ||
08706 (f.frametype == AST_FRAME_IAX)) {
08707 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
08708 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08709 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
08710 ast_mutex_unlock(&iaxsl[fr->callno]);
08711 return 1;
08712 }
08713 }
08714 }
08715
08716 if (f.frametype == AST_FRAME_VOICE) {
08717 if (f.subclass != iaxs[fr->callno]->voiceformat) {
08718 iaxs[fr->callno]->voiceformat = f.subclass;
08719 if (option_debug)
08720 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
08721 if (iaxs[fr->callno]->owner) {
08722 int orignative;
08723 retryowner:
08724 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
08725 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
08726 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
08727 }
08728 if (iaxs[fr->callno]) {
08729 if (iaxs[fr->callno]->owner) {
08730 orignative = iaxs[fr->callno]->owner->nativeformats;
08731 iaxs[fr->callno]->owner->nativeformats = f.subclass;
08732 if (iaxs[fr->callno]->owner->readformat)
08733 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
08734 iaxs[fr->callno]->owner->nativeformats = orignative;
08735 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
08736 }
08737 } else {
08738 if (option_debug)
08739 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
08740 ast_mutex_unlock(&iaxsl[fr->callno]);
08741 return 1;
08742 }
08743 }
08744 }
08745 }
08746 if (f.frametype == AST_FRAME_VIDEO) {
08747 if (f.subclass != iaxs[fr->callno]->videoformat) {
08748 if (option_debug)
08749 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
08750 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
08751 }
08752 }
08753 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
08754 if (f.subclass == AST_CONTROL_BUSY) {
08755 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
08756 } else if (f.subclass == AST_CONTROL_CONGESTION) {
08757 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
08758 }
08759 }
08760 if (f.frametype == AST_FRAME_IAX) {
08761 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
08762
08763 if (option_debug && iaxdebug) {
08764 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
08765 }
08766
08767
08768 if (iaxs[fr->callno]->last < fr->ts &&
08769 f.subclass != IAX_COMMAND_ACK &&
08770 f.subclass != IAX_COMMAND_PONG &&
08771 f.subclass != IAX_COMMAND_LAGRP) {
08772 iaxs[fr->callno]->last = fr->ts;
08773 if (option_debug && iaxdebug) {
08774 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08775 }
08776 }
08777 iaxs[fr->callno]->last_iax_message = f.subclass;
08778 if (!iaxs[fr->callno]->first_iax_message) {
08779 iaxs[fr->callno]->first_iax_message = f.subclass;
08780 }
08781 switch(f.subclass) {
08782 case IAX_COMMAND_ACK:
08783
08784 break;
08785 case IAX_COMMAND_QUELCH:
08786 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08787
08788 if (iaxs[fr->callno]->owner) {
08789 manager_event(EVENT_FLAG_CALL, "Hold",
08790 "Channel: %s\r\n"
08791 "Uniqueid: %s\r\n",
08792 iaxs[fr->callno]->owner->name,
08793 iaxs[fr->callno]->owner->uniqueid);
08794 }
08795
08796 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
08797 if (ies.musiconhold) {
08798 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08799 const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
08800 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
08801 S_OR(mohsuggest, NULL),
08802 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
08803 if (!iaxs[fr->callno]) {
08804 ast_mutex_unlock(&iaxsl[fr->callno]);
08805 return 1;
08806 }
08807 }
08808 }
08809 }
08810 break;
08811 case IAX_COMMAND_UNQUELCH:
08812 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08813
08814 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
08815 manager_event(EVENT_FLAG_CALL, "Unhold",
08816 "Channel: %s\r\n"
08817 "Uniqueid: %s\r\n",
08818 iaxs[fr->callno]->owner->name,
08819 iaxs[fr->callno]->owner->uniqueid);
08820 }
08821
08822 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
08823 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08824 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
08825 if (!iaxs[fr->callno]) {
08826 ast_mutex_unlock(&iaxsl[fr->callno]);
08827 return 1;
08828 }
08829 }
08830 }
08831 break;
08832 case IAX_COMMAND_TXACC:
08833 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
08834
08835 AST_LIST_LOCK(&iaxq.queue);
08836 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08837
08838 if ((fr->callno == cur->callno) && (cur->transfer))
08839 cur->retries = -1;
08840 }
08841 AST_LIST_UNLOCK(&iaxq.queue);
08842 memset(&ied1, 0, sizeof(ied1));
08843 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
08844 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
08845 iaxs[fr->callno]->transferring = TRANSFER_READY;
08846 }
08847 break;
08848 case IAX_COMMAND_NEW:
08849
08850 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
08851 break;
08852 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08853 ast_mutex_unlock(&iaxsl[fr->callno]);
08854 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08855 ast_mutex_lock(&iaxsl[fr->callno]);
08856 if (!iaxs[fr->callno]) {
08857 ast_mutex_unlock(&iaxsl[fr->callno]);
08858 return 1;
08859 }
08860 }
08861
08862 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
08863 int new_callno;
08864 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
08865 fr->callno = new_callno;
08866 }
08867
08868 if (delayreject)
08869 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08870 if (check_access(fr->callno, &sin, &ies)) {
08871
08872 auth_fail(fr->callno, IAX_COMMAND_REJECT);
08873 if (authdebug)
08874 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);
08875 break;
08876 }
08877 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08878 const char *context, *exten, *cid_num;
08879
08880 context = ast_strdupa(iaxs[fr->callno]->context);
08881 exten = ast_strdupa(iaxs[fr->callno]->exten);
08882 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
08883
08884
08885 ast_mutex_unlock(&iaxsl[fr->callno]);
08886 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
08887 ast_mutex_lock(&iaxsl[fr->callno]);
08888
08889 if (!iaxs[fr->callno]) {
08890 ast_mutex_unlock(&iaxsl[fr->callno]);
08891 return 1;
08892 }
08893 } else
08894 exists = 0;
08895 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
08896 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08897 memset(&ied0, 0, sizeof(ied0));
08898 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08899 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08900 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08901 if (!iaxs[fr->callno]) {
08902 ast_mutex_unlock(&iaxsl[fr->callno]);
08903 return 1;
08904 }
08905 if (authdebug)
08906 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);
08907 } else {
08908
08909
08910 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08911 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08912 using_prefs = "reqonly";
08913 } else {
08914 using_prefs = "disabled";
08915 }
08916 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08917 memset(&pref, 0, sizeof(pref));
08918 strcpy(caller_pref_buf, "disabled");
08919 strcpy(host_pref_buf, "disabled");
08920 } else {
08921 using_prefs = "mine";
08922
08923 if (ies.codec_prefs)
08924 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08925 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08926
08927 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08928 pref = iaxs[fr->callno]->rprefs;
08929 using_prefs = "caller";
08930 } else {
08931 pref = iaxs[fr->callno]->prefs;
08932 }
08933 } else
08934 pref = iaxs[fr->callno]->prefs;
08935
08936 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08937 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08938 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08939 }
08940 if (!format) {
08941 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08942 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08943 if (!format) {
08944 memset(&ied0, 0, sizeof(ied0));
08945 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08946 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08947 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08948 if (!iaxs[fr->callno]) {
08949 ast_mutex_unlock(&iaxsl[fr->callno]);
08950 return 1;
08951 }
08952 if (authdebug) {
08953 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08954 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);
08955 else
08956 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);
08957 }
08958 } else {
08959
08960 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08961 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08962 format = 0;
08963 } else {
08964 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08965 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08966 memset(&pref, 0, sizeof(pref));
08967 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08968 strcpy(caller_pref_buf,"disabled");
08969 strcpy(host_pref_buf,"disabled");
08970 } else {
08971 using_prefs = "mine";
08972 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08973
08974 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08975 pref = iaxs[fr->callno]->prefs;
08976 } else {
08977 pref = iaxs[fr->callno]->rprefs;
08978 using_prefs = "caller";
08979 }
08980 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08981
08982 } else
08983 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08984 }
08985 }
08986
08987 if (!format) {
08988 memset(&ied0, 0, sizeof(ied0));
08989 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08990 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08991 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08992 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08993 if (!iaxs[fr->callno]) {
08994 ast_mutex_unlock(&iaxsl[fr->callno]);
08995 return 1;
08996 }
08997 if (authdebug)
08998 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);
08999 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09000 break;
09001 }
09002 }
09003 }
09004 if (format) {
09005
09006 memset(&ied1, 0, sizeof(ied1));
09007 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
09008 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
09009 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
09010 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09011 if (option_verbose > 2)
09012 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
09013 "%srequested format = %s,\n"
09014 "%srequested prefs = %s,\n"
09015 "%sactual format = %s,\n"
09016 "%shost prefs = %s,\n"
09017 "%spriority = %s\n",
09018 ast_inet_ntoa(sin.sin_addr),
09019 VERBOSE_PREFIX_4,
09020 ast_getformatname(iaxs[fr->callno]->peerformat),
09021 VERBOSE_PREFIX_4,
09022 caller_pref_buf,
09023 VERBOSE_PREFIX_4,
09024 ast_getformatname(format),
09025 VERBOSE_PREFIX_4,
09026 host_pref_buf,
09027 VERBOSE_PREFIX_4,
09028 using_prefs);
09029
09030 iaxs[fr->callno]->chosenformat = format;
09031 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
09032 } else {
09033 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09034
09035 if (option_verbose > 2)
09036 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
09037 }
09038 }
09039 }
09040 break;
09041 }
09042 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
09043 merge_encryption(iaxs[fr->callno],ies.encmethods);
09044 else
09045 iaxs[fr->callno]->encmethods = 0;
09046 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
09047 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
09048 if (!iaxs[fr->callno]) {
09049 ast_mutex_unlock(&iaxsl[fr->callno]);
09050 return 1;
09051 }
09052 break;
09053 case IAX_COMMAND_DPREQ:
09054
09055 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
09056 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
09057 if (iaxcompat) {
09058
09059 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
09060 } else {
09061
09062 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
09063 }
09064 }
09065 break;
09066 case IAX_COMMAND_HANGUP:
09067 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09068 if (option_debug)
09069 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
09070
09071 if (ies.causecode && iaxs[fr->callno]->owner)
09072 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09073
09074 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09075 iax2_destroy(fr->callno);
09076 break;
09077 case IAX_COMMAND_REJECT:
09078
09079 if (ies.causecode && iaxs[fr->callno]->owner)
09080 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09081
09082 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09083 if (iaxs[fr->callno]->owner && authdebug)
09084 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
09085 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
09086 ies.cause ? ies.cause : "<Unknown>");
09087 if (option_debug)
09088 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
09089 fr->callno);
09090 }
09091
09092 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
09093 fr->ts, NULL, 0, fr->iseqno);
09094 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
09095 iaxs[fr->callno]->error = EPERM;
09096 iax2_destroy(fr->callno);
09097 break;
09098 case IAX_COMMAND_TRANSFER:
09099 {
09100 struct ast_channel *bridged_chan;
09101
09102 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
09103
09104
09105 ast_mutex_unlock(&iaxsl[fr->callno]);
09106 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
09107 ast_mutex_lock(&iaxsl[fr->callno]);
09108 if (!iaxs[fr->callno]) {
09109 ast_mutex_unlock(&iaxsl[fr->callno]);
09110 return 1;
09111 }
09112
09113 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
09114 if (!strcmp(ies.called_number, ast_parking_ext())) {
09115 struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
09116 ast_mutex_unlock(&iaxsl[fr->callno]);
09117 if (iax_park(bridged_chan, saved_channel)) {
09118 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
09119 } else {
09120 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
09121 }
09122 ast_mutex_lock(&iaxsl[fr->callno]);
09123 } else {
09124 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
09125 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
09126 ies.called_number, iaxs[fr->callno]->context);
09127 else
09128 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
09129 ies.called_number, iaxs[fr->callno]->context);
09130 }
09131 } else
09132 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
09133
09134 break;
09135 }
09136 case IAX_COMMAND_ACCEPT:
09137
09138 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
09139 break;
09140 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09141
09142 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09143 iax2_destroy(fr->callno);
09144 break;
09145 }
09146 if (ies.format) {
09147 iaxs[fr->callno]->peerformat = ies.format;
09148 } else {
09149 if (iaxs[fr->callno]->owner)
09150 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
09151 else
09152 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
09153 }
09154 if (option_verbose > 2)
09155 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));
09156 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
09157 memset(&ied0, 0, sizeof(ied0));
09158 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09159 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09160 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09161 if (!iaxs[fr->callno]) {
09162 ast_mutex_unlock(&iaxsl[fr->callno]);
09163 return 1;
09164 }
09165 if (authdebug)
09166 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);
09167 } else {
09168 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09169 if (iaxs[fr->callno]->owner) {
09170
09171 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
09172 if (option_verbose > 2)
09173 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
09174 retryowner2:
09175 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
09176 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09177 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
09178 }
09179
09180 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
09181
09182 if (iaxs[fr->callno]->owner->writeformat)
09183 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
09184 if (iaxs[fr->callno]->owner->readformat)
09185 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
09186 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
09187 }
09188 }
09189 }
09190 if (iaxs[fr->callno]) {
09191 ast_mutex_lock(&dpcache_lock);
09192 dp = iaxs[fr->callno]->dpentries;
09193 while(dp) {
09194 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
09195 iax2_dprequest(dp, fr->callno);
09196 }
09197 dp = dp->peer;
09198 }
09199 ast_mutex_unlock(&dpcache_lock);
09200 }
09201 break;
09202 case IAX_COMMAND_POKE:
09203
09204 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
09205 if (!iaxs[fr->callno]) {
09206 ast_mutex_unlock(&iaxsl[fr->callno]);
09207 return 1;
09208 }
09209 break;
09210 case IAX_COMMAND_PING:
09211 {
09212 struct iax_ie_data pingied;
09213 construct_rr(iaxs[fr->callno], &pingied);
09214
09215 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
09216 }
09217 break;
09218 case IAX_COMMAND_PONG:
09219
09220 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
09221
09222 save_rr(fr, &ies);
09223
09224 if (iaxs[fr->callno]->peerpoke) {
09225 peer = iaxs[fr->callno]->peerpoke;
09226 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
09227 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
09228 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
09229 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
09230 ast_device_state_changed("IAX2/%s", peer->name);
09231 }
09232 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
09233 if (iaxs[fr->callno]->pingtime > peer->maxms) {
09234 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
09235 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
09236 ast_device_state_changed("IAX2/%s", peer->name);
09237 }
09238 }
09239 peer->lastms = iaxs[fr->callno]->pingtime;
09240 if (peer->smoothing && (peer->lastms > -1))
09241 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
09242 else if (peer->smoothing && peer->lastms < 0)
09243 peer->historicms = (0 + peer->historicms) / 2;
09244 else
09245 peer->historicms = iaxs[fr->callno]->pingtime;
09246
09247
09248 if (peer->pokeexpire > -1) {
09249 if (!ast_sched_del(sched, peer->pokeexpire)) {
09250 peer_unref(peer);
09251 peer->pokeexpire = -1;
09252 }
09253 }
09254
09255 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
09256 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
09257 else
09258 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
09259 if (peer->pokeexpire == -1)
09260 peer_unref(peer);
09261
09262 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09263
09264 iax2_destroy(fr->callno);
09265 peer->callno = 0;
09266 if (option_debug)
09267 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
09268 }
09269 break;
09270 case IAX_COMMAND_LAGRQ:
09271 case IAX_COMMAND_LAGRP:
09272 f.src = "LAGRQ";
09273 f.mallocd = 0;
09274 f.offset = 0;
09275 f.samples = 0;
09276 iax_frame_wrap(fr, &f);
09277 if(f.subclass == IAX_COMMAND_LAGRQ) {
09278
09279 fr->af.subclass = IAX_COMMAND_LAGRP;
09280 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
09281 } else {
09282
09283 unsigned int ts;
09284
09285 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
09286 iaxs[fr->callno]->lag = ts - fr->ts;
09287 if (option_debug && iaxdebug)
09288 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
09289 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
09290 }
09291 break;
09292 case IAX_COMMAND_AUTHREQ:
09293 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09294 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>");
09295 break;
09296 }
09297 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
09298 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
09299 .subclass = AST_CONTROL_HANGUP,
09300 };
09301 ast_log(LOG_WARNING,
09302 "I don't know how to authenticate %s to %s\n",
09303 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
09304 iax2_queue_frame(fr->callno, &hangup_fr);
09305 }
09306 if (!iaxs[fr->callno]) {
09307 ast_mutex_unlock(&iaxsl[fr->callno]);
09308 return 1;
09309 }
09310 break;
09311 case IAX_COMMAND_AUTHREP:
09312
09313 if (delayreject)
09314 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09315
09316 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09317 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>");
09318 break;
09319 }
09320 if (authenticate_verify(iaxs[fr->callno], &ies)) {
09321 if (authdebug)
09322 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);
09323 memset(&ied0, 0, sizeof(ied0));
09324 auth_fail(fr->callno, IAX_COMMAND_REJECT);
09325 break;
09326 }
09327 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
09328
09329 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
09330 } else
09331 exists = 0;
09332 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
09333 if (authdebug)
09334 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);
09335 memset(&ied0, 0, sizeof(ied0));
09336 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09337 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09338 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09339 if (!iaxs[fr->callno]) {
09340 ast_mutex_unlock(&iaxsl[fr->callno]);
09341 return 1;
09342 }
09343 } else {
09344
09345 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09346 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09347 using_prefs = "reqonly";
09348 } else {
09349 using_prefs = "disabled";
09350 }
09351 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
09352 memset(&pref, 0, sizeof(pref));
09353 strcpy(caller_pref_buf, "disabled");
09354 strcpy(host_pref_buf, "disabled");
09355 } else {
09356 using_prefs = "mine";
09357 if (ies.codec_prefs)
09358 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
09359 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09360 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09361 pref = iaxs[fr->callno]->rprefs;
09362 using_prefs = "caller";
09363 } else {
09364 pref = iaxs[fr->callno]->prefs;
09365 }
09366 } else
09367 pref = iaxs[fr->callno]->prefs;
09368
09369 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
09370 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
09371 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
09372 }
09373 if (!format) {
09374 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09375 if (option_debug)
09376 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);
09377 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
09378 }
09379 if (!format) {
09380 if (authdebug) {
09381 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09382 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);
09383 else
09384 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);
09385 }
09386 memset(&ied0, 0, sizeof(ied0));
09387 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09388 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09389 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09390 if (!iaxs[fr->callno]) {
09391 ast_mutex_unlock(&iaxsl[fr->callno]);
09392 return 1;
09393 }
09394 } else {
09395
09396 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09397 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
09398 format = 0;
09399 } else {
09400 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09401 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
09402 memset(&pref, 0, sizeof(pref));
09403 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
09404 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09405 strcpy(caller_pref_buf,"disabled");
09406 strcpy(host_pref_buf,"disabled");
09407 } else {
09408 using_prefs = "mine";
09409 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09410
09411 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09412 pref = iaxs[fr->callno]->prefs;
09413 } else {
09414 pref = iaxs[fr->callno]->rprefs;
09415 using_prefs = "caller";
09416 }
09417 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
09418 } else
09419 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09420 }
09421 }
09422 if (!format) {
09423 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09424 if (authdebug) {
09425 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09426 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);
09427 else
09428 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);
09429 }
09430 memset(&ied0, 0, sizeof(ied0));
09431 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09432 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09433 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09434 if (!iaxs[fr->callno]) {
09435 ast_mutex_unlock(&iaxsl[fr->callno]);
09436 return 1;
09437 }
09438 }
09439 }
09440 }
09441 if (format) {
09442
09443 memset(&ied1, 0, sizeof(ied1));
09444 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
09445 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
09446 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
09447 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09448 if (option_verbose > 2)
09449 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
09450 "%srequested format = %s,\n"
09451 "%srequested prefs = %s,\n"
09452 "%sactual format = %s,\n"
09453 "%shost prefs = %s,\n"
09454 "%spriority = %s\n",
09455 ast_inet_ntoa(sin.sin_addr),
09456 VERBOSE_PREFIX_4,
09457 ast_getformatname(iaxs[fr->callno]->peerformat),
09458 VERBOSE_PREFIX_4,
09459 caller_pref_buf,
09460 VERBOSE_PREFIX_4,
09461 ast_getformatname(format),
09462 VERBOSE_PREFIX_4,
09463 host_pref_buf,
09464 VERBOSE_PREFIX_4,
09465 using_prefs);
09466
09467 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09468 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
09469 iax2_destroy(fr->callno);
09470 } else {
09471 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09472
09473 if (option_verbose > 2)
09474 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
09475 }
09476 }
09477 }
09478 break;
09479 case IAX_COMMAND_DIAL:
09480 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
09481 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09482 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
09483 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
09484 if (authdebug)
09485 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);
09486 memset(&ied0, 0, sizeof(ied0));
09487 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09488 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09489 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09490 if (!iaxs[fr->callno]) {
09491 ast_mutex_unlock(&iaxsl[fr->callno]);
09492 return 1;
09493 }
09494 } else {
09495 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09496 if (option_verbose > 2)
09497 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
09498 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09499 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
09500 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
09501 iax2_destroy(fr->callno);
09502 }
09503 }
09504 break;
09505 case IAX_COMMAND_INVAL:
09506 iaxs[fr->callno]->error = ENOTCONN;
09507 if (option_debug)
09508 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
09509 iax2_destroy(fr->callno);
09510 if (option_debug)
09511 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
09512 break;
09513 case IAX_COMMAND_VNAK:
09514 if (option_debug)
09515 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
09516
09517 vnak_retransmit(fr->callno, fr->iseqno);
09518 break;
09519 case IAX_COMMAND_REGREQ:
09520 case IAX_COMMAND_REGREL:
09521
09522 if (delayreject)
09523 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09524 if (register_verify(fr->callno, &sin, &ies)) {
09525 if (!iaxs[fr->callno]) {
09526 ast_mutex_unlock(&iaxsl[fr->callno]);
09527 return 1;
09528 }
09529
09530 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
09531 break;
09532 }
09533 if (!iaxs[fr->callno]) {
09534 ast_mutex_unlock(&iaxsl[fr->callno]);
09535 return 1;
09536 }
09537 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
09538 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
09539
09540 if (f.subclass == IAX_COMMAND_REGREL)
09541 memset(&sin, 0, sizeof(sin));
09542 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
09543 ast_log(LOG_WARNING, "Registry error\n");
09544 if (!iaxs[fr->callno]) {
09545 ast_mutex_unlock(&iaxsl[fr->callno]);
09546 return 1;
09547 }
09548 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
09549 ast_mutex_unlock(&iaxsl[fr->callno]);
09550 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
09551 ast_mutex_lock(&iaxsl[fr->callno]);
09552 if (!iaxs[fr->callno]) {
09553 ast_mutex_unlock(&iaxsl[fr->callno]);
09554 return 1;
09555 }
09556 }
09557 break;
09558 }
09559 registry_authrequest(fr->callno);
09560 if (!iaxs[fr->callno]) {
09561 ast_mutex_unlock(&iaxsl[fr->callno]);
09562 return 1;
09563 }
09564 break;
09565 case IAX_COMMAND_REGACK:
09566 if (iax2_ack_registry(&ies, &sin, fr->callno))
09567 ast_log(LOG_WARNING, "Registration failure\n");
09568
09569 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09570 iax2_destroy(fr->callno);
09571 break;
09572 case IAX_COMMAND_REGREJ:
09573 if (iaxs[fr->callno]->reg) {
09574 if (authdebug) {
09575 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));
09576 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>");
09577 }
09578 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
09579 }
09580
09581 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09582 iax2_destroy(fr->callno);
09583 break;
09584 case IAX_COMMAND_REGAUTH:
09585
09586 if (registry_rerequest(&ies, fr->callno, &sin)) {
09587 memset(&ied0, 0, sizeof(ied0));
09588 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
09589 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09590 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09591 if (!iaxs[fr->callno]) {
09592 ast_mutex_unlock(&iaxsl[fr->callno]);
09593 return 1;
09594 }
09595 }
09596 break;
09597 case IAX_COMMAND_TXREJ:
09598 iaxs[fr->callno]->transferring = 0;
09599 if (option_verbose > 2)
09600 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09601 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
09602 if (iaxs[fr->callno]->bridgecallno) {
09603 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
09604 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
09605 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
09606 }
09607 }
09608 break;
09609 case IAX_COMMAND_TXREADY:
09610 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
09611 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
09612 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
09613 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
09614 else
09615 iaxs[fr->callno]->transferring = TRANSFER_READY;
09616 if (option_verbose > 2)
09617 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09618 if (iaxs[fr->callno]->bridgecallno) {
09619 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
09620 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
09621
09622 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
09623 if (option_verbose > 2)
09624 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09625 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09626
09627 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
09628 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
09629
09630 memset(&ied0, 0, sizeof(ied0));
09631 memset(&ied1, 0, sizeof(ied1));
09632 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09633 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09634 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
09635 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
09636 } else {
09637 if (option_verbose > 2)
09638 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09639 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09640
09641 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
09642 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
09643 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
09644 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09645
09646
09647 stop_stuff(fr->callno);
09648 stop_stuff(iaxs[fr->callno]->bridgecallno);
09649
09650 memset(&ied0, 0, sizeof(ied0));
09651 memset(&ied1, 0, sizeof(ied1));
09652 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09653 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09654 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
09655 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
09656 }
09657
09658 }
09659 }
09660 }
09661 break;
09662 case IAX_COMMAND_TXREQ:
09663 try_transfer(iaxs[fr->callno], &ies);
09664 break;
09665 case IAX_COMMAND_TXCNT:
09666 if (iaxs[fr->callno]->transferring)
09667 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
09668 break;
09669 case IAX_COMMAND_TXREL:
09670
09671 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09672 complete_transfer(fr->callno, &ies);
09673 stop_stuff(fr->callno);
09674 break;
09675 case IAX_COMMAND_TXMEDIA:
09676 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
09677 AST_LIST_LOCK(&iaxq.queue);
09678 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
09679
09680 if ((fr->callno == cur->callno) && (cur->transfer)) {
09681 cur->retries = -1;
09682 }
09683 }
09684 AST_LIST_UNLOCK(&iaxq.queue);
09685
09686 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
09687 }
09688 break;
09689 case IAX_COMMAND_DPREP:
09690 complete_dpreply(iaxs[fr->callno], &ies);
09691 break;
09692 case IAX_COMMAND_UNSUPPORT:
09693 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
09694 break;
09695 case IAX_COMMAND_FWDOWNL:
09696
09697 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
09698 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
09699 break;
09700 }
09701 memset(&ied0, 0, sizeof(ied0));
09702 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
09703 if (res < 0)
09704 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09705 else if (res > 0)
09706 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09707 else
09708 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09709 if (!iaxs[fr->callno]) {
09710 ast_mutex_unlock(&iaxsl[fr->callno]);
09711 return 1;
09712 }
09713 break;
09714 case IAX_COMMAND_CALLTOKEN:
09715 {
09716 struct iax_frame *cur;
09717 AST_LIST_LOCK(&iaxq.queue);
09718 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
09719
09720
09721
09722 if (cur->callno == fr->callno) {
09723 break;
09724 }
09725 }
09726 AST_LIST_UNLOCK(&iaxq.queue);
09727
09728
09729 if (cur && ies.calltoken && ies.calltokendata) {
09730 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
09731 }
09732 break;
09733 }
09734 default:
09735 if (option_debug)
09736 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
09737 memset(&ied0, 0, sizeof(ied0));
09738 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
09739 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
09740 }
09741
09742 if ((f.subclass != IAX_COMMAND_ACK) &&
09743 (f.subclass != IAX_COMMAND_TXCNT) &&
09744 (f.subclass != IAX_COMMAND_TXACC) &&
09745 (f.subclass != IAX_COMMAND_INVAL) &&
09746 (f.subclass != IAX_COMMAND_VNAK)) {
09747 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09748 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09749 }
09750 ast_mutex_unlock(&iaxsl[fr->callno]);
09751 return 1;
09752 }
09753
09754 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09755 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09756 } else if (minivid) {
09757 f.frametype = AST_FRAME_VIDEO;
09758 if (iaxs[fr->callno]->videoformat > 0)
09759 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
09760 else {
09761 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
09762 iax2_vnak(fr->callno);
09763 ast_mutex_unlock(&iaxsl[fr->callno]);
09764 return 1;
09765 }
09766 f.datalen = res - sizeof(*vh);
09767 if (f.datalen)
09768 f.data = thread->buf + sizeof(*vh);
09769 else
09770 f.data = NULL;
09771 #ifdef IAXTESTS
09772 if (test_resync) {
09773 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
09774 } else
09775 #endif
09776 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
09777 } else {
09778
09779 f.frametype = AST_FRAME_VOICE;
09780 if (iaxs[fr->callno]->voiceformat > 0)
09781 f.subclass = iaxs[fr->callno]->voiceformat;
09782 else {
09783 if (option_debug)
09784 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
09785 iax2_vnak(fr->callno);
09786 ast_mutex_unlock(&iaxsl[fr->callno]);
09787 return 1;
09788 }
09789 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
09790 if (f.datalen < 0) {
09791 ast_log(LOG_WARNING, "Datalen < 0?\n");
09792 ast_mutex_unlock(&iaxsl[fr->callno]);
09793 return 1;
09794 }
09795 if (f.datalen)
09796 f.data = thread->buf + sizeof(*mh);
09797 else
09798 f.data = NULL;
09799 #ifdef IAXTESTS
09800 if (test_resync) {
09801 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
09802 } else
09803 #endif
09804 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
09805
09806 }
09807
09808 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09809 ast_mutex_unlock(&iaxsl[fr->callno]);
09810 return 1;
09811 }
09812
09813 f.src = "IAX2";
09814 f.mallocd = 0;
09815 f.offset = 0;
09816 f.len = 0;
09817 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
09818 f.samples = ast_codec_get_samples(&f);
09819
09820 if (f.subclass == AST_FORMAT_SLINEAR)
09821 ast_frame_byteswap_be(&f);
09822 } else
09823 f.samples = 0;
09824 iax_frame_wrap(fr, &f);
09825
09826
09827 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09828
09829 fr->outoforder = 0;
09830 } else {
09831 if (option_debug && iaxdebug && iaxs[fr->callno])
09832 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);
09833 fr->outoforder = -1;
09834 }
09835 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
09836 duped_fr = iaxfrdup2(fr);
09837 if (duped_fr) {
09838 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
09839 }
09840 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09841 iaxs[fr->callno]->last = fr->ts;
09842 #if 1
09843 if (option_debug && iaxdebug)
09844 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09845 #endif
09846 }
09847
09848
09849 ast_mutex_unlock(&iaxsl[fr->callno]);
09850 return 1;
09851 }
09852
09853
09854 static void iax2_process_thread_cleanup(void *data)
09855 {
09856 struct iax2_thread *thread = data;
09857 ast_mutex_destroy(&thread->lock);
09858 ast_cond_destroy(&thread->cond);
09859 free(thread);
09860 ast_atomic_dec_and_test(&iaxactivethreadcount);
09861 }
09862
09863 static void *iax2_process_thread(void *data)
09864 {
09865 struct iax2_thread *thread = data;
09866 struct timeval tv;
09867 struct timespec ts;
09868 int put_into_idle = 0;
09869
09870 ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
09871 pthread_cleanup_push(iax2_process_thread_cleanup, data);
09872 for(;;) {
09873
09874 ast_mutex_lock(&thread->lock);
09875
09876
09877 thread->ready_for_signal = 1;
09878
09879
09880 if (put_into_idle)
09881 insert_idle_thread(thread);
09882
09883 if (thread->type == IAX_TYPE_DYNAMIC) {
09884 struct iax2_thread *t = NULL;
09885
09886 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09887 ts.tv_sec = tv.tv_sec;
09888 ts.tv_nsec = tv.tv_usec * 1000;
09889 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
09890
09891
09892 if (!put_into_idle) {
09893 ast_mutex_unlock(&thread->lock);
09894 break;
09895 }
09896 AST_LIST_LOCK(&dynamic_list);
09897
09898 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
09899 iaxdynamicthreadcount--;
09900 AST_LIST_UNLOCK(&dynamic_list);
09901 if (t) {
09902
09903
09904
09905 ast_mutex_unlock(&thread->lock);
09906 break;
09907 }
09908
09909
09910
09911 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09912 ts.tv_sec = tv.tv_sec;
09913 ts.tv_nsec = tv.tv_usec * 1000;
09914 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
09915 {
09916 ast_mutex_unlock(&thread->lock);
09917 break;
09918 }
09919 }
09920 } else {
09921 ast_cond_wait(&thread->cond, &thread->lock);
09922 }
09923
09924
09925 put_into_idle = 1;
09926
09927 ast_mutex_unlock(&thread->lock);
09928
09929 if (thread->iostate == IAX_IOSTATE_IDLE)
09930 continue;
09931
09932
09933 AST_LIST_LOCK(&active_list);
09934 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09935 AST_LIST_UNLOCK(&active_list);
09936
09937
09938 switch(thread->iostate) {
09939 case IAX_IOSTATE_READY:
09940 thread->actions++;
09941 thread->iostate = IAX_IOSTATE_PROCESSING;
09942 socket_process(thread);
09943 handle_deferred_full_frames(thread);
09944 break;
09945 case IAX_IOSTATE_SCHEDREADY:
09946 thread->actions++;
09947 thread->iostate = IAX_IOSTATE_PROCESSING;
09948 #ifdef SCHED_MULTITHREADED
09949 thread->schedfunc(thread->scheddata);
09950 #endif
09951 break;
09952 }
09953 time(&thread->checktime);
09954 thread->iostate = IAX_IOSTATE_IDLE;
09955 #ifdef DEBUG_SCHED_MULTITHREAD
09956 thread->curfunc[0]='\0';
09957 #endif
09958
09959
09960 AST_LIST_LOCK(&active_list);
09961 AST_LIST_REMOVE(&active_list, thread, list);
09962 AST_LIST_UNLOCK(&active_list);
09963
09964
09965 handle_deferred_full_frames(thread);
09966 }
09967
09968
09969
09970
09971
09972 AST_LIST_LOCK(&idle_list);
09973 AST_LIST_REMOVE(&idle_list, thread, list);
09974 AST_LIST_UNLOCK(&idle_list);
09975
09976 AST_LIST_LOCK(&dynamic_list);
09977 AST_LIST_REMOVE(&dynamic_list, thread, list);
09978 AST_LIST_UNLOCK(&dynamic_list);
09979
09980
09981
09982
09983 pthread_cleanup_pop(1);
09984
09985 return NULL;
09986 }
09987
09988 static int iax2_do_register(struct iax2_registry *reg)
09989 {
09990 struct iax_ie_data ied;
09991 if (option_debug && iaxdebug)
09992 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
09993
09994 if (reg->dnsmgr &&
09995 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
09996
09997 ast_dnsmgr_refresh(reg->dnsmgr);
09998 }
09999
10000
10001
10002
10003
10004 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
10005 int callno = reg->callno;
10006 ast_mutex_lock(&iaxsl[callno]);
10007 iax2_destroy(callno);
10008 ast_mutex_unlock(&iaxsl[callno]);
10009 reg->callno = 0;
10010 }
10011 if (!reg->addr.sin_addr.s_addr) {
10012 if (option_debug && iaxdebug)
10013 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
10014
10015 AST_SCHED_DEL(sched, reg->expire);
10016 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10017 return -1;
10018 }
10019
10020 if (!reg->callno) {
10021 if (option_debug)
10022 ast_log(LOG_DEBUG, "Allocate call number\n");
10023 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
10024 if (reg->callno < 1) {
10025 ast_log(LOG_WARNING, "Unable to create call for registration\n");
10026 return -1;
10027 } else if (option_debug)
10028 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
10029 iaxs[reg->callno]->reg = reg;
10030 ast_mutex_unlock(&iaxsl[reg->callno]);
10031 }
10032
10033 AST_SCHED_DEL(sched, reg->expire);
10034
10035 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10036
10037 memset(&ied, 0, sizeof(ied));
10038 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
10039 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
10040 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
10041 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
10042 reg->regstate = REG_STATE_REGSENT;
10043 return 0;
10044 }
10045
10046 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
10047 {
10048 if (pos != 3)
10049 return NULL;
10050 return iax_prov_complete_template(line, word, pos, state);
10051 }
10052
10053 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
10054 {
10055
10056
10057 struct iax_ie_data provdata;
10058 struct iax_ie_data ied;
10059 unsigned int sig;
10060 struct sockaddr_in sin;
10061 int callno;
10062 struct create_addr_info cai;
10063
10064 memset(&cai, 0, sizeof(cai));
10065
10066 if (option_debug)
10067 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
10068
10069 if (iax_provision_build(&provdata, &sig, template, force)) {
10070 if (option_debug)
10071 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
10072 return 0;
10073 }
10074
10075 if (end) {
10076 memcpy(&sin, end, sizeof(sin));
10077 cai.sockfd = sockfd;
10078 } else if (create_addr(dest, NULL, &sin, &cai))
10079 return -1;
10080
10081
10082 memset(&ied, 0, sizeof(ied));
10083 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
10084
10085 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10086 if (!callno)
10087 return -1;
10088
10089 if (iaxs[callno]) {
10090
10091 AST_SCHED_DEL(sched, iaxs[callno]->autoid);
10092 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
10093 ast_set_flag(iaxs[callno], IAX_PROVISION);
10094
10095 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
10096 }
10097 ast_mutex_unlock(&iaxsl[callno]);
10098
10099 return 1;
10100 }
10101
10102 static char *papp = "IAX2Provision";
10103 static char *psyn = "Provision a calling IAXy with a given template";
10104 static char *pdescrip =
10105 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
10106 "the calling entity is in fact an IAXy) with the given template or\n"
10107 "default if one is not specified. Returns -1 on error or 0 on success.\n";
10108
10109
10110
10111
10112 static int iax2_prov_app(struct ast_channel *chan, void *data)
10113 {
10114 int res;
10115 char *sdata;
10116 char *opts;
10117 int force =0;
10118 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
10119 if (ast_strlen_zero(data))
10120 data = "default";
10121 sdata = ast_strdupa(data);
10122 opts = strchr(sdata, '|');
10123 if (opts)
10124 *opts='\0';
10125
10126 if (chan->tech != &iax2_tech) {
10127 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
10128 return -1;
10129 }
10130 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
10131 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
10132 return -1;
10133 }
10134 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
10135 if (option_verbose > 2)
10136 ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n",
10137 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
10138 sdata, res);
10139 return res;
10140 }
10141
10142
10143 static int iax2_prov_cmd(int fd, int argc, char *argv[])
10144 {
10145 int force = 0;
10146 int res;
10147 if (argc < 4)
10148 return RESULT_SHOWUSAGE;
10149 if ((argc > 4)) {
10150 if (!strcasecmp(argv[4], "forced"))
10151 force = 1;
10152 else
10153 return RESULT_SHOWUSAGE;
10154 }
10155 res = iax2_provision(NULL, -1, argv[2], argv[3], force);
10156 if (res < 0)
10157 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
10158 else if (res < 1)
10159 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
10160 else
10161 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
10162 return RESULT_SUCCESS;
10163 }
10164
10165 static void __iax2_poke_noanswer(const void *data)
10166 {
10167 struct iax2_peer *peer = (struct iax2_peer *)data;
10168 int callno;
10169
10170 if (peer->lastms > -1) {
10171 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
10172 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
10173 ast_device_state_changed("IAX2/%s", peer->name);
10174 }
10175 if ((callno = peer->callno) > 0) {
10176 ast_mutex_lock(&iaxsl[callno]);
10177 iax2_destroy(callno);
10178 ast_mutex_unlock(&iaxsl[callno]);
10179 }
10180 peer->callno = 0;
10181 peer->lastms = -1;
10182
10183 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10184 if (peer->pokeexpire == -1)
10185 peer_unref(peer);
10186 }
10187
10188 static int iax2_poke_noanswer(const void *data)
10189 {
10190 struct iax2_peer *peer = (struct iax2_peer *)data;
10191 peer->pokeexpire = -1;
10192 #ifdef SCHED_MULTITHREADED
10193 if (schedule_action(__iax2_poke_noanswer, data))
10194 #endif
10195 __iax2_poke_noanswer(data);
10196 peer_unref(peer);
10197 return 0;
10198 }
10199
10200 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
10201 {
10202 struct iax2_peer *peer = obj;
10203
10204 iax2_poke_peer(peer, 0);
10205
10206 return 0;
10207 }
10208
10209 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
10210 {
10211 int callno;
10212 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
10213
10214
10215 peer->lastms = 0;
10216 peer->historicms = 0;
10217 peer->pokeexpire = -1;
10218 peer->callno = 0;
10219 return 0;
10220 }
10221
10222
10223 if ((callno = peer->callno) > 0) {
10224 ast_log(LOG_NOTICE, "Still have a callno...\n");
10225 ast_mutex_lock(&iaxsl[callno]);
10226 iax2_destroy(callno);
10227 ast_mutex_unlock(&iaxsl[callno]);
10228 }
10229 if (heldcall)
10230 ast_mutex_unlock(&iaxsl[heldcall]);
10231 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
10232 if (heldcall)
10233 ast_mutex_lock(&iaxsl[heldcall]);
10234 if (peer->callno < 1) {
10235 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
10236 return -1;
10237 }
10238
10239
10240 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
10241 iaxs[peer->callno]->peerpoke = peer;
10242
10243
10244 if (peer->pokeexpire > -1) {
10245 if (!ast_sched_del(sched, peer->pokeexpire)) {
10246 peer->pokeexpire = -1;
10247 peer_unref(peer);
10248 }
10249 }
10250
10251
10252
10253 if (peer->lastms < 0) {
10254 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
10255 } else
10256 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
10257
10258 if (peer->pokeexpire == -1)
10259 peer_unref(peer);
10260
10261
10262 ast_mutex_lock(&iaxsl[callno]);
10263 if (iaxs[callno]) {
10264 struct iax_ie_data ied = {
10265 .buf = { 0 },
10266 .pos = 0,
10267 };
10268 add_empty_calltoken_ie(iaxs[callno], &ied);
10269 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
10270 }
10271 ast_mutex_unlock(&iaxsl[callno]);
10272
10273 return 0;
10274 }
10275
10276 static void free_context(struct iax2_context *con)
10277 {
10278 struct iax2_context *conl;
10279 while(con) {
10280 conl = con;
10281 con = con->next;
10282 free(conl);
10283 }
10284 }
10285
10286 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
10287 {
10288 int callno;
10289 int res;
10290 int fmt, native;
10291 struct sockaddr_in sin;
10292 struct ast_channel *c;
10293 struct parsed_dial_string pds;
10294 struct create_addr_info cai;
10295 char *tmpstr;
10296
10297 memset(&pds, 0, sizeof(pds));
10298 tmpstr = ast_strdupa(data);
10299 parse_dial_string(tmpstr, &pds);
10300
10301 if (ast_strlen_zero(pds.peer)) {
10302 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10303 return NULL;
10304 }
10305
10306 memset(&cai, 0, sizeof(cai));
10307 cai.capability = iax2_capability;
10308
10309 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10310
10311
10312 if (create_addr(pds.peer, NULL, &sin, &cai)) {
10313 *cause = AST_CAUSE_UNREGISTERED;
10314 return NULL;
10315 }
10316
10317 if (pds.port)
10318 sin.sin_port = htons(atoi(pds.port));
10319
10320 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10321 if (callno < 1) {
10322 ast_log(LOG_WARNING, "Unable to create call\n");
10323 *cause = AST_CAUSE_CONGESTION;
10324 return NULL;
10325 }
10326
10327
10328 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10329 if (ast_test_flag(&cai, IAX_TRUNK)) {
10330 int new_callno;
10331 if ((new_callno = make_trunk(callno, 1)) != -1)
10332 callno = new_callno;
10333 }
10334 iaxs[callno]->maxtime = cai.maxtime;
10335 if (cai.found)
10336 ast_string_field_set(iaxs[callno], host, pds.peer);
10337
10338 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
10339
10340 ast_mutex_unlock(&iaxsl[callno]);
10341
10342 if (c) {
10343
10344 if (c->nativeformats & format)
10345 c->nativeformats &= format;
10346 else {
10347 native = c->nativeformats;
10348 fmt = format;
10349 res = ast_translator_best_choice(&fmt, &native);
10350 if (res < 0) {
10351 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
10352 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
10353 ast_hangup(c);
10354 return NULL;
10355 }
10356 c->nativeformats = native;
10357 }
10358 c->readformat = ast_best_codec(c->nativeformats);
10359 c->writeformat = c->readformat;
10360 }
10361
10362 return c;
10363 }
10364
10365 static void *sched_thread(void *ignore)
10366 {
10367 for (;;) {
10368 int ms, count;
10369 struct timespec ts;
10370
10371 pthread_testcancel();
10372
10373 ast_mutex_lock(&sched_lock);
10374
10375 ms = ast_sched_wait(sched);
10376
10377 if (ms == -1) {
10378 ast_cond_wait(&sched_cond, &sched_lock);
10379 } else {
10380 struct timeval tv;
10381 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000));
10382 ts.tv_sec = tv.tv_sec;
10383 ts.tv_nsec = tv.tv_usec * 1000;
10384 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
10385 }
10386
10387 ast_mutex_unlock(&sched_lock);
10388
10389 pthread_testcancel();
10390
10391 count = ast_sched_runq(sched);
10392 if (option_debug && count >= 20) {
10393 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
10394 }
10395 }
10396
10397 return NULL;
10398 }
10399
10400 static void *network_thread(void *ignore)
10401 {
10402
10403
10404 int res, count, wakeup;
10405 struct iax_frame *f;
10406
10407 if (timingfd > -1)
10408 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
10409
10410 for(;;) {
10411 pthread_testcancel();
10412
10413
10414
10415 AST_LIST_LOCK(&iaxq.queue);
10416 count = 0;
10417 wakeup = -1;
10418 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
10419 if (f->sentyet)
10420 continue;
10421
10422
10423 if (ast_mutex_trylock(&iaxsl[f->callno])) {
10424 wakeup = 1;
10425 continue;
10426 }
10427
10428 f->sentyet++;
10429
10430 if (iaxs[f->callno]) {
10431 send_packet(f);
10432 count++;
10433 }
10434
10435 ast_mutex_unlock(&iaxsl[f->callno]);
10436
10437 if (f->retries < 0) {
10438
10439 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
10440 iaxq.count--;
10441
10442 iax_frame_free(f);
10443 } else {
10444
10445 f->retries++;
10446 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
10447 }
10448 }
10449 AST_LIST_TRAVERSE_SAFE_END
10450 AST_LIST_UNLOCK(&iaxq.queue);
10451
10452 pthread_testcancel();
10453
10454 if (option_debug && count >= 20)
10455 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
10456
10457
10458 res = ast_io_wait(io, wakeup);
10459 if (res >= 0) {
10460 if (option_debug && res >= 20)
10461 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
10462 }
10463 }
10464 return NULL;
10465 }
10466
10467 static int start_network_thread(void)
10468 {
10469 pthread_attr_t attr;
10470 int threadcount = 0;
10471 int x;
10472 for (x = 0; x < iaxthreadcount; x++) {
10473 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
10474 if (thread) {
10475 thread->type = IAX_TYPE_POOL;
10476 thread->threadnum = ++threadcount;
10477 ast_mutex_init(&thread->lock);
10478 ast_cond_init(&thread->cond, NULL);
10479 pthread_attr_init(&attr);
10480 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
10481 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
10482 ast_log(LOG_WARNING, "Failed to create new thread!\n");
10483 free(thread);
10484 thread = NULL;
10485 }
10486 AST_LIST_LOCK(&idle_list);
10487 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
10488 AST_LIST_UNLOCK(&idle_list);
10489 }
10490 }
10491 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
10492 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
10493 if (option_verbose > 1)
10494 ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount);
10495 return 0;
10496 }
10497
10498 static struct iax2_context *build_context(char *context)
10499 {
10500 struct iax2_context *con;
10501
10502 if ((con = ast_calloc(1, sizeof(*con))))
10503 ast_copy_string(con->context, context, sizeof(con->context));
10504
10505 return con;
10506 }
10507
10508 static int get_auth_methods(char *value)
10509 {
10510 int methods = 0;
10511 if (strstr(value, "rsa"))
10512 methods |= IAX_AUTH_RSA;
10513 if (strstr(value, "md5"))
10514 methods |= IAX_AUTH_MD5;
10515 if (strstr(value, "plaintext"))
10516 methods |= IAX_AUTH_PLAINTEXT;
10517 return methods;
10518 }
10519
10520
10521
10522
10523
10524 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
10525 {
10526 int sd;
10527 int res;
10528
10529 sd = socket(AF_INET, SOCK_DGRAM, 0);
10530 if (sd < 0) {
10531 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
10532 return -1;
10533 }
10534
10535 res = bind(sd, sa, salen);
10536 if (res < 0) {
10537 if (option_debug)
10538 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
10539 close(sd);
10540 return 1;
10541 }
10542
10543 close(sd);
10544 return 0;
10545 }
10546
10547
10548
10549
10550 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
10551 {
10552 struct sockaddr_in sin;
10553 int nonlocal = 1;
10554 int port = IAX_DEFAULT_PORTNO;
10555 int sockfd = defaultsockfd;
10556 char *tmp;
10557 char *addr;
10558 char *portstr;
10559
10560 if (!(tmp = ast_strdupa(srcaddr)))
10561 return -1;
10562
10563 addr = strsep(&tmp, ":");
10564 portstr = tmp;
10565
10566 if (portstr) {
10567 port = atoi(portstr);
10568 if (port < 1)
10569 port = IAX_DEFAULT_PORTNO;
10570 }
10571
10572 if (!ast_get_ip(&sin, addr)) {
10573 struct ast_netsock *sock;
10574 int res;
10575
10576 sin.sin_port = 0;
10577 sin.sin_family = AF_INET;
10578 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
10579 if (res == 0) {
10580
10581 sin.sin_port = htons(port);
10582 if (!(sock = ast_netsock_find(netsock, &sin)))
10583 sock = ast_netsock_find(outsock, &sin);
10584 if (sock) {
10585 sockfd = ast_netsock_sockfd(sock);
10586 nonlocal = 0;
10587 } else {
10588 unsigned int orig_saddr = sin.sin_addr.s_addr;
10589
10590 sin.sin_addr.s_addr = INADDR_ANY;
10591 if (ast_netsock_find(netsock, &sin)) {
10592 sin.sin_addr.s_addr = orig_saddr;
10593 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
10594 if (sock) {
10595 sockfd = ast_netsock_sockfd(sock);
10596 ast_netsock_unref(sock);
10597 nonlocal = 0;
10598 } else {
10599 nonlocal = 2;
10600 }
10601 }
10602 }
10603 }
10604 }
10605
10606 peer->sockfd = sockfd;
10607
10608 if (nonlocal == 1) {
10609 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
10610 srcaddr, peer->name);
10611 return -1;
10612 } else if (nonlocal == 2) {
10613 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
10614 srcaddr, peer->name);
10615 return -1;
10616 } else {
10617 if (option_debug)
10618 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
10619 return 0;
10620 }
10621 }
10622
10623 static void peer_destructor(void *obj)
10624 {
10625 struct iax2_peer *peer = obj;
10626 int callno = peer->callno;
10627
10628 ast_free_ha(peer->ha);
10629
10630 if (callno > 0) {
10631 ast_mutex_lock(&iaxsl[callno]);
10632 iax2_destroy(callno);
10633 ast_mutex_unlock(&iaxsl[callno]);
10634 }
10635
10636 register_peer_exten(peer, 0);
10637
10638 if (peer->dnsmgr)
10639 ast_dnsmgr_release(peer->dnsmgr);
10640
10641 ast_string_field_free_memory(peer);
10642 }
10643
10644
10645 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
10646 {
10647 struct iax2_peer *peer = NULL;
10648 struct ast_ha *oldha = NULL;
10649 int maskfound=0;
10650 int found=0;
10651 int firstpass=1;
10652 struct iax2_peer tmp_peer = {
10653 .name = name,
10654 };
10655
10656 if (!temponly) {
10657 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
10658 if (peer && !ast_test_flag(peer, IAX_DELME))
10659 firstpass = 0;
10660 }
10661
10662 if (peer) {
10663 found++;
10664 if (firstpass) {
10665 oldha = peer->ha;
10666 peer->ha = NULL;
10667 }
10668 unlink_peer(peer);
10669 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
10670 peer->expire = -1;
10671 peer->pokeexpire = -1;
10672 peer->sockfd = defaultsockfd;
10673 if (ast_string_field_init(peer, 32))
10674 peer = peer_unref(peer);
10675 }
10676
10677 if (peer) {
10678 if (firstpass) {
10679 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10680 peer->encmethods = iax2_encryption;
10681 peer->adsi = adsi;
10682 ast_string_field_set(peer,secret,"");
10683 if (!found) {
10684 ast_string_field_set(peer, name, name);
10685 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10686 peer->expiry = min_reg_expire;
10687 }
10688 peer->prefs = prefs;
10689 peer->capability = iax2_capability;
10690 peer->smoothing = 0;
10691 peer->pokefreqok = DEFAULT_FREQ_OK;
10692 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
10693 peer->maxcallno = 0;
10694 peercnt_modify(0, 0, &peer->addr);
10695 peer->calltoken_required = CALLTOKEN_DEFAULT;
10696 ast_string_field_set(peer,context,"");
10697 ast_string_field_set(peer,peercontext,"");
10698 ast_clear_flag(peer, IAX_HASCALLERID);
10699 ast_string_field_set(peer, cid_name, "");
10700 ast_string_field_set(peer, cid_num, "");
10701 ast_string_field_set(peer, mohinterpret, mohinterpret);
10702 ast_string_field_set(peer, mohsuggest, mohsuggest);
10703 }
10704
10705 if (!v) {
10706 v = alt;
10707 alt = NULL;
10708 }
10709 while(v) {
10710 if (!strcasecmp(v->name, "secret")) {
10711 ast_string_field_set(peer, secret, v->value);
10712 } else if (!strcasecmp(v->name, "mailbox")) {
10713 ast_string_field_set(peer, mailbox, v->value);
10714 } else if (!strcasecmp(v->name, "hasvoicemail")) {
10715 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
10716 ast_string_field_set(peer, mailbox, name);
10717 }
10718 } else if (!strcasecmp(v->name, "mohinterpret")) {
10719 ast_string_field_set(peer, mohinterpret, v->value);
10720 } else if (!strcasecmp(v->name, "mohsuggest")) {
10721 ast_string_field_set(peer, mohsuggest, v->value);
10722 } else if (!strcasecmp(v->name, "dbsecret")) {
10723 ast_string_field_set(peer, dbsecret, v->value);
10724 } else if (!strcasecmp(v->name, "trunk")) {
10725 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
10726 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
10727 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name);
10728 ast_clear_flag(peer, IAX_TRUNK);
10729 }
10730 } else if (!strcasecmp(v->name, "auth")) {
10731 peer->authmethods = get_auth_methods(v->value);
10732 } else if (!strcasecmp(v->name, "encryption")) {
10733 peer->encmethods = get_encrypt_methods(v->value);
10734 } else if (!strcasecmp(v->name, "notransfer")) {
10735 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10736 ast_clear_flag(peer, IAX_TRANSFERMEDIA);
10737 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER);
10738 } else if (!strcasecmp(v->name, "transfer")) {
10739 if (!strcasecmp(v->value, "mediaonly")) {
10740 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
10741 } else if (ast_true(v->value)) {
10742 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10743 } else
10744 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10745 } else if (!strcasecmp(v->name, "jitterbuffer")) {
10746 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
10747 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10748 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
10749 } else if (!strcasecmp(v->name, "host")) {
10750 if (!strcasecmp(v->value, "dynamic")) {
10751
10752 ast_set_flag(peer, IAX_DYNAMIC);
10753 if (!found) {
10754
10755
10756 memset(&peer->addr.sin_addr, 0, 4);
10757 if (peer->addr.sin_port) {
10758
10759 peer->defaddr.sin_port = peer->addr.sin_port;
10760 peer->addr.sin_port = 0;
10761 }
10762 }
10763 } else {
10764
10765 AST_SCHED_DEL(sched, peer->expire);
10766 ast_clear_flag(peer, IAX_DYNAMIC);
10767 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
10768 return peer_unref(peer);
10769 if (!peer->addr.sin_port)
10770 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10771 }
10772 if (!maskfound)
10773 inet_aton("255.255.255.255", &peer->mask);
10774 } else if (!strcasecmp(v->name, "defaultip")) {
10775 if (ast_get_ip(&peer->defaddr, v->value))
10776 return peer_unref(peer);
10777 } else if (!strcasecmp(v->name, "sourceaddress")) {
10778 peer_set_srcaddr(peer, v->value);
10779 } else if (!strcasecmp(v->name, "permit") ||
10780 !strcasecmp(v->name, "deny")) {
10781 peer->ha = ast_append_ha(v->name, v->value, peer->ha);
10782 } else if (!strcasecmp(v->name, "mask")) {
10783 maskfound++;
10784 inet_aton(v->value, &peer->mask);
10785 } else if (!strcasecmp(v->name, "context")) {
10786 ast_string_field_set(peer, context, v->value);
10787 } else if (!strcasecmp(v->name, "regexten")) {
10788 ast_string_field_set(peer, regexten, v->value);
10789 } else if (!strcasecmp(v->name, "peercontext")) {
10790 ast_string_field_set(peer, peercontext, v->value);
10791 } else if (!strcasecmp(v->name, "port")) {
10792 if (ast_test_flag(peer, IAX_DYNAMIC))
10793 peer->defaddr.sin_port = htons(atoi(v->value));
10794 else
10795 peer->addr.sin_port = htons(atoi(v->value));
10796 } else if (!strcasecmp(v->name, "username")) {
10797 ast_string_field_set(peer, username, v->value);
10798 } else if (!strcasecmp(v->name, "allow")) {
10799 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
10800 } else if (!strcasecmp(v->name, "disallow")) {
10801 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
10802 } else if (!strcasecmp(v->name, "callerid")) {
10803 if (!ast_strlen_zero(v->value)) {
10804 char name2[80];
10805 char num2[80];
10806 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10807 ast_string_field_set(peer, cid_name, name2);
10808 ast_string_field_set(peer, cid_num, num2);
10809 } else {
10810 ast_string_field_set(peer, cid_name, "");
10811 ast_string_field_set(peer, cid_num, "");
10812 }
10813 ast_set_flag(peer, IAX_HASCALLERID);
10814 } else if (!strcasecmp(v->name, "fullname")) {
10815 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
10816 ast_set_flag(peer, IAX_HASCALLERID);
10817 } else if (!strcasecmp(v->name, "cid_number")) {
10818 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
10819 ast_set_flag(peer, IAX_HASCALLERID);
10820 } else if (!strcasecmp(v->name, "sendani")) {
10821 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
10822 } else if (!strcasecmp(v->name, "inkeys")) {
10823 ast_string_field_set(peer, inkeys, v->value);
10824 } else if (!strcasecmp(v->name, "outkey")) {
10825 ast_string_field_set(peer, outkey, v->value);
10826 } else if (!strcasecmp(v->name, "qualify")) {
10827 if (!strcasecmp(v->value, "no")) {
10828 peer->maxms = 0;
10829 } else if (!strcasecmp(v->value, "yes")) {
10830 peer->maxms = DEFAULT_MAXMS;
10831 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
10832 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);
10833 peer->maxms = 0;
10834 }
10835 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
10836 peer->smoothing = ast_true(v->value);
10837 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
10838 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
10839 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);
10840 }
10841 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
10842 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
10843 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);
10844 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
10845 } else if (!strcasecmp(v->name, "timezone")) {
10846 ast_string_field_set(peer, zonetag, v->value);
10847 } else if (!strcasecmp(v->name, "adsi")) {
10848 peer->adsi = ast_true(v->value);
10849 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
10850 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
10851 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
10852 } else {
10853 peercnt_modify(1, peer->maxcallno, &peer->addr);
10854 }
10855 } else if (!strcasecmp(v->name, "requirecalltoken")) {
10856
10857 if (ast_false(v->value)) {
10858 peer->calltoken_required = CALLTOKEN_NO;
10859 } else if (!strcasecmp(v->value, "auto")) {
10860 peer->calltoken_required = CALLTOKEN_AUTO;
10861 } else if (ast_true(v->value)) {
10862 peer->calltoken_required = CALLTOKEN_YES;
10863 } else {
10864 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
10865 }
10866 }
10867
10868 v = v->next;
10869 if (!v) {
10870 v = alt;
10871 alt = NULL;
10872 }
10873 }
10874 if (!peer->authmethods)
10875 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
10876 ast_clear_flag(peer, IAX_DELME);
10877
10878 peer->addr.sin_family = AF_INET;
10879 }
10880 if (oldha)
10881 ast_free_ha(oldha);
10882 return peer;
10883 }
10884
10885 static void user_destructor(void *obj)
10886 {
10887 struct iax2_user *user = obj;
10888
10889 ast_free_ha(user->ha);
10890 free_context(user->contexts);
10891 if(user->vars) {
10892 ast_variables_destroy(user->vars);
10893 user->vars = NULL;
10894 }
10895 ast_string_field_free_memory(user);
10896 }
10897
10898
10899 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
10900 {
10901 struct iax2_user *user = NULL;
10902 struct iax2_context *con, *conl = NULL;
10903 struct ast_ha *oldha = NULL;
10904 struct iax2_context *oldcon = NULL;
10905 int format;
10906 int firstpass=1;
10907 int oldcurauthreq = 0;
10908 char *varname = NULL, *varval = NULL;
10909 struct ast_variable *tmpvar = NULL;
10910 struct iax2_user tmp_user = {
10911 .name = name,
10912 };
10913
10914 if (!temponly) {
10915 user = ao2_find(users, &tmp_user, OBJ_POINTER);
10916 if (user && !ast_test_flag(user, IAX_DELME))
10917 firstpass = 0;
10918 }
10919
10920 if (user) {
10921 if (firstpass) {
10922 oldcurauthreq = user->curauthreq;
10923 oldha = user->ha;
10924 oldcon = user->contexts;
10925 user->ha = NULL;
10926 user->contexts = NULL;
10927 }
10928
10929 ao2_unlink(users, user);
10930 } else {
10931 user = ao2_alloc(sizeof(*user), user_destructor);
10932 }
10933
10934 if (user) {
10935 if (firstpass) {
10936 ast_string_field_free_memory(user);
10937 memset(user, 0, sizeof(struct iax2_user));
10938 if (ast_string_field_init(user, 32)) {
10939 user = user_unref(user);
10940 goto cleanup;
10941 }
10942 user->maxauthreq = maxauthreq;
10943 user->curauthreq = oldcurauthreq;
10944 user->prefs = prefs;
10945 user->capability = iax2_capability;
10946 user->encmethods = iax2_encryption;
10947 user->adsi = adsi;
10948 user->calltoken_required = CALLTOKEN_DEFAULT;
10949 ast_string_field_set(user, name, name);
10950 ast_string_field_set(user, language, language);
10951 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
10952 ast_clear_flag(user, IAX_HASCALLERID);
10953 ast_string_field_set(user, cid_name, "");
10954 ast_string_field_set(user, cid_num, "");
10955 ast_string_field_set(user, accountcode, accountcode);
10956 ast_string_field_set(user, mohinterpret, mohinterpret);
10957 ast_string_field_set(user, mohsuggest, mohsuggest);
10958 }
10959 if (!v) {
10960 v = alt;
10961 alt = NULL;
10962 }
10963 while(v) {
10964 if (!strcasecmp(v->name, "context")) {
10965 con = build_context(v->value);
10966 if (con) {
10967 if (conl)
10968 conl->next = con;
10969 else
10970 user->contexts = con;
10971 conl = con;
10972 }
10973 } else if (!strcasecmp(v->name, "permit") ||
10974 !strcasecmp(v->name, "deny")) {
10975 user->ha = ast_append_ha(v->name, v->value, user->ha);
10976 } else if (!strcasecmp(v->name, "setvar")) {
10977 varname = ast_strdupa(v->value);
10978 if (varname && (varval = strchr(varname,'='))) {
10979 *varval = '\0';
10980 varval++;
10981 if((tmpvar = ast_variable_new(varname, varval))) {
10982 tmpvar->next = user->vars;
10983 user->vars = tmpvar;
10984 }
10985 }
10986 } else if (!strcasecmp(v->name, "allow")) {
10987 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
10988 } else if (!strcasecmp(v->name, "disallow")) {
10989 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
10990 } else if (!strcasecmp(v->name, "trunk")) {
10991 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
10992 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
10993 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name);
10994 ast_clear_flag(user, IAX_TRUNK);
10995 }
10996 } else if (!strcasecmp(v->name, "auth")) {
10997 user->authmethods = get_auth_methods(v->value);
10998 } else if (!strcasecmp(v->name, "encryption")) {
10999 user->encmethods = get_encrypt_methods(v->value);
11000 } else if (!strcasecmp(v->name, "notransfer")) {
11001 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
11002 ast_clear_flag(user, IAX_TRANSFERMEDIA);
11003 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER);
11004 } else if (!strcasecmp(v->name, "transfer")) {
11005 if (!strcasecmp(v->value, "mediaonly")) {
11006 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
11007 } else if (ast_true(v->value)) {
11008 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11009 } else
11010 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11011 } else if (!strcasecmp(v->name, "codecpriority")) {
11012 if(!strcasecmp(v->value, "caller"))
11013 ast_set_flag(user, IAX_CODEC_USER_FIRST);
11014 else if(!strcasecmp(v->value, "disabled"))
11015 ast_set_flag(user, IAX_CODEC_NOPREFS);
11016 else if(!strcasecmp(v->value, "reqonly")) {
11017 ast_set_flag(user, IAX_CODEC_NOCAP);
11018 ast_set_flag(user, IAX_CODEC_NOPREFS);
11019 }
11020 } else if (!strcasecmp(v->name, "jitterbuffer")) {
11021 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
11022 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
11023 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
11024 } else if (!strcasecmp(v->name, "dbsecret")) {
11025 ast_string_field_set(user, dbsecret, v->value);
11026 } else if (!strcasecmp(v->name, "secret")) {
11027 if (!ast_strlen_zero(user->secret)) {
11028 char *old = ast_strdupa(user->secret);
11029
11030 ast_string_field_build(user, secret, "%s;%s", old, v->value);
11031 } else
11032 ast_string_field_set(user, secret, v->value);
11033 } else if (!strcasecmp(v->name, "callerid")) {
11034 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
11035 char name2[80];
11036 char num2[80];
11037 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
11038 ast_string_field_set(user, cid_name, name2);
11039 ast_string_field_set(user, cid_num, num2);
11040 ast_set_flag(user, IAX_HASCALLERID);
11041 } else {
11042 ast_clear_flag(user, IAX_HASCALLERID);
11043 ast_string_field_set(user, cid_name, "");
11044 ast_string_field_set(user, cid_num, "");
11045 }
11046 } else if (!strcasecmp(v->name, "fullname")) {
11047 if (!ast_strlen_zero(v->value)) {
11048 ast_string_field_set(user, cid_name, v->value);
11049 ast_set_flag(user, IAX_HASCALLERID);
11050 } else {
11051 ast_string_field_set(user, cid_name, "");
11052 if (ast_strlen_zero(user->cid_num))
11053 ast_clear_flag(user, IAX_HASCALLERID);
11054 }
11055 } else if (!strcasecmp(v->name, "cid_number")) {
11056 if (!ast_strlen_zero(v->value)) {
11057 ast_string_field_set(user, cid_num, v->value);
11058 ast_set_flag(user, IAX_HASCALLERID);
11059 } else {
11060 ast_string_field_set(user, cid_num, "");
11061 if (ast_strlen_zero(user->cid_name))
11062 ast_clear_flag(user, IAX_HASCALLERID);
11063 }
11064 } else if (!strcasecmp(v->name, "accountcode")) {
11065 ast_string_field_set(user, accountcode, v->value);
11066 } else if (!strcasecmp(v->name, "mohinterpret")) {
11067 ast_string_field_set(user, mohinterpret, v->value);
11068 } else if (!strcasecmp(v->name, "mohsuggest")) {
11069 ast_string_field_set(user, mohsuggest, v->value);
11070 } else if (!strcasecmp(v->name, "language")) {
11071 ast_string_field_set(user, language, v->value);
11072 } else if (!strcasecmp(v->name, "amaflags")) {
11073 format = ast_cdr_amaflags2int(v->value);
11074 if (format < 0) {
11075 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11076 } else {
11077 user->amaflags = format;
11078 }
11079 } else if (!strcasecmp(v->name, "inkeys")) {
11080 ast_string_field_set(user, inkeys, v->value);
11081 } else if (!strcasecmp(v->name, "maxauthreq")) {
11082 user->maxauthreq = atoi(v->value);
11083 if (user->maxauthreq < 0)
11084 user->maxauthreq = 0;
11085 } else if (!strcasecmp(v->name, "adsi")) {
11086 user->adsi = ast_true(v->value);
11087 } else if (!strcasecmp(v->name, "requirecalltoken")) {
11088
11089 if (ast_false(v->value)) {
11090 user->calltoken_required = CALLTOKEN_NO;
11091 } else if (!strcasecmp(v->value, "auto")) {
11092 user->calltoken_required = CALLTOKEN_AUTO;
11093 } else if (ast_true(v->value)) {
11094 user->calltoken_required = CALLTOKEN_YES;
11095 } else {
11096 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
11097 }
11098 }
11099
11100 v = v->next;
11101 if (!v) {
11102 v = alt;
11103 alt = NULL;
11104 }
11105 }
11106 if (!user->authmethods) {
11107 if (!ast_strlen_zero(user->secret)) {
11108 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11109 if (!ast_strlen_zero(user->inkeys))
11110 user->authmethods |= IAX_AUTH_RSA;
11111 } else if (!ast_strlen_zero(user->inkeys)) {
11112 user->authmethods = IAX_AUTH_RSA;
11113 } else {
11114 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11115 }
11116 }
11117 ast_clear_flag(user, IAX_DELME);
11118 }
11119 cleanup:
11120 if (oldha)
11121 ast_free_ha(oldha);
11122 if (oldcon)
11123 free_context(oldcon);
11124 return user;
11125 }
11126
11127 static int peer_delme_cb(void *obj, void *arg, int flags)
11128 {
11129 struct iax2_peer *peer = obj;
11130
11131 ast_set_flag(peer, IAX_DELME);
11132
11133 return 0;
11134 }
11135
11136 static int user_delme_cb(void *obj, void *arg, int flags)
11137 {
11138 struct iax2_user *user = obj;
11139
11140 ast_set_flag(user, IAX_DELME);
11141
11142 return 0;
11143 }
11144
11145 static void delete_users(void)
11146 {
11147 struct iax2_registry *reg;
11148
11149 ao2_callback(users, 0, user_delme_cb, NULL);
11150
11151 AST_LIST_LOCK(®istrations);
11152 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
11153 ast_sched_del(sched, reg->expire);
11154 if (reg->callno) {
11155 int callno = reg->callno;
11156 ast_mutex_lock(&iaxsl[callno]);
11157 if (iaxs[callno]) {
11158 iaxs[callno]->reg = NULL;
11159 iax2_destroy(callno);
11160 }
11161 ast_mutex_unlock(&iaxsl[callno]);
11162 }
11163 if (reg->dnsmgr)
11164 ast_dnsmgr_release(reg->dnsmgr);
11165 free(reg);
11166 }
11167 AST_LIST_UNLOCK(®istrations);
11168
11169 ao2_callback(peers, 0, peer_delme_cb, NULL);
11170 }
11171
11172 static void prune_users(void)
11173 {
11174 struct iax2_user *user;
11175 struct ao2_iterator i;
11176
11177 i = ao2_iterator_init(users, 0);
11178 while ((user = ao2_iterator_next(&i))) {
11179 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
11180 ao2_unlink(users, user);
11181 }
11182 user_unref(user);
11183 }
11184 }
11185
11186
11187 static void prune_peers(void)
11188 {
11189 struct iax2_peer *peer;
11190 struct ao2_iterator i;
11191
11192 i = ao2_iterator_init(peers, 0);
11193 while ((peer = ao2_iterator_next(&i))) {
11194 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
11195 unlink_peer(peer);
11196 }
11197 peer_unref(peer);
11198 }
11199 }
11200
11201 static void set_timing(void)
11202 {
11203 #ifdef HAVE_DAHDI
11204 int bs = trunkfreq * 8;
11205 if (timingfd > -1) {
11206 if (
11207 #ifdef DAHDI_TIMERACK
11208 ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) &&
11209 #endif
11210 ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs))
11211 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
11212 }
11213 #endif
11214 }
11215
11216 static void set_config_destroy(void)
11217 {
11218 strcpy(accountcode, "");
11219 strcpy(language, "");
11220 strcpy(mohinterpret, "default");
11221 strcpy(mohsuggest, "");
11222 amaflags = 0;
11223 delayreject = 0;
11224 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
11225 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
11226 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
11227 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
11228 delete_users();
11229 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
11230 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
11231 }
11232
11233
11234 static int set_config(const char *config_file, int reload)
11235 {
11236 struct ast_config *cfg, *ucfg;
11237 int capability=iax2_capability;
11238 struct ast_variable *v;
11239 char *cat;
11240 const char *utype;
11241 const char *tosval;
11242 int format;
11243 int portno = IAX_DEFAULT_PORTNO;
11244 int x;
11245 struct iax2_user *user;
11246 struct iax2_peer *peer;
11247 struct ast_netsock *ns;
11248 #if 0
11249 static unsigned short int last_port=0;
11250 #endif
11251
11252 cfg = ast_config_load(config_file);
11253
11254 if (!cfg) {
11255 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
11256 return -1;
11257 }
11258
11259 if (reload) {
11260 set_config_destroy();
11261 }
11262
11263
11264 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
11265
11266
11267 memset(&globalflags, 0, sizeof(globalflags));
11268 ast_set_flag(&globalflags, IAX_RTUPDATE);
11269
11270 #ifdef SO_NO_CHECK
11271 nochecksums = 0;
11272 #endif
11273
11274 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11275 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11276 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
11277 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
11278
11279 maxauthreq = 3;
11280
11281 v = ast_variable_browse(cfg, "general");
11282
11283
11284 tosval = ast_variable_retrieve(cfg, "general", "tos");
11285 if (tosval) {
11286 if (ast_str2tos(tosval, &tos))
11287 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
11288 }
11289 while(v) {
11290 if (!strcasecmp(v->name, "bindport")){
11291 if (reload)
11292 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
11293 else
11294 portno = atoi(v->value);
11295 } else if (!strcasecmp(v->name, "pingtime"))
11296 ping_time = atoi(v->value);
11297 else if (!strcasecmp(v->name, "iaxthreadcount")) {
11298 if (reload) {
11299 if (atoi(v->value) != iaxthreadcount)
11300 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
11301 } else {
11302 iaxthreadcount = atoi(v->value);
11303 if (iaxthreadcount < 1) {
11304 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
11305 iaxthreadcount = 1;
11306 } else if (iaxthreadcount > 256) {
11307 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
11308 iaxthreadcount = 256;
11309 }
11310 }
11311 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
11312 if (reload) {
11313 AST_LIST_LOCK(&dynamic_list);
11314 iaxmaxthreadcount = atoi(v->value);
11315 AST_LIST_UNLOCK(&dynamic_list);
11316 } else {
11317 iaxmaxthreadcount = atoi(v->value);
11318 if (iaxmaxthreadcount < 0) {
11319 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
11320 iaxmaxthreadcount = 0;
11321 } else if (iaxmaxthreadcount > 256) {
11322 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
11323 iaxmaxthreadcount = 256;
11324 }
11325 }
11326 } else if (!strcasecmp(v->name, "nochecksums")) {
11327 #ifdef SO_NO_CHECK
11328 if (ast_true(v->value))
11329 nochecksums = 1;
11330 else
11331 nochecksums = 0;
11332 #else
11333 if (ast_true(v->value))
11334 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
11335 #endif
11336 }
11337 else if (!strcasecmp(v->name, "maxjitterbuffer"))
11338 maxjitterbuffer = atoi(v->value);
11339 else if (!strcasecmp(v->name, "resyncthreshold"))
11340 resyncthreshold = atoi(v->value);
11341 else if (!strcasecmp(v->name, "maxjitterinterps"))
11342 maxjitterinterps = atoi(v->value);
11343 else if (!strcasecmp(v->name, "lagrqtime"))
11344 lagrq_time = atoi(v->value);
11345 else if (!strcasecmp(v->name, "maxregexpire"))
11346 max_reg_expire = atoi(v->value);
11347 else if (!strcasecmp(v->name, "minregexpire"))
11348 min_reg_expire = atoi(v->value);
11349 else if (!strcasecmp(v->name, "bindaddr")) {
11350 if (reload) {
11351 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
11352 } else {
11353 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
11354 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
11355 } else {
11356 if (option_verbose > 1) {
11357 if (strchr(v->value, ':'))
11358 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
11359 else
11360 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
11361 }
11362 if (defaultsockfd < 0)
11363 defaultsockfd = ast_netsock_sockfd(ns);
11364 ast_netsock_unref(ns);
11365 }
11366 }
11367 } else if (!strcasecmp(v->name, "authdebug"))
11368 authdebug = ast_true(v->value);
11369 else if (!strcasecmp(v->name, "encryption"))
11370 iax2_encryption = get_encrypt_methods(v->value);
11371 else if (!strcasecmp(v->name, "notransfer")) {
11372 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
11373 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
11374 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);
11375 } else if (!strcasecmp(v->name, "transfer")) {
11376 if (!strcasecmp(v->value, "mediaonly")) {
11377 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
11378 } else if (ast_true(v->value)) {
11379 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11380 } else
11381 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11382 } else if (!strcasecmp(v->name, "codecpriority")) {
11383 if(!strcasecmp(v->value, "caller"))
11384 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
11385 else if(!strcasecmp(v->value, "disabled"))
11386 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11387 else if(!strcasecmp(v->value, "reqonly")) {
11388 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
11389 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11390 }
11391 } else if (!strcasecmp(v->name, "jitterbuffer"))
11392 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
11393 else if (!strcasecmp(v->name, "forcejitterbuffer"))
11394 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
11395 else if (!strcasecmp(v->name, "delayreject"))
11396 delayreject = ast_true(v->value);
11397 else if (!strcasecmp(v->name, "allowfwdownload"))
11398 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
11399 else if (!strcasecmp(v->name, "rtcachefriends"))
11400 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
11401 else if (!strcasecmp(v->name, "rtignoreregexpire"))
11402 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
11403 else if (!strcasecmp(v->name, "rtupdate"))
11404 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
11405 else if (!strcasecmp(v->name, "trunktimestamps"))
11406 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
11407 else if (!strcasecmp(v->name, "rtautoclear")) {
11408 int i = atoi(v->value);
11409 if(i > 0)
11410 global_rtautoclear = i;
11411 else
11412 i = 0;
11413 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
11414 } else if (!strcasecmp(v->name, "trunkfreq")) {
11415 trunkfreq = atoi(v->value);
11416 if (trunkfreq < 10)
11417 trunkfreq = 10;
11418 } else if (!strcasecmp(v->name, "autokill")) {
11419 if (sscanf(v->value, "%30d", &x) == 1) {
11420 if (x >= 0)
11421 autokill = x;
11422 else
11423 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
11424 } else if (ast_true(v->value)) {
11425 autokill = DEFAULT_MAXMS;
11426 } else {
11427 autokill = 0;
11428 }
11429 } else if (!strcasecmp(v->name, "bandwidth")) {
11430 if (!strcasecmp(v->value, "low")) {
11431 capability = IAX_CAPABILITY_LOWBANDWIDTH;
11432 } else if (!strcasecmp(v->value, "medium")) {
11433 capability = IAX_CAPABILITY_MEDBANDWIDTH;
11434 } else if (!strcasecmp(v->value, "high")) {
11435 capability = IAX_CAPABILITY_FULLBANDWIDTH;
11436 } else
11437 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
11438 } else if (!strcasecmp(v->name, "allow")) {
11439 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
11440 } else if (!strcasecmp(v->name, "disallow")) {
11441 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
11442 } else if (!strcasecmp(v->name, "register")) {
11443 iax2_register(v->value, v->lineno);
11444 } else if (!strcasecmp(v->name, "iaxcompat")) {
11445 iaxcompat = ast_true(v->value);
11446 } else if (!strcasecmp(v->name, "regcontext")) {
11447 ast_copy_string(regcontext, v->value, sizeof(regcontext));
11448
11449 if (!ast_context_find(regcontext))
11450 ast_context_create(NULL, regcontext, "IAX2");
11451 } else if (!strcasecmp(v->name, "tos")) {
11452 if (ast_str2tos(v->value, &tos))
11453 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
11454 } else if (!strcasecmp(v->name, "accountcode")) {
11455 ast_copy_string(accountcode, v->value, sizeof(accountcode));
11456 } else if (!strcasecmp(v->name, "mohinterpret")) {
11457 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
11458 } else if (!strcasecmp(v->name, "mohsuggest")) {
11459 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
11460 } else if (!strcasecmp(v->name, "amaflags")) {
11461 format = ast_cdr_amaflags2int(v->value);
11462 if (format < 0) {
11463 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11464 } else {
11465 amaflags = format;
11466 }
11467 } else if (!strcasecmp(v->name, "language")) {
11468 ast_copy_string(language, v->value, sizeof(language));
11469 } else if (!strcasecmp(v->name, "maxauthreq")) {
11470 maxauthreq = atoi(v->value);
11471 if (maxauthreq < 0)
11472 maxauthreq = 0;
11473 } else if (!strcasecmp(v->name, "adsi")) {
11474 adsi = ast_true(v->value);
11475 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
11476 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
11477 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
11478 }
11479 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
11480 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
11481 ast_log(LOG_WARNING, "maxcallnumbers_nonvalidated must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
11482 }
11483 } else if(!strcasecmp(v->name, "calltokenoptional")) {
11484 if (add_calltoken_ignore(v->value)) {
11485 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
11486 }
11487 }
11488
11489 v = v->next;
11490 }
11491
11492 if (defaultsockfd < 0) {
11493 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
11494 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
11495 } else {
11496 if (option_verbose > 1)
11497 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
11498 defaultsockfd = ast_netsock_sockfd(ns);
11499 ast_netsock_unref(ns);
11500 }
11501 }
11502 if (reload) {
11503 ast_netsock_release(outsock);
11504 outsock = ast_netsock_list_alloc();
11505 if (!outsock) {
11506 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11507 return -1;
11508 }
11509 ast_netsock_init(outsock);
11510 }
11511
11512 if (min_reg_expire > max_reg_expire) {
11513 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
11514 min_reg_expire, max_reg_expire, max_reg_expire);
11515 min_reg_expire = max_reg_expire;
11516 }
11517 iax2_capability = capability;
11518
11519 ucfg = ast_config_load("users.conf");
11520 if (ucfg) {
11521 struct ast_variable *gen;
11522 int genhasiax;
11523 int genregisteriax;
11524 const char *hasiax, *registeriax;
11525
11526 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
11527 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
11528 gen = ast_variable_browse(ucfg, "general");
11529 cat = ast_category_browse(ucfg, NULL);
11530 while (cat) {
11531 if (strcasecmp(cat, "general")) {
11532 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
11533 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
11534 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
11535
11536 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
11537 if (user) {
11538 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11539 user = user_unref(user);
11540 }
11541 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
11542 if (peer) {
11543 if (ast_test_flag(peer, IAX_DYNAMIC))
11544 reg_source_db(peer);
11545 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11546 peer = peer_unref(peer);
11547 }
11548 }
11549 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
11550 char tmp[256];
11551 const char *host = ast_variable_retrieve(ucfg, cat, "host");
11552 const char *username = ast_variable_retrieve(ucfg, cat, "username");
11553 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
11554 if (!host)
11555 host = ast_variable_retrieve(ucfg, "general", "host");
11556 if (!username)
11557 username = ast_variable_retrieve(ucfg, "general", "username");
11558 if (!secret)
11559 secret = ast_variable_retrieve(ucfg, "general", "secret");
11560 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
11561 if (!ast_strlen_zero(secret))
11562 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
11563 else
11564 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
11565 iax2_register(tmp, 0);
11566 }
11567 }
11568 }
11569 cat = ast_category_browse(ucfg, cat);
11570 }
11571 ast_config_destroy(ucfg);
11572 }
11573
11574 cat = ast_category_browse(cfg, NULL);
11575 while(cat) {
11576 if (strcasecmp(cat, "general")) {
11577 utype = ast_variable_retrieve(cfg, cat, "type");
11578 if (!strcasecmp(cat, "callnumberlimits")) {
11579 build_callno_limits(ast_variable_browse(cfg, cat));
11580 } else if (utype) {
11581 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
11582 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
11583 if (user) {
11584 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11585 user = user_unref(user);
11586 }
11587 }
11588 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
11589 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
11590 if (peer) {
11591 if (ast_test_flag(peer, IAX_DYNAMIC))
11592 reg_source_db(peer);
11593 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11594 peer = peer_unref(peer);
11595 }
11596 } else if (strcasecmp(utype, "user")) {
11597 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
11598 }
11599 } else
11600 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
11601 }
11602 cat = ast_category_browse(cfg, cat);
11603 }
11604 ast_config_destroy(cfg);
11605 set_timing();
11606 return 1;
11607 }
11608
11609 static void poke_all_peers(void)
11610 {
11611 struct ao2_iterator i;
11612 struct iax2_peer *peer;
11613
11614 i = ao2_iterator_init(peers, 0);
11615 while ((peer = ao2_iterator_next(&i))) {
11616 iax2_poke_peer(peer, 0);
11617 peer_unref(peer);
11618 }
11619 }
11620 static int reload_config(void)
11621 {
11622 static const char config[] = "iax.conf";
11623 struct iax2_registry *reg;
11624
11625 if (set_config(config, 1) > 0) {
11626 prune_peers();
11627 prune_users();
11628 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
11629 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
11630 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
11631 AST_LIST_LOCK(®istrations);
11632 AST_LIST_TRAVERSE(®istrations, reg, entry)
11633 iax2_do_register(reg);
11634 AST_LIST_UNLOCK(®istrations);
11635
11636 poke_all_peers();
11637 }
11638 reload_firmware(0);
11639 iax_provision_reload();
11640
11641 return 0;
11642 }
11643
11644 static int iax2_reload(int fd, int argc, char *argv[])
11645 {
11646 return reload_config();
11647 }
11648
11649 static int reload(void)
11650 {
11651 return reload_config();
11652 }
11653
11654 static int cache_get_callno_locked(const char *data)
11655 {
11656 struct sockaddr_in sin;
11657 int x;
11658 int callno;
11659 struct iax_ie_data ied;
11660 struct create_addr_info cai;
11661 struct parsed_dial_string pds;
11662 char *tmpstr;
11663
11664 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11665
11666
11667 if (!ast_mutex_trylock(&iaxsl[x])) {
11668 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
11669 return x;
11670 ast_mutex_unlock(&iaxsl[x]);
11671 }
11672 }
11673
11674
11675
11676 memset(&cai, 0, sizeof(cai));
11677 memset(&ied, 0, sizeof(ied));
11678 memset(&pds, 0, sizeof(pds));
11679
11680 tmpstr = ast_strdupa(data);
11681 parse_dial_string(tmpstr, &pds);
11682
11683 if (ast_strlen_zero(pds.peer)) {
11684 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
11685 return -1;
11686 }
11687
11688
11689 if (create_addr(pds.peer, NULL, &sin, &cai))
11690 return -1;
11691
11692 if (option_debug)
11693 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
11694 pds.peer, pds.username, pds.password, pds.context);
11695
11696 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11697 if (callno < 1) {
11698 ast_log(LOG_WARNING, "Unable to create call\n");
11699 return -1;
11700 }
11701
11702 ast_string_field_set(iaxs[callno], dproot, data);
11703 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
11704
11705 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
11706 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
11707
11708
11709
11710 if (pds.exten)
11711 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
11712 if (pds.username)
11713 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
11714 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
11715 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
11716
11717 if (pds.password)
11718 ast_string_field_set(iaxs[callno], secret, pds.password);
11719 if (pds.key)
11720 ast_string_field_set(iaxs[callno], outkey, pds.key);
11721
11722 add_empty_calltoken_ie(iaxs[callno], &ied);
11723 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
11724
11725 return callno;
11726 }
11727
11728 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
11729 {
11730 struct iax2_dpcache *dp, *prev = NULL, *next;
11731 struct timeval tv;
11732 int x;
11733 int com[2];
11734 int timeout;
11735 int old=0;
11736 int outfd;
11737 int abort;
11738 int callno;
11739 struct ast_channel *c;
11740 struct ast_frame *f;
11741 gettimeofday(&tv, NULL);
11742 dp = dpcache;
11743 while(dp) {
11744 next = dp->next;
11745
11746 if (ast_tvcmp(tv, dp->expiry) > 0) {
11747
11748 if (prev)
11749 prev->next = dp->next;
11750 else
11751 dpcache = dp->next;
11752 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
11753
11754 free(dp);
11755 } else {
11756 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);
11757 }
11758 dp = next;
11759 continue;
11760 }
11761
11762 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
11763 break;
11764 prev = dp;
11765 dp = next;
11766 }
11767 if (!dp) {
11768
11769
11770 callno = cache_get_callno_locked(data);
11771 if (callno < 0) {
11772 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
11773 return NULL;
11774 }
11775 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
11776 ast_mutex_unlock(&iaxsl[callno]);
11777 return NULL;
11778 }
11779 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
11780 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
11781 gettimeofday(&dp->expiry, NULL);
11782 dp->orig = dp->expiry;
11783
11784 dp->expiry.tv_sec += iaxdefaultdpcache;
11785 dp->next = dpcache;
11786 dp->flags = CACHE_FLAG_PENDING;
11787 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
11788 dp->waiters[x] = -1;
11789 dpcache = dp;
11790 dp->peer = iaxs[callno]->dpentries;
11791 iaxs[callno]->dpentries = dp;
11792
11793 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
11794 iax2_dprequest(dp, callno);
11795 ast_mutex_unlock(&iaxsl[callno]);
11796 }
11797
11798 if (dp->flags & CACHE_FLAG_PENDING) {
11799
11800
11801 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
11802
11803 if (dp->waiters[x] < 0)
11804 break;
11805 }
11806 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
11807 ast_log(LOG_WARNING, "No more waiter positions available\n");
11808 return NULL;
11809 }
11810 if (pipe(com)) {
11811 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
11812 return NULL;
11813 }
11814 dp->waiters[x] = com[1];
11815
11816 timeout = iaxdefaulttimeout * 1000;
11817
11818 ast_mutex_unlock(&dpcache_lock);
11819
11820 if (chan)
11821 old = ast_channel_defer_dtmf(chan);
11822 abort = 0;
11823 while(timeout) {
11824 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
11825 if (outfd > -1) {
11826 break;
11827 }
11828 if (c) {
11829 f = ast_read(c);
11830 if (f)
11831 ast_frfree(f);
11832 else {
11833
11834 break;
11835 abort = 1;
11836 }
11837 }
11838 }
11839 if (!timeout) {
11840 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
11841 }
11842 ast_mutex_lock(&dpcache_lock);
11843 dp->waiters[x] = -1;
11844 close(com[1]);
11845 close(com[0]);
11846 if (abort) {
11847
11848
11849 if (!old && chan)
11850 ast_channel_undefer_dtmf(chan);
11851 return NULL;
11852 }
11853 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
11854
11855 if (dp->flags & CACHE_FLAG_PENDING) {
11856
11857
11858 dp->flags &= ~CACHE_FLAG_PENDING;
11859 dp->flags |= CACHE_FLAG_TIMEOUT;
11860
11861
11862 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
11863 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11864 if (dp->waiters[x] > -1) {
11865 if (write(dp->waiters[x], "asdf", 4) < 0) {
11866 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
11867 }
11868 }
11869 }
11870 }
11871 }
11872
11873 if (!old && chan)
11874 ast_channel_undefer_dtmf(chan);
11875 }
11876 return dp;
11877 }
11878
11879
11880 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11881 {
11882 struct iax2_dpcache *dp;
11883 int res = 0;
11884 #if 0
11885 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11886 #endif
11887 if ((priority != 1) && (priority != 2))
11888 return 0;
11889 ast_mutex_lock(&dpcache_lock);
11890 dp = find_cache(chan, data, context, exten, priority);
11891 if (dp) {
11892 if (dp->flags & CACHE_FLAG_EXISTS)
11893 res= 1;
11894 }
11895 ast_mutex_unlock(&dpcache_lock);
11896 if (!dp) {
11897 ast_log(LOG_WARNING, "Unable to make DP cache\n");
11898 }
11899 return res;
11900 }
11901
11902
11903 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11904 {
11905 int res = 0;
11906 struct iax2_dpcache *dp;
11907 #if 0
11908 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11909 #endif
11910 if ((priority != 1) && (priority != 2))
11911 return 0;
11912 ast_mutex_lock(&dpcache_lock);
11913 dp = find_cache(chan, data, context, exten, priority);
11914 if (dp) {
11915 if (dp->flags & CACHE_FLAG_CANEXIST)
11916 res= 1;
11917 }
11918 ast_mutex_unlock(&dpcache_lock);
11919 if (!dp) {
11920 ast_log(LOG_WARNING, "Unable to make DP cache\n");
11921 }
11922 return res;
11923 }
11924
11925
11926 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11927 {
11928 int res = 0;
11929 struct iax2_dpcache *dp;
11930 #if 0
11931 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11932 #endif
11933 if ((priority != 1) && (priority != 2))
11934 return 0;
11935 ast_mutex_lock(&dpcache_lock);
11936 dp = find_cache(chan, data, context, exten, priority);
11937 if (dp) {
11938 if (dp->flags & CACHE_FLAG_MATCHMORE)
11939 res= 1;
11940 }
11941 ast_mutex_unlock(&dpcache_lock);
11942 if (!dp) {
11943 ast_log(LOG_WARNING, "Unable to make DP cache\n");
11944 }
11945 return res;
11946 }
11947
11948
11949 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11950 {
11951 char odata[256];
11952 char req[256];
11953 char *ncontext;
11954 struct iax2_dpcache *dp;
11955 struct ast_app *dial;
11956 #if 0
11957 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);
11958 #endif
11959 if (priority == 2) {
11960
11961 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
11962 if (dialstatus) {
11963 dial = pbx_findapp(dialstatus);
11964 if (dial)
11965 pbx_exec(chan, dial, "");
11966 }
11967 return -1;
11968 } else if (priority != 1)
11969 return -1;
11970 ast_mutex_lock(&dpcache_lock);
11971 dp = find_cache(chan, data, context, exten, priority);
11972 if (dp) {
11973 if (dp->flags & CACHE_FLAG_EXISTS) {
11974 ast_copy_string(odata, data, sizeof(odata));
11975 ncontext = strchr(odata, '/');
11976 if (ncontext) {
11977 *ncontext = '\0';
11978 ncontext++;
11979 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
11980 } else {
11981 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
11982 }
11983 if (option_verbose > 2)
11984 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
11985 } else {
11986 ast_mutex_unlock(&dpcache_lock);
11987 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
11988 return -1;
11989 }
11990 }
11991 ast_mutex_unlock(&dpcache_lock);
11992 dial = pbx_findapp("Dial");
11993 if (dial) {
11994 return pbx_exec(chan, dial, req);
11995 } else {
11996 ast_log(LOG_WARNING, "No dial application registered\n");
11997 }
11998 return -1;
11999 }
12000
12001 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
12002 {
12003 struct iax2_peer *peer;
12004 char *peername, *colname;
12005
12006 peername = ast_strdupa(data);
12007
12008
12009 if (!strcmp(peername,"CURRENTCHANNEL")) {
12010 unsigned short callno;
12011 if (chan->tech != &iax2_tech)
12012 return -1;
12013 callno = PTR_TO_CALLNO(chan->tech_pvt);
12014 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
12015 return 0;
12016 }
12017
12018 if ((colname = strchr(peername, ':')))
12019 *colname++ = '\0';
12020 else if ((colname = strchr(peername, '|')))
12021 *colname++ = '\0';
12022 else
12023 colname = "ip";
12024
12025 if (!(peer = find_peer(peername, 1)))
12026 return -1;
12027
12028 if (!strcasecmp(colname, "ip")) {
12029 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
12030 } else if (!strcasecmp(colname, "status")) {
12031 peer_status(peer, buf, len);
12032 } else if (!strcasecmp(colname, "mailbox")) {
12033 ast_copy_string(buf, peer->mailbox, len);
12034 } else if (!strcasecmp(colname, "context")) {
12035 ast_copy_string(buf, peer->context, len);
12036 } else if (!strcasecmp(colname, "expire")) {
12037 snprintf(buf, len, "%d", peer->expire);
12038 } else if (!strcasecmp(colname, "dynamic")) {
12039 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
12040 } else if (!strcasecmp(colname, "callerid_name")) {
12041 ast_copy_string(buf, peer->cid_name, len);
12042 } else if (!strcasecmp(colname, "callerid_num")) {
12043 ast_copy_string(buf, peer->cid_num, len);
12044 } else if (!strcasecmp(colname, "codecs")) {
12045 ast_getformatname_multiple(buf, len -1, peer->capability);
12046 } else if (!strncasecmp(colname, "codec[", 6)) {
12047 char *codecnum, *ptr;
12048 int index = 0, codec = 0;
12049
12050 codecnum = strchr(colname, '[');
12051 *codecnum = '\0';
12052 codecnum++;
12053 if ((ptr = strchr(codecnum, ']'))) {
12054 *ptr = '\0';
12055 }
12056 index = atoi(codecnum);
12057 if((codec = ast_codec_pref_index(&peer->prefs, index))) {
12058 ast_copy_string(buf, ast_getformatname(codec), len);
12059 } else {
12060 buf[0] = '\0';
12061 }
12062 } else {
12063 buf[0] = '\0';
12064 }
12065
12066 peer_unref(peer);
12067
12068 return 0;
12069 }
12070
12071 struct ast_custom_function iaxpeer_function = {
12072 .name = "IAXPEER",
12073 .synopsis = "Gets IAX peer information",
12074 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
12075 .read = function_iaxpeer,
12076 .desc = "If peername specified, valid items are:\n"
12077 "- ip (default) The IP address.\n"
12078 "- status The peer's status (if qualify=yes)\n"
12079 "- mailbox The configured mailbox.\n"
12080 "- context The configured context.\n"
12081 "- expire The epoch time of the next expire.\n"
12082 "- dynamic Is it dynamic? (yes/no).\n"
12083 "- callerid_name The configured Caller ID name.\n"
12084 "- callerid_num The configured Caller ID number.\n"
12085 "- codecs The configured codecs.\n"
12086 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
12087 "\n"
12088 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
12089 "\n"
12090 };
12091
12092
12093
12094 static int iax2_devicestate(void *data)
12095 {
12096 struct parsed_dial_string pds;
12097 char *tmp = ast_strdupa(data);
12098 struct iax2_peer *p;
12099 int res = AST_DEVICE_INVALID;
12100
12101 memset(&pds, 0, sizeof(pds));
12102 parse_dial_string(tmp, &pds);
12103
12104 if (ast_strlen_zero(pds.peer)) {
12105 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12106 return res;
12107 }
12108
12109 if (option_debug > 2)
12110 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
12111
12112
12113 if (!(p = find_peer(pds.peer, 1)))
12114 return res;
12115
12116 res = AST_DEVICE_UNAVAILABLE;
12117 if (option_debug > 2)
12118 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
12119 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
12120
12121 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
12122 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
12123
12124
12125 if (p->historicms == 0 || p->historicms <= p->maxms)
12126
12127 res = AST_DEVICE_UNKNOWN;
12128 }
12129
12130 peer_unref(p);
12131
12132 return res;
12133 }
12134
12135 static struct ast_switch iax2_switch =
12136 {
12137 name: "IAX2",
12138 description: "IAX Remote Dialplan Switch",
12139 exists: iax2_exists,
12140 canmatch: iax2_canmatch,
12141 exec: iax2_exec,
12142 matchmore: iax2_matchmore,
12143 };
12144
12145 static char show_stats_usage[] =
12146 "Usage: iax2 show stats\n"
12147 " Display statistics on IAX channel driver.\n";
12148
12149 static char show_cache_usage[] =
12150 "Usage: iax2 show cache\n"
12151 " Display currently cached IAX Dialplan results.\n";
12152
12153 static char show_peer_usage[] =
12154 "Usage: iax2 show peer <name>\n"
12155 " Display details on specific IAX peer\n";
12156
12157 static char show_callnumber_usage[] =
12158 "Usage: iax2 show callnumber usage <ip optional>\n"
12159 " Show current entries in the ip Call Number Limit table.\n";
12160
12161 static char prune_realtime_usage[] =
12162 "Usage: iax2 prune realtime [<peername>|all]\n"
12163 " Prunes object(s) from the cache\n";
12164
12165 static char iax2_reload_usage[] =
12166 "Usage: iax2 reload\n"
12167 " Reloads IAX configuration from iax.conf\n";
12168
12169 static char show_prov_usage[] =
12170 "Usage: iax2 provision <host> <template> [forced]\n"
12171 " Provisions the given peer or IP address using a template\n"
12172 " matching either 'template' or '*' if the template is not\n"
12173 " found. If 'forced' is specified, even empty provisioning\n"
12174 " fields will be provisioned as empty fields.\n";
12175
12176 static char show_users_usage[] =
12177 "Usage: iax2 show users [like <pattern>]\n"
12178 " Lists all known IAX2 users.\n"
12179 " Optional regular expression pattern is used to filter the user list.\n";
12180
12181 static char show_channels_usage[] =
12182 "Usage: iax2 show channels\n"
12183 " Lists all currently active IAX channels.\n";
12184
12185 static char show_netstats_usage[] =
12186 "Usage: iax2 show netstats\n"
12187 " Lists network status for all currently active IAX channels.\n";
12188
12189 static char show_threads_usage[] =
12190 "Usage: iax2 show threads\n"
12191 " Lists status of IAX helper threads\n";
12192
12193 static char show_peers_usage[] =
12194 "Usage: iax2 show peers [registered] [like <pattern>]\n"
12195 " Lists all known IAX2 peers.\n"
12196 " Optional 'registered' argument lists only peers with known addresses.\n"
12197 " Optional regular expression pattern is used to filter the peer list.\n";
12198
12199 static char show_firmware_usage[] =
12200 "Usage: iax2 show firmware\n"
12201 " Lists all known IAX firmware images.\n";
12202
12203 static char show_reg_usage[] =
12204 "Usage: iax2 show registry\n"
12205 " Lists all registration requests and status.\n";
12206
12207 static char debug_usage[] =
12208 "Usage: iax2 set debug\n"
12209 " Enables dumping of IAX packets for debugging purposes\n";
12210
12211 static char no_debug_usage[] =
12212 "Usage: iax2 set debug off\n"
12213 " Disables dumping of IAX packets for debugging purposes\n";
12214
12215 static char debug_trunk_usage[] =
12216 "Usage: iax2 set debug trunk\n"
12217 " Requests current status of IAX trunking\n";
12218
12219 static char no_debug_trunk_usage[] =
12220 "Usage: iax2 set debug trunk off\n"
12221 " Requests current status of IAX trunking\n";
12222
12223 static char debug_jb_usage[] =
12224 "Usage: iax2 set debug jb\n"
12225 " Enables jitterbuffer debugging information\n";
12226
12227 static char no_debug_jb_usage[] =
12228 "Usage: iax2 set debug jb off\n"
12229 " Disables jitterbuffer debugging information\n";
12230
12231 static char iax2_test_losspct_usage[] =
12232 "Usage: iax2 test losspct <percentage>\n"
12233 " For testing, throws away <percentage> percent of incoming packets\n";
12234
12235 #ifdef IAXTESTS
12236 static char iax2_test_late_usage[] =
12237 "Usage: iax2 test late <ms>\n"
12238 " For testing, count the next frame as <ms> ms late\n";
12239
12240 static char iax2_test_resync_usage[] =
12241 "Usage: iax2 test resync <ms>\n"
12242 " For testing, adjust all future frames by <ms> ms\n";
12243
12244 static char iax2_test_jitter_usage[] =
12245 "Usage: iax2 test jitter <ms> <pct>\n"
12246 " For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
12247 #endif
12248
12249 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
12250 { "iax2", "trunk", "debug", NULL },
12251 iax2_do_trunk_debug, NULL,
12252 NULL };
12253
12254 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
12255 { "iax2", "jb", "debug", NULL },
12256 iax2_do_jb_debug, NULL,
12257 NULL };
12258
12259 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
12260 { "iax2", "no", "debug", NULL },
12261 iax2_no_debug, NULL,
12262 NULL };
12263
12264 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
12265 { "iax2", "no", "trunk", "debug", NULL },
12266 iax2_no_trunk_debug, NULL,
12267 NULL };
12268
12269 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
12270 { "iax2", "no", "jb", "debug", NULL },
12271 iax2_no_jb_debug, NULL,
12272 NULL };
12273
12274 static struct ast_cli_entry cli_iax2[] = {
12275 { { "iax2", "show", "cache", NULL },
12276 iax2_show_cache, "Display IAX cached dialplan",
12277 show_cache_usage, NULL, },
12278
12279 { { "iax2", "show", "channels", NULL },
12280 iax2_show_channels, "List active IAX channels",
12281 show_channels_usage, NULL, },
12282
12283 { { "iax2", "show", "firmware", NULL },
12284 iax2_show_firmware, "List available IAX firmwares",
12285 show_firmware_usage, NULL, },
12286
12287 { { "iax2", "show", "netstats", NULL },
12288 iax2_show_netstats, "List active IAX channel netstats",
12289 show_netstats_usage, NULL, },
12290
12291 { { "iax2", "show", "peers", NULL },
12292 iax2_show_peers, "List defined IAX peers",
12293 show_peers_usage, NULL, },
12294
12295 { { "iax2", "show", "registry", NULL },
12296 iax2_show_registry, "Display IAX registration status",
12297 show_reg_usage, NULL, },
12298
12299 { { "iax2", "show", "stats", NULL },
12300 iax2_show_stats, "Display IAX statistics",
12301 show_stats_usage, NULL, },
12302
12303 { { "iax2", "show", "threads", NULL },
12304 iax2_show_threads, "Display IAX helper thread info",
12305 show_threads_usage, NULL, },
12306
12307 { { "iax2", "show", "users", NULL },
12308 iax2_show_users, "List defined IAX users",
12309 show_users_usage, NULL, },
12310
12311 { { "iax2", "prune", "realtime", NULL },
12312 iax2_prune_realtime, "Prune a cached realtime lookup",
12313 prune_realtime_usage, complete_iax2_show_peer },
12314
12315 { { "iax2", "reload", NULL },
12316 iax2_reload, "Reload IAX configuration",
12317 iax2_reload_usage },
12318
12319 { { "iax2", "show", "peer", NULL },
12320 iax2_show_peer, "Show details on specific IAX peer",
12321 show_peer_usage, complete_iax2_show_peer },
12322
12323 { { "iax2", "show", "callnumber", "usage", NULL },
12324 iax2_show_callnumber_usage, "Show current entries in ip Call number limit table",
12325 show_callnumber_usage, NULL },
12326
12327 { { "iax2", "set", "debug", NULL },
12328 iax2_do_debug, "Enable IAX debugging",
12329 debug_usage },
12330
12331 { { "iax2", "set", "debug", "trunk", NULL },
12332 iax2_do_trunk_debug, "Enable IAX trunk debugging",
12333 debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
12334
12335 { { "iax2", "set", "debug", "jb", NULL },
12336 iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
12337 debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
12338
12339 { { "iax2", "set", "debug", "off", NULL },
12340 iax2_no_debug, "Disable IAX debugging",
12341 no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
12342
12343 { { "iax2", "set", "debug", "trunk", "off", NULL },
12344 iax2_no_trunk_debug, "Disable IAX trunk debugging",
12345 no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
12346
12347 { { "iax2", "set", "debug", "jb", "off", NULL },
12348 iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
12349 no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
12350
12351 { { "iax2", "test", "losspct", NULL },
12352 iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
12353 iax2_test_losspct_usage },
12354
12355 { { "iax2", "provision", NULL },
12356 iax2_prov_cmd, "Provision an IAX device",
12357 show_prov_usage, iax2_prov_complete_template_3rd },
12358
12359 #ifdef IAXTESTS
12360 { { "iax2", "test", "late", NULL },
12361 iax2_test_late, "Test the receipt of a late frame",
12362 iax2_test_late_usage },
12363
12364 { { "iax2", "test", "resync", NULL },
12365 iax2_test_resync, "Test a resync in received timestamps",
12366 iax2_test_resync_usage },
12367
12368 { { "iax2", "test", "jitter", NULL },
12369 iax2_test_jitter, "Simulates jitter for testing",
12370 iax2_test_jitter_usage },
12371 #endif
12372 };
12373
12374 static int __unload_module(void)
12375 {
12376 struct iax2_thread *thread = NULL;
12377 int x;
12378
12379
12380
12381
12382
12383 if (netthreadid != AST_PTHREADT_NULL) {
12384 AST_LIST_LOCK(&iaxq.queue);
12385 ast_mutex_lock(&sched_lock);
12386 pthread_cancel(netthreadid);
12387 ast_cond_signal(&sched_cond);
12388 ast_mutex_unlock(&sched_lock);
12389 AST_LIST_UNLOCK(&iaxq.queue);
12390 pthread_join(netthreadid, NULL);
12391 }
12392 if (schedthreadid != AST_PTHREADT_NULL) {
12393 ast_mutex_lock(&sched_lock);
12394 pthread_cancel(schedthreadid);
12395 ast_cond_signal(&sched_cond);
12396 ast_mutex_unlock(&sched_lock);
12397 pthread_join(schedthreadid, NULL);
12398 }
12399
12400
12401 AST_LIST_LOCK(&idle_list);
12402 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
12403 AST_LIST_REMOVE_CURRENT(&idle_list, list);
12404 pthread_cancel(thread->threadid);
12405 }
12406 AST_LIST_TRAVERSE_SAFE_END
12407 AST_LIST_UNLOCK(&idle_list);
12408
12409 AST_LIST_LOCK(&active_list);
12410 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
12411 AST_LIST_REMOVE_CURRENT(&active_list, list);
12412 pthread_cancel(thread->threadid);
12413 }
12414 AST_LIST_TRAVERSE_SAFE_END
12415 AST_LIST_UNLOCK(&active_list);
12416
12417 AST_LIST_LOCK(&dynamic_list);
12418 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
12419 AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
12420 pthread_cancel(thread->threadid);
12421 }
12422 AST_LIST_TRAVERSE_SAFE_END
12423 AST_LIST_UNLOCK(&dynamic_list);
12424
12425 AST_LIST_HEAD_DESTROY(&iaxq.queue);
12426
12427
12428 while(0 < iaxactivethreadcount)
12429 usleep(10000);
12430
12431 ast_netsock_release(netsock);
12432 ast_netsock_release(outsock);
12433 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12434 if (iaxs[x]) {
12435 iax2_destroy(x);
12436 }
12437 }
12438 ast_manager_unregister( "IAXpeers" );
12439 ast_manager_unregister( "IAXnetstats" );
12440 ast_unregister_application(papp);
12441 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12442 ast_unregister_switch(&iax2_switch);
12443 ast_channel_unregister(&iax2_tech);
12444 delete_users();
12445 iax_provision_unload();
12446 sched_context_destroy(sched);
12447 reload_firmware(1);
12448
12449 ast_mutex_destroy(&waresl.lock);
12450
12451 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12452 ast_mutex_destroy(&iaxsl[x]);
12453 }
12454
12455 ao2_ref(peers, -1);
12456 ao2_ref(users, -1);
12457 ao2_ref(iax_peercallno_pvts, -1);
12458 ao2_ref(iax_transfercallno_pvts, -1);
12459 ao2_ref(peercnts, -1);
12460 ao2_ref(callno_limits, -1);
12461 ao2_ref(calltoken_ignores, -1);
12462 ao2_ref(callno_pool, -1);
12463 ao2_ref(callno_pool_trunk, -1);
12464
12465 return 0;
12466 }
12467
12468 static int unload_module(void)
12469 {
12470 ast_custom_function_unregister(&iaxpeer_function);
12471 return __unload_module();
12472 }
12473
12474 static int peer_set_sock_cb(void *obj, void *arg, int flags)
12475 {
12476 struct iax2_peer *peer = obj;
12477
12478 if (peer->sockfd < 0)
12479 peer->sockfd = defaultsockfd;
12480
12481 return 0;
12482 }
12483
12484 static int pvt_hash_cb(const void *obj, const int flags)
12485 {
12486 const struct chan_iax2_pvt *pvt = obj;
12487
12488 return pvt->peercallno;
12489 }
12490
12491 static int pvt_cmp_cb(void *obj, void *arg, int flags)
12492 {
12493 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12494
12495
12496
12497
12498 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
12499 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12500 }
12501
12502 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
12503 {
12504 const struct chan_iax2_pvt *pvt = obj;
12505
12506 return pvt->transfercallno;
12507 }
12508
12509 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
12510 {
12511 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12512
12513
12514
12515
12516 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
12517 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12518 }
12519
12520
12521 static int load_objects(void)
12522 {
12523 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
12524 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
12525
12526 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
12527 goto container_fail;
12528 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
12529 goto container_fail;
12530 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
12531 goto container_fail;
12532 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
12533 goto container_fail;
12534 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
12535 goto container_fail;
12536 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
12537 goto container_fail;
12538 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
12539 goto container_fail;
12540 } else if (create_callno_pools()) {
12541 goto container_fail;
12542 }
12543
12544 return 0;
12545
12546 container_fail:
12547 if (peers) {
12548 ao2_ref(peers, -1);
12549 }
12550 if (users) {
12551 ao2_ref(users, -1);
12552 }
12553 if (iax_peercallno_pvts) {
12554 ao2_ref(iax_peercallno_pvts, -1);
12555 }
12556 if (iax_transfercallno_pvts) {
12557 ao2_ref(iax_transfercallno_pvts, -1);
12558 }
12559 if (peercnts) {
12560 ao2_ref(peercnts, -1);
12561 }
12562 if (callno_limits) {
12563 ao2_ref(callno_limits, -1);
12564 }
12565 if (calltoken_ignores) {
12566 ao2_ref(calltoken_ignores, -1);
12567 }
12568 if (callno_pool) {
12569 ao2_ref(callno_pool, -1);
12570 }
12571 if (callno_pool_trunk) {
12572 ao2_ref(callno_pool_trunk, -1);
12573 }
12574 return AST_MODULE_LOAD_FAILURE;
12575 }
12576
12577
12578 static int load_module(void)
12579 {
12580 static const char config[] = "iax.conf";
12581 int res = 0;
12582 int x;
12583 struct iax2_registry *reg = NULL;
12584
12585 if (load_objects()) {
12586 return AST_MODULE_LOAD_FAILURE;
12587 }
12588
12589 randomcalltokendata = ast_random();
12590 ast_custom_function_register(&iaxpeer_function);
12591
12592 iax_set_output(iax_debug_output);
12593 iax_set_error(iax_error_output);
12594 jb_setoutput(jb_error_output, jb_warning_output, NULL);
12595
12596 #ifdef HAVE_DAHDI
12597 #ifdef DAHDI_TIMERACK
12598 timingfd = open(DAHDI_FILE_TIMER, O_RDWR);
12599 if (timingfd < 0)
12600 #endif
12601 timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR);
12602 if (timingfd < 0)
12603 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
12604 #endif
12605
12606 memset(iaxs, 0, sizeof(iaxs));
12607
12608 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12609 ast_mutex_init(&iaxsl[x]);
12610 }
12611
12612 ast_cond_init(&sched_cond, NULL);
12613
12614 io = io_context_create();
12615 sched = sched_context_create();
12616
12617 if (!io || !sched) {
12618 ast_log(LOG_ERROR, "Out of memory\n");
12619 return -1;
12620 }
12621
12622 netsock = ast_netsock_list_alloc();
12623 if (!netsock) {
12624 ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
12625 return -1;
12626 }
12627 ast_netsock_init(netsock);
12628
12629 outsock = ast_netsock_list_alloc();
12630 if (!outsock) {
12631 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12632 return -1;
12633 }
12634 ast_netsock_init(outsock);
12635
12636 ast_mutex_init(&waresl.lock);
12637
12638 AST_LIST_HEAD_INIT(&iaxq.queue);
12639
12640 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12641
12642 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
12643
12644 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
12645 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
12646
12647 if(set_config(config, 0) == -1)
12648 return AST_MODULE_LOAD_DECLINE;
12649
12650 if (ast_channel_register(&iax2_tech)) {
12651 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
12652 __unload_module();
12653 return -1;
12654 }
12655
12656 if (ast_register_switch(&iax2_switch))
12657 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
12658
12659 res = start_network_thread();
12660 if (!res) {
12661 if (option_verbose > 1)
12662 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
12663 } else {
12664 ast_log(LOG_ERROR, "Unable to start network thread\n");
12665 ast_netsock_release(netsock);
12666 ast_netsock_release(outsock);
12667 }
12668
12669 AST_LIST_LOCK(®istrations);
12670 AST_LIST_TRAVERSE(®istrations, reg, entry)
12671 iax2_do_register(reg);
12672 AST_LIST_UNLOCK(®istrations);
12673
12674 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
12675 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
12676
12677 reload_firmware(0);
12678 iax_provision_reload();
12679 return res;
12680 }
12681
12682 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
12683 .load = load_module,
12684 .unload = unload_module,
12685 .reload = reload,
12686 );