00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "asterisk.h"
00039
00040 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 250397 $")
00041
00042 #include <sys/mman.h>
00043 #include <dirent.h>
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 #include <arpa/inet.h>
00047 #include <netinet/in_systm.h>
00048 #include <netinet/ip.h>
00049 #include <sys/time.h>
00050 #include <sys/signal.h>
00051 #include <signal.h>
00052 #include <strings.h>
00053 #include <netdb.h>
00054 #include <fcntl.h>
00055 #include <sys/stat.h>
00056 #include <regex.h>
00057
00058 #include "asterisk/paths.h"
00059
00060 #include "asterisk/lock.h"
00061 #include "asterisk/frame.h"
00062 #include "asterisk/channel.h"
00063 #include "asterisk/module.h"
00064 #include "asterisk/pbx.h"
00065 #include "asterisk/sched.h"
00066 #include "asterisk/io.h"
00067 #include "asterisk/config.h"
00068 #include "asterisk/cli.h"
00069 #include "asterisk/translate.h"
00070 #include "asterisk/md5.h"
00071 #include "asterisk/cdr.h"
00072 #include "asterisk/crypto.h"
00073 #include "asterisk/acl.h"
00074 #include "asterisk/manager.h"
00075 #include "asterisk/callerid.h"
00076 #include "asterisk/app.h"
00077 #include "asterisk/astdb.h"
00078 #include "asterisk/musiconhold.h"
00079 #include "asterisk/features.h"
00080 #include "asterisk/utils.h"
00081 #include "asterisk/causes.h"
00082 #include "asterisk/localtime.h"
00083 #include "asterisk/aes.h"
00084 #include "asterisk/dnsmgr.h"
00085 #include "asterisk/devicestate.h"
00086 #include "asterisk/netsock.h"
00087 #include "asterisk/stringfields.h"
00088 #include "asterisk/linkedlists.h"
00089 #include "asterisk/event.h"
00090 #include "asterisk/astobj2.h"
00091 #include "asterisk/timing.h"
00092
00093 #include "iax2.h"
00094 #include "iax2-parser.h"
00095 #include "iax2-provision.h"
00096 #include "jitterbuf.h"
00097
00098
00099
00100 #define SCHED_MULTITHREADED
00101
00102
00103
00104 #define DEBUG_SCHED_MULTITHREAD
00105
00106
00107 #ifdef SO_NO_CHECK
00108 static int nochecksums = 0;
00109 #endif
00110
00111 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00112 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00113
00114 #define DEFAULT_THREAD_COUNT 10
00115 #define DEFAULT_MAX_THREAD_COUNT 100
00116 #define DEFAULT_RETRY_TIME 1000
00117 #define MEMORY_SIZE 100
00118 #define DEFAULT_DROP 3
00119
00120 #define DEBUG_SUPPORT
00121
00122 #define MIN_REUSE_TIME 60
00123
00124
00125 #define GAMMA (0.01)
00126
00127 static struct ast_codec_pref prefs;
00128
00129 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00130
00131
00132
00133
00134 #define MAX_TRUNK_MTU 1240
00135
00136 static int global_max_trunk_mtu;
00137 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00138
00139 #define DEFAULT_CONTEXT "default"
00140
00141 static char default_parkinglot[AST_MAX_CONTEXT];
00142
00143 static char language[MAX_LANGUAGE] = "";
00144 static char regcontext[AST_MAX_CONTEXT] = "";
00145
00146 static int maxauthreq = 3;
00147 static int max_retries = 4;
00148 static int ping_time = 21;
00149 static int lagrq_time = 10;
00150 static int maxjitterbuffer=1000;
00151 static int resyncthreshold=1000;
00152 static int maxjitterinterps=10;
00153 static int jittertargetextra = 40;
00154
00155 #define MAX_TRUNKDATA 640 * 200
00156
00157 static int trunkfreq = 20;
00158 static int trunkmaxsize = MAX_TRUNKDATA;
00159
00160 static int authdebug = 1;
00161 static int autokill = 0;
00162 static int iaxcompat = 0;
00163 static int last_authmethod = 0;
00164
00165 static int iaxdefaultdpcache=10 * 60;
00166
00167 static int iaxdefaulttimeout = 5;
00168
00169 static struct {
00170 unsigned int tos;
00171 unsigned int cos;
00172 } qos = { 0, 0 };
00173
00174 static int min_reg_expire;
00175 static int max_reg_expire;
00176
00177 static int srvlookup = 0;
00178
00179 static struct ast_timer *timer;
00180
00181 static struct ast_netsock_list *netsock;
00182 static struct ast_netsock_list *outsock;
00183 static int defaultsockfd = -1;
00184
00185 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00186
00187
00188 #define IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)
00189
00190 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00191 ~AST_FORMAT_SLINEAR & \
00192 ~AST_FORMAT_SLINEAR16 & \
00193 ~AST_FORMAT_ULAW & \
00194 ~AST_FORMAT_ALAW & \
00195 ~AST_FORMAT_G722)
00196
00197 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00198 ~AST_FORMAT_G726 & \
00199 ~AST_FORMAT_G726_AAL2 & \
00200 ~AST_FORMAT_ADPCM)
00201
00202 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00203 ~AST_FORMAT_G723_1)
00204
00205
00206 #define DEFAULT_MAXMS 2000
00207 #define DEFAULT_FREQ_OK 60 * 1000
00208 #define DEFAULT_FREQ_NOTOK 10 * 1000
00209
00210
00211 #define IAX_CALLENCRYPTED(pvt) \
00212 (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED))
00213
00214 #define IAX_DEBUGDIGEST(msg, key) do { \
00215 int idx; \
00216 char digest[33] = ""; \
00217 \
00218 if (!iaxdebug) \
00219 break; \
00220 \
00221 for (idx = 0; idx < 16; idx++) \
00222 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00223 \
00224 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00225 } while(0)
00226
00227 static struct io_context *io;
00228 static struct sched_context *sched;
00229
00230 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00231
00232 static int iaxdebug = 0;
00233
00234 static int iaxtrunkdebug = 0;
00235
00236 static int test_losspct = 0;
00237 #ifdef IAXTESTS
00238 static int test_late = 0;
00239 static int test_resync = 0;
00240 static int test_jit = 0;
00241 static int test_jitpct = 0;
00242 #endif
00243
00244 static char accountcode[AST_MAX_ACCOUNT_CODE];
00245 static char mohinterpret[MAX_MUSICCLASS];
00246 static char mohsuggest[MAX_MUSICCLASS];
00247 static int amaflags = 0;
00248 static int adsi = 0;
00249 static int delayreject = 0;
00250 static int iax2_encryption = 0;
00251
00252 static struct ast_flags globalflags = { 0 };
00253
00254 static pthread_t netthreadid = AST_PTHREADT_NULL;
00255 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00256 AST_MUTEX_DEFINE_STATIC(sched_lock);
00257 static ast_cond_t sched_cond;
00258
00259 enum iax2_state {
00260 IAX_STATE_STARTED = (1 << 0),
00261 IAX_STATE_AUTHENTICATED = (1 << 1),
00262 IAX_STATE_TBD = (1 << 2),
00263 };
00264
00265 struct iax2_context {
00266 char context[AST_MAX_CONTEXT];
00267 struct iax2_context *next;
00268 };
00269
00270 enum iax2_flags {
00271 IAX_HASCALLERID = (1 << 0),
00272 IAX_DELME = (1 << 1),
00273 IAX_TEMPONLY = (1 << 2),
00274 IAX_TRUNK = (1 << 3),
00275 IAX_NOTRANSFER = (1 << 4),
00276 IAX_USEJITTERBUF = (1 << 5),
00277 IAX_DYNAMIC = (1 << 6),
00278 IAX_SENDANI = (1 << 7),
00279
00280 IAX_ALREADYGONE = (1 << 9),
00281 IAX_PROVISION = (1 << 10),
00282 IAX_QUELCH = (1 << 11),
00283 IAX_ENCRYPTED = (1 << 12),
00284 IAX_KEYPOPULATED = (1 << 13),
00285 IAX_CODEC_USER_FIRST = (1 << 14),
00286 IAX_CODEC_NOPREFS = (1 << 15),
00287 IAX_CODEC_NOCAP = (1 << 16),
00288 IAX_RTCACHEFRIENDS = (1 << 17),
00289 IAX_RTUPDATE = (1 << 18),
00290 IAX_RTAUTOCLEAR = (1 << 19),
00291 IAX_FORCEJITTERBUF = (1 << 20),
00292 IAX_RTIGNOREREGEXPIRE = (1 << 21),
00293 IAX_TRUNKTIMESTAMPS = (1 << 22),
00294 IAX_TRANSFERMEDIA = (1 << 23),
00295 IAX_MAXAUTHREQ = (1 << 24),
00296 IAX_DELAYPBXSTART = (1 << 25),
00297
00298
00299 IAX_ALLOWFWDOWNLOAD = (1 << 26),
00300 IAX_SHRINKCALLERID = (1 << 27),
00301 };
00302
00303 static int global_rtautoclear = 120;
00304
00305 static int reload_config(void);
00306
00307
00308
00309
00310 enum calltoken_peer_enum {
00311
00312 CALLTOKEN_DEFAULT = 0,
00313
00314 CALLTOKEN_YES = 1,
00315
00316
00317 CALLTOKEN_AUTO = 2,
00318
00319 CALLTOKEN_NO = 3,
00320 };
00321
00322 struct iax2_user {
00323 AST_DECLARE_STRING_FIELDS(
00324 AST_STRING_FIELD(name);
00325 AST_STRING_FIELD(secret);
00326 AST_STRING_FIELD(dbsecret);
00327 AST_STRING_FIELD(accountcode);
00328 AST_STRING_FIELD(mohinterpret);
00329 AST_STRING_FIELD(mohsuggest);
00330 AST_STRING_FIELD(inkeys);
00331 AST_STRING_FIELD(language);
00332 AST_STRING_FIELD(cid_num);
00333 AST_STRING_FIELD(cid_name);
00334 AST_STRING_FIELD(parkinglot);
00335 );
00336
00337 int authmethods;
00338 int encmethods;
00339 int amaflags;
00340 int adsi;
00341 unsigned int flags;
00342 int capability;
00343 int maxauthreq;
00344 int curauthreq;
00345 struct ast_codec_pref prefs;
00346 struct ast_ha *ha;
00347 struct iax2_context *contexts;
00348 struct ast_variable *vars;
00349 enum calltoken_peer_enum calltoken_required;
00350 };
00351
00352 struct iax2_peer {
00353 AST_DECLARE_STRING_FIELDS(
00354 AST_STRING_FIELD(name);
00355 AST_STRING_FIELD(username);
00356 AST_STRING_FIELD(secret);
00357 AST_STRING_FIELD(dbsecret);
00358 AST_STRING_FIELD(outkey);
00359
00360 AST_STRING_FIELD(regexten);
00361 AST_STRING_FIELD(context);
00362 AST_STRING_FIELD(peercontext);
00363 AST_STRING_FIELD(mailbox);
00364 AST_STRING_FIELD(mohinterpret);
00365 AST_STRING_FIELD(mohsuggest);
00366 AST_STRING_FIELD(inkeys);
00367
00368 AST_STRING_FIELD(cid_num);
00369 AST_STRING_FIELD(cid_name);
00370 AST_STRING_FIELD(zonetag);
00371 AST_STRING_FIELD(parkinglot);
00372 );
00373 struct ast_codec_pref prefs;
00374 struct ast_dnsmgr_entry *dnsmgr;
00375 struct sockaddr_in addr;
00376 int formats;
00377 int sockfd;
00378 struct in_addr mask;
00379 int adsi;
00380 unsigned int flags;
00381
00382
00383 struct sockaddr_in defaddr;
00384 int authmethods;
00385 int encmethods;
00386
00387 int expire;
00388 int expiry;
00389 int capability;
00390
00391
00392 int callno;
00393 int pokeexpire;
00394 int lastms;
00395 int maxms;
00396
00397 int pokefreqok;
00398 int pokefreqnotok;
00399 int historicms;
00400 int smoothing;
00401 uint16_t maxcallno;
00402
00403 struct ast_event_sub *mwi_event_sub;
00404
00405 struct ast_ha *ha;
00406 enum calltoken_peer_enum calltoken_required;
00407 };
00408
00409 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00410
00411 struct iax2_trunk_peer {
00412 ast_mutex_t lock;
00413 int sockfd;
00414 struct sockaddr_in addr;
00415 struct timeval txtrunktime;
00416 struct timeval rxtrunktime;
00417 struct timeval lasttxtime;
00418 struct timeval trunkact;
00419 unsigned int lastsent;
00420
00421 unsigned char *trunkdata;
00422 unsigned int trunkdatalen;
00423 unsigned int trunkdataalloc;
00424 int trunkmaxmtu;
00425 int trunkerror;
00426 int calls;
00427 AST_LIST_ENTRY(iax2_trunk_peer) list;
00428 };
00429
00430 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00431
00432 struct iax_firmware {
00433 AST_LIST_ENTRY(iax_firmware) list;
00434 int fd;
00435 int mmaplen;
00436 int dead;
00437 struct ast_iax2_firmware_header *fwh;
00438 unsigned char *buf;
00439 };
00440
00441 enum iax_reg_state {
00442 REG_STATE_UNREGISTERED = 0,
00443 REG_STATE_REGSENT,
00444 REG_STATE_AUTHSENT,
00445 REG_STATE_REGISTERED,
00446 REG_STATE_REJECTED,
00447 REG_STATE_TIMEOUT,
00448 REG_STATE_NOAUTH
00449 };
00450
00451 enum iax_transfer_state {
00452 TRANSFER_NONE = 0,
00453 TRANSFER_BEGIN,
00454 TRANSFER_READY,
00455 TRANSFER_RELEASED,
00456 TRANSFER_PASSTHROUGH,
00457 TRANSFER_MBEGIN,
00458 TRANSFER_MREADY,
00459 TRANSFER_MRELEASED,
00460 TRANSFER_MPASSTHROUGH,
00461 TRANSFER_MEDIA,
00462 TRANSFER_MEDIAPASS
00463 };
00464
00465 struct iax2_registry {
00466 struct sockaddr_in addr;
00467 char username[80];
00468 char secret[80];
00469 int expire;
00470 int refresh;
00471 enum iax_reg_state regstate;
00472 int messages;
00473 int callno;
00474 struct sockaddr_in us;
00475 struct ast_dnsmgr_entry *dnsmgr;
00476 AST_LIST_ENTRY(iax2_registry) entry;
00477 };
00478
00479 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00480
00481
00482 #define MIN_RETRY_TIME 100
00483 #define MAX_RETRY_TIME 10000
00484
00485 #define MAX_JITTER_BUFFER 50
00486 #define MIN_JITTER_BUFFER 10
00487
00488 #define DEFAULT_TRUNKDATA 640 * 10
00489
00490 #define MAX_TIMESTAMP_SKEW 160
00491
00492
00493 #define TS_GAP_FOR_JB_RESYNC 5000
00494
00495
00496 #define MARK_IAX_SUBCLASS_TX 0x8000
00497
00498 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00499 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00500 static int iaxdynamicthreadcount = 0;
00501 static int iaxdynamicthreadnum = 0;
00502 static int iaxactivethreadcount = 0;
00503
00504 struct iax_rr {
00505 int jitter;
00506 int losspct;
00507 int losscnt;
00508 int packets;
00509 int delay;
00510 int dropped;
00511 int ooo;
00512 };
00513
00514 struct iax2_pvt_ref;
00515
00516 struct chan_iax2_pvt {
00517
00518 int sockfd;
00519
00520 int voiceformat;
00521
00522 int videoformat;
00523
00524 int svoiceformat;
00525
00526 int svideoformat;
00527
00528 int capability;
00529
00530 unsigned int last;
00531
00532 unsigned int lastsent;
00533
00534 unsigned int lastvsent;
00535
00536 unsigned int nextpred;
00537
00538 int first_iax_message;
00539
00540 int last_iax_message;
00541
00542 unsigned int notsilenttx:1;
00543
00544 unsigned int pingtime;
00545
00546 int maxtime;
00547
00548 struct sockaddr_in addr;
00549
00550 struct ast_codec_pref prefs;
00551
00552 struct ast_codec_pref rprefs;
00553
00554 unsigned short callno;
00555
00556 struct callno_entry *callno_entry;
00557
00558 unsigned short peercallno;
00559
00560
00561
00562 int chosenformat;
00563
00564 int peerformat;
00565
00566 int peercapability;
00567
00568 struct timeval offset;
00569
00570 struct timeval rxcore;
00571
00572 jitterbuf *jb;
00573
00574 int jbid;
00575
00576 int lag;
00577
00578 int error;
00579
00580 struct ast_channel *owner;
00581
00582 struct ast_flags state;
00583
00584 int expiry;
00585
00586 unsigned char oseqno;
00587
00588 unsigned char rseqno;
00589
00590 unsigned char iseqno;
00591
00592 unsigned char aseqno;
00593
00594 AST_DECLARE_STRING_FIELDS(
00595
00596 AST_STRING_FIELD(peer);
00597
00598 AST_STRING_FIELD(context);
00599
00600 AST_STRING_FIELD(cid_num);
00601 AST_STRING_FIELD(cid_name);
00602
00603 AST_STRING_FIELD(ani);
00604
00605 AST_STRING_FIELD(dnid);
00606
00607 AST_STRING_FIELD(rdnis);
00608
00609 AST_STRING_FIELD(exten);
00610
00611 AST_STRING_FIELD(username);
00612
00613 AST_STRING_FIELD(secret);
00614
00615 AST_STRING_FIELD(challenge);
00616
00617 AST_STRING_FIELD(inkeys);
00618
00619 AST_STRING_FIELD(outkey);
00620
00621 AST_STRING_FIELD(language);
00622
00623 AST_STRING_FIELD(host);
00624
00625 AST_STRING_FIELD(dproot);
00626 AST_STRING_FIELD(accountcode);
00627 AST_STRING_FIELD(mohinterpret);
00628 AST_STRING_FIELD(mohsuggest);
00629
00630 AST_STRING_FIELD(osptoken);
00631
00632 AST_STRING_FIELD(parkinglot);
00633 );
00634
00635 int authrej;
00636
00637 int authmethods;
00638
00639 int encmethods;
00640
00641 ast_aes_encrypt_key ecx;
00642
00643 ast_aes_decrypt_key mydcx;
00644
00645 ast_aes_decrypt_key dcx;
00646
00647
00648 int keyrotateid;
00649
00650 unsigned char semirand[32];
00651
00652 struct iax2_registry *reg;
00653
00654 struct iax2_peer *peerpoke;
00655
00656 unsigned int flags;
00657 int adsi;
00658
00659
00660 enum iax_transfer_state transferring;
00661
00662 int transferid;
00663
00664 struct sockaddr_in transfer;
00665
00666 unsigned short transfercallno;
00667
00668 ast_aes_encrypt_key tdcx;
00669
00670
00671 int peeradsicpe;
00672
00673
00674 unsigned short bridgecallno;
00675
00676 int pingid;
00677 int lagid;
00678 int autoid;
00679 int authid;
00680 int authfail;
00681 int initid;
00682 int calling_ton;
00683 int calling_tns;
00684 int calling_pres;
00685 int amaflags;
00686 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00687
00688 struct ast_variable *vars;
00689
00690 struct ast_variable *iaxvars;
00691
00692 struct iax_rr remote_rr;
00693
00694 int min;
00695
00696 int frames_dropped;
00697
00698 int frames_received;
00699
00700 unsigned char calltoken_ie_len;
00701
00702 char hold_signaling;
00703
00704 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00705 };
00706
00707 struct signaling_queue_entry {
00708 struct ast_frame f;
00709 AST_LIST_ENTRY(signaling_queue_entry) next;
00710 };
00711
00712
00713 static struct ao2_container *callno_pool;
00714
00715
00716 static struct ao2_container *callno_pool_trunk;
00717
00718 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00719
00720
00721
00722
00723
00724
00725
00726
00727 static AST_LIST_HEAD_STATIC(frame_queue, iax_frame);
00728
00729 static int randomcalltokendata;
00730
00731 static const time_t MAX_CALLTOKEN_DELAY = 10;
00732
00733
00734
00735
00736
00737
00738
00739
00740 #ifdef LOW_MEMORY
00741 #define MAX_PEER_BUCKETS 17
00742 #else
00743 #define MAX_PEER_BUCKETS 563
00744 #endif
00745 static struct ao2_container *peers;
00746
00747 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00748 static struct ao2_container *users;
00749
00750
00751 static struct ao2_container *peercnts;
00752
00753
00754 static struct ao2_container *callno_limits;
00755
00756
00757 static struct ao2_container *calltoken_ignores;
00758
00759 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00760
00761 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00762
00763 static uint16_t global_maxcallno;
00764
00765
00766 static uint16_t global_maxcallno_nonval;
00767
00768 static uint16_t total_nonval_callno_used = 0;
00769
00770
00771
00772 struct peercnt {
00773
00774 unsigned long addr;
00775
00776 uint16_t cur;
00777
00778 uint16_t limit;
00779
00780
00781 unsigned char reg;
00782 };
00783
00784
00785 struct addr_range {
00786
00787 struct ast_ha ha;
00788
00789 uint16_t limit;
00790
00791 unsigned char delme;
00792 };
00793
00794 struct callno_entry {
00795
00796 uint16_t callno;
00797
00798 unsigned char validated;
00799 };
00800
00801 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00802
00803 enum {
00804
00805 CACHE_FLAG_EXISTS = (1 << 0),
00806
00807 CACHE_FLAG_NONEXISTENT = (1 << 1),
00808
00809 CACHE_FLAG_CANEXIST = (1 << 2),
00810
00811 CACHE_FLAG_PENDING = (1 << 3),
00812
00813 CACHE_FLAG_TIMEOUT = (1 << 4),
00814
00815 CACHE_FLAG_TRANSMITTED = (1 << 5),
00816
00817 CACHE_FLAG_UNKNOWN = (1 << 6),
00818
00819 CACHE_FLAG_MATCHMORE = (1 << 7),
00820 };
00821
00822 struct iax2_dpcache {
00823 char peercontext[AST_MAX_CONTEXT];
00824 char exten[AST_MAX_EXTENSION];
00825 struct timeval orig;
00826 struct timeval expiry;
00827 int flags;
00828 unsigned short callno;
00829 int waiters[256];
00830 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00831 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00832 };
00833
00834 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00835
00836 static void reg_source_db(struct iax2_peer *p);
00837 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00838 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00839
00840 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00841 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state);
00842 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00843
00844 enum iax2_thread_iostate {
00845 IAX_IOSTATE_IDLE,
00846 IAX_IOSTATE_READY,
00847 IAX_IOSTATE_PROCESSING,
00848 IAX_IOSTATE_SCHEDREADY,
00849 };
00850
00851 enum iax2_thread_type {
00852 IAX_THREAD_TYPE_POOL,
00853 IAX_THREAD_TYPE_DYNAMIC,
00854 };
00855
00856 struct iax2_pkt_buf {
00857 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00858 size_t len;
00859 unsigned char buf[1];
00860 };
00861
00862 struct iax2_thread {
00863 AST_LIST_ENTRY(iax2_thread) list;
00864 enum iax2_thread_type type;
00865 enum iax2_thread_iostate iostate;
00866 #ifdef SCHED_MULTITHREADED
00867 void (*schedfunc)(const void *);
00868 const void *scheddata;
00869 #endif
00870 #ifdef DEBUG_SCHED_MULTITHREAD
00871 char curfunc[80];
00872 #endif
00873 int actions;
00874 pthread_t threadid;
00875 int threadnum;
00876 struct sockaddr_in iosin;
00877 unsigned char readbuf[4096];
00878 unsigned char *buf;
00879 ssize_t buf_len;
00880 size_t buf_size;
00881 int iofd;
00882 time_t checktime;
00883 ast_mutex_t lock;
00884 ast_cond_t cond;
00885 ast_mutex_t init_lock;
00886 ast_cond_t init_cond;
00887
00888
00889
00890
00891 struct {
00892 unsigned short callno;
00893 struct sockaddr_in sin;
00894 unsigned char type;
00895 unsigned char csub;
00896 } ffinfo;
00897
00898
00899
00900 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00901 };
00902
00903
00904 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00905 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00906 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00907
00908 static void *iax2_process_thread(void *data);
00909 static void iax2_destroy(int callno);
00910
00911 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00912 {
00913 ast_mutex_lock(lock);
00914 ast_cond_signal(cond);
00915 ast_mutex_unlock(lock);
00916 }
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS + 1];
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 static struct ao2_container *iax_peercallno_pvts;
00938
00939
00940
00941
00942
00943
00944
00945
00946 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00947
00948
00949
00950
00951
00952
00953 static struct ao2_container *iax_transfercallno_pvts;
00954
00955
00956
00957 #define TRUNK_CALL_START IAX_MAX_CALLS / 2
00958
00959
00960 static struct sockaddr_in debugaddr;
00961
00962 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
00963 {
00964 if (iaxdebug ||
00965 (sin && debugaddr.sin_addr.s_addr &&
00966 (!ntohs(debugaddr.sin_port) ||
00967 debugaddr.sin_port == sin->sin_port) &&
00968 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
00969 if (iaxdebug) {
00970 iax_showframe(f, fhi, rx, sin, datalen);
00971 } else {
00972 iaxdebug = 1;
00973 iax_showframe(f, fhi, rx, sin, datalen);
00974 iaxdebug = 0;
00975 }
00976 }
00977 }
00978
00979 static void iax_debug_output(const char *data)
00980 {
00981 if (iaxdebug)
00982 ast_verbose("%s", data);
00983 }
00984
00985 static void iax_error_output(const char *data)
00986 {
00987 ast_log(LOG_WARNING, "%s", data);
00988 }
00989
00990 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
00991 {
00992 va_list args;
00993 char buf[1024];
00994
00995 va_start(args, fmt);
00996 vsnprintf(buf, sizeof(buf), fmt, args);
00997 va_end(args);
00998
00999 ast_log(LOG_ERROR, "%s", buf);
01000 }
01001
01002 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01003 {
01004 va_list args;
01005 char buf[1024];
01006
01007 va_start(args, fmt);
01008 vsnprintf(buf, sizeof(buf), fmt, args);
01009 va_end(args);
01010
01011 ast_log(LOG_WARNING, "%s", buf);
01012 }
01013
01014 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01015 {
01016 va_list args;
01017 char buf[1024];
01018
01019 va_start(args, fmt);
01020 vsnprintf(buf, sizeof(buf), fmt, args);
01021 va_end(args);
01022
01023 ast_verbose("%s", buf);
01024 }
01025
01026 static int maxtrunkcall = TRUNK_CALL_START;
01027 static int maxnontrunkcall = 1;
01028
01029 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);
01030 static int expire_registry(const void *data);
01031 static int iax2_answer(struct ast_channel *c);
01032 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01033 static int iax2_devicestate(void *data);
01034 static int iax2_digit_begin(struct ast_channel *c, char digit);
01035 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01036 static int iax2_do_register(struct iax2_registry *reg);
01037 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01038 static int iax2_hangup(struct ast_channel *c);
01039 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01040 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01041 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
01042 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01043 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01044 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01045 static int iax2_sendtext(struct ast_channel *c, const char *text);
01046 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01047 static int iax2_transfer(struct ast_channel *c, const char *dest);
01048 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01049 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01050 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01051 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01052 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01053 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01054 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01055 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
01056 static struct ast_frame *iax2_read(struct ast_channel *c);
01057 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01058 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01059 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
01060 static void *iax2_dup_variable_datastore(void *);
01061 static void prune_peers(void);
01062 static void prune_users(void);
01063 static void iax2_free_variable_datastore(void *);
01064
01065 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01066 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01067 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01068 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01069 static void build_rand_pad(unsigned char *buf, ssize_t len);
01070 static struct callno_entry *get_unused_callno(int trunk, int validated);
01071 static int replace_callno(const void *obj);
01072 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01073
01074 static const struct ast_channel_tech iax2_tech = {
01075 .type = "IAX2",
01076 .description = tdesc,
01077 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01078 .properties = AST_CHAN_TP_WANTSJITTER,
01079 .requester = iax2_request,
01080 .devicestate = iax2_devicestate,
01081 .send_digit_begin = iax2_digit_begin,
01082 .send_digit_end = iax2_digit_end,
01083 .send_text = iax2_sendtext,
01084 .send_image = iax2_sendimage,
01085 .send_html = iax2_sendhtml,
01086 .call = iax2_call,
01087 .hangup = iax2_hangup,
01088 .answer = iax2_answer,
01089 .read = iax2_read,
01090 .write = iax2_write,
01091 .write_video = iax2_write,
01092 .indicate = iax2_indicate,
01093 .setoption = iax2_setoption,
01094 .bridge = iax2_bridge,
01095 .transfer = iax2_transfer,
01096 .fixup = iax2_fixup,
01097 .func_channel_read = acf_channel_read,
01098 };
01099
01100 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01101 {
01102
01103
01104
01105 }
01106
01107
01108
01109 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01110 {
01111 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01112 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01113 pvt->owner ? pvt->owner->name : "",
01114 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01115 }
01116
01117
01118 static struct ast_datastore_info iax2_variable_datastore_info = {
01119 .type = "IAX2_VARIABLE",
01120 .duplicate = iax2_dup_variable_datastore,
01121 .destroy = iax2_free_variable_datastore,
01122 };
01123
01124 static void *iax2_dup_variable_datastore(void *old)
01125 {
01126 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01127 struct ast_var_t *oldvar, *newvar;
01128
01129 newlist = ast_calloc(sizeof(*newlist), 1);
01130 if (!newlist) {
01131 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01132 return NULL;
01133 }
01134
01135 AST_LIST_HEAD_INIT(newlist);
01136 AST_LIST_LOCK(oldlist);
01137 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01138 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01139 if (newvar)
01140 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01141 else
01142 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01143 }
01144 AST_LIST_UNLOCK(oldlist);
01145 return newlist;
01146 }
01147
01148 static void iax2_free_variable_datastore(void *old)
01149 {
01150 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01151 struct ast_var_t *oldvar;
01152
01153 AST_LIST_LOCK(oldlist);
01154 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01155 ast_free(oldvar);
01156 }
01157 AST_LIST_UNLOCK(oldlist);
01158 AST_LIST_HEAD_DESTROY(oldlist);
01159 ast_free(oldlist);
01160 }
01161
01162
01163
01164
01165
01166 static void insert_idle_thread(struct iax2_thread *thread)
01167 {
01168 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01169 AST_LIST_LOCK(&dynamic_list);
01170 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01171 AST_LIST_UNLOCK(&dynamic_list);
01172 } else {
01173 AST_LIST_LOCK(&idle_list);
01174 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01175 AST_LIST_UNLOCK(&idle_list);
01176 }
01177
01178 return;
01179 }
01180
01181 static struct iax2_thread *find_idle_thread(void)
01182 {
01183 struct iax2_thread *thread = NULL;
01184
01185
01186 AST_LIST_LOCK(&idle_list);
01187 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01188 AST_LIST_UNLOCK(&idle_list);
01189
01190
01191 if (thread) {
01192 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01193 return thread;
01194 }
01195
01196
01197 AST_LIST_LOCK(&dynamic_list);
01198 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01199 AST_LIST_UNLOCK(&dynamic_list);
01200
01201
01202 if (thread) {
01203 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01204 return thread;
01205 }
01206
01207
01208 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01209 return NULL;
01210
01211
01212 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01213 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01214 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01215
01216
01217 ast_mutex_init(&thread->lock);
01218 ast_cond_init(&thread->cond, NULL);
01219 ast_mutex_init(&thread->init_lock);
01220 ast_cond_init(&thread->init_cond, NULL);
01221 ast_mutex_lock(&thread->init_lock);
01222
01223
01224 if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01225 ast_cond_destroy(&thread->cond);
01226 ast_mutex_destroy(&thread->lock);
01227 ast_free(thread);
01228 return NULL;
01229 }
01230
01231
01232
01233 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01234
01235
01236 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01237
01238
01239 ast_mutex_unlock(&thread->init_lock);
01240
01241 return thread;
01242 }
01243
01244 #ifdef SCHED_MULTITHREADED
01245 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01246 {
01247 struct iax2_thread *thread = NULL;
01248 static time_t lasterror;
01249 static time_t t;
01250
01251 thread = find_idle_thread();
01252
01253 if (thread != NULL) {
01254 thread->schedfunc = func;
01255 thread->scheddata = data;
01256 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01257 #ifdef DEBUG_SCHED_MULTITHREAD
01258 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01259 #endif
01260 signal_condition(&thread->lock, &thread->cond);
01261 return 0;
01262 }
01263 time(&t);
01264 if (t != lasterror)
01265 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01266 lasterror = t;
01267
01268 return -1;
01269 }
01270 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01271 #endif
01272
01273 static int iax2_sched_replace(int id, struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01274 {
01275 AST_SCHED_REPLACE(id, con, when, callback, data);
01276 signal_condition(&sched_lock, &sched_cond);
01277
01278 return id;
01279 }
01280
01281 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01282 {
01283 int res;
01284
01285 res = ast_sched_add(con, when, callback, data);
01286 signal_condition(&sched_lock, &sched_cond);
01287
01288 return res;
01289 }
01290
01291 static int send_ping(const void *data);
01292
01293 static void __send_ping(const void *data)
01294 {
01295 int callno = (long) data;
01296
01297 ast_mutex_lock(&iaxsl[callno]);
01298
01299 if (iaxs[callno]) {
01300 if (iaxs[callno]->peercallno) {
01301 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01302 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01303 } else {
01304
01305 iaxs[callno]->pingid = -1;
01306 }
01307 } else {
01308 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01309 }
01310
01311 ast_mutex_unlock(&iaxsl[callno]);
01312 }
01313
01314 static int send_ping(const void *data)
01315 {
01316 #ifdef SCHED_MULTITHREADED
01317 if (schedule_action(__send_ping, data))
01318 #endif
01319 __send_ping(data);
01320
01321 return 0;
01322 }
01323
01324 static int get_encrypt_methods(const char *s)
01325 {
01326 int e;
01327 if (!strcasecmp(s, "aes128"))
01328 e = IAX_ENCRYPT_AES128;
01329 else if (ast_true(s))
01330 e = IAX_ENCRYPT_AES128;
01331 else
01332 e = 0;
01333 return e;
01334 }
01335
01336 static int send_lagrq(const void *data);
01337
01338 static void __send_lagrq(const void *data)
01339 {
01340 int callno = (long) data;
01341
01342 ast_mutex_lock(&iaxsl[callno]);
01343
01344 if (iaxs[callno]) {
01345 if (iaxs[callno]->peercallno) {
01346 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01347 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01348 } else {
01349
01350 iaxs[callno]->lagid = -1;
01351 }
01352 } else {
01353 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01354 }
01355
01356 ast_mutex_unlock(&iaxsl[callno]);
01357 }
01358
01359 static int send_lagrq(const void *data)
01360 {
01361 #ifdef SCHED_MULTITHREADED
01362 if (schedule_action(__send_lagrq, data))
01363 #endif
01364 __send_lagrq(data);
01365
01366 return 0;
01367 }
01368
01369 static unsigned char compress_subclass(int subclass)
01370 {
01371 int x;
01372 int power=-1;
01373
01374 if (subclass < IAX_FLAG_SC_LOG)
01375 return subclass;
01376
01377 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01378 if (subclass & (1 << x)) {
01379 if (power > -1) {
01380 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01381 return 0;
01382 } else
01383 power = x;
01384 }
01385 }
01386 return power | IAX_FLAG_SC_LOG;
01387 }
01388
01389 static int uncompress_subclass(unsigned char csub)
01390 {
01391
01392 if (csub & IAX_FLAG_SC_LOG) {
01393
01394 if (csub == 0xff)
01395 return -1;
01396 else
01397 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01398 }
01399 else
01400 return csub;
01401 }
01402
01403
01404
01405
01406 static int peer_hash_cb(const void *obj, const int flags)
01407 {
01408 const struct iax2_peer *peer = obj;
01409
01410 return ast_str_hash(peer->name);
01411 }
01412
01413
01414
01415
01416 static int peer_cmp_cb(void *obj, void *arg, int flags)
01417 {
01418 struct iax2_peer *peer = obj, *peer2 = arg;
01419
01420 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01421 }
01422
01423
01424
01425
01426 static int user_hash_cb(const void *obj, const int flags)
01427 {
01428 const struct iax2_user *user = obj;
01429
01430 return ast_str_hash(user->name);
01431 }
01432
01433
01434
01435
01436 static int user_cmp_cb(void *obj, void *arg, int flags)
01437 {
01438 struct iax2_user *user = obj, *user2 = arg;
01439
01440 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01441 }
01442
01443
01444
01445
01446
01447 static struct iax2_peer *find_peer(const char *name, int realtime)
01448 {
01449 struct iax2_peer *peer = NULL;
01450 struct iax2_peer tmp_peer = {
01451 .name = name,
01452 };
01453
01454 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01455
01456
01457 if(!peer && realtime)
01458 peer = realtime_peer(name, NULL);
01459
01460 return peer;
01461 }
01462
01463 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01464 {
01465 ao2_ref(peer, +1);
01466 return peer;
01467 }
01468
01469 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01470 {
01471 ao2_ref(peer, -1);
01472 return NULL;
01473 }
01474
01475 static struct iax2_user *find_user(const char *name)
01476 {
01477 struct iax2_user tmp_user = {
01478 .name = name,
01479 };
01480
01481 return ao2_find(users, &tmp_user, OBJ_POINTER);
01482 }
01483 static inline struct iax2_user *user_ref(struct iax2_user *user)
01484 {
01485 ao2_ref(user, +1);
01486 return user;
01487 }
01488
01489 static inline struct iax2_user *user_unref(struct iax2_user *user)
01490 {
01491 ao2_ref(user, -1);
01492 return NULL;
01493 }
01494
01495 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01496 {
01497 struct iax2_peer *peer = NULL;
01498 int res = 0;
01499 struct ao2_iterator i;
01500
01501 i = ao2_iterator_init(peers, 0);
01502 while ((peer = ao2_iterator_next(&i))) {
01503 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01504 (peer->addr.sin_port == sin.sin_port)) {
01505 ast_copy_string(host, peer->name, len);
01506 peer_unref(peer);
01507 res = 1;
01508 break;
01509 }
01510 peer_unref(peer);
01511 }
01512 ao2_iterator_destroy(&i);
01513
01514 if (!peer) {
01515 peer = realtime_peer(NULL, &sin);
01516 if (peer) {
01517 ast_copy_string(host, peer->name, len);
01518 peer_unref(peer);
01519 res = 1;
01520 }
01521 }
01522
01523 return res;
01524 }
01525
01526
01527
01528 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01529 {
01530
01531 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01532 struct iax2_user *user;
01533 struct iax2_user tmp_user = {
01534 .name = pvt->username,
01535 };
01536
01537 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01538 if (user) {
01539 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01540 user_unref(user);
01541 }
01542
01543 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01544 }
01545
01546 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]);
01547 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]);
01548 AST_SCHED_DEL(sched, pvt->autoid);
01549 AST_SCHED_DEL(sched, pvt->authid);
01550 AST_SCHED_DEL(sched, pvt->initid);
01551 AST_SCHED_DEL(sched, pvt->jbid);
01552 AST_SCHED_DEL(sched, pvt->keyrotateid);
01553 }
01554
01555 static void iax2_frame_free(struct iax_frame *fr)
01556 {
01557 AST_SCHED_DEL(sched, fr->retrans);
01558 iax_frame_free(fr);
01559 }
01560
01561 static int scheduled_destroy(const void *vid)
01562 {
01563 unsigned short callno = PTR_TO_CALLNO(vid);
01564 ast_mutex_lock(&iaxsl[callno]);
01565 if (iaxs[callno]) {
01566 if (option_debug) {
01567 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01568 }
01569 iax2_destroy(callno);
01570 }
01571 ast_mutex_unlock(&iaxsl[callno]);
01572 return 0;
01573 }
01574
01575 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01576 {
01577 ast_free(s->f.data.ptr);
01578 ast_free(s);
01579 }
01580
01581
01582
01583 static void send_signaling(struct chan_iax2_pvt *pvt)
01584 {
01585 struct signaling_queue_entry *s = NULL;
01586
01587 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01588 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01589 free_signaling_queue_entry(s);
01590 }
01591 pvt->hold_signaling = 0;
01592 }
01593
01594
01595
01596 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01597 {
01598 struct signaling_queue_entry *new;
01599
01600 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01601 return 1;
01602 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01603 return -1;
01604 }
01605
01606 memcpy(&new->f, f, sizeof(new->f));
01607
01608 if (new->f.datalen) {
01609 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01610 free_signaling_queue_entry(new);
01611 return -1;
01612 }
01613 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01614 }
01615 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01616
01617 return 0;
01618 }
01619
01620 static void pvt_destructor(void *obj)
01621 {
01622 struct chan_iax2_pvt *pvt = obj;
01623 struct iax_frame *cur = NULL;
01624 struct signaling_queue_entry *s = NULL;
01625
01626 ast_mutex_lock(&iaxsl[pvt->callno]);
01627 iax2_destroy_helper(pvt);
01628 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01629 pvt->callno_entry = NULL;
01630 ast_mutex_unlock(&iaxsl[pvt->callno]);
01631
01632
01633 ast_set_flag(pvt, IAX_ALREADYGONE);
01634
01635 AST_LIST_LOCK(&frame_queue);
01636 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01637
01638 if (cur->callno == pvt->callno) {
01639 cur->retries = -1;
01640 }
01641 }
01642 AST_LIST_UNLOCK(&frame_queue);
01643
01644 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01645 free_signaling_queue_entry(s);
01646 }
01647
01648 if (pvt->reg) {
01649 pvt->reg->callno = 0;
01650 }
01651
01652 if (!pvt->owner) {
01653 jb_frame frame;
01654 if (pvt->vars) {
01655 ast_variables_destroy(pvt->vars);
01656 pvt->vars = NULL;
01657 }
01658
01659 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01660 iax2_frame_free(frame.data);
01661 }
01662
01663 jb_destroy(pvt->jb);
01664 ast_string_field_free_memory(pvt);
01665 }
01666 }
01667
01668 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01669 {
01670 struct chan_iax2_pvt *tmp;
01671 jb_conf jbconf;
01672
01673 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01674 return NULL;
01675 }
01676
01677 if (ast_string_field_init(tmp, 32)) {
01678 ao2_ref(tmp, -1);
01679 tmp = NULL;
01680 return NULL;
01681 }
01682
01683 tmp->prefs = prefs;
01684 tmp->pingid = -1;
01685 tmp->lagid = -1;
01686 tmp->autoid = -1;
01687 tmp->authid = -1;
01688 tmp->initid = -1;
01689 tmp->keyrotateid = -1;
01690
01691 ast_string_field_set(tmp,exten, "s");
01692 ast_string_field_set(tmp,host, host);
01693
01694 tmp->jb = jb_new();
01695 tmp->jbid = -1;
01696 jbconf.max_jitterbuf = maxjitterbuffer;
01697 jbconf.resync_threshold = resyncthreshold;
01698 jbconf.max_contig_interp = maxjitterinterps;
01699 jbconf.target_extra = jittertargetextra;
01700 jb_setconf(tmp->jb,&jbconf);
01701
01702 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01703
01704 tmp->hold_signaling = 1;
01705 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01706
01707 return tmp;
01708 }
01709
01710 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01711 {
01712 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01713 if (new) {
01714 size_t afdatalen = new->afdatalen;
01715 memcpy(new, fr, sizeof(*new));
01716 iax_frame_wrap(new, &fr->af);
01717 new->afdatalen = afdatalen;
01718 new->data = NULL;
01719 new->datalen = 0;
01720 new->direction = DIRECTION_INGRESS;
01721 new->retrans = -1;
01722 }
01723 return new;
01724 }
01725
01726
01727 enum {
01728
01729 NEW_PREVENT = 0,
01730
01731 NEW_ALLOW = 1,
01732
01733 NEW_FORCE = 2,
01734
01735
01736 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01737 };
01738
01739 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01740 {
01741 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01742 (cur->addr.sin_port == sin->sin_port)) {
01743
01744 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01745 (check_dcallno ? dcallno == cur->callno : 1) ) {
01746
01747 return 1;
01748 }
01749 }
01750 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01751 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01752
01753 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01754 return 1;
01755 }
01756 return 0;
01757 }
01758
01759 static void update_max_trunk(void)
01760 {
01761 int max = TRUNK_CALL_START;
01762 int x;
01763
01764
01765 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01766 if (iaxs[x]) {
01767 max = x + 1;
01768 }
01769 }
01770
01771 maxtrunkcall = max;
01772 if (iaxdebug)
01773 ast_debug(1, "New max trunk callno is %d\n", max);
01774 }
01775
01776 static void update_max_nontrunk(void)
01777 {
01778 int max = 1;
01779 int x;
01780
01781 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01782 if (iaxs[x])
01783 max = x + 1;
01784 }
01785 maxnontrunkcall = max;
01786 if (iaxdebug)
01787 ast_debug(1, "New max nontrunk callno is %d\n", max);
01788 }
01789
01790 static int make_trunk(unsigned short callno, int locked)
01791 {
01792 int x;
01793 int res= 0;
01794 struct callno_entry *callno_entry;
01795 if (iaxs[callno]->oseqno) {
01796 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01797 return -1;
01798 }
01799 if (callno & TRUNK_CALL_START) {
01800 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01801 return -1;
01802 }
01803
01804 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
01805 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01806 return -1;
01807 }
01808
01809 x = callno_entry->callno;
01810 ast_mutex_lock(&iaxsl[x]);
01811
01812
01813
01814
01815
01816 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01817 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01818 iaxs[x] = iaxs[callno];
01819 iaxs[x]->callno = x;
01820
01821
01822
01823 if (iaxs[x]->callno_entry) {
01824 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
01825 }
01826 iaxs[x]->callno_entry = callno_entry;
01827
01828 iaxs[callno] = NULL;
01829
01830 iaxs[x]->pingid = iax2_sched_add(sched,
01831 ping_time * 1000, send_ping, (void *)(long)x);
01832 iaxs[x]->lagid = iax2_sched_add(sched,
01833 lagrq_time * 1000, send_lagrq, (void *)(long)x);
01834
01835 if (locked)
01836 ast_mutex_unlock(&iaxsl[callno]);
01837 res = x;
01838 if (!locked)
01839 ast_mutex_unlock(&iaxsl[x]);
01840
01841 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01842
01843 update_max_trunk();
01844 update_max_nontrunk();
01845 return res;
01846 }
01847
01848 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01849 {
01850 if (!pvt->transfercallno) {
01851 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01852 return;
01853 }
01854
01855 ao2_link(iax_transfercallno_pvts, pvt);
01856 }
01857
01858 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01859 {
01860 if (!pvt->transfercallno) {
01861 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01862 return;
01863 }
01864
01865 ao2_unlink(iax_transfercallno_pvts, pvt);
01866 }
01867 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01868 {
01869 if (!pvt->peercallno) {
01870 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01871 return;
01872 }
01873
01874 ao2_link(iax_peercallno_pvts, pvt);
01875 }
01876
01877 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01878 {
01879 if (!pvt->peercallno) {
01880 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01881 return;
01882 }
01883
01884 ao2_unlink(iax_peercallno_pvts, pvt);
01885 }
01886
01887 static int addr_range_delme_cb(void *obj, void *arg, int flags)
01888 {
01889 struct addr_range *lim = obj;
01890 lim->delme = 1;
01891 return 0;
01892 }
01893
01894 static int addr_range_hash_cb(const void *obj, const int flags)
01895 {
01896 const struct addr_range *lim = obj;
01897 return abs((int) lim->ha.netaddr.s_addr);
01898 }
01899
01900 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
01901 {
01902 struct addr_range *lim1 = obj, *lim2 = arg;
01903 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
01904 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
01905 CMP_MATCH | CMP_STOP : 0;
01906 }
01907
01908 static int peercnt_hash_cb(const void *obj, const int flags)
01909 {
01910 const struct peercnt *peercnt = obj;
01911 return abs((int) peercnt->addr);
01912 }
01913
01914 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
01915 {
01916 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
01917 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
01918 }
01919
01920 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
01921 {
01922 struct addr_range *addr_range = obj;
01923 struct sockaddr_in *sin = arg;
01924
01925 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
01926 return CMP_MATCH | CMP_STOP;
01927 }
01928 return 0;
01929 }
01930
01931
01932
01933
01934
01935
01936 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
01937 {
01938 struct addr_range *addr_range;
01939 struct iax2_peer *peer = NULL;
01940 struct iax2_user *user = NULL;
01941
01942 const char *find = S_OR(name, "guest");
01943 int res = 1;
01944 int optional = 0;
01945 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
01946
01947
01948
01949
01950
01951
01952
01953 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
01954 ao2_ref(addr_range, -1);
01955 optional = 1;
01956 }
01957
01958
01959 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
01960 calltoken_required = user->calltoken_required;
01961 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
01962 calltoken_required = user->calltoken_required;
01963 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
01964 calltoken_required = peer->calltoken_required;
01965 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
01966 calltoken_required = peer->calltoken_required;
01967 }
01968
01969 if (peer) {
01970 peer_unref(peer);
01971 }
01972 if (user) {
01973 user_unref(user);
01974 }
01975
01976 ast_debug(1, "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);
01977 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
01978 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
01979 res = 0;
01980 }
01981
01982 return res;
01983 }
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995 static void set_peercnt_limit(struct peercnt *peercnt)
01996 {
01997 uint16_t limit = global_maxcallno;
01998 struct addr_range *addr_range;
01999 struct sockaddr_in sin = {
02000 .sin_addr.s_addr = peercnt->addr,
02001 };
02002
02003
02004 if (peercnt->reg && peercnt->limit) {
02005 return;
02006 }
02007
02008 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02009 limit = addr_range->limit;
02010 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02011 ao2_ref(addr_range, -1);
02012 }
02013
02014 peercnt->limit = limit;
02015 }
02016
02017
02018
02019
02020
02021 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02022 {
02023 struct peercnt *peercnt = obj;
02024
02025 set_peercnt_limit(peercnt);
02026 ast_debug(1, "Reset limits for peercnts table\n");
02027
02028 return 0;
02029 }
02030
02031
02032
02033
02034
02035 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02036 {
02037 struct addr_range *addr_range = obj;
02038
02039 return addr_range->delme ? CMP_MATCH : 0;
02040 }
02041
02042
02043
02044
02045
02046 static void peercnt_modify(unsigned char reg, uint16_t limit, struct sockaddr_in *sin)
02047 {
02048
02049 struct peercnt *peercnt;
02050 struct peercnt tmp = {
02051 .addr = sin->sin_addr.s_addr,
02052 };
02053
02054 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02055 peercnt->reg = reg;
02056 if (limit) {
02057 peercnt->limit = limit;
02058 } else {
02059 set_peercnt_limit(peercnt);
02060 }
02061 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg);
02062 ao2_ref(peercnt, -1);
02063 }
02064 }
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074 static int peercnt_add(struct sockaddr_in *sin)
02075 {
02076 struct peercnt *peercnt;
02077 unsigned long addr = sin->sin_addr.s_addr;
02078 int res = 0;
02079 struct peercnt tmp = {
02080 .addr = addr,
02081 };
02082
02083
02084
02085
02086
02087
02088
02089 ao2_lock(peercnts);
02090 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02091 ao2_lock(peercnt);
02092 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02093 ao2_lock(peercnt);
02094
02095 peercnt->addr = addr;
02096 set_peercnt_limit(peercnt);
02097
02098
02099 ao2_link(peercnts, peercnt);
02100 } else {
02101 ao2_unlock(peercnts);
02102 return -1;
02103 }
02104
02105
02106 if (peercnt->limit > peercnt->cur) {
02107 peercnt->cur++;
02108 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02109 } else {
02110 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02111 res = -1;
02112 }
02113
02114
02115 ao2_unlock(peercnt);
02116 ao2_unlock(peercnts);
02117 ao2_ref(peercnt, -1);
02118
02119 return res;
02120 }
02121
02122
02123
02124
02125
02126 static void peercnt_remove(struct peercnt *peercnt)
02127 {
02128 struct sockaddr_in sin = {
02129 .sin_addr.s_addr = peercnt->addr,
02130 };
02131
02132 if (peercnt) {
02133
02134
02135
02136 ao2_lock(peercnts);
02137 peercnt->cur--;
02138 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02139
02140 if (peercnt->cur == 0) {
02141 ao2_unlink(peercnts, peercnt);
02142 }
02143 ao2_unlock(peercnts);
02144 }
02145 }
02146
02147
02148
02149
02150
02151 static int peercnt_remove_cb(const void *obj)
02152 {
02153 struct peercnt *peercnt = (struct peercnt *) obj;
02154
02155 peercnt_remove(peercnt);
02156 ao2_ref(peercnt, -1);
02157
02158 return 0;
02159 }
02160
02161
02162
02163
02164
02165 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02166 {
02167 struct peercnt *peercnt;
02168 struct peercnt tmp = {
02169 .addr = sin->sin_addr.s_addr,
02170 };
02171
02172 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02173 peercnt_remove(peercnt);
02174 ao2_ref(peercnt, -1);
02175 }
02176 return 0;
02177 }
02178
02179
02180
02181
02182
02183 static void build_callno_limits(struct ast_variable *v)
02184 {
02185 struct addr_range *addr_range = NULL;
02186 struct addr_range tmp;
02187 struct ast_ha *ha;
02188 int limit;
02189 int error;
02190 int found;
02191
02192 for (; v; v = v->next) {
02193 limit = -1;
02194 error = 0;
02195 found = 0;
02196 ha = ast_append_ha("permit", v->name, NULL, &error);
02197
02198
02199 if (error) {
02200 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02201 continue;
02202 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02203 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02204 ast_free_ha(ha);
02205 continue;
02206 }
02207
02208 ast_copy_ha(ha, &tmp.ha);
02209
02210 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02211 ao2_lock(addr_range);
02212 found = 1;
02213 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02214 ast_free_ha(ha);
02215 return;
02216 }
02217
02218
02219 ast_copy_ha(ha, &addr_range->ha);
02220 ast_free_ha(ha);
02221 addr_range->limit = limit;
02222 addr_range->delme = 0;
02223
02224
02225 if (found) {
02226 ao2_unlock(addr_range);
02227 } else {
02228 ao2_link(callno_limits, addr_range);
02229 }
02230 ao2_ref(addr_range, -1);
02231 }
02232 }
02233
02234
02235
02236
02237
02238 static int add_calltoken_ignore(const char *addr)
02239 {
02240 struct addr_range tmp;
02241 struct addr_range *addr_range = NULL;
02242 struct ast_ha *ha = NULL;
02243 int error = 0;
02244
02245 if (ast_strlen_zero(addr)) {
02246 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02247 return -1;
02248 }
02249
02250 ha = ast_append_ha("permit", addr, NULL, &error);
02251
02252
02253 if (error) {
02254 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02255 return -1;
02256 }
02257
02258 ast_copy_ha(ha, &tmp.ha);
02259
02260 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02261 ao2_lock(addr_range);
02262 addr_range->delme = 0;
02263 ao2_unlock(addr_range);
02264 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02265
02266 ast_copy_ha(ha, &addr_range->ha);
02267 ao2_link(calltoken_ignores, addr_range);
02268 } else {
02269 ast_free_ha(ha);
02270 return -1;
02271 }
02272
02273 ast_free_ha(ha);
02274 ao2_ref(addr_range, -1);
02275
02276 return 0;
02277 }
02278
02279 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02280 {
02281 struct ao2_iterator i;
02282 struct peercnt *peercnt;
02283 struct sockaddr_in sin;
02284 int found = 0;
02285
02286 switch (cmd) {
02287 case CLI_INIT:
02288 e->command = "iax2 show callnumber usage";
02289 e->usage =
02290 "Usage: iax2 show callnumber usage <ip address (optional)>\n"
02291 " Shows current ip addresses which are consuming iax2 call numbers\n";
02292 return NULL;
02293 case CLI_GENERATE:
02294 return NULL;
02295 case CLI_HANDLER:
02296 if (a->argc < 4 || a->argc > 5)
02297 return CLI_SHOWUSAGE;
02298
02299 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02300 i = ao2_iterator_init(peercnts, 0);
02301 while ((peercnt = ao2_iterator_next(&i))) {
02302 sin.sin_addr.s_addr = peercnt->addr;
02303 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02304 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02305 found = 1;
02306 break;
02307 } else {
02308 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02309 }
02310 ao2_ref(peercnt, -1);
02311 }
02312 ao2_iterator_destroy(&i);
02313
02314 if (a->argc == 4) {
02315 ast_cli(a->fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
02316 } else if (a->argc == 5 && !found) {
02317 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02318 }
02319
02320 return CLI_SUCCESS;
02321 default:
02322 return NULL;
02323 }
02324 }
02325
02326 static struct callno_entry *get_unused_callno(int trunk, int validated)
02327 {
02328 struct callno_entry *callno_entry = NULL;
02329 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02330 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02331
02332 return NULL;
02333 }
02334
02335
02336
02337 ao2_lock(callno_pool);
02338
02339
02340
02341
02342 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02343 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02344 ao2_unlock(callno_pool);
02345 return NULL;
02346 }
02347
02348
02349
02350 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02351
02352 if (callno_entry) {
02353 callno_entry->validated = validated;
02354 if (!validated) {
02355 total_nonval_callno_used++;
02356 }
02357 }
02358
02359 ao2_unlock(callno_pool);
02360 return callno_entry;
02361 }
02362
02363 static int replace_callno(const void *obj)
02364 {
02365 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02366
02367
02368
02369 ao2_lock(callno_pool);
02370
02371 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02372 total_nonval_callno_used--;
02373 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02374 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02375 }
02376
02377 if (callno_entry->callno < TRUNK_CALL_START) {
02378 ao2_link(callno_pool, callno_entry);
02379 } else {
02380 ao2_link(callno_pool_trunk, callno_entry);
02381 }
02382 ao2_ref(callno_entry, -1);
02383
02384 ao2_unlock(callno_pool);
02385 return 0;
02386 }
02387
02388 static int callno_hash(const void *obj, const int flags)
02389 {
02390 return abs(ast_random());
02391 }
02392
02393 static int create_callno_pools(void)
02394 {
02395 uint16_t i;
02396
02397 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02398 return -1;
02399 }
02400
02401 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02402 return -1;
02403 }
02404
02405
02406 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02407 struct callno_entry *callno_entry;
02408
02409 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02410 return -1;
02411 }
02412
02413 callno_entry->callno = i;
02414
02415 if (i < TRUNK_CALL_START) {
02416 ao2_link(callno_pool, callno_entry);
02417 } else {
02418 ao2_link(callno_pool_trunk, callno_entry);
02419 }
02420
02421 ao2_ref(callno_entry, -1);
02422 }
02423
02424 return 0;
02425 }
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02436 {
02437 int i;
02438 struct peercnt *peercnt;
02439 struct peercnt tmp = {
02440 .addr = sin->sin_addr.s_addr,
02441 };
02442
02443 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02444
02445 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02446 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02447 if (i == -1) {
02448 ao2_ref(peercnt, -1);
02449 }
02450 }
02451
02452 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02453 }
02454
02455
02456
02457
02458
02459
02460
02461
02462 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02463 {
02464 if (frametype != AST_FRAME_IAX) {
02465 return 0;
02466 }
02467 switch (subclass) {
02468 case IAX_COMMAND_NEW:
02469 case IAX_COMMAND_REGREQ:
02470 case IAX_COMMAND_FWDOWNL:
02471 case IAX_COMMAND_REGREL:
02472 return 1;
02473 case IAX_COMMAND_POKE:
02474 if (!inbound) {
02475 return 1;
02476 }
02477 break;
02478 }
02479 return 0;
02480 }
02481
02482
02483
02484
02485 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02486 {
02487 int res = 0;
02488 int x;
02489
02490
02491 int validated = (new > NEW_ALLOW) ? 1 : 0;
02492 char host[80];
02493
02494 if (new <= NEW_ALLOW) {
02495 if (callno) {
02496 struct chan_iax2_pvt *pvt;
02497 struct chan_iax2_pvt tmp_pvt = {
02498 .callno = dcallno,
02499 .peercallno = callno,
02500 .transfercallno = callno,
02501
02502 .frames_received = check_dcallno,
02503 };
02504
02505 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02506
02507 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02508 if (return_locked) {
02509 ast_mutex_lock(&iaxsl[pvt->callno]);
02510 }
02511 res = pvt->callno;
02512 ao2_ref(pvt, -1);
02513 pvt = NULL;
02514 return res;
02515 }
02516
02517 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02518 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02519 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02520 if (return_locked) {
02521 ast_mutex_lock(&iaxsl[pvt->callno]);
02522 }
02523 res = pvt->callno;
02524 ao2_ref(pvt, -1);
02525 pvt = NULL;
02526 return res;
02527 }
02528 }
02529
02530
02531 if (dcallno) {
02532 ast_mutex_lock(&iaxsl[dcallno]);
02533 }
02534 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02535 iaxs[dcallno]->peercallno = callno;
02536 res = dcallno;
02537 store_by_peercallno(iaxs[dcallno]);
02538 if (!res || !return_locked) {
02539 ast_mutex_unlock(&iaxsl[dcallno]);
02540 }
02541 return res;
02542 }
02543 if (dcallno) {
02544 ast_mutex_unlock(&iaxsl[dcallno]);
02545 }
02546 #ifdef IAX_OLD_FIND
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558 for (x = 1; !res && x < maxnontrunkcall; x++) {
02559 ast_mutex_lock(&iaxsl[x]);
02560 if (iaxs[x]) {
02561
02562 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02563 res = x;
02564 }
02565 }
02566 if (!res || !return_locked)
02567 ast_mutex_unlock(&iaxsl[x]);
02568 }
02569 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02570 ast_mutex_lock(&iaxsl[x]);
02571 if (iaxs[x]) {
02572
02573 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02574 res = x;
02575 }
02576 }
02577 if (!res || !return_locked)
02578 ast_mutex_unlock(&iaxsl[x]);
02579 }
02580 #endif
02581 }
02582 if (!res && (new >= NEW_ALLOW)) {
02583 struct callno_entry *callno_entry;
02584
02585
02586
02587
02588
02589
02590 if (!iax2_getpeername(*sin, host, sizeof(host)))
02591 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02592
02593 if (peercnt_add(sin)) {
02594
02595
02596 return 0;
02597 }
02598
02599 if (!(callno_entry = get_unused_callno(0, validated))) {
02600
02601
02602 peercnt_remove_by_addr(sin);
02603 ast_log(LOG_WARNING, "No more space\n");
02604 return 0;
02605 }
02606 x = callno_entry->callno;
02607 ast_mutex_lock(&iaxsl[x]);
02608
02609 iaxs[x] = new_iax(sin, host);
02610 update_max_nontrunk();
02611 if (iaxs[x]) {
02612 if (iaxdebug)
02613 ast_debug(1, "Creating new call structure %d\n", x);
02614 iaxs[x]->callno_entry = callno_entry;
02615 iaxs[x]->sockfd = sockfd;
02616 iaxs[x]->addr.sin_port = sin->sin_port;
02617 iaxs[x]->addr.sin_family = sin->sin_family;
02618 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02619 iaxs[x]->peercallno = callno;
02620 iaxs[x]->callno = x;
02621 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02622 iaxs[x]->expiry = min_reg_expire;
02623 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02624 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02625 iaxs[x]->amaflags = amaflags;
02626 ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02627
02628 ast_string_field_set(iaxs[x], accountcode, accountcode);
02629 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02630 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02631 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02632
02633 if (iaxs[x]->peercallno) {
02634 store_by_peercallno(iaxs[x]);
02635 }
02636 } else {
02637 ast_log(LOG_WARNING, "Out of resources\n");
02638 ast_mutex_unlock(&iaxsl[x]);
02639 replace_callno(callno_entry);
02640 return 0;
02641 }
02642 if (!return_locked)
02643 ast_mutex_unlock(&iaxsl[x]);
02644 res = x;
02645 }
02646 return res;
02647 }
02648
02649 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02650
02651 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02652 }
02653
02654 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02655
02656 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02657 }
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669 static int iax2_queue_frame(int callno, struct ast_frame *f)
02670 {
02671 for (;;) {
02672 if (iaxs[callno] && iaxs[callno]->owner) {
02673 if (ast_channel_trylock(iaxs[callno]->owner)) {
02674
02675 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02676 } else {
02677 ast_queue_frame(iaxs[callno]->owner, f);
02678 ast_channel_unlock(iaxs[callno]->owner);
02679 break;
02680 }
02681 } else
02682 break;
02683 }
02684 return 0;
02685 }
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700 static int iax2_queue_hangup(int callno)
02701 {
02702 for (;;) {
02703 if (iaxs[callno] && iaxs[callno]->owner) {
02704 if (ast_channel_trylock(iaxs[callno]->owner)) {
02705
02706 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02707 } else {
02708 ast_queue_hangup(iaxs[callno]->owner);
02709 ast_channel_unlock(iaxs[callno]->owner);
02710 break;
02711 }
02712 } else
02713 break;
02714 }
02715 return 0;
02716 }
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731 static int iax2_queue_control_data(int callno,
02732 enum ast_control_frame_type control, const void *data, size_t datalen)
02733 {
02734 for (;;) {
02735 if (iaxs[callno] && iaxs[callno]->owner) {
02736 if (ast_channel_trylock(iaxs[callno]->owner)) {
02737
02738 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02739 } else {
02740 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02741 ast_channel_unlock(iaxs[callno]->owner);
02742 break;
02743 }
02744 } else
02745 break;
02746 }
02747 return 0;
02748 }
02749 static void destroy_firmware(struct iax_firmware *cur)
02750 {
02751
02752 if (cur->fwh) {
02753 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02754 }
02755 close(cur->fd);
02756 ast_free(cur);
02757 }
02758
02759 static int try_firmware(char *s)
02760 {
02761 struct stat stbuf;
02762 struct iax_firmware *cur = NULL;
02763 int ifd, fd, res, len, chunk;
02764 struct ast_iax2_firmware_header *fwh, fwh2;
02765 struct MD5Context md5;
02766 unsigned char sum[16], buf[1024];
02767 char *s2, *last;
02768
02769 if (!(s2 = alloca(strlen(s) + 100))) {
02770 ast_log(LOG_WARNING, "Alloca failed!\n");
02771 return -1;
02772 }
02773
02774 last = strrchr(s, '/');
02775 if (last)
02776 last++;
02777 else
02778 last = s;
02779
02780 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02781
02782 if ((res = stat(s, &stbuf) < 0)) {
02783 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02784 return -1;
02785 }
02786
02787
02788 if (S_ISDIR(stbuf.st_mode))
02789 return -1;
02790 ifd = open(s, O_RDONLY);
02791 if (ifd < 0) {
02792 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02793 return -1;
02794 }
02795 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02796 if (fd < 0) {
02797 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02798 close(ifd);
02799 return -1;
02800 }
02801
02802 unlink(s2);
02803
02804
02805 len = stbuf.st_size;
02806 while(len) {
02807 chunk = len;
02808 if (chunk > sizeof(buf))
02809 chunk = sizeof(buf);
02810 res = read(ifd, buf, chunk);
02811 if (res != chunk) {
02812 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02813 close(ifd);
02814 close(fd);
02815 return -1;
02816 }
02817 res = write(fd, buf, chunk);
02818 if (res != chunk) {
02819 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02820 close(ifd);
02821 close(fd);
02822 return -1;
02823 }
02824 len -= chunk;
02825 }
02826 close(ifd);
02827
02828 lseek(fd, 0, SEEK_SET);
02829 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02830 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02831 close(fd);
02832 return -1;
02833 }
02834 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02835 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02836 close(fd);
02837 return -1;
02838 }
02839 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02840 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02841 close(fd);
02842 return -1;
02843 }
02844 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02845 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02846 close(fd);
02847 return -1;
02848 }
02849 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
02850 if (fwh == MAP_FAILED) {
02851 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02852 close(fd);
02853 return -1;
02854 }
02855 MD5Init(&md5);
02856 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02857 MD5Final(sum, &md5);
02858 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02859 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02860 munmap((void*)fwh, stbuf.st_size);
02861 close(fd);
02862 return -1;
02863 }
02864
02865 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02866 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02867
02868 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02869
02870 break;
02871
02872
02873 munmap((void*)fwh, stbuf.st_size);
02874 close(fd);
02875 return 0;
02876 }
02877 }
02878
02879 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02880 cur->fd = -1;
02881 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02882 }
02883
02884 if (cur) {
02885 if (cur->fwh)
02886 munmap((void*)cur->fwh, cur->mmaplen);
02887 if (cur->fd > -1)
02888 close(cur->fd);
02889 cur->fwh = fwh;
02890 cur->fd = fd;
02891 cur->mmaplen = stbuf.st_size;
02892 cur->dead = 0;
02893 }
02894
02895 return 0;
02896 }
02897
02898 static int iax_check_version(char *dev)
02899 {
02900 int res = 0;
02901 struct iax_firmware *cur = NULL;
02902
02903 if (ast_strlen_zero(dev))
02904 return 0;
02905
02906 AST_LIST_LOCK(&firmwares);
02907 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02908 if (!strcmp(dev, (char *)cur->fwh->devname)) {
02909 res = ntohs(cur->fwh->version);
02910 break;
02911 }
02912 }
02913 AST_LIST_UNLOCK(&firmwares);
02914
02915 return res;
02916 }
02917
02918 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
02919 {
02920 int res = -1;
02921 unsigned int bs = desc & 0xff;
02922 unsigned int start = (desc >> 8) & 0xffffff;
02923 unsigned int bytes;
02924 struct iax_firmware *cur;
02925
02926 if (ast_strlen_zero((char *)dev) || !bs)
02927 return -1;
02928
02929 start *= bs;
02930
02931 AST_LIST_LOCK(&firmwares);
02932 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02933 if (strcmp((char *)dev, (char *)cur->fwh->devname))
02934 continue;
02935 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02936 if (start < ntohl(cur->fwh->datalen)) {
02937 bytes = ntohl(cur->fwh->datalen) - start;
02938 if (bytes > bs)
02939 bytes = bs;
02940 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02941 } else {
02942 bytes = 0;
02943 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02944 }
02945 if (bytes == bs)
02946 res = 0;
02947 else
02948 res = 1;
02949 break;
02950 }
02951 AST_LIST_UNLOCK(&firmwares);
02952
02953 return res;
02954 }
02955
02956
02957 static void reload_firmware(int unload)
02958 {
02959 struct iax_firmware *cur = NULL;
02960 DIR *fwd;
02961 struct dirent *de;
02962 char dir[256], fn[256];
02963
02964 AST_LIST_LOCK(&firmwares);
02965
02966
02967 AST_LIST_TRAVERSE(&firmwares, cur, list)
02968 cur->dead = 1;
02969
02970
02971 if (!unload) {
02972 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
02973 fwd = opendir(dir);
02974 if (fwd) {
02975 while((de = readdir(fwd))) {
02976 if (de->d_name[0] != '.') {
02977 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02978 if (!try_firmware(fn)) {
02979 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
02980 }
02981 }
02982 }
02983 closedir(fwd);
02984 } else
02985 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02986 }
02987
02988
02989 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
02990 if (!cur->dead)
02991 continue;
02992 AST_LIST_REMOVE_CURRENT(list);
02993 destroy_firmware(cur);
02994 }
02995 AST_LIST_TRAVERSE_SAFE_END;
02996
02997 AST_LIST_UNLOCK(&firmwares);
02998 }
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008 static int __do_deliver(void *data)
03009 {
03010
03011
03012 struct iax_frame *fr = data;
03013 fr->retrans = -1;
03014 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03015 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
03016 iax2_queue_frame(fr->callno, &fr->af);
03017
03018 iax2_frame_free(fr);
03019
03020 return 0;
03021 }
03022
03023 static int handle_error(void)
03024 {
03025
03026
03027
03028 #if 0
03029 struct sockaddr_in *sin;
03030 int res;
03031 struct msghdr m;
03032 struct sock_extended_err e;
03033 m.msg_name = NULL;
03034 m.msg_namelen = 0;
03035 m.msg_iov = NULL;
03036 m.msg_control = &e;
03037 m.msg_controllen = sizeof(e);
03038 m.msg_flags = 0;
03039 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03040 if (res < 0)
03041 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03042 else {
03043 if (m.msg_controllen) {
03044 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03045 if (sin)
03046 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03047 else
03048 ast_log(LOG_WARNING, "No address detected??\n");
03049 } else {
03050 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03051 }
03052 }
03053 #endif
03054 return 0;
03055 }
03056
03057 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03058 {
03059 int res;
03060 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03061 sizeof(*sin));
03062 if (res < 0) {
03063 ast_debug(1, "Received error: %s\n", strerror(errno));
03064 handle_error();
03065 } else
03066 res = 0;
03067 return res;
03068 }
03069
03070 static int send_packet(struct iax_frame *f)
03071 {
03072 int res;
03073 int callno = f->callno;
03074
03075
03076 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03077 return -1;
03078
03079
03080 if (iaxdebug)
03081 ast_debug(3, "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));
03082
03083 if (f->transfer) {
03084 if (iaxdebug)
03085 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03086 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03087 } else {
03088 if (iaxdebug)
03089 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03090 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03091 }
03092 if (res < 0) {
03093 if (iaxdebug)
03094 ast_debug(1, "Received error: %s\n", strerror(errno));
03095 handle_error();
03096 } else
03097 res = 0;
03098
03099 return res;
03100 }
03101
03102
03103
03104
03105
03106 static int iax2_predestroy(int callno)
03107 {
03108 struct ast_channel *c = NULL;
03109 struct chan_iax2_pvt *pvt = iaxs[callno];
03110
03111 if (!pvt)
03112 return -1;
03113
03114 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
03115 iax2_destroy_helper(pvt);
03116 ast_set_flag(pvt, IAX_ALREADYGONE);
03117 }
03118
03119 if ((c = pvt->owner)) {
03120 c->tech_pvt = NULL;
03121 iax2_queue_hangup(callno);
03122 pvt->owner = NULL;
03123 ast_module_unref(ast_module_info->self);
03124 }
03125
03126 return 0;
03127 }
03128
03129 static void iax2_destroy(int callno)
03130 {
03131 struct chan_iax2_pvt *pvt = NULL;
03132 struct ast_channel *owner = NULL;
03133
03134 retry:
03135 if ((pvt = iaxs[callno])) {
03136 iax2_destroy_helper(pvt);
03137 }
03138
03139 owner = pvt ? pvt->owner : NULL;
03140
03141 if (owner) {
03142 if (ast_channel_trylock(owner)) {
03143 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03144 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03145 goto retry;
03146 }
03147 }
03148
03149 if (!owner) {
03150 iaxs[callno] = NULL;
03151 }
03152
03153 if (pvt) {
03154 if (!owner) {
03155 pvt->owner = NULL;
03156 } else {
03157
03158
03159
03160 ast_queue_hangup(owner);
03161 }
03162
03163 if (pvt->peercallno) {
03164 remove_by_peercallno(pvt);
03165 }
03166
03167 if (pvt->transfercallno) {
03168 remove_by_transfercallno(pvt);
03169 }
03170
03171 if (!owner) {
03172 ao2_ref(pvt, -1);
03173 pvt = NULL;
03174 }
03175 }
03176
03177 if (owner) {
03178 ast_channel_unlock(owner);
03179 }
03180
03181 if (callno & 0x4000) {
03182 update_max_trunk();
03183 }
03184 }
03185
03186 static int update_packet(struct iax_frame *f)
03187 {
03188
03189 struct ast_iax2_full_hdr *fh = f->data;
03190 struct ast_frame af;
03191
03192
03193 if (f->encmethods) {
03194 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03195 }
03196
03197 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03198
03199 f->iseqno = iaxs[f->callno]->iseqno;
03200 fh->iseqno = f->iseqno;
03201
03202
03203 if (f->encmethods) {
03204
03205
03206 build_rand_pad(f->semirand, sizeof(f->semirand));
03207 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03208 }
03209 return 0;
03210 }
03211
03212 static int attempt_transmit(const void *data);
03213 static void __attempt_transmit(const void *data)
03214 {
03215
03216
03217 struct iax_frame *f = (struct iax_frame *)data;
03218 int freeme = 0;
03219 int callno = f->callno;
03220
03221 if (callno)
03222 ast_mutex_lock(&iaxsl[callno]);
03223 if (callno && iaxs[callno]) {
03224 if ((f->retries < 0) ||
03225 (f->retries >= max_retries) ) {
03226
03227 if (f->retries >= max_retries) {
03228 if (f->transfer) {
03229
03230 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03231 } else if (f->final) {
03232 if (f->final)
03233 iax2_destroy(callno);
03234 } else {
03235 if (iaxs[callno]->owner)
03236 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);
03237 iaxs[callno]->error = ETIMEDOUT;
03238 if (iaxs[callno]->owner) {
03239 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03240
03241 iax2_queue_frame(callno, &fr);
03242
03243 if (iaxs[callno] && iaxs[callno]->owner)
03244 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03245 } else {
03246 if (iaxs[callno]->reg) {
03247 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03248 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03249 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03250 }
03251 iax2_destroy(callno);
03252 }
03253 }
03254
03255 }
03256 freeme = 1;
03257 } else {
03258
03259 update_packet(f);
03260
03261 send_packet(f);
03262 f->retries++;
03263
03264 f->retrytime *= 10;
03265 if (f->retrytime > MAX_RETRY_TIME)
03266 f->retrytime = MAX_RETRY_TIME;
03267
03268 if (f->transfer && (f->retrytime > 1000))
03269 f->retrytime = 1000;
03270 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03271 }
03272 } else {
03273
03274 f->retries = -1;
03275 freeme = 1;
03276 }
03277 if (callno)
03278 ast_mutex_unlock(&iaxsl[callno]);
03279
03280 if (freeme) {
03281
03282 AST_LIST_LOCK(&frame_queue);
03283 AST_LIST_REMOVE(&frame_queue, f, list);
03284 AST_LIST_UNLOCK(&frame_queue);
03285 f->retrans = -1;
03286
03287 iax2_frame_free(f);
03288 }
03289 }
03290
03291 static int attempt_transmit(const void *data)
03292 {
03293 #ifdef SCHED_MULTITHREADED
03294 if (schedule_action(__attempt_transmit, data))
03295 #endif
03296 __attempt_transmit(data);
03297 return 0;
03298 }
03299
03300 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03301 {
03302 struct iax2_peer *peer = NULL;
03303 struct iax2_user *user = NULL;
03304
03305 switch (cmd) {
03306 case CLI_INIT:
03307 e->command = "iax2 prune realtime";
03308 e->usage =
03309 "Usage: iax2 prune realtime [<peername>|all]\n"
03310 " Prunes object(s) from the cache\n";
03311 return NULL;
03312 case CLI_GENERATE:
03313 if (a->pos == 3)
03314 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
03315 return NULL;
03316 }
03317 if (a->argc != 4)
03318 return CLI_SHOWUSAGE;
03319 if (!strcmp(a->argv[3], "all")) {
03320 prune_users();
03321 prune_peers();
03322 ast_cli(a->fd, "Cache flushed successfully.\n");
03323 return CLI_SUCCESS;
03324 }
03325 peer = find_peer(a->argv[3], 0);
03326 user = find_user(a->argv[3]);
03327 if (peer || user) {
03328 if (peer) {
03329 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
03330 ast_set_flag(peer, IAX_RTAUTOCLEAR);
03331 expire_registry(peer_ref(peer));
03332 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03333 } else {
03334 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03335 }
03336 peer_unref(peer);
03337 }
03338 if (user) {
03339 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
03340 ast_set_flag(user, IAX_RTAUTOCLEAR);
03341 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03342 } else {
03343 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03344 }
03345 ao2_unlink(users,user);
03346 user_unref(user);
03347 }
03348 } else {
03349 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03350 }
03351
03352 return CLI_SUCCESS;
03353 }
03354
03355 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03356 {
03357 switch (cmd) {
03358 case CLI_INIT:
03359 e->command = "iax2 test losspct";
03360 e->usage =
03361 "Usage: iax2 test losspct <percentage>\n"
03362 " For testing, throws away <percentage> percent of incoming packets\n";
03363 return NULL;
03364 case CLI_GENERATE:
03365 return NULL;
03366 }
03367 if (a->argc != 4)
03368 return CLI_SHOWUSAGE;
03369
03370 test_losspct = atoi(a->argv[3]);
03371
03372 return CLI_SUCCESS;
03373 }
03374
03375 #ifdef IAXTESTS
03376 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03377 {
03378 switch (cmd) {
03379 case CLI_INIT:
03380 e->command = "iax2 test late";
03381 e->usage =
03382 "Usage: iax2 test late <ms>\n"
03383 " For testing, count the next frame as <ms> ms late\n";
03384 return NULL;
03385 case CLI_GENERATE:
03386 return NULL;
03387 }
03388
03389 if (a->argc != 4)
03390 return CLI_SHOWUSAGE;
03391
03392 test_late = atoi(a->argv[3]);
03393
03394 return CLI_SUCCESS;
03395 }
03396
03397 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03398 {
03399 switch (cmd) {
03400 case CLI_INIT:
03401 e->command = "iax2 test resync";
03402 e->usage =
03403 "Usage: iax2 test resync <ms>\n"
03404 " For testing, adjust all future frames by <ms> ms\n";
03405 return NULL;
03406 case CLI_GENERATE:
03407 return NULL;
03408 }
03409
03410 if (a->argc != 4)
03411 return CLI_SHOWUSAGE;
03412
03413 test_resync = atoi(a->argv[3]);
03414
03415 return CLI_SUCCESS;
03416 }
03417
03418 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03419 {
03420 switch (cmd) {
03421 case CLI_INIT:
03422 e->command = "iax2 test jitter";
03423 e->usage =
03424 "Usage: iax2 test jitter <ms> <pct>\n"
03425 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03426 " percentage of packets. If <pct> is not specified, adds\n"
03427 " jitter to all packets.\n";
03428 return NULL;
03429 case CLI_GENERATE:
03430 return NULL;
03431 }
03432
03433 if (a->argc < 4 || a->argc > 5)
03434 return CLI_SHOWUSAGE;
03435
03436 test_jit = atoi(a->argv[3]);
03437 if (a->argc == 5)
03438 test_jitpct = atoi(a->argv[4]);
03439
03440 return CLI_SUCCESS;
03441 }
03442 #endif
03443
03444
03445
03446 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03447 {
03448 int res = 0;
03449 if (peer->maxms) {
03450 if (peer->lastms < 0) {
03451 ast_copy_string(status, "UNREACHABLE", statuslen);
03452 } else if (peer->lastms > peer->maxms) {
03453 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03454 res = 1;
03455 } else if (peer->lastms) {
03456 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03457 res = 1;
03458 } else {
03459 ast_copy_string(status, "UNKNOWN", statuslen);
03460 }
03461 } else {
03462 ast_copy_string(status, "Unmonitored", statuslen);
03463 res = -1;
03464 }
03465 return res;
03466 }
03467
03468
03469 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03470 {
03471 char status[30];
03472 char cbuf[256];
03473 struct iax2_peer *peer;
03474 char codec_buf[512];
03475 int x = 0, codec = 0, load_realtime = 0;
03476
03477 switch (cmd) {
03478 case CLI_INIT:
03479 e->command = "iax2 show peer";
03480 e->usage =
03481 "Usage: iax2 show peer <name>\n"
03482 " Display details on specific IAX peer\n";
03483 return NULL;
03484 case CLI_GENERATE:
03485 if (a->pos == 3)
03486 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
03487 return NULL;
03488 }
03489
03490 if (a->argc < 4)
03491 return CLI_SHOWUSAGE;
03492
03493 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03494
03495 peer = find_peer(a->argv[3], load_realtime);
03496 if (peer) {
03497 ast_cli(a->fd, "\n\n");
03498 ast_cli(a->fd, " * Name : %s\n", peer->name);
03499 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03500 ast_cli(a->fd, " Context : %s\n", peer->context);
03501 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03502 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03503 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
03504 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03505 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03506 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
03507 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03508 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03509 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03510 ast_cli(a->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));
03511 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03512 ast_cli(a->fd, " Username : %s\n", peer->username);
03513 ast_cli(a->fd, " Codecs : ");
03514 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03515 ast_cli(a->fd, "%s\n", codec_buf);
03516
03517 ast_cli(a->fd, " Codec Order : (");
03518 for(x = 0; x < 32 ; x++) {
03519 codec = ast_codec_pref_index(&peer->prefs,x);
03520 if(!codec)
03521 break;
03522 ast_cli(a->fd, "%s", ast_getformatname(codec));
03523 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03524 ast_cli(a->fd, "|");
03525 }
03526
03527 if (!x)
03528 ast_cli(a->fd, "none");
03529 ast_cli(a->fd, ")\n");
03530
03531 ast_cli(a->fd, " Status : ");
03532 peer_status(peer, status, sizeof(status));
03533 ast_cli(a->fd, "%s\n",status);
03534 ast_cli(a->fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
03535 ast_cli(a->fd, "\n");
03536 peer_unref(peer);
03537 } else {
03538 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03539 ast_cli(a->fd, "\n");
03540 }
03541
03542 return CLI_SUCCESS;
03543 }
03544
03545 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state)
03546 {
03547 int which = 0;
03548 struct iax2_peer *peer;
03549 char *res = NULL;
03550 int wordlen = strlen(word);
03551 struct ao2_iterator i;
03552
03553 i = ao2_iterator_init(peers, 0);
03554 while ((peer = ao2_iterator_next(&i))) {
03555 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
03556 res = ast_strdup(peer->name);
03557 peer_unref(peer);
03558 break;
03559 }
03560 peer_unref(peer);
03561 }
03562 ao2_iterator_destroy(&i);
03563
03564 return res;
03565 }
03566
03567 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03568 {
03569 struct iax_frame *cur;
03570 int cnt = 0, dead = 0, final = 0;
03571
03572 switch (cmd) {
03573 case CLI_INIT:
03574 e->command = "iax2 show stats";
03575 e->usage =
03576 "Usage: iax2 show stats\n"
03577 " Display statistics on IAX channel driver.\n";
03578 return NULL;
03579 case CLI_GENERATE:
03580 return NULL;
03581 }
03582
03583 if (a->argc != 3)
03584 return CLI_SHOWUSAGE;
03585
03586 AST_LIST_LOCK(&frame_queue);
03587 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
03588 if (cur->retries < 0)
03589 dead++;
03590 if (cur->final)
03591 final++;
03592 cnt++;
03593 }
03594 AST_LIST_UNLOCK(&frame_queue);
03595
03596 ast_cli(a->fd, " IAX Statistics\n");
03597 ast_cli(a->fd, "---------------------\n");
03598 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03599 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03600 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03601 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03602
03603 trunk_timed = trunk_untimed = 0;
03604 if (trunk_maxmtu > trunk_nmaxmtu)
03605 trunk_nmaxmtu = trunk_maxmtu;
03606
03607 return CLI_SUCCESS;
03608 }
03609
03610
03611 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03612 {
03613 int mtuv;
03614
03615 switch (cmd) {
03616 case CLI_INIT:
03617 e->command = "iax2 set mtu";
03618 e->usage =
03619 "Usage: iax2 set mtu <value>\n"
03620 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03621 " zero to disable. Disabling means that the operating system\n"
03622 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03623 " packet exceeds the UDP payload size. This is substantially\n"
03624 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03625 " greater for G.711 samples.\n";
03626 return NULL;
03627 case CLI_GENERATE:
03628 return NULL;
03629 }
03630
03631 if (a->argc != 4)
03632 return CLI_SHOWUSAGE;
03633 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03634 mtuv = MAX_TRUNK_MTU;
03635 else
03636 mtuv = atoi(a->argv[3]);
03637
03638 if (mtuv == 0) {
03639 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03640 global_max_trunk_mtu = 0;
03641 return CLI_SUCCESS;
03642 }
03643 if (mtuv < 172 || mtuv > 4000) {
03644 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03645 return CLI_SHOWUSAGE;
03646 }
03647 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03648 global_max_trunk_mtu = mtuv;
03649 return CLI_SUCCESS;
03650 }
03651
03652 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03653 {
03654 struct iax2_dpcache *dp = NULL;
03655 char tmp[1024], *pc = NULL;
03656 int s, x, y;
03657 struct timeval now = ast_tvnow();
03658
03659 switch (cmd) {
03660 case CLI_INIT:
03661 e->command = "iax2 show cache";
03662 e->usage =
03663 "Usage: iax2 show cache\n"
03664 " Display currently cached IAX Dialplan results.\n";
03665 return NULL;
03666 case CLI_GENERATE:
03667 return NULL;
03668 }
03669
03670 AST_LIST_LOCK(&dpcache);
03671
03672 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03673
03674 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03675 s = dp->expiry.tv_sec - now.tv_sec;
03676 tmp[0] = '\0';
03677 if (dp->flags & CACHE_FLAG_EXISTS)
03678 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03679 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03680 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03681 if (dp->flags & CACHE_FLAG_CANEXIST)
03682 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03683 if (dp->flags & CACHE_FLAG_PENDING)
03684 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03685 if (dp->flags & CACHE_FLAG_TIMEOUT)
03686 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03687 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03688 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03689 if (dp->flags & CACHE_FLAG_MATCHMORE)
03690 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03691 if (dp->flags & CACHE_FLAG_UNKNOWN)
03692 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03693
03694 if (!ast_strlen_zero(tmp)) {
03695 tmp[strlen(tmp) - 1] = '\0';
03696 } else {
03697 ast_copy_string(tmp, "(none)", sizeof(tmp));
03698 }
03699 y = 0;
03700 pc = strchr(dp->peercontext, '@');
03701 if (!pc) {
03702 pc = dp->peercontext;
03703 } else {
03704 pc++;
03705 }
03706 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03707 if (dp->waiters[x] > -1)
03708 y++;
03709 }
03710 if (s > 0) {
03711 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03712 } else {
03713 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03714 }
03715 }
03716
03717 AST_LIST_UNLOCK(&dpcache);
03718
03719 return CLI_SUCCESS;
03720 }
03721
03722 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03723
03724 static void unwrap_timestamp(struct iax_frame *fr)
03725 {
03726
03727
03728 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03729 const int lower_mask = (1 << ts_shift) - 1;
03730 const int upper_mask = ~lower_mask;
03731 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03732
03733 if ( (fr->ts & upper_mask) == last_upper ) {
03734 const int x = fr->ts - iaxs[fr->callno]->last;
03735 const int threshold = (ts_shift == 15) ? 25000 : 50000;
03736
03737 if (x < -threshold) {
03738
03739
03740
03741
03742 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
03743 if (iaxdebug)
03744 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
03745 } else if (x > threshold) {
03746
03747
03748
03749
03750 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03751 if (iaxdebug)
03752 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
03753 }
03754 }
03755 }
03756
03757 static int get_from_jb(const void *p);
03758
03759 static void update_jbsched(struct chan_iax2_pvt *pvt)
03760 {
03761 int when;
03762
03763 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03764
03765 when = jb_next(pvt->jb) - when;
03766
03767 if (when <= 0) {
03768
03769 when = 1;
03770 }
03771
03772 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
03773 CALLNO_TO_PTR(pvt->callno));
03774 }
03775
03776 static void __get_from_jb(const void *p)
03777 {
03778 int callno = PTR_TO_CALLNO(p);
03779 struct chan_iax2_pvt *pvt = NULL;
03780 struct iax_frame *fr;
03781 jb_frame frame;
03782 int ret;
03783 long ms;
03784 long next;
03785 struct timeval now = ast_tvnow();
03786
03787
03788 ast_mutex_lock(&iaxsl[callno]);
03789 pvt = iaxs[callno];
03790 if (!pvt) {
03791
03792 ast_mutex_unlock(&iaxsl[callno]);
03793 return;
03794 }
03795
03796 pvt->jbid = -1;
03797
03798
03799
03800
03801 now.tv_usec += 1000;
03802
03803 ms = ast_tvdiff_ms(now, pvt->rxcore);
03804
03805 if(ms >= (next = jb_next(pvt->jb))) {
03806 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
03807 switch(ret) {
03808 case JB_OK:
03809 fr = frame.data;
03810 __do_deliver(fr);
03811
03812 pvt = iaxs[callno];
03813 break;
03814 case JB_INTERP:
03815 {
03816 struct ast_frame af = { 0, };
03817
03818
03819 af.frametype = AST_FRAME_VOICE;
03820 af.subclass = pvt->voiceformat;
03821 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03822 af.src = "IAX2 JB interpolation";
03823 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03824 af.offset = AST_FRIENDLY_OFFSET;
03825
03826
03827
03828 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03829 iax2_queue_frame(callno, &af);
03830
03831 pvt = iaxs[callno];
03832 }
03833 }
03834 break;
03835 case JB_DROP:
03836 iax2_frame_free(frame.data);
03837 break;
03838 case JB_NOFRAME:
03839 case JB_EMPTY:
03840
03841 break;
03842 default:
03843
03844 break;
03845 }
03846 }
03847 if (pvt)
03848 update_jbsched(pvt);
03849 ast_mutex_unlock(&iaxsl[callno]);
03850 }
03851
03852 static int get_from_jb(const void *data)
03853 {
03854 #ifdef SCHED_MULTITHREADED
03855 if (schedule_action(__get_from_jb, data))
03856 #endif
03857 __get_from_jb(data);
03858 return 0;
03859 }
03860
03861
03862
03863
03864
03865
03866
03867 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03868 {
03869 int type, len;
03870 int ret;
03871 int needfree = 0;
03872 struct ast_channel *owner = NULL;
03873 struct ast_channel *bridge = NULL;
03874
03875
03876 unwrap_timestamp(fr);
03877
03878
03879 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03880 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03881 else {
03882 #if 0
03883 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03884 #endif
03885 fr->af.delivery = ast_tv(0,0);
03886 }
03887
03888 type = JB_TYPE_CONTROL;
03889 len = 0;
03890
03891 if(fr->af.frametype == AST_FRAME_VOICE) {
03892 type = JB_TYPE_VOICE;
03893 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
03894 } else if(fr->af.frametype == AST_FRAME_CNG) {
03895 type = JB_TYPE_SILENCE;
03896 }
03897
03898 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03899 if (tsout)
03900 *tsout = fr->ts;
03901 __do_deliver(fr);
03902 return -1;
03903 }
03904
03905 if ((owner = iaxs[fr->callno]->owner))
03906 bridge = ast_bridged_channel(owner);
03907
03908
03909
03910 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03911 jb_frame frame;
03912
03913
03914 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03915 __do_deliver(frame.data);
03916
03917 if (!iaxs[fr->callno])
03918 return -1;
03919 }
03920
03921 jb_reset(iaxs[fr->callno]->jb);
03922
03923 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03924
03925
03926 if (tsout)
03927 *tsout = fr->ts;
03928 __do_deliver(fr);
03929 return -1;
03930 }
03931
03932
03933
03934 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03935 calc_rxstamp(iaxs[fr->callno],fr->ts));
03936 if (ret == JB_DROP) {
03937 needfree++;
03938 } else if (ret == JB_SCHED) {
03939 update_jbsched(iaxs[fr->callno]);
03940 }
03941 if (tsout)
03942 *tsout = fr->ts;
03943 if (needfree) {
03944
03945 iax2_frame_free(fr);
03946 return -1;
03947 }
03948 return 0;
03949 }
03950
03951 static int iax2_transmit(struct iax_frame *fr)
03952 {
03953
03954
03955
03956 fr->sentyet = 0;
03957 AST_LIST_LOCK(&frame_queue);
03958 AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
03959 AST_LIST_UNLOCK(&frame_queue);
03960
03961 if (netthreadid != AST_PTHREADT_NULL)
03962 pthread_kill(netthreadid, SIGURG);
03963 signal_condition(&sched_lock, &sched_cond);
03964 return 0;
03965 }
03966
03967
03968
03969 static int iax2_digit_begin(struct ast_channel *c, char digit)
03970 {
03971 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03972 }
03973
03974 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
03975 {
03976 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03977 }
03978
03979 static int iax2_sendtext(struct ast_channel *c, const char *text)
03980 {
03981
03982 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03983 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03984 }
03985
03986 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
03987 {
03988 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1);
03989 }
03990
03991 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
03992 {
03993 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03994 }
03995
03996 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
03997 {
03998 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
03999 ast_mutex_lock(&iaxsl[callno]);
04000 if (iaxs[callno])
04001 iaxs[callno]->owner = newchan;
04002 else
04003 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04004 ast_mutex_unlock(&iaxsl[callno]);
04005 return 0;
04006 }
04007
04008
04009
04010
04011
04012 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04013 {
04014 struct ast_variable *var = NULL;
04015 struct ast_variable *tmp;
04016 struct iax2_peer *peer=NULL;
04017 time_t regseconds = 0, nowtime;
04018 int dynamic=0;
04019
04020 if (peername) {
04021 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04022 if (!var && sin)
04023 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04024 } else if (sin) {
04025 char porta[25];
04026 sprintf(porta, "%d", ntohs(sin->sin_port));
04027 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04028 if (var) {
04029
04030 for (tmp = var; tmp; tmp = tmp->next) {
04031 if (!strcasecmp(tmp->name, "name"))
04032 peername = tmp->value;
04033 }
04034 }
04035 }
04036 if (!var && peername) {
04037 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04038
04039
04040
04041
04042
04043
04044 if (var && sin) {
04045 for (tmp = var; tmp; tmp = tmp->next) {
04046 if (!strcasecmp(tmp->name, "host")) {
04047 struct ast_hostent ahp;
04048 struct hostent *hp;
04049 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04050
04051 ast_variables_destroy(var);
04052 var = NULL;
04053 }
04054 break;
04055 }
04056 }
04057 }
04058 }
04059 if (!var)
04060 return NULL;
04061
04062 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04063
04064 if (!peer) {
04065 ast_variables_destroy(var);
04066 return NULL;
04067 }
04068
04069 for (tmp = var; tmp; tmp = tmp->next) {
04070
04071 if (!strcasecmp(tmp->name, "type")) {
04072 if (strcasecmp(tmp->value, "friend") &&
04073 strcasecmp(tmp->value, "peer")) {
04074
04075 peer = peer_unref(peer);
04076 break;
04077 }
04078 } else if (!strcasecmp(tmp->name, "regseconds")) {
04079 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04080 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04081 inet_aton(tmp->value, &(peer->addr.sin_addr));
04082 } else if (!strcasecmp(tmp->name, "port")) {
04083 peer->addr.sin_port = htons(atoi(tmp->value));
04084 } else if (!strcasecmp(tmp->name, "host")) {
04085 if (!strcasecmp(tmp->value, "dynamic"))
04086 dynamic = 1;
04087 }
04088 }
04089
04090 ast_variables_destroy(var);
04091
04092 if (!peer)
04093 return NULL;
04094
04095 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04096 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04097 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
04098 if (peer->expire > -1) {
04099 if (!ast_sched_del(sched, peer->expire)) {
04100 peer->expire = -1;
04101 peer_unref(peer);
04102 }
04103 }
04104 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04105 if (peer->expire == -1)
04106 peer_unref(peer);
04107 }
04108 ao2_link(peers, peer);
04109 if (ast_test_flag(peer, IAX_DYNAMIC))
04110 reg_source_db(peer);
04111 } else {
04112 ast_set_flag(peer, IAX_TEMPONLY);
04113 }
04114
04115 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04116 time(&nowtime);
04117 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04118 memset(&peer->addr, 0, sizeof(peer->addr));
04119 realtime_update_peer(peer->name, &peer->addr, 0);
04120 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04121 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04122 }
04123 else {
04124 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04125 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04126 }
04127 }
04128
04129 return peer;
04130 }
04131
04132 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04133 {
04134 struct ast_variable *var;
04135 struct ast_variable *tmp;
04136 struct iax2_user *user=NULL;
04137
04138 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04139 if (!var)
04140 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04141 if (!var && sin) {
04142 char porta[6];
04143 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04144 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04145 if (!var)
04146 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04147 }
04148 if (!var) {
04149 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04150
04151
04152
04153
04154
04155
04156 if (var) {
04157 for (tmp = var; tmp; tmp = tmp->next) {
04158 if (!strcasecmp(tmp->name, "host")) {
04159 struct ast_hostent ahp;
04160 struct hostent *hp;
04161 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04162
04163 ast_variables_destroy(var);
04164 var = NULL;
04165 }
04166 break;
04167 }
04168 }
04169 }
04170 }
04171 if (!var)
04172 return NULL;
04173
04174 tmp = var;
04175 while(tmp) {
04176
04177 if (!strcasecmp(tmp->name, "type")) {
04178 if (strcasecmp(tmp->value, "friend") &&
04179 strcasecmp(tmp->value, "user")) {
04180 return NULL;
04181 }
04182 }
04183 tmp = tmp->next;
04184 }
04185
04186 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
04187
04188 ast_variables_destroy(var);
04189
04190 if (!user)
04191 return NULL;
04192
04193 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04194 ast_set_flag(user, IAX_RTCACHEFRIENDS);
04195 ao2_link(users, user);
04196 } else {
04197 ast_set_flag(user, IAX_TEMPONLY);
04198 }
04199
04200 return user;
04201 }
04202
04203 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
04204 {
04205 char port[10];
04206 char regseconds[20];
04207
04208 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04209 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
04210 ast_update_realtime("iaxpeers", "name", peername,
04211 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
04212 "regseconds", regseconds, SENTINEL);
04213 }
04214
04215 struct create_addr_info {
04216 int capability;
04217 unsigned int flags;
04218 int maxtime;
04219 int encmethods;
04220 int found;
04221 int sockfd;
04222 int adsi;
04223 char username[80];
04224 char secret[80];
04225 char outkey[80];
04226 char timezone[80];
04227 char prefs[32];
04228 char context[AST_MAX_CONTEXT];
04229 char peercontext[AST_MAX_CONTEXT];
04230 char mohinterpret[MAX_MUSICCLASS];
04231 char mohsuggest[MAX_MUSICCLASS];
04232 };
04233
04234 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04235 {
04236 struct iax2_peer *peer;
04237 int res = -1;
04238 struct ast_codec_pref ourprefs;
04239
04240 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
04241 cai->sockfd = defaultsockfd;
04242 cai->maxtime = 0;
04243 sin->sin_family = AF_INET;
04244
04245 if (!(peer = find_peer(peername, 1))) {
04246 cai->found = 0;
04247 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
04248 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04249 return -1;
04250 }
04251 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04252
04253
04254 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04255 if (c)
04256 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04257 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04258 return 0;
04259 }
04260
04261 cai->found = 1;
04262
04263
04264 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
04265 goto return_unref;
04266
04267
04268 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04269 goto return_unref;
04270
04271 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
04272 cai->maxtime = peer->maxms;
04273 cai->capability = peer->capability;
04274 cai->encmethods = peer->encmethods;
04275 cai->sockfd = peer->sockfd;
04276 cai->adsi = peer->adsi;
04277 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04278
04279 if (c) {
04280 ast_debug(1, "prepending %x to prefs\n", c->nativeformats);
04281 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04282 }
04283 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04284 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04285 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04286 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04287 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04288 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04289 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04290 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04291 if (ast_strlen_zero(peer->dbsecret)) {
04292 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04293 } else {
04294 char *family;
04295 char *key = NULL;
04296
04297 family = ast_strdupa(peer->dbsecret);
04298 key = strchr(family, '/');
04299 if (key)
04300 *key++ = '\0';
04301 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04302 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04303 goto return_unref;
04304 }
04305 }
04306
04307 if (peer->addr.sin_addr.s_addr) {
04308 sin->sin_addr = peer->addr.sin_addr;
04309 sin->sin_port = peer->addr.sin_port;
04310 } else {
04311 sin->sin_addr = peer->defaddr.sin_addr;
04312 sin->sin_port = peer->defaddr.sin_port;
04313 }
04314
04315 res = 0;
04316
04317 return_unref:
04318 peer_unref(peer);
04319
04320 return res;
04321 }
04322
04323 static void __auto_congest(const void *nothing)
04324 {
04325 int callno = PTR_TO_CALLNO(nothing);
04326 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
04327 ast_mutex_lock(&iaxsl[callno]);
04328 if (iaxs[callno]) {
04329 iaxs[callno]->initid = -1;
04330 iax2_queue_frame(callno, &f);
04331 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04332 }
04333 ast_mutex_unlock(&iaxsl[callno]);
04334 }
04335
04336 static int auto_congest(const void *data)
04337 {
04338 #ifdef SCHED_MULTITHREADED
04339 if (schedule_action(__auto_congest, data))
04340 #endif
04341 __auto_congest(data);
04342 return 0;
04343 }
04344
04345 static unsigned int iax2_datetime(const char *tz)
04346 {
04347 struct timeval t = ast_tvnow();
04348 struct ast_tm tm;
04349 unsigned int tmp;
04350 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04351 tmp = (tm.tm_sec >> 1) & 0x1f;
04352 tmp |= (tm.tm_min & 0x3f) << 5;
04353 tmp |= (tm.tm_hour & 0x1f) << 11;
04354 tmp |= (tm.tm_mday & 0x1f) << 16;
04355 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04356 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04357 return tmp;
04358 }
04359
04360 struct parsed_dial_string {
04361 char *username;
04362 char *password;
04363 char *key;
04364 char *peer;
04365 char *port;
04366 char *exten;
04367 char *context;
04368 char *options;
04369 };
04370
04371 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04372 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04373 int sockfd, struct iax_ie_data *ied)
04374 {
04375 struct {
04376 struct ast_iax2_full_hdr f;
04377 struct iax_ie_data ied;
04378 } data;
04379 size_t size = sizeof(struct ast_iax2_full_hdr);
04380
04381 if (ied) {
04382 size += ied->pos;
04383 memcpy(&data.ied, ied->buf, ied->pos);
04384 }
04385
04386 data.f.scallno = htons(0x8000 | callno);
04387 data.f.dcallno = htons(dcallno);
04388 data.f.ts = htonl(ts);
04389 data.f.iseqno = seqno;
04390 data.f.oseqno = 0;
04391 data.f.type = AST_FRAME_IAX;
04392 data.f.csub = compress_subclass(command);
04393
04394 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04395 }
04396
04397 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04398 {
04399
04400 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04401 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04402 ied->buf[ied->pos++] = 0;
04403 pvt->calltoken_ie_len = 2;
04404 }
04405 }
04406
04407 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04408 {
04409 struct chan_iax2_pvt *pvt = iaxs[callno];
04410 int frametype = f->af.frametype;
04411 int subclass = f->af.subclass;
04412 struct {
04413 struct ast_iax2_full_hdr fh;
04414 struct iax_ie_data ied;
04415 } data = {
04416 .ied.buf = { 0 },
04417 .ied.pos = 0,
04418 };
04419
04420 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04421
04422 if (!pvt) {
04423 return;
04424 }
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04438 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04439 (f->datalen > sizeof(data))) {
04440
04441 return;
04442 }
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458 memcpy(&data, f->data, f->datalen);
04459 data.ied.pos = ie_data_pos;
04460
04461
04462
04463 data.ied.pos -= pvt->calltoken_ie_len;
04464 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04465
04466
04467 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04468
04469
04470 AST_LIST_LOCK(&frame_queue);
04471 AST_LIST_REMOVE(&frame_queue, f, list);
04472 AST_LIST_UNLOCK(&frame_queue);
04473
04474
04475 iax2_frame_free(f);
04476
04477
04478 pvt->oseqno = 0;
04479 pvt->rseqno = 0;
04480 pvt->iseqno = 0;
04481 pvt->aseqno = 0;
04482 if (pvt->peercallno) {
04483 remove_by_peercallno(pvt);
04484 pvt->peercallno = 0;
04485 }
04486
04487
04488 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04489 }
04490
04491 static void requirecalltoken_mark_auto(const char *name, int subclass)
04492 {
04493 struct iax2_user *user = NULL;
04494 struct iax2_peer *peer = NULL;
04495
04496 if (ast_strlen_zero(name)) {
04497 return;
04498 }
04499
04500 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04501 user->calltoken_required = CALLTOKEN_YES;
04502 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04503 peer->calltoken_required = CALLTOKEN_YES;
04504 }
04505
04506 if (peer) {
04507 peer_unref(peer);
04508 }
04509 if (user) {
04510 user_unref(user);
04511 }
04512 }
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530
04531 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04532 struct sockaddr_in *sin, int fd)
04533 {
04534 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04535 #define CALLTOKEN_IE_FORMAT "%u?%s"
04536 struct ast_str *buf = ast_str_alloca(256);
04537 time_t t = time(NULL);
04538 char hash[41];
04539 int subclass = uncompress_subclass(fh->csub);
04540
04541
04542 if (ies->calltoken && !ies->calltokendata) {
04543 struct iax_ie_data ied = {
04544 .buf = { 0 },
04545 .pos = 0,
04546 };
04547
04548
04549 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04550 ast_sha1_hash(hash, ast_str_buffer(buf));
04551
04552 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04553 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04554 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04555
04556 return 1;
04557
04558
04559 } else if (ies->calltoken && ies->calltokendata) {
04560 char *rec_hash = NULL;
04561 char *rec_ts = NULL;
04562 unsigned int rec_time;
04563
04564
04565 rec_hash = strchr((char *) ies->calltokendata, '?');
04566 if (rec_hash) {
04567 *rec_hash++ = '\0';
04568 rec_ts = (char *) ies->calltokendata;
04569 }
04570
04571
04572 if (!rec_hash || !rec_ts) {
04573 goto reject;
04574 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04575 goto reject;
04576 }
04577
04578
04579 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04580 ast_sha1_hash(hash, ast_str_buffer(buf));
04581
04582
04583 if (strcmp(hash, rec_hash)) {
04584 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04585 goto reject;
04586 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04587 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04588 goto reject;
04589 }
04590
04591
04592
04593 requirecalltoken_mark_auto(ies->username, subclass);
04594 return 0;
04595
04596
04597 } else {
04598 if (calltoken_required(sin, ies->username, subclass)) {
04599 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest"));
04600 goto reject;
04601 }
04602 return 0;
04603 }
04604
04605 reject:
04606
04607 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04608 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04609 } else {
04610 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04611 }
04612
04613 return 1;
04614 }
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04635 {
04636 if (ast_strlen_zero(data))
04637 return;
04638
04639 pds->peer = strsep(&data, "/");
04640 pds->exten = strsep(&data, "/");
04641 pds->options = data;
04642
04643 if (pds->exten) {
04644 data = pds->exten;
04645 pds->exten = strsep(&data, "@");
04646 pds->context = data;
04647 }
04648
04649 if (strchr(pds->peer, '@')) {
04650 data = pds->peer;
04651 pds->username = strsep(&data, "@");
04652 pds->peer = data;
04653 }
04654
04655 if (pds->username) {
04656 data = pds->username;
04657 pds->username = strsep(&data, ":");
04658 pds->password = data;
04659 }
04660
04661 data = pds->peer;
04662 pds->peer = strsep(&data, ":");
04663 pds->port = data;
04664
04665
04666
04667
04668 if (pds->password && (pds->password[0] == '[')) {
04669 pds->key = ast_strip_quoted(pds->password, "[", "]");
04670 pds->password = NULL;
04671 }
04672 }
04673
04674 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04675 {
04676 struct sockaddr_in sin;
04677 char *l=NULL, *n=NULL, *tmpstr;
04678 struct iax_ie_data ied;
04679 char *defaultrdest = "s";
04680 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04681 struct parsed_dial_string pds;
04682 struct create_addr_info cai;
04683 struct ast_var_t *var;
04684 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04685 const char* osp_token_ptr;
04686 unsigned int osp_token_length;
04687 unsigned char osp_block_index;
04688 unsigned int osp_block_length;
04689 unsigned char osp_buffer[256];
04690
04691 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
04692 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
04693 return -1;
04694 }
04695
04696 memset(&cai, 0, sizeof(cai));
04697 cai.encmethods = iax2_encryption;
04698
04699 memset(&pds, 0, sizeof(pds));
04700 tmpstr = ast_strdupa(dest);
04701 parse_dial_string(tmpstr, &pds);
04702
04703 if (ast_strlen_zero(pds.peer)) {
04704 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
04705 return -1;
04706 }
04707
04708 if (!pds.exten) {
04709 pds.exten = defaultrdest;
04710 }
04711
04712 if (create_addr(pds.peer, c, &sin, &cai)) {
04713 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
04714 return -1;
04715 }
04716
04717 if (!pds.username && !ast_strlen_zero(cai.username))
04718 pds.username = cai.username;
04719 if (!pds.password && !ast_strlen_zero(cai.secret))
04720 pds.password = cai.secret;
04721 if (!pds.key && !ast_strlen_zero(cai.outkey))
04722 pds.key = cai.outkey;
04723 if (!pds.context && !ast_strlen_zero(cai.peercontext))
04724 pds.context = cai.peercontext;
04725
04726
04727 ast_copy_string(c->context, cai.context, sizeof(c->context));
04728
04729 if (pds.port)
04730 sin.sin_port = htons(atoi(pds.port));
04731
04732 l = c->cid.cid_num;
04733 n = c->cid.cid_name;
04734
04735
04736 memset(&ied, 0, sizeof(ied));
04737
04738
04739 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
04740 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
04741 if (pds.options && strchr(pds.options, 'a')) {
04742
04743 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
04744 }
04745
04746 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
04747
04748 if (l) {
04749 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
04750 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04751 } else {
04752 if (n)
04753 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04754 else
04755 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
04756 }
04757
04758 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
04759 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
04760
04761 if (n)
04762 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
04763 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
04764 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
04765
04766 if (!ast_strlen_zero(c->language))
04767 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
04768 if (!ast_strlen_zero(c->cid.cid_dnid))
04769 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
04770 if (!ast_strlen_zero(c->cid.cid_rdnis))
04771 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
04772
04773 if (pds.context)
04774 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
04775
04776 if (pds.username)
04777 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
04778
04779 if (cai.encmethods)
04780 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
04781
04782 ast_mutex_lock(&iaxsl[callno]);
04783
04784 if (!ast_strlen_zero(c->context))
04785 ast_string_field_set(iaxs[callno], context, c->context);
04786
04787 if (pds.username)
04788 ast_string_field_set(iaxs[callno], username, pds.username);
04789
04790 iaxs[callno]->encmethods = cai.encmethods;
04791
04792 iaxs[callno]->adsi = cai.adsi;
04793
04794 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
04795 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
04796
04797 if (pds.key)
04798 ast_string_field_set(iaxs[callno], outkey, pds.key);
04799 if (pds.password)
04800 ast_string_field_set(iaxs[callno], secret, pds.password);
04801
04802 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
04803 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
04804 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
04805 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
04806
04807 if (iaxs[callno]->maxtime) {
04808
04809 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
04810 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
04811 } else if (autokill) {
04812 iaxs[callno]->pingtime = autokill / 2;
04813 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
04814 }
04815
04816
04817 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
04818 if (!ast_strlen_zero(osp_token_ptr)) {
04819 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
04820 osp_block_index = 0;
04821 while (osp_token_length > 0) {
04822 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
04823 osp_buffer[0] = osp_block_index;
04824 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
04825 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
04826 osp_block_index++;
04827 osp_token_ptr += osp_block_length;
04828 osp_token_length -= osp_block_length;
04829 }
04830 } else
04831 ast_log(LOG_WARNING, "OSP token is too long\n");
04832 } else if (iaxdebug)
04833 ast_debug(1, "OSP token is undefined\n");
04834
04835
04836 iaxs[callno]->sockfd = cai.sockfd;
04837
04838
04839 if (variablestore) {
04840 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
04841 ast_debug(1, "Found an IAX variable store on this channel\n");
04842 AST_LIST_LOCK(variablelist);
04843 AST_LIST_TRAVERSE(variablelist, var, entries) {
04844 char tmp[256];
04845 int i;
04846 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
04847
04848 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
04849 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
04850 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
04851 }
04852 }
04853 AST_LIST_UNLOCK(variablelist);
04854 }
04855
04856
04857 add_empty_calltoken_ie(iaxs[callno], &ied);
04858 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
04859
04860 ast_mutex_unlock(&iaxsl[callno]);
04861 ast_setstate(c, AST_STATE_RINGING);
04862
04863 return 0;
04864 }
04865
04866 static int iax2_hangup(struct ast_channel *c)
04867 {
04868 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04869 struct iax_ie_data ied;
04870 int alreadygone;
04871 memset(&ied, 0, sizeof(ied));
04872 ast_mutex_lock(&iaxsl[callno]);
04873 if (callno && iaxs[callno]) {
04874 ast_debug(1, "We're hanging up %s now...\n", c->name);
04875 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
04876
04877 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
04878 if (!iaxs[callno]->error && !alreadygone) {
04879 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
04880 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
04881 }
04882 if (!iaxs[callno]) {
04883 ast_mutex_unlock(&iaxsl[callno]);
04884 return 0;
04885 }
04886 }
04887
04888 iax2_predestroy(callno);
04889
04890 if (iaxs[callno] && alreadygone) {
04891 ast_debug(1, "Really destroying %s now...\n", c->name);
04892 iax2_destroy(callno);
04893 } else if (iaxs[callno]) {
04894 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
04895 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
04896 iax2_destroy(callno);
04897 }
04898 }
04899 } else if (c->tech_pvt) {
04900
04901
04902
04903
04904 c->tech_pvt = NULL;
04905 }
04906 ast_mutex_unlock(&iaxsl[callno]);
04907 ast_verb(3, "Hungup '%s'\n", c->name);
04908 return 0;
04909 }
04910
04911
04912
04913
04914 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
04915 {
04916 unsigned short callno = pvt->callno;
04917
04918 if (!pvt->peercallno) {
04919
04920 int count = 10;
04921 while (count-- && pvt && !pvt->peercallno) {
04922 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
04923 pvt = iaxs[callno];
04924 }
04925 if (!pvt->peercallno) {
04926 return -1;
04927 }
04928 }
04929
04930 return 0;
04931 }
04932
04933 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
04934 {
04935 struct ast_option_header *h;
04936 int res;
04937
04938 switch (option) {
04939 case AST_OPTION_TXGAIN:
04940 case AST_OPTION_RXGAIN:
04941
04942 errno = ENOSYS;
04943 return -1;
04944 default:
04945 {
04946 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04947 struct chan_iax2_pvt *pvt;
04948
04949 ast_mutex_lock(&iaxsl[callno]);
04950 pvt = iaxs[callno];
04951
04952 if (wait_for_peercallno(pvt)) {
04953 ast_mutex_unlock(&iaxsl[callno]);
04954 return -1;
04955 }
04956
04957 ast_mutex_unlock(&iaxsl[callno]);
04958
04959 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
04960 return -1;
04961 }
04962
04963 h->flag = AST_OPTION_FLAG_REQUEST;
04964 h->option = htons(option);
04965 memcpy(h->data, data, datalen);
04966 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
04967 AST_CONTROL_OPTION, 0, (unsigned char *) h,
04968 datalen + sizeof(*h), -1);
04969 ast_free(h);
04970 return res;
04971 }
04972 }
04973 }
04974
04975 static struct ast_frame *iax2_read(struct ast_channel *c)
04976 {
04977 ast_log(LOG_NOTICE, "I should never be called!\n");
04978 return &ast_null_frame;
04979 }
04980
04981 static int iax2_key_rotate(const void *vpvt)
04982 {
04983 int res = 0;
04984 struct chan_iax2_pvt *pvt = (void *) vpvt;
04985 struct MD5Context md5;
04986 char key[17] = "";
04987 struct iax_ie_data ied = {
04988 .pos = 0,
04989 };
04990
04991 ast_mutex_lock(&iaxsl[pvt->callno]);
04992 pvt->keyrotateid =
04993 ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
04994
04995 snprintf(key, sizeof(key), "%lX", ast_random());
04996
04997 MD5Init(&md5);
04998 MD5Update(&md5, (unsigned char *) key, strlen(key));
04999 MD5Final((unsigned char *) key, &md5);
05000
05001 IAX_DEBUGDIGEST("Sending", key);
05002
05003 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05004
05005 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05006
05007 build_ecx_key((unsigned char *) key, pvt);
05008
05009 ast_mutex_unlock(&iaxsl[pvt->callno]);
05010
05011 return res;
05012 }
05013
05014 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05015 {
05016 int res;
05017 struct iax_ie_data ied0;
05018 struct iax_ie_data ied1;
05019 unsigned int transferid = (unsigned int)ast_random();
05020
05021 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05022 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05023 ast_set_flag(iaxs[callno0], IAX_NOTRANSFER);
05024 ast_set_flag(iaxs[callno1], IAX_NOTRANSFER);
05025 return 0;
05026 }
05027
05028 memset(&ied0, 0, sizeof(ied0));
05029 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05030 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05031 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05032
05033 memset(&ied1, 0, sizeof(ied1));
05034 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05035 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05036 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05037
05038 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05039 if (res)
05040 return -1;
05041 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05042 if (res)
05043 return -1;
05044 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05045 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05046 return 0;
05047 }
05048
05049 static void lock_both(unsigned short callno0, unsigned short callno1)
05050 {
05051 ast_mutex_lock(&iaxsl[callno0]);
05052 while (ast_mutex_trylock(&iaxsl[callno1])) {
05053 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05054 }
05055 }
05056
05057 static void unlock_both(unsigned short callno0, unsigned short callno1)
05058 {
05059 ast_mutex_unlock(&iaxsl[callno1]);
05060 ast_mutex_unlock(&iaxsl[callno0]);
05061 }
05062
05063 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)
05064 {
05065 struct ast_channel *cs[3];
05066 struct ast_channel *who, *other;
05067 int to = -1;
05068 int res = -1;
05069 int transferstarted=0;
05070 struct ast_frame *f;
05071 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05072 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05073 struct timeval waittimer = {0, 0};
05074
05075
05076 if (timeoutms > 0) {
05077 return AST_BRIDGE_FAILED;
05078 }
05079
05080 timeoutms = -1;
05081
05082 lock_both(callno0, callno1);
05083 if (!iaxs[callno0] || !iaxs[callno1]) {
05084 unlock_both(callno0, callno1);
05085 return AST_BRIDGE_FAILED;
05086 }
05087
05088 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05089 iaxs[callno0]->bridgecallno = callno1;
05090 iaxs[callno1]->bridgecallno = callno0;
05091 }
05092 unlock_both(callno0, callno1);
05093
05094
05095 cs[0] = c0;
05096 cs[1] = c1;
05097 for (;;) {
05098
05099 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05100 ast_verb(3, "Can't masquerade, we're different...\n");
05101
05102 if (c0->tech == &iax2_tech) {
05103 ast_mutex_lock(&iaxsl[callno0]);
05104 iaxs[callno0]->bridgecallno = 0;
05105 ast_mutex_unlock(&iaxsl[callno0]);
05106 }
05107 if (c1->tech == &iax2_tech) {
05108 ast_mutex_lock(&iaxsl[callno1]);
05109 iaxs[callno1]->bridgecallno = 0;
05110 ast_mutex_unlock(&iaxsl[callno1]);
05111 }
05112 return AST_BRIDGE_FAILED_NOWARN;
05113 }
05114 if (c0->nativeformats != c1->nativeformats) {
05115 char buf0[255];
05116 char buf1[255];
05117 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
05118 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
05119 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
05120
05121 lock_both(callno0, callno1);
05122 if (iaxs[callno0])
05123 iaxs[callno0]->bridgecallno = 0;
05124 if (iaxs[callno1])
05125 iaxs[callno1]->bridgecallno = 0;
05126 unlock_both(callno0, callno1);
05127 return AST_BRIDGE_FAILED_NOWARN;
05128 }
05129
05130 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
05131
05132 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05133 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
05134 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05135 transferstarted = 1;
05136 }
05137 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05138
05139 struct timeval now = ast_tvnow();
05140 if (ast_tvzero(waittimer)) {
05141 waittimer = now;
05142 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05143 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05144 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05145 *fo = NULL;
05146 *rc = c0;
05147 res = AST_BRIDGE_COMPLETE;
05148 break;
05149 }
05150 }
05151 to = 1000;
05152 who = ast_waitfor_n(cs, 2, &to);
05153 if (timeoutms > -1) {
05154 timeoutms -= (1000 - to);
05155 if (timeoutms < 0)
05156 timeoutms = 0;
05157 }
05158 if (!who) {
05159 if (!timeoutms) {
05160 res = AST_BRIDGE_RETRY;
05161 break;
05162 }
05163 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05164 res = AST_BRIDGE_FAILED;
05165 break;
05166 }
05167 continue;
05168 }
05169 f = ast_read(who);
05170 if (!f) {
05171 *fo = NULL;
05172 *rc = who;
05173 res = AST_BRIDGE_COMPLETE;
05174 break;
05175 }
05176 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
05177 *fo = f;
05178 *rc = who;
05179 res = AST_BRIDGE_COMPLETE;
05180 break;
05181 }
05182 other = (who == c0) ? c1 : c0;
05183 if ((f->frametype == AST_FRAME_VOICE) ||
05184 (f->frametype == AST_FRAME_TEXT) ||
05185 (f->frametype == AST_FRAME_VIDEO) ||
05186 (f->frametype == AST_FRAME_IMAGE) ||
05187 (f->frametype == AST_FRAME_DTMF) ||
05188 (f->frametype == AST_FRAME_CONTROL)) {
05189
05190
05191
05192 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05193 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05194 *rc = who;
05195 *fo = f;
05196 res = AST_BRIDGE_COMPLETE;
05197
05198 break;
05199 }
05200
05201 ast_write(other, f);
05202 }
05203 ast_frfree(f);
05204
05205 cs[2] = cs[0];
05206 cs[0] = cs[1];
05207 cs[1] = cs[2];
05208 }
05209 lock_both(callno0, callno1);
05210 if(iaxs[callno0])
05211 iaxs[callno0]->bridgecallno = 0;
05212 if(iaxs[callno1])
05213 iaxs[callno1]->bridgecallno = 0;
05214 unlock_both(callno0, callno1);
05215 return res;
05216 }
05217
05218 static int iax2_answer(struct ast_channel *c)
05219 {
05220 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05221 ast_debug(1, "Answering IAX2 call\n");
05222 ast_mutex_lock(&iaxsl[callno]);
05223 if (iaxs[callno])
05224 iax2_ami_channelupdate(iaxs[callno]);
05225 ast_mutex_unlock(&iaxsl[callno]);
05226 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05227 }
05228
05229 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05230 {
05231 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05232 struct chan_iax2_pvt *pvt;
05233 int res = 0;
05234
05235 if (iaxdebug)
05236 ast_debug(1, "Indicating condition %d\n", condition);
05237
05238 ast_mutex_lock(&iaxsl[callno]);
05239 pvt = iaxs[callno];
05240
05241 if (wait_for_peercallno(pvt)) {
05242 res = -1;
05243 goto done;
05244 }
05245
05246 switch (condition) {
05247 case AST_CONTROL_HOLD:
05248 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05249 ast_moh_start(c, data, pvt->mohinterpret);
05250 goto done;
05251 }
05252 break;
05253 case AST_CONTROL_UNHOLD:
05254 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05255 ast_moh_stop(c);
05256 goto done;
05257 }
05258 }
05259
05260 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05261
05262 done:
05263 ast_mutex_unlock(&iaxsl[callno]);
05264
05265 return res;
05266 }
05267
05268 static int iax2_transfer(struct ast_channel *c, const char *dest)
05269 {
05270 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05271 struct iax_ie_data ied = { "", };
05272 char tmp[256], *context;
05273 ast_copy_string(tmp, dest, sizeof(tmp));
05274 context = strchr(tmp, '@');
05275 if (context) {
05276 *context = '\0';
05277 context++;
05278 }
05279 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05280 if (context)
05281 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05282 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05283 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05284 }
05285
05286 static int iax2_getpeertrunk(struct sockaddr_in sin)
05287 {
05288 struct iax2_peer *peer;
05289 int res = 0;
05290 struct ao2_iterator i;
05291
05292 i = ao2_iterator_init(peers, 0);
05293 while ((peer = ao2_iterator_next(&i))) {
05294 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05295 (peer->addr.sin_port == sin.sin_port)) {
05296 res = ast_test_flag(peer, IAX_TRUNK);
05297 peer_unref(peer);
05298 break;
05299 }
05300 peer_unref(peer);
05301 }
05302 ao2_iterator_destroy(&i);
05303
05304 return res;
05305 }
05306
05307
05308 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
05309 {
05310 struct ast_channel *tmp;
05311 struct chan_iax2_pvt *i;
05312 struct ast_variable *v = NULL;
05313
05314 if (!(i = iaxs[callno])) {
05315 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05316 return NULL;
05317 }
05318
05319
05320 ast_mutex_unlock(&iaxsl[callno]);
05321 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);
05322 ast_mutex_lock(&iaxsl[callno]);
05323 if (i != iaxs[callno]) {
05324 if (tmp) {
05325
05326 ast_mutex_unlock(&iaxsl[callno]);
05327 ast_channel_free(tmp);
05328 ast_mutex_lock(&iaxsl[callno]);
05329 }
05330 return NULL;
05331 }
05332 iax2_ami_channelupdate(i);
05333 if (!tmp)
05334 return NULL;
05335 tmp->tech = &iax2_tech;
05336
05337 tmp->nativeformats = capability;
05338 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05339 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05340 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05341
05342 if (!ast_strlen_zero(i->parkinglot))
05343 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05344
05345
05346 if (!ast_strlen_zero(i->ani))
05347 tmp->cid.cid_ani = ast_strdup(i->ani);
05348 else
05349 tmp->cid.cid_ani = ast_strdup(i->cid_num);
05350 tmp->cid.cid_dnid = ast_strdup(i->dnid);
05351 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05352 tmp->cid.cid_pres = i->calling_pres;
05353 tmp->cid.cid_ton = i->calling_ton;
05354 tmp->cid.cid_tns = i->calling_tns;
05355 if (!ast_strlen_zero(i->language))
05356 ast_string_field_set(tmp, language, i->language);
05357 if (!ast_strlen_zero(i->accountcode))
05358 ast_string_field_set(tmp, accountcode, i->accountcode);
05359 if (i->amaflags)
05360 tmp->amaflags = i->amaflags;
05361 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05362 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05363 if (i->adsi)
05364 tmp->adsicpe = i->peeradsicpe;
05365 else
05366 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05367 i->owner = tmp;
05368 i->capability = capability;
05369
05370
05371 if (i->vars) {
05372 for (v = i->vars ; v ; v = v->next)
05373 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05374 }
05375 if (i->iaxvars) {
05376 struct ast_datastore *variablestore;
05377 struct ast_variable *var, *prev = NULL;
05378 AST_LIST_HEAD(, ast_var_t) *varlist;
05379 ast_debug(1, "Loading up the channel with IAXVARs\n");
05380 varlist = ast_calloc(1, sizeof(*varlist));
05381 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05382 if (variablestore && varlist) {
05383 variablestore->data = varlist;
05384 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05385 AST_LIST_HEAD_INIT(varlist);
05386 for (var = i->iaxvars; var; var = var->next) {
05387 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05388 if (prev)
05389 ast_free(prev);
05390 prev = var;
05391 if (!newvar) {
05392
05393 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05394 } else {
05395 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05396 }
05397 }
05398 if (prev)
05399 ast_free(prev);
05400 i->iaxvars = NULL;
05401 ast_channel_datastore_add(i->owner, variablestore);
05402 } else {
05403 if (variablestore) {
05404 ast_datastore_free(variablestore);
05405 }
05406 if (varlist) {
05407 ast_free(varlist);
05408 }
05409 }
05410 }
05411
05412 if (state != AST_STATE_DOWN) {
05413 if (ast_pbx_start(tmp)) {
05414 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05415 ast_hangup(tmp);
05416 i->owner = NULL;
05417 return NULL;
05418 }
05419 }
05420
05421 ast_module_ref(ast_module_info->self);
05422 return tmp;
05423 }
05424
05425 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05426 {
05427 unsigned long int mssincetx;
05428 long int ms, pred;
05429
05430 tpeer->trunkact = *now;
05431 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05432 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05433
05434 tpeer->txtrunktime = *now;
05435 tpeer->lastsent = 999999;
05436 }
05437
05438 tpeer->lasttxtime = *now;
05439
05440
05441 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05442
05443 pred = tpeer->lastsent + sampms;
05444 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05445 ms = pred;
05446
05447
05448 if (ms == tpeer->lastsent)
05449 ms = tpeer->lastsent + 1;
05450 tpeer->lastsent = ms;
05451 return ms;
05452 }
05453
05454 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05455 {
05456 long ms;
05457 if (ast_tvzero(iaxs[callno]->rxcore)) {
05458
05459 iaxs[callno]->rxcore = ast_tvnow();
05460
05461 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05462 }
05463
05464 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05465
05466 return ms + ts;
05467 }
05468
05469 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05470 {
05471 int ms;
05472 int voice = 0;
05473 int genuine = 0;
05474 int adjust;
05475 int rate = ast_format_rate(f->subclass) / 1000;
05476 struct timeval *delivery = NULL;
05477
05478
05479
05480
05481
05482
05483
05484
05485 if (f) {
05486 if (f->frametype == AST_FRAME_VOICE) {
05487 voice = 1;
05488 delivery = &f->delivery;
05489 } else if (f->frametype == AST_FRAME_IAX) {
05490 genuine = 1;
05491 } else if (f->frametype == AST_FRAME_CNG) {
05492 p->notsilenttx = 0;
05493 }
05494 }
05495 if (ast_tvzero(p->offset)) {
05496 p->offset = ast_tvnow();
05497
05498 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05499 }
05500
05501 if (ts)
05502 return ts;
05503
05504 if (delivery && !ast_tvzero(*delivery)) {
05505 ms = ast_tvdiff_ms(*delivery, p->offset);
05506 if (ms < 0) {
05507 ms = 0;
05508 }
05509 if (iaxdebug)
05510 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05511 } else {
05512 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05513 if (ms < 0)
05514 ms = 0;
05515 if (voice) {
05516
05517 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05518
05519
05520
05521
05522
05523
05524
05525
05526
05527
05528
05529
05530
05531
05532
05533
05534
05535
05536 adjust = (ms - p->nextpred);
05537 if (adjust < 0)
05538 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05539 else if (adjust > 0)
05540 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05541
05542 if (!p->nextpred) {
05543 p->nextpred = ms;
05544 if (p->nextpred <= p->lastsent)
05545 p->nextpred = p->lastsent + 3;
05546 }
05547 ms = p->nextpred;
05548 } else {
05549
05550
05551
05552
05553
05554
05555
05556
05557
05558 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05559 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05560 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05561
05562 if (f->samples >= rate)
05563 {
05564 int diff = ms % (f->samples / rate);
05565 if (diff)
05566 ms += f->samples/rate - diff;
05567 }
05568
05569 p->nextpred = ms;
05570 p->notsilenttx = 1;
05571 }
05572 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05573
05574
05575
05576
05577
05578
05579
05580
05581 if ( (unsigned int)ms < p->lastsent )
05582 ms = p->lastsent;
05583 } else {
05584
05585
05586 if (genuine) {
05587
05588 if (ms <= p->lastsent)
05589 ms = p->lastsent + 3;
05590 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05591
05592 ms = p->lastsent + 3;
05593 }
05594 }
05595 }
05596 p->lastsent = ms;
05597 if (voice)
05598 p->nextpred = p->nextpred + f->samples / rate;
05599 return ms;
05600 }
05601
05602 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05603 {
05604
05605
05606 int ms;
05607 #ifdef IAXTESTS
05608 int jit;
05609 #endif
05610
05611 if (ast_tvzero(p->rxcore)) {
05612 p->rxcore = ast_tvnow();
05613 if (iaxdebug)
05614 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05615 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05616 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05617 #if 1
05618 if (iaxdebug)
05619 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05620 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05621 #endif
05622 }
05623
05624 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05625 #ifdef IAXTESTS
05626 if (test_jit) {
05627 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05628 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05629 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05630 jit = -jit;
05631 ms += jit;
05632 }
05633 }
05634 if (test_late) {
05635 ms += test_late;
05636 test_late = 0;
05637 }
05638 #endif
05639 return ms;
05640 }
05641
05642 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
05643 {
05644 struct iax2_trunk_peer *tpeer = NULL;
05645
05646
05647 AST_LIST_LOCK(&tpeers);
05648
05649 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
05650 if (!inaddrcmp(&tpeer->addr, sin)) {
05651 ast_mutex_lock(&tpeer->lock);
05652 break;
05653 }
05654 }
05655
05656 if (!tpeer) {
05657 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
05658 ast_mutex_init(&tpeer->lock);
05659 tpeer->lastsent = 9999;
05660 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
05661 tpeer->trunkact = ast_tvnow();
05662 ast_mutex_lock(&tpeer->lock);
05663 tpeer->sockfd = fd;
05664 #ifdef SO_NO_CHECK
05665 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
05666 #endif
05667 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05668 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
05669 }
05670 }
05671
05672 AST_LIST_UNLOCK(&tpeers);
05673
05674 return tpeer;
05675 }
05676
05677 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
05678 {
05679 struct ast_frame *f;
05680 struct iax2_trunk_peer *tpeer;
05681 void *tmp, *ptr;
05682 struct timeval now;
05683 int res;
05684 struct ast_iax2_meta_trunk_entry *met;
05685 struct ast_iax2_meta_trunk_mini *mtm;
05686
05687 f = &fr->af;
05688 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
05689 if (tpeer) {
05690 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
05691
05692 if (tpeer->trunkdataalloc < trunkmaxsize) {
05693 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
05694 ast_mutex_unlock(&tpeer->lock);
05695 return -1;
05696 }
05697
05698 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
05699 tpeer->trunkdata = tmp;
05700 ast_debug(1, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
05701 } else {
05702 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));
05703 ast_mutex_unlock(&tpeer->lock);
05704 return -1;
05705 }
05706 }
05707
05708
05709 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
05710 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
05711 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
05712 mtm->len = htons(f->datalen);
05713 mtm->mini.callno = htons(pvt->callno);
05714 mtm->mini.ts = htons(0xffff & fr->ts);
05715 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
05716 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
05717 } else {
05718 met = (struct ast_iax2_meta_trunk_entry *)ptr;
05719
05720 met->callno = htons(pvt->callno);
05721 met->len = htons(f->datalen);
05722
05723 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
05724 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
05725 }
05726
05727 memcpy(ptr, f->data.ptr, f->datalen);
05728 tpeer->trunkdatalen += f->datalen;
05729
05730 tpeer->calls++;
05731
05732
05733 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
05734 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
05735
05736
05737 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
05738 now = ast_tvnow();
05739 res = send_trunk(tpeer, &now);
05740 trunk_untimed ++;
05741 }
05742
05743 ast_mutex_unlock(&tpeer->lock);
05744 }
05745 return 0;
05746 }
05747
05748
05749
05750 static void build_rand_pad(unsigned char *buf, ssize_t len)
05751 {
05752 long tmp;
05753 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05754 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05755 buf += sizeof(tmp);
05756 len -= sizeof(tmp);
05757 }
05758 }
05759
05760 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05761 {
05762 build_ecx_key(digest, pvt);
05763 ast_aes_decrypt_key(digest, &pvt->dcx);
05764 }
05765
05766 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05767 {
05768
05769
05770
05771 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05772 ast_aes_encrypt_key(digest, &pvt->ecx);
05773 ast_aes_decrypt_key(digest, &pvt->mydcx);
05774 }
05775
05776 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
05777 {
05778 #if 0
05779
05780 int x;
05781 if (len % 16)
05782 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05783 for (x=0;x<len;x++)
05784 dst[x] = src[x] ^ 0xff;
05785 #else
05786 unsigned char lastblock[16] = { 0 };
05787 int x;
05788 while(len > 0) {
05789 ast_aes_decrypt(src, dst, dcx);
05790 for (x=0;x<16;x++)
05791 dst[x] ^= lastblock[x];
05792 memcpy(lastblock, src, sizeof(lastblock));
05793 dst += 16;
05794 src += 16;
05795 len -= 16;
05796 }
05797 #endif
05798 }
05799
05800 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
05801 {
05802 #if 0
05803
05804 int x;
05805 if (len % 16)
05806 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05807 for (x=0;x<len;x++)
05808 dst[x] = src[x] ^ 0xff;
05809 #else
05810 unsigned char curblock[16] = { 0 };
05811 int x;
05812 while(len > 0) {
05813 for (x=0;x<16;x++)
05814 curblock[x] ^= src[x];
05815 ast_aes_encrypt(curblock, dst, ecx);
05816 memcpy(curblock, dst, sizeof(curblock));
05817 dst += 16;
05818 src += 16;
05819 len -= 16;
05820 }
05821 #endif
05822 }
05823
05824 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05825 {
05826 int padding;
05827 unsigned char *workspace;
05828
05829 workspace = alloca(*datalen);
05830 memset(f, 0, sizeof(*f));
05831 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05832 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05833 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
05834 return -1;
05835
05836 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
05837
05838 padding = 16 + (workspace[15] & 0x0f);
05839 if (iaxdebug)
05840 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
05841 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
05842 return -1;
05843
05844 *datalen -= padding;
05845 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05846 f->frametype = fh->type;
05847 if (f->frametype == AST_FRAME_VIDEO) {
05848 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
05849 } else {
05850 f->subclass = uncompress_subclass(fh->csub);
05851 }
05852 } else {
05853 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05854 if (iaxdebug)
05855 ast_debug(1, "Decoding mini with length %d\n", *datalen);
05856 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
05857 return -1;
05858
05859 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
05860 padding = 16 + (workspace[15] & 0x0f);
05861 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
05862 return -1;
05863 *datalen -= padding;
05864 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05865 }
05866 return 0;
05867 }
05868
05869 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
05870 {
05871 int padding;
05872 unsigned char *workspace;
05873 workspace = alloca(*datalen + 32);
05874 if (!workspace)
05875 return -1;
05876 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05877 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05878 if (iaxdebug)
05879 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
05880 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
05881 padding = 16 + (padding & 0xf);
05882 memcpy(workspace, poo, padding);
05883 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05884 workspace[15] &= 0xf0;
05885 workspace[15] |= (padding & 0xf);
05886 if (iaxdebug)
05887 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
05888 *datalen += padding;
05889 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
05890 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
05891 memcpy(poo, workspace + *datalen - 32, 32);
05892 } else {
05893 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05894 if (iaxdebug)
05895 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
05896 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
05897 padding = 16 + (padding & 0xf);
05898 memcpy(workspace, poo, padding);
05899 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05900 workspace[15] &= 0xf0;
05901 workspace[15] |= (padding & 0x0f);
05902 *datalen += padding;
05903 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
05904 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
05905 memcpy(poo, workspace + *datalen - 32, 32);
05906 }
05907 return 0;
05908 }
05909
05910 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05911 {
05912 int res=-1;
05913 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
05914
05915 struct MD5Context md5;
05916 unsigned char digest[16];
05917 char *tmppw, *stringp;
05918
05919 tmppw = ast_strdupa(iaxs[callno]->secret);
05920 stringp = tmppw;
05921 while ((tmppw = strsep(&stringp, ";"))) {
05922 MD5Init(&md5);
05923 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05924 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05925 MD5Final(digest, &md5);
05926 build_encryption_keys(digest, iaxs[callno]);
05927 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05928 if (!res) {
05929 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
05930 break;
05931 }
05932 }
05933 } else
05934 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05935 return res;
05936 }
05937
05938 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
05939 {
05940
05941
05942
05943 struct ast_iax2_full_hdr *fh;
05944 struct ast_iax2_mini_hdr *mh;
05945 struct ast_iax2_video_hdr *vh;
05946 struct {
05947 struct iax_frame fr2;
05948 unsigned char buffer[4096];
05949 } frb;
05950 struct iax_frame *fr;
05951 int res;
05952 int sendmini=0;
05953 unsigned int lastsent;
05954 unsigned int fts;
05955
05956 frb.fr2.afdatalen = sizeof(frb.buffer);
05957
05958 if (!pvt) {
05959 ast_log(LOG_WARNING, "No private structure for packet?\n");
05960 return -1;
05961 }
05962
05963 lastsent = pvt->lastsent;
05964
05965
05966 fts = calc_timestamp(pvt, ts, f);
05967
05968
05969
05970
05971 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
05972 return 0;
05973 #if 0
05974 ast_log(LOG_NOTICE,
05975 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
05976 *("=!" + (f->frametype == AST_FRAME_VOICE)),
05977 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
05978 pvt->keyrotateid != -1 ? "" : "no "
05979 );
05980 #endif
05981 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
05982 iax2_key_rotate(pvt);
05983 }
05984
05985 if ((ast_test_flag(pvt, IAX_TRUNK) ||
05986 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
05987 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
05988 &&
05989 (f->frametype == AST_FRAME_VOICE)
05990 &&
05991 (f->subclass == pvt->svoiceformat)
05992 ) {
05993
05994 now = 1;
05995
05996 sendmini = 1;
05997 }
05998 if ( f->frametype == AST_FRAME_VIDEO ) {
05999
06000
06001
06002
06003
06004 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06005 ((f->subclass & ~0x1) == pvt->svideoformat)
06006 ) {
06007 now = 1;
06008 sendmini = 1;
06009 } else {
06010 now = 0;
06011 sendmini = 0;
06012 }
06013 pvt->lastvsent = fts;
06014 }
06015 if (f->frametype == AST_FRAME_IAX) {
06016
06017 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
06018 if (!pvt->first_iax_message) {
06019 pvt->first_iax_message = pvt->last_iax_message;
06020 }
06021 }
06022
06023 if (now) {
06024 fr = &frb.fr2;
06025 } else
06026 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));
06027 if (!fr) {
06028 ast_log(LOG_WARNING, "Out of memory\n");
06029 return -1;
06030 }
06031
06032 iax_frame_wrap(fr, f);
06033
06034 fr->ts = fts;
06035 fr->callno = pvt->callno;
06036 fr->transfer = transfer;
06037 fr->final = final;
06038 fr->encmethods = 0;
06039 if (!sendmini) {
06040
06041 if (seqno > -1)
06042 fr->oseqno = seqno;
06043 else
06044 fr->oseqno = pvt->oseqno++;
06045 fr->iseqno = pvt->iseqno;
06046 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06047 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06048 fh->ts = htonl(fr->ts);
06049 fh->oseqno = fr->oseqno;
06050 if (transfer) {
06051 fh->iseqno = 0;
06052 } else
06053 fh->iseqno = fr->iseqno;
06054
06055 if (!transfer)
06056 pvt->aseqno = fr->iseqno;
06057 fh->type = fr->af.frametype & 0xFF;
06058 if (fr->af.frametype == AST_FRAME_VIDEO)
06059 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
06060 else
06061 fh->csub = compress_subclass(fr->af.subclass);
06062 if (transfer) {
06063 fr->dcallno = pvt->transfercallno;
06064 } else
06065 fr->dcallno = pvt->peercallno;
06066 fh->dcallno = htons(fr->dcallno);
06067 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06068 fr->data = fh;
06069 fr->retries = 0;
06070
06071 fr->retrytime = pvt->pingtime * 2;
06072 if (fr->retrytime < MIN_RETRY_TIME)
06073 fr->retrytime = MIN_RETRY_TIME;
06074 if (fr->retrytime > MAX_RETRY_TIME)
06075 fr->retrytime = MAX_RETRY_TIME;
06076
06077 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
06078 fr->retries = -1;
06079 else if (f->frametype == AST_FRAME_VOICE)
06080 pvt->svoiceformat = f->subclass;
06081 else if (f->frametype == AST_FRAME_VIDEO)
06082 pvt->svideoformat = f->subclass & ~0x1;
06083 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06084 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06085 if (fr->transfer)
06086 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06087 else
06088 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06089 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06090 fr->encmethods = pvt->encmethods;
06091 fr->ecx = pvt->ecx;
06092 fr->mydcx = pvt->mydcx;
06093 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06094 } else
06095 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06096 }
06097
06098 if (now) {
06099 res = send_packet(fr);
06100 } else
06101 res = iax2_transmit(fr);
06102 } else {
06103 if (ast_test_flag(pvt, IAX_TRUNK)) {
06104 iax2_trunk_queue(pvt, fr);
06105 res = 0;
06106 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06107
06108 fr->oseqno = -1;
06109 fr->iseqno = -1;
06110 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06111 vh->zeros = 0;
06112 vh->callno = htons(0x8000 | fr->callno);
06113 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
06114 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06115 fr->data = vh;
06116 fr->retries = -1;
06117 res = send_packet(fr);
06118 } else {
06119
06120 fr->oseqno = -1;
06121 fr->iseqno = -1;
06122
06123 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06124 mh->callno = htons(fr->callno);
06125 mh->ts = htons(fr->ts & 0xFFFF);
06126 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06127 fr->data = mh;
06128 fr->retries = -1;
06129 if (pvt->transferring == TRANSFER_MEDIAPASS)
06130 fr->transfer = 1;
06131 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06132 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06133 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06134 } else
06135 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06136 }
06137 res = send_packet(fr);
06138 }
06139 }
06140 return res;
06141 }
06142
06143 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06144 {
06145 regex_t regexbuf;
06146 int havepattern = 0;
06147
06148 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06149 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06150
06151 struct iax2_user *user = NULL;
06152 char auth[90];
06153 char *pstr = "";
06154 struct ao2_iterator i;
06155
06156 switch (cmd) {
06157 case CLI_INIT:
06158 e->command = "iax2 show users [like]";
06159 e->usage =
06160 "Usage: iax2 show users [like <pattern>]\n"
06161 " Lists all known IAX2 users.\n"
06162 " Optional regular expression pattern is used to filter the user list.\n";
06163 return NULL;
06164 case CLI_GENERATE:
06165 return NULL;
06166 }
06167
06168 switch (a->argc) {
06169 case 5:
06170 if (!strcasecmp(a->argv[3], "like")) {
06171 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06172 return CLI_SHOWUSAGE;
06173 havepattern = 1;
06174 } else
06175 return CLI_SHOWUSAGE;
06176 case 3:
06177 break;
06178 default:
06179 return CLI_SHOWUSAGE;
06180 }
06181
06182 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06183 i = ao2_iterator_init(users, 0);
06184 for (user = ao2_iterator_next(&i); user;
06185 user_unref(user), user = ao2_iterator_next(&i)) {
06186 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06187 continue;
06188
06189 if (!ast_strlen_zero(user->secret)) {
06190 ast_copy_string(auth,user->secret, sizeof(auth));
06191 } else if (!ast_strlen_zero(user->inkeys)) {
06192 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06193 } else
06194 ast_copy_string(auth, "-no secret-", sizeof(auth));
06195
06196 if(ast_test_flag(user,IAX_CODEC_NOCAP))
06197 pstr = "REQ Only";
06198 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
06199 pstr = "Disabled";
06200 else
06201 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06202
06203 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06204 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06205 user->ha ? "Yes" : "No", pstr);
06206 }
06207 ao2_iterator_destroy(&i);
06208
06209 if (havepattern)
06210 regfree(®exbuf);
06211
06212 return CLI_SUCCESS;
06213 #undef FORMAT
06214 #undef FORMAT2
06215 }
06216
06217 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
06218 {
06219 regex_t regexbuf;
06220 int havepattern = 0;
06221 int total_peers = 0;
06222 int online_peers = 0;
06223 int offline_peers = 0;
06224 int unmonitored_peers = 0;
06225 struct ao2_iterator i;
06226
06227 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
06228 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
06229
06230 struct iax2_peer *peer = NULL;
06231 char name[256];
06232 int registeredonly=0;
06233 char *term = manager ? "\r\n" : "\n";
06234 char idtext[256] = "";
06235 switch (argc) {
06236 case 6:
06237 if (!strcasecmp(argv[3], "registered"))
06238 registeredonly = 1;
06239 else
06240 return RESULT_SHOWUSAGE;
06241 if (!strcasecmp(argv[4], "like")) {
06242 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06243 return RESULT_SHOWUSAGE;
06244 havepattern = 1;
06245 } else
06246 return RESULT_SHOWUSAGE;
06247 break;
06248 case 5:
06249 if (!strcasecmp(argv[3], "like")) {
06250 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06251 return RESULT_SHOWUSAGE;
06252 havepattern = 1;
06253 } else
06254 return RESULT_SHOWUSAGE;
06255 break;
06256 case 4:
06257 if (!strcasecmp(argv[3], "registered"))
06258 registeredonly = 1;
06259 else
06260 return RESULT_SHOWUSAGE;
06261 break;
06262 case 3:
06263 break;
06264 default:
06265 return RESULT_SHOWUSAGE;
06266 }
06267
06268
06269 if (!s)
06270 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
06271
06272 i = ao2_iterator_init(peers, 0);
06273 for (peer = ao2_iterator_next(&i); peer;
06274 peer_unref(peer), peer = ao2_iterator_next(&i)) {
06275 char nm[20];
06276 char status[20];
06277 char srch[2000];
06278 int retstatus;
06279
06280 if (registeredonly && !peer->addr.sin_addr.s_addr)
06281 continue;
06282 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
06283 continue;
06284
06285 if (!ast_strlen_zero(peer->username))
06286 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06287 else
06288 ast_copy_string(name, peer->name, sizeof(name));
06289
06290 retstatus = peer_status(peer, status, sizeof(status));
06291 if (retstatus > 0)
06292 online_peers++;
06293 else if (!retstatus)
06294 offline_peers++;
06295 else
06296 unmonitored_peers++;
06297
06298 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06299
06300 snprintf(srch, sizeof(srch), FORMAT, name,
06301 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06302 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06303 nm,
06304 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
06305 peer->encmethods ? "(E)" : " ", status, term);
06306
06307 if (s)
06308 astman_append(s,
06309 "Event: PeerEntry\r\n%s"
06310 "Channeltype: IAX2\r\n"
06311 "ChanObjectType: peer\r\n"
06312 "ObjectName: %s\r\n"
06313 "IPaddress: %s\r\n"
06314 "IPport: %d\r\n"
06315 "Dynamic: %s\r\n"
06316 "Status: %s\r\n\r\n",
06317 idtext,
06318 name,
06319 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
06320 ntohs(peer->addr.sin_port),
06321 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
06322 status);
06323
06324 else
06325 ast_cli(fd, FORMAT, name,
06326 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06327 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06328 nm,
06329 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
06330 peer->encmethods ? "(E)" : " ", status, term);
06331 total_peers++;
06332 }
06333 ao2_iterator_destroy(&i);
06334
06335 if (!s)
06336 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
06337
06338 if (havepattern)
06339 regfree(®exbuf);
06340
06341 return RESULT_SUCCESS;
06342 #undef FORMAT
06343 #undef FORMAT2
06344 }
06345
06346 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06347 {
06348 struct iax2_thread *thread = NULL;
06349 time_t t;
06350 int threadcount = 0, dynamiccount = 0;
06351 char type;
06352
06353 switch (cmd) {
06354 case CLI_INIT:
06355 e->command = "iax2 show threads";
06356 e->usage =
06357 "Usage: iax2 show threads\n"
06358 " Lists status of IAX helper threads\n";
06359 return NULL;
06360 case CLI_GENERATE:
06361 return NULL;
06362 }
06363 if (a->argc != 3)
06364 return CLI_SHOWUSAGE;
06365
06366 ast_cli(a->fd, "IAX2 Thread Information\n");
06367 time(&t);
06368 ast_cli(a->fd, "Idle Threads:\n");
06369 AST_LIST_LOCK(&idle_list);
06370 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06371 #ifdef DEBUG_SCHED_MULTITHREAD
06372 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06373 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06374 #else
06375 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06376 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06377 #endif
06378 threadcount++;
06379 }
06380 AST_LIST_UNLOCK(&idle_list);
06381 ast_cli(a->fd, "Active Threads:\n");
06382 AST_LIST_LOCK(&active_list);
06383 AST_LIST_TRAVERSE(&active_list, thread, list) {
06384 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06385 type = 'D';
06386 else
06387 type = 'P';
06388 #ifdef DEBUG_SCHED_MULTITHREAD
06389 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06390 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06391 #else
06392 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06393 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06394 #endif
06395 threadcount++;
06396 }
06397 AST_LIST_UNLOCK(&active_list);
06398 ast_cli(a->fd, "Dynamic Threads:\n");
06399 AST_LIST_LOCK(&dynamic_list);
06400 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06401 #ifdef DEBUG_SCHED_MULTITHREAD
06402 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06403 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06404 #else
06405 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06406 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06407 #endif
06408 dynamiccount++;
06409 }
06410 AST_LIST_UNLOCK(&dynamic_list);
06411 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06412 return CLI_SUCCESS;
06413 }
06414
06415 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06416 {
06417 struct iax2_peer *p;
06418
06419 switch (cmd) {
06420 case CLI_INIT:
06421 e->command = "iax2 unregister";
06422 e->usage =
06423 "Usage: iax2 unregister <peername>\n"
06424 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06425 return NULL;
06426 case CLI_GENERATE:
06427 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06428 }
06429
06430 if (a->argc != 3)
06431 return CLI_SHOWUSAGE;
06432
06433 p = find_peer(a->argv[2], 1);
06434 if (p) {
06435 if (p->expire > 0) {
06436 struct iax2_peer tmp_peer = {
06437 .name = a->argv[2],
06438 };
06439 struct iax2_peer *peer;
06440
06441 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06442 if (peer) {
06443 expire_registry(peer_ref(peer));
06444 peer_unref(peer);
06445 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06446 } else {
06447 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06448 }
06449 } else {
06450 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06451 }
06452 } else {
06453 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06454 }
06455 return CLI_SUCCESS;
06456 }
06457
06458 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06459 {
06460 int which = 0;
06461 struct iax2_peer *p = NULL;
06462 char *res = NULL;
06463 int wordlen = strlen(word);
06464
06465
06466 if (pos == 2) {
06467 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06468 while ((p = ao2_iterator_next(&i))) {
06469 if (!strncasecmp(p->name, word, wordlen) &&
06470 ++which > state && p->expire > 0) {
06471 res = ast_strdup(p->name);
06472 peer_unref(p);
06473 break;
06474 }
06475 peer_unref(p);
06476 }
06477 ao2_iterator_destroy(&i);
06478 }
06479
06480 return res;
06481 }
06482
06483 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06484 {
06485 switch (cmd) {
06486 case CLI_INIT:
06487 e->command = "iax2 show peers";
06488 e->usage =
06489 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06490 " Lists all known IAX2 peers.\n"
06491 " Optional 'registered' argument lists only peers with known addresses.\n"
06492 " Optional regular expression pattern is used to filter the peer list.\n";
06493 return NULL;
06494 case CLI_GENERATE:
06495 return NULL;
06496 }
06497
06498 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
06499 case RESULT_SHOWUSAGE:
06500 return CLI_SHOWUSAGE;
06501 case RESULT_FAILURE:
06502 return CLI_FAILURE;
06503 default:
06504 return CLI_SUCCESS;
06505 }
06506 }
06507
06508 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06509 {
06510 ast_cli_netstats(s, -1, 0);
06511 astman_append(s, "\r\n");
06512 return RESULT_SUCCESS;
06513 }
06514
06515 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06516 {
06517 struct iax_firmware *cur = NULL;
06518
06519 switch (cmd) {
06520 case CLI_INIT:
06521 e->command = "iax2 show firmware";
06522 e->usage =
06523 "Usage: iax2 show firmware\n"
06524 " Lists all known IAX firmware images.\n";
06525 return NULL;
06526 case CLI_GENERATE:
06527 return NULL;
06528 }
06529
06530 if (a->argc != 3 && a->argc != 4)
06531 return CLI_SHOWUSAGE;
06532
06533 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06534 AST_LIST_LOCK(&firmwares);
06535 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06536 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06537 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06538 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06539 }
06540 }
06541 AST_LIST_UNLOCK(&firmwares);
06542
06543 return CLI_SUCCESS;
06544 }
06545
06546
06547 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06548 {
06549 char *a[] = { "iax2", "show", "users" };
06550 const char *id = astman_get_header(m,"ActionID");
06551 char idtext[256] = "";
06552
06553 if (!ast_strlen_zero(id))
06554 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06555 astman_send_ack(s, m, "Peer status list will follow");
06556 return __iax2_show_peers(1, -1, s, 3, a );
06557 }
06558
06559
06560 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06561 {
06562 struct iax2_peer *peer = NULL;
06563 int peer_count = 0;
06564 char nm[20];
06565 char status[20];
06566 const char *id = astman_get_header(m,"ActionID");
06567 char idtext[256] = "";
06568 struct ao2_iterator i;
06569
06570 if (!ast_strlen_zero(id))
06571 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06572
06573 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06574
06575
06576 i = ao2_iterator_init(peers, 0);
06577 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06578
06579 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06580 if (!ast_strlen_zero(peer->username)) {
06581 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06582 } else {
06583 astman_append(s, "ObjectName: %s\r\n", peer->name);
06584 }
06585 astman_append(s, "ChanObjectType: peer\r\n");
06586 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
06587 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06588 astman_append(s, "Mask: %s\r\n", nm);
06589 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
06590 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
06591 peer_status(peer, status, sizeof(status));
06592 astman_append(s, "Status: %s\r\n\r\n", status);
06593 peer_count++;
06594 }
06595 ao2_iterator_destroy(&i);
06596
06597 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
06598 return RESULT_SUCCESS;
06599 }
06600
06601
06602 static char *regstate2str(int regstate)
06603 {
06604 switch(regstate) {
06605 case REG_STATE_UNREGISTERED:
06606 return "Unregistered";
06607 case REG_STATE_REGSENT:
06608 return "Request Sent";
06609 case REG_STATE_AUTHSENT:
06610 return "Auth. Sent";
06611 case REG_STATE_REGISTERED:
06612 return "Registered";
06613 case REG_STATE_REJECTED:
06614 return "Rejected";
06615 case REG_STATE_TIMEOUT:
06616 return "Timeout";
06617 case REG_STATE_NOAUTH:
06618 return "No Authentication";
06619 default:
06620 return "Unknown";
06621 }
06622 }
06623
06624 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06625 {
06626 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
06627 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
06628 struct iax2_registry *reg = NULL;
06629 char host[80];
06630 char perceived[80];
06631 int counter = 0;
06632
06633 switch (cmd) {
06634 case CLI_INIT:
06635 e->command = "iax2 show registry";
06636 e->usage =
06637 "Usage: iax2 show registry\n"
06638 " Lists all registration requests and status.\n";
06639 return NULL;
06640 case CLI_GENERATE:
06641 return NULL;
06642 }
06643 if (a->argc != 3)
06644 return CLI_SHOWUSAGE;
06645 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
06646 AST_LIST_LOCK(®istrations);
06647 AST_LIST_TRAVERSE(®istrations, reg, entry) {
06648 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06649 if (reg->us.sin_addr.s_addr)
06650 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06651 else
06652 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06653 ast_cli(a->fd, FORMAT, host,
06654 (reg->dnsmgr) ? "Y" : "N",
06655 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
06656 counter++;
06657 }
06658 AST_LIST_UNLOCK(®istrations);
06659 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
06660 return CLI_SUCCESS;
06661 #undef FORMAT
06662 #undef FORMAT2
06663 }
06664
06665 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06666 {
06667 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
06668 #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"
06669 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
06670 int x;
06671 int numchans = 0;
06672 char first_message[10] = { 0, };
06673 char last_message[10] = { 0, };
06674
06675 switch (cmd) {
06676 case CLI_INIT:
06677 e->command = "iax2 show channels";
06678 e->usage =
06679 "Usage: iax2 show channels\n"
06680 " Lists all currently active IAX channels.\n";
06681 return NULL;
06682 case CLI_GENERATE:
06683 return NULL;
06684 }
06685
06686 if (a->argc != 3)
06687 return CLI_SHOWUSAGE;
06688 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
06689 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06690 ast_mutex_lock(&iaxsl[x]);
06691 if (iaxs[x]) {
06692 int lag, jitter, localdelay;
06693 jb_info jbinfo;
06694 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06695 jb_getinfo(iaxs[x]->jb, &jbinfo);
06696 jitter = jbinfo.jitter;
06697 localdelay = jbinfo.current - jbinfo.min;
06698 } else {
06699 jitter = -1;
06700 localdelay = 0;
06701 }
06702
06703 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06704 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06705 lag = iaxs[x]->remote_rr.delay;
06706 ast_cli(a->fd, FORMAT,
06707 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06708 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
06709 S_OR(iaxs[x]->username, "(None)"),
06710 iaxs[x]->callno, iaxs[x]->peercallno,
06711 iaxs[x]->oseqno, iaxs[x]->iseqno,
06712 lag,
06713 jitter,
06714 localdelay,
06715 ast_getformatname(iaxs[x]->voiceformat),
06716 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06717 first_message,
06718 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06719 last_message);
06720 numchans++;
06721 }
06722 ast_mutex_unlock(&iaxsl[x]);
06723 }
06724 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06725 return CLI_SUCCESS;
06726 #undef FORMAT
06727 #undef FORMAT2
06728 #undef FORMATB
06729 }
06730
06731 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
06732 {
06733 int x;
06734 int numchans = 0;
06735 char first_message[10] = { 0, };
06736 char last_message[10] = { 0, };
06737 #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
06738 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
06739 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06740 ast_mutex_lock(&iaxsl[x]);
06741 if (iaxs[x]) {
06742 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06743 jb_info jbinfo;
06744 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06745 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06746
06747 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06748 jb_getinfo(iaxs[x]->jb, &jbinfo);
06749 localjitter = jbinfo.jitter;
06750 localdelay = jbinfo.current - jbinfo.min;
06751 locallost = jbinfo.frames_lost;
06752 locallosspct = jbinfo.losspct/1000;
06753 localdropped = jbinfo.frames_dropped;
06754 localooo = jbinfo.frames_ooo;
06755 } else {
06756 localjitter = -1;
06757 localdelay = 0;
06758 locallost = -1;
06759 locallosspct = -1;
06760 localdropped = 0;
06761 localooo = -1;
06762 }
06763 if (s)
06764 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06765 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06766 iaxs[x]->pingtime,
06767 localjitter,
06768 localdelay,
06769 locallost,
06770 locallosspct,
06771 localdropped,
06772 localooo,
06773 iaxs[x]->frames_received/1000,
06774 iaxs[x]->remote_rr.jitter,
06775 iaxs[x]->remote_rr.delay,
06776 iaxs[x]->remote_rr.losscnt,
06777 iaxs[x]->remote_rr.losspct,
06778 iaxs[x]->remote_rr.dropped,
06779 iaxs[x]->remote_rr.ooo,
06780 iaxs[x]->remote_rr.packets/1000,
06781 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06782 first_message,
06783 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06784 last_message);
06785 else
06786 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06787 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06788 iaxs[x]->pingtime,
06789 localjitter,
06790 localdelay,
06791 locallost,
06792 locallosspct,
06793 localdropped,
06794 localooo,
06795 iaxs[x]->frames_received/1000,
06796 iaxs[x]->remote_rr.jitter,
06797 iaxs[x]->remote_rr.delay,
06798 iaxs[x]->remote_rr.losscnt,
06799 iaxs[x]->remote_rr.losspct,
06800 iaxs[x]->remote_rr.dropped,
06801 iaxs[x]->remote_rr.ooo,
06802 iaxs[x]->remote_rr.packets/1000,
06803 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06804 first_message,
06805 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06806 last_message);
06807 numchans++;
06808 }
06809 ast_mutex_unlock(&iaxsl[x]);
06810 }
06811
06812 return numchans;
06813 }
06814
06815 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06816 {
06817 int numchans = 0;
06818
06819 switch (cmd) {
06820 case CLI_INIT:
06821 e->command = "iax2 show netstats";
06822 e->usage =
06823 "Usage: iax2 show netstats\n"
06824 " Lists network status for all currently active IAX channels.\n";
06825 return NULL;
06826 case CLI_GENERATE:
06827 return NULL;
06828 }
06829 if (a->argc != 3)
06830 return CLI_SHOWUSAGE;
06831 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
06832 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
06833 numchans = ast_cli_netstats(NULL, a->fd, 1);
06834 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06835 return CLI_SUCCESS;
06836 }
06837
06838 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06839 {
06840 switch (cmd) {
06841 case CLI_INIT:
06842 e->command = "iax2 set debug {on|off|peer}";
06843 e->usage =
06844 "Usage: iax2 set debug {on|off|peer peername}\n"
06845 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
06846 return NULL;
06847 case CLI_GENERATE:
06848 if (a->pos == 4)
06849 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
06850 return NULL;
06851 }
06852
06853 if (a->argc < e->args || a->argc > e->args + 1)
06854 return CLI_SHOWUSAGE;
06855
06856 if (!strcasecmp(a->argv[3], "peer")) {
06857 struct iax2_peer *peer;
06858
06859 if (a->argc != e->args + 1)
06860 return CLI_SHOWUSAGE;
06861
06862 peer = find_peer(a->argv[4], 1);
06863
06864 if (!peer) {
06865 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
06866 return CLI_FAILURE;
06867 }
06868
06869 debugaddr.sin_addr = peer->addr.sin_addr;
06870 debugaddr.sin_port = peer->addr.sin_port;
06871
06872 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
06873 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
06874
06875 ao2_ref(peer, -1);
06876 } else if (!strncasecmp(a->argv[3], "on", 2)) {
06877 iaxdebug = 1;
06878 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
06879 } else {
06880 iaxdebug = 0;
06881 memset(&debugaddr, 0, sizeof(debugaddr));
06882 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
06883 }
06884 return CLI_SUCCESS;
06885 }
06886
06887 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06888 {
06889 switch (cmd) {
06890 case CLI_INIT:
06891 e->command = "iax2 set debug trunk {on|off}";
06892 e->usage =
06893 "Usage: iax2 set debug trunk {on|off}\n"
06894 " Enables/Disables debugging of IAX trunking\n";
06895 return NULL;
06896 case CLI_GENERATE:
06897 return NULL;
06898 }
06899
06900 if (a->argc != e->args)
06901 return CLI_SHOWUSAGE;
06902
06903 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
06904 iaxtrunkdebug = 1;
06905 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
06906 } else {
06907 iaxtrunkdebug = 0;
06908 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
06909 }
06910 return CLI_SUCCESS;
06911 }
06912
06913 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06914 {
06915 switch (cmd) {
06916 case CLI_INIT:
06917 e->command = "iax2 set debug jb {on|off}";
06918 e->usage =
06919 "Usage: iax2 set debug jb {on|off}\n"
06920 " Enables/Disables jitterbuffer debugging information\n";
06921 return NULL;
06922 case CLI_GENERATE:
06923 return NULL;
06924 }
06925
06926 if (a->argc != e->args)
06927 return CLI_SHOWUSAGE;
06928
06929 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
06930 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
06931 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
06932 } else {
06933 jb_setoutput(jb_error_output, jb_warning_output, NULL);
06934 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
06935 }
06936 return CLI_SUCCESS;
06937 }
06938
06939 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
06940 {
06941 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
06942 int res = -1;
06943 ast_mutex_lock(&iaxsl[callno]);
06944 if (iaxs[callno]) {
06945
06946 if (!iaxs[callno]->error) {
06947 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
06948 res = 0;
06949
06950 else if (f->frametype == AST_FRAME_NULL)
06951 res = 0;
06952 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
06953 res = 0;
06954 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
06955 res = 0;
06956 else
06957
06958 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
06959 } else {
06960 ast_debug(1, "Write error: %s\n", strerror(errno));
06961 }
06962 }
06963
06964 ast_mutex_unlock(&iaxsl[callno]);
06965 return res;
06966 }
06967
06968 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
06969 int now, int transfer, int final)
06970 {
06971 struct ast_frame f = { 0, };
06972 int res = 0;
06973
06974 f.frametype = type;
06975 f.subclass = command;
06976 f.datalen = datalen;
06977 f.src = __FUNCTION__;
06978 f.data.ptr = (void *) data;
06979
06980 if ((res = queue_signalling(i, &f)) <= 0) {
06981 return res;
06982 }
06983
06984 return iax2_send(i, &f, ts, seqno, now, transfer, final);
06985 }
06986
06987 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
06988 {
06989 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
06990 }
06991
06992 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
06993 {
06994 int res;
06995 ast_mutex_lock(&iaxsl[callno]);
06996 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
06997 ast_mutex_unlock(&iaxsl[callno]);
06998 return res;
06999 }
07000
07001
07002
07003
07004
07005
07006 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)
07007 {
07008 int call_num = i->callno;
07009
07010 iax2_predestroy(i->callno);
07011 if (!iaxs[call_num])
07012 return -1;
07013 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07014 }
07015
07016 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)
07017 {
07018 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07019 }
07020
07021 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07022 {
07023 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07024 }
07025
07026 static int apply_context(struct iax2_context *con, const char *context)
07027 {
07028 while(con) {
07029 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07030 return -1;
07031 con = con->next;
07032 }
07033 return 0;
07034 }
07035
07036
07037 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07038 {
07039
07040 int res = -1;
07041 int version = 2;
07042 struct iax2_user *user = NULL, *best = NULL;
07043 int bestscore = 0;
07044 int gotcapability = 0;
07045 struct ast_variable *v = NULL, *tmpvar = NULL;
07046 struct ao2_iterator i;
07047
07048 if (!iaxs[callno])
07049 return res;
07050 if (ies->called_number)
07051 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07052 if (ies->calling_number) {
07053 if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) {
07054 ast_shrink_phone_number(ies->calling_number);
07055 }
07056 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07057 }
07058 if (ies->calling_name)
07059 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07060 if (ies->calling_ani)
07061 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07062 if (ies->dnid)
07063 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07064 if (ies->rdnis)
07065 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07066 if (ies->called_context)
07067 ast_string_field_set(iaxs[callno], context, ies->called_context);
07068 if (ies->language)
07069 ast_string_field_set(iaxs[callno], language, ies->language);
07070 if (ies->username)
07071 ast_string_field_set(iaxs[callno], username, ies->username);
07072 if (ies->calling_ton > -1)
07073 iaxs[callno]->calling_ton = ies->calling_ton;
07074 if (ies->calling_tns > -1)
07075 iaxs[callno]->calling_tns = ies->calling_tns;
07076 if (ies->calling_pres > -1)
07077 iaxs[callno]->calling_pres = ies->calling_pres;
07078 if (ies->format)
07079 iaxs[callno]->peerformat = ies->format;
07080 if (ies->adsicpe)
07081 iaxs[callno]->peeradsicpe = ies->adsicpe;
07082 if (ies->capability) {
07083 gotcapability = 1;
07084 iaxs[callno]->peercapability = ies->capability;
07085 }
07086 if (ies->version)
07087 version = ies->version;
07088
07089
07090 if(ies->codec_prefs) {
07091 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07092 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07093 }
07094
07095 if (!gotcapability)
07096 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07097 if (version > IAX_PROTO_VERSION) {
07098 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07099 ast_inet_ntoa(sin->sin_addr), version);
07100 return res;
07101 }
07102
07103 i = ao2_iterator_init(users, 0);
07104 while ((user = ao2_iterator_next(&i))) {
07105 if ((ast_strlen_zero(iaxs[callno]->username) ||
07106 !strcmp(iaxs[callno]->username, user->name))
07107 && ast_apply_ha(user->ha, sin)
07108 && (ast_strlen_zero(iaxs[callno]->context) ||
07109 apply_context(user->contexts, iaxs[callno]->context))) {
07110 if (!ast_strlen_zero(iaxs[callno]->username)) {
07111
07112 if (best)
07113 user_unref(best);
07114 best = user;
07115 break;
07116 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07117
07118 if (user->ha) {
07119
07120 if (bestscore < 4) {
07121 bestscore = 4;
07122 if (best)
07123 user_unref(best);
07124 best = user;
07125 continue;
07126 }
07127 } else {
07128
07129 if (bestscore < 3) {
07130 bestscore = 3;
07131 if (best)
07132 user_unref(best);
07133 best = user;
07134 continue;
07135 }
07136 }
07137 } else {
07138 if (user->ha) {
07139
07140 if (bestscore < 2) {
07141 bestscore = 2;
07142 if (best)
07143 user_unref(best);
07144 best = user;
07145 continue;
07146 }
07147 } else {
07148
07149 if (bestscore < 1) {
07150 bestscore = 1;
07151 if (best)
07152 user_unref(best);
07153 best = user;
07154 continue;
07155 }
07156 }
07157 }
07158 }
07159 user_unref(user);
07160 }
07161 ao2_iterator_destroy(&i);
07162 user = best;
07163 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07164 user = realtime_user(iaxs[callno]->username, sin);
07165 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07166 !apply_context(user->contexts, iaxs[callno]->context)) {
07167 user = user_unref(user);
07168 }
07169 }
07170 if (user) {
07171
07172
07173 for (v = user->vars ; v ; v = v->next) {
07174 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07175 tmpvar->next = iaxs[callno]->vars;
07176 iaxs[callno]->vars = tmpvar;
07177 }
07178 }
07179
07180 if (user->maxauthreq > 0)
07181 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
07182 iaxs[callno]->prefs = user->prefs;
07183 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
07184 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
07185 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
07186 iaxs[callno]->encmethods = user->encmethods;
07187
07188 if (ast_strlen_zero(iaxs[callno]->username))
07189 ast_string_field_set(iaxs[callno], username, user->name);
07190
07191 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
07192 iaxs[callno]->capability = user->capability;
07193
07194 if (ast_strlen_zero(iaxs[callno]->context)) {
07195 if (user->contexts)
07196 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07197 else
07198 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07199 }
07200
07201 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07202
07203 iaxs[callno]->authmethods = user->authmethods;
07204 iaxs[callno]->adsi = user->adsi;
07205
07206 if (ast_test_flag(user, IAX_HASCALLERID)) {
07207 iaxs[callno]->calling_tns = 0;
07208 iaxs[callno]->calling_ton = 0;
07209 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07210 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07211 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07212 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07213 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07214 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07215 }
07216 if (!ast_strlen_zero(user->accountcode))
07217 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07218 if (!ast_strlen_zero(user->mohinterpret))
07219 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07220 if (!ast_strlen_zero(user->mohsuggest))
07221 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07222 if (!ast_strlen_zero(user->parkinglot))
07223 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07224 if (user->amaflags)
07225 iaxs[callno]->amaflags = user->amaflags;
07226 if (!ast_strlen_zero(user->language))
07227 ast_string_field_set(iaxs[callno], language, user->language);
07228 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07229
07230 if (!ast_strlen_zero(user->dbsecret)) {
07231 char *family, *key=NULL;
07232 char buf[80];
07233 family = ast_strdupa(user->dbsecret);
07234 key = strchr(family, '/');
07235 if (key) {
07236 *key = '\0';
07237 key++;
07238 }
07239 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07240 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07241 else
07242 ast_string_field_set(iaxs[callno], secret, buf);
07243 } else
07244 ast_string_field_set(iaxs[callno], secret, user->secret);
07245 res = 0;
07246 user = user_unref(user);
07247 } else {
07248
07249
07250
07251
07252 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07253 ast_string_field_set(iaxs[callno], secret, "badsecret");
07254 iaxs[callno]->authrej = 1;
07255 if (!ast_strlen_zero(iaxs[callno]->username)) {
07256
07257 res = 0;
07258 }
07259 }
07260 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07261 return res;
07262 }
07263
07264 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07265 {
07266 struct ast_iax2_full_hdr fh;
07267 fh.scallno = htons(src | IAX_FLAG_FULL);
07268 fh.dcallno = htons(dst);
07269 fh.ts = 0;
07270 fh.oseqno = 0;
07271 fh.iseqno = 0;
07272 fh.type = AST_FRAME_IAX;
07273 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07274 iax_outputframe(NULL, &fh, 0, sin, 0);
07275 #if 0
07276 if (option_debug)
07277 #endif
07278 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07279 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07280 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07281 }
07282
07283 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07284 {
07285
07286 p->encmethods &= enc;
07287 if (p->encmethods) {
07288 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07289 p->keyrotateid = -2;
07290 }
07291 if (p->encmethods & IAX_ENCRYPT_AES128)
07292 p->encmethods = IAX_ENCRYPT_AES128;
07293 else
07294 p->encmethods = 0;
07295 }
07296 }
07297
07298
07299
07300
07301
07302
07303
07304 static int authenticate_request(int call_num)
07305 {
07306 struct iax_ie_data ied;
07307 int res = -1, authreq_restrict = 0;
07308 char challenge[10];
07309 struct chan_iax2_pvt *p = iaxs[call_num];
07310
07311 memset(&ied, 0, sizeof(ied));
07312
07313
07314 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07315 struct iax2_user *user, tmp_user = {
07316 .name = p->username,
07317 };
07318
07319 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07320 if (user) {
07321 if (user->curauthreq == user->maxauthreq)
07322 authreq_restrict = 1;
07323 else
07324 user->curauthreq++;
07325 user = user_unref(user);
07326 }
07327 }
07328
07329
07330 if (authreq_restrict) {
07331 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07332 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07333 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07334 return 0;
07335 }
07336
07337 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07338 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07339 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07340 ast_string_field_set(p, challenge, challenge);
07341
07342 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07343 }
07344 if (p->encmethods)
07345 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07346
07347 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07348
07349 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07350
07351 if (p->encmethods)
07352 ast_set_flag(p, IAX_ENCRYPTED);
07353
07354 return res;
07355 }
07356
07357 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07358 {
07359 char requeststr[256];
07360 char md5secret[256] = "";
07361 char secret[256] = "";
07362 char rsasecret[256] = "";
07363 int res = -1;
07364 int x;
07365 struct iax2_user *user, tmp_user = {
07366 .name = p->username,
07367 };
07368
07369 if (p->authrej) {
07370 return res;
07371 }
07372 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07373 if (user) {
07374 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07375 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07376 ast_clear_flag(p, IAX_MAXAUTHREQ);
07377 }
07378 ast_string_field_set(p, host, user->name);
07379 user = user_unref(user);
07380 }
07381
07382 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07383 return res;
07384 if (ies->password)
07385 ast_copy_string(secret, ies->password, sizeof(secret));
07386 if (ies->md5_result)
07387 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07388 if (ies->rsa_result)
07389 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07390 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07391 struct ast_key *key;
07392 char *keyn;
07393 char tmpkey[256];
07394 char *stringp=NULL;
07395 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07396 stringp=tmpkey;
07397 keyn = strsep(&stringp, ":");
07398 while(keyn) {
07399 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07400 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07401 res = 0;
07402 break;
07403 } else if (!key)
07404 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07405 keyn = strsep(&stringp, ":");
07406 }
07407 } else if (p->authmethods & IAX_AUTH_MD5) {
07408 struct MD5Context md5;
07409 unsigned char digest[16];
07410 char *tmppw, *stringp;
07411
07412 tmppw = ast_strdupa(p->secret);
07413 stringp = tmppw;
07414 while((tmppw = strsep(&stringp, ";"))) {
07415 MD5Init(&md5);
07416 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07417 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07418 MD5Final(digest, &md5);
07419
07420 for (x=0;x<16;x++)
07421 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07422 if (!strcasecmp(requeststr, md5secret)) {
07423 res = 0;
07424 break;
07425 }
07426 }
07427 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07428 if (!strcmp(secret, p->secret))
07429 res = 0;
07430 }
07431 return res;
07432 }
07433
07434
07435 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07436 {
07437 char requeststr[256] = "";
07438 char peer[256] = "";
07439 char md5secret[256] = "";
07440 char rsasecret[256] = "";
07441 char secret[256] = "";
07442 struct iax2_peer *p = NULL;
07443 struct ast_key *key;
07444 char *keyn;
07445 int x;
07446 int expire = 0;
07447 int res = -1;
07448
07449 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07450
07451 if (ies->username)
07452 ast_copy_string(peer, ies->username, sizeof(peer));
07453 if (ies->password)
07454 ast_copy_string(secret, ies->password, sizeof(secret));
07455 if (ies->md5_result)
07456 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07457 if (ies->rsa_result)
07458 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07459 if (ies->refresh)
07460 expire = ies->refresh;
07461
07462 if (ast_strlen_zero(peer)) {
07463 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07464 return -1;
07465 }
07466
07467
07468 ast_mutex_unlock(&iaxsl[callno]);
07469 p = find_peer(peer, 1);
07470 ast_mutex_lock(&iaxsl[callno]);
07471 if (!p || !iaxs[callno]) {
07472 if (iaxs[callno]) {
07473 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07474
07475 ast_string_field_set(iaxs[callno], secret, "badsecret");
07476
07477
07478
07479
07480
07481
07482
07483
07484
07485 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07486 !(!ast_strlen_zero(secret) && plaintext)) {
07487
07488 res = 0;
07489 }
07490 }
07491 if (authdebug && !p)
07492 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07493 goto return_unref;
07494 }
07495
07496 if (!ast_test_flag(p, IAX_DYNAMIC)) {
07497 if (authdebug)
07498 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07499 goto return_unref;
07500 }
07501
07502 if (!ast_apply_ha(p->ha, sin)) {
07503 if (authdebug)
07504 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07505 goto return_unref;
07506 }
07507 ast_string_field_set(iaxs[callno], secret, p->secret);
07508 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07509
07510 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07511 if (!ast_strlen_zero(p->inkeys)) {
07512 char tmpkeys[256];
07513 char *stringp=NULL;
07514 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07515 stringp=tmpkeys;
07516 keyn = strsep(&stringp, ":");
07517 while(keyn) {
07518 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07519 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07520 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07521 break;
07522 } else if (!key)
07523 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
07524 keyn = strsep(&stringp, ":");
07525 }
07526 if (!keyn) {
07527 if (authdebug)
07528 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
07529 goto return_unref;
07530 }
07531 } else {
07532 if (authdebug)
07533 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
07534 goto return_unref;
07535 }
07536 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07537 struct MD5Context md5;
07538 unsigned char digest[16];
07539 char *tmppw, *stringp;
07540
07541 tmppw = ast_strdupa(p->secret);
07542 stringp = tmppw;
07543 while((tmppw = strsep(&stringp, ";"))) {
07544 MD5Init(&md5);
07545 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
07546 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07547 MD5Final(digest, &md5);
07548 for (x=0;x<16;x++)
07549 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07550 if (!strcasecmp(requeststr, md5secret))
07551 break;
07552 }
07553 if (tmppw) {
07554 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07555 } else {
07556 if (authdebug)
07557 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
07558 goto return_unref;
07559 }
07560 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
07561
07562 if (strcmp(secret, p->secret)) {
07563 if (authdebug)
07564 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07565 goto return_unref;
07566 } else
07567 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07568 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
07569
07570 goto return_unref;
07571 }
07572 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
07573
07574
07575 res = 0;
07576
07577 return_unref:
07578 if (iaxs[callno]) {
07579 ast_string_field_set(iaxs[callno], peer, peer);
07580
07581
07582 if (expire && (expire < iaxs[callno]->expiry)) {
07583 iaxs[callno]->expiry = expire;
07584 }
07585 }
07586
07587 if (p) {
07588 peer_unref(p);
07589 }
07590 return res;
07591 }
07592
07593 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)
07594 {
07595 int res = -1;
07596 int x;
07597 if (!ast_strlen_zero(keyn)) {
07598 if (!(authmethods & IAX_AUTH_RSA)) {
07599 if (ast_strlen_zero(secret))
07600 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));
07601 } else if (ast_strlen_zero(challenge)) {
07602 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
07603 } else {
07604 char sig[256];
07605 struct ast_key *key;
07606 key = ast_key_get(keyn, AST_KEY_PRIVATE);
07607 if (!key) {
07608 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
07609 } else {
07610 if (ast_sign(key, (char*)challenge, sig)) {
07611 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
07612 res = -1;
07613 } else {
07614 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
07615 res = 0;
07616 }
07617 }
07618 }
07619 }
07620
07621 if (res && !ast_strlen_zero(secret)) {
07622 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
07623 struct MD5Context md5;
07624 unsigned char digest[16];
07625 char digres[128];
07626 MD5Init(&md5);
07627 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
07628 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
07629 MD5Final(digest, &md5);
07630
07631 for (x=0;x<16;x++)
07632 sprintf(digres + (x << 1), "%2.2x", digest[x]);
07633 if (pvt) {
07634 build_encryption_keys(digest, pvt);
07635 }
07636 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
07637 res = 0;
07638 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
07639 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
07640 res = 0;
07641 } else
07642 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
07643 }
07644 return res;
07645 }
07646
07647
07648
07649
07650
07651 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
07652 {
07653 struct iax2_peer *peer = NULL;
07654
07655 int res = -1;
07656 int authmethods = 0;
07657 struct iax_ie_data ied;
07658 uint16_t callno = p->callno;
07659
07660 memset(&ied, 0, sizeof(ied));
07661
07662 if (ies->username)
07663 ast_string_field_set(p, username, ies->username);
07664 if (ies->challenge)
07665 ast_string_field_set(p, challenge, ies->challenge);
07666 if (ies->authmethods)
07667 authmethods = ies->authmethods;
07668 if (authmethods & IAX_AUTH_MD5)
07669 merge_encryption(p, ies->encmethods);
07670 else
07671 p->encmethods = 0;
07672
07673
07674 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
07675
07676 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
07677 } else {
07678 struct ao2_iterator i = ao2_iterator_init(peers, 0);
07679 while ((peer = ao2_iterator_next(&i))) {
07680 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
07681
07682 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
07683
07684 && (!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)))
07685
07686 ) {
07687 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
07688 if (!res) {
07689 peer_unref(peer);
07690 break;
07691 }
07692 }
07693 peer_unref(peer);
07694 }
07695 ao2_iterator_destroy(&i);
07696 if (!peer) {
07697
07698
07699 const char *peer_name = ast_strdupa(p->peer);
07700 ast_mutex_unlock(&iaxsl[callno]);
07701 if ((peer = realtime_peer(peer_name, NULL))) {
07702 ast_mutex_lock(&iaxsl[callno]);
07703 if (!(p = iaxs[callno])) {
07704 peer_unref(peer);
07705 return -1;
07706 }
07707 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
07708 peer_unref(peer);
07709 }
07710 if (!peer) {
07711 ast_mutex_lock(&iaxsl[callno]);
07712 if (!(p = iaxs[callno]))
07713 return -1;
07714 }
07715 }
07716 }
07717 if (ies->encmethods)
07718 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
07719 if (!res) {
07720 struct ast_datastore *variablestore;
07721 struct ast_variable *var, *prev = NULL;
07722 AST_LIST_HEAD(, ast_var_t) *varlist;
07723 varlist = ast_calloc(1, sizeof(*varlist));
07724 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
07725 if (variablestore && varlist && p->owner) {
07726 variablestore->data = varlist;
07727 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
07728 AST_LIST_HEAD_INIT(varlist);
07729 for (var = ies->vars; var; var = var->next) {
07730 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
07731 if (prev)
07732 ast_free(prev);
07733 prev = var;
07734 if (!newvar) {
07735
07736 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07737 } else {
07738 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
07739 }
07740 }
07741 if (prev)
07742 ast_free(prev);
07743 ies->vars = NULL;
07744 ast_channel_datastore_add(p->owner, variablestore);
07745 } else {
07746 if (p->owner)
07747 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07748 if (variablestore)
07749 ast_datastore_free(variablestore);
07750 if (varlist)
07751 ast_free(varlist);
07752 }
07753 }
07754
07755 if (!res)
07756 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
07757 return res;
07758 }
07759
07760 static int iax2_do_register(struct iax2_registry *reg);
07761
07762 static void __iax2_do_register_s(const void *data)
07763 {
07764 struct iax2_registry *reg = (struct iax2_registry *)data;
07765 reg->expire = -1;
07766 iax2_do_register(reg);
07767 }
07768
07769 static int iax2_do_register_s(const void *data)
07770 {
07771 #ifdef SCHED_MULTITHREADED
07772 if (schedule_action(__iax2_do_register_s, data))
07773 #endif
07774 __iax2_do_register_s(data);
07775 return 0;
07776 }
07777
07778 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07779 {
07780 int newcall = 0;
07781 char newip[256];
07782 struct iax_ie_data ied;
07783 struct sockaddr_in new;
07784
07785
07786 memset(&ied, 0, sizeof(ied));
07787 if (ies->apparent_addr)
07788 memmove(&new, ies->apparent_addr, sizeof(new));
07789 if (ies->callno)
07790 newcall = ies->callno;
07791 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
07792 ast_log(LOG_WARNING, "Invalid transfer request\n");
07793 return -1;
07794 }
07795 pvt->transfercallno = newcall;
07796 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
07797 inet_aton(newip, &pvt->transfer.sin_addr);
07798 pvt->transfer.sin_family = AF_INET;
07799 pvt->transferid = ies->transferid;
07800
07801
07802 if (pvt->transferring == TRANSFER_NONE) {
07803 store_by_transfercallno(pvt);
07804 }
07805 pvt->transferring = TRANSFER_BEGIN;
07806
07807 if (ies->transferid)
07808 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
07809 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
07810 return 0;
07811 }
07812
07813 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07814 {
07815 char exten[256] = "";
07816 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
07817 struct iax2_dpcache *dp = NULL;
07818
07819 if (ies->called_number)
07820 ast_copy_string(exten, ies->called_number, sizeof(exten));
07821
07822 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
07823 status = CACHE_FLAG_EXISTS;
07824 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
07825 status = CACHE_FLAG_CANEXIST;
07826 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
07827 status = CACHE_FLAG_NONEXISTENT;
07828
07829 if (ies->refresh)
07830 expiry = ies->refresh;
07831 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
07832 matchmore = CACHE_FLAG_MATCHMORE;
07833
07834 AST_LIST_LOCK(&dpcache);
07835 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
07836 if (strcmp(dp->exten, exten))
07837 continue;
07838 AST_LIST_REMOVE_CURRENT(peer_list);
07839 dp->callno = 0;
07840 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
07841 if (dp->flags & CACHE_FLAG_PENDING) {
07842 dp->flags &= ~CACHE_FLAG_PENDING;
07843 dp->flags |= status;
07844 dp->flags |= matchmore;
07845 }
07846
07847 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
07848 if (dp->waiters[x] > -1) {
07849 if (write(dp->waiters[x], "asdf", 4) < 0) {
07850 }
07851 }
07852 }
07853 }
07854 AST_LIST_TRAVERSE_SAFE_END;
07855 AST_LIST_UNLOCK(&dpcache);
07856
07857 return 0;
07858 }
07859
07860 static int complete_transfer(int callno, struct iax_ies *ies)
07861 {
07862 int peercallno = 0;
07863 struct chan_iax2_pvt *pvt = iaxs[callno];
07864 struct iax_frame *cur;
07865 jb_frame frame;
07866
07867 if (ies->callno)
07868 peercallno = ies->callno;
07869
07870 if (peercallno < 1) {
07871 ast_log(LOG_WARNING, "Invalid transfer request\n");
07872 return -1;
07873 }
07874 remove_by_transfercallno(pvt);
07875
07876
07877
07878 peercnt_remove_by_addr(&pvt->addr);
07879 peercnt_add(&pvt->transfer);
07880
07881 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
07882 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
07883
07884 pvt->oseqno = 0;
07885 pvt->rseqno = 0;
07886 pvt->iseqno = 0;
07887 pvt->aseqno = 0;
07888
07889 if (pvt->peercallno) {
07890 remove_by_peercallno(pvt);
07891 }
07892 pvt->peercallno = peercallno;
07893
07894 store_by_peercallno(pvt);
07895 pvt->transferring = TRANSFER_NONE;
07896 pvt->svoiceformat = -1;
07897 pvt->voiceformat = 0;
07898 pvt->svideoformat = -1;
07899 pvt->videoformat = 0;
07900 pvt->transfercallno = 0;
07901 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
07902 memset(&pvt->offset, 0, sizeof(pvt->offset));
07903
07904 while(jb_getall(pvt->jb,&frame) == JB_OK)
07905 iax2_frame_free(frame.data);
07906 jb_reset(pvt->jb);
07907 pvt->lag = 0;
07908 pvt->last = 0;
07909 pvt->lastsent = 0;
07910 pvt->nextpred = 0;
07911 pvt->pingtime = DEFAULT_RETRY_TIME;
07912 AST_LIST_LOCK(&frame_queue);
07913 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
07914
07915
07916
07917 if (callno == cur->callno)
07918 cur->retries = -1;
07919 }
07920 AST_LIST_UNLOCK(&frame_queue);
07921 return 0;
07922 }
07923
07924
07925 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
07926 {
07927 struct iax2_registry *reg;
07928
07929 char peer[256] = "";
07930 char msgstatus[60];
07931 int refresh = 60;
07932 char ourip[256] = "<Unspecified>";
07933 struct sockaddr_in oldus;
07934 struct sockaddr_in us;
07935 int oldmsgs;
07936
07937 memset(&us, 0, sizeof(us));
07938 if (ies->apparent_addr)
07939 memmove(&us, ies->apparent_addr, sizeof(us));
07940 if (ies->username)
07941 ast_copy_string(peer, ies->username, sizeof(peer));
07942 if (ies->refresh)
07943 refresh = ies->refresh;
07944 if (ies->calling_number) {
07945
07946 }
07947 reg = iaxs[callno]->reg;
07948 if (!reg) {
07949 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
07950 return -1;
07951 }
07952 memcpy(&oldus, ®->us, sizeof(oldus));
07953 oldmsgs = reg->messages;
07954 if (inaddrcmp(®->addr, sin)) {
07955 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07956 return -1;
07957 }
07958 memcpy(®->us, &us, sizeof(reg->us));
07959 if (ies->msgcount >= 0)
07960 reg->messages = ies->msgcount & 0xffff;
07961
07962
07963
07964 reg->refresh = refresh;
07965 reg->expire = iax2_sched_replace(reg->expire, sched,
07966 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07967 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
07968 if (reg->messages > 255)
07969 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
07970 else if (reg->messages > 1)
07971 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
07972 else if (reg->messages > 0)
07973 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
07974 else
07975 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
07976 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07977 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
07978 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
07979 }
07980 reg->regstate = REG_STATE_REGISTERED;
07981 return 0;
07982 }
07983
07984 static int iax2_append_register(const char *hostname, const char *username,
07985 const char *secret, const char *porta)
07986 {
07987 struct iax2_registry *reg;
07988
07989 if (!(reg = ast_calloc(1, sizeof(*reg))))
07990 return -1;
07991
07992 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
07993 ast_free(reg);
07994 return -1;
07995 }
07996
07997 ast_copy_string(reg->username, username, sizeof(reg->username));
07998
07999 if (secret)
08000 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08001
08002 reg->expire = -1;
08003 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08004 reg->addr.sin_family = AF_INET;
08005 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
08006
08007 AST_LIST_LOCK(®istrations);
08008 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08009 AST_LIST_UNLOCK(®istrations);
08010
08011 return 0;
08012 }
08013
08014 static int iax2_register(const char *value, int lineno)
08015 {
08016 char copy[256];
08017 char *username, *hostname, *secret;
08018 char *porta;
08019 char *stringp=NULL;
08020
08021 if (!value)
08022 return -1;
08023
08024 ast_copy_string(copy, value, sizeof(copy));
08025 stringp = copy;
08026 username = strsep(&stringp, "@");
08027 hostname = strsep(&stringp, "@");
08028
08029 if (!hostname) {
08030 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08031 return -1;
08032 }
08033
08034 stringp = username;
08035 username = strsep(&stringp, ":");
08036 secret = strsep(&stringp, ":");
08037 stringp = hostname;
08038 hostname = strsep(&stringp, ":");
08039 porta = strsep(&stringp, ":");
08040
08041 if (porta && !atoi(porta)) {
08042 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08043 return -1;
08044 }
08045
08046 return iax2_append_register(hostname, username, secret, porta);
08047 }
08048
08049
08050 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08051 {
08052 char multi[256];
08053 char *stringp, *ext;
08054 if (!ast_strlen_zero(regcontext)) {
08055 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08056 stringp = multi;
08057 while((ext = strsep(&stringp, "&"))) {
08058 if (onoff) {
08059 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08060 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08061 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08062 } else
08063 ast_context_remove_extension(regcontext, ext, 1, NULL);
08064 }
08065 }
08066 }
08067 static void prune_peers(void);
08068
08069 static void unlink_peer(struct iax2_peer *peer)
08070 {
08071 if (peer->expire > -1) {
08072 if (!ast_sched_del(sched, peer->expire)) {
08073 peer->expire = -1;
08074 peer_unref(peer);
08075 }
08076 }
08077
08078 if (peer->pokeexpire > -1) {
08079 if (!ast_sched_del(sched, peer->pokeexpire)) {
08080 peer->pokeexpire = -1;
08081 peer_unref(peer);
08082 }
08083 }
08084
08085 ao2_unlink(peers, peer);
08086 }
08087
08088 static void __expire_registry(const void *data)
08089 {
08090 struct iax2_peer *peer = (struct iax2_peer *) data;
08091
08092 if (!peer)
08093 return;
08094
08095 peer->expire = -1;
08096
08097 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08098 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08099 realtime_update_peer(peer->name, &peer->addr, 0);
08100 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08101
08102 peercnt_modify(0, 0, &peer->addr);
08103
08104 memset(&peer->addr, 0, sizeof(peer->addr));
08105
08106 peer->expiry = min_reg_expire;
08107 if (!ast_test_flag(peer, IAX_TEMPONLY))
08108 ast_db_del("IAX/Registry", peer->name);
08109 register_peer_exten(peer, 0);
08110 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08111 if (iax2_regfunk)
08112 iax2_regfunk(peer->name, 0);
08113
08114 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
08115 unlink_peer(peer);
08116
08117 peer_unref(peer);
08118 }
08119
08120 static int expire_registry(const void *data)
08121 {
08122 #ifdef SCHED_MULTITHREADED
08123 if (schedule_action(__expire_registry, data))
08124 #endif
08125 __expire_registry(data);
08126 return 0;
08127 }
08128
08129 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08130
08131 static void reg_source_db(struct iax2_peer *p)
08132 {
08133 char data[80];
08134 struct in_addr in;
08135 char *c, *d;
08136 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
08137 c = strchr(data, ':');
08138 if (c) {
08139 *c = '\0';
08140 c++;
08141 if (inet_aton(data, &in)) {
08142 d = strchr(c, ':');
08143 if (d) {
08144 *d = '\0';
08145 d++;
08146 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
08147 ast_inet_ntoa(in), atoi(c), atoi(d));
08148 iax2_poke_peer(p, 0);
08149 p->expiry = atoi(d);
08150 memset(&p->addr, 0, sizeof(p->addr));
08151 p->addr.sin_family = AF_INET;
08152 p->addr.sin_addr = in;
08153 p->addr.sin_port = htons(atoi(c));
08154 if (p->expire > -1) {
08155 if (!ast_sched_del(sched, p->expire)) {
08156 p->expire = -1;
08157 peer_unref(p);
08158 }
08159 }
08160 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08161 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08162 if (p->expire == -1)
08163 peer_unref(p);
08164 if (iax2_regfunk)
08165 iax2_regfunk(p->name, 1);
08166 register_peer_exten(p, 1);
08167 }
08168
08169 }
08170 }
08171 }
08172 }
08173
08174
08175
08176
08177
08178
08179
08180 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08181 {
08182
08183 struct iax_ie_data ied;
08184 struct iax2_peer *p;
08185 int msgcount;
08186 char data[80];
08187 int version;
08188 const char *peer_name;
08189 int res = -1;
08190
08191 memset(&ied, 0, sizeof(ied));
08192
08193 peer_name = ast_strdupa(iaxs[callno]->peer);
08194
08195
08196 ast_mutex_unlock(&iaxsl[callno]);
08197 if (!(p = find_peer(peer_name, 1))) {
08198 ast_mutex_lock(&iaxsl[callno]);
08199 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08200 return -1;
08201 }
08202 ast_mutex_lock(&iaxsl[callno]);
08203 if (!iaxs[callno])
08204 goto return_unref;
08205
08206 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08207 if (sin->sin_addr.s_addr) {
08208 time_t nowtime;
08209 time(&nowtime);
08210 realtime_update_peer(peer_name, sin, nowtime);
08211 } else {
08212 realtime_update_peer(peer_name, sin, 0);
08213 }
08214 }
08215 if (inaddrcmp(&p->addr, sin)) {
08216 if (iax2_regfunk)
08217 iax2_regfunk(p->name, 1);
08218
08219
08220 peercnt_modify(0, 0, &p->addr);
08221
08222
08223 memcpy(&p->addr, sin, sizeof(p->addr));
08224
08225 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08226 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08227 ast_db_put("IAX/Registry", p->name, data);
08228 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08229 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08230 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08231 register_peer_exten(p, 1);
08232 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08233 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
08234 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08235 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08236 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08237 register_peer_exten(p, 0);
08238 ast_db_del("IAX/Registry", p->name);
08239 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08240 }
08241
08242
08243 iax2_poke_peer(p, callno);
08244 }
08245
08246
08247 if (p->maxcallno) {
08248 peercnt_modify(1, p->maxcallno, &p->addr);
08249 }
08250
08251
08252 if (!iaxs[callno]) {
08253 res = -1;
08254 goto return_unref;
08255 }
08256
08257
08258 p->sockfd = fd;
08259
08260 if (p->expire > -1) {
08261 if (!ast_sched_del(sched, p->expire)) {
08262 p->expire = -1;
08263 peer_unref(p);
08264 }
08265 }
08266
08267 if (!refresh)
08268 refresh = min_reg_expire;
08269 if (refresh > max_reg_expire) {
08270 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08271 p->name, max_reg_expire, refresh);
08272 p->expiry = max_reg_expire;
08273 } else if (refresh < min_reg_expire) {
08274 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08275 p->name, min_reg_expire, refresh);
08276 p->expiry = min_reg_expire;
08277 } else {
08278 p->expiry = refresh;
08279 }
08280 if (p->expiry && sin->sin_addr.s_addr) {
08281 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08282 if (p->expire == -1)
08283 peer_unref(p);
08284 }
08285 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08286 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08287 if (sin->sin_addr.s_addr) {
08288 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08289 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
08290 if (!ast_strlen_zero(p->mailbox)) {
08291 struct ast_event *event;
08292 int new, old;
08293 char *mailbox, *context;
08294
08295 context = mailbox = ast_strdupa(p->mailbox);
08296 strsep(&context, "@");
08297 if (ast_strlen_zero(context))
08298 context = "default";
08299
08300 event = ast_event_get_cached(AST_EVENT_MWI,
08301 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08302 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08303 AST_EVENT_IE_END);
08304 if (event) {
08305 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08306 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08307 ast_event_destroy(event);
08308 } else {
08309 ast_app_inboxcount(p->mailbox, &new, &old);
08310 }
08311
08312 if (new > 255) {
08313 new = 255;
08314 }
08315 if (old > 255) {
08316 old = 255;
08317 }
08318 msgcount = (old << 8) | new;
08319
08320 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08321 }
08322 if (ast_test_flag(p, IAX_HASCALLERID)) {
08323 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08324 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08325 }
08326 }
08327 version = iax_check_version(devtype);
08328 if (version)
08329 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08330
08331 res = 0;
08332
08333 return_unref:
08334 peer_unref(p);
08335
08336 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08337 }
08338
08339 static int registry_authrequest(int callno)
08340 {
08341 struct iax_ie_data ied;
08342 struct iax2_peer *p;
08343 char challenge[10];
08344 const char *peer_name;
08345 int sentauthmethod;
08346
08347 peer_name = ast_strdupa(iaxs[callno]->peer);
08348
08349
08350 ast_mutex_unlock(&iaxsl[callno]);
08351 if ((p = find_peer(peer_name, 1))) {
08352 last_authmethod = p->authmethods;
08353 }
08354
08355 ast_mutex_lock(&iaxsl[callno]);
08356 if (!iaxs[callno])
08357 goto return_unref;
08358
08359 memset(&ied, 0, sizeof(ied));
08360
08361
08362
08363
08364
08365
08366 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08367 if (!p) {
08368 iaxs[callno]->authmethods = sentauthmethod;
08369 }
08370 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08371 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08372
08373 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08374 ast_string_field_set(iaxs[callno], challenge, challenge);
08375 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08376 }
08377 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08378
08379 return_unref:
08380 if (p) {
08381 peer_unref(p);
08382 }
08383
08384 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08385 }
08386
08387 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08388 {
08389 struct iax2_registry *reg;
08390
08391 struct iax_ie_data ied;
08392 char peer[256] = "";
08393 char challenge[256] = "";
08394 int res;
08395 int authmethods = 0;
08396 if (ies->authmethods)
08397 authmethods = ies->authmethods;
08398 if (ies->username)
08399 ast_copy_string(peer, ies->username, sizeof(peer));
08400 if (ies->challenge)
08401 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08402 memset(&ied, 0, sizeof(ied));
08403 reg = iaxs[callno]->reg;
08404 if (reg) {
08405 if (inaddrcmp(®->addr, sin)) {
08406 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08407 return -1;
08408 }
08409 if (ast_strlen_zero(reg->secret)) {
08410 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08411 reg->regstate = REG_STATE_NOAUTH;
08412 return -1;
08413 }
08414 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08415 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08416 if (reg->secret[0] == '[') {
08417 char tmpkey[256];
08418 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08419 tmpkey[strlen(tmpkey) - 1] = '\0';
08420 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08421 } else
08422 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08423 if (!res) {
08424 reg->regstate = REG_STATE_AUTHSENT;
08425 add_empty_calltoken_ie(iaxs[callno], &ied);
08426 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08427 } else
08428 return -1;
08429 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08430 } else
08431 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08432 return -1;
08433 }
08434
08435 static void stop_stuff(int callno)
08436 {
08437 iax2_destroy_helper(iaxs[callno]);
08438 }
08439
08440 static void __auth_reject(const void *nothing)
08441 {
08442
08443 int callno = (int)(long)(nothing);
08444 struct iax_ie_data ied;
08445 ast_mutex_lock(&iaxsl[callno]);
08446 if (iaxs[callno]) {
08447 memset(&ied, 0, sizeof(ied));
08448 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08449 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08450 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08451 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08452 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08453 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08454 }
08455 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08456 }
08457 ast_mutex_unlock(&iaxsl[callno]);
08458 }
08459
08460 static int auth_reject(const void *data)
08461 {
08462 int callno = (int)(long)(data);
08463 ast_mutex_lock(&iaxsl[callno]);
08464 if (iaxs[callno])
08465 iaxs[callno]->authid = -1;
08466 ast_mutex_unlock(&iaxsl[callno]);
08467 #ifdef SCHED_MULTITHREADED
08468 if (schedule_action(__auth_reject, data))
08469 #endif
08470 __auth_reject(data);
08471 return 0;
08472 }
08473
08474 static int auth_fail(int callno, int failcode)
08475 {
08476
08477
08478 if (iaxs[callno]) {
08479 iaxs[callno]->authfail = failcode;
08480 if (delayreject) {
08481 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08482 sched, 1000, auth_reject, (void *)(long)callno);
08483 } else
08484 auth_reject((void *)(long)callno);
08485 }
08486 return 0;
08487 }
08488
08489 static void __auto_hangup(const void *nothing)
08490 {
08491
08492 int callno = (int)(long)(nothing);
08493 struct iax_ie_data ied;
08494 ast_mutex_lock(&iaxsl[callno]);
08495 if (iaxs[callno]) {
08496 memset(&ied, 0, sizeof(ied));
08497 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08498 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
08499 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
08500 }
08501 ast_mutex_unlock(&iaxsl[callno]);
08502 }
08503
08504 static int auto_hangup(const void *data)
08505 {
08506 int callno = (int)(long)(data);
08507 ast_mutex_lock(&iaxsl[callno]);
08508 if (iaxs[callno]) {
08509 iaxs[callno]->autoid = -1;
08510 }
08511 ast_mutex_unlock(&iaxsl[callno]);
08512 #ifdef SCHED_MULTITHREADED
08513 if (schedule_action(__auto_hangup, data))
08514 #endif
08515 __auto_hangup(data);
08516 return 0;
08517 }
08518
08519 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
08520 {
08521 struct iax_ie_data ied;
08522
08523 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
08524 sched, 30000, auto_hangup, (void *)(long)callno);
08525 memset(&ied, 0, sizeof(ied));
08526 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
08527 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
08528 dp->flags |= CACHE_FLAG_TRANSMITTED;
08529 }
08530
08531 static int iax2_vnak(int callno)
08532 {
08533 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
08534 }
08535
08536 static void vnak_retransmit(int callno, int last)
08537 {
08538 struct iax_frame *f;
08539
08540 AST_LIST_LOCK(&frame_queue);
08541 AST_LIST_TRAVERSE(&frame_queue, f, list) {
08542
08543 if ((f->callno == callno) && iaxs[f->callno] &&
08544 ((unsigned char ) (f->oseqno - last) < 128) &&
08545 (f->retries >= 0)) {
08546 send_packet(f);
08547 }
08548 }
08549 AST_LIST_UNLOCK(&frame_queue);
08550 }
08551
08552 static void __iax2_poke_peer_s(const void *data)
08553 {
08554 struct iax2_peer *peer = (struct iax2_peer *)data;
08555 iax2_poke_peer(peer, 0);
08556 peer_unref(peer);
08557 }
08558
08559 static int iax2_poke_peer_s(const void *data)
08560 {
08561 struct iax2_peer *peer = (struct iax2_peer *)data;
08562 peer->pokeexpire = -1;
08563 #ifdef SCHED_MULTITHREADED
08564 if (schedule_action(__iax2_poke_peer_s, data))
08565 #endif
08566 __iax2_poke_peer_s(data);
08567 return 0;
08568 }
08569
08570 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
08571 {
08572 int res = 0;
08573 struct iax_frame *fr;
08574 struct ast_iax2_meta_hdr *meta;
08575 struct ast_iax2_meta_trunk_hdr *mth;
08576 int calls = 0;
08577
08578
08579 fr = (struct iax_frame *)tpeer->trunkdata;
08580
08581 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
08582 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
08583 if (tpeer->trunkdatalen) {
08584
08585 meta->zeros = 0;
08586 meta->metacmd = IAX_META_TRUNK;
08587 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
08588 meta->cmddata = IAX_META_TRUNK_MINI;
08589 else
08590 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
08591 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
08592
08593 fr->direction = DIRECTION_OUTGRESS;
08594 fr->retrans = -1;
08595 fr->transfer = 0;
08596
08597 fr->data = fr->afdata;
08598 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
08599 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
08600 calls = tpeer->calls;
08601 #if 0
08602 ast_debug(1, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
08603 #endif
08604
08605 tpeer->trunkdatalen = 0;
08606 tpeer->calls = 0;
08607 }
08608 if (res < 0)
08609 return res;
08610 return calls;
08611 }
08612
08613 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
08614 {
08615
08616 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
08617 return 1;
08618 return 0;
08619 }
08620
08621 static int timing_read(int *id, int fd, short events, void *cbdata)
08622 {
08623 int res, processed = 0, totalcalls = 0;
08624 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
08625 struct timeval now = ast_tvnow();
08626
08627 if (iaxtrunkdebug)
08628 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
08629
08630 if (timer) {
08631 ast_timer_ack(timer, 1);
08632 }
08633
08634
08635 AST_LIST_LOCK(&tpeers);
08636 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
08637 processed++;
08638 res = 0;
08639 ast_mutex_lock(&tpeer->lock);
08640
08641
08642 if (!drop && iax2_trunk_expired(tpeer, &now)) {
08643
08644
08645 AST_LIST_REMOVE_CURRENT(list);
08646 drop = tpeer;
08647 } else {
08648 res = send_trunk(tpeer, &now);
08649 trunk_timed++;
08650 if (iaxtrunkdebug)
08651 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);
08652 }
08653 totalcalls += res;
08654 res = 0;
08655 ast_mutex_unlock(&tpeer->lock);
08656 }
08657 AST_LIST_TRAVERSE_SAFE_END;
08658 AST_LIST_UNLOCK(&tpeers);
08659
08660 if (drop) {
08661 ast_mutex_lock(&drop->lock);
08662
08663
08664 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
08665 if (drop->trunkdata) {
08666 ast_free(drop->trunkdata);
08667 drop->trunkdata = NULL;
08668 }
08669 ast_mutex_unlock(&drop->lock);
08670 ast_mutex_destroy(&drop->lock);
08671 ast_free(drop);
08672
08673 }
08674
08675 if (iaxtrunkdebug)
08676 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
08677 iaxtrunkdebug = 0;
08678
08679 return 1;
08680 }
08681
08682 struct dpreq_data {
08683 int callno;
08684 char context[AST_MAX_EXTENSION];
08685 char callednum[AST_MAX_EXTENSION];
08686 char *callerid;
08687 };
08688
08689 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
08690 {
08691 unsigned short dpstatus = 0;
08692 struct iax_ie_data ied1;
08693 int mm;
08694
08695 memset(&ied1, 0, sizeof(ied1));
08696 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
08697
08698 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
08699 dpstatus = IAX_DPSTATUS_EXISTS;
08700 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
08701 dpstatus = IAX_DPSTATUS_CANEXIST;
08702 } else {
08703 dpstatus = IAX_DPSTATUS_NONEXISTENT;
08704 }
08705 if (ast_ignore_pattern(context, callednum))
08706 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
08707 if (mm)
08708 dpstatus |= IAX_DPSTATUS_MATCHMORE;
08709 if (!skiplock)
08710 ast_mutex_lock(&iaxsl[callno]);
08711 if (iaxs[callno]) {
08712 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
08713 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
08714 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
08715 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
08716 }
08717 if (!skiplock)
08718 ast_mutex_unlock(&iaxsl[callno]);
08719 }
08720
08721 static void *dp_lookup_thread(void *data)
08722 {
08723
08724 struct dpreq_data *dpr = data;
08725 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
08726 if (dpr->callerid)
08727 ast_free(dpr->callerid);
08728 ast_free(dpr);
08729 return NULL;
08730 }
08731
08732 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
08733 {
08734 pthread_t newthread;
08735 struct dpreq_data *dpr;
08736
08737 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
08738 return;
08739
08740 dpr->callno = callno;
08741 ast_copy_string(dpr->context, context, sizeof(dpr->context));
08742 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
08743 if (callerid)
08744 dpr->callerid = ast_strdup(callerid);
08745 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
08746 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
08747 }
08748 }
08749
08750 struct iax_dual {
08751 struct ast_channel *chan1;
08752 struct ast_channel *chan2;
08753 };
08754
08755 static void *iax_park_thread(void *stuff)
08756 {
08757 struct ast_channel *chan1, *chan2;
08758 struct iax_dual *d;
08759 struct ast_frame *f;
08760 int ext;
08761 int res;
08762 d = stuff;
08763 chan1 = d->chan1;
08764 chan2 = d->chan2;
08765 ast_free(d);
08766 f = ast_read(chan1);
08767 if (f)
08768 ast_frfree(f);
08769 res = ast_park_call(chan1, chan2, 0, &ext);
08770 ast_hangup(chan2);
08771 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
08772 return NULL;
08773 }
08774
08775 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
08776 {
08777 struct iax_dual *d;
08778 struct ast_channel *chan1m, *chan2m;
08779 pthread_t th;
08780 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
08781 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
08782 if (chan2m && chan1m) {
08783
08784 chan1m->readformat = chan1->readformat;
08785 chan1m->writeformat = chan1->writeformat;
08786 ast_channel_masquerade(chan1m, chan1);
08787
08788 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
08789 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
08790 chan1m->priority = chan1->priority;
08791
08792
08793
08794
08795 chan2m->readformat = chan2->readformat;
08796 chan2m->writeformat = chan2->writeformat;
08797 ast_channel_masquerade(chan2m, chan2);
08798
08799 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
08800 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
08801 chan2m->priority = chan2->priority;
08802 if (ast_do_masquerade(chan2m)) {
08803 ast_log(LOG_WARNING, "Masquerade failed :(\n");
08804 ast_hangup(chan2m);
08805 return -1;
08806 }
08807 } else {
08808 if (chan1m)
08809 ast_hangup(chan1m);
08810 if (chan2m)
08811 ast_hangup(chan2m);
08812 return -1;
08813 }
08814 if ((d = ast_calloc(1, sizeof(*d)))) {
08815 d->chan1 = chan1m;
08816 d->chan2 = chan2m;
08817 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
08818 return 0;
08819 }
08820 ast_free(d);
08821 }
08822 return -1;
08823 }
08824
08825
08826 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
08827
08828 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
08829 {
08830 unsigned int ourver;
08831 char rsi[80];
08832 snprintf(rsi, sizeof(rsi), "si-%s", si);
08833 if (iax_provision_version(&ourver, rsi, 1))
08834 return 0;
08835 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
08836 if (ourver != ver)
08837 iax2_provision(sin, sockfd, NULL, rsi, 1);
08838 return 0;
08839 }
08840
08841 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
08842 {
08843 jb_info stats;
08844 jb_getinfo(pvt->jb, &stats);
08845
08846 memset(iep, 0, sizeof(*iep));
08847
08848 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
08849 if(stats.frames_in == 0) stats.frames_in = 1;
08850 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
08851 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
08852 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
08853 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
08854 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
08855 }
08856
08857 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
08858 {
08859 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
08860 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
08861 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
08862 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
08863 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
08864 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
08865 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
08866 }
08867
08868 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
08869 {
08870 int i;
08871 unsigned int length, offset = 0;
08872 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
08873
08874 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
08875 length = ies->ospblocklength[i];
08876 if (length != 0) {
08877 if (length > IAX_MAX_OSPBLOCK_SIZE) {
08878
08879 offset = 0;
08880 break;
08881 } else {
08882 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
08883 offset += length;
08884 }
08885 } else {
08886 break;
08887 }
08888 }
08889 *(full_osptoken + offset) = '\0';
08890 if (strlen(full_osptoken) != offset) {
08891
08892 *full_osptoken = '\0';
08893 }
08894
08895 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
08896 }
08897
08898 static void log_jitterstats(unsigned short callno)
08899 {
08900 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
08901 jb_info jbinfo;
08902
08903 ast_mutex_lock(&iaxsl[callno]);
08904 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
08905 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
08906 jb_getinfo(iaxs[callno]->jb, &jbinfo);
08907 localjitter = jbinfo.jitter;
08908 localdelay = jbinfo.current - jbinfo.min;
08909 locallost = jbinfo.frames_lost;
08910 locallosspct = jbinfo.losspct/1000;
08911 localdropped = jbinfo.frames_dropped;
08912 localooo = jbinfo.frames_ooo;
08913 localpackets = jbinfo.frames_in;
08914 }
08915 ast_debug(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n",
08916 iaxs[callno]->owner->name,
08917 iaxs[callno]->pingtime,
08918 localjitter,
08919 localdelay,
08920 locallost,
08921 locallosspct,
08922 localdropped,
08923 localooo,
08924 localpackets,
08925 iaxs[callno]->remote_rr.jitter,
08926 iaxs[callno]->remote_rr.delay,
08927 iaxs[callno]->remote_rr.losscnt,
08928 iaxs[callno]->remote_rr.losspct/1000,
08929 iaxs[callno]->remote_rr.dropped,
08930 iaxs[callno]->remote_rr.ooo,
08931 iaxs[callno]->remote_rr.packets);
08932 manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n",
08933 iaxs[callno]->owner->name,
08934 iaxs[callno]->pingtime,
08935 localjitter,
08936 localdelay,
08937 locallost,
08938 locallosspct,
08939 localdropped,
08940 localooo,
08941 localpackets,
08942 iaxs[callno]->remote_rr.jitter,
08943 iaxs[callno]->remote_rr.delay,
08944 iaxs[callno]->remote_rr.losscnt,
08945 iaxs[callno]->remote_rr.losspct/1000,
08946 iaxs[callno]->remote_rr.dropped,
08947 iaxs[callno]->remote_rr.ooo,
08948 iaxs[callno]->remote_rr.packets);
08949 }
08950 ast_mutex_unlock(&iaxsl[callno]);
08951 }
08952
08953 static int socket_process(struct iax2_thread *thread);
08954
08955
08956
08957
08958 static void handle_deferred_full_frames(struct iax2_thread *thread)
08959 {
08960 struct iax2_pkt_buf *pkt_buf;
08961
08962 ast_mutex_lock(&thread->lock);
08963
08964 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
08965 ast_mutex_unlock(&thread->lock);
08966
08967 thread->buf = pkt_buf->buf;
08968 thread->buf_len = pkt_buf->len;
08969 thread->buf_size = pkt_buf->len + 1;
08970
08971 socket_process(thread);
08972
08973 thread->buf = NULL;
08974 ast_free(pkt_buf);
08975
08976 ast_mutex_lock(&thread->lock);
08977 }
08978
08979 ast_mutex_unlock(&thread->lock);
08980 }
08981
08982
08983
08984
08985
08986
08987
08988 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
08989 {
08990 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
08991 struct ast_iax2_full_hdr *fh, *cur_fh;
08992
08993 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
08994 return;
08995
08996 pkt_buf->len = from_here->buf_len;
08997 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
08998
08999 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09000 ast_mutex_lock(&to_here->lock);
09001 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09002 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09003 if (fh->oseqno < cur_fh->oseqno) {
09004 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09005 break;
09006 }
09007 }
09008 AST_LIST_TRAVERSE_SAFE_END
09009
09010 if (!cur_pkt_buf)
09011 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09012
09013 ast_mutex_unlock(&to_here->lock);
09014 }
09015
09016 static int socket_read(int *id, int fd, short events, void *cbdata)
09017 {
09018 struct iax2_thread *thread;
09019 socklen_t len;
09020 time_t t;
09021 static time_t last_errtime = 0;
09022 struct ast_iax2_full_hdr *fh;
09023
09024 if (!(thread = find_idle_thread())) {
09025 time(&t);
09026 if (t != last_errtime)
09027 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09028 last_errtime = t;
09029 usleep(1);
09030 return 1;
09031 }
09032
09033 len = sizeof(thread->iosin);
09034 thread->iofd = fd;
09035 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09036 thread->buf_size = sizeof(thread->readbuf);
09037 thread->buf = thread->readbuf;
09038 if (thread->buf_len < 0) {
09039 if (errno != ECONNREFUSED && errno != EAGAIN)
09040 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09041 handle_error();
09042 thread->iostate = IAX_IOSTATE_IDLE;
09043 signal_condition(&thread->lock, &thread->cond);
09044 return 1;
09045 }
09046 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09047 thread->iostate = IAX_IOSTATE_IDLE;
09048 signal_condition(&thread->lock, &thread->cond);
09049 return 1;
09050 }
09051
09052
09053
09054
09055 fh = (struct ast_iax2_full_hdr *) thread->buf;
09056 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09057 struct iax2_thread *cur = NULL;
09058 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09059
09060 AST_LIST_LOCK(&active_list);
09061 AST_LIST_TRAVERSE(&active_list, cur, list) {
09062 if ((cur->ffinfo.callno == callno) &&
09063 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09064 break;
09065 }
09066 if (cur) {
09067
09068
09069 defer_full_frame(thread, cur);
09070 AST_LIST_UNLOCK(&active_list);
09071 thread->iostate = IAX_IOSTATE_IDLE;
09072 signal_condition(&thread->lock, &thread->cond);
09073 return 1;
09074 } else {
09075
09076 thread->ffinfo.callno = callno;
09077 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09078 thread->ffinfo.type = fh->type;
09079 thread->ffinfo.csub = fh->csub;
09080 }
09081 AST_LIST_UNLOCK(&active_list);
09082 }
09083
09084
09085 thread->iostate = IAX_IOSTATE_READY;
09086 #ifdef DEBUG_SCHED_MULTITHREAD
09087 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09088 #endif
09089 signal_condition(&thread->lock, &thread->cond);
09090
09091 return 1;
09092 }
09093
09094 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09095 struct iax_frame *fr)
09096 {
09097 unsigned char metatype;
09098 struct ast_iax2_meta_trunk_mini *mtm;
09099 struct ast_iax2_meta_trunk_hdr *mth;
09100 struct ast_iax2_meta_trunk_entry *mte;
09101 struct iax2_trunk_peer *tpeer;
09102 unsigned int ts;
09103 void *ptr;
09104 struct timeval rxtrunktime;
09105 struct ast_frame f = { 0, };
09106
09107 if (packet_len < sizeof(*meta)) {
09108 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09109 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09110 return 1;
09111 }
09112
09113 if (meta->metacmd != IAX_META_TRUNK)
09114 return 1;
09115
09116 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09117 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09118 (int) (sizeof(*meta) + sizeof(*mth)));
09119 return 1;
09120 }
09121 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09122 ts = ntohl(mth->ts);
09123 metatype = meta->cmddata;
09124 packet_len -= (sizeof(*meta) + sizeof(*mth));
09125 ptr = mth->data;
09126 tpeer = find_tpeer(sin, sockfd);
09127 if (!tpeer) {
09128 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09129 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09130 return 1;
09131 }
09132 tpeer->trunkact = ast_tvnow();
09133 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09134 tpeer->rxtrunktime = tpeer->trunkact;
09135 rxtrunktime = tpeer->rxtrunktime;
09136 ast_mutex_unlock(&tpeer->lock);
09137 while (packet_len >= sizeof(*mte)) {
09138
09139 unsigned short callno, trunked_ts, len;
09140
09141 if (metatype == IAX_META_TRUNK_MINI) {
09142 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09143 ptr += sizeof(*mtm);
09144 packet_len -= sizeof(*mtm);
09145 len = ntohs(mtm->len);
09146 callno = ntohs(mtm->mini.callno);
09147 trunked_ts = ntohs(mtm->mini.ts);
09148 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09149 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09150 ptr += sizeof(*mte);
09151 packet_len -= sizeof(*mte);
09152 len = ntohs(mte->len);
09153 callno = ntohs(mte->callno);
09154 trunked_ts = 0;
09155 } else {
09156 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09157 break;
09158 }
09159
09160 if (len > packet_len)
09161 break;
09162 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09163 if (!fr->callno)
09164 continue;
09165
09166
09167
09168
09169 memset(&f, 0, sizeof(f));
09170 f.frametype = AST_FRAME_VOICE;
09171 if (!iaxs[fr->callno]) {
09172
09173 } else if (iaxs[fr->callno]->voiceformat == 0) {
09174 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09175 iax2_vnak(fr->callno);
09176 } else {
09177 f.subclass = iaxs[fr->callno]->voiceformat;
09178 f.datalen = len;
09179 if (f.datalen >= 0) {
09180 if (f.datalen)
09181 f.data.ptr = ptr;
09182 else
09183 f.data.ptr = NULL;
09184 if (trunked_ts)
09185 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09186 else
09187 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09188
09189 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09190 struct iax_frame *duped_fr;
09191
09192
09193 f.src = "IAX2";
09194 f.mallocd = 0;
09195 f.offset = 0;
09196 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09197 f.samples = ast_codec_get_samples(&f);
09198 else
09199 f.samples = 0;
09200 fr->outoforder = 0;
09201 iax_frame_wrap(fr, &f);
09202 duped_fr = iaxfrdup2(fr);
09203 if (duped_fr)
09204 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09205 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09206 iaxs[fr->callno]->last = fr->ts;
09207 }
09208 } else {
09209 ast_log(LOG_WARNING, "Datalen < 0?\n");
09210 }
09211 }
09212 ast_mutex_unlock(&iaxsl[fr->callno]);
09213 ptr += len;
09214 packet_len -= len;
09215 }
09216
09217 return 1;
09218 }
09219
09220 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09221 {
09222 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09223 AST_LIST_HEAD(, ast_var_t) *varlist;
09224 struct ast_var_t *var;
09225
09226 if (!variablestore) {
09227 *buf = '\0';
09228 return 0;
09229 }
09230 varlist = variablestore->data;
09231
09232 AST_LIST_LOCK(varlist);
09233 AST_LIST_TRAVERSE(varlist, var, entries) {
09234 if (strcmp(var->name, data) == 0) {
09235 ast_copy_string(buf, var->value, len);
09236 break;
09237 }
09238 }
09239 AST_LIST_UNLOCK(varlist);
09240 return 0;
09241 }
09242
09243 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09244 {
09245 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09246 AST_LIST_HEAD(, ast_var_t) *varlist;
09247 struct ast_var_t *var;
09248
09249 if (!variablestore) {
09250 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09251 if (!variablestore) {
09252 ast_log(LOG_ERROR, "Memory allocation error\n");
09253 return -1;
09254 }
09255 varlist = ast_calloc(1, sizeof(*varlist));
09256 if (!varlist) {
09257 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09258 return -1;
09259 }
09260
09261 AST_LIST_HEAD_INIT(varlist);
09262 variablestore->data = varlist;
09263 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09264 ast_channel_datastore_add(chan, variablestore);
09265 } else
09266 varlist = variablestore->data;
09267
09268 AST_LIST_LOCK(varlist);
09269 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09270 if (strcmp(var->name, data) == 0) {
09271 AST_LIST_REMOVE_CURRENT(entries);
09272 ast_var_delete(var);
09273 break;
09274 }
09275 }
09276 AST_LIST_TRAVERSE_SAFE_END;
09277 var = ast_var_assign(data, value);
09278 if (var)
09279 AST_LIST_INSERT_TAIL(varlist, var, entries);
09280 else
09281 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09282 AST_LIST_UNLOCK(varlist);
09283 return 0;
09284 }
09285
09286 static struct ast_custom_function iaxvar_function = {
09287 .name = "IAXVAR",
09288 .synopsis = "Sets or retrieves a remote variable",
09289 .syntax = "IAXVAR(<varname>)",
09290 .read = acf_iaxvar_read,
09291 .write = acf_iaxvar_write,
09292 };
09293
09294 static int socket_process(struct iax2_thread *thread)
09295 {
09296 struct sockaddr_in sin;
09297 int res;
09298 int updatehistory=1;
09299 int new = NEW_PREVENT;
09300 int dcallno = 0;
09301 char decrypted = 0;
09302 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09303 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09304 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09305 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09306 struct iax_frame *fr;
09307 struct iax_frame *cur;
09308 struct ast_frame f = { 0, };
09309 struct ast_channel *c = NULL;
09310 struct iax2_dpcache *dp;
09311 struct iax2_peer *peer;
09312 struct iax_ies ies;
09313 struct iax_ie_data ied0, ied1;
09314 int format;
09315 int fd;
09316 int exists;
09317 int minivid = 0;
09318 char empty[32]="";
09319 struct iax_frame *duped_fr;
09320 char host_pref_buf[128];
09321 char caller_pref_buf[128];
09322 struct ast_codec_pref pref;
09323 char *using_prefs = "mine";
09324
09325
09326 fr = alloca(sizeof(*fr) + 4096);
09327 memset(fr, 0, sizeof(*fr));
09328 fr->afdatalen = 4096;
09329
09330
09331 res = thread->buf_len;
09332 fd = thread->iofd;
09333 memcpy(&sin, &thread->iosin, sizeof(sin));
09334
09335 if (res < sizeof(*mh)) {
09336 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09337 return 1;
09338 }
09339 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09340 if (res < sizeof(*vh)) {
09341 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));
09342 return 1;
09343 }
09344
09345
09346 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09347 minivid = 1;
09348 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09349 return socket_process_meta(res, meta, &sin, fd, fr);
09350
09351 #ifdef DEBUG_SUPPORT
09352 if (res >= sizeof(*fh))
09353 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09354 #endif
09355 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09356 if (res < sizeof(*fh)) {
09357 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));
09358 return 1;
09359 }
09360
09361
09362 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09363
09364
09365
09366
09367
09368
09369 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09370 ast_mutex_lock(&iaxsl[fr->callno]);
09371 if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
09372 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09373 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09374 ast_mutex_unlock(&iaxsl[fr->callno]);
09375 return 1;
09376 }
09377 decrypted = 1;
09378 }
09379 ast_mutex_unlock(&iaxsl[fr->callno]);
09380 }
09381
09382
09383 f.frametype = fh->type;
09384 if (f.frametype == AST_FRAME_VIDEO) {
09385 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09386 } else {
09387 f.subclass = uncompress_subclass(fh->csub);
09388 }
09389
09390
09391 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
09392
09393 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09394 return 1;
09395 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
09396
09397 return 1;
09398 }
09399
09400 f.datalen = res - sizeof(*fh);
09401 if (f.datalen) {
09402 if (f.frametype == AST_FRAME_IAX) {
09403 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09404 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09405 return 1;
09406 }
09407 f.data.ptr = NULL;
09408 f.datalen = 0;
09409 } else {
09410 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09411 memset(&ies, 0, sizeof(ies));
09412 }
09413 } else {
09414 if (f.frametype == AST_FRAME_IAX)
09415 f.data.ptr = NULL;
09416 else
09417 f.data.ptr = empty;
09418 memset(&ies, 0, sizeof(ies));
09419 }
09420
09421 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) {
09422
09423 if (handle_call_token(fh, &ies, &sin, fd)) {
09424 return 1;
09425 }
09426
09427 if (ies.calltoken && ies.calltokendata) {
09428
09429
09430
09431
09432 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09433 } else {
09434 new = NEW_ALLOW;
09435 }
09436 }
09437 } else {
09438
09439 f.frametype = AST_FRAME_NULL;
09440 f.subclass = 0;
09441 }
09442
09443 if (!fr->callno) {
09444 int check_dcallno = 0;
09445
09446
09447
09448
09449
09450
09451
09452
09453
09454 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) {
09455 check_dcallno = 1;
09456 }
09457
09458 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09459 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) {
09460 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09461 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) {
09462 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09463 }
09464 return 1;
09465 }
09466 }
09467
09468 if (fr->callno > 0)
09469 ast_mutex_lock(&iaxsl[fr->callno]);
09470
09471 if (!fr->callno || !iaxs[fr->callno]) {
09472
09473
09474 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09475
09476 if (((f.subclass != IAX_COMMAND_INVAL) &&
09477 (f.subclass != IAX_COMMAND_TXCNT) &&
09478 (f.subclass != IAX_COMMAND_TXACC) &&
09479 (f.subclass != IAX_COMMAND_FWDOWNL))||
09480 (f.frametype != AST_FRAME_IAX))
09481 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09482 fd);
09483 }
09484 if (fr->callno > 0)
09485 ast_mutex_unlock(&iaxsl[fr->callno]);
09486 return 1;
09487 }
09488 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
09489 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09490 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09491 ast_mutex_unlock(&iaxsl[fr->callno]);
09492 return 1;
09493 }
09494 decrypted = 1;
09495 }
09496 #ifdef DEBUG_SUPPORT
09497 if (decrypted) {
09498 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
09499 }
09500 #endif
09501
09502
09503 iaxs[fr->callno]->frames_received++;
09504
09505 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
09506 f.subclass != IAX_COMMAND_TXCNT &&
09507 f.subclass != IAX_COMMAND_TXACC) {
09508 unsigned short new_peercallno;
09509
09510 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
09511 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
09512 if (iaxs[fr->callno]->peercallno) {
09513 remove_by_peercallno(iaxs[fr->callno]);
09514 }
09515 iaxs[fr->callno]->peercallno = new_peercallno;
09516 store_by_peercallno(iaxs[fr->callno]);
09517 }
09518 }
09519 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09520 if (iaxdebug)
09521 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
09522
09523 fr->oseqno = fh->oseqno;
09524 fr->iseqno = fh->iseqno;
09525 fr->ts = ntohl(fh->ts);
09526 #ifdef IAXTESTS
09527 if (test_resync) {
09528 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
09529 fr->ts += test_resync;
09530 }
09531 #endif
09532 #if 0
09533 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
09534 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
09535 (f.subclass == IAX_COMMAND_NEW ||
09536 f.subclass == IAX_COMMAND_AUTHREQ ||
09537 f.subclass == IAX_COMMAND_ACCEPT ||
09538 f.subclass == IAX_COMMAND_REJECT)) ) )
09539 #endif
09540 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
09541 updatehistory = 0;
09542 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
09543 (iaxs[fr->callno]->iseqno ||
09544 ((f.subclass != IAX_COMMAND_TXCNT) &&
09545 (f.subclass != IAX_COMMAND_TXREADY) &&
09546 (f.subclass != IAX_COMMAND_TXREL) &&
09547 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09548 (f.subclass != IAX_COMMAND_TXACC)) ||
09549 (f.frametype != AST_FRAME_IAX))) {
09550 if (
09551 ((f.subclass != IAX_COMMAND_ACK) &&
09552 (f.subclass != IAX_COMMAND_INVAL) &&
09553 (f.subclass != IAX_COMMAND_TXCNT) &&
09554 (f.subclass != IAX_COMMAND_TXREADY) &&
09555 (f.subclass != IAX_COMMAND_TXREL) &&
09556 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09557 (f.subclass != IAX_COMMAND_TXACC) &&
09558 (f.subclass != IAX_COMMAND_VNAK)) ||
09559 (f.frametype != AST_FRAME_IAX)) {
09560
09561 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
09562 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
09563
09564
09565 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
09566
09567 if ((f.frametype != AST_FRAME_IAX) ||
09568 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
09569 ast_debug(1, "Acking anyway\n");
09570
09571
09572 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09573 }
09574 } else {
09575
09576 iax2_vnak(fr->callno);
09577 }
09578 ast_mutex_unlock(&iaxsl[fr->callno]);
09579 return 1;
09580 }
09581 } else {
09582
09583 if (((f.subclass != IAX_COMMAND_ACK) &&
09584 (f.subclass != IAX_COMMAND_INVAL) &&
09585 (f.subclass != IAX_COMMAND_TXCNT) &&
09586 (f.subclass != IAX_COMMAND_TXACC) &&
09587 (f.subclass != IAX_COMMAND_VNAK)) ||
09588 (f.frametype != AST_FRAME_IAX))
09589 iaxs[fr->callno]->iseqno++;
09590 }
09591
09592 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
09593 if (res < thread->buf_size)
09594 thread->buf[res++] = '\0';
09595 else
09596 thread->buf[res - 1] = '\0';
09597 }
09598
09599
09600
09601 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09602 ((f.subclass != IAX_COMMAND_INVAL) ||
09603 (f.frametype != AST_FRAME_IAX))) {
09604 unsigned char x;
09605 int call_to_destroy;
09606
09607 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
09608 x = fr->iseqno;
09609 else
09610 x = iaxs[fr->callno]->oseqno;
09611 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
09612
09613
09614 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
09615
09616 if (iaxdebug)
09617 ast_debug(1, "Cancelling transmission of packet %d\n", x);
09618 call_to_destroy = 0;
09619 AST_LIST_LOCK(&frame_queue);
09620 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09621
09622 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
09623 cur->retries = -1;
09624
09625 if (cur->final)
09626 call_to_destroy = fr->callno;
09627 }
09628 }
09629 AST_LIST_UNLOCK(&frame_queue);
09630 if (call_to_destroy) {
09631 if (iaxdebug)
09632 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
09633 ast_mutex_lock(&iaxsl[call_to_destroy]);
09634 iax2_destroy(call_to_destroy);
09635 ast_mutex_unlock(&iaxsl[call_to_destroy]);
09636 }
09637 }
09638
09639 if (iaxs[fr->callno])
09640 iaxs[fr->callno]->rseqno = fr->iseqno;
09641 else {
09642
09643 ast_mutex_unlock(&iaxsl[fr->callno]);
09644 return 1;
09645 }
09646 } else {
09647 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
09648 }
09649 }
09650 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09651 ((f.frametype != AST_FRAME_IAX) ||
09652 ((f.subclass != IAX_COMMAND_TXACC) &&
09653 (f.subclass != IAX_COMMAND_TXCNT)))) {
09654
09655 ast_mutex_unlock(&iaxsl[fr->callno]);
09656 return 1;
09657 }
09658
09659
09660
09661
09662 if ((f.frametype == AST_FRAME_VOICE) ||
09663 (f.frametype == AST_FRAME_VIDEO) ||
09664 (f.frametype == AST_FRAME_IAX)) {
09665 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
09666 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
09667 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
09668 ast_mutex_unlock(&iaxsl[fr->callno]);
09669 return 1;
09670 }
09671 }
09672
09673 if (ies.vars) {
09674 struct ast_datastore *variablestore = NULL;
09675 struct ast_variable *var, *prev = NULL;
09676 AST_LIST_HEAD(, ast_var_t) *varlist;
09677 if ((c = iaxs[fr->callno]->owner)) {
09678 varlist = ast_calloc(1, sizeof(*varlist));
09679 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09680
09681 if (variablestore && varlist) {
09682 variablestore->data = varlist;
09683 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09684 AST_LIST_HEAD_INIT(varlist);
09685 ast_debug(1, "I can haz IAX vars?\n");
09686 for (var = ies.vars; var; var = var->next) {
09687 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09688 if (prev) {
09689 ast_free(prev);
09690 }
09691 prev = var;
09692 if (!newvar) {
09693
09694 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09695 } else {
09696 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09697 }
09698 }
09699 if (prev) {
09700 ast_free(prev);
09701 }
09702 ies.vars = NULL;
09703 ast_channel_datastore_add(c, variablestore);
09704 } else {
09705 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09706 if (variablestore) {
09707 ast_datastore_free(variablestore);
09708 }
09709 if (varlist) {
09710 ast_free(varlist);
09711 }
09712 }
09713 } else {
09714
09715
09716 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
09717 for (var = ies.vars; var && var->next; var = var->next);
09718 if (var) {
09719 var->next = iaxs[fr->callno]->iaxvars;
09720 iaxs[fr->callno]->iaxvars = ies.vars;
09721 ies.vars = NULL;
09722 }
09723 }
09724 }
09725
09726 if (ies.vars) {
09727 ast_debug(1, "I have IAX variables, but they were not processed\n");
09728 }
09729 }
09730
09731
09732
09733 if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
09734 send_signaling(iaxs[fr->callno]);
09735 }
09736
09737 if (f.frametype == AST_FRAME_VOICE) {
09738 if (f.subclass != iaxs[fr->callno]->voiceformat) {
09739 iaxs[fr->callno]->voiceformat = f.subclass;
09740 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
09741 if (iaxs[fr->callno]->owner) {
09742 int orignative;
09743 retryowner:
09744 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
09745 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09746 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
09747 }
09748 if (iaxs[fr->callno]) {
09749 if (iaxs[fr->callno]->owner) {
09750 orignative = iaxs[fr->callno]->owner->nativeformats;
09751 iaxs[fr->callno]->owner->nativeformats = f.subclass;
09752 if (iaxs[fr->callno]->owner->readformat)
09753 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
09754 iaxs[fr->callno]->owner->nativeformats = orignative;
09755 ast_channel_unlock(iaxs[fr->callno]->owner);
09756 }
09757 } else {
09758 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
09759
09760 if (ies.vars) {
09761 ast_variables_destroy(ies.vars);
09762 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
09763 ies.vars = NULL;
09764 }
09765 ast_mutex_unlock(&iaxsl[fr->callno]);
09766 return 1;
09767 }
09768 }
09769 }
09770 }
09771 if (f.frametype == AST_FRAME_VIDEO) {
09772 if (f.subclass != iaxs[fr->callno]->videoformat) {
09773 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
09774 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
09775 }
09776 }
09777 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
09778 if (f.subclass == AST_CONTROL_BUSY) {
09779 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
09780 } else if (f.subclass == AST_CONTROL_CONGESTION) {
09781 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
09782 }
09783 }
09784 if (f.frametype == AST_FRAME_IAX) {
09785 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
09786
09787 if (iaxdebug)
09788 ast_debug(1, "IAX subclass %d received\n", f.subclass);
09789
09790
09791 if (iaxs[fr->callno]->last < fr->ts &&
09792 f.subclass != IAX_COMMAND_ACK &&
09793 f.subclass != IAX_COMMAND_PONG &&
09794 f.subclass != IAX_COMMAND_LAGRP) {
09795 iaxs[fr->callno]->last = fr->ts;
09796 if (iaxdebug)
09797 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09798 }
09799 iaxs[fr->callno]->last_iax_message = f.subclass;
09800 if (!iaxs[fr->callno]->first_iax_message) {
09801 iaxs[fr->callno]->first_iax_message = f.subclass;
09802 }
09803 switch(f.subclass) {
09804 case IAX_COMMAND_ACK:
09805
09806 break;
09807 case IAX_COMMAND_QUELCH:
09808 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09809
09810 if (iaxs[fr->callno]->owner) {
09811 manager_event(EVENT_FLAG_CALL, "Hold",
09812 "Status: On\r\n"
09813 "Channel: %s\r\n"
09814 "Uniqueid: %s\r\n",
09815 iaxs[fr->callno]->owner->name,
09816 iaxs[fr->callno]->owner->uniqueid);
09817 }
09818
09819 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
09820 if (ies.musiconhold) {
09821 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
09822 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
09823 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
09824 S_OR(moh_suggest, NULL),
09825 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
09826 if (!iaxs[fr->callno]) {
09827 ast_mutex_unlock(&iaxsl[fr->callno]);
09828 return 1;
09829 }
09830 }
09831 }
09832 }
09833 break;
09834 case IAX_COMMAND_UNQUELCH:
09835 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09836
09837 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
09838 manager_event(EVENT_FLAG_CALL, "Hold",
09839 "Status: Off\r\n"
09840 "Channel: %s\r\n"
09841 "Uniqueid: %s\r\n",
09842 iaxs[fr->callno]->owner->name,
09843 iaxs[fr->callno]->owner->uniqueid);
09844 }
09845
09846 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
09847 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
09848 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
09849 if (!iaxs[fr->callno]) {
09850 ast_mutex_unlock(&iaxsl[fr->callno]);
09851 return 1;
09852 }
09853 }
09854 }
09855 break;
09856 case IAX_COMMAND_TXACC:
09857 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
09858
09859 AST_LIST_LOCK(&frame_queue);
09860 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09861
09862 if ((fr->callno == cur->callno) && (cur->transfer))
09863 cur->retries = -1;
09864 }
09865 AST_LIST_UNLOCK(&frame_queue);
09866 memset(&ied1, 0, sizeof(ied1));
09867 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
09868 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
09869 iaxs[fr->callno]->transferring = TRANSFER_READY;
09870 }
09871 break;
09872 case IAX_COMMAND_NEW:
09873
09874 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
09875 break;
09876 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
09877 ast_mutex_unlock(&iaxsl[fr->callno]);
09878 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
09879 ast_mutex_lock(&iaxsl[fr->callno]);
09880 if (!iaxs[fr->callno]) {
09881 ast_mutex_unlock(&iaxsl[fr->callno]);
09882 return 1;
09883 }
09884 }
09885
09886 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
09887 int new_callno;
09888 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
09889 fr->callno = new_callno;
09890 }
09891
09892 if (delayreject)
09893 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09894 if (check_access(fr->callno, &sin, &ies)) {
09895
09896 auth_fail(fr->callno, IAX_COMMAND_REJECT);
09897 if (authdebug)
09898 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);
09899 break;
09900 }
09901 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
09902 const char *context, *exten, *cid_num;
09903
09904 context = ast_strdupa(iaxs[fr->callno]->context);
09905 exten = ast_strdupa(iaxs[fr->callno]->exten);
09906 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
09907
09908
09909 ast_mutex_unlock(&iaxsl[fr->callno]);
09910 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
09911 ast_mutex_lock(&iaxsl[fr->callno]);
09912
09913 if (!iaxs[fr->callno]) {
09914 ast_mutex_unlock(&iaxsl[fr->callno]);
09915 return 1;
09916 }
09917 } else
09918 exists = 0;
09919
09920 save_osptoken(fr, &ies);
09921 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
09922 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
09923 memset(&ied0, 0, sizeof(ied0));
09924 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09925 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09926 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09927 if (!iaxs[fr->callno]) {
09928 ast_mutex_unlock(&iaxsl[fr->callno]);
09929 return 1;
09930 }
09931 if (authdebug)
09932 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);
09933 } else {
09934
09935
09936 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09937 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09938 using_prefs = "reqonly";
09939 } else {
09940 using_prefs = "disabled";
09941 }
09942 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
09943 memset(&pref, 0, sizeof(pref));
09944 strcpy(caller_pref_buf, "disabled");
09945 strcpy(host_pref_buf, "disabled");
09946 } else {
09947 using_prefs = "mine";
09948
09949 if (ies.codec_prefs)
09950 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
09951 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09952
09953 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09954 pref = iaxs[fr->callno]->rprefs;
09955 using_prefs = "caller";
09956 } else {
09957 pref = iaxs[fr->callno]->prefs;
09958 }
09959 } else
09960 pref = iaxs[fr->callno]->prefs;
09961
09962 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
09963 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
09964 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
09965 }
09966 if (!format) {
09967 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09968 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
09969 if (!format) {
09970 memset(&ied0, 0, sizeof(ied0));
09971 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09972 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09973 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09974 if (!iaxs[fr->callno]) {
09975 ast_mutex_unlock(&iaxsl[fr->callno]);
09976 return 1;
09977 }
09978 if (authdebug) {
09979 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09980 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);
09981 else
09982 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);
09983 }
09984 } else {
09985
09986 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09987 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
09988 format = 0;
09989 } else {
09990 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09991 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
09992 memset(&pref, 0, sizeof(pref));
09993 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09994 strcpy(caller_pref_buf,"disabled");
09995 strcpy(host_pref_buf,"disabled");
09996 } else {
09997 using_prefs = "mine";
09998 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09999
10000 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10001 pref = iaxs[fr->callno]->prefs;
10002 } else {
10003 pref = iaxs[fr->callno]->rprefs;
10004 using_prefs = "caller";
10005 }
10006 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10007
10008 } else
10009 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10010 }
10011 }
10012
10013 if (!format) {
10014 memset(&ied0, 0, sizeof(ied0));
10015 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10016 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10017 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10018 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10019 if (!iaxs[fr->callno]) {
10020 ast_mutex_unlock(&iaxsl[fr->callno]);
10021 return 1;
10022 }
10023 if (authdebug)
10024 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);
10025 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10026 break;
10027 }
10028 }
10029 }
10030 if (format) {
10031
10032 memset(&ied1, 0, sizeof(ied1));
10033 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10034 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10035 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10036 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10037 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10038 "%srequested format = %s,\n"
10039 "%srequested prefs = %s,\n"
10040 "%sactual format = %s,\n"
10041 "%shost prefs = %s,\n"
10042 "%spriority = %s\n",
10043 ast_inet_ntoa(sin.sin_addr),
10044 VERBOSE_PREFIX_4,
10045 ast_getformatname(iaxs[fr->callno]->peerformat),
10046 VERBOSE_PREFIX_4,
10047 caller_pref_buf,
10048 VERBOSE_PREFIX_4,
10049 ast_getformatname(format),
10050 VERBOSE_PREFIX_4,
10051 host_pref_buf,
10052 VERBOSE_PREFIX_4,
10053 using_prefs);
10054
10055 iaxs[fr->callno]->chosenformat = format;
10056 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
10057 } else {
10058 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10059
10060 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10061 }
10062 }
10063 }
10064 break;
10065 }
10066 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10067 merge_encryption(iaxs[fr->callno],ies.encmethods);
10068 else
10069 iaxs[fr->callno]->encmethods = 0;
10070 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10071 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10072 if (!iaxs[fr->callno]) {
10073 ast_mutex_unlock(&iaxsl[fr->callno]);
10074 return 1;
10075 }
10076 break;
10077 case IAX_COMMAND_DPREQ:
10078
10079 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10080 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10081 if (iaxcompat) {
10082
10083 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10084 } else {
10085
10086 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10087 }
10088 }
10089 break;
10090 case IAX_COMMAND_HANGUP:
10091 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10092 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10093
10094 if (ies.causecode && iaxs[fr->callno]->owner)
10095 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10096
10097 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10098 iax2_destroy(fr->callno);
10099 break;
10100 case IAX_COMMAND_REJECT:
10101
10102 if (ies.causecode && iaxs[fr->callno]->owner)
10103 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10104
10105 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10106 if (iaxs[fr->callno]->owner && authdebug)
10107 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10108 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10109 ies.cause ? ies.cause : "<Unknown>");
10110 ast_debug(1, "Immediately destroying %d, having received reject\n",
10111 fr->callno);
10112 }
10113
10114 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10115 fr->ts, NULL, 0, fr->iseqno);
10116 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
10117 iaxs[fr->callno]->error = EPERM;
10118 iax2_destroy(fr->callno);
10119 break;
10120 case IAX_COMMAND_TRANSFER:
10121 {
10122 struct ast_channel *bridged_chan;
10123
10124 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
10125
10126
10127 ast_mutex_unlock(&iaxsl[fr->callno]);
10128 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
10129 ast_mutex_lock(&iaxsl[fr->callno]);
10130 if (!iaxs[fr->callno]) {
10131 ast_mutex_unlock(&iaxsl[fr->callno]);
10132 return 1;
10133 }
10134
10135 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
10136 if (!strcmp(ies.called_number, ast_parking_ext())) {
10137 struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
10138 ast_mutex_unlock(&iaxsl[fr->callno]);
10139 if (iax_park(bridged_chan, saved_channel)) {
10140 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
10141 } else {
10142 ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
10143 }
10144 ast_mutex_lock(&iaxsl[fr->callno]);
10145 } else {
10146 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
10147 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
10148 ies.called_number, iaxs[fr->callno]->context);
10149 else {
10150 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
10151 ies.called_number, iaxs[fr->callno]->context);
10152 }
10153 }
10154 } else {
10155 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10156 }
10157
10158 break;
10159 }
10160 case IAX_COMMAND_ACCEPT:
10161
10162 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10163 break;
10164 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10165
10166 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10167 iax2_destroy(fr->callno);
10168 break;
10169 }
10170 if (ies.format) {
10171 iaxs[fr->callno]->peerformat = ies.format;
10172 } else {
10173 if (iaxs[fr->callno]->owner)
10174 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10175 else
10176 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10177 }
10178 ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
10179 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10180 memset(&ied0, 0, sizeof(ied0));
10181 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10182 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10183 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10184 if (!iaxs[fr->callno]) {
10185 ast_mutex_unlock(&iaxsl[fr->callno]);
10186 return 1;
10187 }
10188 if (authdebug)
10189 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);
10190 } else {
10191 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10192 if (iaxs[fr->callno]->owner) {
10193
10194 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10195 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10196 retryowner2:
10197 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
10198 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
10199 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
10200 }
10201
10202 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10203
10204 if (iaxs[fr->callno]->owner->writeformat)
10205 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10206 if (iaxs[fr->callno]->owner->readformat)
10207 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10208 ast_channel_unlock(iaxs[fr->callno]->owner);
10209 }
10210 }
10211 }
10212 if (iaxs[fr->callno]) {
10213 AST_LIST_LOCK(&dpcache);
10214 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10215 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10216 iax2_dprequest(dp, fr->callno);
10217 AST_LIST_UNLOCK(&dpcache);
10218 }
10219 break;
10220 case IAX_COMMAND_POKE:
10221
10222 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10223 if (!iaxs[fr->callno]) {
10224 ast_mutex_unlock(&iaxsl[fr->callno]);
10225 return 1;
10226 }
10227 break;
10228 case IAX_COMMAND_PING:
10229 {
10230 struct iax_ie_data pingied;
10231 construct_rr(iaxs[fr->callno], &pingied);
10232
10233 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10234 }
10235 break;
10236 case IAX_COMMAND_PONG:
10237
10238 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10239
10240 save_rr(fr, &ies);
10241
10242
10243 log_jitterstats(fr->callno);
10244
10245 if (iaxs[fr->callno]->peerpoke) {
10246 peer = iaxs[fr->callno]->peerpoke;
10247 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10248 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10249 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10250 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
10251 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10252 }
10253 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10254 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10255 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10256 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
10257 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10258 }
10259 }
10260 peer->lastms = iaxs[fr->callno]->pingtime;
10261 if (peer->smoothing && (peer->lastms > -1))
10262 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10263 else if (peer->smoothing && peer->lastms < 0)
10264 peer->historicms = (0 + peer->historicms) / 2;
10265 else
10266 peer->historicms = iaxs[fr->callno]->pingtime;
10267
10268
10269 if (peer->pokeexpire > -1) {
10270 if (!ast_sched_del(sched, peer->pokeexpire)) {
10271 peer_unref(peer);
10272 peer->pokeexpire = -1;
10273 }
10274 }
10275
10276 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10277 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10278 else
10279 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10280 if (peer->pokeexpire == -1)
10281 peer_unref(peer);
10282
10283 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10284
10285 iax2_destroy(fr->callno);
10286 peer->callno = 0;
10287 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10288 }
10289 break;
10290 case IAX_COMMAND_LAGRQ:
10291 case IAX_COMMAND_LAGRP:
10292 f.src = "LAGRQ";
10293 f.mallocd = 0;
10294 f.offset = 0;
10295 f.samples = 0;
10296 iax_frame_wrap(fr, &f);
10297 if(f.subclass == IAX_COMMAND_LAGRQ) {
10298
10299 fr->af.subclass = IAX_COMMAND_LAGRP;
10300 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10301 } else {
10302
10303 unsigned int ts;
10304
10305 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10306 iaxs[fr->callno]->lag = ts - fr->ts;
10307 if (iaxdebug)
10308 ast_debug(1, "Peer %s lag measured as %dms\n",
10309 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10310 }
10311 break;
10312 case IAX_COMMAND_AUTHREQ:
10313 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10314 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>");
10315 break;
10316 }
10317 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10318 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10319 .subclass = AST_CONTROL_HANGUP,
10320 };
10321 ast_log(LOG_WARNING,
10322 "I don't know how to authenticate %s to %s\n",
10323 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10324 iax2_queue_frame(fr->callno, &hangup_fr);
10325 }
10326 if (!iaxs[fr->callno]) {
10327 ast_mutex_unlock(&iaxsl[fr->callno]);
10328 return 1;
10329 }
10330 break;
10331 case IAX_COMMAND_AUTHREP:
10332
10333 if (delayreject)
10334 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10335
10336 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10337 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>");
10338 break;
10339 }
10340 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10341 if (authdebug)
10342 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);
10343 memset(&ied0, 0, sizeof(ied0));
10344 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10345 break;
10346 }
10347 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10348
10349 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10350 } else
10351 exists = 0;
10352 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10353 if (authdebug)
10354 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);
10355 memset(&ied0, 0, sizeof(ied0));
10356 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10357 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10358 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10359 if (!iaxs[fr->callno]) {
10360 ast_mutex_unlock(&iaxsl[fr->callno]);
10361 return 1;
10362 }
10363 } else {
10364
10365 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10366 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10367 using_prefs = "reqonly";
10368 } else {
10369 using_prefs = "disabled";
10370 }
10371 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10372 memset(&pref, 0, sizeof(pref));
10373 strcpy(caller_pref_buf, "disabled");
10374 strcpy(host_pref_buf, "disabled");
10375 } else {
10376 using_prefs = "mine";
10377 if (ies.codec_prefs)
10378 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10379 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10380 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10381 pref = iaxs[fr->callno]->rprefs;
10382 using_prefs = "caller";
10383 } else {
10384 pref = iaxs[fr->callno]->prefs;
10385 }
10386 } else
10387 pref = iaxs[fr->callno]->prefs;
10388
10389 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10390 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10391 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10392 }
10393 if (!format) {
10394 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10395 ast_debug(1, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
10396 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10397 }
10398 if (!format) {
10399 if (authdebug) {
10400 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10401 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);
10402 else
10403 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);
10404 }
10405 memset(&ied0, 0, sizeof(ied0));
10406 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10407 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10408 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10409 if (!iaxs[fr->callno]) {
10410 ast_mutex_unlock(&iaxsl[fr->callno]);
10411 return 1;
10412 }
10413 } else {
10414
10415 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10416 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10417 format = 0;
10418 } else {
10419 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10420 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10421 memset(&pref, 0, sizeof(pref));
10422 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10423 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10424 strcpy(caller_pref_buf,"disabled");
10425 strcpy(host_pref_buf,"disabled");
10426 } else {
10427 using_prefs = "mine";
10428 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10429
10430 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10431 pref = iaxs[fr->callno]->prefs;
10432 } else {
10433 pref = iaxs[fr->callno]->rprefs;
10434 using_prefs = "caller";
10435 }
10436 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10437 } else
10438 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10439 }
10440 }
10441 if (!format) {
10442 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10443 if (authdebug) {
10444 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10445 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);
10446 else
10447 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);
10448 }
10449 memset(&ied0, 0, sizeof(ied0));
10450 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10451 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10452 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10453 if (!iaxs[fr->callno]) {
10454 ast_mutex_unlock(&iaxsl[fr->callno]);
10455 return 1;
10456 }
10457 }
10458 }
10459 }
10460 if (format) {
10461
10462 memset(&ied1, 0, sizeof(ied1));
10463 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10464 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10465 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10466 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10467 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
10468 "%srequested format = %s,\n"
10469 "%srequested prefs = %s,\n"
10470 "%sactual format = %s,\n"
10471 "%shost prefs = %s,\n"
10472 "%spriority = %s\n",
10473 ast_inet_ntoa(sin.sin_addr),
10474 VERBOSE_PREFIX_4,
10475 ast_getformatname(iaxs[fr->callno]->peerformat),
10476 VERBOSE_PREFIX_4,
10477 caller_pref_buf,
10478 VERBOSE_PREFIX_4,
10479 ast_getformatname(format),
10480 VERBOSE_PREFIX_4,
10481 host_pref_buf,
10482 VERBOSE_PREFIX_4,
10483 using_prefs);
10484
10485 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10486 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
10487 iax2_destroy(fr->callno);
10488 else if (ies.vars) {
10489 struct ast_datastore *variablestore;
10490 struct ast_variable *var, *prev = NULL;
10491 AST_LIST_HEAD(, ast_var_t) *varlist;
10492 varlist = ast_calloc(1, sizeof(*varlist));
10493 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10494 if (variablestore && varlist) {
10495 variablestore->data = varlist;
10496 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10497 AST_LIST_HEAD_INIT(varlist);
10498 ast_debug(1, "I can haz IAX vars? w00t\n");
10499 for (var = ies.vars; var; var = var->next) {
10500 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10501 if (prev)
10502 ast_free(prev);
10503 prev = var;
10504 if (!newvar) {
10505
10506 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10507 } else {
10508 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10509 }
10510 }
10511 if (prev)
10512 ast_free(prev);
10513 ies.vars = NULL;
10514 ast_channel_datastore_add(c, variablestore);
10515 } else {
10516 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10517 if (variablestore)
10518 ast_datastore_free(variablestore);
10519 if (varlist)
10520 ast_free(varlist);
10521 }
10522 }
10523 } else {
10524 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10525
10526 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10527 }
10528 }
10529 }
10530 break;
10531 case IAX_COMMAND_DIAL:
10532 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
10533 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10534 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
10535 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
10536 if (authdebug)
10537 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);
10538 memset(&ied0, 0, sizeof(ied0));
10539 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10540 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10541 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10542 if (!iaxs[fr->callno]) {
10543 ast_mutex_unlock(&iaxsl[fr->callno]);
10544 return 1;
10545 }
10546 } else {
10547 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10548 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
10549 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10550 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
10551 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
10552 iax2_destroy(fr->callno);
10553 else if (ies.vars) {
10554 struct ast_datastore *variablestore;
10555 struct ast_variable *var, *prev = NULL;
10556 AST_LIST_HEAD(, ast_var_t) *varlist;
10557 varlist = ast_calloc(1, sizeof(*varlist));
10558 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10559 ast_debug(1, "I can haz IAX vars? w00t\n");
10560 if (variablestore && varlist) {
10561 variablestore->data = varlist;
10562 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10563 AST_LIST_HEAD_INIT(varlist);
10564 for (var = ies.vars; var; var = var->next) {
10565 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10566 if (prev)
10567 ast_free(prev);
10568 prev = var;
10569 if (!newvar) {
10570
10571 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10572 } else {
10573 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10574 }
10575 }
10576 if (prev)
10577 ast_free(prev);
10578 ies.vars = NULL;
10579 ast_channel_datastore_add(c, variablestore);
10580 } else {
10581 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10582 if (variablestore)
10583 ast_datastore_free(variablestore);
10584 if (varlist)
10585 ast_free(varlist);
10586 }
10587 }
10588 }
10589 }
10590 break;
10591 case IAX_COMMAND_INVAL:
10592 iaxs[fr->callno]->error = ENOTCONN;
10593 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
10594 iax2_destroy(fr->callno);
10595 ast_debug(1, "Destroying call %d\n", fr->callno);
10596 break;
10597 case IAX_COMMAND_VNAK:
10598 ast_debug(1, "Received VNAK: resending outstanding frames\n");
10599
10600 vnak_retransmit(fr->callno, fr->iseqno);
10601 break;
10602 case IAX_COMMAND_REGREQ:
10603 case IAX_COMMAND_REGREL:
10604
10605 if (delayreject)
10606 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10607 if (register_verify(fr->callno, &sin, &ies)) {
10608 if (!iaxs[fr->callno]) {
10609 ast_mutex_unlock(&iaxsl[fr->callno]);
10610 return 1;
10611 }
10612
10613 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
10614 break;
10615 }
10616 if (!iaxs[fr->callno]) {
10617 ast_mutex_unlock(&iaxsl[fr->callno]);
10618 return 1;
10619 }
10620 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
10621 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
10622
10623 if (f.subclass == IAX_COMMAND_REGREL)
10624 memset(&sin, 0, sizeof(sin));
10625 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
10626 ast_log(LOG_WARNING, "Registry error\n");
10627 if (!iaxs[fr->callno]) {
10628 ast_mutex_unlock(&iaxsl[fr->callno]);
10629 return 1;
10630 }
10631 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10632 ast_mutex_unlock(&iaxsl[fr->callno]);
10633 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10634 ast_mutex_lock(&iaxsl[fr->callno]);
10635 if (!iaxs[fr->callno]) {
10636 ast_mutex_unlock(&iaxsl[fr->callno]);
10637 return 1;
10638 }
10639 }
10640 break;
10641 }
10642 registry_authrequest(fr->callno);
10643 if (!iaxs[fr->callno]) {
10644 ast_mutex_unlock(&iaxsl[fr->callno]);
10645 return 1;
10646 }
10647 break;
10648 case IAX_COMMAND_REGACK:
10649 if (iax2_ack_registry(&ies, &sin, fr->callno))
10650 ast_log(LOG_WARNING, "Registration failure\n");
10651
10652 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10653 iax2_destroy(fr->callno);
10654 break;
10655 case IAX_COMMAND_REGREJ:
10656 if (iaxs[fr->callno]->reg) {
10657 if (authdebug) {
10658 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));
10659 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
10660 }
10661 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
10662 }
10663
10664 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10665 iax2_destroy(fr->callno);
10666 break;
10667 case IAX_COMMAND_REGAUTH:
10668
10669 if (registry_rerequest(&ies, fr->callno, &sin)) {
10670 memset(&ied0, 0, sizeof(ied0));
10671 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
10672 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
10673 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10674 if (!iaxs[fr->callno]) {
10675 ast_mutex_unlock(&iaxsl[fr->callno]);
10676 return 1;
10677 }
10678 }
10679 break;
10680 case IAX_COMMAND_TXREJ:
10681 iaxs[fr->callno]->transferring = 0;
10682 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10683 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
10684 if (iaxs[fr->callno]->bridgecallno) {
10685 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
10686 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
10687 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
10688 }
10689 }
10690 break;
10691 case IAX_COMMAND_TXREADY:
10692 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
10693 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
10694 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
10695 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
10696 else
10697 iaxs[fr->callno]->transferring = TRANSFER_READY;
10698 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10699 if (iaxs[fr->callno]->bridgecallno) {
10700 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
10701 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
10702
10703 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
10704 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10705 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10706
10707 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
10708 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
10709
10710 memset(&ied0, 0, sizeof(ied0));
10711 memset(&ied1, 0, sizeof(ied1));
10712 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10713 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10714 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
10715 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
10716 } else {
10717 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10718 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10719
10720 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
10721 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
10722 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
10723 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10724
10725
10726 stop_stuff(fr->callno);
10727 stop_stuff(iaxs[fr->callno]->bridgecallno);
10728
10729 memset(&ied0, 0, sizeof(ied0));
10730 memset(&ied1, 0, sizeof(ied1));
10731 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10732 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10733 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
10734 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
10735 }
10736
10737 }
10738 }
10739 }
10740 break;
10741 case IAX_COMMAND_TXREQ:
10742 try_transfer(iaxs[fr->callno], &ies);
10743 break;
10744 case IAX_COMMAND_TXCNT:
10745 if (iaxs[fr->callno]->transferring)
10746 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
10747 break;
10748 case IAX_COMMAND_TXREL:
10749
10750 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10751 complete_transfer(fr->callno, &ies);
10752 stop_stuff(fr->callno);
10753 break;
10754 case IAX_COMMAND_TXMEDIA:
10755 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
10756 AST_LIST_LOCK(&frame_queue);
10757 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10758
10759 if ((fr->callno == cur->callno) && (cur->transfer))
10760 cur->retries = -1;
10761 }
10762 AST_LIST_UNLOCK(&frame_queue);
10763
10764 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
10765 }
10766 break;
10767 case IAX_COMMAND_RTKEY:
10768 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
10769 ast_log(LOG_WARNING,
10770 "we've been told to rotate our encryption key, "
10771 "but this isn't an encrypted call. bad things will happen.\n"
10772 );
10773 break;
10774 }
10775
10776 IAX_DEBUGDIGEST("Receiving", ies.challenge);
10777
10778 ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
10779 break;
10780 case IAX_COMMAND_DPREP:
10781 complete_dpreply(iaxs[fr->callno], &ies);
10782 break;
10783 case IAX_COMMAND_UNSUPPORT:
10784 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
10785 break;
10786 case IAX_COMMAND_FWDOWNL:
10787
10788 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
10789 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
10790 break;
10791 }
10792 memset(&ied0, 0, sizeof(ied0));
10793 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
10794 if (res < 0)
10795 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10796 else if (res > 0)
10797 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
10798 else
10799 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
10800 if (!iaxs[fr->callno]) {
10801 ast_mutex_unlock(&iaxsl[fr->callno]);
10802 return 1;
10803 }
10804 break;
10805 case IAX_COMMAND_CALLTOKEN:
10806 {
10807 struct iax_frame *cur;
10808 int found = 0;
10809 AST_LIST_LOCK(&frame_queue);
10810 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10811
10812
10813
10814 if (cur->callno == fr->callno) {
10815 found = 1;
10816 break;
10817 }
10818 }
10819 AST_LIST_UNLOCK(&frame_queue);
10820
10821
10822 if (cur && found && ies.calltoken && ies.calltokendata) {
10823 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
10824 }
10825 break;
10826 }
10827 default:
10828 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
10829 memset(&ied0, 0, sizeof(ied0));
10830 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
10831 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
10832 }
10833
10834 if (ies.vars) {
10835 ast_variables_destroy(ies.vars);
10836 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
10837 ies.vars = NULL;
10838 }
10839
10840
10841 if ((f.subclass != IAX_COMMAND_ACK) &&
10842 (f.subclass != IAX_COMMAND_TXCNT) &&
10843 (f.subclass != IAX_COMMAND_TXACC) &&
10844 (f.subclass != IAX_COMMAND_INVAL) &&
10845 (f.subclass != IAX_COMMAND_VNAK)) {
10846 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
10847 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10848 }
10849 ast_mutex_unlock(&iaxsl[fr->callno]);
10850 return 1;
10851 }
10852
10853 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
10854 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10855 } else if (minivid) {
10856 f.frametype = AST_FRAME_VIDEO;
10857 if (iaxs[fr->callno]->videoformat > 0)
10858 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
10859 else {
10860 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
10861 iax2_vnak(fr->callno);
10862 ast_mutex_unlock(&iaxsl[fr->callno]);
10863 return 1;
10864 }
10865 f.datalen = res - sizeof(*vh);
10866 if (f.datalen)
10867 f.data.ptr = thread->buf + sizeof(*vh);
10868 else
10869 f.data.ptr = NULL;
10870 #ifdef IAXTESTS
10871 if (test_resync) {
10872 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
10873 } else
10874 #endif
10875 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
10876 } else {
10877
10878 f.frametype = AST_FRAME_VOICE;
10879 if (iaxs[fr->callno]->voiceformat > 0)
10880 f.subclass = iaxs[fr->callno]->voiceformat;
10881 else {
10882 ast_debug(1, "Received mini frame before first full voice frame\n");
10883 iax2_vnak(fr->callno);
10884 ast_mutex_unlock(&iaxsl[fr->callno]);
10885 return 1;
10886 }
10887 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
10888 if (f.datalen < 0) {
10889 ast_log(LOG_WARNING, "Datalen < 0?\n");
10890 ast_mutex_unlock(&iaxsl[fr->callno]);
10891 return 1;
10892 }
10893 if (f.datalen)
10894 f.data.ptr = thread->buf + sizeof(*mh);
10895 else
10896 f.data.ptr = NULL;
10897 #ifdef IAXTESTS
10898 if (test_resync) {
10899 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
10900 } else
10901 #endif
10902 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
10903
10904 }
10905
10906 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10907 ast_mutex_unlock(&iaxsl[fr->callno]);
10908 return 1;
10909 }
10910
10911 f.src = "IAX2";
10912 f.mallocd = 0;
10913 f.offset = 0;
10914 f.len = 0;
10915 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
10916 f.samples = ast_codec_get_samples(&f);
10917
10918 if (f.subclass == AST_FORMAT_SLINEAR)
10919 ast_frame_byteswap_be(&f);
10920 } else
10921 f.samples = 0;
10922 iax_frame_wrap(fr, &f);
10923
10924
10925 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
10926
10927 fr->outoforder = 0;
10928 } else {
10929 if (iaxdebug && iaxs[fr->callno])
10930 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
10931 fr->outoforder = -1;
10932 }
10933 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
10934 duped_fr = iaxfrdup2(fr);
10935 if (duped_fr) {
10936 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
10937 }
10938 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
10939 iaxs[fr->callno]->last = fr->ts;
10940 #if 1
10941 if (iaxdebug)
10942 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10943 #endif
10944 }
10945
10946
10947 ast_mutex_unlock(&iaxsl[fr->callno]);
10948 return 1;
10949 }
10950
10951
10952 static void iax2_process_thread_cleanup(void *data)
10953 {
10954 struct iax2_thread *thread = data;
10955 ast_mutex_destroy(&thread->lock);
10956 ast_cond_destroy(&thread->cond);
10957 ast_mutex_destroy(&thread->init_lock);
10958 ast_cond_destroy(&thread->init_cond);
10959 ast_free(thread);
10960 ast_atomic_dec_and_test(&iaxactivethreadcount);
10961 }
10962
10963 static void *iax2_process_thread(void *data)
10964 {
10965 struct iax2_thread *thread = data;
10966 struct timeval wait;
10967 struct timespec ts;
10968 int put_into_idle = 0;
10969 int first_time = 1;
10970
10971 ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
10972 pthread_cleanup_push(iax2_process_thread_cleanup, data);
10973 for(;;) {
10974
10975 ast_mutex_lock(&thread->lock);
10976
10977
10978 if (first_time) {
10979 signal_condition(&thread->init_lock, &thread->init_cond);
10980 first_time = 0;
10981 }
10982
10983
10984 if (put_into_idle)
10985 insert_idle_thread(thread);
10986
10987 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
10988 struct iax2_thread *t = NULL;
10989
10990 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
10991 ts.tv_sec = wait.tv_sec;
10992 ts.tv_nsec = wait.tv_usec * 1000;
10993 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
10994
10995
10996 if (!put_into_idle) {
10997 ast_mutex_unlock(&thread->lock);
10998 break;
10999 }
11000 AST_LIST_LOCK(&dynamic_list);
11001
11002 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11003 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11004 AST_LIST_UNLOCK(&dynamic_list);
11005 if (t) {
11006
11007
11008
11009 ast_mutex_unlock(&thread->lock);
11010 break;
11011 }
11012
11013
11014
11015 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11016 ts.tv_sec = wait.tv_sec;
11017 ts.tv_nsec = wait.tv_usec * 1000;
11018 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
11019 {
11020 ast_mutex_unlock(&thread->lock);
11021 break;
11022 }
11023 }
11024 } else {
11025 ast_cond_wait(&thread->cond, &thread->lock);
11026 }
11027
11028
11029 put_into_idle = 1;
11030
11031 ast_mutex_unlock(&thread->lock);
11032
11033 if (thread->iostate == IAX_IOSTATE_IDLE)
11034 continue;
11035
11036
11037 AST_LIST_LOCK(&active_list);
11038 AST_LIST_INSERT_HEAD(&active_list, thread, list);
11039 AST_LIST_UNLOCK(&active_list);
11040
11041
11042 switch(thread->iostate) {
11043 case IAX_IOSTATE_READY:
11044 thread->actions++;
11045 thread->iostate = IAX_IOSTATE_PROCESSING;
11046 socket_process(thread);
11047 handle_deferred_full_frames(thread);
11048 break;
11049 case IAX_IOSTATE_SCHEDREADY:
11050 thread->actions++;
11051 thread->iostate = IAX_IOSTATE_PROCESSING;
11052 #ifdef SCHED_MULTITHREADED
11053 thread->schedfunc(thread->scheddata);
11054 #endif
11055 default:
11056 break;
11057 }
11058 time(&thread->checktime);
11059 thread->iostate = IAX_IOSTATE_IDLE;
11060 #ifdef DEBUG_SCHED_MULTITHREAD
11061 thread->curfunc[0]='\0';
11062 #endif
11063
11064
11065 AST_LIST_LOCK(&active_list);
11066 AST_LIST_REMOVE(&active_list, thread, list);
11067 AST_LIST_UNLOCK(&active_list);
11068
11069
11070 handle_deferred_full_frames(thread);
11071 }
11072
11073
11074
11075
11076
11077 AST_LIST_LOCK(&idle_list);
11078 AST_LIST_REMOVE(&idle_list, thread, list);
11079 AST_LIST_UNLOCK(&idle_list);
11080
11081 AST_LIST_LOCK(&dynamic_list);
11082 AST_LIST_REMOVE(&dynamic_list, thread, list);
11083 AST_LIST_UNLOCK(&dynamic_list);
11084
11085
11086
11087
11088 pthread_cleanup_pop(1);
11089 return NULL;
11090 }
11091
11092 static int iax2_do_register(struct iax2_registry *reg)
11093 {
11094 struct iax_ie_data ied;
11095 if (iaxdebug)
11096 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11097
11098 if (reg->dnsmgr &&
11099 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
11100
11101 ast_dnsmgr_refresh(reg->dnsmgr);
11102 }
11103
11104
11105
11106
11107
11108 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11109 int callno = reg->callno;
11110 ast_mutex_lock(&iaxsl[callno]);
11111 iax2_destroy(callno);
11112 ast_mutex_unlock(&iaxsl[callno]);
11113 reg->callno = 0;
11114 }
11115 if (!reg->addr.sin_addr.s_addr) {
11116 if (iaxdebug)
11117 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11118
11119 reg->expire = iax2_sched_replace(reg->expire, sched,
11120 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11121 return -1;
11122 }
11123
11124 if (!reg->callno) {
11125 ast_debug(3, "Allocate call number\n");
11126 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
11127 if (reg->callno < 1) {
11128 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11129 return -1;
11130 } else
11131 ast_debug(3, "Registration created on call %d\n", reg->callno);
11132 iaxs[reg->callno]->reg = reg;
11133 ast_mutex_unlock(&iaxsl[reg->callno]);
11134 }
11135
11136 reg->expire = iax2_sched_replace(reg->expire, sched,
11137 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11138
11139 memset(&ied, 0, sizeof(ied));
11140 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11141 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11142 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11143 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11144 reg->regstate = REG_STATE_REGSENT;
11145 return 0;
11146 }
11147
11148 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
11149 {
11150
11151
11152 struct iax_ie_data provdata;
11153 struct iax_ie_data ied;
11154 unsigned int sig;
11155 struct sockaddr_in sin;
11156 int callno;
11157 struct create_addr_info cai;
11158
11159 memset(&cai, 0, sizeof(cai));
11160
11161 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11162
11163 if (iax_provision_build(&provdata, &sig, template, force)) {
11164 ast_debug(1, "No provisioning found for template '%s'\n", template);
11165 return 0;
11166 }
11167
11168 if (end) {
11169 memcpy(&sin, end, sizeof(sin));
11170 cai.sockfd = sockfd;
11171 } else if (create_addr(dest, NULL, &sin, &cai))
11172 return -1;
11173
11174
11175 memset(&ied, 0, sizeof(ied));
11176 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11177
11178 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11179 if (!callno)
11180 return -1;
11181
11182 if (iaxs[callno]) {
11183
11184 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11185 sched, 15000, auto_hangup, (void *)(long)callno);
11186 ast_set_flag(iaxs[callno], IAX_PROVISION);
11187
11188 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11189 }
11190 ast_mutex_unlock(&iaxsl[callno]);
11191
11192 return 1;
11193 }
11194
11195 static char *papp = "IAX2Provision";
11196 static char *psyn = "Provision a calling IAXy with a given template";
11197 static char *pdescrip =
11198 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
11199 "the calling entity is in fact an IAXy) with the given template or\n"
11200 "default if one is not specified. Returns -1 on error or 0 on success.\n";
11201
11202
11203
11204
11205 static int iax2_prov_app(struct ast_channel *chan, void *data)
11206 {
11207 int res;
11208 char *sdata;
11209 char *opts;
11210 int force =0;
11211 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11212 if (ast_strlen_zero(data))
11213 data = "default";
11214 sdata = ast_strdupa(data);
11215 opts = strchr(sdata, '|');
11216 if (opts)
11217 *opts='\0';
11218
11219 if (chan->tech != &iax2_tech) {
11220 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11221 return -1;
11222 }
11223 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11224 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11225 return -1;
11226 }
11227 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11228 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11229 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11230 sdata, res);
11231 return res;
11232 }
11233
11234 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11235 {
11236 int force = 0;
11237 int res;
11238
11239 switch (cmd) {
11240 case CLI_INIT:
11241 e->command = "iax2 provision";
11242 e->usage =
11243 "Usage: iax2 provision <host> <template> [forced]\n"
11244 " Provisions the given peer or IP address using a template\n"
11245 " matching either 'template' or '*' if the template is not\n"
11246 " found. If 'forced' is specified, even empty provisioning\n"
11247 " fields will be provisioned as empty fields.\n";
11248 return NULL;
11249 case CLI_GENERATE:
11250 if (a->pos == 3)
11251 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11252 return NULL;
11253 }
11254
11255 if (a->argc < 4)
11256 return CLI_SHOWUSAGE;
11257 if (a->argc > 4) {
11258 if (!strcasecmp(a->argv[4], "forced"))
11259 force = 1;
11260 else
11261 return CLI_SHOWUSAGE;
11262 }
11263 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11264 if (res < 0)
11265 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11266 else if (res < 1)
11267 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11268 else
11269 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11270 return CLI_SUCCESS;
11271 }
11272
11273 static void __iax2_poke_noanswer(const void *data)
11274 {
11275 struct iax2_peer *peer = (struct iax2_peer *)data;
11276 int callno;
11277
11278 if (peer->lastms > -1) {
11279 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11280 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11281 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11282 }
11283 if ((callno = peer->callno) > 0) {
11284 ast_mutex_lock(&iaxsl[callno]);
11285 iax2_destroy(callno);
11286 ast_mutex_unlock(&iaxsl[callno]);
11287 }
11288 peer->callno = 0;
11289 peer->lastms = -1;
11290
11291 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11292 if (peer->pokeexpire == -1)
11293 peer_unref(peer);
11294 }
11295
11296 static int iax2_poke_noanswer(const void *data)
11297 {
11298 struct iax2_peer *peer = (struct iax2_peer *)data;
11299 peer->pokeexpire = -1;
11300 #ifdef SCHED_MULTITHREADED
11301 if (schedule_action(__iax2_poke_noanswer, data))
11302 #endif
11303 __iax2_poke_noanswer(data);
11304 peer_unref(peer);
11305 return 0;
11306 }
11307
11308 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11309 {
11310 struct iax2_peer *peer = obj;
11311
11312 iax2_poke_peer(peer, 0);
11313
11314 return 0;
11315 }
11316
11317 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11318 {
11319 int callno;
11320 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
11321
11322
11323 peer->lastms = 0;
11324 peer->historicms = 0;
11325 peer->pokeexpire = -1;
11326 peer->callno = 0;
11327 return 0;
11328 }
11329
11330
11331 if ((callno = peer->callno) > 0) {
11332 ast_log(LOG_NOTICE, "Still have a callno...\n");
11333 ast_mutex_lock(&iaxsl[callno]);
11334 iax2_destroy(callno);
11335 ast_mutex_unlock(&iaxsl[callno]);
11336 }
11337 if (heldcall)
11338 ast_mutex_unlock(&iaxsl[heldcall]);
11339 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
11340 if (heldcall)
11341 ast_mutex_lock(&iaxsl[heldcall]);
11342 if (peer->callno < 1) {
11343 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11344 return -1;
11345 }
11346
11347
11348 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11349 iaxs[peer->callno]->peerpoke = peer;
11350
11351 if (peer->pokeexpire > -1) {
11352 if (!ast_sched_del(sched, peer->pokeexpire)) {
11353 peer->pokeexpire = -1;
11354 peer_unref(peer);
11355 }
11356 }
11357
11358
11359
11360 if (peer->lastms < 0)
11361 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11362 else
11363 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11364
11365 if (peer->pokeexpire == -1)
11366 peer_unref(peer);
11367
11368
11369 ast_mutex_lock(&iaxsl[callno]);
11370 if (iaxs[callno]) {
11371 struct iax_ie_data ied = {
11372 .buf = { 0 },
11373 .pos = 0,
11374 };
11375 add_empty_calltoken_ie(iaxs[callno], &ied);
11376 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11377 }
11378 ast_mutex_unlock(&iaxsl[callno]);
11379
11380 return 0;
11381 }
11382
11383 static void free_context(struct iax2_context *con)
11384 {
11385 struct iax2_context *conl;
11386 while(con) {
11387 conl = con;
11388 con = con->next;
11389 ast_free(conl);
11390 }
11391 }
11392
11393 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
11394 {
11395 int callno;
11396 int res;
11397 int fmt, native;
11398 struct sockaddr_in sin;
11399 struct ast_channel *c;
11400 struct parsed_dial_string pds;
11401 struct create_addr_info cai;
11402 char *tmpstr;
11403
11404 memset(&pds, 0, sizeof(pds));
11405 tmpstr = ast_strdupa(data);
11406 parse_dial_string(tmpstr, &pds);
11407
11408 if (ast_strlen_zero(pds.peer)) {
11409 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
11410 return NULL;
11411 }
11412
11413 memset(&cai, 0, sizeof(cai));
11414 cai.capability = iax2_capability;
11415
11416 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11417
11418
11419 if (create_addr(pds.peer, NULL, &sin, &cai)) {
11420 *cause = AST_CAUSE_UNREGISTERED;
11421 return NULL;
11422 }
11423
11424 if (pds.port)
11425 sin.sin_port = htons(atoi(pds.port));
11426
11427 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11428 if (callno < 1) {
11429 ast_log(LOG_WARNING, "Unable to create call\n");
11430 *cause = AST_CAUSE_CONGESTION;
11431 return NULL;
11432 }
11433
11434
11435 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11436 if (ast_test_flag(&cai, IAX_TRUNK)) {
11437 int new_callno;
11438 if ((new_callno = make_trunk(callno, 1)) != -1)
11439 callno = new_callno;
11440 }
11441 iaxs[callno]->maxtime = cai.maxtime;
11442 if (cai.found)
11443 ast_string_field_set(iaxs[callno], host, pds.peer);
11444
11445 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
11446
11447 ast_mutex_unlock(&iaxsl[callno]);
11448
11449 if (c) {
11450
11451 if (c->nativeformats & format)
11452 c->nativeformats &= format;
11453 else {
11454 native = c->nativeformats;
11455 fmt = format;
11456 res = ast_translator_best_choice(&fmt, &native);
11457 if (res < 0) {
11458 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
11459 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
11460 ast_hangup(c);
11461 return NULL;
11462 }
11463 c->nativeformats = native;
11464 }
11465 c->readformat = ast_best_codec(c->nativeformats);
11466 c->writeformat = c->readformat;
11467 }
11468
11469 return c;
11470 }
11471
11472 static void *sched_thread(void *ignore)
11473 {
11474 int count;
11475 int res;
11476 struct timeval wait;
11477 struct timespec ts;
11478
11479 for (;;) {
11480 pthread_testcancel();
11481 ast_mutex_lock(&sched_lock);
11482 res = ast_sched_wait(sched);
11483 if ((res > 1000) || (res < 0))
11484 res = 1000;
11485 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
11486 ts.tv_sec = wait.tv_sec;
11487 ts.tv_nsec = wait.tv_usec * 1000;
11488 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
11489 ast_mutex_unlock(&sched_lock);
11490 pthread_testcancel();
11491
11492 count = ast_sched_runq(sched);
11493 if (count >= 20)
11494 ast_debug(1, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
11495 }
11496
11497 return NULL;
11498 }
11499
11500 static void *network_thread(void *ignore)
11501 {
11502
11503
11504 int res, count, wakeup;
11505 struct iax_frame *f;
11506
11507 if (timer)
11508 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
11509
11510 for(;;) {
11511 pthread_testcancel();
11512
11513
11514
11515 AST_LIST_LOCK(&frame_queue);
11516 count = 0;
11517 wakeup = -1;
11518 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
11519 if (f->sentyet)
11520 continue;
11521
11522
11523 if (ast_mutex_trylock(&iaxsl[f->callno])) {
11524 wakeup = 1;
11525 continue;
11526 }
11527
11528 f->sentyet = 1;
11529
11530 if (iaxs[f->callno]) {
11531 send_packet(f);
11532 count++;
11533 }
11534
11535 ast_mutex_unlock(&iaxsl[f->callno]);
11536
11537 if (f->retries < 0) {
11538
11539 AST_LIST_REMOVE_CURRENT(list);
11540
11541 iax_frame_free(f);
11542 } else {
11543
11544 f->retries++;
11545 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
11546 }
11547 }
11548 AST_LIST_TRAVERSE_SAFE_END;
11549 AST_LIST_UNLOCK(&frame_queue);
11550
11551 pthread_testcancel();
11552 if (count >= 20)
11553 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
11554
11555
11556 res = ast_io_wait(io, wakeup);
11557 if (res >= 0) {
11558 if (res >= 20)
11559 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
11560 }
11561 }
11562 return NULL;
11563 }
11564
11565 static int start_network_thread(void)
11566 {
11567 struct iax2_thread *thread;
11568 int threadcount = 0;
11569 int x;
11570 for (x = 0; x < iaxthreadcount; x++) {
11571 thread = ast_calloc(1, sizeof(*thread));
11572 if (thread) {
11573 thread->type = IAX_THREAD_TYPE_POOL;
11574 thread->threadnum = ++threadcount;
11575 ast_mutex_init(&thread->lock);
11576 ast_cond_init(&thread->cond, NULL);
11577 if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) {
11578 ast_log(LOG_WARNING, "Failed to create new thread!\n");
11579 ast_free(thread);
11580 thread = NULL;
11581 }
11582 AST_LIST_LOCK(&idle_list);
11583 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
11584 AST_LIST_UNLOCK(&idle_list);
11585 }
11586 }
11587 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
11588 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
11589 ast_verb(2, "%d helper threads started\n", threadcount);
11590 return 0;
11591 }
11592
11593 static struct iax2_context *build_context(const char *context)
11594 {
11595 struct iax2_context *con;
11596
11597 if ((con = ast_calloc(1, sizeof(*con))))
11598 ast_copy_string(con->context, context, sizeof(con->context));
11599
11600 return con;
11601 }
11602
11603 static int get_auth_methods(const char *value)
11604 {
11605 int methods = 0;
11606 if (strstr(value, "rsa"))
11607 methods |= IAX_AUTH_RSA;
11608 if (strstr(value, "md5"))
11609 methods |= IAX_AUTH_MD5;
11610 if (strstr(value, "plaintext"))
11611 methods |= IAX_AUTH_PLAINTEXT;
11612 return methods;
11613 }
11614
11615
11616
11617
11618
11619 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
11620 {
11621 int sd;
11622 int res;
11623
11624 sd = socket(AF_INET, SOCK_DGRAM, 0);
11625 if (sd < 0) {
11626 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
11627 return -1;
11628 }
11629
11630 res = bind(sd, sa, salen);
11631 if (res < 0) {
11632 ast_debug(1, "Can't bind: %s\n", strerror(errno));
11633 close(sd);
11634 return 1;
11635 }
11636
11637 close(sd);
11638 return 0;
11639 }
11640
11641
11642
11643
11644 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
11645 {
11646 struct sockaddr_in sin;
11647 int nonlocal = 1;
11648 int port = IAX_DEFAULT_PORTNO;
11649 int sockfd = defaultsockfd;
11650 char *tmp;
11651 char *addr;
11652 char *portstr;
11653
11654 if (!(tmp = ast_strdupa(srcaddr)))
11655 return -1;
11656
11657 addr = strsep(&tmp, ":");
11658 portstr = tmp;
11659
11660 if (portstr) {
11661 port = atoi(portstr);
11662 if (port < 1)
11663 port = IAX_DEFAULT_PORTNO;
11664 }
11665
11666 if (!ast_get_ip(&sin, addr)) {
11667 struct ast_netsock *sock;
11668 int res;
11669
11670 sin.sin_port = 0;
11671 sin.sin_family = AF_INET;
11672 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
11673 if (res == 0) {
11674
11675 sin.sin_port = htons(port);
11676 if (!(sock = ast_netsock_find(netsock, &sin)))
11677 sock = ast_netsock_find(outsock, &sin);
11678 if (sock) {
11679 sockfd = ast_netsock_sockfd(sock);
11680 nonlocal = 0;
11681 } else {
11682 unsigned int orig_saddr = sin.sin_addr.s_addr;
11683
11684 sin.sin_addr.s_addr = INADDR_ANY;
11685 if (ast_netsock_find(netsock, &sin)) {
11686 sin.sin_addr.s_addr = orig_saddr;
11687 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
11688 if (sock) {
11689 sockfd = ast_netsock_sockfd(sock);
11690 ast_netsock_unref(sock);
11691 nonlocal = 0;
11692 } else {
11693 nonlocal = 2;
11694 }
11695 }
11696 }
11697 }
11698 }
11699
11700 peer->sockfd = sockfd;
11701
11702 if (nonlocal == 1) {
11703 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
11704 srcaddr, peer->name);
11705 return -1;
11706 } else if (nonlocal == 2) {
11707 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
11708 srcaddr, peer->name);
11709 return -1;
11710 } else {
11711 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
11712 return 0;
11713 }
11714 }
11715
11716 static void peer_destructor(void *obj)
11717 {
11718 struct iax2_peer *peer = obj;
11719 int callno = peer->callno;
11720
11721 ast_free_ha(peer->ha);
11722
11723 if (callno > 0) {
11724 ast_mutex_lock(&iaxsl[callno]);
11725 iax2_destroy(callno);
11726 ast_mutex_unlock(&iaxsl[callno]);
11727 }
11728
11729 register_peer_exten(peer, 0);
11730
11731 if (peer->dnsmgr)
11732 ast_dnsmgr_release(peer->dnsmgr);
11733
11734 if (peer->mwi_event_sub)
11735 ast_event_unsubscribe(peer->mwi_event_sub);
11736
11737 ast_string_field_free_memory(peer);
11738 }
11739
11740
11741 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
11742 {
11743 struct iax2_peer *peer = NULL;
11744 struct ast_ha *oldha = NULL;
11745 int maskfound = 0;
11746 int found = 0;
11747 int firstpass = 1;
11748 struct iax2_peer tmp_peer = {
11749 .name = name,
11750 };
11751
11752 if (!temponly) {
11753 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
11754 if (peer && !ast_test_flag(peer, IAX_DELME))
11755 firstpass = 0;
11756 }
11757
11758 if (peer) {
11759 found++;
11760 if (firstpass) {
11761 oldha = peer->ha;
11762 peer->ha = NULL;
11763 }
11764 unlink_peer(peer);
11765 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
11766 peer->expire = -1;
11767 peer->pokeexpire = -1;
11768 peer->sockfd = defaultsockfd;
11769 if (ast_string_field_init(peer, 32))
11770 peer = peer_unref(peer);
11771 }
11772
11773 if (peer) {
11774 if (firstpass) {
11775 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11776 peer->encmethods = iax2_encryption;
11777 peer->adsi = adsi;
11778 ast_string_field_set(peer,secret,"");
11779 if (!found) {
11780 ast_string_field_set(peer, name, name);
11781 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11782 peer->expiry = min_reg_expire;
11783 }
11784 peer->prefs = prefs;
11785 peer->capability = iax2_capability;
11786 peer->smoothing = 0;
11787 peer->pokefreqok = DEFAULT_FREQ_OK;
11788 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
11789 peer->maxcallno = 0;
11790 peercnt_modify(0, 0, &peer->addr);
11791 peer->calltoken_required = CALLTOKEN_DEFAULT;
11792 ast_string_field_set(peer,context,"");
11793 ast_string_field_set(peer,peercontext,"");
11794 ast_clear_flag(peer, IAX_HASCALLERID);
11795 ast_string_field_set(peer, cid_name, "");
11796 ast_string_field_set(peer, cid_num, "");
11797 ast_string_field_set(peer, mohinterpret, mohinterpret);
11798 ast_string_field_set(peer, mohsuggest, mohsuggest);
11799 }
11800
11801 if (!v) {
11802 v = alt;
11803 alt = NULL;
11804 }
11805 while(v) {
11806 if (!strcasecmp(v->name, "secret")) {
11807 ast_string_field_set(peer, secret, v->value);
11808 } else if (!strcasecmp(v->name, "mailbox")) {
11809 ast_string_field_set(peer, mailbox, v->value);
11810 } else if (!strcasecmp(v->name, "hasvoicemail")) {
11811 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
11812 ast_string_field_set(peer, mailbox, name);
11813 }
11814 } else if (!strcasecmp(v->name, "mohinterpret")) {
11815 ast_string_field_set(peer, mohinterpret, v->value);
11816 } else if (!strcasecmp(v->name, "mohsuggest")) {
11817 ast_string_field_set(peer, mohsuggest, v->value);
11818 } else if (!strcasecmp(v->name, "dbsecret")) {
11819 ast_string_field_set(peer, dbsecret, v->value);
11820 } else if (!strcasecmp(v->name, "trunk")) {
11821 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
11822 if (ast_test_flag(peer, IAX_TRUNK) && !timer) {
11823 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
11824 ast_clear_flag(peer, IAX_TRUNK);
11825 }
11826 } else if (!strcasecmp(v->name, "auth")) {
11827 peer->authmethods = get_auth_methods(v->value);
11828 } else if (!strcasecmp(v->name, "encryption")) {
11829 peer->encmethods |= get_encrypt_methods(v->value);
11830 } else if (!strcasecmp(v->name, "transfer")) {
11831 if (!strcasecmp(v->value, "mediaonly")) {
11832 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
11833 } else if (ast_true(v->value)) {
11834 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11835 } else
11836 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11837 } else if (!strcasecmp(v->name, "jitterbuffer")) {
11838 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
11839 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
11840 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
11841 } else if (!strcasecmp(v->name, "host")) {
11842 if (!strcasecmp(v->value, "dynamic")) {
11843
11844 ast_set_flag(peer, IAX_DYNAMIC);
11845 if (!found) {
11846
11847
11848 memset(&peer->addr.sin_addr, 0, 4);
11849 if (peer->addr.sin_port) {
11850
11851 peer->defaddr.sin_port = peer->addr.sin_port;
11852 peer->addr.sin_port = 0;
11853 }
11854 }
11855 } else {
11856
11857 AST_SCHED_DEL(sched, peer->expire);
11858 ast_clear_flag(peer, IAX_DYNAMIC);
11859 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
11860 return peer_unref(peer);
11861 if (!peer->addr.sin_port)
11862 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11863 }
11864 if (!maskfound)
11865 inet_aton("255.255.255.255", &peer->mask);
11866 } else if (!strcasecmp(v->name, "defaultip")) {
11867 if (ast_get_ip(&peer->defaddr, v->value))
11868 return peer_unref(peer);
11869 } else if (!strcasecmp(v->name, "sourceaddress")) {
11870 peer_set_srcaddr(peer, v->value);
11871 } else if (!strcasecmp(v->name, "permit") ||
11872 !strcasecmp(v->name, "deny")) {
11873 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
11874 } else if (!strcasecmp(v->name, "mask")) {
11875 maskfound++;
11876 inet_aton(v->value, &peer->mask);
11877 } else if (!strcasecmp(v->name, "context")) {
11878 ast_string_field_set(peer, context, v->value);
11879 } else if (!strcasecmp(v->name, "regexten")) {
11880 ast_string_field_set(peer, regexten, v->value);
11881 } else if (!strcasecmp(v->name, "peercontext")) {
11882 ast_string_field_set(peer, peercontext, v->value);
11883 } else if (!strcasecmp(v->name, "port")) {
11884 if (ast_test_flag(peer, IAX_DYNAMIC))
11885 peer->defaddr.sin_port = htons(atoi(v->value));
11886 else
11887 peer->addr.sin_port = htons(atoi(v->value));
11888 } else if (!strcasecmp(v->name, "username")) {
11889 ast_string_field_set(peer, username, v->value);
11890 } else if (!strcasecmp(v->name, "allow")) {
11891 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
11892 } else if (!strcasecmp(v->name, "disallow")) {
11893 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
11894 } else if (!strcasecmp(v->name, "callerid")) {
11895 if (!ast_strlen_zero(v->value)) {
11896 char name2[80];
11897 char num2[80];
11898 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
11899 ast_string_field_set(peer, cid_name, name2);
11900 ast_string_field_set(peer, cid_num, num2);
11901 } else {
11902 ast_string_field_set(peer, cid_name, "");
11903 ast_string_field_set(peer, cid_num, "");
11904 }
11905 ast_set_flag(peer, IAX_HASCALLERID);
11906 } else if (!strcasecmp(v->name, "fullname")) {
11907 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
11908 ast_set_flag(peer, IAX_HASCALLERID);
11909 } else if (!strcasecmp(v->name, "cid_number")) {
11910 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
11911 ast_set_flag(peer, IAX_HASCALLERID);
11912 } else if (!strcasecmp(v->name, "sendani")) {
11913 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
11914 } else if (!strcasecmp(v->name, "inkeys")) {
11915 ast_string_field_set(peer, inkeys, v->value);
11916 } else if (!strcasecmp(v->name, "outkey")) {
11917 ast_string_field_set(peer, outkey, v->value);
11918 } else if (!strcasecmp(v->name, "qualify")) {
11919 if (!strcasecmp(v->value, "no")) {
11920 peer->maxms = 0;
11921 } else if (!strcasecmp(v->value, "yes")) {
11922 peer->maxms = DEFAULT_MAXMS;
11923 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
11924 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);
11925 peer->maxms = 0;
11926 }
11927 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
11928 peer->smoothing = ast_true(v->value);
11929 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
11930 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
11931 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);
11932 }
11933 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
11934 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
11935 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);
11936 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
11937 } else if (!strcasecmp(v->name, "timezone")) {
11938 ast_string_field_set(peer, zonetag, v->value);
11939 } else if (!strcasecmp(v->name, "adsi")) {
11940 peer->adsi = ast_true(v->value);
11941 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
11942 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
11943 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
11944 } else {
11945 peercnt_modify(1, peer->maxcallno, &peer->addr);
11946 }
11947 } else if (!strcasecmp(v->name, "requirecalltoken")) {
11948
11949 if (ast_false(v->value)) {
11950 peer->calltoken_required = CALLTOKEN_NO;
11951 } else if (!strcasecmp(v->value, "auto")) {
11952 peer->calltoken_required = CALLTOKEN_AUTO;
11953 } else if (ast_true(v->value)) {
11954 peer->calltoken_required = CALLTOKEN_YES;
11955 } else {
11956 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
11957 }
11958 }
11959
11960 v = v->next;
11961 if (!v) {
11962 v = alt;
11963 alt = NULL;
11964 }
11965 }
11966 if (!peer->authmethods)
11967 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11968 ast_clear_flag(peer, IAX_DELME);
11969
11970 peer->addr.sin_family = AF_INET;
11971 }
11972
11973 if (oldha)
11974 ast_free_ha(oldha);
11975
11976 if (!ast_strlen_zero(peer->mailbox)) {
11977 char *mailbox, *context;
11978 context = mailbox = ast_strdupa(peer->mailbox);
11979 strsep(&context, "@");
11980 if (ast_strlen_zero(context))
11981 context = "default";
11982 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
11983 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
11984 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
11985 AST_EVENT_IE_END);
11986 }
11987
11988 return peer;
11989 }
11990
11991 static void user_destructor(void *obj)
11992 {
11993 struct iax2_user *user = obj;
11994
11995 ast_free_ha(user->ha);
11996 free_context(user->contexts);
11997 if(user->vars) {
11998 ast_variables_destroy(user->vars);
11999 user->vars = NULL;
12000 }
12001 ast_string_field_free_memory(user);
12002 }
12003
12004
12005 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12006 {
12007 struct iax2_user *user = NULL;
12008 struct iax2_context *con, *conl = NULL;
12009 struct ast_ha *oldha = NULL;
12010 struct iax2_context *oldcon = NULL;
12011 int format;
12012 int firstpass=1;
12013 int oldcurauthreq = 0;
12014 char *varname = NULL, *varval = NULL;
12015 struct ast_variable *tmpvar = NULL;
12016 struct iax2_user tmp_user = {
12017 .name = name,
12018 };
12019
12020 if (!temponly) {
12021 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12022 if (user && !ast_test_flag(user, IAX_DELME))
12023 firstpass = 0;
12024 }
12025
12026 if (user) {
12027 if (firstpass) {
12028 oldcurauthreq = user->curauthreq;
12029 oldha = user->ha;
12030 oldcon = user->contexts;
12031 user->ha = NULL;
12032 user->contexts = NULL;
12033 }
12034
12035 ao2_unlink(users, user);
12036 } else {
12037 user = ao2_alloc(sizeof(*user), user_destructor);
12038 }
12039
12040 if (user) {
12041 if (firstpass) {
12042 ast_string_field_free_memory(user);
12043 memset(user, 0, sizeof(struct iax2_user));
12044 if (ast_string_field_init(user, 32)) {
12045 user = user_unref(user);
12046 goto cleanup;
12047 }
12048 user->maxauthreq = maxauthreq;
12049 user->curauthreq = oldcurauthreq;
12050 user->prefs = prefs;
12051 user->capability = iax2_capability;
12052 user->encmethods = iax2_encryption;
12053 user->adsi = adsi;
12054 user->calltoken_required = CALLTOKEN_DEFAULT;
12055 ast_string_field_set(user, name, name);
12056 ast_string_field_set(user, language, language);
12057 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
12058 ast_clear_flag(user, IAX_HASCALLERID);
12059 ast_string_field_set(user, cid_name, "");
12060 ast_string_field_set(user, cid_num, "");
12061 ast_string_field_set(user, accountcode, accountcode);
12062 ast_string_field_set(user, mohinterpret, mohinterpret);
12063 ast_string_field_set(user, mohsuggest, mohsuggest);
12064 }
12065 if (!v) {
12066 v = alt;
12067 alt = NULL;
12068 }
12069 while(v) {
12070 if (!strcasecmp(v->name, "context")) {
12071 con = build_context(v->value);
12072 if (con) {
12073 if (conl)
12074 conl->next = con;
12075 else
12076 user->contexts = con;
12077 conl = con;
12078 }
12079 } else if (!strcasecmp(v->name, "permit") ||
12080 !strcasecmp(v->name, "deny")) {
12081 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12082 } else if (!strcasecmp(v->name, "setvar")) {
12083 varname = ast_strdupa(v->value);
12084 if (varname && (varval = strchr(varname,'='))) {
12085 *varval = '\0';
12086 varval++;
12087 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12088 tmpvar->next = user->vars;
12089 user->vars = tmpvar;
12090 }
12091 }
12092 } else if (!strcasecmp(v->name, "allow")) {
12093 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12094 } else if (!strcasecmp(v->name, "disallow")) {
12095 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12096 } else if (!strcasecmp(v->name, "trunk")) {
12097 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
12098 if (ast_test_flag(user, IAX_TRUNK) && !timer) {
12099 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12100 ast_clear_flag(user, IAX_TRUNK);
12101 }
12102 } else if (!strcasecmp(v->name, "auth")) {
12103 user->authmethods = get_auth_methods(v->value);
12104 } else if (!strcasecmp(v->name, "encryption")) {
12105 user->encmethods |= get_encrypt_methods(v->value);
12106 } else if (!strcasecmp(v->name, "transfer")) {
12107 if (!strcasecmp(v->value, "mediaonly")) {
12108 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12109 } else if (ast_true(v->value)) {
12110 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12111 } else
12112 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12113 } else if (!strcasecmp(v->name, "codecpriority")) {
12114 if(!strcasecmp(v->value, "caller"))
12115 ast_set_flag(user, IAX_CODEC_USER_FIRST);
12116 else if(!strcasecmp(v->value, "disabled"))
12117 ast_set_flag(user, IAX_CODEC_NOPREFS);
12118 else if(!strcasecmp(v->value, "reqonly")) {
12119 ast_set_flag(user, IAX_CODEC_NOCAP);
12120 ast_set_flag(user, IAX_CODEC_NOPREFS);
12121 }
12122 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12123 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
12124 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12125 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12126 } else if (!strcasecmp(v->name, "dbsecret")) {
12127 ast_string_field_set(user, dbsecret, v->value);
12128 } else if (!strcasecmp(v->name, "secret")) {
12129 if (!ast_strlen_zero(user->secret)) {
12130 char *old = ast_strdupa(user->secret);
12131
12132 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12133 } else
12134 ast_string_field_set(user, secret, v->value);
12135 } else if (!strcasecmp(v->name, "callerid")) {
12136 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12137 char name2[80];
12138 char num2[80];
12139 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12140 ast_string_field_set(user, cid_name, name2);
12141 ast_string_field_set(user, cid_num, num2);
12142 ast_set_flag(user, IAX_HASCALLERID);
12143 } else {
12144 ast_clear_flag(user, IAX_HASCALLERID);
12145 ast_string_field_set(user, cid_name, "");
12146 ast_string_field_set(user, cid_num, "");
12147 }
12148 } else if (!strcasecmp(v->name, "fullname")) {
12149 if (!ast_strlen_zero(v->value)) {
12150 ast_string_field_set(user, cid_name, v->value);
12151 ast_set_flag(user, IAX_HASCALLERID);
12152 } else {
12153 ast_string_field_set(user, cid_name, "");
12154 if (ast_strlen_zero(user->cid_num))
12155 ast_clear_flag(user, IAX_HASCALLERID);
12156 }
12157 } else if (!strcasecmp(v->name, "cid_number")) {
12158 if (!ast_strlen_zero(v->value)) {
12159 ast_string_field_set(user, cid_num, v->value);
12160 ast_set_flag(user, IAX_HASCALLERID);
12161 } else {
12162 ast_string_field_set(user, cid_num, "");
12163 if (ast_strlen_zero(user->cid_name))
12164 ast_clear_flag(user, IAX_HASCALLERID);
12165 }
12166 } else if (!strcasecmp(v->name, "accountcode")) {
12167 ast_string_field_set(user, accountcode, v->value);
12168 } else if (!strcasecmp(v->name, "mohinterpret")) {
12169 ast_string_field_set(user, mohinterpret, v->value);
12170 } else if (!strcasecmp(v->name, "mohsuggest")) {
12171 ast_string_field_set(user, mohsuggest, v->value);
12172 } else if (!strcasecmp(v->name, "parkinglot")) {
12173 ast_string_field_set(user, parkinglot, v->value);
12174 } else if (!strcasecmp(v->name, "language")) {
12175 ast_string_field_set(user, language, v->value);
12176 } else if (!strcasecmp(v->name, "amaflags")) {
12177 format = ast_cdr_amaflags2int(v->value);
12178 if (format < 0) {
12179 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12180 } else {
12181 user->amaflags = format;
12182 }
12183 } else if (!strcasecmp(v->name, "inkeys")) {
12184 ast_string_field_set(user, inkeys, v->value);
12185 } else if (!strcasecmp(v->name, "maxauthreq")) {
12186 user->maxauthreq = atoi(v->value);
12187 if (user->maxauthreq < 0)
12188 user->maxauthreq = 0;
12189 } else if (!strcasecmp(v->name, "adsi")) {
12190 user->adsi = ast_true(v->value);
12191 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12192
12193 if (ast_false(v->value)) {
12194 user->calltoken_required = CALLTOKEN_NO;
12195 } else if (!strcasecmp(v->value, "auto")) {
12196 user->calltoken_required = CALLTOKEN_AUTO;
12197 } else if (ast_true(v->value)) {
12198 user->calltoken_required = CALLTOKEN_YES;
12199 } else {
12200 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12201 }
12202 }
12203
12204 v = v->next;
12205 if (!v) {
12206 v = alt;
12207 alt = NULL;
12208 }
12209 }
12210 if (!user->authmethods) {
12211 if (!ast_strlen_zero(user->secret)) {
12212 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12213 if (!ast_strlen_zero(user->inkeys))
12214 user->authmethods |= IAX_AUTH_RSA;
12215 } else if (!ast_strlen_zero(user->inkeys)) {
12216 user->authmethods = IAX_AUTH_RSA;
12217 } else {
12218 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12219 }
12220 }
12221 ast_clear_flag(user, IAX_DELME);
12222 }
12223 cleanup:
12224 if (oldha)
12225 ast_free_ha(oldha);
12226 if (oldcon)
12227 free_context(oldcon);
12228 return user;
12229 }
12230
12231 static int peer_delme_cb(void *obj, void *arg, int flags)
12232 {
12233 struct iax2_peer *peer = obj;
12234
12235 ast_set_flag(peer, IAX_DELME);
12236
12237 return 0;
12238 }
12239
12240 static int user_delme_cb(void *obj, void *arg, int flags)
12241 {
12242 struct iax2_user *user = obj;
12243
12244 ast_set_flag(user, IAX_DELME);
12245
12246 return 0;
12247 }
12248
12249 static void delete_users(void)
12250 {
12251 struct iax2_registry *reg;
12252
12253 ao2_callback(users, 0, user_delme_cb, NULL);
12254
12255 AST_LIST_LOCK(®istrations);
12256 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12257 AST_SCHED_DEL(sched, reg->expire);
12258 if (reg->callno) {
12259 int callno = reg->callno;
12260 ast_mutex_lock(&iaxsl[callno]);
12261 if (iaxs[callno]) {
12262 iaxs[callno]->reg = NULL;
12263 iax2_destroy(callno);
12264 }
12265 ast_mutex_unlock(&iaxsl[callno]);
12266 }
12267 if (reg->dnsmgr)
12268 ast_dnsmgr_release(reg->dnsmgr);
12269 ast_free(reg);
12270 }
12271 AST_LIST_UNLOCK(®istrations);
12272
12273 ao2_callback(peers, 0, peer_delme_cb, NULL);
12274 }
12275
12276 static void prune_users(void)
12277 {
12278 struct iax2_user *user;
12279 struct ao2_iterator i;
12280
12281 i = ao2_iterator_init(users, 0);
12282 while ((user = ao2_iterator_next(&i))) {
12283 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
12284 ao2_unlink(users, user);
12285 }
12286 user_unref(user);
12287 }
12288 ao2_iterator_destroy(&i);
12289 }
12290
12291
12292 static void prune_peers(void)
12293 {
12294 struct iax2_peer *peer;
12295 struct ao2_iterator i;
12296
12297 i = ao2_iterator_init(peers, 0);
12298 while ((peer = ao2_iterator_next(&i))) {
12299 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
12300 unlink_peer(peer);
12301 }
12302 peer_unref(peer);
12303 }
12304 ao2_iterator_destroy(&i);
12305 }
12306
12307 static void set_config_destroy(void)
12308 {
12309 strcpy(accountcode, "");
12310 strcpy(language, "");
12311 strcpy(mohinterpret, "default");
12312 strcpy(mohsuggest, "");
12313 trunkmaxsize = MAX_TRUNKDATA;
12314 amaflags = 0;
12315 delayreject = 0;
12316 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
12317 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
12318 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
12319 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
12320 delete_users();
12321 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12322 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12323 }
12324
12325
12326 static int set_config(const char *config_file, int reload)
12327 {
12328 struct ast_config *cfg, *ucfg;
12329 int capability=iax2_capability;
12330 struct ast_variable *v;
12331 char *cat;
12332 const char *utype;
12333 const char *tosval;
12334 int format;
12335 int portno = IAX_DEFAULT_PORTNO;
12336 int x;
12337 int mtuv;
12338 struct iax2_user *user;
12339 struct iax2_peer *peer;
12340 struct ast_netsock *ns;
12341 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12342 #if 0
12343 static unsigned short int last_port=0;
12344 #endif
12345
12346 cfg = ast_config_load(config_file, config_flags);
12347
12348 if (!cfg) {
12349 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12350 return -1;
12351 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12352 ucfg = ast_config_load("users.conf", config_flags);
12353 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12354 return 0;
12355
12356 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12357 cfg = ast_config_load(config_file, config_flags);
12358 } else {
12359 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12360 ucfg = ast_config_load("users.conf", config_flags);
12361 }
12362
12363 if (reload) {
12364 set_config_destroy();
12365 }
12366
12367
12368 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12369
12370
12371 memset(&globalflags, 0, sizeof(globalflags));
12372 ast_set_flag(&globalflags, IAX_RTUPDATE);
12373 ast_set_flag(&globalflags, IAX_SHRINKCALLERID);
12374
12375
12376 iax2_encryption |= IAX_ENCRYPT_KEYROTATE;
12377 #ifdef SO_NO_CHECK
12378 nochecksums = 0;
12379 #endif
12380
12381 default_parkinglot[0] = '\0';
12382
12383 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12384 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12385 global_max_trunk_mtu = MAX_TRUNK_MTU;
12386 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12387 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12388
12389 maxauthreq = 3;
12390
12391 srvlookup = 0;
12392
12393 v = ast_variable_browse(cfg, "general");
12394
12395
12396 tosval = ast_variable_retrieve(cfg, "general", "tos");
12397 if (tosval) {
12398 if (ast_str2tos(tosval, &qos.tos))
12399 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
12400 }
12401
12402 tosval = ast_variable_retrieve(cfg, "general", "cos");
12403 if (tosval) {
12404 if (ast_str2cos(tosval, &qos.cos))
12405 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
12406 }
12407 while(v) {
12408 if (!strcasecmp(v->name, "bindport")){
12409 if (reload)
12410 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
12411 else
12412 portno = atoi(v->value);
12413 } else if (!strcasecmp(v->name, "pingtime"))
12414 ping_time = atoi(v->value);
12415 else if (!strcasecmp(v->name, "iaxthreadcount")) {
12416 if (reload) {
12417 if (atoi(v->value) != iaxthreadcount)
12418 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
12419 } else {
12420 iaxthreadcount = atoi(v->value);
12421 if (iaxthreadcount < 1) {
12422 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
12423 iaxthreadcount = 1;
12424 } else if (iaxthreadcount > 256) {
12425 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
12426 iaxthreadcount = 256;
12427 }
12428 }
12429 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
12430 if (reload) {
12431 AST_LIST_LOCK(&dynamic_list);
12432 iaxmaxthreadcount = atoi(v->value);
12433 AST_LIST_UNLOCK(&dynamic_list);
12434 } else {
12435 iaxmaxthreadcount = atoi(v->value);
12436 if (iaxmaxthreadcount < 0) {
12437 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
12438 iaxmaxthreadcount = 0;
12439 } else if (iaxmaxthreadcount > 256) {
12440 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
12441 iaxmaxthreadcount = 256;
12442 }
12443 }
12444 } else if (!strcasecmp(v->name, "nochecksums")) {
12445 #ifdef SO_NO_CHECK
12446 if (ast_true(v->value))
12447 nochecksums = 1;
12448 else
12449 nochecksums = 0;
12450 #else
12451 if (ast_true(v->value))
12452 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
12453 #endif
12454 }
12455 else if (!strcasecmp(v->name, "maxjitterbuffer"))
12456 maxjitterbuffer = atoi(v->value);
12457 else if (!strcasecmp(v->name, "resyncthreshold"))
12458 resyncthreshold = atoi(v->value);
12459 else if (!strcasecmp(v->name, "maxjitterinterps"))
12460 maxjitterinterps = atoi(v->value);
12461 else if (!strcasecmp(v->name, "jittertargetextra"))
12462 jittertargetextra = atoi(v->value);
12463 else if (!strcasecmp(v->name, "lagrqtime"))
12464 lagrq_time = atoi(v->value);
12465 else if (!strcasecmp(v->name, "maxregexpire"))
12466 max_reg_expire = atoi(v->value);
12467 else if (!strcasecmp(v->name, "minregexpire"))
12468 min_reg_expire = atoi(v->value);
12469 else if (!strcasecmp(v->name, "bindaddr")) {
12470 if (reload) {
12471 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
12472 } else {
12473 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
12474 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
12475 } else {
12476 if (strchr(v->value, ':'))
12477 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
12478 else
12479 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
12480 if (defaultsockfd < 0)
12481 defaultsockfd = ast_netsock_sockfd(ns);
12482 ast_netsock_unref(ns);
12483 }
12484 }
12485 } else if (!strcasecmp(v->name, "authdebug"))
12486 authdebug = ast_true(v->value);
12487 else if (!strcasecmp(v->name, "encryption"))
12488 iax2_encryption |= get_encrypt_methods(v->value);
12489 else if (!strcasecmp(v->name, "transfer")) {
12490 if (!strcasecmp(v->value, "mediaonly")) {
12491 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12492 } else if (ast_true(v->value)) {
12493 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12494 } else
12495 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12496 } else if (!strcasecmp(v->name, "codecpriority")) {
12497 if(!strcasecmp(v->value, "caller"))
12498 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
12499 else if(!strcasecmp(v->value, "disabled"))
12500 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12501 else if(!strcasecmp(v->value, "reqonly")) {
12502 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
12503 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12504 }
12505 } else if (!strcasecmp(v->name, "jitterbuffer"))
12506 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
12507 else if (!strcasecmp(v->name, "forcejitterbuffer"))
12508 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
12509 else if (!strcasecmp(v->name, "delayreject"))
12510 delayreject = ast_true(v->value);
12511 else if (!strcasecmp(v->name, "allowfwdownload"))
12512 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
12513 else if (!strcasecmp(v->name, "rtcachefriends"))
12514 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
12515 else if (!strcasecmp(v->name, "rtignoreregexpire"))
12516 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
12517 else if (!strcasecmp(v->name, "rtupdate"))
12518 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
12519 else if (!strcasecmp(v->name, "trunktimestamps"))
12520 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
12521 else if (!strcasecmp(v->name, "rtautoclear")) {
12522 int i = atoi(v->value);
12523 if(i > 0)
12524 global_rtautoclear = i;
12525 else
12526 i = 0;
12527 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
12528 } else if (!strcasecmp(v->name, "trunkfreq")) {
12529 trunkfreq = atoi(v->value);
12530 if (trunkfreq < 10)
12531 trunkfreq = 10;
12532 } else if (!strcasecmp(v->name, "trunkmtu")) {
12533 mtuv = atoi(v->value);
12534 if (mtuv == 0 )
12535 global_max_trunk_mtu = 0;
12536 else if (mtuv >= 172 && mtuv < 4000)
12537 global_max_trunk_mtu = mtuv;
12538 else
12539 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
12540 mtuv, v->lineno);
12541 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
12542 trunkmaxsize = atoi(v->value);
12543 if (trunkmaxsize == 0)
12544 trunkmaxsize = MAX_TRUNKDATA;
12545 } else if (!strcasecmp(v->name, "autokill")) {
12546 if (sscanf(v->value, "%30d", &x) == 1) {
12547 if (x >= 0)
12548 autokill = x;
12549 else
12550 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
12551 } else if (ast_true(v->value)) {
12552 autokill = DEFAULT_MAXMS;
12553 } else {
12554 autokill = 0;
12555 }
12556 } else if (!strcasecmp(v->name, "bandwidth")) {
12557 if (!strcasecmp(v->value, "low")) {
12558 capability = IAX_CAPABILITY_LOWBANDWIDTH;
12559 } else if (!strcasecmp(v->value, "medium")) {
12560 capability = IAX_CAPABILITY_MEDBANDWIDTH;
12561 } else if (!strcasecmp(v->value, "high")) {
12562 capability = IAX_CAPABILITY_FULLBANDWIDTH;
12563 } else
12564 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
12565 } else if (!strcasecmp(v->name, "allow")) {
12566 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
12567 } else if (!strcasecmp(v->name, "disallow")) {
12568 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
12569 } else if (!strcasecmp(v->name, "register")) {
12570 iax2_register(v->value, v->lineno);
12571 } else if (!strcasecmp(v->name, "iaxcompat")) {
12572 iaxcompat = ast_true(v->value);
12573 } else if (!strcasecmp(v->name, "regcontext")) {
12574 ast_copy_string(regcontext, v->value, sizeof(regcontext));
12575
12576 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
12577 } else if (!strcasecmp(v->name, "tos")) {
12578 if (ast_str2tos(v->value, &qos.tos))
12579 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
12580 } else if (!strcasecmp(v->name, "cos")) {
12581 if (ast_str2cos(v->value, &qos.cos))
12582 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
12583 } else if (!strcasecmp(v->name, "parkinglot")) {
12584 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
12585 } else if (!strcasecmp(v->name, "accountcode")) {
12586 ast_copy_string(accountcode, v->value, sizeof(accountcode));
12587 } else if (!strcasecmp(v->name, "mohinterpret")) {
12588 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
12589 } else if (!strcasecmp(v->name, "mohsuggest")) {
12590 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
12591 } else if (!strcasecmp(v->name, "amaflags")) {
12592 format = ast_cdr_amaflags2int(v->value);
12593 if (format < 0) {
12594 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12595 } else {
12596 amaflags = format;
12597 }
12598 } else if (!strcasecmp(v->name, "language")) {
12599 ast_copy_string(language, v->value, sizeof(language));
12600 } else if (!strcasecmp(v->name, "maxauthreq")) {
12601 maxauthreq = atoi(v->value);
12602 if (maxauthreq < 0)
12603 maxauthreq = 0;
12604 } else if (!strcasecmp(v->name, "adsi")) {
12605 adsi = ast_true(v->value);
12606 } else if (!strcasecmp(v->name, "srvlookup")) {
12607 srvlookup = ast_true(v->value);
12608 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12609 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
12610 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
12611 }
12612 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
12613 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
12614 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);
12615 }
12616 } else if (!strcasecmp(v->name, "calltokenoptional")) {
12617 if (add_calltoken_ignore(v->value)) {
12618 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
12619 }
12620 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
12621 if (ast_true(v->value)) {
12622 ast_set_flag((&globalflags), IAX_SHRINKCALLERID);
12623 } else if (ast_false(v->value)) {
12624 ast_clear_flag((&globalflags), IAX_SHRINKCALLERID);
12625 } else {
12626 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
12627 }
12628 }
12629
12630 v = v->next;
12631 }
12632
12633 if (defaultsockfd < 0) {
12634 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
12635 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
12636 } else {
12637 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
12638 defaultsockfd = ast_netsock_sockfd(ns);
12639 ast_netsock_unref(ns);
12640 }
12641 }
12642 if (reload) {
12643 ast_netsock_release(outsock);
12644 outsock = ast_netsock_list_alloc();
12645 if (!outsock) {
12646 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12647 return -1;
12648 }
12649 ast_netsock_init(outsock);
12650 }
12651
12652 if (min_reg_expire > max_reg_expire) {
12653 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
12654 min_reg_expire, max_reg_expire, max_reg_expire);
12655 min_reg_expire = max_reg_expire;
12656 }
12657 iax2_capability = capability;
12658
12659 if (ucfg) {
12660 struct ast_variable *gen;
12661 int genhasiax;
12662 int genregisteriax;
12663 const char *hasiax, *registeriax;
12664
12665 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
12666 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
12667 gen = ast_variable_browse(ucfg, "general");
12668 cat = ast_category_browse(ucfg, NULL);
12669 while (cat) {
12670 if (strcasecmp(cat, "general")) {
12671 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
12672 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
12673 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
12674
12675 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
12676 if (user) {
12677 ao2_link(users, user);
12678 user = user_unref(user);
12679 }
12680 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
12681 if (peer) {
12682 if (ast_test_flag(peer, IAX_DYNAMIC))
12683 reg_source_db(peer);
12684 ao2_link(peers, peer);
12685 peer = peer_unref(peer);
12686 }
12687 }
12688 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
12689 char tmp[256];
12690 const char *host = ast_variable_retrieve(ucfg, cat, "host");
12691 const char *username = ast_variable_retrieve(ucfg, cat, "username");
12692 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
12693 if (!host)
12694 host = ast_variable_retrieve(ucfg, "general", "host");
12695 if (!username)
12696 username = ast_variable_retrieve(ucfg, "general", "username");
12697 if (!secret)
12698 secret = ast_variable_retrieve(ucfg, "general", "secret");
12699 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
12700 if (!ast_strlen_zero(secret))
12701 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
12702 else
12703 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
12704 iax2_register(tmp, 0);
12705 }
12706 }
12707 }
12708 cat = ast_category_browse(ucfg, cat);
12709 }
12710 ast_config_destroy(ucfg);
12711 }
12712
12713 cat = ast_category_browse(cfg, NULL);
12714 while(cat) {
12715 if (strcasecmp(cat, "general")) {
12716 utype = ast_variable_retrieve(cfg, cat, "type");
12717 if (!strcasecmp(cat, "callnumberlimits")) {
12718 build_callno_limits(ast_variable_browse(cfg, cat));
12719 } else if (utype) {
12720 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
12721 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
12722 if (user) {
12723 ao2_link(users, user);
12724 user = user_unref(user);
12725 }
12726 }
12727 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
12728 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
12729 if (peer) {
12730 if (ast_test_flag(peer, IAX_DYNAMIC))
12731 reg_source_db(peer);
12732 ao2_link(peers, peer);
12733 peer = peer_unref(peer);
12734 }
12735 } else if (strcasecmp(utype, "user")) {
12736 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
12737 }
12738 } else
12739 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
12740 }
12741 cat = ast_category_browse(cfg, cat);
12742 }
12743 ast_config_destroy(cfg);
12744 return 1;
12745 }
12746
12747 static void poke_all_peers(void)
12748 {
12749 struct ao2_iterator i;
12750 struct iax2_peer *peer;
12751
12752 i = ao2_iterator_init(peers, 0);
12753 while ((peer = ao2_iterator_next(&i))) {
12754 iax2_poke_peer(peer, 0);
12755 peer_unref(peer);
12756 }
12757 ao2_iterator_destroy(&i);
12758 }
12759 static int reload_config(void)
12760 {
12761 static const char config[] = "iax.conf";
12762 struct iax2_registry *reg;
12763
12764 if (set_config(config, 1) > 0) {
12765 prune_peers();
12766 prune_users();
12767 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
12768 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
12769 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
12770 trunk_timed = trunk_untimed = 0;
12771 trunk_nmaxmtu = trunk_maxmtu = 0;
12772 memset(&debugaddr, '\0', sizeof(debugaddr));
12773
12774 AST_LIST_LOCK(®istrations);
12775 AST_LIST_TRAVERSE(®istrations, reg, entry)
12776 iax2_do_register(reg);
12777 AST_LIST_UNLOCK(®istrations);
12778
12779
12780 poke_all_peers();
12781 }
12782
12783 reload_firmware(0);
12784 iax_provision_reload(1);
12785 ast_unload_realtime("iaxpeers");
12786
12787 return 0;
12788 }
12789
12790 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
12791 {
12792 switch (cmd) {
12793 case CLI_INIT:
12794 e->command = "iax2 reload";
12795 e->usage =
12796 "Usage: iax2 reload\n"
12797 " Reloads IAX configuration from iax.conf\n";
12798 return NULL;
12799 case CLI_GENERATE:
12800 return NULL;
12801 }
12802
12803 reload_config();
12804
12805 return CLI_SUCCESS;
12806 }
12807
12808 static int reload(void)
12809 {
12810 return reload_config();
12811 }
12812
12813 static int cache_get_callno_locked(const char *data)
12814 {
12815 struct sockaddr_in sin;
12816 int x;
12817 int callno;
12818 struct iax_ie_data ied;
12819 struct create_addr_info cai;
12820 struct parsed_dial_string pds;
12821 char *tmpstr;
12822
12823 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12824
12825
12826 if (!ast_mutex_trylock(&iaxsl[x])) {
12827 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
12828 return x;
12829 ast_mutex_unlock(&iaxsl[x]);
12830 }
12831 }
12832
12833
12834
12835 memset(&cai, 0, sizeof(cai));
12836 memset(&ied, 0, sizeof(ied));
12837 memset(&pds, 0, sizeof(pds));
12838
12839 tmpstr = ast_strdupa(data);
12840 parse_dial_string(tmpstr, &pds);
12841
12842 if (ast_strlen_zero(pds.peer)) {
12843 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
12844 return -1;
12845 }
12846
12847
12848 if (create_addr(pds.peer, NULL, &sin, &cai))
12849 return -1;
12850
12851 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
12852 pds.peer, pds.username, pds.password, pds.context);
12853
12854 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12855 if (callno < 1) {
12856 ast_log(LOG_WARNING, "Unable to create call\n");
12857 return -1;
12858 }
12859
12860 ast_string_field_set(iaxs[callno], dproot, data);
12861 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
12862
12863 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
12864 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
12865
12866
12867
12868 if (pds.exten)
12869 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
12870 if (pds.username)
12871 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
12872 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
12873 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
12874
12875 if (pds.password)
12876 ast_string_field_set(iaxs[callno], secret, pds.password);
12877 if (pds.key)
12878 ast_string_field_set(iaxs[callno], outkey, pds.key);
12879
12880 add_empty_calltoken_ie(iaxs[callno], &ied);
12881 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
12882
12883 return callno;
12884 }
12885
12886 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
12887 {
12888 struct iax2_dpcache *dp = NULL;
12889 struct timeval now = ast_tvnow();
12890 int x, com[2], timeout, old = 0, outfd, doabort, callno;
12891 struct ast_channel *c = NULL;
12892 struct ast_frame *f = NULL;
12893
12894 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
12895 if (ast_tvcmp(now, dp->expiry) > 0) {
12896 AST_LIST_REMOVE_CURRENT(cache_list);
12897 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
12898 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
12899 else
12900 ast_free(dp);
12901 continue;
12902 }
12903 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
12904 break;
12905 }
12906 AST_LIST_TRAVERSE_SAFE_END;
12907
12908 if (!dp) {
12909
12910
12911 if ((callno = cache_get_callno_locked(data)) < 0) {
12912 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
12913 return NULL;
12914 }
12915 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
12916 ast_mutex_unlock(&iaxsl[callno]);
12917 return NULL;
12918 }
12919 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
12920 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
12921 dp->expiry = ast_tvnow();
12922 dp->orig = dp->expiry;
12923
12924 dp->expiry.tv_sec += iaxdefaultdpcache;
12925 dp->flags = CACHE_FLAG_PENDING;
12926 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
12927 dp->waiters[x] = -1;
12928
12929 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
12930 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
12931
12932 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
12933 iax2_dprequest(dp, callno);
12934 ast_mutex_unlock(&iaxsl[callno]);
12935 }
12936
12937
12938 if (dp->flags & CACHE_FLAG_PENDING) {
12939
12940
12941 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
12942
12943 if (dp->waiters[x] < 0)
12944 break;
12945 }
12946 if (x >= ARRAY_LEN(dp->waiters)) {
12947 ast_log(LOG_WARNING, "No more waiter positions available\n");
12948 return NULL;
12949 }
12950 if (pipe(com)) {
12951 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
12952 return NULL;
12953 }
12954 dp->waiters[x] = com[1];
12955
12956 timeout = iaxdefaulttimeout * 1000;
12957
12958 AST_LIST_UNLOCK(&dpcache);
12959
12960 if (chan)
12961 old = ast_channel_defer_dtmf(chan);
12962 doabort = 0;
12963 while(timeout) {
12964 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
12965 if (outfd > -1)
12966 break;
12967 if (!c)
12968 continue;
12969 if (!(f = ast_read(c))) {
12970 doabort = 1;
12971 break;
12972 }
12973 ast_frfree(f);
12974 }
12975 if (!timeout) {
12976 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
12977 }
12978 AST_LIST_LOCK(&dpcache);
12979 dp->waiters[x] = -1;
12980 close(com[1]);
12981 close(com[0]);
12982 if (doabort) {
12983
12984
12985 if (!old && chan)
12986 ast_channel_undefer_dtmf(chan);
12987 return NULL;
12988 }
12989 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
12990
12991 if (dp->flags & CACHE_FLAG_PENDING) {
12992
12993
12994 dp->flags &= ~CACHE_FLAG_PENDING;
12995 dp->flags |= CACHE_FLAG_TIMEOUT;
12996
12997
12998 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
12999 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13000 if (dp->waiters[x] > -1) {
13001 if (write(dp->waiters[x], "asdf", 4) < 0) {
13002 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13003 }
13004 }
13005 }
13006 }
13007 }
13008
13009 if (!old && chan)
13010 ast_channel_undefer_dtmf(chan);
13011 }
13012 return dp;
13013 }
13014
13015
13016 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13017 {
13018 int res = 0;
13019 struct iax2_dpcache *dp = NULL;
13020 #if 0
13021 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13022 #endif
13023 if ((priority != 1) && (priority != 2))
13024 return 0;
13025
13026 AST_LIST_LOCK(&dpcache);
13027 if ((dp = find_cache(chan, data, context, exten, priority))) {
13028 if (dp->flags & CACHE_FLAG_EXISTS)
13029 res = 1;
13030 } else {
13031 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13032 }
13033 AST_LIST_UNLOCK(&dpcache);
13034
13035 return res;
13036 }
13037
13038
13039 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13040 {
13041 int res = 0;
13042 struct iax2_dpcache *dp = NULL;
13043 #if 0
13044 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13045 #endif
13046 if ((priority != 1) && (priority != 2))
13047 return 0;
13048
13049 AST_LIST_LOCK(&dpcache);
13050 if ((dp = find_cache(chan, data, context, exten, priority))) {
13051 if (dp->flags & CACHE_FLAG_CANEXIST)
13052 res = 1;
13053 } else {
13054 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13055 }
13056 AST_LIST_UNLOCK(&dpcache);
13057
13058 return res;
13059 }
13060
13061
13062 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13063 {
13064 int res = 0;
13065 struct iax2_dpcache *dp = NULL;
13066 #if 0
13067 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13068 #endif
13069 if ((priority != 1) && (priority != 2))
13070 return 0;
13071
13072 AST_LIST_LOCK(&dpcache);
13073 if ((dp = find_cache(chan, data, context, exten, priority))) {
13074 if (dp->flags & CACHE_FLAG_MATCHMORE)
13075 res = 1;
13076 } else {
13077 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13078 }
13079 AST_LIST_UNLOCK(&dpcache);
13080
13081 return res;
13082 }
13083
13084
13085 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13086 {
13087 char odata[256];
13088 char req[256];
13089 char *ncontext;
13090 struct iax2_dpcache *dp = NULL;
13091 struct ast_app *dial = NULL;
13092 #if 0
13093 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);
13094 #endif
13095 if (priority == 2) {
13096
13097 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13098 if (dialstatus) {
13099 dial = pbx_findapp(dialstatus);
13100 if (dial)
13101 pbx_exec(chan, dial, "");
13102 }
13103 return -1;
13104 } else if (priority != 1)
13105 return -1;
13106
13107 AST_LIST_LOCK(&dpcache);
13108 if ((dp = find_cache(chan, data, context, exten, priority))) {
13109 if (dp->flags & CACHE_FLAG_EXISTS) {
13110 ast_copy_string(odata, data, sizeof(odata));
13111 ncontext = strchr(odata, '/');
13112 if (ncontext) {
13113 *ncontext = '\0';
13114 ncontext++;
13115 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13116 } else {
13117 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13118 }
13119 ast_verb(3, "Executing Dial('%s')\n", req);
13120 } else {
13121 AST_LIST_UNLOCK(&dpcache);
13122 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13123 return -1;
13124 }
13125 }
13126 AST_LIST_UNLOCK(&dpcache);
13127
13128 if ((dial = pbx_findapp("Dial")))
13129 return pbx_exec(chan, dial, req);
13130 else
13131 ast_log(LOG_WARNING, "No dial application registered\n");
13132
13133 return -1;
13134 }
13135
13136 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13137 {
13138 struct iax2_peer *peer;
13139 char *peername, *colname;
13140
13141 peername = ast_strdupa(data);
13142
13143
13144 if (!strcmp(peername,"CURRENTCHANNEL")) {
13145 unsigned short callno;
13146 if (chan->tech != &iax2_tech)
13147 return -1;
13148 callno = PTR_TO_CALLNO(chan->tech_pvt);
13149 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13150 return 0;
13151 }
13152
13153 if ((colname = strchr(peername, ',')))
13154 *colname++ = '\0';
13155 else
13156 colname = "ip";
13157
13158 if (!(peer = find_peer(peername, 1)))
13159 return -1;
13160
13161 if (!strcasecmp(colname, "ip")) {
13162 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
13163 } else if (!strcasecmp(colname, "status")) {
13164 peer_status(peer, buf, len);
13165 } else if (!strcasecmp(colname, "mailbox")) {
13166 ast_copy_string(buf, peer->mailbox, len);
13167 } else if (!strcasecmp(colname, "context")) {
13168 ast_copy_string(buf, peer->context, len);
13169 } else if (!strcasecmp(colname, "expire")) {
13170 snprintf(buf, len, "%d", peer->expire);
13171 } else if (!strcasecmp(colname, "dynamic")) {
13172 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13173 } else if (!strcasecmp(colname, "callerid_name")) {
13174 ast_copy_string(buf, peer->cid_name, len);
13175 } else if (!strcasecmp(colname, "callerid_num")) {
13176 ast_copy_string(buf, peer->cid_num, len);
13177 } else if (!strcasecmp(colname, "codecs")) {
13178 ast_getformatname_multiple(buf, len -1, peer->capability);
13179 } else if (!strncasecmp(colname, "codec[", 6)) {
13180 char *codecnum, *ptr;
13181 int codec = 0;
13182
13183 codecnum = strchr(colname, '[');
13184 *codecnum = '\0';
13185 codecnum++;
13186 if ((ptr = strchr(codecnum, ']'))) {
13187 *ptr = '\0';
13188 }
13189 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13190 ast_copy_string(buf, ast_getformatname(codec), len);
13191 } else {
13192 buf[0] = '\0';
13193 }
13194 } else {
13195 buf[0] = '\0';
13196 }
13197
13198 peer_unref(peer);
13199
13200 return 0;
13201 }
13202
13203 struct ast_custom_function iaxpeer_function = {
13204 .name = "IAXPEER",
13205 .synopsis = "Gets IAX peer information",
13206 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[,item])",
13207 .read = function_iaxpeer,
13208 .desc = "If peername specified, valid items are:\n"
13209 "- ip (default) The IP address.\n"
13210 "- status The peer's status (if qualify=yes)\n"
13211 "- mailbox The configured mailbox.\n"
13212 "- context The configured context.\n"
13213 "- expire The epoch time of the next expire.\n"
13214 "- dynamic Is it dynamic? (yes/no).\n"
13215 "- callerid_name The configured Caller ID name.\n"
13216 "- callerid_num The configured Caller ID number.\n"
13217 "- codecs The configured codecs.\n"
13218 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
13219 "\n"
13220 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
13221 "\n"
13222 };
13223
13224 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13225 {
13226 struct chan_iax2_pvt *pvt;
13227 unsigned int callno;
13228 int res = 0;
13229
13230 if (!chan || chan->tech != &iax2_tech) {
13231 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13232 return -1;
13233 }
13234
13235 callno = PTR_TO_CALLNO(chan->tech_pvt);
13236 ast_mutex_lock(&iaxsl[callno]);
13237 if (!(pvt = iaxs[callno])) {
13238 ast_mutex_unlock(&iaxsl[callno]);
13239 return -1;
13240 }
13241
13242 if (!strcasecmp(args, "osptoken")) {
13243 ast_copy_string(buf, pvt->osptoken, buflen);
13244 } else if (!strcasecmp(args, "peerip")) {
13245 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13246 } else if (!strcasecmp(args, "peername")) {
13247 ast_copy_string(buf, pvt->username, buflen);
13248 } else {
13249 res = -1;
13250 }
13251
13252 ast_mutex_unlock(&iaxsl[callno]);
13253
13254 return res;
13255 }
13256
13257
13258 static int iax2_devicestate(void *data)
13259 {
13260 struct parsed_dial_string pds;
13261 char *tmp = ast_strdupa(data);
13262 struct iax2_peer *p;
13263 int res = AST_DEVICE_INVALID;
13264
13265 memset(&pds, 0, sizeof(pds));
13266 parse_dial_string(tmp, &pds);
13267
13268 if (ast_strlen_zero(pds.peer)) {
13269 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13270 return res;
13271 }
13272
13273 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13274
13275
13276 if (!(p = find_peer(pds.peer, 1)))
13277 return res;
13278
13279 res = AST_DEVICE_UNAVAILABLE;
13280 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13281 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13282
13283 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
13284 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13285
13286
13287 if (p->historicms == 0 || p->historicms <= p->maxms)
13288
13289 res = AST_DEVICE_UNKNOWN;
13290 }
13291
13292 peer_unref(p);
13293
13294 return res;
13295 }
13296
13297 static struct ast_switch iax2_switch =
13298 {
13299 name: "IAX2",
13300 description: "IAX Remote Dialplan Switch",
13301 exists: iax2_exists,
13302 canmatch: iax2_canmatch,
13303 exec: iax2_exec,
13304 matchmore: iax2_matchmore,
13305 };
13306
13307
13308
13309
13310
13311
13312
13313
13314
13315
13316
13317
13318
13319
13320
13321
13322
13323
13324
13325
13326
13327
13328
13329
13330
13331
13332
13333
13334
13335
13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361
13362
13363
13364
13365
13366
13367
13368
13369
13370
13371
13372
13373
13374
13375
13376
13377
13378
13379
13380
13381
13382
13383
13384
13385
13386
13387
13388
13389
13390
13391
13392
13393
13394
13395
13396
13397
13398
13399
13400
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411 static struct ast_cli_entry cli_iax2[] = {
13412 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
13413 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
13414 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
13415 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
13416 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
13417 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
13418 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
13419 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
13420 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
13421 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
13422 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
13423 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
13424 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
13425 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
13426 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
13427 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
13428 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
13429 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
13430 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
13431 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
13432 #ifdef IAXTESTS
13433 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
13434 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
13435 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
13436 #endif
13437 };
13438
13439 static int __unload_module(void)
13440 {
13441 struct iax2_thread *thread = NULL;
13442 struct ast_context *con;
13443 int x;
13444
13445
13446
13447
13448
13449 if (netthreadid != AST_PTHREADT_NULL) {
13450 AST_LIST_LOCK(&frame_queue);
13451 ast_mutex_lock(&sched_lock);
13452 pthread_cancel(netthreadid);
13453 ast_cond_signal(&sched_cond);
13454 ast_mutex_unlock(&sched_lock);
13455 AST_LIST_UNLOCK(&frame_queue);
13456 pthread_join(netthreadid, NULL);
13457 }
13458 if (schedthreadid != AST_PTHREADT_NULL) {
13459 ast_mutex_lock(&sched_lock);
13460 pthread_cancel(schedthreadid);
13461 ast_cond_signal(&sched_cond);
13462 ast_mutex_unlock(&sched_lock);
13463 pthread_join(schedthreadid, NULL);
13464 }
13465
13466
13467 AST_LIST_LOCK(&idle_list);
13468 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list)))
13469 pthread_cancel(thread->threadid);
13470 AST_LIST_UNLOCK(&idle_list);
13471
13472 AST_LIST_LOCK(&active_list);
13473 while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list)))
13474 pthread_cancel(thread->threadid);
13475 AST_LIST_UNLOCK(&active_list);
13476
13477 AST_LIST_LOCK(&dynamic_list);
13478 while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list)))
13479 pthread_cancel(thread->threadid);
13480 AST_LIST_UNLOCK(&dynamic_list);
13481
13482
13483 while(0 < iaxactivethreadcount)
13484 usleep(10000);
13485
13486 ast_netsock_release(netsock);
13487 ast_netsock_release(outsock);
13488 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13489 if (iaxs[x]) {
13490 iax2_destroy(x);
13491 }
13492 }
13493 ast_manager_unregister( "IAXpeers" );
13494 ast_manager_unregister( "IAXpeerlist" );
13495 ast_manager_unregister( "IAXnetstats" );
13496 ast_unregister_application(papp);
13497 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
13498 ast_unregister_switch(&iax2_switch);
13499 ast_channel_unregister(&iax2_tech);
13500 delete_users();
13501 iax_provision_unload();
13502 sched_context_destroy(sched);
13503 reload_firmware(1);
13504
13505 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13506 ast_mutex_destroy(&iaxsl[x]);
13507 }
13508
13509 ao2_ref(peers, -1);
13510 ao2_ref(users, -1);
13511 ao2_ref(iax_peercallno_pvts, -1);
13512 ao2_ref(iax_transfercallno_pvts, -1);
13513 ao2_ref(peercnts, -1);
13514 ao2_ref(callno_limits, -1);
13515 ao2_ref(calltoken_ignores, -1);
13516 ao2_ref(callno_pool, -1);
13517 ao2_ref(callno_pool_trunk, -1);
13518 if (timer) {
13519 ast_timer_close(timer);
13520 }
13521
13522 con = ast_context_find(regcontext);
13523 if (con)
13524 ast_context_destroy(con, "IAX2");
13525 ast_unload_realtime("iaxpeers");
13526 return 0;
13527 }
13528
13529 static int unload_module(void)
13530 {
13531 ast_custom_function_unregister(&iaxpeer_function);
13532 ast_custom_function_unregister(&iaxvar_function);
13533 return __unload_module();
13534 }
13535
13536 static int peer_set_sock_cb(void *obj, void *arg, int flags)
13537 {
13538 struct iax2_peer *peer = obj;
13539
13540 if (peer->sockfd < 0)
13541 peer->sockfd = defaultsockfd;
13542
13543 return 0;
13544 }
13545
13546 static int pvt_hash_cb(const void *obj, const int flags)
13547 {
13548 const struct chan_iax2_pvt *pvt = obj;
13549
13550 return pvt->peercallno;
13551 }
13552
13553 static int pvt_cmp_cb(void *obj, void *arg, int flags)
13554 {
13555 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13556
13557
13558
13559
13560 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
13561 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13562 }
13563
13564 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
13565 {
13566 const struct chan_iax2_pvt *pvt = obj;
13567
13568 return pvt->transfercallno;
13569 }
13570
13571 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
13572 {
13573 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13574
13575
13576
13577
13578 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
13579 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13580 }
13581
13582 static int load_objects(void)
13583 {
13584 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
13585 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
13586
13587 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
13588 goto container_fail;
13589 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
13590 goto container_fail;
13591 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
13592 goto container_fail;
13593 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
13594 goto container_fail;
13595 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
13596 goto container_fail;
13597 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13598 goto container_fail;
13599 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13600 goto container_fail;
13601 } else if (create_callno_pools()) {
13602 goto container_fail;
13603 }
13604
13605 return 0;
13606
13607 container_fail:
13608 if (peers) {
13609 ao2_ref(peers, -1);
13610 }
13611 if (users) {
13612 ao2_ref(users, -1);
13613 }
13614 if (iax_peercallno_pvts) {
13615 ao2_ref(iax_peercallno_pvts, -1);
13616 }
13617 if (iax_transfercallno_pvts) {
13618 ao2_ref(iax_transfercallno_pvts, -1);
13619 }
13620 if (peercnts) {
13621 ao2_ref(peercnts, -1);
13622 }
13623 if (callno_limits) {
13624 ao2_ref(callno_limits, -1);
13625 }
13626 if (calltoken_ignores) {
13627 ao2_ref(calltoken_ignores, -1);
13628 }
13629 if (callno_pool) {
13630 ao2_ref(callno_pool, -1);
13631 }
13632 if (callno_pool_trunk) {
13633 ao2_ref(callno_pool_trunk, -1);
13634 }
13635 return AST_MODULE_LOAD_FAILURE;
13636 }
13637
13638
13639
13640
13641 static int load_module(void)
13642 {
13643
13644 static const char config[] = "iax.conf";
13645 int x = 0;
13646 struct iax2_registry *reg = NULL;
13647
13648 if (load_objects()) {
13649 return AST_MODULE_LOAD_FAILURE;
13650 }
13651
13652 randomcalltokendata = ast_random();
13653 ast_custom_function_register(&iaxpeer_function);
13654 ast_custom_function_register(&iaxvar_function);
13655
13656 iax_set_output(iax_debug_output);
13657 iax_set_error(iax_error_output);
13658 jb_setoutput(jb_error_output, jb_warning_output, NULL);
13659
13660 memset(iaxs, 0, sizeof(iaxs));
13661
13662 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13663 ast_mutex_init(&iaxsl[x]);
13664 }
13665
13666 ast_cond_init(&sched_cond, NULL);
13667
13668 if (!(sched = sched_context_create())) {
13669 ast_log(LOG_ERROR, "Failed to create scheduler context\n");
13670 return AST_MODULE_LOAD_FAILURE;
13671 }
13672
13673 if (!(io = io_context_create())) {
13674 ast_log(LOG_ERROR, "Failed to create I/O context\n");
13675 sched_context_destroy(sched);
13676 return AST_MODULE_LOAD_FAILURE;
13677 }
13678
13679 if (!(netsock = ast_netsock_list_alloc())) {
13680 ast_log(LOG_ERROR, "Failed to create netsock list\n");
13681 io_context_destroy(io);
13682 sched_context_destroy(sched);
13683 return AST_MODULE_LOAD_FAILURE;
13684 }
13685 ast_netsock_init(netsock);
13686
13687 outsock = ast_netsock_list_alloc();
13688 if (!outsock) {
13689 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13690 io_context_destroy(io);
13691 sched_context_destroy(sched);
13692 return AST_MODULE_LOAD_FAILURE;
13693 }
13694 ast_netsock_init(outsock);
13695
13696 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
13697
13698 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
13699
13700 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
13701 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
13702 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
13703
13704 if ((timer = ast_timer_open())) {
13705 ast_timer_set_rate(timer, trunkfreq);
13706 }
13707
13708 if (set_config(config, 0) == -1) {
13709 if (timer) {
13710 ast_timer_close(timer);
13711 }
13712 return AST_MODULE_LOAD_DECLINE;
13713 }
13714
13715 if (ast_channel_register(&iax2_tech)) {
13716 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
13717 __unload_module();
13718 return AST_MODULE_LOAD_FAILURE;
13719 }
13720
13721 if (ast_register_switch(&iax2_switch))
13722 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
13723
13724 if (start_network_thread()) {
13725 ast_log(LOG_ERROR, "Unable to start network thread\n");
13726 __unload_module();
13727 return AST_MODULE_LOAD_FAILURE;
13728 } else
13729 ast_verb(2, "IAX Ready and Listening\n");
13730
13731 AST_LIST_LOCK(®istrations);
13732 AST_LIST_TRAVERSE(®istrations, reg, entry)
13733 iax2_do_register(reg);
13734 AST_LIST_UNLOCK(®istrations);
13735
13736 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
13737 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
13738
13739
13740 reload_firmware(0);
13741 iax_provision_reload(0);
13742
13743 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
13744
13745 return AST_MODULE_LOAD_SUCCESS;
13746 }
13747
13748 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
13749 .load = load_module,
13750 .unload = unload_module,
13751 .reload = reload,
13752 );