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 #include "asterisk.h"
00038
00039 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 216010 $")
00040
00041 #include <sys/mman.h>
00042 #include <dirent.h>
00043 #include <sys/socket.h>
00044 #include <netinet/in.h>
00045 #include <arpa/inet.h>
00046 #include <netinet/in_systm.h>
00047 #include <netinet/ip.h>
00048 #include <sys/time.h>
00049 #include <sys/signal.h>
00050 #include <signal.h>
00051 #include <strings.h>
00052 #include <netdb.h>
00053 #include <fcntl.h>
00054 #include <sys/stat.h>
00055 #include <regex.h>
00056
00057 #include "asterisk/paths.h"
00058
00059 #include "asterisk/lock.h"
00060 #include "asterisk/frame.h"
00061 #include "asterisk/channel.h"
00062 #include "asterisk/module.h"
00063 #include "asterisk/pbx.h"
00064 #include "asterisk/sched.h"
00065 #include "asterisk/io.h"
00066 #include "asterisk/config.h"
00067 #include "asterisk/cli.h"
00068 #include "asterisk/translate.h"
00069 #include "asterisk/md5.h"
00070 #include "asterisk/cdr.h"
00071 #include "asterisk/crypto.h"
00072 #include "asterisk/acl.h"
00073 #include "asterisk/manager.h"
00074 #include "asterisk/callerid.h"
00075 #include "asterisk/app.h"
00076 #include "asterisk/astdb.h"
00077 #include "asterisk/musiconhold.h"
00078 #include "asterisk/features.h"
00079 #include "asterisk/utils.h"
00080 #include "asterisk/causes.h"
00081 #include "asterisk/localtime.h"
00082 #include "asterisk/aes.h"
00083 #include "asterisk/dnsmgr.h"
00084 #include "asterisk/devicestate.h"
00085 #include "asterisk/netsock.h"
00086 #include "asterisk/stringfields.h"
00087 #include "asterisk/linkedlists.h"
00088 #include "asterisk/event.h"
00089 #include "asterisk/astobj2.h"
00090 #include "asterisk/timing.h"
00091
00092 #include "iax2.h"
00093 #include "iax2-parser.h"
00094 #include "iax2-provision.h"
00095 #include "jitterbuf.h"
00096
00097
00098
00099 #define SCHED_MULTITHREADED
00100
00101
00102
00103 #define DEBUG_SCHED_MULTITHREAD
00104
00105
00106 #ifdef SO_NO_CHECK
00107 static int nochecksums = 0;
00108 #endif
00109
00110 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00111 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00112
00113 #define DEFAULT_THREAD_COUNT 10
00114 #define DEFAULT_MAX_THREAD_COUNT 100
00115 #define DEFAULT_RETRY_TIME 1000
00116 #define MEMORY_SIZE 100
00117 #define DEFAULT_DROP 3
00118
00119 #define DEBUG_SUPPORT
00120
00121 #define MIN_REUSE_TIME 60
00122
00123
00124 #define GAMMA (0.01)
00125
00126 static struct ast_codec_pref prefs;
00127
00128 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00129
00130
00131
00132
00133 #define MAX_TRUNK_MTU 1240
00134
00135 static int global_max_trunk_mtu;
00136 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00137
00138 #define DEFAULT_CONTEXT "default"
00139
00140 static char default_parkinglot[AST_MAX_CONTEXT];
00141
00142 static char language[MAX_LANGUAGE] = "";
00143 static char regcontext[AST_MAX_CONTEXT] = "";
00144
00145 static int maxauthreq = 3;
00146 static int max_retries = 4;
00147 static int ping_time = 21;
00148 static int lagrq_time = 10;
00149 static int maxjitterbuffer=1000;
00150 static int resyncthreshold=1000;
00151 static int maxjitterinterps=10;
00152 static int jittertargetextra = 40;
00153
00154 #define MAX_TRUNKDATA 640 * 200
00155
00156 static int trunkfreq = 20;
00157 static int trunkmaxsize = MAX_TRUNKDATA;
00158
00159 static int authdebug = 1;
00160 static int autokill = 0;
00161 static int iaxcompat = 0;
00162 static int last_authmethod = 0;
00163
00164 static int iaxdefaultdpcache=10 * 60;
00165
00166 static int iaxdefaulttimeout = 5;
00167
00168 static struct {
00169 unsigned int tos;
00170 unsigned int cos;
00171 } qos = { 0, 0 };
00172
00173 static int min_reg_expire;
00174 static int max_reg_expire;
00175
00176 static int srvlookup = 0;
00177
00178 static struct ast_timer *timer;
00179
00180 static struct ast_netsock_list *netsock;
00181 static struct ast_netsock_list *outsock;
00182 static int defaultsockfd = -1;
00183
00184 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00185
00186
00187 #define IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)
00188
00189 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00190 ~AST_FORMAT_SLINEAR & \
00191 ~AST_FORMAT_SLINEAR16 & \
00192 ~AST_FORMAT_ULAW & \
00193 ~AST_FORMAT_ALAW & \
00194 ~AST_FORMAT_G722)
00195
00196 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00197 ~AST_FORMAT_G726 & \
00198 ~AST_FORMAT_G726_AAL2 & \
00199 ~AST_FORMAT_ADPCM)
00200
00201 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00202 ~AST_FORMAT_G723_1)
00203
00204
00205 #define DEFAULT_MAXMS 2000
00206 #define DEFAULT_FREQ_OK 60 * 1000
00207 #define DEFAULT_FREQ_NOTOK 10 * 1000
00208
00209
00210 #define IAX_CALLENCRYPTED(pvt) \
00211 (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED))
00212
00213 #define IAX_DEBUGDIGEST(msg, key) do { \
00214 int idx; \
00215 char digest[33] = ""; \
00216 \
00217 if (!iaxdebug) \
00218 break; \
00219 \
00220 for (idx = 0; idx < 16; idx++) \
00221 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00222 \
00223 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00224 } while(0)
00225
00226 static struct io_context *io;
00227 static struct sched_context *sched;
00228
00229 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00230
00231 static int iaxdebug = 0;
00232
00233 static int iaxtrunkdebug = 0;
00234
00235 static int test_losspct = 0;
00236 #ifdef IAXTESTS
00237 static int test_late = 0;
00238 static int test_resync = 0;
00239 static int test_jit = 0;
00240 static int test_jitpct = 0;
00241 #endif
00242
00243 static char accountcode[AST_MAX_ACCOUNT_CODE];
00244 static char mohinterpret[MAX_MUSICCLASS];
00245 static char mohsuggest[MAX_MUSICCLASS];
00246 static int amaflags = 0;
00247 static int adsi = 0;
00248 static int delayreject = 0;
00249 static int iax2_encryption = 0;
00250
00251 static struct ast_flags globalflags = { 0 };
00252
00253 static pthread_t netthreadid = AST_PTHREADT_NULL;
00254 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00255 AST_MUTEX_DEFINE_STATIC(sched_lock);
00256 static ast_cond_t sched_cond;
00257
00258 enum iax2_state {
00259 IAX_STATE_STARTED = (1 << 0),
00260 IAX_STATE_AUTHENTICATED = (1 << 1),
00261 IAX_STATE_TBD = (1 << 2),
00262 };
00263
00264 struct iax2_context {
00265 char context[AST_MAX_CONTEXT];
00266 struct iax2_context *next;
00267 };
00268
00269 enum iax2_flags {
00270 IAX_HASCALLERID = (1 << 0),
00271 IAX_DELME = (1 << 1),
00272 IAX_TEMPONLY = (1 << 2),
00273 IAX_TRUNK = (1 << 3),
00274 IAX_NOTRANSFER = (1 << 4),
00275 IAX_USEJITTERBUF = (1 << 5),
00276 IAX_DYNAMIC = (1 << 6),
00277 IAX_SENDANI = (1 << 7),
00278
00279 IAX_ALREADYGONE = (1 << 9),
00280 IAX_PROVISION = (1 << 10),
00281 IAX_QUELCH = (1 << 11),
00282 IAX_ENCRYPTED = (1 << 12),
00283 IAX_KEYPOPULATED = (1 << 13),
00284 IAX_CODEC_USER_FIRST = (1 << 14),
00285 IAX_CODEC_NOPREFS = (1 << 15),
00286 IAX_CODEC_NOCAP = (1 << 16),
00287 IAX_RTCACHEFRIENDS = (1 << 17),
00288 IAX_RTUPDATE = (1 << 18),
00289 IAX_RTAUTOCLEAR = (1 << 19),
00290 IAX_FORCEJITTERBUF = (1 << 20),
00291 IAX_RTIGNOREREGEXPIRE = (1 << 21),
00292 IAX_TRUNKTIMESTAMPS = (1 << 22),
00293 IAX_TRANSFERMEDIA = (1 << 23),
00294 IAX_MAXAUTHREQ = (1 << 24),
00295 IAX_DELAYPBXSTART = (1 << 25),
00296
00297
00298 IAX_ALLOWFWDOWNLOAD = (1 << 26),
00299 };
00300
00301 static int global_rtautoclear = 120;
00302
00303 static int reload_config(void);
00304
00305
00306
00307
00308 enum calltoken_peer_enum {
00309
00310 CALLTOKEN_DEFAULT = 0,
00311
00312 CALLTOKEN_YES = 1,
00313
00314
00315 CALLTOKEN_AUTO = 2,
00316
00317 CALLTOKEN_NO = 3,
00318 };
00319
00320 struct iax2_user {
00321 AST_DECLARE_STRING_FIELDS(
00322 AST_STRING_FIELD(name);
00323 AST_STRING_FIELD(secret);
00324 AST_STRING_FIELD(dbsecret);
00325 AST_STRING_FIELD(accountcode);
00326 AST_STRING_FIELD(mohinterpret);
00327 AST_STRING_FIELD(mohsuggest);
00328 AST_STRING_FIELD(inkeys);
00329 AST_STRING_FIELD(language);
00330 AST_STRING_FIELD(cid_num);
00331 AST_STRING_FIELD(cid_name);
00332 AST_STRING_FIELD(parkinglot);
00333 );
00334
00335 int authmethods;
00336 int encmethods;
00337 int amaflags;
00338 int adsi;
00339 unsigned int flags;
00340 int capability;
00341 int maxauthreq;
00342 int curauthreq;
00343 struct ast_codec_pref prefs;
00344 struct ast_ha *ha;
00345 struct iax2_context *contexts;
00346 struct ast_variable *vars;
00347 enum calltoken_peer_enum calltoken_required;
00348 };
00349
00350 struct iax2_peer {
00351 AST_DECLARE_STRING_FIELDS(
00352 AST_STRING_FIELD(name);
00353 AST_STRING_FIELD(username);
00354 AST_STRING_FIELD(secret);
00355 AST_STRING_FIELD(dbsecret);
00356 AST_STRING_FIELD(outkey);
00357
00358 AST_STRING_FIELD(regexten);
00359 AST_STRING_FIELD(context);
00360 AST_STRING_FIELD(peercontext);
00361 AST_STRING_FIELD(mailbox);
00362 AST_STRING_FIELD(mohinterpret);
00363 AST_STRING_FIELD(mohsuggest);
00364 AST_STRING_FIELD(inkeys);
00365
00366 AST_STRING_FIELD(cid_num);
00367 AST_STRING_FIELD(cid_name);
00368 AST_STRING_FIELD(zonetag);
00369 AST_STRING_FIELD(parkinglot);
00370 );
00371 struct ast_codec_pref prefs;
00372 struct ast_dnsmgr_entry *dnsmgr;
00373 struct sockaddr_in addr;
00374 int formats;
00375 int sockfd;
00376 struct in_addr mask;
00377 int adsi;
00378 unsigned int flags;
00379
00380
00381 struct sockaddr_in defaddr;
00382 int authmethods;
00383 int encmethods;
00384
00385 int expire;
00386 int expiry;
00387 int capability;
00388
00389
00390 int callno;
00391 int pokeexpire;
00392 int lastms;
00393 int maxms;
00394
00395 int pokefreqok;
00396 int pokefreqnotok;
00397 int historicms;
00398 int smoothing;
00399 uint16_t maxcallno;
00400
00401 struct ast_event_sub *mwi_event_sub;
00402
00403 struct ast_ha *ha;
00404 enum calltoken_peer_enum calltoken_required;
00405 };
00406
00407 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00408
00409 struct iax2_trunk_peer {
00410 ast_mutex_t lock;
00411 int sockfd;
00412 struct sockaddr_in addr;
00413 struct timeval txtrunktime;
00414 struct timeval rxtrunktime;
00415 struct timeval lasttxtime;
00416 struct timeval trunkact;
00417 unsigned int lastsent;
00418
00419 unsigned char *trunkdata;
00420 unsigned int trunkdatalen;
00421 unsigned int trunkdataalloc;
00422 int trunkmaxmtu;
00423 int trunkerror;
00424 int calls;
00425 AST_LIST_ENTRY(iax2_trunk_peer) list;
00426 };
00427
00428 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00429
00430 struct iax_firmware {
00431 AST_LIST_ENTRY(iax_firmware) list;
00432 int fd;
00433 int mmaplen;
00434 int dead;
00435 struct ast_iax2_firmware_header *fwh;
00436 unsigned char *buf;
00437 };
00438
00439 enum iax_reg_state {
00440 REG_STATE_UNREGISTERED = 0,
00441 REG_STATE_REGSENT,
00442 REG_STATE_AUTHSENT,
00443 REG_STATE_REGISTERED,
00444 REG_STATE_REJECTED,
00445 REG_STATE_TIMEOUT,
00446 REG_STATE_NOAUTH
00447 };
00448
00449 enum iax_transfer_state {
00450 TRANSFER_NONE = 0,
00451 TRANSFER_BEGIN,
00452 TRANSFER_READY,
00453 TRANSFER_RELEASED,
00454 TRANSFER_PASSTHROUGH,
00455 TRANSFER_MBEGIN,
00456 TRANSFER_MREADY,
00457 TRANSFER_MRELEASED,
00458 TRANSFER_MPASSTHROUGH,
00459 TRANSFER_MEDIA,
00460 TRANSFER_MEDIAPASS
00461 };
00462
00463 struct iax2_registry {
00464 struct sockaddr_in addr;
00465 char username[80];
00466 char secret[80];
00467 int expire;
00468 int refresh;
00469 enum iax_reg_state regstate;
00470 int messages;
00471 int callno;
00472 struct sockaddr_in us;
00473 struct ast_dnsmgr_entry *dnsmgr;
00474 AST_LIST_ENTRY(iax2_registry) entry;
00475 };
00476
00477 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00478
00479
00480 #define MIN_RETRY_TIME 100
00481 #define MAX_RETRY_TIME 10000
00482
00483 #define MAX_JITTER_BUFFER 50
00484 #define MIN_JITTER_BUFFER 10
00485
00486 #define DEFAULT_TRUNKDATA 640 * 10
00487
00488 #define MAX_TIMESTAMP_SKEW 160
00489
00490
00491 #define TS_GAP_FOR_JB_RESYNC 5000
00492
00493
00494 #define MARK_IAX_SUBCLASS_TX 0x8000
00495
00496 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00497 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00498 static int iaxdynamicthreadcount = 0;
00499 static int iaxdynamicthreadnum = 0;
00500 static int iaxactivethreadcount = 0;
00501
00502 struct iax_rr {
00503 int jitter;
00504 int losspct;
00505 int losscnt;
00506 int packets;
00507 int delay;
00508 int dropped;
00509 int ooo;
00510 };
00511
00512 struct iax2_pvt_ref;
00513
00514 struct chan_iax2_pvt {
00515
00516 int sockfd;
00517
00518 int voiceformat;
00519
00520 int videoformat;
00521
00522 int svoiceformat;
00523
00524 int svideoformat;
00525
00526 int capability;
00527
00528 unsigned int last;
00529
00530 unsigned int lastsent;
00531
00532 unsigned int lastvsent;
00533
00534 unsigned int nextpred;
00535
00536 int first_iax_message;
00537
00538 int last_iax_message;
00539
00540 unsigned int notsilenttx:1;
00541
00542 unsigned int pingtime;
00543
00544 int maxtime;
00545
00546 struct sockaddr_in addr;
00547
00548 struct ast_codec_pref prefs;
00549
00550 struct ast_codec_pref rprefs;
00551
00552 unsigned short callno;
00553
00554 struct callno_entry *callno_entry;
00555
00556 unsigned short peercallno;
00557
00558
00559
00560 int chosenformat;
00561
00562 int peerformat;
00563
00564 int peercapability;
00565
00566 struct timeval offset;
00567
00568 struct timeval rxcore;
00569
00570 jitterbuf *jb;
00571
00572 int jbid;
00573
00574 int lag;
00575
00576 int error;
00577
00578 struct ast_channel *owner;
00579
00580 struct ast_flags state;
00581
00582 int expiry;
00583
00584 unsigned char oseqno;
00585
00586 unsigned char rseqno;
00587
00588 unsigned char iseqno;
00589
00590 unsigned char aseqno;
00591
00592 AST_DECLARE_STRING_FIELDS(
00593
00594 AST_STRING_FIELD(peer);
00595
00596 AST_STRING_FIELD(context);
00597
00598 AST_STRING_FIELD(cid_num);
00599 AST_STRING_FIELD(cid_name);
00600
00601 AST_STRING_FIELD(ani);
00602
00603 AST_STRING_FIELD(dnid);
00604
00605 AST_STRING_FIELD(rdnis);
00606
00607 AST_STRING_FIELD(exten);
00608
00609 AST_STRING_FIELD(username);
00610
00611 AST_STRING_FIELD(secret);
00612
00613 AST_STRING_FIELD(challenge);
00614
00615 AST_STRING_FIELD(inkeys);
00616
00617 AST_STRING_FIELD(outkey);
00618
00619 AST_STRING_FIELD(language);
00620
00621 AST_STRING_FIELD(host);
00622
00623 AST_STRING_FIELD(dproot);
00624 AST_STRING_FIELD(accountcode);
00625 AST_STRING_FIELD(mohinterpret);
00626 AST_STRING_FIELD(mohsuggest);
00627
00628 AST_STRING_FIELD(osptoken);
00629
00630 AST_STRING_FIELD(parkinglot);
00631 );
00632
00633 int authrej;
00634
00635 int authmethods;
00636
00637 int encmethods;
00638
00639 ast_aes_encrypt_key ecx;
00640
00641 ast_aes_decrypt_key mydcx;
00642
00643 ast_aes_decrypt_key dcx;
00644
00645
00646 int keyrotateid;
00647
00648 unsigned char semirand[32];
00649
00650 struct iax2_registry *reg;
00651
00652 struct iax2_peer *peerpoke;
00653
00654 unsigned int flags;
00655 int adsi;
00656
00657
00658 enum iax_transfer_state transferring;
00659
00660 int transferid;
00661
00662 struct sockaddr_in transfer;
00663
00664 unsigned short transfercallno;
00665
00666 ast_aes_encrypt_key tdcx;
00667
00668
00669 int peeradsicpe;
00670
00671
00672 unsigned short bridgecallno;
00673
00674 int pingid;
00675 int lagid;
00676 int autoid;
00677 int authid;
00678 int authfail;
00679 int initid;
00680 int calling_ton;
00681 int calling_tns;
00682 int calling_pres;
00683 int amaflags;
00684 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00685
00686 struct ast_variable *vars;
00687
00688 struct ast_variable *iaxvars;
00689
00690 struct iax_rr remote_rr;
00691
00692 int min;
00693
00694 int frames_dropped;
00695
00696 int frames_received;
00697
00698 unsigned char calltoken_ie_len;
00699 };
00700
00701
00702 static struct ao2_container *callno_pool;
00703
00704
00705 static struct ao2_container *callno_pool_trunk;
00706
00707 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00708
00709
00710
00711
00712
00713
00714
00715
00716 static AST_LIST_HEAD_STATIC(frame_queue, iax_frame);
00717
00718 static int randomcalltokendata;
00719
00720 static const time_t MAX_CALLTOKEN_DELAY = 10;
00721
00722
00723
00724
00725
00726
00727
00728
00729 #ifdef LOW_MEMORY
00730 #define MAX_PEER_BUCKETS 17
00731 #else
00732 #define MAX_PEER_BUCKETS 563
00733 #endif
00734 static struct ao2_container *peers;
00735
00736 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00737 static struct ao2_container *users;
00738
00739
00740 static struct ao2_container *peercnts;
00741
00742
00743 static struct ao2_container *callno_limits;
00744
00745
00746 static struct ao2_container *calltoken_ignores;
00747
00748 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00749
00750 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00751
00752 static uint16_t global_maxcallno;
00753
00754
00755 static uint16_t global_maxcallno_nonval;
00756
00757 static uint16_t total_nonval_callno_used = 0;
00758
00759
00760
00761 struct peercnt {
00762
00763 unsigned long addr;
00764
00765 uint16_t cur;
00766
00767 uint16_t limit;
00768
00769
00770 unsigned char reg;
00771 };
00772
00773
00774 struct addr_range {
00775
00776 struct ast_ha ha;
00777
00778 uint16_t limit;
00779
00780 unsigned char delme;
00781 };
00782
00783 struct callno_entry {
00784
00785 uint16_t callno;
00786
00787 unsigned char validated;
00788 };
00789
00790 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00791
00792 enum {
00793
00794 CACHE_FLAG_EXISTS = (1 << 0),
00795
00796 CACHE_FLAG_NONEXISTENT = (1 << 1),
00797
00798 CACHE_FLAG_CANEXIST = (1 << 2),
00799
00800 CACHE_FLAG_PENDING = (1 << 3),
00801
00802 CACHE_FLAG_TIMEOUT = (1 << 4),
00803
00804 CACHE_FLAG_TRANSMITTED = (1 << 5),
00805
00806 CACHE_FLAG_UNKNOWN = (1 << 6),
00807
00808 CACHE_FLAG_MATCHMORE = (1 << 7),
00809 };
00810
00811 struct iax2_dpcache {
00812 char peercontext[AST_MAX_CONTEXT];
00813 char exten[AST_MAX_EXTENSION];
00814 struct timeval orig;
00815 struct timeval expiry;
00816 int flags;
00817 unsigned short callno;
00818 int waiters[256];
00819 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00820 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00821 };
00822
00823 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00824
00825 static void reg_source_db(struct iax2_peer *p);
00826 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00827
00828 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00829 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state);
00830 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00831
00832 enum iax2_thread_iostate {
00833 IAX_IOSTATE_IDLE,
00834 IAX_IOSTATE_READY,
00835 IAX_IOSTATE_PROCESSING,
00836 IAX_IOSTATE_SCHEDREADY,
00837 };
00838
00839 enum iax2_thread_type {
00840 IAX_THREAD_TYPE_POOL,
00841 IAX_THREAD_TYPE_DYNAMIC,
00842 };
00843
00844 struct iax2_pkt_buf {
00845 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00846 size_t len;
00847 unsigned char buf[1];
00848 };
00849
00850 struct iax2_thread {
00851 AST_LIST_ENTRY(iax2_thread) list;
00852 enum iax2_thread_type type;
00853 enum iax2_thread_iostate iostate;
00854 #ifdef SCHED_MULTITHREADED
00855 void (*schedfunc)(const void *);
00856 const void *scheddata;
00857 #endif
00858 #ifdef DEBUG_SCHED_MULTITHREAD
00859 char curfunc[80];
00860 #endif
00861 int actions;
00862 pthread_t threadid;
00863 int threadnum;
00864 struct sockaddr_in iosin;
00865 unsigned char readbuf[4096];
00866 unsigned char *buf;
00867 ssize_t buf_len;
00868 size_t buf_size;
00869 int iofd;
00870 time_t checktime;
00871 ast_mutex_t lock;
00872 ast_cond_t cond;
00873 ast_mutex_t init_lock;
00874 ast_cond_t init_cond;
00875
00876
00877
00878
00879 struct {
00880 unsigned short callno;
00881 struct sockaddr_in sin;
00882 unsigned char type;
00883 unsigned char csub;
00884 } ffinfo;
00885
00886
00887
00888 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00889 };
00890
00891
00892 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00893 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00894 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00895
00896 static void *iax2_process_thread(void *data);
00897 static void iax2_destroy(int callno);
00898
00899 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00900 {
00901 ast_mutex_lock(lock);
00902 ast_cond_signal(cond);
00903 ast_mutex_unlock(lock);
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 static struct ao2_container *iax_peercallno_pvts;
00926
00927
00928
00929
00930
00931
00932
00933
00934 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00935
00936
00937
00938
00939
00940
00941 static struct ao2_container *iax_transfercallno_pvts;
00942
00943
00944
00945 #define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2
00946
00947
00948 static struct sockaddr_in debugaddr;
00949
00950 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
00951 {
00952 if (iaxdebug ||
00953 (sin && debugaddr.sin_addr.s_addr &&
00954 (!ntohs(debugaddr.sin_port) ||
00955 debugaddr.sin_port == sin->sin_port) &&
00956 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
00957 if (iaxdebug) {
00958 iax_showframe(f, fhi, rx, sin, datalen);
00959 } else {
00960 iaxdebug = 1;
00961 iax_showframe(f, fhi, rx, sin, datalen);
00962 iaxdebug = 0;
00963 }
00964 }
00965 }
00966
00967 static void iax_debug_output(const char *data)
00968 {
00969 if (iaxdebug)
00970 ast_verbose("%s", data);
00971 }
00972
00973 static void iax_error_output(const char *data)
00974 {
00975 ast_log(LOG_WARNING, "%s", data);
00976 }
00977
00978 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
00979 {
00980 va_list args;
00981 char buf[1024];
00982
00983 va_start(args, fmt);
00984 vsnprintf(buf, sizeof(buf), fmt, args);
00985 va_end(args);
00986
00987 ast_log(LOG_ERROR, "%s", buf);
00988 }
00989
00990 static void __attribute__((format(printf, 1, 2))) jb_warning_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_WARNING, "%s", buf);
01000 }
01001
01002 static void __attribute__((format(printf, 1, 2))) jb_debug_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_verbose("%s", buf);
01012 }
01013
01014 static int maxtrunkcall = TRUNK_CALL_START;
01015 static int maxnontrunkcall = 1;
01016
01017 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);
01018 static int expire_registry(const void *data);
01019 static int iax2_answer(struct ast_channel *c);
01020 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01021 static int iax2_devicestate(void *data);
01022 static int iax2_digit_begin(struct ast_channel *c, char digit);
01023 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01024 static int iax2_do_register(struct iax2_registry *reg);
01025 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01026 static int iax2_hangup(struct ast_channel *c);
01027 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01028 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01029 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
01030 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01031 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01032 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01033 static int iax2_sendtext(struct ast_channel *c, const char *text);
01034 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01035 static int iax2_transfer(struct ast_channel *c, const char *dest);
01036 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01037 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01038 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01039 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01040 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01041 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01042 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01043 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
01044 static struct ast_frame *iax2_read(struct ast_channel *c);
01045 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01046 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01047 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
01048 static void *iax2_dup_variable_datastore(void *);
01049 static void prune_peers(void);
01050 static void prune_users(void);
01051 static void iax2_free_variable_datastore(void *);
01052
01053 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01054 static int acf_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value);
01055 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01056 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01057 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01058 static void build_rand_pad(unsigned char *buf, ssize_t len);
01059 static struct callno_entry *get_unused_callno(int trunk, int validated);
01060 static int replace_callno(const void *obj);
01061 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01062
01063 static const struct ast_channel_tech iax2_tech = {
01064 .type = "IAX2",
01065 .description = tdesc,
01066 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01067 .properties = AST_CHAN_TP_WANTSJITTER,
01068 .requester = iax2_request,
01069 .devicestate = iax2_devicestate,
01070 .send_digit_begin = iax2_digit_begin,
01071 .send_digit_end = iax2_digit_end,
01072 .send_text = iax2_sendtext,
01073 .send_image = iax2_sendimage,
01074 .send_html = iax2_sendhtml,
01075 .call = iax2_call,
01076 .hangup = iax2_hangup,
01077 .answer = iax2_answer,
01078 .read = iax2_read,
01079 .write = iax2_write,
01080 .write_video = iax2_write,
01081 .indicate = iax2_indicate,
01082 .setoption = iax2_setoption,
01083 .bridge = iax2_bridge,
01084 .transfer = iax2_transfer,
01085 .fixup = iax2_fixup,
01086 .func_channel_read = acf_channel_read,
01087 .func_channel_write = acf_channel_write,
01088 };
01089
01090 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01091 {
01092
01093
01094
01095 }
01096
01097
01098
01099 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01100 {
01101 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01102 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01103 pvt->owner ? pvt->owner->name : "",
01104 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01105 }
01106
01107
01108 static struct ast_datastore_info iax2_variable_datastore_info = {
01109 .type = "IAX2_VARIABLE",
01110 .duplicate = iax2_dup_variable_datastore,
01111 .destroy = iax2_free_variable_datastore,
01112 };
01113
01114 static void *iax2_dup_variable_datastore(void *old)
01115 {
01116 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01117 struct ast_var_t *oldvar, *newvar;
01118
01119 newlist = ast_calloc(sizeof(*newlist), 1);
01120 if (!newlist) {
01121 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01122 return NULL;
01123 }
01124
01125 AST_LIST_HEAD_INIT(newlist);
01126 AST_LIST_LOCK(oldlist);
01127 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01128 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01129 if (newvar)
01130 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01131 else
01132 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01133 }
01134 AST_LIST_UNLOCK(oldlist);
01135 return newlist;
01136 }
01137
01138 static void iax2_free_variable_datastore(void *old)
01139 {
01140 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01141 struct ast_var_t *oldvar;
01142
01143 AST_LIST_LOCK(oldlist);
01144 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01145 ast_free(oldvar);
01146 }
01147 AST_LIST_UNLOCK(oldlist);
01148 AST_LIST_HEAD_DESTROY(oldlist);
01149 ast_free(oldlist);
01150 }
01151
01152
01153
01154
01155
01156 static void insert_idle_thread(struct iax2_thread *thread)
01157 {
01158 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01159 AST_LIST_LOCK(&dynamic_list);
01160 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01161 AST_LIST_UNLOCK(&dynamic_list);
01162 } else {
01163 AST_LIST_LOCK(&idle_list);
01164 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01165 AST_LIST_UNLOCK(&idle_list);
01166 }
01167
01168 return;
01169 }
01170
01171 static struct iax2_thread *find_idle_thread(void)
01172 {
01173 struct iax2_thread *thread = NULL;
01174
01175
01176 AST_LIST_LOCK(&idle_list);
01177 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01178 AST_LIST_UNLOCK(&idle_list);
01179
01180
01181 if (thread) {
01182 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01183 return thread;
01184 }
01185
01186
01187 AST_LIST_LOCK(&dynamic_list);
01188 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01189 AST_LIST_UNLOCK(&dynamic_list);
01190
01191
01192 if (thread) {
01193 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01194 return thread;
01195 }
01196
01197
01198 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01199 return NULL;
01200
01201
01202 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01203 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01204 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01205
01206
01207 ast_mutex_init(&thread->lock);
01208 ast_cond_init(&thread->cond, NULL);
01209 ast_mutex_init(&thread->init_lock);
01210 ast_cond_init(&thread->init_cond, NULL);
01211 ast_mutex_lock(&thread->init_lock);
01212
01213
01214 if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01215 ast_cond_destroy(&thread->cond);
01216 ast_mutex_destroy(&thread->lock);
01217 ast_free(thread);
01218 return NULL;
01219 }
01220
01221
01222
01223 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01224
01225
01226 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01227
01228
01229 ast_mutex_unlock(&thread->init_lock);
01230
01231 return thread;
01232 }
01233
01234 #ifdef SCHED_MULTITHREADED
01235 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01236 {
01237 struct iax2_thread *thread = NULL;
01238 static time_t lasterror;
01239 static time_t t;
01240
01241 thread = find_idle_thread();
01242
01243 if (thread != NULL) {
01244 thread->schedfunc = func;
01245 thread->scheddata = data;
01246 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01247 #ifdef DEBUG_SCHED_MULTITHREAD
01248 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01249 #endif
01250 signal_condition(&thread->lock, &thread->cond);
01251 return 0;
01252 }
01253 time(&t);
01254 if (t != lasterror)
01255 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01256 lasterror = t;
01257
01258 return -1;
01259 }
01260 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01261 #endif
01262
01263 static int iax2_sched_replace(int id, struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01264 {
01265 AST_SCHED_REPLACE(id, con, when, callback, data);
01266 signal_condition(&sched_lock, &sched_cond);
01267
01268 return id;
01269 }
01270
01271 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01272 {
01273 int res;
01274
01275 res = ast_sched_add(con, when, callback, data);
01276 signal_condition(&sched_lock, &sched_cond);
01277
01278 return res;
01279 }
01280
01281 static int send_ping(const void *data);
01282
01283 static void __send_ping(const void *data)
01284 {
01285 int callno = (long) data;
01286
01287 ast_mutex_lock(&iaxsl[callno]);
01288
01289 if (iaxs[callno]) {
01290 if (iaxs[callno]->peercallno) {
01291 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01292 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01293 } else {
01294
01295 iaxs[callno]->pingid = -1;
01296 }
01297 } else {
01298 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01299 }
01300
01301 ast_mutex_unlock(&iaxsl[callno]);
01302 }
01303
01304 static int send_ping(const void *data)
01305 {
01306 #ifdef SCHED_MULTITHREADED
01307 if (schedule_action(__send_ping, data))
01308 #endif
01309 __send_ping(data);
01310
01311 return 0;
01312 }
01313
01314 static int get_encrypt_methods(const char *s)
01315 {
01316 int e;
01317 if (!strcasecmp(s, "aes128"))
01318 e = IAX_ENCRYPT_AES128;
01319 else if (ast_true(s))
01320 e = IAX_ENCRYPT_AES128;
01321 else
01322 e = 0;
01323 return e;
01324 }
01325
01326 static int send_lagrq(const void *data);
01327
01328 static void __send_lagrq(const void *data)
01329 {
01330 int callno = (long) data;
01331
01332 ast_mutex_lock(&iaxsl[callno]);
01333
01334 if (iaxs[callno]) {
01335 if (iaxs[callno]->peercallno) {
01336 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01337 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01338 } else {
01339
01340 iaxs[callno]->lagid = -1;
01341 }
01342 } else {
01343 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01344 }
01345
01346 ast_mutex_unlock(&iaxsl[callno]);
01347 }
01348
01349 static int send_lagrq(const void *data)
01350 {
01351 #ifdef SCHED_MULTITHREADED
01352 if (schedule_action(__send_lagrq, data))
01353 #endif
01354 __send_lagrq(data);
01355
01356 return 0;
01357 }
01358
01359 static unsigned char compress_subclass(int subclass)
01360 {
01361 int x;
01362 int power=-1;
01363
01364 if (subclass < IAX_FLAG_SC_LOG)
01365 return subclass;
01366
01367 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01368 if (subclass & (1 << x)) {
01369 if (power > -1) {
01370 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01371 return 0;
01372 } else
01373 power = x;
01374 }
01375 }
01376 return power | IAX_FLAG_SC_LOG;
01377 }
01378
01379 static int uncompress_subclass(unsigned char csub)
01380 {
01381
01382 if (csub & IAX_FLAG_SC_LOG) {
01383
01384 if (csub == 0xff)
01385 return -1;
01386 else
01387 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01388 }
01389 else
01390 return csub;
01391 }
01392
01393
01394
01395
01396 static int peer_hash_cb(const void *obj, const int flags)
01397 {
01398 const struct iax2_peer *peer = obj;
01399
01400 return ast_str_hash(peer->name);
01401 }
01402
01403
01404
01405
01406 static int peer_cmp_cb(void *obj, void *arg, int flags)
01407 {
01408 struct iax2_peer *peer = obj, *peer2 = arg;
01409
01410 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01411 }
01412
01413
01414
01415
01416 static int user_hash_cb(const void *obj, const int flags)
01417 {
01418 const struct iax2_user *user = obj;
01419
01420 return ast_str_hash(user->name);
01421 }
01422
01423
01424
01425
01426 static int user_cmp_cb(void *obj, void *arg, int flags)
01427 {
01428 struct iax2_user *user = obj, *user2 = arg;
01429
01430 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01431 }
01432
01433
01434
01435
01436
01437 static struct iax2_peer *find_peer(const char *name, int realtime)
01438 {
01439 struct iax2_peer *peer = NULL;
01440 struct iax2_peer tmp_peer = {
01441 .name = name,
01442 };
01443
01444 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01445
01446
01447 if(!peer && realtime)
01448 peer = realtime_peer(name, NULL);
01449
01450 return peer;
01451 }
01452
01453 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01454 {
01455 ao2_ref(peer, +1);
01456 return peer;
01457 }
01458
01459 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01460 {
01461 ao2_ref(peer, -1);
01462 return NULL;
01463 }
01464
01465 static struct iax2_user *find_user(const char *name)
01466 {
01467 struct iax2_user tmp_user = {
01468 .name = name,
01469 };
01470
01471 return ao2_find(users, &tmp_user, OBJ_POINTER);
01472 }
01473 static inline struct iax2_user *user_ref(struct iax2_user *user)
01474 {
01475 ao2_ref(user, +1);
01476 return user;
01477 }
01478
01479 static inline struct iax2_user *user_unref(struct iax2_user *user)
01480 {
01481 ao2_ref(user, -1);
01482 return NULL;
01483 }
01484
01485 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01486 {
01487 struct iax2_peer *peer = NULL;
01488 int res = 0;
01489 struct ao2_iterator i;
01490
01491 i = ao2_iterator_init(peers, 0);
01492 while ((peer = ao2_iterator_next(&i))) {
01493 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01494 (peer->addr.sin_port == sin.sin_port)) {
01495 ast_copy_string(host, peer->name, len);
01496 peer_unref(peer);
01497 res = 1;
01498 break;
01499 }
01500 peer_unref(peer);
01501 }
01502
01503 if (!peer) {
01504 peer = realtime_peer(NULL, &sin);
01505 if (peer) {
01506 ast_copy_string(host, peer->name, len);
01507 peer_unref(peer);
01508 res = 1;
01509 }
01510 }
01511
01512 return res;
01513 }
01514
01515
01516
01517 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01518 {
01519
01520 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01521 struct iax2_user *user;
01522 struct iax2_user tmp_user = {
01523 .name = pvt->username,
01524 };
01525
01526 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01527 if (user) {
01528 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01529 user_unref(user);
01530 }
01531
01532 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01533 }
01534
01535 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]);
01536 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]);
01537 AST_SCHED_DEL(sched, pvt->autoid);
01538 AST_SCHED_DEL(sched, pvt->authid);
01539 AST_SCHED_DEL(sched, pvt->initid);
01540 AST_SCHED_DEL(sched, pvt->jbid);
01541 AST_SCHED_DEL(sched, pvt->keyrotateid);
01542 }
01543
01544 static void iax2_frame_free(struct iax_frame *fr)
01545 {
01546 AST_SCHED_DEL(sched, fr->retrans);
01547 iax_frame_free(fr);
01548 }
01549
01550 static int scheduled_destroy(const void *vid)
01551 {
01552 short callno = PTR_TO_CALLNO(vid);
01553 ast_mutex_lock(&iaxsl[callno]);
01554 if (iaxs[callno]) {
01555 if (option_debug) {
01556 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01557 }
01558 iax2_destroy(callno);
01559 }
01560 ast_mutex_unlock(&iaxsl[callno]);
01561 return 0;
01562 }
01563
01564 static void pvt_destructor(void *obj)
01565 {
01566 struct chan_iax2_pvt *pvt = obj;
01567 struct iax_frame *cur = NULL;
01568
01569 ast_mutex_lock(&iaxsl[pvt->callno]);
01570 iax2_destroy_helper(pvt);
01571 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01572 pvt->callno_entry = NULL;
01573 ast_mutex_unlock(&iaxsl[pvt->callno]);
01574
01575
01576 ast_set_flag(pvt, IAX_ALREADYGONE);
01577
01578 AST_LIST_LOCK(&frame_queue);
01579 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01580
01581 if (cur->callno == pvt->callno) {
01582 cur->retries = -1;
01583 }
01584 }
01585 AST_LIST_UNLOCK(&frame_queue);
01586
01587 if (pvt->reg) {
01588 pvt->reg->callno = 0;
01589 }
01590
01591 if (!pvt->owner) {
01592 jb_frame frame;
01593 if (pvt->vars) {
01594 ast_variables_destroy(pvt->vars);
01595 pvt->vars = NULL;
01596 }
01597
01598 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01599 iax2_frame_free(frame.data);
01600 }
01601
01602 jb_destroy(pvt->jb);
01603 ast_string_field_free_memory(pvt);
01604 }
01605 }
01606
01607 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01608 {
01609 struct chan_iax2_pvt *tmp;
01610 jb_conf jbconf;
01611
01612 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01613 return NULL;
01614 }
01615
01616 if (ast_string_field_init(tmp, 32)) {
01617 ao2_ref(tmp, -1);
01618 tmp = NULL;
01619 return NULL;
01620 }
01621
01622 tmp->prefs = prefs;
01623 tmp->pingid = -1;
01624 tmp->lagid = -1;
01625 tmp->autoid = -1;
01626 tmp->authid = -1;
01627 tmp->initid = -1;
01628 tmp->keyrotateid = -1;
01629
01630 ast_string_field_set(tmp,exten, "s");
01631 ast_string_field_set(tmp,host, host);
01632
01633 tmp->jb = jb_new();
01634 tmp->jbid = -1;
01635 jbconf.max_jitterbuf = maxjitterbuffer;
01636 jbconf.resync_threshold = resyncthreshold;
01637 jbconf.max_contig_interp = maxjitterinterps;
01638 jbconf.target_extra = jittertargetextra;
01639 jb_setconf(tmp->jb,&jbconf);
01640
01641 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01642
01643 return tmp;
01644 }
01645
01646 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01647 {
01648 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01649 if (new) {
01650 size_t afdatalen = new->afdatalen;
01651 memcpy(new, fr, sizeof(*new));
01652 iax_frame_wrap(new, &fr->af);
01653 new->afdatalen = afdatalen;
01654 new->data = NULL;
01655 new->datalen = 0;
01656 new->direction = DIRECTION_INGRESS;
01657 new->retrans = -1;
01658 }
01659 return new;
01660 }
01661
01662
01663 enum {
01664
01665 NEW_PREVENT = 0,
01666
01667 NEW_ALLOW = 1,
01668
01669 NEW_FORCE = 2,
01670
01671
01672 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01673 };
01674
01675 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01676 {
01677 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01678 (cur->addr.sin_port == sin->sin_port)) {
01679
01680 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01681 (check_dcallno ? dcallno == cur->callno : 1) ) {
01682
01683 return 1;
01684 }
01685 }
01686 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01687 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01688
01689 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01690 return 1;
01691 }
01692 return 0;
01693 }
01694
01695 static void update_max_trunk(void)
01696 {
01697 int max = TRUNK_CALL_START;
01698 int x;
01699
01700
01701 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01702 if (iaxs[x]) {
01703 max = x + 1;
01704 }
01705 }
01706
01707 maxtrunkcall = max;
01708 if (iaxdebug)
01709 ast_debug(1, "New max trunk callno is %d\n", max);
01710 }
01711
01712 static void update_max_nontrunk(void)
01713 {
01714 int max = 1;
01715 int x;
01716
01717 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01718 if (iaxs[x])
01719 max = x + 1;
01720 }
01721 maxnontrunkcall = max;
01722 if (iaxdebug)
01723 ast_debug(1, "New max nontrunk callno is %d\n", max);
01724 }
01725
01726 static int make_trunk(unsigned short callno, int locked)
01727 {
01728 int x;
01729 int res= 0;
01730 struct callno_entry *callno_entry;
01731 if (iaxs[callno]->oseqno) {
01732 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01733 return -1;
01734 }
01735 if (callno & TRUNK_CALL_START) {
01736 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01737 return -1;
01738 }
01739
01740 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
01741 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01742 return -1;
01743 }
01744
01745 x = callno_entry->callno;
01746 ast_mutex_lock(&iaxsl[x]);
01747
01748
01749
01750
01751
01752 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01753 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01754 iaxs[x] = iaxs[callno];
01755 iaxs[x]->callno = x;
01756
01757
01758
01759 if (iaxs[x]->callno_entry) {
01760 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
01761 }
01762 iaxs[x]->callno_entry = callno_entry;
01763
01764 iaxs[callno] = NULL;
01765
01766 iaxs[x]->pingid = iax2_sched_add(sched,
01767 ping_time * 1000, send_ping, (void *)(long)x);
01768 iaxs[x]->lagid = iax2_sched_add(sched,
01769 lagrq_time * 1000, send_lagrq, (void *)(long)x);
01770
01771 if (locked)
01772 ast_mutex_unlock(&iaxsl[callno]);
01773 res = x;
01774 if (!locked)
01775 ast_mutex_unlock(&iaxsl[x]);
01776
01777 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01778
01779 update_max_trunk();
01780 update_max_nontrunk();
01781 return res;
01782 }
01783
01784 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01785 {
01786 if (!pvt->transfercallno) {
01787 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01788 return;
01789 }
01790
01791 ao2_link(iax_transfercallno_pvts, pvt);
01792 }
01793
01794 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01795 {
01796 if (!pvt->transfercallno) {
01797 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01798 return;
01799 }
01800
01801 ao2_unlink(iax_transfercallno_pvts, pvt);
01802 }
01803 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01804 {
01805 if (!pvt->peercallno) {
01806 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01807 return;
01808 }
01809
01810 ao2_link(iax_peercallno_pvts, pvt);
01811 }
01812
01813 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01814 {
01815 if (!pvt->peercallno) {
01816 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01817 return;
01818 }
01819
01820 ao2_unlink(iax_peercallno_pvts, pvt);
01821 }
01822
01823 static int addr_range_delme_cb(void *obj, void *arg, int flags)
01824 {
01825 struct addr_range *lim = obj;
01826 lim->delme = 1;
01827 return 0;
01828 }
01829
01830 static int addr_range_hash_cb(const void *obj, const int flags)
01831 {
01832 const struct addr_range *lim = obj;
01833 return abs((int) lim->ha.netaddr.s_addr);
01834 }
01835
01836 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
01837 {
01838 struct addr_range *lim1 = obj, *lim2 = arg;
01839 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
01840 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
01841 CMP_MATCH | CMP_STOP : 0;
01842 }
01843
01844 static int peercnt_hash_cb(const void *obj, const int flags)
01845 {
01846 const struct peercnt *peercnt = obj;
01847 return abs((int) peercnt->addr);
01848 }
01849
01850 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
01851 {
01852 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
01853 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
01854 }
01855
01856 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
01857 {
01858 struct addr_range *addr_range = obj;
01859 struct sockaddr_in *sin = arg;
01860
01861 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
01862 return CMP_MATCH | CMP_STOP;
01863 }
01864 return 0;
01865 }
01866
01867
01868
01869
01870
01871
01872 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
01873 {
01874 struct addr_range *addr_range;
01875 struct iax2_peer *peer = NULL;
01876 struct iax2_user *user = NULL;
01877
01878 const char *find = S_OR(name, "guest");
01879 int res = 1;
01880 int optional = 0;
01881 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
01882
01883
01884
01885
01886
01887
01888
01889 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
01890 ao2_ref(addr_range, -1);
01891 optional = 1;
01892 }
01893
01894
01895 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
01896 calltoken_required = user->calltoken_required;
01897 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 1))) {
01898 calltoken_required = peer->calltoken_required;
01899 }
01900
01901 if (peer) {
01902 peer_unref(peer);
01903 }
01904 if (user) {
01905 user_unref(user);
01906 }
01907
01908 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);
01909 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
01910 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
01911 res = 0;
01912 }
01913
01914 return res;
01915 }
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927 static void set_peercnt_limit(struct peercnt *peercnt)
01928 {
01929 uint16_t limit = global_maxcallno;
01930 struct addr_range *addr_range;
01931 struct sockaddr_in sin = {
01932 .sin_addr.s_addr = peercnt->addr,
01933 };
01934
01935
01936 if (peercnt->reg && peercnt->limit) {
01937 return;
01938 }
01939
01940 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
01941 limit = addr_range->limit;
01942 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
01943 ao2_ref(addr_range, -1);
01944 }
01945
01946 peercnt->limit = limit;
01947 }
01948
01949
01950
01951
01952
01953 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
01954 {
01955 struct peercnt *peercnt = obj;
01956
01957 set_peercnt_limit(peercnt);
01958 ast_debug(1, "Reset limits for peercnts table\n");
01959
01960 return 0;
01961 }
01962
01963
01964
01965
01966
01967 static int prune_addr_range_cb(void *obj, void *arg, int flags)
01968 {
01969 struct addr_range *addr_range = obj;
01970
01971 return addr_range->delme ? CMP_MATCH : 0;
01972 }
01973
01974
01975
01976
01977
01978 static void peercnt_modify(unsigned char reg, uint16_t limit, struct sockaddr_in *sin)
01979 {
01980
01981 struct peercnt *peercnt;
01982 struct peercnt tmp = {
01983 .addr = sin->sin_addr.s_addr,
01984 };
01985
01986 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
01987 peercnt->reg = reg;
01988 if (limit) {
01989 peercnt->limit = limit;
01990 } else {
01991 set_peercnt_limit(peercnt);
01992 }
01993 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg);
01994 ao2_ref(peercnt, -1);
01995 }
01996 }
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006 static int peercnt_add(struct sockaddr_in *sin)
02007 {
02008 struct peercnt *peercnt;
02009 unsigned long addr = sin->sin_addr.s_addr;
02010 int res = 0;
02011 struct peercnt tmp = {
02012 .addr = addr,
02013 };
02014
02015
02016
02017
02018
02019
02020
02021 ao2_lock(peercnts);
02022 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02023 ao2_lock(peercnt);
02024 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02025 ao2_lock(peercnt);
02026
02027 peercnt->addr = addr;
02028 set_peercnt_limit(peercnt);
02029
02030
02031 ao2_link(peercnts, peercnt);
02032 } else {
02033 ao2_unlock(peercnts);
02034 return -1;
02035 }
02036
02037
02038 if (peercnt->limit > peercnt->cur) {
02039 peercnt->cur++;
02040 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02041 } else {
02042 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02043 res = -1;
02044 }
02045
02046
02047 ao2_unlock(peercnt);
02048 ao2_unlock(peercnts);
02049 ao2_ref(peercnt, -1);
02050
02051 return res;
02052 }
02053
02054
02055
02056
02057
02058 static void peercnt_remove(struct peercnt *peercnt)
02059 {
02060 struct sockaddr_in sin = {
02061 .sin_addr.s_addr = peercnt->addr,
02062 };
02063
02064 if (peercnt) {
02065
02066
02067
02068 ao2_lock(peercnts);
02069 peercnt->cur--;
02070 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02071
02072 if (peercnt->cur == 0) {
02073 ao2_unlink(peercnts, peercnt);
02074 }
02075 ao2_unlock(peercnts);
02076 }
02077 }
02078
02079
02080
02081
02082
02083 static int peercnt_remove_cb(const void *obj)
02084 {
02085 struct peercnt *peercnt = (struct peercnt *) obj;
02086
02087 peercnt_remove(peercnt);
02088 ao2_ref(peercnt, -1);
02089
02090 return 0;
02091 }
02092
02093
02094
02095
02096
02097 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02098 {
02099 struct peercnt *peercnt;
02100 struct peercnt tmp = {
02101 .addr = sin->sin_addr.s_addr,
02102 };
02103
02104 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02105 peercnt_remove(peercnt);
02106 ao2_ref(peercnt, -1);
02107 }
02108 return 0;
02109 }
02110
02111
02112
02113
02114
02115 static void build_callno_limits(struct ast_variable *v)
02116 {
02117 struct addr_range *addr_range = NULL;
02118 struct addr_range tmp;
02119 struct ast_ha *ha;
02120 int limit;
02121 int error;
02122 int found;
02123
02124 for (; v; v = v->next) {
02125 limit = -1;
02126 error = 0;
02127 found = 0;
02128 ha = ast_append_ha("permit", v->name, NULL, &error);
02129
02130
02131 if (error) {
02132 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02133 continue;
02134 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02135 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02136 ast_free_ha(ha);
02137 continue;
02138 }
02139
02140 ast_copy_ha(ha, &tmp.ha);
02141
02142 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02143 ao2_lock(addr_range);
02144 found = 1;
02145 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02146 ast_free_ha(ha);
02147 return;
02148 }
02149
02150
02151 ast_copy_ha(ha, &addr_range->ha);
02152 ast_free_ha(ha);
02153 addr_range->limit = limit;
02154 addr_range->delme = 0;
02155
02156
02157 if (found) {
02158 ao2_unlock(addr_range);
02159 } else {
02160 ao2_link(callno_limits, addr_range);
02161 }
02162 ao2_ref(addr_range, -1);
02163 }
02164 }
02165
02166
02167
02168
02169
02170 static int add_calltoken_ignore(const char *addr)
02171 {
02172 struct addr_range tmp;
02173 struct addr_range *addr_range = NULL;
02174 struct ast_ha *ha = NULL;
02175 int error = 0;
02176
02177 if (ast_strlen_zero(addr)) {
02178 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02179 return -1;
02180 }
02181
02182 ha = ast_append_ha("permit", addr, NULL, &error);
02183
02184
02185 if (error) {
02186 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02187 return -1;
02188 }
02189
02190 ast_copy_ha(ha, &tmp.ha);
02191
02192 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02193 ao2_lock(addr_range);
02194 addr_range->delme = 0;
02195 ao2_unlock(addr_range);
02196 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02197
02198 ast_copy_ha(ha, &addr_range->ha);
02199 ao2_link(calltoken_ignores, addr_range);
02200 } else {
02201 ast_free_ha(ha);
02202 return -1;
02203 }
02204
02205 ast_free_ha(ha);
02206 ao2_ref(addr_range, -1);
02207
02208 return 0;
02209 }
02210
02211 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02212 {
02213 struct ao2_iterator i;
02214 struct peercnt *peercnt;
02215 struct sockaddr_in sin;
02216 int found = 0;
02217
02218 switch (cmd) {
02219 case CLI_INIT:
02220 e->command = "iax2 show callnumber usage";
02221 e->usage =
02222 "Usage: iax2 show callnumber usage <ip address (optional)>\n"
02223 " Shows current ip addresses which are consuming iax2 call numbers\n";
02224 return NULL;
02225 case CLI_GENERATE:
02226 return NULL;
02227 case CLI_HANDLER:
02228 if (a->argc < 4 || a->argc > 5)
02229 return CLI_SHOWUSAGE;
02230
02231 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02232 i = ao2_iterator_init(peercnts, 0);
02233 while ((peercnt = ao2_iterator_next(&i))) {
02234 sin.sin_addr.s_addr = peercnt->addr;
02235 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02236 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02237 found = 1;
02238 break;
02239 } else {
02240 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02241 }
02242 ao2_ref(peercnt, -1);
02243 }
02244
02245 if (a->argc == 4) {
02246 ast_cli(a->fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
02247 } else if (a->argc == 5 && !found) {
02248 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02249 }
02250
02251 return CLI_SUCCESS;
02252 default:
02253 return NULL;
02254 }
02255 }
02256
02257 static struct callno_entry *get_unused_callno(int trunk, int validated)
02258 {
02259 struct callno_entry *callno_entry = NULL;
02260 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02261 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02262
02263 return NULL;
02264 }
02265
02266
02267
02268 ao2_lock(callno_pool);
02269
02270
02271
02272
02273 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02274 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02275 ao2_unlock(callno_pool);
02276 return NULL;
02277 }
02278
02279
02280
02281 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02282
02283 if (callno_entry) {
02284 callno_entry->validated = validated;
02285 if (!validated) {
02286 total_nonval_callno_used++;
02287 }
02288 }
02289
02290 ao2_unlock(callno_pool);
02291 return callno_entry;
02292 }
02293
02294 static int replace_callno(const void *obj)
02295 {
02296 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02297
02298
02299
02300 ao2_lock(callno_pool);
02301
02302 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02303 total_nonval_callno_used--;
02304 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02305 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02306 }
02307
02308 if (callno_entry->callno < TRUNK_CALL_START) {
02309 ao2_link(callno_pool, callno_entry);
02310 } else {
02311 ao2_link(callno_pool_trunk, callno_entry);
02312 }
02313 ao2_ref(callno_entry, -1);
02314
02315 ao2_unlock(callno_pool);
02316 return 0;
02317 }
02318
02319 static int callno_hash(const void *obj, const int flags)
02320 {
02321 return abs(ast_random());
02322 }
02323
02324 static int create_callno_pools(void)
02325 {
02326 uint16_t i;
02327
02328 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02329 return -1;
02330 }
02331
02332 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02333 return -1;
02334 }
02335
02336
02337 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02338 struct callno_entry *callno_entry;
02339
02340 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02341 return -1;
02342 }
02343
02344 callno_entry->callno = i;
02345
02346 if (i < TRUNK_CALL_START) {
02347 ao2_link(callno_pool, callno_entry);
02348 } else {
02349 ao2_link(callno_pool_trunk, callno_entry);
02350 }
02351
02352 ao2_ref(callno_entry, -1);
02353 }
02354
02355 return 0;
02356 }
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02367 {
02368 int i;
02369 struct peercnt *peercnt;
02370 struct peercnt tmp = {
02371 .addr = sin->sin_addr.s_addr,
02372 };
02373
02374 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02375
02376 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02377 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02378 if (i == -1) {
02379 ao2_ref(peercnt, -1);
02380 }
02381 }
02382
02383 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02384 }
02385
02386
02387
02388
02389
02390
02391
02392
02393 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02394 {
02395 if (frametype != AST_FRAME_IAX) {
02396 return 0;
02397 }
02398 switch (subclass) {
02399 case IAX_COMMAND_NEW:
02400 case IAX_COMMAND_REGREQ:
02401 case IAX_COMMAND_FWDOWNL:
02402 case IAX_COMMAND_REGREL:
02403 return 1;
02404 case IAX_COMMAND_POKE:
02405 if (!inbound) {
02406 return 1;
02407 }
02408 break;
02409 }
02410 return 0;
02411 }
02412
02413
02414
02415
02416 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02417 {
02418 int res = 0;
02419 int x;
02420
02421
02422 int validated = (new > NEW_ALLOW) ? 1 : 0;
02423 char host[80];
02424
02425 if (new <= NEW_ALLOW) {
02426 if (callno) {
02427 struct chan_iax2_pvt *pvt;
02428 struct chan_iax2_pvt tmp_pvt = {
02429 .callno = dcallno,
02430 .peercallno = callno,
02431 .transfercallno = callno,
02432
02433 .frames_received = check_dcallno,
02434 };
02435
02436 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02437
02438 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02439 if (return_locked) {
02440 ast_mutex_lock(&iaxsl[pvt->callno]);
02441 }
02442 res = pvt->callno;
02443 ao2_ref(pvt, -1);
02444 pvt = NULL;
02445 return res;
02446 }
02447
02448 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02449 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr));
02450 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02451 if (return_locked) {
02452 ast_mutex_lock(&iaxsl[pvt->callno]);
02453 }
02454 res = pvt->callno;
02455 ao2_ref(pvt, -1);
02456 pvt = NULL;
02457 return res;
02458 }
02459 }
02460
02461
02462 if (dcallno) {
02463 ast_mutex_lock(&iaxsl[dcallno]);
02464 }
02465 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02466 iaxs[dcallno]->peercallno = callno;
02467 res = dcallno;
02468 store_by_peercallno(iaxs[dcallno]);
02469 if (!res || !return_locked) {
02470 ast_mutex_unlock(&iaxsl[dcallno]);
02471 }
02472 return res;
02473 }
02474 if (dcallno) {
02475 ast_mutex_unlock(&iaxsl[dcallno]);
02476 }
02477 #ifdef IAX_OLD_FIND
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489 for (x = 1; !res && x < maxnontrunkcall; x++) {
02490 ast_mutex_lock(&iaxsl[x]);
02491 if (iaxs[x]) {
02492
02493 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02494 res = x;
02495 }
02496 }
02497 if (!res || !return_locked)
02498 ast_mutex_unlock(&iaxsl[x]);
02499 }
02500 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02501 ast_mutex_lock(&iaxsl[x]);
02502 if (iaxs[x]) {
02503
02504 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02505 res = x;
02506 }
02507 }
02508 if (!res || !return_locked)
02509 ast_mutex_unlock(&iaxsl[x]);
02510 }
02511 #endif
02512 }
02513 if (!res && (new >= NEW_ALLOW)) {
02514 struct callno_entry *callno_entry;
02515
02516
02517
02518
02519
02520
02521 if (!iax2_getpeername(*sin, host, sizeof(host)))
02522 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02523
02524 if (peercnt_add(sin)) {
02525
02526
02527 return 0;
02528 }
02529
02530 if (!(callno_entry = get_unused_callno(0, validated))) {
02531
02532
02533 peercnt_remove_by_addr(sin);
02534 ast_log(LOG_WARNING, "No more space\n");
02535 return 0;
02536 }
02537 x = callno_entry->callno;
02538 ast_mutex_lock(&iaxsl[x]);
02539
02540 iaxs[x] = new_iax(sin, host);
02541 update_max_nontrunk();
02542 if (iaxs[x]) {
02543 if (iaxdebug)
02544 ast_debug(1, "Creating new call structure %d\n", x);
02545 iaxs[x]->callno_entry = callno_entry;
02546 iaxs[x]->sockfd = sockfd;
02547 iaxs[x]->addr.sin_port = sin->sin_port;
02548 iaxs[x]->addr.sin_family = sin->sin_family;
02549 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02550 iaxs[x]->peercallno = callno;
02551 iaxs[x]->callno = x;
02552 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02553 iaxs[x]->expiry = min_reg_expire;
02554 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02555 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02556 iaxs[x]->amaflags = amaflags;
02557 ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02558
02559 ast_string_field_set(iaxs[x], accountcode, accountcode);
02560 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02561 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02562 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02563
02564 if (iaxs[x]->peercallno) {
02565 store_by_peercallno(iaxs[x]);
02566 }
02567 } else {
02568 ast_log(LOG_WARNING, "Out of resources\n");
02569 ast_mutex_unlock(&iaxsl[x]);
02570 replace_callno(callno_entry);
02571 return 0;
02572 }
02573 if (!return_locked)
02574 ast_mutex_unlock(&iaxsl[x]);
02575 res = x;
02576 }
02577 return res;
02578 }
02579
02580 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02581
02582 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02583 }
02584
02585 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02586
02587 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02588 }
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600 static int iax2_queue_frame(int callno, struct ast_frame *f)
02601 {
02602 for (;;) {
02603 if (iaxs[callno] && iaxs[callno]->owner) {
02604 if (ast_channel_trylock(iaxs[callno]->owner)) {
02605
02606 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02607 } else {
02608 ast_queue_frame(iaxs[callno]->owner, f);
02609 ast_channel_unlock(iaxs[callno]->owner);
02610 break;
02611 }
02612 } else
02613 break;
02614 }
02615 return 0;
02616 }
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631 static int iax2_queue_hangup(int callno)
02632 {
02633 for (;;) {
02634 if (iaxs[callno] && iaxs[callno]->owner) {
02635 if (ast_channel_trylock(iaxs[callno]->owner)) {
02636
02637 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02638 } else {
02639 ast_queue_hangup(iaxs[callno]->owner);
02640 ast_channel_unlock(iaxs[callno]->owner);
02641 break;
02642 }
02643 } else
02644 break;
02645 }
02646 return 0;
02647 }
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662 static int iax2_queue_control_data(int callno,
02663 enum ast_control_frame_type control, const void *data, size_t datalen)
02664 {
02665 for (;;) {
02666 if (iaxs[callno] && iaxs[callno]->owner) {
02667 if (ast_channel_trylock(iaxs[callno]->owner)) {
02668
02669 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02670 } else {
02671 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02672 ast_channel_unlock(iaxs[callno]->owner);
02673 break;
02674 }
02675 } else
02676 break;
02677 }
02678 return 0;
02679 }
02680 static void destroy_firmware(struct iax_firmware *cur)
02681 {
02682
02683 if (cur->fwh) {
02684 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02685 }
02686 close(cur->fd);
02687 ast_free(cur);
02688 }
02689
02690 static int try_firmware(char *s)
02691 {
02692 struct stat stbuf;
02693 struct iax_firmware *cur = NULL;
02694 int ifd, fd, res, len, chunk;
02695 struct ast_iax2_firmware_header *fwh, fwh2;
02696 struct MD5Context md5;
02697 unsigned char sum[16], buf[1024];
02698 char *s2, *last;
02699
02700 if (!(s2 = alloca(strlen(s) + 100))) {
02701 ast_log(LOG_WARNING, "Alloca failed!\n");
02702 return -1;
02703 }
02704
02705 last = strrchr(s, '/');
02706 if (last)
02707 last++;
02708 else
02709 last = s;
02710
02711 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02712
02713 if ((res = stat(s, &stbuf) < 0)) {
02714 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02715 return -1;
02716 }
02717
02718
02719 if (S_ISDIR(stbuf.st_mode))
02720 return -1;
02721 ifd = open(s, O_RDONLY);
02722 if (ifd < 0) {
02723 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02724 return -1;
02725 }
02726 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02727 if (fd < 0) {
02728 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02729 close(ifd);
02730 return -1;
02731 }
02732
02733 unlink(s2);
02734
02735
02736 len = stbuf.st_size;
02737 while(len) {
02738 chunk = len;
02739 if (chunk > sizeof(buf))
02740 chunk = sizeof(buf);
02741 res = read(ifd, buf, chunk);
02742 if (res != chunk) {
02743 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02744 close(ifd);
02745 close(fd);
02746 return -1;
02747 }
02748 res = write(fd, buf, chunk);
02749 if (res != chunk) {
02750 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02751 close(ifd);
02752 close(fd);
02753 return -1;
02754 }
02755 len -= chunk;
02756 }
02757 close(ifd);
02758
02759 lseek(fd, 0, SEEK_SET);
02760 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02761 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02762 close(fd);
02763 return -1;
02764 }
02765 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02766 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02767 close(fd);
02768 return -1;
02769 }
02770 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02771 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02772 close(fd);
02773 return -1;
02774 }
02775 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02776 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02777 close(fd);
02778 return -1;
02779 }
02780 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
02781 if (fwh == MAP_FAILED) {
02782 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02783 close(fd);
02784 return -1;
02785 }
02786 MD5Init(&md5);
02787 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02788 MD5Final(sum, &md5);
02789 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02790 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02791 munmap((void*)fwh, stbuf.st_size);
02792 close(fd);
02793 return -1;
02794 }
02795
02796 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02797 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02798
02799 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02800
02801 break;
02802
02803
02804 munmap((void*)fwh, stbuf.st_size);
02805 close(fd);
02806 return 0;
02807 }
02808 }
02809
02810 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02811 cur->fd = -1;
02812 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02813 }
02814
02815 if (cur) {
02816 if (cur->fwh)
02817 munmap((void*)cur->fwh, cur->mmaplen);
02818 if (cur->fd > -1)
02819 close(cur->fd);
02820 cur->fwh = fwh;
02821 cur->fd = fd;
02822 cur->mmaplen = stbuf.st_size;
02823 cur->dead = 0;
02824 }
02825
02826 return 0;
02827 }
02828
02829 static int iax_check_version(char *dev)
02830 {
02831 int res = 0;
02832 struct iax_firmware *cur = NULL;
02833
02834 if (ast_strlen_zero(dev))
02835 return 0;
02836
02837 AST_LIST_LOCK(&firmwares);
02838 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02839 if (!strcmp(dev, (char *)cur->fwh->devname)) {
02840 res = ntohs(cur->fwh->version);
02841 break;
02842 }
02843 }
02844 AST_LIST_UNLOCK(&firmwares);
02845
02846 return res;
02847 }
02848
02849 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
02850 {
02851 int res = -1;
02852 unsigned int bs = desc & 0xff;
02853 unsigned int start = (desc >> 8) & 0xffffff;
02854 unsigned int bytes;
02855 struct iax_firmware *cur;
02856
02857 if (ast_strlen_zero((char *)dev) || !bs)
02858 return -1;
02859
02860 start *= bs;
02861
02862 AST_LIST_LOCK(&firmwares);
02863 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02864 if (strcmp((char *)dev, (char *)cur->fwh->devname))
02865 continue;
02866 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02867 if (start < ntohl(cur->fwh->datalen)) {
02868 bytes = ntohl(cur->fwh->datalen) - start;
02869 if (bytes > bs)
02870 bytes = bs;
02871 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02872 } else {
02873 bytes = 0;
02874 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02875 }
02876 if (bytes == bs)
02877 res = 0;
02878 else
02879 res = 1;
02880 break;
02881 }
02882 AST_LIST_UNLOCK(&firmwares);
02883
02884 return res;
02885 }
02886
02887
02888 static void reload_firmware(int unload)
02889 {
02890 struct iax_firmware *cur = NULL;
02891 DIR *fwd;
02892 struct dirent *de;
02893 char dir[256], fn[256];
02894
02895 AST_LIST_LOCK(&firmwares);
02896
02897
02898 AST_LIST_TRAVERSE(&firmwares, cur, list)
02899 cur->dead = 1;
02900
02901
02902 if (!unload) {
02903 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
02904 fwd = opendir(dir);
02905 if (fwd) {
02906 while((de = readdir(fwd))) {
02907 if (de->d_name[0] != '.') {
02908 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02909 if (!try_firmware(fn)) {
02910 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
02911 }
02912 }
02913 }
02914 closedir(fwd);
02915 } else
02916 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02917 }
02918
02919
02920 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
02921 if (!cur->dead)
02922 continue;
02923 AST_LIST_REMOVE_CURRENT(list);
02924 destroy_firmware(cur);
02925 }
02926 AST_LIST_TRAVERSE_SAFE_END;
02927
02928 AST_LIST_UNLOCK(&firmwares);
02929 }
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939 static int __do_deliver(void *data)
02940 {
02941
02942
02943 struct iax_frame *fr = data;
02944 fr->retrans = -1;
02945 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02946 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02947 iax2_queue_frame(fr->callno, &fr->af);
02948
02949 iax2_frame_free(fr);
02950
02951 return 0;
02952 }
02953
02954 static int handle_error(void)
02955 {
02956
02957
02958
02959 #if 0
02960 struct sockaddr_in *sin;
02961 int res;
02962 struct msghdr m;
02963 struct sock_extended_err e;
02964 m.msg_name = NULL;
02965 m.msg_namelen = 0;
02966 m.msg_iov = NULL;
02967 m.msg_control = &e;
02968 m.msg_controllen = sizeof(e);
02969 m.msg_flags = 0;
02970 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02971 if (res < 0)
02972 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02973 else {
02974 if (m.msg_controllen) {
02975 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02976 if (sin)
02977 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02978 else
02979 ast_log(LOG_WARNING, "No address detected??\n");
02980 } else {
02981 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02982 }
02983 }
02984 #endif
02985 return 0;
02986 }
02987
02988 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02989 {
02990 int res;
02991 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02992 sizeof(*sin));
02993 if (res < 0) {
02994 ast_debug(1, "Received error: %s\n", strerror(errno));
02995 handle_error();
02996 } else
02997 res = 0;
02998 return res;
02999 }
03000
03001 static int send_packet(struct iax_frame *f)
03002 {
03003 int res;
03004 int callno = f->callno;
03005
03006
03007 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03008 return -1;
03009
03010
03011 if (iaxdebug)
03012 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));
03013
03014 if (f->transfer) {
03015 if (iaxdebug)
03016 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03017 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03018 } else {
03019 if (iaxdebug)
03020 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03021 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03022 }
03023 if (res < 0) {
03024 if (iaxdebug)
03025 ast_debug(1, "Received error: %s\n", strerror(errno));
03026 handle_error();
03027 } else
03028 res = 0;
03029
03030 return res;
03031 }
03032
03033
03034
03035
03036
03037 static int iax2_predestroy(int callno)
03038 {
03039 struct ast_channel *c = NULL;
03040 struct chan_iax2_pvt *pvt = iaxs[callno];
03041
03042 if (!pvt)
03043 return -1;
03044
03045 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
03046 iax2_destroy_helper(pvt);
03047 ast_set_flag(pvt, IAX_ALREADYGONE);
03048 }
03049
03050 if ((c = pvt->owner)) {
03051 c->tech_pvt = NULL;
03052 iax2_queue_hangup(callno);
03053 pvt->owner = NULL;
03054 ast_module_unref(ast_module_info->self);
03055 }
03056
03057 return 0;
03058 }
03059
03060 static void iax2_destroy(int callno)
03061 {
03062 struct chan_iax2_pvt *pvt = NULL;
03063 struct ast_channel *owner = NULL;
03064
03065 retry:
03066 if ((pvt = iaxs[callno])) {
03067 iax2_destroy_helper(pvt);
03068 }
03069
03070 owner = pvt ? pvt->owner : NULL;
03071
03072 if (owner) {
03073 if (ast_channel_trylock(owner)) {
03074 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03075 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03076 goto retry;
03077 }
03078 }
03079
03080 if (!owner) {
03081 iaxs[callno] = NULL;
03082 }
03083
03084 if (pvt) {
03085 if (!owner) {
03086 pvt->owner = NULL;
03087 } else {
03088
03089
03090
03091 ast_queue_hangup(owner);
03092 }
03093
03094 if (pvt->peercallno) {
03095 remove_by_peercallno(pvt);
03096 }
03097
03098 if (pvt->transfercallno) {
03099 remove_by_transfercallno(pvt);
03100 }
03101
03102 if (!owner) {
03103 ao2_ref(pvt, -1);
03104 pvt = NULL;
03105 }
03106 }
03107
03108 if (owner) {
03109 ast_channel_unlock(owner);
03110 }
03111
03112 if (callno & 0x4000) {
03113 update_max_trunk();
03114 }
03115 }
03116
03117 static int update_packet(struct iax_frame *f)
03118 {
03119
03120 struct ast_iax2_full_hdr *fh = f->data;
03121 struct ast_frame af;
03122
03123
03124 if (f->encmethods) {
03125 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03126 }
03127
03128 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03129
03130 f->iseqno = iaxs[f->callno]->iseqno;
03131 fh->iseqno = f->iseqno;
03132
03133
03134 if (f->encmethods) {
03135
03136
03137 build_rand_pad(f->semirand, sizeof(f->semirand));
03138 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03139 }
03140 return 0;
03141 }
03142
03143 static int attempt_transmit(const void *data);
03144 static void __attempt_transmit(const void *data)
03145 {
03146
03147
03148 struct iax_frame *f = (struct iax_frame *)data;
03149 int freeme = 0;
03150 int callno = f->callno;
03151
03152 if (callno)
03153 ast_mutex_lock(&iaxsl[callno]);
03154 if (callno && iaxs[callno]) {
03155 if ((f->retries < 0) ||
03156 (f->retries >= max_retries) ) {
03157
03158 if (f->retries >= max_retries) {
03159 if (f->transfer) {
03160
03161 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03162 } else if (f->final) {
03163 if (f->final)
03164 iax2_destroy(callno);
03165 } else {
03166 if (iaxs[callno]->owner)
03167 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);
03168 iaxs[callno]->error = ETIMEDOUT;
03169 if (iaxs[callno]->owner) {
03170 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03171
03172 iax2_queue_frame(callno, &fr);
03173
03174 if (iaxs[callno] && iaxs[callno]->owner)
03175 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03176 } else {
03177 if (iaxs[callno]->reg) {
03178 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03179 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03180 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03181 }
03182 iax2_destroy(callno);
03183 }
03184 }
03185
03186 }
03187 freeme = 1;
03188 } else {
03189
03190 update_packet(f);
03191
03192 send_packet(f);
03193 f->retries++;
03194
03195 f->retrytime *= 10;
03196 if (f->retrytime > MAX_RETRY_TIME)
03197 f->retrytime = MAX_RETRY_TIME;
03198
03199 if (f->transfer && (f->retrytime > 1000))
03200 f->retrytime = 1000;
03201 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03202 }
03203 } else {
03204
03205 f->retries = -1;
03206 freeme = 1;
03207 }
03208 if (callno)
03209 ast_mutex_unlock(&iaxsl[callno]);
03210
03211 if (freeme) {
03212
03213 AST_LIST_LOCK(&frame_queue);
03214 AST_LIST_REMOVE(&frame_queue, f, list);
03215 AST_LIST_UNLOCK(&frame_queue);
03216 f->retrans = -1;
03217
03218 iax2_frame_free(f);
03219 }
03220 }
03221
03222 static int attempt_transmit(const void *data)
03223 {
03224 #ifdef SCHED_MULTITHREADED
03225 if (schedule_action(__attempt_transmit, data))
03226 #endif
03227 __attempt_transmit(data);
03228 return 0;
03229 }
03230
03231 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03232 {
03233 struct iax2_peer *peer = NULL;
03234 struct iax2_user *user = NULL;
03235
03236 switch (cmd) {
03237 case CLI_INIT:
03238 e->command = "iax2 prune realtime";
03239 e->usage =
03240 "Usage: iax2 prune realtime [<peername>|all]\n"
03241 " Prunes object(s) from the cache\n";
03242 return NULL;
03243 case CLI_GENERATE:
03244 if (a->pos == 3)
03245 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
03246 return NULL;
03247 }
03248 if (a->argc != 4)
03249 return CLI_SHOWUSAGE;
03250 if (!strcmp(a->argv[3], "all")) {
03251 prune_users();
03252 prune_peers();
03253 ast_cli(a->fd, "Cache flushed successfully.\n");
03254 return CLI_SUCCESS;
03255 }
03256 peer = find_peer(a->argv[3], 0);
03257 user = find_user(a->argv[3]);
03258 if (peer || user) {
03259 if (peer) {
03260 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
03261 ast_set_flag(peer, IAX_RTAUTOCLEAR);
03262 expire_registry(peer_ref(peer));
03263 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03264 } else {
03265 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03266 }
03267 peer_unref(peer);
03268 }
03269 if (user) {
03270 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
03271 ast_set_flag(user, IAX_RTAUTOCLEAR);
03272 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03273 } else {
03274 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03275 }
03276 ao2_unlink(users,user);
03277 user_unref(user);
03278 }
03279 } else {
03280 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03281 }
03282
03283 return CLI_SUCCESS;
03284 }
03285
03286 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03287 {
03288 switch (cmd) {
03289 case CLI_INIT:
03290 e->command = "iax2 test losspct";
03291 e->usage =
03292 "Usage: iax2 test losspct <percentage>\n"
03293 " For testing, throws away <percentage> percent of incoming packets\n";
03294 return NULL;
03295 case CLI_GENERATE:
03296 return NULL;
03297 }
03298 if (a->argc != 4)
03299 return CLI_SHOWUSAGE;
03300
03301 test_losspct = atoi(a->argv[3]);
03302
03303 return CLI_SUCCESS;
03304 }
03305
03306 #ifdef IAXTESTS
03307 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03308 {
03309 switch (cmd) {
03310 case CLI_INIT:
03311 e->command = "iax2 test late";
03312 e->usage =
03313 "Usage: iax2 test late <ms>\n"
03314 " For testing, count the next frame as <ms> ms late\n";
03315 return NULL;
03316 case CLI_GENERATE:
03317 return NULL;
03318 }
03319
03320 if (a->argc != 4)
03321 return CLI_SHOWUSAGE;
03322
03323 test_late = atoi(a->argv[3]);
03324
03325 return CLI_SUCCESS;
03326 }
03327
03328 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03329 {
03330 switch (cmd) {
03331 case CLI_INIT:
03332 e->command = "iax2 test resync";
03333 e->usage =
03334 "Usage: iax2 test resync <ms>\n"
03335 " For testing, adjust all future frames by <ms> ms\n";
03336 return NULL;
03337 case CLI_GENERATE:
03338 return NULL;
03339 }
03340
03341 if (a->argc != 4)
03342 return CLI_SHOWUSAGE;
03343
03344 test_resync = atoi(a->argv[3]);
03345
03346 return CLI_SUCCESS;
03347 }
03348
03349 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03350 {
03351 switch (cmd) {
03352 case CLI_INIT:
03353 e->command = "iax2 test jitter";
03354 e->usage =
03355 "Usage: iax2 test jitter <ms> <pct>\n"
03356 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03357 " percentage of packets. If <pct> is not specified, adds\n"
03358 " jitter to all packets.\n";
03359 return NULL;
03360 case CLI_GENERATE:
03361 return NULL;
03362 }
03363
03364 if (a->argc < 4 || a->argc > 5)
03365 return CLI_SHOWUSAGE;
03366
03367 test_jit = atoi(a->argv[3]);
03368 if (a->argc == 5)
03369 test_jitpct = atoi(a->argv[4]);
03370
03371 return CLI_SUCCESS;
03372 }
03373 #endif
03374
03375
03376
03377 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03378 {
03379 int res = 0;
03380 if (peer->maxms) {
03381 if (peer->lastms < 0) {
03382 ast_copy_string(status, "UNREACHABLE", statuslen);
03383 } else if (peer->lastms > peer->maxms) {
03384 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03385 res = 1;
03386 } else if (peer->lastms) {
03387 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03388 res = 1;
03389 } else {
03390 ast_copy_string(status, "UNKNOWN", statuslen);
03391 }
03392 } else {
03393 ast_copy_string(status, "Unmonitored", statuslen);
03394 res = -1;
03395 }
03396 return res;
03397 }
03398
03399
03400 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03401 {
03402 char status[30];
03403 char cbuf[256];
03404 struct iax2_peer *peer;
03405 char codec_buf[512];
03406 int x = 0, codec = 0, load_realtime = 0;
03407
03408 switch (cmd) {
03409 case CLI_INIT:
03410 e->command = "iax2 show peer";
03411 e->usage =
03412 "Usage: iax2 show peer <name>\n"
03413 " Display details on specific IAX peer\n";
03414 return NULL;
03415 case CLI_GENERATE:
03416 if (a->pos == 3)
03417 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
03418 return NULL;
03419 }
03420
03421 if (a->argc < 4)
03422 return CLI_SHOWUSAGE;
03423
03424 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03425
03426 peer = find_peer(a->argv[3], load_realtime);
03427 if (peer) {
03428 ast_cli(a->fd, "\n\n");
03429 ast_cli(a->fd, " * Name : %s\n", peer->name);
03430 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03431 ast_cli(a->fd, " Context : %s\n", peer->context);
03432 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03433 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03434 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
03435 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03436 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03437 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
03438 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03439 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03440 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03441 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));
03442 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03443 ast_cli(a->fd, " Username : %s\n", peer->username);
03444 ast_cli(a->fd, " Codecs : ");
03445 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03446 ast_cli(a->fd, "%s\n", codec_buf);
03447
03448 ast_cli(a->fd, " Codec Order : (");
03449 for(x = 0; x < 32 ; x++) {
03450 codec = ast_codec_pref_index(&peer->prefs,x);
03451 if(!codec)
03452 break;
03453 ast_cli(a->fd, "%s", ast_getformatname(codec));
03454 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03455 ast_cli(a->fd, "|");
03456 }
03457
03458 if (!x)
03459 ast_cli(a->fd, "none");
03460 ast_cli(a->fd, ")\n");
03461
03462 ast_cli(a->fd, " Status : ");
03463 peer_status(peer, status, sizeof(status));
03464 ast_cli(a->fd, "%s\n",status);
03465 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");
03466 ast_cli(a->fd, "\n");
03467 peer_unref(peer);
03468 } else {
03469 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03470 ast_cli(a->fd, "\n");
03471 }
03472
03473 return CLI_SUCCESS;
03474 }
03475
03476 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state)
03477 {
03478 int which = 0;
03479 struct iax2_peer *peer;
03480 char *res = NULL;
03481 int wordlen = strlen(word);
03482 struct ao2_iterator i;
03483
03484 i = ao2_iterator_init(peers, 0);
03485 while ((peer = ao2_iterator_next(&i))) {
03486 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
03487 res = ast_strdup(peer->name);
03488 peer_unref(peer);
03489 break;
03490 }
03491 peer_unref(peer);
03492 }
03493
03494 return res;
03495 }
03496
03497 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03498 {
03499 struct iax_frame *cur;
03500 int cnt = 0, dead = 0, final = 0;
03501
03502 switch (cmd) {
03503 case CLI_INIT:
03504 e->command = "iax2 show stats";
03505 e->usage =
03506 "Usage: iax2 show stats\n"
03507 " Display statistics on IAX channel driver.\n";
03508 return NULL;
03509 case CLI_GENERATE:
03510 return NULL;
03511 }
03512
03513 if (a->argc != 3)
03514 return CLI_SHOWUSAGE;
03515
03516 AST_LIST_LOCK(&frame_queue);
03517 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
03518 if (cur->retries < 0)
03519 dead++;
03520 if (cur->final)
03521 final++;
03522 cnt++;
03523 }
03524 AST_LIST_UNLOCK(&frame_queue);
03525
03526 ast_cli(a->fd, " IAX Statistics\n");
03527 ast_cli(a->fd, "---------------------\n");
03528 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03529 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03530 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03531 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03532
03533 trunk_timed = trunk_untimed = 0;
03534 if (trunk_maxmtu > trunk_nmaxmtu)
03535 trunk_nmaxmtu = trunk_maxmtu;
03536
03537 return CLI_SUCCESS;
03538 }
03539
03540
03541 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03542 {
03543 int mtuv;
03544
03545 switch (cmd) {
03546 case CLI_INIT:
03547 e->command = "iax2 set mtu";
03548 e->usage =
03549 "Usage: iax2 set mtu <value>\n"
03550 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03551 " zero to disable. Disabling means that the operating system\n"
03552 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03553 " packet exceeds the UDP payload size. This is substantially\n"
03554 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03555 " greater for G.711 samples.\n";
03556 return NULL;
03557 case CLI_GENERATE:
03558 return NULL;
03559 }
03560
03561 if (a->argc != 4)
03562 return CLI_SHOWUSAGE;
03563 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03564 mtuv = MAX_TRUNK_MTU;
03565 else
03566 mtuv = atoi(a->argv[3]);
03567
03568 if (mtuv == 0) {
03569 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03570 global_max_trunk_mtu = 0;
03571 return CLI_SUCCESS;
03572 }
03573 if (mtuv < 172 || mtuv > 4000) {
03574 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03575 return CLI_SHOWUSAGE;
03576 }
03577 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03578 global_max_trunk_mtu = mtuv;
03579 return CLI_SUCCESS;
03580 }
03581
03582 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03583 {
03584 struct iax2_dpcache *dp = NULL;
03585 char tmp[1024], *pc = NULL;
03586 int s, x, y;
03587 struct timeval now = ast_tvnow();
03588
03589 switch (cmd) {
03590 case CLI_INIT:
03591 e->command = "iax2 show cache";
03592 e->usage =
03593 "Usage: iax2 show cache\n"
03594 " Display currently cached IAX Dialplan results.\n";
03595 return NULL;
03596 case CLI_GENERATE:
03597 return NULL;
03598 }
03599
03600 AST_LIST_LOCK(&dpcache);
03601
03602 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03603
03604 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03605 s = dp->expiry.tv_sec - now.tv_sec;
03606 tmp[0] = '\0';
03607 if (dp->flags & CACHE_FLAG_EXISTS)
03608 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03609 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03610 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03611 if (dp->flags & CACHE_FLAG_CANEXIST)
03612 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03613 if (dp->flags & CACHE_FLAG_PENDING)
03614 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03615 if (dp->flags & CACHE_FLAG_TIMEOUT)
03616 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03617 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03618 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03619 if (dp->flags & CACHE_FLAG_MATCHMORE)
03620 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03621 if (dp->flags & CACHE_FLAG_UNKNOWN)
03622 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03623
03624 if (!ast_strlen_zero(tmp)) {
03625 tmp[strlen(tmp) - 1] = '\0';
03626 } else {
03627 ast_copy_string(tmp, "(none)", sizeof(tmp));
03628 }
03629 y = 0;
03630 pc = strchr(dp->peercontext, '@');
03631 if (!pc) {
03632 pc = dp->peercontext;
03633 } else {
03634 pc++;
03635 }
03636 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03637 if (dp->waiters[x] > -1)
03638 y++;
03639 }
03640 if (s > 0) {
03641 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03642 } else {
03643 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03644 }
03645 }
03646
03647 AST_LIST_LOCK(&dpcache);
03648
03649 return CLI_SUCCESS;
03650 }
03651
03652 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03653
03654 static void unwrap_timestamp(struct iax_frame *fr)
03655 {
03656
03657
03658 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03659 const int lower_mask = (1 << ts_shift) - 1;
03660 const int upper_mask = ~lower_mask;
03661 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03662
03663 if ( (fr->ts & upper_mask) == last_upper ) {
03664 const int x = fr->ts - iaxs[fr->callno]->last;
03665 const int threshold = (ts_shift == 15) ? 25000 : 50000;
03666
03667 if (x < -threshold) {
03668
03669
03670
03671
03672 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
03673 if (iaxdebug)
03674 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
03675 } else if (x > threshold) {
03676
03677
03678
03679
03680 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03681 if (iaxdebug)
03682 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
03683 }
03684 }
03685 }
03686
03687 static int get_from_jb(const void *p);
03688
03689 static void update_jbsched(struct chan_iax2_pvt *pvt)
03690 {
03691 int when;
03692
03693 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03694
03695 when = jb_next(pvt->jb) - when;
03696
03697 if (when <= 0) {
03698
03699 when = 1;
03700 }
03701
03702 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
03703 CALLNO_TO_PTR(pvt->callno));
03704 }
03705
03706 static void __get_from_jb(const void *p)
03707 {
03708 int callno = PTR_TO_CALLNO(p);
03709 struct chan_iax2_pvt *pvt = NULL;
03710 struct iax_frame *fr;
03711 jb_frame frame;
03712 int ret;
03713 long ms;
03714 long next;
03715 struct timeval now = ast_tvnow();
03716
03717
03718 ast_mutex_lock(&iaxsl[callno]);
03719 pvt = iaxs[callno];
03720 if (!pvt) {
03721
03722 ast_mutex_unlock(&iaxsl[callno]);
03723 return;
03724 }
03725
03726 pvt->jbid = -1;
03727
03728
03729
03730
03731 now.tv_usec += 1000;
03732
03733 ms = ast_tvdiff_ms(now, pvt->rxcore);
03734
03735 if(ms >= (next = jb_next(pvt->jb))) {
03736 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
03737 switch(ret) {
03738 case JB_OK:
03739 fr = frame.data;
03740 __do_deliver(fr);
03741
03742 pvt = iaxs[callno];
03743 break;
03744 case JB_INTERP:
03745 {
03746 struct ast_frame af = { 0, };
03747
03748
03749 af.frametype = AST_FRAME_VOICE;
03750 af.subclass = pvt->voiceformat;
03751 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03752 af.src = "IAX2 JB interpolation";
03753 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03754 af.offset = AST_FRIENDLY_OFFSET;
03755
03756
03757
03758 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03759 iax2_queue_frame(callno, &af);
03760
03761 pvt = iaxs[callno];
03762 }
03763 }
03764 break;
03765 case JB_DROP:
03766 iax2_frame_free(frame.data);
03767 break;
03768 case JB_NOFRAME:
03769 case JB_EMPTY:
03770
03771 break;
03772 default:
03773
03774 break;
03775 }
03776 }
03777 if (pvt)
03778 update_jbsched(pvt);
03779 ast_mutex_unlock(&iaxsl[callno]);
03780 }
03781
03782 static int get_from_jb(const void *data)
03783 {
03784 #ifdef SCHED_MULTITHREADED
03785 if (schedule_action(__get_from_jb, data))
03786 #endif
03787 __get_from_jb(data);
03788 return 0;
03789 }
03790
03791
03792
03793
03794
03795
03796
03797 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03798 {
03799 int type, len;
03800 int ret;
03801 int needfree = 0;
03802 struct ast_channel *owner = NULL;
03803 struct ast_channel *bridge = NULL;
03804
03805
03806 unwrap_timestamp(fr);
03807
03808
03809 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03810 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03811 else {
03812 #if 0
03813 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03814 #endif
03815 fr->af.delivery = ast_tv(0,0);
03816 }
03817
03818 type = JB_TYPE_CONTROL;
03819 len = 0;
03820
03821 if(fr->af.frametype == AST_FRAME_VOICE) {
03822 type = JB_TYPE_VOICE;
03823 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
03824 } else if(fr->af.frametype == AST_FRAME_CNG) {
03825 type = JB_TYPE_SILENCE;
03826 }
03827
03828 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03829 if (tsout)
03830 *tsout = fr->ts;
03831 __do_deliver(fr);
03832 return -1;
03833 }
03834
03835 if ((owner = iaxs[fr->callno]->owner))
03836 bridge = ast_bridged_channel(owner);
03837
03838
03839
03840 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03841 jb_frame frame;
03842
03843
03844 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03845 __do_deliver(frame.data);
03846
03847 if (!iaxs[fr->callno])
03848 return -1;
03849 }
03850
03851 jb_reset(iaxs[fr->callno]->jb);
03852
03853 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03854
03855
03856 if (tsout)
03857 *tsout = fr->ts;
03858 __do_deliver(fr);
03859 return -1;
03860 }
03861
03862
03863
03864 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03865 calc_rxstamp(iaxs[fr->callno],fr->ts));
03866 if (ret == JB_DROP) {
03867 needfree++;
03868 } else if (ret == JB_SCHED) {
03869 update_jbsched(iaxs[fr->callno]);
03870 }
03871 if (tsout)
03872 *tsout = fr->ts;
03873 if (needfree) {
03874
03875 iax2_frame_free(fr);
03876 return -1;
03877 }
03878 return 0;
03879 }
03880
03881 static int iax2_transmit(struct iax_frame *fr)
03882 {
03883
03884
03885
03886 fr->sentyet = 0;
03887 AST_LIST_LOCK(&frame_queue);
03888 AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
03889 AST_LIST_UNLOCK(&frame_queue);
03890
03891 if (netthreadid != AST_PTHREADT_NULL)
03892 pthread_kill(netthreadid, SIGURG);
03893 signal_condition(&sched_lock, &sched_cond);
03894 return 0;
03895 }
03896
03897
03898
03899 static int iax2_digit_begin(struct ast_channel *c, char digit)
03900 {
03901 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03902 }
03903
03904 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
03905 {
03906 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03907 }
03908
03909 static int iax2_sendtext(struct ast_channel *c, const char *text)
03910 {
03911
03912 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03913 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03914 }
03915
03916 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
03917 {
03918 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1);
03919 }
03920
03921 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
03922 {
03923 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03924 }
03925
03926 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
03927 {
03928 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
03929 ast_mutex_lock(&iaxsl[callno]);
03930 if (iaxs[callno])
03931 iaxs[callno]->owner = newchan;
03932 else
03933 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
03934 ast_mutex_unlock(&iaxsl[callno]);
03935 return 0;
03936 }
03937
03938
03939
03940
03941
03942 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
03943 {
03944 struct ast_variable *var = NULL;
03945 struct ast_variable *tmp;
03946 struct iax2_peer *peer=NULL;
03947 time_t regseconds = 0, nowtime;
03948 int dynamic=0;
03949
03950 if (peername) {
03951 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
03952 if (!var && sin)
03953 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
03954 } else if (sin) {
03955 char porta[25];
03956 sprintf(porta, "%d", ntohs(sin->sin_port));
03957 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
03958 if (var) {
03959
03960 for (tmp = var; tmp; tmp = tmp->next) {
03961 if (!strcasecmp(tmp->name, "name"))
03962 peername = tmp->value;
03963 }
03964 }
03965 }
03966 if (!var && peername) {
03967 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
03968
03969
03970
03971
03972
03973
03974 if (var && sin) {
03975 for (tmp = var; tmp; tmp = tmp->next) {
03976 if (!strcasecmp(tmp->name, "host")) {
03977 struct ast_hostent ahp;
03978 struct hostent *hp;
03979 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03980
03981 ast_variables_destroy(var);
03982 var = NULL;
03983 }
03984 break;
03985 }
03986 }
03987 }
03988 }
03989 if (!var)
03990 return NULL;
03991
03992 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
03993
03994 if (!peer) {
03995 ast_variables_destroy(var);
03996 return NULL;
03997 }
03998
03999 for (tmp = var; tmp; tmp = tmp->next) {
04000
04001 if (!strcasecmp(tmp->name, "type")) {
04002 if (strcasecmp(tmp->value, "friend") &&
04003 strcasecmp(tmp->value, "peer")) {
04004
04005 peer = peer_unref(peer);
04006 break;
04007 }
04008 } else if (!strcasecmp(tmp->name, "regseconds")) {
04009 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04010 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04011 inet_aton(tmp->value, &(peer->addr.sin_addr));
04012 } else if (!strcasecmp(tmp->name, "port")) {
04013 peer->addr.sin_port = htons(atoi(tmp->value));
04014 } else if (!strcasecmp(tmp->name, "host")) {
04015 if (!strcasecmp(tmp->value, "dynamic"))
04016 dynamic = 1;
04017 }
04018 }
04019
04020 ast_variables_destroy(var);
04021
04022 if (!peer)
04023 return NULL;
04024
04025 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04026 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04027 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
04028 if (peer->expire > -1) {
04029 if (!ast_sched_del(sched, peer->expire)) {
04030 peer->expire = -1;
04031 peer_unref(peer);
04032 }
04033 }
04034 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04035 if (peer->expire == -1)
04036 peer_unref(peer);
04037 }
04038 ao2_link(peers, peer);
04039 if (ast_test_flag(peer, IAX_DYNAMIC))
04040 reg_source_db(peer);
04041 } else {
04042 ast_set_flag(peer, IAX_TEMPONLY);
04043 }
04044
04045 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04046 time(&nowtime);
04047 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04048 memset(&peer->addr, 0, sizeof(peer->addr));
04049 realtime_update_peer(peer->name, &peer->addr, 0);
04050 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04051 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04052 }
04053 else {
04054 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04055 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04056 }
04057 }
04058
04059 return peer;
04060 }
04061
04062 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04063 {
04064 struct ast_variable *var;
04065 struct ast_variable *tmp;
04066 struct iax2_user *user=NULL;
04067
04068 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04069 if (!var)
04070 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04071 if (!var && sin) {
04072 char porta[6];
04073 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04074 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04075 if (!var)
04076 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04077 }
04078 if (!var) {
04079 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04080
04081
04082
04083
04084
04085
04086 if (var) {
04087 for (tmp = var; tmp; tmp = tmp->next) {
04088 if (!strcasecmp(tmp->name, "host")) {
04089 struct ast_hostent ahp;
04090 struct hostent *hp;
04091 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04092
04093 ast_variables_destroy(var);
04094 var = NULL;
04095 }
04096 break;
04097 }
04098 }
04099 }
04100 }
04101 if (!var)
04102 return NULL;
04103
04104 tmp = var;
04105 while(tmp) {
04106
04107 if (!strcasecmp(tmp->name, "type")) {
04108 if (strcasecmp(tmp->value, "friend") &&
04109 strcasecmp(tmp->value, "user")) {
04110 return NULL;
04111 }
04112 }
04113 tmp = tmp->next;
04114 }
04115
04116 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
04117
04118 ast_variables_destroy(var);
04119
04120 if (!user)
04121 return NULL;
04122
04123 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04124 ast_set_flag(user, IAX_RTCACHEFRIENDS);
04125 ao2_link(users, user);
04126 } else {
04127 ast_set_flag(user, IAX_TEMPONLY);
04128 }
04129
04130 return user;
04131 }
04132
04133 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
04134 {
04135 char port[10];
04136 char regseconds[20];
04137
04138 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04139 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
04140 ast_update_realtime("iaxpeers", "name", peername,
04141 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
04142 "regseconds", regseconds, SENTINEL);
04143 }
04144
04145 struct create_addr_info {
04146 int capability;
04147 unsigned int flags;
04148 int maxtime;
04149 int encmethods;
04150 int found;
04151 int sockfd;
04152 int adsi;
04153 char username[80];
04154 char secret[80];
04155 char outkey[80];
04156 char timezone[80];
04157 char prefs[32];
04158 char context[AST_MAX_CONTEXT];
04159 char peercontext[AST_MAX_CONTEXT];
04160 char mohinterpret[MAX_MUSICCLASS];
04161 char mohsuggest[MAX_MUSICCLASS];
04162 };
04163
04164 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04165 {
04166 struct iax2_peer *peer;
04167 int res = -1;
04168 struct ast_codec_pref ourprefs;
04169
04170 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
04171 cai->sockfd = defaultsockfd;
04172 cai->maxtime = 0;
04173 sin->sin_family = AF_INET;
04174
04175 if (!(peer = find_peer(peername, 1))) {
04176 cai->found = 0;
04177 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
04178 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04179 return -1;
04180 }
04181 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04182
04183
04184 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04185 if (c)
04186 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04187 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04188 return 0;
04189 }
04190
04191 cai->found = 1;
04192
04193
04194 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
04195 goto return_unref;
04196
04197
04198 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04199 goto return_unref;
04200
04201 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
04202 cai->maxtime = peer->maxms;
04203 cai->capability = peer->capability;
04204 cai->encmethods = peer->encmethods;
04205 cai->sockfd = peer->sockfd;
04206 cai->adsi = peer->adsi;
04207 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04208
04209 if (c) {
04210 ast_debug(1, "prepending %x to prefs\n", c->nativeformats);
04211 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04212 }
04213 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04214 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04215 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04216 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04217 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04218 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04219 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04220 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04221 if (ast_strlen_zero(peer->dbsecret)) {
04222 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04223 } else {
04224 char *family;
04225 char *key = NULL;
04226
04227 family = ast_strdupa(peer->dbsecret);
04228 key = strchr(family, '/');
04229 if (key)
04230 *key++ = '\0';
04231 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04232 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04233 goto return_unref;
04234 }
04235 }
04236
04237 if (peer->addr.sin_addr.s_addr) {
04238 sin->sin_addr = peer->addr.sin_addr;
04239 sin->sin_port = peer->addr.sin_port;
04240 } else {
04241 sin->sin_addr = peer->defaddr.sin_addr;
04242 sin->sin_port = peer->defaddr.sin_port;
04243 }
04244
04245 res = 0;
04246
04247 return_unref:
04248 peer_unref(peer);
04249
04250 return res;
04251 }
04252
04253 static void __auto_congest(const void *nothing)
04254 {
04255 int callno = PTR_TO_CALLNO(nothing);
04256 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
04257 ast_mutex_lock(&iaxsl[callno]);
04258 if (iaxs[callno]) {
04259 iaxs[callno]->initid = -1;
04260 iax2_queue_frame(callno, &f);
04261 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04262 }
04263 ast_mutex_unlock(&iaxsl[callno]);
04264 }
04265
04266 static int auto_congest(const void *data)
04267 {
04268 #ifdef SCHED_MULTITHREADED
04269 if (schedule_action(__auto_congest, data))
04270 #endif
04271 __auto_congest(data);
04272 return 0;
04273 }
04274
04275 static unsigned int iax2_datetime(const char *tz)
04276 {
04277 struct timeval t = ast_tvnow();
04278 struct ast_tm tm;
04279 unsigned int tmp;
04280 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04281 tmp = (tm.tm_sec >> 1) & 0x1f;
04282 tmp |= (tm.tm_min & 0x3f) << 5;
04283 tmp |= (tm.tm_hour & 0x1f) << 11;
04284 tmp |= (tm.tm_mday & 0x1f) << 16;
04285 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04286 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04287 return tmp;
04288 }
04289
04290 struct parsed_dial_string {
04291 char *username;
04292 char *password;
04293 char *key;
04294 char *peer;
04295 char *port;
04296 char *exten;
04297 char *context;
04298 char *options;
04299 };
04300
04301 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04302 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04303 int sockfd, struct iax_ie_data *ied)
04304 {
04305 struct {
04306 struct ast_iax2_full_hdr f;
04307 struct iax_ie_data ied;
04308 } data;
04309 size_t size = sizeof(struct ast_iax2_full_hdr);
04310
04311 if (ied) {
04312 size += ied->pos;
04313 memcpy(&data.ied, ied->buf, ied->pos);
04314 }
04315
04316 data.f.scallno = htons(0x8000 | callno);
04317 data.f.dcallno = htons(dcallno);
04318 data.f.ts = htonl(ts);
04319 data.f.iseqno = seqno;
04320 data.f.oseqno = 0;
04321 data.f.type = AST_FRAME_IAX;
04322 data.f.csub = compress_subclass(command);
04323
04324 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04325 }
04326
04327 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04328 {
04329
04330 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04331 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04332 ied->buf[ied->pos++] = 0;
04333 pvt->calltoken_ie_len = 2;
04334 }
04335 }
04336
04337 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04338 {
04339 struct chan_iax2_pvt *pvt = iaxs[callno];
04340 int frametype = f->af.frametype;
04341 int subclass = f->af.subclass;
04342 struct {
04343 struct ast_iax2_full_hdr fh;
04344 struct iax_ie_data ied;
04345 } data = {
04346 .ied.buf = { 0 },
04347 .ied.pos = 0,
04348 };
04349
04350 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04351
04352 if (!pvt) {
04353 return;
04354 }
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04368 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04369 (f->datalen > sizeof(data))) {
04370
04371 return;
04372 }
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388 memcpy(&data, f->data, f->datalen);
04389 data.ied.pos = ie_data_pos;
04390
04391
04392
04393 data.ied.pos -= pvt->calltoken_ie_len;
04394 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04395
04396
04397 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04398
04399
04400 AST_LIST_LOCK(&frame_queue);
04401 AST_LIST_REMOVE(&frame_queue, f, list);
04402 AST_LIST_UNLOCK(&frame_queue);
04403
04404
04405 iax2_frame_free(f);
04406
04407
04408 pvt->oseqno = 0;
04409 pvt->rseqno = 0;
04410 pvt->iseqno = 0;
04411 pvt->aseqno = 0;
04412 if (pvt->peercallno) {
04413 remove_by_peercallno(pvt);
04414 pvt->peercallno = 0;
04415 }
04416
04417
04418 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04419 }
04420
04421 static void requirecalltoken_mark_auto(const char *name, int subclass)
04422 {
04423 struct iax2_user *user = NULL;
04424 struct iax2_peer *peer = NULL;
04425
04426 if (ast_strlen_zero(name)) {
04427 return;
04428 }
04429
04430 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04431 user->calltoken_required = CALLTOKEN_YES;
04432 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04433 peer->calltoken_required = CALLTOKEN_YES;
04434 }
04435
04436 if (peer) {
04437 peer_unref(peer);
04438 }
04439 if (user) {
04440 user_unref(user);
04441 }
04442 }
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04462 struct sockaddr_in *sin, int fd)
04463 {
04464 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04465 #define CALLTOKEN_IE_FORMAT "%u?%s"
04466 struct ast_str *buf = ast_str_alloca(256);
04467 time_t t = time(NULL);
04468 char hash[41];
04469 int subclass = uncompress_subclass(fh->csub);
04470
04471
04472 if (ies->calltoken && !ies->calltokendata) {
04473 struct iax_ie_data ied = {
04474 .buf = { 0 },
04475 .pos = 0,
04476 };
04477
04478
04479 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04480 ast_sha1_hash(hash, ast_str_buffer(buf));
04481
04482 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04483 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04484 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04485
04486 return 1;
04487
04488
04489 } else if (ies->calltoken && ies->calltokendata) {
04490 char *rec_hash = NULL;
04491 char *rec_ts = NULL;
04492 unsigned int rec_time;
04493
04494
04495 rec_hash = strchr((char *) ies->calltokendata, '?');
04496 if (rec_hash) {
04497 *rec_hash++ = '\0';
04498 rec_ts = (char *) ies->calltokendata;
04499 }
04500
04501
04502 if (!rec_hash || !rec_ts) {
04503 goto reject;
04504 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04505 goto reject;
04506 }
04507
04508
04509 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04510 ast_sha1_hash(hash, ast_str_buffer(buf));
04511
04512
04513 if (strcmp(hash, rec_hash)) {
04514 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04515 goto reject;
04516 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04517 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04518 goto reject;
04519 }
04520
04521
04522
04523 requirecalltoken_mark_auto(ies->username, subclass);
04524 return 0;
04525
04526
04527 } else {
04528 if (calltoken_required(sin, ies->username, subclass)) {
04529 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenignore list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), ies->username);
04530 goto reject;
04531 }
04532 return 0;
04533 }
04534
04535 reject:
04536
04537 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04538 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04539 } else {
04540 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04541 }
04542
04543 return 1;
04544 }
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04565 {
04566 if (ast_strlen_zero(data))
04567 return;
04568
04569 pds->peer = strsep(&data, "/");
04570 pds->exten = strsep(&data, "/");
04571 pds->options = data;
04572
04573 if (pds->exten) {
04574 data = pds->exten;
04575 pds->exten = strsep(&data, "@");
04576 pds->context = data;
04577 }
04578
04579 if (strchr(pds->peer, '@')) {
04580 data = pds->peer;
04581 pds->username = strsep(&data, "@");
04582 pds->peer = data;
04583 }
04584
04585 if (pds->username) {
04586 data = pds->username;
04587 pds->username = strsep(&data, ":");
04588 pds->password = data;
04589 }
04590
04591 data = pds->peer;
04592 pds->peer = strsep(&data, ":");
04593 pds->port = data;
04594
04595
04596
04597
04598 if (pds->password && (pds->password[0] == '[')) {
04599 pds->key = ast_strip_quoted(pds->password, "[", "]");
04600 pds->password = NULL;
04601 }
04602 }
04603
04604 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04605 {
04606 struct sockaddr_in sin;
04607 char *l=NULL, *n=NULL, *tmpstr;
04608 struct iax_ie_data ied;
04609 char *defaultrdest = "s";
04610 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04611 struct parsed_dial_string pds;
04612 struct create_addr_info cai;
04613 struct ast_var_t *var;
04614 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04615 const char* osp_token_ptr;
04616 unsigned int osp_token_length;
04617 unsigned char osp_block_index;
04618 unsigned int osp_block_length;
04619 unsigned char osp_buffer[256];
04620
04621 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
04622 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
04623 return -1;
04624 }
04625
04626 memset(&cai, 0, sizeof(cai));
04627 cai.encmethods = iax2_encryption;
04628
04629 memset(&pds, 0, sizeof(pds));
04630 tmpstr = ast_strdupa(dest);
04631 parse_dial_string(tmpstr, &pds);
04632
04633 if (ast_strlen_zero(pds.peer)) {
04634 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
04635 return -1;
04636 }
04637
04638 if (!pds.exten) {
04639 pds.exten = defaultrdest;
04640 }
04641
04642 if (create_addr(pds.peer, c, &sin, &cai)) {
04643 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
04644 return -1;
04645 }
04646
04647 if (!pds.username && !ast_strlen_zero(cai.username))
04648 pds.username = cai.username;
04649 if (!pds.password && !ast_strlen_zero(cai.secret))
04650 pds.password = cai.secret;
04651 if (!pds.key && !ast_strlen_zero(cai.outkey))
04652 pds.key = cai.outkey;
04653 if (!pds.context && !ast_strlen_zero(cai.peercontext))
04654 pds.context = cai.peercontext;
04655
04656
04657 ast_copy_string(c->context, cai.context, sizeof(c->context));
04658
04659 if (pds.port)
04660 sin.sin_port = htons(atoi(pds.port));
04661
04662 l = c->cid.cid_num;
04663 n = c->cid.cid_name;
04664
04665
04666 memset(&ied, 0, sizeof(ied));
04667
04668
04669 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
04670 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
04671 if (pds.options && strchr(pds.options, 'a')) {
04672
04673 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
04674 }
04675
04676 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
04677
04678 if (l) {
04679 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
04680 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04681 } else {
04682 if (n)
04683 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04684 else
04685 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
04686 }
04687
04688 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
04689 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
04690
04691 if (n)
04692 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
04693 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
04694 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
04695
04696 if (!ast_strlen_zero(c->language))
04697 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
04698 if (!ast_strlen_zero(c->cid.cid_dnid))
04699 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
04700 if (!ast_strlen_zero(c->cid.cid_rdnis))
04701 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
04702
04703 if (pds.context)
04704 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
04705
04706 if (pds.username)
04707 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
04708
04709 if (cai.encmethods)
04710 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
04711
04712 ast_mutex_lock(&iaxsl[callno]);
04713
04714 if (!ast_strlen_zero(c->context))
04715 ast_string_field_set(iaxs[callno], context, c->context);
04716
04717 if (pds.username)
04718 ast_string_field_set(iaxs[callno], username, pds.username);
04719
04720 iaxs[callno]->encmethods = cai.encmethods;
04721
04722 iaxs[callno]->adsi = cai.adsi;
04723
04724 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
04725 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
04726
04727 if (pds.key)
04728 ast_string_field_set(iaxs[callno], outkey, pds.key);
04729 if (pds.password)
04730 ast_string_field_set(iaxs[callno], secret, pds.password);
04731
04732 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
04733 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
04734 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
04735 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
04736
04737 if (iaxs[callno]->maxtime) {
04738
04739 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
04740 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
04741 } else if (autokill) {
04742 iaxs[callno]->pingtime = autokill / 2;
04743 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
04744 }
04745
04746
04747 osp_token_ptr = iaxs[callno]->osptoken;
04748 if (!ast_strlen_zero(osp_token_ptr)) {
04749 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
04750 osp_block_index = 0;
04751 while (osp_token_length > 0) {
04752 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
04753 osp_buffer[0] = osp_block_index;
04754 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
04755 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
04756 osp_block_index++;
04757 osp_token_ptr += osp_block_length;
04758 osp_token_length -= osp_block_length;
04759 }
04760 } else
04761 ast_log(LOG_WARNING, "OSP token is too long\n");
04762 } else if (iaxdebug)
04763 ast_debug(1, "OSP token is undefined\n");
04764
04765
04766 iaxs[callno]->sockfd = cai.sockfd;
04767
04768
04769 if (variablestore) {
04770 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
04771 ast_debug(1, "Found an IAX variable store on this channel\n");
04772 AST_LIST_LOCK(variablelist);
04773 AST_LIST_TRAVERSE(variablelist, var, entries) {
04774 char tmp[256];
04775 int i;
04776 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
04777
04778 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
04779 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
04780 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
04781 }
04782 }
04783 AST_LIST_UNLOCK(variablelist);
04784 }
04785
04786
04787 add_empty_calltoken_ie(iaxs[callno], &ied);
04788 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
04789
04790 ast_mutex_unlock(&iaxsl[callno]);
04791 ast_setstate(c, AST_STATE_RINGING);
04792
04793 return 0;
04794 }
04795
04796 static int iax2_hangup(struct ast_channel *c)
04797 {
04798 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04799 struct iax_ie_data ied;
04800 int alreadygone;
04801 memset(&ied, 0, sizeof(ied));
04802 ast_mutex_lock(&iaxsl[callno]);
04803 if (callno && iaxs[callno]) {
04804 ast_debug(1, "We're hanging up %s now...\n", c->name);
04805 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
04806
04807 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
04808 if (!iaxs[callno]->error && !alreadygone) {
04809 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
04810 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
04811 }
04812 if (!iaxs[callno]) {
04813 ast_mutex_unlock(&iaxsl[callno]);
04814 return 0;
04815 }
04816 }
04817
04818 iax2_predestroy(callno);
04819
04820 if (iaxs[callno] && alreadygone) {
04821 ast_debug(1, "Really destroying %s now...\n", c->name);
04822 iax2_destroy(callno);
04823 } else if (iaxs[callno]) {
04824 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
04825 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
04826 iax2_destroy(callno);
04827 }
04828 }
04829 } else if (c->tech_pvt) {
04830
04831
04832
04833
04834 c->tech_pvt = NULL;
04835 }
04836 ast_mutex_unlock(&iaxsl[callno]);
04837 ast_verb(3, "Hungup '%s'\n", c->name);
04838 return 0;
04839 }
04840
04841
04842
04843
04844 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
04845 {
04846 unsigned short callno = pvt->callno;
04847
04848 if (!pvt->peercallno) {
04849
04850 int count = 10;
04851 while (count-- && pvt && !pvt->peercallno) {
04852 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
04853 pvt = iaxs[callno];
04854 }
04855 if (!pvt->peercallno) {
04856 return -1;
04857 }
04858 }
04859
04860 return 0;
04861 }
04862
04863 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
04864 {
04865 struct ast_option_header *h;
04866 int res;
04867
04868 switch (option) {
04869 case AST_OPTION_TXGAIN:
04870 case AST_OPTION_RXGAIN:
04871
04872 errno = ENOSYS;
04873 return -1;
04874 default:
04875 {
04876 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04877 struct chan_iax2_pvt *pvt;
04878
04879 ast_mutex_lock(&iaxsl[callno]);
04880 pvt = iaxs[callno];
04881
04882 if (wait_for_peercallno(pvt)) {
04883 ast_mutex_unlock(&iaxsl[callno]);
04884 return -1;
04885 }
04886
04887 ast_mutex_unlock(&iaxsl[callno]);
04888
04889 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
04890 return -1;
04891 }
04892
04893 h->flag = AST_OPTION_FLAG_REQUEST;
04894 h->option = htons(option);
04895 memcpy(h->data, data, datalen);
04896 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
04897 AST_CONTROL_OPTION, 0, (unsigned char *) h,
04898 datalen + sizeof(*h), -1);
04899 ast_free(h);
04900 return res;
04901 }
04902 }
04903 }
04904
04905 static struct ast_frame *iax2_read(struct ast_channel *c)
04906 {
04907 ast_log(LOG_NOTICE, "I should never be called!\n");
04908 return &ast_null_frame;
04909 }
04910
04911 static int iax2_key_rotate(const void *vpvt)
04912 {
04913 int res = 0;
04914 struct chan_iax2_pvt *pvt = (void *) vpvt;
04915 struct MD5Context md5;
04916 char key[17] = "";
04917 struct iax_ie_data ied = {
04918 .pos = 0,
04919 };
04920
04921 ast_mutex_lock(&iaxsl[pvt->callno]);
04922 pvt->keyrotateid =
04923 ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
04924
04925 snprintf(key, sizeof(key), "%lX", ast_random());
04926
04927 MD5Init(&md5);
04928 MD5Update(&md5, (unsigned char *) key, strlen(key));
04929 MD5Final((unsigned char *) key, &md5);
04930
04931 IAX_DEBUGDIGEST("Sending", key);
04932
04933 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
04934
04935 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
04936
04937 build_ecx_key((unsigned char *) key, pvt);
04938
04939 ast_mutex_unlock(&iaxsl[pvt->callno]);
04940
04941 return res;
04942 }
04943
04944 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
04945 {
04946 int res;
04947 struct iax_ie_data ied0;
04948 struct iax_ie_data ied1;
04949 unsigned int transferid = (unsigned int)ast_random();
04950
04951 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
04952 ast_debug(1, "transfers are not supported for encrypted calls at this time");
04953 ast_set_flag(iaxs[callno0], IAX_NOTRANSFER);
04954 ast_set_flag(iaxs[callno1], IAX_NOTRANSFER);
04955 return 0;
04956 }
04957
04958 memset(&ied0, 0, sizeof(ied0));
04959 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
04960 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
04961 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
04962
04963 memset(&ied1, 0, sizeof(ied1));
04964 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
04965 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
04966 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
04967
04968 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
04969 if (res)
04970 return -1;
04971 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
04972 if (res)
04973 return -1;
04974 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04975 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04976 return 0;
04977 }
04978
04979 static void lock_both(unsigned short callno0, unsigned short callno1)
04980 {
04981 ast_mutex_lock(&iaxsl[callno0]);
04982 while (ast_mutex_trylock(&iaxsl[callno1])) {
04983 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
04984 }
04985 }
04986
04987 static void unlock_both(unsigned short callno0, unsigned short callno1)
04988 {
04989 ast_mutex_unlock(&iaxsl[callno1]);
04990 ast_mutex_unlock(&iaxsl[callno0]);
04991 }
04992
04993 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)
04994 {
04995 struct ast_channel *cs[3];
04996 struct ast_channel *who, *other;
04997 int to = -1;
04998 int res = -1;
04999 int transferstarted=0;
05000 struct ast_frame *f;
05001 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05002 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05003 struct timeval waittimer = {0, 0};
05004
05005
05006 if (timeoutms > 0) {
05007 return AST_BRIDGE_FAILED;
05008 }
05009
05010 timeoutms = -1;
05011
05012 lock_both(callno0, callno1);
05013 if (!iaxs[callno0] || !iaxs[callno1]) {
05014 unlock_both(callno0, callno1);
05015 return AST_BRIDGE_FAILED;
05016 }
05017
05018 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05019 iaxs[callno0]->bridgecallno = callno1;
05020 iaxs[callno1]->bridgecallno = callno0;
05021 }
05022 unlock_both(callno0, callno1);
05023
05024
05025 cs[0] = c0;
05026 cs[1] = c1;
05027 for (;;) {
05028
05029 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05030 ast_verb(3, "Can't masquerade, we're different...\n");
05031
05032 if (c0->tech == &iax2_tech) {
05033 ast_mutex_lock(&iaxsl[callno0]);
05034 iaxs[callno0]->bridgecallno = 0;
05035 ast_mutex_unlock(&iaxsl[callno0]);
05036 }
05037 if (c1->tech == &iax2_tech) {
05038 ast_mutex_lock(&iaxsl[callno1]);
05039 iaxs[callno1]->bridgecallno = 0;
05040 ast_mutex_unlock(&iaxsl[callno1]);
05041 }
05042 return AST_BRIDGE_FAILED_NOWARN;
05043 }
05044 if (c0->nativeformats != c1->nativeformats) {
05045 char buf0[255];
05046 char buf1[255];
05047 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
05048 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
05049 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
05050
05051 lock_both(callno0, callno1);
05052 if (iaxs[callno0])
05053 iaxs[callno0]->bridgecallno = 0;
05054 if (iaxs[callno1])
05055 iaxs[callno1]->bridgecallno = 0;
05056 unlock_both(callno0, callno1);
05057 return AST_BRIDGE_FAILED_NOWARN;
05058 }
05059
05060 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
05061
05062 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05063 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
05064 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05065 transferstarted = 1;
05066 }
05067 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05068
05069 struct timeval now = ast_tvnow();
05070 if (ast_tvzero(waittimer)) {
05071 waittimer = now;
05072 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05073 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05074 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05075 *fo = NULL;
05076 *rc = c0;
05077 res = AST_BRIDGE_COMPLETE;
05078 break;
05079 }
05080 }
05081 to = 1000;
05082 who = ast_waitfor_n(cs, 2, &to);
05083 if (timeoutms > -1) {
05084 timeoutms -= (1000 - to);
05085 if (timeoutms < 0)
05086 timeoutms = 0;
05087 }
05088 if (!who) {
05089 if (!timeoutms) {
05090 res = AST_BRIDGE_RETRY;
05091 break;
05092 }
05093 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05094 res = AST_BRIDGE_FAILED;
05095 break;
05096 }
05097 continue;
05098 }
05099 f = ast_read(who);
05100 if (!f) {
05101 *fo = NULL;
05102 *rc = who;
05103 res = AST_BRIDGE_COMPLETE;
05104 break;
05105 }
05106 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
05107 *fo = f;
05108 *rc = who;
05109 res = AST_BRIDGE_COMPLETE;
05110 break;
05111 }
05112 other = (who == c0) ? c1 : c0;
05113 if ((f->frametype == AST_FRAME_VOICE) ||
05114 (f->frametype == AST_FRAME_TEXT) ||
05115 (f->frametype == AST_FRAME_VIDEO) ||
05116 (f->frametype == AST_FRAME_IMAGE) ||
05117 (f->frametype == AST_FRAME_DTMF) ||
05118 (f->frametype == AST_FRAME_CONTROL)) {
05119
05120
05121
05122 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05123 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05124 *rc = who;
05125 *fo = f;
05126 res = AST_BRIDGE_COMPLETE;
05127
05128 break;
05129 }
05130
05131 ast_write(other, f);
05132 }
05133 ast_frfree(f);
05134
05135 cs[2] = cs[0];
05136 cs[0] = cs[1];
05137 cs[1] = cs[2];
05138 }
05139 lock_both(callno0, callno1);
05140 if(iaxs[callno0])
05141 iaxs[callno0]->bridgecallno = 0;
05142 if(iaxs[callno1])
05143 iaxs[callno1]->bridgecallno = 0;
05144 unlock_both(callno0, callno1);
05145 return res;
05146 }
05147
05148 static int iax2_answer(struct ast_channel *c)
05149 {
05150 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05151 ast_debug(1, "Answering IAX2 call\n");
05152 ast_mutex_lock(&iaxsl[callno]);
05153 if (iaxs[callno])
05154 iax2_ami_channelupdate(iaxs[callno]);
05155 ast_mutex_unlock(&iaxsl[callno]);
05156 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05157 }
05158
05159 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05160 {
05161 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05162 struct chan_iax2_pvt *pvt;
05163 int res = 0;
05164
05165 if (iaxdebug)
05166 ast_debug(1, "Indicating condition %d\n", condition);
05167
05168 ast_mutex_lock(&iaxsl[callno]);
05169 pvt = iaxs[callno];
05170
05171 if (wait_for_peercallno(pvt)) {
05172 res = -1;
05173 goto done;
05174 }
05175
05176 switch (condition) {
05177 case AST_CONTROL_HOLD:
05178 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05179 ast_moh_start(c, data, pvt->mohinterpret);
05180 goto done;
05181 }
05182 break;
05183 case AST_CONTROL_UNHOLD:
05184 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05185 ast_moh_stop(c);
05186 goto done;
05187 }
05188 }
05189
05190 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05191
05192 done:
05193 ast_mutex_unlock(&iaxsl[callno]);
05194
05195 return res;
05196 }
05197
05198 static int iax2_transfer(struct ast_channel *c, const char *dest)
05199 {
05200 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05201 struct iax_ie_data ied = { "", };
05202 char tmp[256], *context;
05203 ast_copy_string(tmp, dest, sizeof(tmp));
05204 context = strchr(tmp, '@');
05205 if (context) {
05206 *context = '\0';
05207 context++;
05208 }
05209 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05210 if (context)
05211 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05212 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05213 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05214 }
05215
05216 static int iax2_getpeertrunk(struct sockaddr_in sin)
05217 {
05218 struct iax2_peer *peer;
05219 int res = 0;
05220 struct ao2_iterator i;
05221
05222 i = ao2_iterator_init(peers, 0);
05223 while ((peer = ao2_iterator_next(&i))) {
05224 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05225 (peer->addr.sin_port == sin.sin_port)) {
05226 res = ast_test_flag(peer, IAX_TRUNK);
05227 peer_unref(peer);
05228 break;
05229 }
05230 peer_unref(peer);
05231 }
05232
05233 return res;
05234 }
05235
05236
05237 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
05238 {
05239 struct ast_channel *tmp;
05240 struct chan_iax2_pvt *i;
05241 struct ast_variable *v = NULL;
05242
05243 if (!(i = iaxs[callno])) {
05244 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05245 return NULL;
05246 }
05247
05248
05249 ast_mutex_unlock(&iaxsl[callno]);
05250 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);
05251 ast_mutex_lock(&iaxsl[callno]);
05252 if (i != iaxs[callno]) {
05253 if (tmp) {
05254
05255 ast_mutex_unlock(&iaxsl[callno]);
05256 ast_channel_free(tmp);
05257 ast_mutex_lock(&iaxsl[callno]);
05258 }
05259 return NULL;
05260 }
05261 iax2_ami_channelupdate(i);
05262 if (!tmp)
05263 return NULL;
05264 tmp->tech = &iax2_tech;
05265
05266 tmp->nativeformats = capability;
05267 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05268 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05269 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05270
05271 if (!ast_strlen_zero(i->parkinglot))
05272 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05273
05274
05275 if (!ast_strlen_zero(i->ani))
05276 tmp->cid.cid_ani = ast_strdup(i->ani);
05277 else
05278 tmp->cid.cid_ani = ast_strdup(i->cid_num);
05279 tmp->cid.cid_dnid = ast_strdup(i->dnid);
05280 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05281 tmp->cid.cid_pres = i->calling_pres;
05282 tmp->cid.cid_ton = i->calling_ton;
05283 tmp->cid.cid_tns = i->calling_tns;
05284 if (!ast_strlen_zero(i->language))
05285 ast_string_field_set(tmp, language, i->language);
05286 if (!ast_strlen_zero(i->accountcode))
05287 ast_string_field_set(tmp, accountcode, i->accountcode);
05288 if (i->amaflags)
05289 tmp->amaflags = i->amaflags;
05290 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05291 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05292 if (i->adsi)
05293 tmp->adsicpe = i->peeradsicpe;
05294 else
05295 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05296 i->owner = tmp;
05297 i->capability = capability;
05298
05299
05300 if (i->vars) {
05301 for (v = i->vars ; v ; v = v->next)
05302 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05303 }
05304 if (i->iaxvars) {
05305 struct ast_datastore *variablestore;
05306 struct ast_variable *var, *prev = NULL;
05307 AST_LIST_HEAD(, ast_var_t) *varlist;
05308 ast_debug(1, "Loading up the channel with IAXVARs\n");
05309 varlist = ast_calloc(1, sizeof(*varlist));
05310 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05311 if (variablestore && varlist) {
05312 variablestore->data = varlist;
05313 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05314 AST_LIST_HEAD_INIT(varlist);
05315 for (var = i->iaxvars; var; var = var->next) {
05316 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05317 if (prev)
05318 ast_free(prev);
05319 prev = var;
05320 if (!newvar) {
05321
05322 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05323 } else {
05324 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05325 }
05326 }
05327 if (prev)
05328 ast_free(prev);
05329 i->iaxvars = NULL;
05330 ast_channel_datastore_add(i->owner, variablestore);
05331 } else {
05332 if (variablestore) {
05333 ast_datastore_free(variablestore);
05334 }
05335 if (varlist) {
05336 ast_free(varlist);
05337 }
05338 }
05339 }
05340
05341 if (state != AST_STATE_DOWN) {
05342 if (ast_pbx_start(tmp)) {
05343 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05344 ast_hangup(tmp);
05345 i->owner = NULL;
05346 return NULL;
05347 }
05348 }
05349
05350 ast_module_ref(ast_module_info->self);
05351 return tmp;
05352 }
05353
05354 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05355 {
05356 unsigned long int mssincetx;
05357 long int ms, pred;
05358
05359 tpeer->trunkact = *now;
05360 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05361 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05362
05363 tpeer->txtrunktime = *now;
05364 tpeer->lastsent = 999999;
05365 }
05366
05367 tpeer->lasttxtime = *now;
05368
05369
05370 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05371
05372 pred = tpeer->lastsent + sampms;
05373 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05374 ms = pred;
05375
05376
05377 if (ms == tpeer->lastsent)
05378 ms = tpeer->lastsent + 1;
05379 tpeer->lastsent = ms;
05380 return ms;
05381 }
05382
05383 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05384 {
05385 long ms;
05386 if (ast_tvzero(iaxs[callno]->rxcore)) {
05387
05388 iaxs[callno]->rxcore = ast_tvnow();
05389
05390 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05391 }
05392
05393 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05394
05395 return ms + ts;
05396 }
05397
05398 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05399 {
05400 int ms;
05401 int voice = 0;
05402 int genuine = 0;
05403 int adjust;
05404 int rate = ast_format_rate(f->subclass) / 1000;
05405 struct timeval *delivery = NULL;
05406
05407
05408
05409
05410
05411
05412
05413
05414 if (f) {
05415 if (f->frametype == AST_FRAME_VOICE) {
05416 voice = 1;
05417 delivery = &f->delivery;
05418 } else if (f->frametype == AST_FRAME_IAX) {
05419 genuine = 1;
05420 } else if (f->frametype == AST_FRAME_CNG) {
05421 p->notsilenttx = 0;
05422 }
05423 }
05424 if (ast_tvzero(p->offset)) {
05425 p->offset = ast_tvnow();
05426
05427 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05428 }
05429
05430 if (ts)
05431 return ts;
05432
05433 if (delivery && !ast_tvzero(*delivery)) {
05434 ms = ast_tvdiff_ms(*delivery, p->offset);
05435 if (ms < 0) {
05436 ms = 0;
05437 }
05438 if (iaxdebug)
05439 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05440 } else {
05441 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05442 if (ms < 0)
05443 ms = 0;
05444 if (voice) {
05445
05446 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05447
05448
05449
05450
05451
05452
05453
05454
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465 adjust = (ms - p->nextpred);
05466 if (adjust < 0)
05467 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05468 else if (adjust > 0)
05469 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05470
05471 if (!p->nextpred) {
05472 p->nextpred = ms;
05473 if (p->nextpred <= p->lastsent)
05474 p->nextpred = p->lastsent + 3;
05475 }
05476 ms = p->nextpred;
05477 } else {
05478
05479
05480
05481
05482
05483
05484
05485
05486
05487 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05488 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05489 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05490
05491 if (f->samples >= rate)
05492 {
05493 int diff = ms % (f->samples / rate);
05494 if (diff)
05495 ms += f->samples/rate - diff;
05496 }
05497
05498 p->nextpred = ms;
05499 p->notsilenttx = 1;
05500 }
05501 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05502
05503
05504
05505
05506
05507
05508
05509
05510 if ( (unsigned int)ms < p->lastsent )
05511 ms = p->lastsent;
05512 } else {
05513
05514
05515 if (genuine) {
05516
05517 if (ms <= p->lastsent)
05518 ms = p->lastsent + 3;
05519 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05520
05521 ms = p->lastsent + 3;
05522 }
05523 }
05524 }
05525 p->lastsent = ms;
05526 if (voice)
05527 p->nextpred = p->nextpred + f->samples / rate;
05528 return ms;
05529 }
05530
05531 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05532 {
05533
05534
05535 int ms;
05536 #ifdef IAXTESTS
05537 int jit;
05538 #endif
05539
05540 if (ast_tvzero(p->rxcore)) {
05541 p->rxcore = ast_tvnow();
05542 if (iaxdebug)
05543 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05544 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05545 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05546 #if 1
05547 if (iaxdebug)
05548 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05549 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05550 #endif
05551 }
05552
05553 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05554 #ifdef IAXTESTS
05555 if (test_jit) {
05556 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05557 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05558 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05559 jit = -jit;
05560 ms += jit;
05561 }
05562 }
05563 if (test_late) {
05564 ms += test_late;
05565 test_late = 0;
05566 }
05567 #endif
05568 return ms;
05569 }
05570
05571 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
05572 {
05573 struct iax2_trunk_peer *tpeer = NULL;
05574
05575
05576 AST_LIST_LOCK(&tpeers);
05577
05578 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
05579 if (!inaddrcmp(&tpeer->addr, sin)) {
05580 ast_mutex_lock(&tpeer->lock);
05581 break;
05582 }
05583 }
05584
05585 if (!tpeer) {
05586 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
05587 ast_mutex_init(&tpeer->lock);
05588 tpeer->lastsent = 9999;
05589 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
05590 tpeer->trunkact = ast_tvnow();
05591 ast_mutex_lock(&tpeer->lock);
05592 tpeer->sockfd = fd;
05593 #ifdef SO_NO_CHECK
05594 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
05595 #endif
05596 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05597 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
05598 }
05599 }
05600
05601 AST_LIST_UNLOCK(&tpeers);
05602
05603 return tpeer;
05604 }
05605
05606 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
05607 {
05608 struct ast_frame *f;
05609 struct iax2_trunk_peer *tpeer;
05610 void *tmp, *ptr;
05611 struct timeval now;
05612 int res;
05613 struct ast_iax2_meta_trunk_entry *met;
05614 struct ast_iax2_meta_trunk_mini *mtm;
05615
05616 f = &fr->af;
05617 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
05618 if (tpeer) {
05619 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
05620
05621 if (tpeer->trunkdataalloc < trunkmaxsize) {
05622 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
05623 ast_mutex_unlock(&tpeer->lock);
05624 return -1;
05625 }
05626
05627 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
05628 tpeer->trunkdata = tmp;
05629 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);
05630 } else {
05631 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));
05632 ast_mutex_unlock(&tpeer->lock);
05633 return -1;
05634 }
05635 }
05636
05637
05638 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
05639 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
05640 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
05641 mtm->len = htons(f->datalen);
05642 mtm->mini.callno = htons(pvt->callno);
05643 mtm->mini.ts = htons(0xffff & fr->ts);
05644 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
05645 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
05646 } else {
05647 met = (struct ast_iax2_meta_trunk_entry *)ptr;
05648
05649 met->callno = htons(pvt->callno);
05650 met->len = htons(f->datalen);
05651
05652 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
05653 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
05654 }
05655
05656 memcpy(ptr, f->data.ptr, f->datalen);
05657 tpeer->trunkdatalen += f->datalen;
05658
05659 tpeer->calls++;
05660
05661
05662 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
05663 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
05664
05665
05666 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
05667 now = ast_tvnow();
05668 res = send_trunk(tpeer, &now);
05669 trunk_untimed ++;
05670 }
05671
05672 ast_mutex_unlock(&tpeer->lock);
05673 }
05674 return 0;
05675 }
05676
05677
05678
05679 static void build_rand_pad(unsigned char *buf, ssize_t len)
05680 {
05681 long tmp;
05682 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05683 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05684 buf += sizeof(tmp);
05685 len -= sizeof(tmp);
05686 }
05687 }
05688
05689 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05690 {
05691 build_ecx_key(digest, pvt);
05692 ast_aes_decrypt_key(digest, &pvt->dcx);
05693 }
05694
05695 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05696 {
05697
05698
05699
05700 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05701 ast_aes_encrypt_key(digest, &pvt->ecx);
05702 ast_aes_decrypt_key(digest, &pvt->mydcx);
05703 }
05704
05705 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
05706 {
05707 #if 0
05708
05709 int x;
05710 if (len % 16)
05711 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05712 for (x=0;x<len;x++)
05713 dst[x] = src[x] ^ 0xff;
05714 #else
05715 unsigned char lastblock[16] = { 0 };
05716 int x;
05717 while(len > 0) {
05718 ast_aes_decrypt(src, dst, dcx);
05719 for (x=0;x<16;x++)
05720 dst[x] ^= lastblock[x];
05721 memcpy(lastblock, src, sizeof(lastblock));
05722 dst += 16;
05723 src += 16;
05724 len -= 16;
05725 }
05726 #endif
05727 }
05728
05729 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
05730 {
05731 #if 0
05732
05733 int x;
05734 if (len % 16)
05735 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05736 for (x=0;x<len;x++)
05737 dst[x] = src[x] ^ 0xff;
05738 #else
05739 unsigned char curblock[16] = { 0 };
05740 int x;
05741 while(len > 0) {
05742 for (x=0;x<16;x++)
05743 curblock[x] ^= src[x];
05744 ast_aes_encrypt(curblock, dst, ecx);
05745 memcpy(curblock, dst, sizeof(curblock));
05746 dst += 16;
05747 src += 16;
05748 len -= 16;
05749 }
05750 #endif
05751 }
05752
05753 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05754 {
05755 int padding;
05756 unsigned char *workspace;
05757
05758 workspace = alloca(*datalen);
05759 memset(f, 0, sizeof(*f));
05760 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05761 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05762 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
05763 return -1;
05764
05765 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
05766
05767 padding = 16 + (workspace[15] & 0x0f);
05768 if (iaxdebug)
05769 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
05770 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
05771 return -1;
05772
05773 *datalen -= padding;
05774 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05775 f->frametype = fh->type;
05776 if (f->frametype == AST_FRAME_VIDEO) {
05777 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
05778 } else {
05779 f->subclass = uncompress_subclass(fh->csub);
05780 }
05781 } else {
05782 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05783 if (iaxdebug)
05784 ast_debug(1, "Decoding mini with length %d\n", *datalen);
05785 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
05786 return -1;
05787
05788 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
05789 padding = 16 + (workspace[15] & 0x0f);
05790 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
05791 return -1;
05792 *datalen -= padding;
05793 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05794 }
05795 return 0;
05796 }
05797
05798 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
05799 {
05800 int padding;
05801 unsigned char *workspace;
05802 workspace = alloca(*datalen + 32);
05803 if (!workspace)
05804 return -1;
05805 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05806 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05807 if (iaxdebug)
05808 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
05809 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
05810 padding = 16 + (padding & 0xf);
05811 memcpy(workspace, poo, padding);
05812 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05813 workspace[15] &= 0xf0;
05814 workspace[15] |= (padding & 0xf);
05815 if (iaxdebug)
05816 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
05817 *datalen += padding;
05818 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
05819 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
05820 memcpy(poo, workspace + *datalen - 32, 32);
05821 } else {
05822 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05823 if (iaxdebug)
05824 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
05825 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
05826 padding = 16 + (padding & 0xf);
05827 memcpy(workspace, poo, padding);
05828 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05829 workspace[15] &= 0xf0;
05830 workspace[15] |= (padding & 0x0f);
05831 *datalen += padding;
05832 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
05833 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
05834 memcpy(poo, workspace + *datalen - 32, 32);
05835 }
05836 return 0;
05837 }
05838
05839 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05840 {
05841 int res=-1;
05842 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
05843
05844 struct MD5Context md5;
05845 unsigned char digest[16];
05846 char *tmppw, *stringp;
05847
05848 tmppw = ast_strdupa(iaxs[callno]->secret);
05849 stringp = tmppw;
05850 while ((tmppw = strsep(&stringp, ";"))) {
05851 MD5Init(&md5);
05852 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05853 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05854 MD5Final(digest, &md5);
05855 build_encryption_keys(digest, iaxs[callno]);
05856 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05857 if (!res) {
05858 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
05859 break;
05860 }
05861 }
05862 } else
05863 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05864 return res;
05865 }
05866
05867 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
05868 {
05869
05870
05871
05872 struct ast_iax2_full_hdr *fh;
05873 struct ast_iax2_mini_hdr *mh;
05874 struct ast_iax2_video_hdr *vh;
05875 struct {
05876 struct iax_frame fr2;
05877 unsigned char buffer[4096];
05878 } frb;
05879 struct iax_frame *fr;
05880 int res;
05881 int sendmini=0;
05882 unsigned int lastsent;
05883 unsigned int fts;
05884
05885 frb.fr2.afdatalen = sizeof(frb.buffer);
05886
05887 if (!pvt) {
05888 ast_log(LOG_WARNING, "No private structure for packet?\n");
05889 return -1;
05890 }
05891
05892 lastsent = pvt->lastsent;
05893
05894
05895 fts = calc_timestamp(pvt, ts, f);
05896
05897
05898
05899
05900 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
05901 return 0;
05902 #if 0
05903 ast_log(LOG_NOTICE,
05904 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
05905 *("=!" + (f->frametype == AST_FRAME_VOICE)),
05906 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
05907 pvt->keyrotateid != -1 ? "" : "no "
05908 );
05909 #endif
05910 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
05911 iax2_key_rotate(pvt);
05912 }
05913
05914 if ((ast_test_flag(pvt, IAX_TRUNK) ||
05915 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
05916 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
05917 &&
05918 (f->frametype == AST_FRAME_VOICE)
05919 &&
05920 (f->subclass == pvt->svoiceformat)
05921 ) {
05922
05923 now = 1;
05924
05925 sendmini = 1;
05926 }
05927 if ( f->frametype == AST_FRAME_VIDEO ) {
05928
05929
05930
05931
05932
05933 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
05934 ((f->subclass & ~0x1) == pvt->svideoformat)
05935 ) {
05936 now = 1;
05937 sendmini = 1;
05938 } else {
05939 now = 0;
05940 sendmini = 0;
05941 }
05942 pvt->lastvsent = fts;
05943 }
05944 if (f->frametype == AST_FRAME_IAX) {
05945
05946 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
05947 if (!pvt->first_iax_message) {
05948 pvt->first_iax_message = pvt->last_iax_message;
05949 }
05950 }
05951
05952 if (now) {
05953 fr = &frb.fr2;
05954 } else
05955 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));
05956 if (!fr) {
05957 ast_log(LOG_WARNING, "Out of memory\n");
05958 return -1;
05959 }
05960
05961 iax_frame_wrap(fr, f);
05962
05963 fr->ts = fts;
05964 fr->callno = pvt->callno;
05965 fr->transfer = transfer;
05966 fr->final = final;
05967 fr->encmethods = 0;
05968 if (!sendmini) {
05969
05970 if (seqno > -1)
05971 fr->oseqno = seqno;
05972 else
05973 fr->oseqno = pvt->oseqno++;
05974 fr->iseqno = pvt->iseqno;
05975 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
05976 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
05977 fh->ts = htonl(fr->ts);
05978 fh->oseqno = fr->oseqno;
05979 if (transfer) {
05980 fh->iseqno = 0;
05981 } else
05982 fh->iseqno = fr->iseqno;
05983
05984 if (!transfer)
05985 pvt->aseqno = fr->iseqno;
05986 fh->type = fr->af.frametype & 0xFF;
05987 if (fr->af.frametype == AST_FRAME_VIDEO)
05988 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
05989 else
05990 fh->csub = compress_subclass(fr->af.subclass);
05991 if (transfer) {
05992 fr->dcallno = pvt->transfercallno;
05993 } else
05994 fr->dcallno = pvt->peercallno;
05995 fh->dcallno = htons(fr->dcallno);
05996 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
05997 fr->data = fh;
05998 fr->retries = 0;
05999
06000 fr->retrytime = pvt->pingtime * 2;
06001 if (fr->retrytime < MIN_RETRY_TIME)
06002 fr->retrytime = MIN_RETRY_TIME;
06003 if (fr->retrytime > MAX_RETRY_TIME)
06004 fr->retrytime = MAX_RETRY_TIME;
06005
06006 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
06007 fr->retries = -1;
06008 else if (f->frametype == AST_FRAME_VOICE)
06009 pvt->svoiceformat = f->subclass;
06010 else if (f->frametype == AST_FRAME_VIDEO)
06011 pvt->svideoformat = f->subclass & ~0x1;
06012 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06013 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06014 if (fr->transfer)
06015 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06016 else
06017 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06018 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06019 fr->encmethods = pvt->encmethods;
06020 fr->ecx = pvt->ecx;
06021 fr->mydcx = pvt->mydcx;
06022 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06023 } else
06024 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06025 }
06026
06027 if (now) {
06028 res = send_packet(fr);
06029 } else
06030 res = iax2_transmit(fr);
06031 } else {
06032 if (ast_test_flag(pvt, IAX_TRUNK)) {
06033 iax2_trunk_queue(pvt, fr);
06034 res = 0;
06035 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06036
06037 fr->oseqno = -1;
06038 fr->iseqno = -1;
06039 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06040 vh->zeros = 0;
06041 vh->callno = htons(0x8000 | fr->callno);
06042 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
06043 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06044 fr->data = vh;
06045 fr->retries = -1;
06046 res = send_packet(fr);
06047 } else {
06048
06049 fr->oseqno = -1;
06050 fr->iseqno = -1;
06051
06052 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06053 mh->callno = htons(fr->callno);
06054 mh->ts = htons(fr->ts & 0xFFFF);
06055 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06056 fr->data = mh;
06057 fr->retries = -1;
06058 if (pvt->transferring == TRANSFER_MEDIAPASS)
06059 fr->transfer = 1;
06060 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06061 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06062 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06063 } else
06064 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06065 }
06066 res = send_packet(fr);
06067 }
06068 }
06069 return res;
06070 }
06071
06072 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06073 {
06074 regex_t regexbuf;
06075 int havepattern = 0;
06076
06077 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06078 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06079
06080 struct iax2_user *user = NULL;
06081 char auth[90];
06082 char *pstr = "";
06083 struct ao2_iterator i;
06084
06085 switch (cmd) {
06086 case CLI_INIT:
06087 e->command = "iax2 show users [like]";
06088 e->usage =
06089 "Usage: iax2 show users [like <pattern>]\n"
06090 " Lists all known IAX2 users.\n"
06091 " Optional regular expression pattern is used to filter the user list.\n";
06092 return NULL;
06093 case CLI_GENERATE:
06094 return NULL;
06095 }
06096
06097 switch (a->argc) {
06098 case 5:
06099 if (!strcasecmp(a->argv[3], "like")) {
06100 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06101 return CLI_SHOWUSAGE;
06102 havepattern = 1;
06103 } else
06104 return CLI_SHOWUSAGE;
06105 case 3:
06106 break;
06107 default:
06108 return CLI_SHOWUSAGE;
06109 }
06110
06111 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06112 i = ao2_iterator_init(users, 0);
06113 for (user = ao2_iterator_next(&i); user;
06114 user_unref(user), user = ao2_iterator_next(&i)) {
06115 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06116 continue;
06117
06118 if (!ast_strlen_zero(user->secret)) {
06119 ast_copy_string(auth,user->secret, sizeof(auth));
06120 } else if (!ast_strlen_zero(user->inkeys)) {
06121 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06122 } else
06123 ast_copy_string(auth, "-no secret-", sizeof(auth));
06124
06125 if(ast_test_flag(user,IAX_CODEC_NOCAP))
06126 pstr = "REQ Only";
06127 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
06128 pstr = "Disabled";
06129 else
06130 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06131
06132 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06133 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06134 user->ha ? "Yes" : "No", pstr);
06135 }
06136
06137 if (havepattern)
06138 regfree(®exbuf);
06139
06140 return CLI_SUCCESS;
06141 #undef FORMAT
06142 #undef FORMAT2
06143 }
06144
06145 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
06146 {
06147 regex_t regexbuf;
06148 int havepattern = 0;
06149 int total_peers = 0;
06150 int online_peers = 0;
06151 int offline_peers = 0;
06152 int unmonitored_peers = 0;
06153 struct ao2_iterator i;
06154
06155 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
06156 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
06157
06158 struct iax2_peer *peer = NULL;
06159 char name[256];
06160 int registeredonly=0;
06161 char *term = manager ? "\r\n" : "\n";
06162 char idtext[256] = "";
06163 switch (argc) {
06164 case 6:
06165 if (!strcasecmp(argv[3], "registered"))
06166 registeredonly = 1;
06167 else
06168 return RESULT_SHOWUSAGE;
06169 if (!strcasecmp(argv[4], "like")) {
06170 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06171 return RESULT_SHOWUSAGE;
06172 havepattern = 1;
06173 } else
06174 return RESULT_SHOWUSAGE;
06175 break;
06176 case 5:
06177 if (!strcasecmp(argv[3], "like")) {
06178 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06179 return RESULT_SHOWUSAGE;
06180 havepattern = 1;
06181 } else
06182 return RESULT_SHOWUSAGE;
06183 break;
06184 case 4:
06185 if (!strcasecmp(argv[3], "registered"))
06186 registeredonly = 1;
06187 else
06188 return RESULT_SHOWUSAGE;
06189 break;
06190 case 3:
06191 break;
06192 default:
06193 return RESULT_SHOWUSAGE;
06194 }
06195
06196
06197 if (!s)
06198 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
06199
06200 i = ao2_iterator_init(peers, 0);
06201 for (peer = ao2_iterator_next(&i); peer;
06202 peer_unref(peer), peer = ao2_iterator_next(&i)) {
06203 char nm[20];
06204 char status[20];
06205 char srch[2000];
06206 int retstatus;
06207
06208 if (registeredonly && !peer->addr.sin_addr.s_addr)
06209 continue;
06210 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
06211 continue;
06212
06213 if (!ast_strlen_zero(peer->username))
06214 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06215 else
06216 ast_copy_string(name, peer->name, sizeof(name));
06217
06218 retstatus = peer_status(peer, status, sizeof(status));
06219 if (retstatus > 0)
06220 online_peers++;
06221 else if (!retstatus)
06222 offline_peers++;
06223 else
06224 unmonitored_peers++;
06225
06226 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06227
06228 snprintf(srch, sizeof(srch), FORMAT, name,
06229 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06230 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06231 nm,
06232 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
06233 peer->encmethods ? "(E)" : " ", status, term);
06234
06235 if (s)
06236 astman_append(s,
06237 "Event: PeerEntry\r\n%s"
06238 "Channeltype: IAX2\r\n"
06239 "ChanObjectType: peer\r\n"
06240 "ObjectName: %s\r\n"
06241 "IPaddress: %s\r\n"
06242 "IPport: %d\r\n"
06243 "Dynamic: %s\r\n"
06244 "Status: %s\r\n\r\n",
06245 idtext,
06246 name,
06247 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
06248 ntohs(peer->addr.sin_port),
06249 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
06250 status);
06251
06252 else
06253 ast_cli(fd, FORMAT, name,
06254 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06255 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06256 nm,
06257 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
06258 peer->encmethods ? "(E)" : " ", status, term);
06259 total_peers++;
06260 }
06261
06262 if (!s)
06263 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
06264
06265 if (havepattern)
06266 regfree(®exbuf);
06267
06268 return RESULT_SUCCESS;
06269 #undef FORMAT
06270 #undef FORMAT2
06271 }
06272
06273 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06274 {
06275 struct iax2_thread *thread = NULL;
06276 time_t t;
06277 int threadcount = 0, dynamiccount = 0;
06278 char type;
06279
06280 switch (cmd) {
06281 case CLI_INIT:
06282 e->command = "iax2 show threads";
06283 e->usage =
06284 "Usage: iax2 show threads\n"
06285 " Lists status of IAX helper threads\n";
06286 return NULL;
06287 case CLI_GENERATE:
06288 return NULL;
06289 }
06290 if (a->argc != 3)
06291 return CLI_SHOWUSAGE;
06292
06293 ast_cli(a->fd, "IAX2 Thread Information\n");
06294 time(&t);
06295 ast_cli(a->fd, "Idle Threads:\n");
06296 AST_LIST_LOCK(&idle_list);
06297 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06298 #ifdef DEBUG_SCHED_MULTITHREAD
06299 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06300 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06301 #else
06302 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06303 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06304 #endif
06305 threadcount++;
06306 }
06307 AST_LIST_UNLOCK(&idle_list);
06308 ast_cli(a->fd, "Active Threads:\n");
06309 AST_LIST_LOCK(&active_list);
06310 AST_LIST_TRAVERSE(&active_list, thread, list) {
06311 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06312 type = 'D';
06313 else
06314 type = 'P';
06315 #ifdef DEBUG_SCHED_MULTITHREAD
06316 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06317 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06318 #else
06319 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06320 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06321 #endif
06322 threadcount++;
06323 }
06324 AST_LIST_UNLOCK(&active_list);
06325 ast_cli(a->fd, "Dynamic Threads:\n");
06326 AST_LIST_LOCK(&dynamic_list);
06327 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06328 #ifdef DEBUG_SCHED_MULTITHREAD
06329 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06330 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06331 #else
06332 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06333 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06334 #endif
06335 dynamiccount++;
06336 }
06337 AST_LIST_UNLOCK(&dynamic_list);
06338 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06339 return CLI_SUCCESS;
06340 }
06341
06342 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06343 {
06344 struct iax2_peer *p;
06345
06346 switch (cmd) {
06347 case CLI_INIT:
06348 e->command = "iax2 unregister";
06349 e->usage =
06350 "Usage: iax2 unregister <peername>\n"
06351 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06352 return NULL;
06353 case CLI_GENERATE:
06354 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06355 }
06356
06357 if (a->argc != 3)
06358 return CLI_SHOWUSAGE;
06359
06360 p = find_peer(a->argv[2], 1);
06361 if (p) {
06362 if (p->expire > 0) {
06363 struct iax2_peer tmp_peer = {
06364 .name = a->argv[2],
06365 };
06366 struct iax2_peer *peer;
06367
06368 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06369 if (peer) {
06370 expire_registry(peer_ref(peer));
06371 peer_unref(peer);
06372 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06373 } else {
06374 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06375 }
06376 } else {
06377 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06378 }
06379 } else {
06380 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06381 }
06382 return CLI_SUCCESS;
06383 }
06384
06385 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06386 {
06387 int which = 0;
06388 struct iax2_peer *p = NULL;
06389 char *res = NULL;
06390 int wordlen = strlen(word);
06391
06392
06393 if (pos == 2) {
06394 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06395 while ((p = ao2_iterator_next(&i))) {
06396 if (!strncasecmp(p->name, word, wordlen) &&
06397 ++which > state && p->expire > 0) {
06398 res = ast_strdup(p->name);
06399 peer_unref(p);
06400 break;
06401 }
06402 peer_unref(p);
06403 }
06404 }
06405
06406 return res;
06407 }
06408
06409 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06410 {
06411 switch (cmd) {
06412 case CLI_INIT:
06413 e->command = "iax2 show peers";
06414 e->usage =
06415 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06416 " Lists all known IAX2 peers.\n"
06417 " Optional 'registered' argument lists only peers with known addresses.\n"
06418 " Optional regular expression pattern is used to filter the peer list.\n";
06419 return NULL;
06420 case CLI_GENERATE:
06421 return NULL;
06422 }
06423
06424 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
06425 case RESULT_SHOWUSAGE:
06426 return CLI_SHOWUSAGE;
06427 case RESULT_FAILURE:
06428 return CLI_FAILURE;
06429 default:
06430 return CLI_SUCCESS;
06431 }
06432 }
06433
06434 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06435 {
06436 ast_cli_netstats(s, -1, 0);
06437 astman_append(s, "\r\n");
06438 return RESULT_SUCCESS;
06439 }
06440
06441 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06442 {
06443 struct iax_firmware *cur = NULL;
06444
06445 switch (cmd) {
06446 case CLI_INIT:
06447 e->command = "iax2 show firmware";
06448 e->usage =
06449 "Usage: iax2 show firmware\n"
06450 " Lists all known IAX firmware images.\n";
06451 return NULL;
06452 case CLI_GENERATE:
06453 return NULL;
06454 }
06455
06456 if (a->argc != 3 && a->argc != 4)
06457 return CLI_SHOWUSAGE;
06458
06459 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06460 AST_LIST_LOCK(&firmwares);
06461 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06462 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06463 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06464 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06465 }
06466 }
06467 AST_LIST_UNLOCK(&firmwares);
06468
06469 return CLI_SUCCESS;
06470 }
06471
06472
06473 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06474 {
06475 char *a[] = { "iax2", "show", "users" };
06476 const char *id = astman_get_header(m,"ActionID");
06477 char idtext[256] = "";
06478
06479 if (!ast_strlen_zero(id))
06480 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06481 astman_send_ack(s, m, "Peer status list will follow");
06482 return __iax2_show_peers(1, -1, s, 3, a );
06483 }
06484
06485
06486 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06487 {
06488 struct iax2_peer *peer = NULL;
06489 int peer_count = 0;
06490 char nm[20];
06491 char status[20];
06492 const char *id = astman_get_header(m,"ActionID");
06493 char idtext[256] = "";
06494 struct ao2_iterator i;
06495
06496 if (!ast_strlen_zero(id))
06497 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06498
06499 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06500
06501
06502 i = ao2_iterator_init(peers, 0);
06503 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06504
06505 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06506 if (!ast_strlen_zero(peer->username)) {
06507 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06508 } else {
06509 astman_append(s, "ObjectName: %s\r\n", peer->name);
06510 }
06511 astman_append(s, "ChanObjectType: peer\r\n");
06512 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
06513 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06514 astman_append(s, "Mask: %s\r\n", nm);
06515 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
06516 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
06517 peer_status(peer, status, sizeof(status));
06518 astman_append(s, "Status: %s\r\n\r\n", status);
06519 peer_count++;
06520 }
06521
06522 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
06523 return RESULT_SUCCESS;
06524 }
06525
06526
06527 static char *regstate2str(int regstate)
06528 {
06529 switch(regstate) {
06530 case REG_STATE_UNREGISTERED:
06531 return "Unregistered";
06532 case REG_STATE_REGSENT:
06533 return "Request Sent";
06534 case REG_STATE_AUTHSENT:
06535 return "Auth. Sent";
06536 case REG_STATE_REGISTERED:
06537 return "Registered";
06538 case REG_STATE_REJECTED:
06539 return "Rejected";
06540 case REG_STATE_TIMEOUT:
06541 return "Timeout";
06542 case REG_STATE_NOAUTH:
06543 return "No Authentication";
06544 default:
06545 return "Unknown";
06546 }
06547 }
06548
06549 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06550 {
06551 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
06552 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
06553 struct iax2_registry *reg = NULL;
06554 char host[80];
06555 char perceived[80];
06556 int counter = 0;
06557
06558 switch (cmd) {
06559 case CLI_INIT:
06560 e->command = "iax2 show registry";
06561 e->usage =
06562 "Usage: iax2 show registry\n"
06563 " Lists all registration requests and status.\n";
06564 return NULL;
06565 case CLI_GENERATE:
06566 return NULL;
06567 }
06568 if (a->argc != 3)
06569 return CLI_SHOWUSAGE;
06570 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
06571 AST_LIST_LOCK(®istrations);
06572 AST_LIST_TRAVERSE(®istrations, reg, entry) {
06573 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06574 if (reg->us.sin_addr.s_addr)
06575 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06576 else
06577 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06578 ast_cli(a->fd, FORMAT, host,
06579 (reg->dnsmgr) ? "Y" : "N",
06580 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
06581 counter++;
06582 }
06583 AST_LIST_UNLOCK(®istrations);
06584 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
06585 return CLI_SUCCESS;
06586 #undef FORMAT
06587 #undef FORMAT2
06588 }
06589
06590 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06591 {
06592 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
06593 #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"
06594 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
06595 int x;
06596 int numchans = 0;
06597 char first_message[10] = { 0, };
06598 char last_message[10] = { 0, };
06599
06600 switch (cmd) {
06601 case CLI_INIT:
06602 e->command = "iax2 show channels";
06603 e->usage =
06604 "Usage: iax2 show channels\n"
06605 " Lists all currently active IAX channels.\n";
06606 return NULL;
06607 case CLI_GENERATE:
06608 return NULL;
06609 }
06610
06611 if (a->argc != 3)
06612 return CLI_SHOWUSAGE;
06613 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
06614 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06615 ast_mutex_lock(&iaxsl[x]);
06616 if (iaxs[x]) {
06617 int lag, jitter, localdelay;
06618 jb_info jbinfo;
06619 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06620 jb_getinfo(iaxs[x]->jb, &jbinfo);
06621 jitter = jbinfo.jitter;
06622 localdelay = jbinfo.current - jbinfo.min;
06623 } else {
06624 jitter = -1;
06625 localdelay = 0;
06626 }
06627
06628 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06629 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06630 lag = iaxs[x]->remote_rr.delay;
06631 ast_cli(a->fd, FORMAT,
06632 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06633 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
06634 S_OR(iaxs[x]->username, "(None)"),
06635 iaxs[x]->callno, iaxs[x]->peercallno,
06636 iaxs[x]->oseqno, iaxs[x]->iseqno,
06637 lag,
06638 jitter,
06639 localdelay,
06640 ast_getformatname(iaxs[x]->voiceformat),
06641 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06642 first_message,
06643 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06644 last_message);
06645 numchans++;
06646 }
06647 ast_mutex_unlock(&iaxsl[x]);
06648 }
06649 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06650 return CLI_SUCCESS;
06651 #undef FORMAT
06652 #undef FORMAT2
06653 #undef FORMATB
06654 }
06655
06656 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
06657 {
06658 int x;
06659 int numchans = 0;
06660 char first_message[10] = { 0, };
06661 char last_message[10] = { 0, };
06662 #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"
06663 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
06664 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06665 ast_mutex_lock(&iaxsl[x]);
06666 if (iaxs[x]) {
06667 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06668 jb_info jbinfo;
06669 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06670 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06671
06672 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06673 jb_getinfo(iaxs[x]->jb, &jbinfo);
06674 localjitter = jbinfo.jitter;
06675 localdelay = jbinfo.current - jbinfo.min;
06676 locallost = jbinfo.frames_lost;
06677 locallosspct = jbinfo.losspct/1000;
06678 localdropped = jbinfo.frames_dropped;
06679 localooo = jbinfo.frames_ooo;
06680 } else {
06681 localjitter = -1;
06682 localdelay = 0;
06683 locallost = -1;
06684 locallosspct = -1;
06685 localdropped = 0;
06686 localooo = -1;
06687 }
06688 if (s)
06689 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06690 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06691 iaxs[x]->pingtime,
06692 localjitter,
06693 localdelay,
06694 locallost,
06695 locallosspct,
06696 localdropped,
06697 localooo,
06698 iaxs[x]->frames_received/1000,
06699 iaxs[x]->remote_rr.jitter,
06700 iaxs[x]->remote_rr.delay,
06701 iaxs[x]->remote_rr.losscnt,
06702 iaxs[x]->remote_rr.losspct,
06703 iaxs[x]->remote_rr.dropped,
06704 iaxs[x]->remote_rr.ooo,
06705 iaxs[x]->remote_rr.packets/1000,
06706 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06707 first_message,
06708 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06709 last_message);
06710 else
06711 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06712 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06713 iaxs[x]->pingtime,
06714 localjitter,
06715 localdelay,
06716 locallost,
06717 locallosspct,
06718 localdropped,
06719 localooo,
06720 iaxs[x]->frames_received/1000,
06721 iaxs[x]->remote_rr.jitter,
06722 iaxs[x]->remote_rr.delay,
06723 iaxs[x]->remote_rr.losscnt,
06724 iaxs[x]->remote_rr.losspct,
06725 iaxs[x]->remote_rr.dropped,
06726 iaxs[x]->remote_rr.ooo,
06727 iaxs[x]->remote_rr.packets/1000,
06728 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06729 first_message,
06730 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06731 last_message);
06732 numchans++;
06733 }
06734 ast_mutex_unlock(&iaxsl[x]);
06735 }
06736
06737 return numchans;
06738 }
06739
06740 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06741 {
06742 int numchans = 0;
06743
06744 switch (cmd) {
06745 case CLI_INIT:
06746 e->command = "iax2 show netstats";
06747 e->usage =
06748 "Usage: iax2 show netstats\n"
06749 " Lists network status for all currently active IAX channels.\n";
06750 return NULL;
06751 case CLI_GENERATE:
06752 return NULL;
06753 }
06754 if (a->argc != 3)
06755 return CLI_SHOWUSAGE;
06756 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
06757 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
06758 numchans = ast_cli_netstats(NULL, a->fd, 1);
06759 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06760 return CLI_SUCCESS;
06761 }
06762
06763 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06764 {
06765 switch (cmd) {
06766 case CLI_INIT:
06767 e->command = "iax2 set debug {on|off|peer}";
06768 e->usage =
06769 "Usage: iax2 set debug {on|off|peer peername}\n"
06770 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
06771 return NULL;
06772 case CLI_GENERATE:
06773 if (a->pos == 4)
06774 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
06775 return NULL;
06776 }
06777
06778 if (a->argc < e->args || a->argc > e->args + 1)
06779 return CLI_SHOWUSAGE;
06780
06781 if (!strcasecmp(a->argv[3], "peer")) {
06782 struct iax2_peer *peer;
06783
06784 if (a->argc != e->args + 1)
06785 return CLI_SHOWUSAGE;
06786
06787 peer = find_peer(a->argv[4], 1);
06788
06789 if (!peer) {
06790 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
06791 return CLI_FAILURE;
06792 }
06793
06794 debugaddr.sin_addr = peer->addr.sin_addr;
06795 debugaddr.sin_port = peer->addr.sin_port;
06796
06797 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
06798 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
06799
06800 ao2_ref(peer, -1);
06801 } else if (!strncasecmp(a->argv[3], "on", 2)) {
06802 iaxdebug = 1;
06803 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
06804 } else {
06805 iaxdebug = 0;
06806 memset(&debugaddr, 0, sizeof(debugaddr));
06807 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
06808 }
06809 return CLI_SUCCESS;
06810 }
06811
06812 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06813 {
06814 switch (cmd) {
06815 case CLI_INIT:
06816 e->command = "iax2 set debug trunk {on|off}";
06817 e->usage =
06818 "Usage: iax2 set debug trunk {on|off}\n"
06819 " Enables/Disables debugging of IAX trunking\n";
06820 return NULL;
06821 case CLI_GENERATE:
06822 return NULL;
06823 }
06824
06825 if (a->argc != e->args)
06826 return CLI_SHOWUSAGE;
06827
06828 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
06829 iaxtrunkdebug = 1;
06830 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
06831 } else {
06832 iaxtrunkdebug = 0;
06833 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
06834 }
06835 return CLI_SUCCESS;
06836 }
06837
06838 static char *handle_cli_iax2_set_debug_jb(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 jb {on|off}";
06843 e->usage =
06844 "Usage: iax2 set debug jb {on|off}\n"
06845 " Enables/Disables jitterbuffer debugging information\n";
06846 return NULL;
06847 case CLI_GENERATE:
06848 return NULL;
06849 }
06850
06851 if (a->argc != e->args)
06852 return CLI_SHOWUSAGE;
06853
06854 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
06855 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
06856 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
06857 } else {
06858 jb_setoutput(jb_error_output, jb_warning_output, NULL);
06859 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
06860 }
06861 return CLI_SUCCESS;
06862 }
06863
06864 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
06865 {
06866 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
06867 int res = -1;
06868 ast_mutex_lock(&iaxsl[callno]);
06869 if (iaxs[callno]) {
06870
06871 if (!iaxs[callno]->error) {
06872 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
06873 res = 0;
06874
06875 else if (f->frametype == AST_FRAME_NULL)
06876 res = 0;
06877 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
06878 res = 0;
06879 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
06880 res = 0;
06881 else
06882
06883 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
06884 } else {
06885 ast_debug(1, "Write error: %s\n", strerror(errno));
06886 }
06887 }
06888
06889 ast_mutex_unlock(&iaxsl[callno]);
06890 return res;
06891 }
06892
06893 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
06894 int now, int transfer, int final)
06895 {
06896 struct ast_frame f = { 0, };
06897
06898 f.frametype = type;
06899 f.subclass = command;
06900 f.datalen = datalen;
06901 f.src = __FUNCTION__;
06902 f.data.ptr = (void *) data;
06903
06904 return iax2_send(i, &f, ts, seqno, now, transfer, final);
06905 }
06906
06907 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
06908 {
06909 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
06910 }
06911
06912 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
06913 {
06914 int res;
06915 ast_mutex_lock(&iaxsl[callno]);
06916 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
06917 ast_mutex_unlock(&iaxsl[callno]);
06918 return res;
06919 }
06920
06921
06922
06923
06924
06925
06926 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)
06927 {
06928 int call_num = i->callno;
06929
06930 iax2_predestroy(i->callno);
06931 if (!iaxs[call_num])
06932 return -1;
06933 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
06934 }
06935
06936 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)
06937 {
06938 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
06939 }
06940
06941 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
06942 {
06943 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
06944 }
06945
06946 static int apply_context(struct iax2_context *con, const char *context)
06947 {
06948 while(con) {
06949 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
06950 return -1;
06951 con = con->next;
06952 }
06953 return 0;
06954 }
06955
06956
06957 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06958 {
06959
06960 int res = -1;
06961 int version = 2;
06962 struct iax2_user *user = NULL, *best = NULL;
06963 int bestscore = 0;
06964 int gotcapability = 0;
06965 struct ast_variable *v = NULL, *tmpvar = NULL;
06966 struct ao2_iterator i;
06967
06968 if (!iaxs[callno])
06969 return res;
06970 if (ies->called_number)
06971 ast_string_field_set(iaxs[callno], exten, ies->called_number);
06972 if (ies->calling_number) {
06973 ast_shrink_phone_number(ies->calling_number);
06974 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
06975 }
06976 if (ies->calling_name)
06977 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
06978 if (ies->calling_ani)
06979 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
06980 if (ies->dnid)
06981 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
06982 if (ies->rdnis)
06983 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
06984 if (ies->called_context)
06985 ast_string_field_set(iaxs[callno], context, ies->called_context);
06986 if (ies->language)
06987 ast_string_field_set(iaxs[callno], language, ies->language);
06988 if (ies->username)
06989 ast_string_field_set(iaxs[callno], username, ies->username);
06990 if (ies->calling_ton > -1)
06991 iaxs[callno]->calling_ton = ies->calling_ton;
06992 if (ies->calling_tns > -1)
06993 iaxs[callno]->calling_tns = ies->calling_tns;
06994 if (ies->calling_pres > -1)
06995 iaxs[callno]->calling_pres = ies->calling_pres;
06996 if (ies->format)
06997 iaxs[callno]->peerformat = ies->format;
06998 if (ies->adsicpe)
06999 iaxs[callno]->peeradsicpe = ies->adsicpe;
07000 if (ies->capability) {
07001 gotcapability = 1;
07002 iaxs[callno]->peercapability = ies->capability;
07003 }
07004 if (ies->version)
07005 version = ies->version;
07006
07007
07008 if(ies->codec_prefs) {
07009 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07010 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07011 }
07012
07013 if (!gotcapability)
07014 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07015 if (version > IAX_PROTO_VERSION) {
07016 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07017 ast_inet_ntoa(sin->sin_addr), version);
07018 return res;
07019 }
07020
07021 i = ao2_iterator_init(users, 0);
07022 while ((user = ao2_iterator_next(&i))) {
07023 if ((ast_strlen_zero(iaxs[callno]->username) ||
07024 !strcmp(iaxs[callno]->username, user->name))
07025 && ast_apply_ha(user->ha, sin)
07026 && (ast_strlen_zero(iaxs[callno]->context) ||
07027 apply_context(user->contexts, iaxs[callno]->context))) {
07028 if (!ast_strlen_zero(iaxs[callno]->username)) {
07029
07030 if (best)
07031 user_unref(best);
07032 best = user;
07033 break;
07034 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07035
07036 if (user->ha) {
07037
07038 if (bestscore < 4) {
07039 bestscore = 4;
07040 if (best)
07041 user_unref(best);
07042 best = user;
07043 continue;
07044 }
07045 } else {
07046
07047 if (bestscore < 3) {
07048 bestscore = 3;
07049 if (best)
07050 user_unref(best);
07051 best = user;
07052 continue;
07053 }
07054 }
07055 } else {
07056 if (user->ha) {
07057
07058 if (bestscore < 2) {
07059 bestscore = 2;
07060 if (best)
07061 user_unref(best);
07062 best = user;
07063 continue;
07064 }
07065 } else {
07066
07067 if (bestscore < 1) {
07068 bestscore = 1;
07069 if (best)
07070 user_unref(best);
07071 best = user;
07072 continue;
07073 }
07074 }
07075 }
07076 }
07077 user_unref(user);
07078 }
07079 user = best;
07080 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07081 user = realtime_user(iaxs[callno]->username, sin);
07082 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07083 !apply_context(user->contexts, iaxs[callno]->context)) {
07084 user = user_unref(user);
07085 }
07086 }
07087 if (user) {
07088
07089
07090 for (v = user->vars ; v ; v = v->next) {
07091 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07092 tmpvar->next = iaxs[callno]->vars;
07093 iaxs[callno]->vars = tmpvar;
07094 }
07095 }
07096
07097 if (user->maxauthreq > 0)
07098 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
07099 iaxs[callno]->prefs = user->prefs;
07100 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
07101 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
07102 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
07103 iaxs[callno]->encmethods = user->encmethods;
07104
07105 if (ast_strlen_zero(iaxs[callno]->username))
07106 ast_string_field_set(iaxs[callno], username, user->name);
07107
07108 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
07109 iaxs[callno]->capability = user->capability;
07110
07111 if (ast_strlen_zero(iaxs[callno]->context)) {
07112 if (user->contexts)
07113 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07114 else
07115 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07116 }
07117
07118 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07119
07120 iaxs[callno]->authmethods = user->authmethods;
07121 iaxs[callno]->adsi = user->adsi;
07122
07123 if (ast_test_flag(user, IAX_HASCALLERID)) {
07124 iaxs[callno]->calling_tns = 0;
07125 iaxs[callno]->calling_ton = 0;
07126 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07127 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07128 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07129 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07130 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07131 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07132 }
07133 if (!ast_strlen_zero(user->accountcode))
07134 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07135 if (!ast_strlen_zero(user->mohinterpret))
07136 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07137 if (!ast_strlen_zero(user->mohsuggest))
07138 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07139 if (!ast_strlen_zero(user->parkinglot))
07140 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07141 if (user->amaflags)
07142 iaxs[callno]->amaflags = user->amaflags;
07143 if (!ast_strlen_zero(user->language))
07144 ast_string_field_set(iaxs[callno], language, user->language);
07145 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07146
07147 if (!ast_strlen_zero(user->dbsecret)) {
07148 char *family, *key=NULL;
07149 char buf[80];
07150 family = ast_strdupa(user->dbsecret);
07151 key = strchr(family, '/');
07152 if (key) {
07153 *key = '\0';
07154 key++;
07155 }
07156 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07157 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07158 else
07159 ast_string_field_set(iaxs[callno], secret, buf);
07160 } else
07161 ast_string_field_set(iaxs[callno], secret, user->secret);
07162 res = 0;
07163 user = user_unref(user);
07164 } else {
07165
07166
07167
07168
07169 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07170 ast_string_field_set(iaxs[callno], secret, "badsecret");
07171 iaxs[callno]->authrej = 1;
07172 if (!ast_strlen_zero(iaxs[callno]->username)) {
07173
07174 res = 0;
07175 }
07176 }
07177 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07178 return res;
07179 }
07180
07181 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07182 {
07183 struct ast_iax2_full_hdr fh;
07184 fh.scallno = htons(src | IAX_FLAG_FULL);
07185 fh.dcallno = htons(dst);
07186 fh.ts = 0;
07187 fh.oseqno = 0;
07188 fh.iseqno = 0;
07189 fh.type = AST_FRAME_IAX;
07190 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07191 iax_outputframe(NULL, &fh, 0, sin, 0);
07192 #if 0
07193 if (option_debug)
07194 #endif
07195 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07196 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07197 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07198 }
07199
07200 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07201 {
07202
07203 p->encmethods &= enc;
07204 if (p->encmethods) {
07205 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07206 p->keyrotateid = -2;
07207 }
07208 if (p->encmethods & IAX_ENCRYPT_AES128)
07209 p->encmethods = IAX_ENCRYPT_AES128;
07210 else
07211 p->encmethods = 0;
07212 }
07213 }
07214
07215
07216
07217
07218
07219
07220
07221 static int authenticate_request(int call_num)
07222 {
07223 struct iax_ie_data ied;
07224 int res = -1, authreq_restrict = 0;
07225 char challenge[10];
07226 struct chan_iax2_pvt *p = iaxs[call_num];
07227
07228 memset(&ied, 0, sizeof(ied));
07229
07230
07231 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07232 struct iax2_user *user, tmp_user = {
07233 .name = p->username,
07234 };
07235
07236 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07237 if (user) {
07238 if (user->curauthreq == user->maxauthreq)
07239 authreq_restrict = 1;
07240 else
07241 user->curauthreq++;
07242 user = user_unref(user);
07243 }
07244 }
07245
07246
07247 if (authreq_restrict) {
07248 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07249 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07250 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07251 return 0;
07252 }
07253
07254 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07255 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07256 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07257 ast_string_field_set(p, challenge, challenge);
07258
07259 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07260 }
07261 if (p->encmethods)
07262 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07263
07264 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07265
07266 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07267
07268 if (p->encmethods)
07269 ast_set_flag(p, IAX_ENCRYPTED);
07270
07271 return res;
07272 }
07273
07274 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07275 {
07276 char requeststr[256];
07277 char md5secret[256] = "";
07278 char secret[256] = "";
07279 char rsasecret[256] = "";
07280 int res = -1;
07281 int x;
07282 struct iax2_user *user, tmp_user = {
07283 .name = p->username,
07284 };
07285
07286 if (p->authrej) {
07287 return res;
07288 }
07289 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07290 if (user) {
07291 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07292 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07293 ast_clear_flag(p, IAX_MAXAUTHREQ);
07294 }
07295 ast_string_field_set(p, host, user->name);
07296 user = user_unref(user);
07297 }
07298
07299 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07300 return res;
07301 if (ies->password)
07302 ast_copy_string(secret, ies->password, sizeof(secret));
07303 if (ies->md5_result)
07304 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07305 if (ies->rsa_result)
07306 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07307 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07308 struct ast_key *key;
07309 char *keyn;
07310 char tmpkey[256];
07311 char *stringp=NULL;
07312 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07313 stringp=tmpkey;
07314 keyn = strsep(&stringp, ":");
07315 while(keyn) {
07316 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07317 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07318 res = 0;
07319 break;
07320 } else if (!key)
07321 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07322 keyn = strsep(&stringp, ":");
07323 }
07324 } else if (p->authmethods & IAX_AUTH_MD5) {
07325 struct MD5Context md5;
07326 unsigned char digest[16];
07327 char *tmppw, *stringp;
07328
07329 tmppw = ast_strdupa(p->secret);
07330 stringp = tmppw;
07331 while((tmppw = strsep(&stringp, ";"))) {
07332 MD5Init(&md5);
07333 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07334 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07335 MD5Final(digest, &md5);
07336
07337 for (x=0;x<16;x++)
07338 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07339 if (!strcasecmp(requeststr, md5secret)) {
07340 res = 0;
07341 break;
07342 }
07343 }
07344 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07345 if (!strcmp(secret, p->secret))
07346 res = 0;
07347 }
07348 return res;
07349 }
07350
07351
07352 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07353 {
07354 char requeststr[256] = "";
07355 char peer[256] = "";
07356 char md5secret[256] = "";
07357 char rsasecret[256] = "";
07358 char secret[256] = "";
07359 struct iax2_peer *p = NULL;
07360 struct ast_key *key;
07361 char *keyn;
07362 int x;
07363 int expire = 0;
07364 int res = -1;
07365
07366 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07367
07368 if (ies->username)
07369 ast_copy_string(peer, ies->username, sizeof(peer));
07370 if (ies->password)
07371 ast_copy_string(secret, ies->password, sizeof(secret));
07372 if (ies->md5_result)
07373 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07374 if (ies->rsa_result)
07375 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07376 if (ies->refresh)
07377 expire = ies->refresh;
07378
07379 if (ast_strlen_zero(peer)) {
07380 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07381 return -1;
07382 }
07383
07384
07385 ast_mutex_unlock(&iaxsl[callno]);
07386 p = find_peer(peer, 1);
07387 ast_mutex_lock(&iaxsl[callno]);
07388 if (!p || !iaxs[callno]) {
07389 if (iaxs[callno]) {
07390 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07391
07392 ast_string_field_set(iaxs[callno], secret, "badsecret");
07393
07394
07395
07396
07397
07398
07399
07400
07401
07402 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07403 !(!ast_strlen_zero(secret) && plaintext)) {
07404
07405 res = 0;
07406 }
07407 }
07408 if (authdebug && !p)
07409 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07410 goto return_unref;
07411 }
07412
07413 if (!ast_test_flag(p, IAX_DYNAMIC)) {
07414 if (authdebug)
07415 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07416 goto return_unref;
07417 }
07418
07419 if (!ast_apply_ha(p->ha, sin)) {
07420 if (authdebug)
07421 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07422 goto return_unref;
07423 }
07424 ast_string_field_set(iaxs[callno], secret, p->secret);
07425 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07426
07427 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07428 if (!ast_strlen_zero(p->inkeys)) {
07429 char tmpkeys[256];
07430 char *stringp=NULL;
07431 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07432 stringp=tmpkeys;
07433 keyn = strsep(&stringp, ":");
07434 while(keyn) {
07435 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07436 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07437 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07438 break;
07439 } else if (!key)
07440 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
07441 keyn = strsep(&stringp, ":");
07442 }
07443 if (!keyn) {
07444 if (authdebug)
07445 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
07446 goto return_unref;
07447 }
07448 } else {
07449 if (authdebug)
07450 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
07451 goto return_unref;
07452 }
07453 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07454 struct MD5Context md5;
07455 unsigned char digest[16];
07456 char *tmppw, *stringp;
07457
07458 tmppw = ast_strdupa(p->secret);
07459 stringp = tmppw;
07460 while((tmppw = strsep(&stringp, ";"))) {
07461 MD5Init(&md5);
07462 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
07463 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07464 MD5Final(digest, &md5);
07465 for (x=0;x<16;x++)
07466 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07467 if (!strcasecmp(requeststr, md5secret))
07468 break;
07469 }
07470 if (tmppw) {
07471 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07472 } else {
07473 if (authdebug)
07474 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
07475 goto return_unref;
07476 }
07477 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
07478
07479 if (strcmp(secret, p->secret)) {
07480 if (authdebug)
07481 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07482 goto return_unref;
07483 } else
07484 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07485 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
07486
07487 goto return_unref;
07488 }
07489 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
07490
07491
07492 res = 0;
07493
07494 return_unref:
07495 if (iaxs[callno]) {
07496 ast_string_field_set(iaxs[callno], peer, peer);
07497
07498
07499 if (expire && (expire < iaxs[callno]->expiry)) {
07500 iaxs[callno]->expiry = expire;
07501 }
07502 }
07503
07504 if (p) {
07505 peer_unref(p);
07506 }
07507 return res;
07508 }
07509
07510 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)
07511 {
07512 int res = -1;
07513 int x;
07514 if (!ast_strlen_zero(keyn)) {
07515 if (!(authmethods & IAX_AUTH_RSA)) {
07516 if (ast_strlen_zero(secret))
07517 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));
07518 } else if (ast_strlen_zero(challenge)) {
07519 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
07520 } else {
07521 char sig[256];
07522 struct ast_key *key;
07523 key = ast_key_get(keyn, AST_KEY_PRIVATE);
07524 if (!key) {
07525 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
07526 } else {
07527 if (ast_sign(key, (char*)challenge, sig)) {
07528 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
07529 res = -1;
07530 } else {
07531 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
07532 res = 0;
07533 }
07534 }
07535 }
07536 }
07537
07538 if (res && !ast_strlen_zero(secret)) {
07539 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
07540 struct MD5Context md5;
07541 unsigned char digest[16];
07542 char digres[128];
07543 MD5Init(&md5);
07544 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
07545 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
07546 MD5Final(digest, &md5);
07547
07548 for (x=0;x<16;x++)
07549 sprintf(digres + (x << 1), "%2.2x", digest[x]);
07550 if (pvt) {
07551 build_encryption_keys(digest, pvt);
07552 }
07553 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
07554 res = 0;
07555 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
07556 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
07557 res = 0;
07558 } else
07559 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
07560 }
07561 return res;
07562 }
07563
07564
07565
07566
07567
07568 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
07569 {
07570 struct iax2_peer *peer = NULL;
07571
07572 int res = -1;
07573 int authmethods = 0;
07574 struct iax_ie_data ied;
07575 uint16_t callno = p->callno;
07576
07577 memset(&ied, 0, sizeof(ied));
07578
07579 if (ies->username)
07580 ast_string_field_set(p, username, ies->username);
07581 if (ies->challenge)
07582 ast_string_field_set(p, challenge, ies->challenge);
07583 if (ies->authmethods)
07584 authmethods = ies->authmethods;
07585 if (authmethods & IAX_AUTH_MD5)
07586 merge_encryption(p, ies->encmethods);
07587 else
07588 p->encmethods = 0;
07589
07590
07591 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
07592
07593 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
07594 } else {
07595 struct ao2_iterator i = ao2_iterator_init(peers, 0);
07596 while ((peer = ao2_iterator_next(&i))) {
07597 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
07598
07599 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
07600
07601 && (!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)))
07602
07603 ) {
07604 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
07605 if (!res) {
07606 peer_unref(peer);
07607 break;
07608 }
07609 }
07610 peer_unref(peer);
07611 }
07612 if (!peer) {
07613
07614
07615 const char *peer_name = ast_strdupa(p->peer);
07616 ast_mutex_unlock(&iaxsl[callno]);
07617 if ((peer = realtime_peer(peer_name, NULL))) {
07618 ast_mutex_lock(&iaxsl[callno]);
07619 if (!(p = iaxs[callno])) {
07620 peer_unref(peer);
07621 return -1;
07622 }
07623 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
07624 peer_unref(peer);
07625 }
07626 if (!peer) {
07627 ast_mutex_lock(&iaxsl[callno]);
07628 if (!(p = iaxs[callno]))
07629 return -1;
07630 }
07631 }
07632 }
07633 if (ies->encmethods)
07634 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
07635 if (!res) {
07636 struct ast_datastore *variablestore;
07637 struct ast_variable *var, *prev = NULL;
07638 AST_LIST_HEAD(, ast_var_t) *varlist;
07639 varlist = ast_calloc(1, sizeof(*varlist));
07640 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
07641 if (variablestore && varlist && p->owner) {
07642 variablestore->data = varlist;
07643 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
07644 AST_LIST_HEAD_INIT(varlist);
07645 for (var = ies->vars; var; var = var->next) {
07646 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
07647 if (prev)
07648 ast_free(prev);
07649 prev = var;
07650 if (!newvar) {
07651
07652 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07653 } else {
07654 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
07655 }
07656 }
07657 if (prev)
07658 ast_free(prev);
07659 ies->vars = NULL;
07660 ast_channel_datastore_add(p->owner, variablestore);
07661 } else {
07662 if (p->owner)
07663 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07664 if (variablestore)
07665 ast_datastore_free(variablestore);
07666 if (varlist)
07667 ast_free(varlist);
07668 }
07669 }
07670
07671 if (!res)
07672 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
07673 return res;
07674 }
07675
07676 static int iax2_do_register(struct iax2_registry *reg);
07677
07678 static void __iax2_do_register_s(const void *data)
07679 {
07680 struct iax2_registry *reg = (struct iax2_registry *)data;
07681 reg->expire = -1;
07682 iax2_do_register(reg);
07683 }
07684
07685 static int iax2_do_register_s(const void *data)
07686 {
07687 #ifdef SCHED_MULTITHREADED
07688 if (schedule_action(__iax2_do_register_s, data))
07689 #endif
07690 __iax2_do_register_s(data);
07691 return 0;
07692 }
07693
07694 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07695 {
07696 int newcall = 0;
07697 char newip[256];
07698 struct iax_ie_data ied;
07699 struct sockaddr_in new;
07700
07701
07702 memset(&ied, 0, sizeof(ied));
07703 if (ies->apparent_addr)
07704 memmove(&new, ies->apparent_addr, sizeof(new));
07705 if (ies->callno)
07706 newcall = ies->callno;
07707 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
07708 ast_log(LOG_WARNING, "Invalid transfer request\n");
07709 return -1;
07710 }
07711 pvt->transfercallno = newcall;
07712 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
07713 inet_aton(newip, &pvt->transfer.sin_addr);
07714 pvt->transfer.sin_family = AF_INET;
07715 pvt->transferring = TRANSFER_BEGIN;
07716 pvt->transferid = ies->transferid;
07717 store_by_transfercallno(pvt);
07718 if (ies->transferid)
07719 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
07720 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
07721 return 0;
07722 }
07723
07724 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07725 {
07726 char exten[256] = "";
07727 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
07728 struct iax2_dpcache *dp = NULL;
07729
07730 if (ies->called_number)
07731 ast_copy_string(exten, ies->called_number, sizeof(exten));
07732
07733 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
07734 status = CACHE_FLAG_EXISTS;
07735 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
07736 status = CACHE_FLAG_CANEXIST;
07737 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
07738 status = CACHE_FLAG_NONEXISTENT;
07739
07740 if (ies->refresh)
07741 expiry = ies->refresh;
07742 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
07743 matchmore = CACHE_FLAG_MATCHMORE;
07744
07745 AST_LIST_LOCK(&dpcache);
07746 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
07747 if (strcmp(dp->exten, exten))
07748 continue;
07749 AST_LIST_REMOVE_CURRENT(peer_list);
07750 dp->callno = 0;
07751 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
07752 if (dp->flags & CACHE_FLAG_PENDING) {
07753 dp->flags &= ~CACHE_FLAG_PENDING;
07754 dp->flags |= status;
07755 dp->flags |= matchmore;
07756 }
07757
07758 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
07759 if (dp->waiters[x] > -1) {
07760 if (write(dp->waiters[x], "asdf", 4) < 0) {
07761 }
07762 }
07763 }
07764 }
07765 AST_LIST_TRAVERSE_SAFE_END;
07766 AST_LIST_UNLOCK(&dpcache);
07767
07768 return 0;
07769 }
07770
07771 static int complete_transfer(int callno, struct iax_ies *ies)
07772 {
07773 int peercallno = 0;
07774 struct chan_iax2_pvt *pvt = iaxs[callno];
07775 struct iax_frame *cur;
07776 jb_frame frame;
07777
07778 if (ies->callno)
07779 peercallno = ies->callno;
07780
07781 if (peercallno < 1) {
07782 ast_log(LOG_WARNING, "Invalid transfer request\n");
07783 return -1;
07784 }
07785 remove_by_transfercallno(pvt);
07786
07787
07788
07789 peercnt_remove_by_addr(&pvt->addr);
07790 peercnt_add(&pvt->transfer);
07791
07792 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
07793 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
07794
07795 pvt->oseqno = 0;
07796 pvt->rseqno = 0;
07797 pvt->iseqno = 0;
07798 pvt->aseqno = 0;
07799
07800 if (pvt->peercallno) {
07801 remove_by_peercallno(pvt);
07802 }
07803 pvt->peercallno = peercallno;
07804
07805 store_by_peercallno(pvt);
07806 pvt->transferring = TRANSFER_NONE;
07807 pvt->svoiceformat = -1;
07808 pvt->voiceformat = 0;
07809 pvt->svideoformat = -1;
07810 pvt->videoformat = 0;
07811 pvt->transfercallno = -1;
07812 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
07813 memset(&pvt->offset, 0, sizeof(pvt->offset));
07814
07815 while(jb_getall(pvt->jb,&frame) == JB_OK)
07816 iax2_frame_free(frame.data);
07817 jb_reset(pvt->jb);
07818 pvt->lag = 0;
07819 pvt->last = 0;
07820 pvt->lastsent = 0;
07821 pvt->nextpred = 0;
07822 pvt->pingtime = DEFAULT_RETRY_TIME;
07823 AST_LIST_LOCK(&frame_queue);
07824 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
07825
07826
07827
07828 if (callno == cur->callno)
07829 cur->retries = -1;
07830 }
07831 AST_LIST_UNLOCK(&frame_queue);
07832 return 0;
07833 }
07834
07835
07836 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
07837 {
07838 struct iax2_registry *reg;
07839
07840 char peer[256] = "";
07841 char msgstatus[60];
07842 int refresh = 60;
07843 char ourip[256] = "<Unspecified>";
07844 struct sockaddr_in oldus;
07845 struct sockaddr_in us;
07846 int oldmsgs;
07847
07848 memset(&us, 0, sizeof(us));
07849 if (ies->apparent_addr)
07850 memmove(&us, ies->apparent_addr, sizeof(us));
07851 if (ies->username)
07852 ast_copy_string(peer, ies->username, sizeof(peer));
07853 if (ies->refresh)
07854 refresh = ies->refresh;
07855 if (ies->calling_number) {
07856
07857 }
07858 reg = iaxs[callno]->reg;
07859 if (!reg) {
07860 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
07861 return -1;
07862 }
07863 memcpy(&oldus, ®->us, sizeof(oldus));
07864 oldmsgs = reg->messages;
07865 if (inaddrcmp(®->addr, sin)) {
07866 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07867 return -1;
07868 }
07869 memcpy(®->us, &us, sizeof(reg->us));
07870 if (ies->msgcount >= 0)
07871 reg->messages = ies->msgcount & 0xffff;
07872
07873
07874
07875 reg->refresh = refresh;
07876 reg->expire = iax2_sched_replace(reg->expire, sched,
07877 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07878 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
07879 if (reg->messages > 255)
07880 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
07881 else if (reg->messages > 1)
07882 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
07883 else if (reg->messages > 0)
07884 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
07885 else
07886 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
07887 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07888 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
07889 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
07890 }
07891 reg->regstate = REG_STATE_REGISTERED;
07892 return 0;
07893 }
07894
07895 static int iax2_append_register(const char *hostname, const char *username,
07896 const char *secret, const char *porta)
07897 {
07898 struct iax2_registry *reg;
07899
07900 if (!(reg = ast_calloc(1, sizeof(*reg))))
07901 return -1;
07902
07903 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
07904 ast_free(reg);
07905 return -1;
07906 }
07907
07908 ast_copy_string(reg->username, username, sizeof(reg->username));
07909
07910 if (secret)
07911 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
07912
07913 reg->expire = -1;
07914 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
07915 reg->addr.sin_family = AF_INET;
07916 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
07917
07918 AST_LIST_LOCK(®istrations);
07919 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
07920 AST_LIST_UNLOCK(®istrations);
07921
07922 return 0;
07923 }
07924
07925 static int iax2_register(const char *value, int lineno)
07926 {
07927 char copy[256];
07928 char *username, *hostname, *secret;
07929 char *porta;
07930 char *stringp=NULL;
07931
07932 if (!value)
07933 return -1;
07934
07935 ast_copy_string(copy, value, sizeof(copy));
07936 stringp = copy;
07937 username = strsep(&stringp, "@");
07938 hostname = strsep(&stringp, "@");
07939
07940 if (!hostname) {
07941 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
07942 return -1;
07943 }
07944
07945 stringp = username;
07946 username = strsep(&stringp, ":");
07947 secret = strsep(&stringp, ":");
07948 stringp = hostname;
07949 hostname = strsep(&stringp, ":");
07950 porta = strsep(&stringp, ":");
07951
07952 if (porta && !atoi(porta)) {
07953 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
07954 return -1;
07955 }
07956
07957 return iax2_append_register(hostname, username, secret, porta);
07958 }
07959
07960
07961 static void register_peer_exten(struct iax2_peer *peer, int onoff)
07962 {
07963 char multi[256];
07964 char *stringp, *ext;
07965 if (!ast_strlen_zero(regcontext)) {
07966 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
07967 stringp = multi;
07968 while((ext = strsep(&stringp, "&"))) {
07969 if (onoff) {
07970 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
07971 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
07972 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
07973 } else
07974 ast_context_remove_extension(regcontext, ext, 1, NULL);
07975 }
07976 }
07977 }
07978 static void prune_peers(void);
07979
07980 static void unlink_peer(struct iax2_peer *peer)
07981 {
07982 if (peer->expire > -1) {
07983 if (!ast_sched_del(sched, peer->expire)) {
07984 peer->expire = -1;
07985 peer_unref(peer);
07986 }
07987 }
07988
07989 if (peer->pokeexpire > -1) {
07990 if (!ast_sched_del(sched, peer->pokeexpire)) {
07991 peer->pokeexpire = -1;
07992 peer_unref(peer);
07993 }
07994 }
07995
07996 ao2_unlink(peers, peer);
07997 }
07998
07999 static void __expire_registry(const void *data)
08000 {
08001 struct iax2_peer *peer = (struct iax2_peer *) data;
08002
08003 if (!peer)
08004 return;
08005
08006 peer->expire = -1;
08007
08008 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08009 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08010 realtime_update_peer(peer->name, &peer->addr, 0);
08011 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08012
08013 peercnt_modify(0, 0, &peer->addr);
08014
08015 memset(&peer->addr, 0, sizeof(peer->addr));
08016
08017 peer->expiry = min_reg_expire;
08018 if (!ast_test_flag(peer, IAX_TEMPONLY))
08019 ast_db_del("IAX/Registry", peer->name);
08020 register_peer_exten(peer, 0);
08021 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08022 if (iax2_regfunk)
08023 iax2_regfunk(peer->name, 0);
08024
08025 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
08026 unlink_peer(peer);
08027
08028 peer_unref(peer);
08029 }
08030
08031 static int expire_registry(const void *data)
08032 {
08033 #ifdef SCHED_MULTITHREADED
08034 if (schedule_action(__expire_registry, data))
08035 #endif
08036 __expire_registry(data);
08037 return 0;
08038 }
08039
08040 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08041
08042 static void reg_source_db(struct iax2_peer *p)
08043 {
08044 char data[80];
08045 struct in_addr in;
08046 char *c, *d;
08047 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
08048 c = strchr(data, ':');
08049 if (c) {
08050 *c = '\0';
08051 c++;
08052 if (inet_aton(data, &in)) {
08053 d = strchr(c, ':');
08054 if (d) {
08055 *d = '\0';
08056 d++;
08057 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
08058 ast_inet_ntoa(in), atoi(c), atoi(d));
08059 iax2_poke_peer(p, 0);
08060 p->expiry = atoi(d);
08061 memset(&p->addr, 0, sizeof(p->addr));
08062 p->addr.sin_family = AF_INET;
08063 p->addr.sin_addr = in;
08064 p->addr.sin_port = htons(atoi(c));
08065 if (p->expire > -1) {
08066 if (!ast_sched_del(sched, p->expire)) {
08067 p->expire = -1;
08068 peer_unref(p);
08069 }
08070 }
08071 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08072 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08073 if (p->expire == -1)
08074 peer_unref(p);
08075 if (iax2_regfunk)
08076 iax2_regfunk(p->name, 1);
08077 register_peer_exten(p, 1);
08078 }
08079
08080 }
08081 }
08082 }
08083 }
08084
08085
08086
08087
08088
08089
08090
08091 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08092 {
08093
08094 struct iax_ie_data ied;
08095 struct iax2_peer *p;
08096 int msgcount;
08097 char data[80];
08098 int version;
08099 const char *peer_name;
08100 int res = -1;
08101
08102 memset(&ied, 0, sizeof(ied));
08103
08104 peer_name = ast_strdupa(iaxs[callno]->peer);
08105
08106
08107 ast_mutex_unlock(&iaxsl[callno]);
08108 if (!(p = find_peer(peer_name, 1))) {
08109 ast_mutex_lock(&iaxsl[callno]);
08110 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08111 return -1;
08112 }
08113 ast_mutex_lock(&iaxsl[callno]);
08114 if (!iaxs[callno])
08115 goto return_unref;
08116
08117 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08118 if (sin->sin_addr.s_addr) {
08119 time_t nowtime;
08120 time(&nowtime);
08121 realtime_update_peer(peer_name, sin, nowtime);
08122 } else {
08123 realtime_update_peer(peer_name, sin, 0);
08124 }
08125 }
08126 if (inaddrcmp(&p->addr, sin)) {
08127 if (iax2_regfunk)
08128 iax2_regfunk(p->name, 1);
08129
08130
08131 peercnt_modify(0, 0, &p->addr);
08132
08133
08134 memcpy(&p->addr, sin, sizeof(p->addr));
08135
08136 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08137 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08138 ast_db_put("IAX/Registry", p->name, data);
08139 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08140 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08141 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08142 register_peer_exten(p, 1);
08143 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08144 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
08145 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08146 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08147 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08148 register_peer_exten(p, 0);
08149 ast_db_del("IAX/Registry", p->name);
08150 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08151 }
08152
08153
08154 iax2_poke_peer(p, callno);
08155 }
08156
08157
08158 if (p->maxcallno) {
08159 peercnt_modify(1, p->maxcallno, &p->addr);
08160 }
08161
08162
08163 if (!iaxs[callno]) {
08164 res = -1;
08165 goto return_unref;
08166 }
08167
08168
08169 p->sockfd = fd;
08170
08171 if (p->expire > -1) {
08172 if (!ast_sched_del(sched, p->expire)) {
08173 p->expire = -1;
08174 peer_unref(p);
08175 }
08176 }
08177
08178 if (!refresh)
08179 refresh = min_reg_expire;
08180 if (refresh > max_reg_expire) {
08181 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08182 p->name, max_reg_expire, refresh);
08183 p->expiry = max_reg_expire;
08184 } else if (refresh < min_reg_expire) {
08185 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08186 p->name, min_reg_expire, refresh);
08187 p->expiry = min_reg_expire;
08188 } else {
08189 p->expiry = refresh;
08190 }
08191 if (p->expiry && sin->sin_addr.s_addr) {
08192 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08193 if (p->expire == -1)
08194 peer_unref(p);
08195 }
08196 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08197 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08198 if (sin->sin_addr.s_addr) {
08199 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08200 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
08201 if (!ast_strlen_zero(p->mailbox)) {
08202 struct ast_event *event;
08203 int new, old;
08204 char *mailbox, *context;
08205
08206 context = mailbox = ast_strdupa(p->mailbox);
08207 strsep(&context, "@");
08208 if (ast_strlen_zero(context))
08209 context = "default";
08210
08211 event = ast_event_get_cached(AST_EVENT_MWI,
08212 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08213 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08214 AST_EVENT_IE_END);
08215 if (event) {
08216 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08217 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08218 ast_event_destroy(event);
08219 } else {
08220 ast_app_inboxcount(p->mailbox, &new, &old);
08221 }
08222
08223 if (new > 255) {
08224 new = 255;
08225 }
08226 if (old > 255) {
08227 old = 255;
08228 }
08229 msgcount = (old << 8) | new;
08230
08231 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08232 }
08233 if (ast_test_flag(p, IAX_HASCALLERID)) {
08234 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08235 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08236 }
08237 }
08238 version = iax_check_version(devtype);
08239 if (version)
08240 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08241
08242 res = 0;
08243
08244 return_unref:
08245 peer_unref(p);
08246
08247 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08248 }
08249
08250 static int registry_authrequest(int callno)
08251 {
08252 struct iax_ie_data ied;
08253 struct iax2_peer *p;
08254 char challenge[10];
08255 const char *peer_name;
08256 int sentauthmethod;
08257
08258 peer_name = ast_strdupa(iaxs[callno]->peer);
08259
08260
08261 ast_mutex_unlock(&iaxsl[callno]);
08262 if ((p = find_peer(peer_name, 1))) {
08263 last_authmethod = p->authmethods;
08264 }
08265
08266 ast_mutex_lock(&iaxsl[callno]);
08267 if (!iaxs[callno])
08268 goto return_unref;
08269
08270 memset(&ied, 0, sizeof(ied));
08271
08272
08273
08274
08275
08276
08277 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08278 if (!p) {
08279 iaxs[callno]->authmethods = sentauthmethod;
08280 }
08281 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08282 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08283
08284 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08285 ast_string_field_set(iaxs[callno], challenge, challenge);
08286 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08287 }
08288 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08289
08290 return_unref:
08291 if (p) {
08292 peer_unref(p);
08293 }
08294
08295 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08296 }
08297
08298 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08299 {
08300 struct iax2_registry *reg;
08301
08302 struct iax_ie_data ied;
08303 char peer[256] = "";
08304 char challenge[256] = "";
08305 int res;
08306 int authmethods = 0;
08307 if (ies->authmethods)
08308 authmethods = ies->authmethods;
08309 if (ies->username)
08310 ast_copy_string(peer, ies->username, sizeof(peer));
08311 if (ies->challenge)
08312 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08313 memset(&ied, 0, sizeof(ied));
08314 reg = iaxs[callno]->reg;
08315 if (reg) {
08316 if (inaddrcmp(®->addr, sin)) {
08317 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08318 return -1;
08319 }
08320 if (ast_strlen_zero(reg->secret)) {
08321 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08322 reg->regstate = REG_STATE_NOAUTH;
08323 return -1;
08324 }
08325 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08326 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08327 if (reg->secret[0] == '[') {
08328 char tmpkey[256];
08329 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08330 tmpkey[strlen(tmpkey) - 1] = '\0';
08331 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08332 } else
08333 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08334 if (!res) {
08335 reg->regstate = REG_STATE_AUTHSENT;
08336 add_empty_calltoken_ie(iaxs[callno], &ied);
08337 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08338 } else
08339 return -1;
08340 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08341 } else
08342 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08343 return -1;
08344 }
08345
08346 static void stop_stuff(int callno)
08347 {
08348 iax2_destroy_helper(iaxs[callno]);
08349 }
08350
08351 static void __auth_reject(const void *nothing)
08352 {
08353
08354 int callno = (int)(long)(nothing);
08355 struct iax_ie_data ied;
08356 ast_mutex_lock(&iaxsl[callno]);
08357 if (iaxs[callno]) {
08358 memset(&ied, 0, sizeof(ied));
08359 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08360 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08361 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08362 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08363 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08364 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08365 }
08366 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08367 }
08368 ast_mutex_unlock(&iaxsl[callno]);
08369 }
08370
08371 static int auth_reject(const void *data)
08372 {
08373 int callno = (int)(long)(data);
08374 ast_mutex_lock(&iaxsl[callno]);
08375 if (iaxs[callno])
08376 iaxs[callno]->authid = -1;
08377 ast_mutex_unlock(&iaxsl[callno]);
08378 #ifdef SCHED_MULTITHREADED
08379 if (schedule_action(__auth_reject, data))
08380 #endif
08381 __auth_reject(data);
08382 return 0;
08383 }
08384
08385 static int auth_fail(int callno, int failcode)
08386 {
08387
08388
08389 if (iaxs[callno]) {
08390 iaxs[callno]->authfail = failcode;
08391 if (delayreject) {
08392 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08393 sched, 1000, auth_reject, (void *)(long)callno);
08394 } else
08395 auth_reject((void *)(long)callno);
08396 }
08397 return 0;
08398 }
08399
08400 static void __auto_hangup(const void *nothing)
08401 {
08402
08403 int callno = (int)(long)(nothing);
08404 struct iax_ie_data ied;
08405 ast_mutex_lock(&iaxsl[callno]);
08406 if (iaxs[callno]) {
08407 memset(&ied, 0, sizeof(ied));
08408 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08409 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
08410 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
08411 }
08412 ast_mutex_unlock(&iaxsl[callno]);
08413 }
08414
08415 static int auto_hangup(const void *data)
08416 {
08417 int callno = (int)(long)(data);
08418 ast_mutex_lock(&iaxsl[callno]);
08419 if (iaxs[callno]) {
08420 iaxs[callno]->autoid = -1;
08421 }
08422 ast_mutex_unlock(&iaxsl[callno]);
08423 #ifdef SCHED_MULTITHREADED
08424 if (schedule_action(__auto_hangup, data))
08425 #endif
08426 __auto_hangup(data);
08427 return 0;
08428 }
08429
08430 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
08431 {
08432 struct iax_ie_data ied;
08433
08434 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
08435 sched, 30000, auto_hangup, (void *)(long)callno);
08436 memset(&ied, 0, sizeof(ied));
08437 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
08438 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
08439 dp->flags |= CACHE_FLAG_TRANSMITTED;
08440 }
08441
08442 static int iax2_vnak(int callno)
08443 {
08444 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
08445 }
08446
08447 static void vnak_retransmit(int callno, int last)
08448 {
08449 struct iax_frame *f;
08450
08451 AST_LIST_LOCK(&frame_queue);
08452 AST_LIST_TRAVERSE(&frame_queue, f, list) {
08453
08454 if ((f->callno == callno) && iaxs[f->callno] &&
08455 ((unsigned char ) (f->oseqno - last) < 128) &&
08456 (f->retries >= 0)) {
08457 send_packet(f);
08458 }
08459 }
08460 AST_LIST_UNLOCK(&frame_queue);
08461 }
08462
08463 static void __iax2_poke_peer_s(const void *data)
08464 {
08465 struct iax2_peer *peer = (struct iax2_peer *)data;
08466 iax2_poke_peer(peer, 0);
08467 peer_unref(peer);
08468 }
08469
08470 static int iax2_poke_peer_s(const void *data)
08471 {
08472 struct iax2_peer *peer = (struct iax2_peer *)data;
08473 peer->pokeexpire = -1;
08474 #ifdef SCHED_MULTITHREADED
08475 if (schedule_action(__iax2_poke_peer_s, data))
08476 #endif
08477 __iax2_poke_peer_s(data);
08478 return 0;
08479 }
08480
08481 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
08482 {
08483 int res = 0;
08484 struct iax_frame *fr;
08485 struct ast_iax2_meta_hdr *meta;
08486 struct ast_iax2_meta_trunk_hdr *mth;
08487 int calls = 0;
08488
08489
08490 fr = (struct iax_frame *)tpeer->trunkdata;
08491
08492 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
08493 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
08494 if (tpeer->trunkdatalen) {
08495
08496 meta->zeros = 0;
08497 meta->metacmd = IAX_META_TRUNK;
08498 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
08499 meta->cmddata = IAX_META_TRUNK_MINI;
08500 else
08501 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
08502 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
08503
08504 fr->direction = DIRECTION_OUTGRESS;
08505 fr->retrans = -1;
08506 fr->transfer = 0;
08507
08508 fr->data = fr->afdata;
08509 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
08510 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
08511 calls = tpeer->calls;
08512 #if 0
08513 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));
08514 #endif
08515
08516 tpeer->trunkdatalen = 0;
08517 tpeer->calls = 0;
08518 }
08519 if (res < 0)
08520 return res;
08521 return calls;
08522 }
08523
08524 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
08525 {
08526
08527 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
08528 return 1;
08529 return 0;
08530 }
08531
08532 static int timing_read(int *id, int fd, short events, void *cbdata)
08533 {
08534 int res, processed = 0, totalcalls = 0;
08535 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
08536 struct timeval now = ast_tvnow();
08537
08538 if (iaxtrunkdebug)
08539 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
08540
08541 if (timer) {
08542 ast_timer_ack(timer, 1);
08543 }
08544
08545
08546 AST_LIST_LOCK(&tpeers);
08547 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
08548 processed++;
08549 res = 0;
08550 ast_mutex_lock(&tpeer->lock);
08551
08552
08553 if (!drop && iax2_trunk_expired(tpeer, &now)) {
08554
08555
08556 AST_LIST_REMOVE_CURRENT(list);
08557 drop = tpeer;
08558 } else {
08559 res = send_trunk(tpeer, &now);
08560 trunk_timed++;
08561 if (iaxtrunkdebug)
08562 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);
08563 }
08564 totalcalls += res;
08565 res = 0;
08566 ast_mutex_unlock(&tpeer->lock);
08567 }
08568 AST_LIST_TRAVERSE_SAFE_END;
08569 AST_LIST_UNLOCK(&tpeers);
08570
08571 if (drop) {
08572 ast_mutex_lock(&drop->lock);
08573
08574
08575 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
08576 if (drop->trunkdata) {
08577 ast_free(drop->trunkdata);
08578 drop->trunkdata = NULL;
08579 }
08580 ast_mutex_unlock(&drop->lock);
08581 ast_mutex_destroy(&drop->lock);
08582 ast_free(drop);
08583
08584 }
08585
08586 if (iaxtrunkdebug)
08587 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
08588 iaxtrunkdebug = 0;
08589
08590 return 1;
08591 }
08592
08593 struct dpreq_data {
08594 int callno;
08595 char context[AST_MAX_EXTENSION];
08596 char callednum[AST_MAX_EXTENSION];
08597 char *callerid;
08598 };
08599
08600 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
08601 {
08602 unsigned short dpstatus = 0;
08603 struct iax_ie_data ied1;
08604 int mm;
08605
08606 memset(&ied1, 0, sizeof(ied1));
08607 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
08608
08609 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
08610 dpstatus = IAX_DPSTATUS_EXISTS;
08611 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
08612 dpstatus = IAX_DPSTATUS_CANEXIST;
08613 } else {
08614 dpstatus = IAX_DPSTATUS_NONEXISTENT;
08615 }
08616 if (ast_ignore_pattern(context, callednum))
08617 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
08618 if (mm)
08619 dpstatus |= IAX_DPSTATUS_MATCHMORE;
08620 if (!skiplock)
08621 ast_mutex_lock(&iaxsl[callno]);
08622 if (iaxs[callno]) {
08623 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
08624 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
08625 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
08626 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
08627 }
08628 if (!skiplock)
08629 ast_mutex_unlock(&iaxsl[callno]);
08630 }
08631
08632 static void *dp_lookup_thread(void *data)
08633 {
08634
08635 struct dpreq_data *dpr = data;
08636 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
08637 if (dpr->callerid)
08638 ast_free(dpr->callerid);
08639 ast_free(dpr);
08640 return NULL;
08641 }
08642
08643 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
08644 {
08645 pthread_t newthread;
08646 struct dpreq_data *dpr;
08647
08648 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
08649 return;
08650
08651 dpr->callno = callno;
08652 ast_copy_string(dpr->context, context, sizeof(dpr->context));
08653 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
08654 if (callerid)
08655 dpr->callerid = ast_strdup(callerid);
08656 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
08657 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
08658 }
08659 }
08660
08661 struct iax_dual {
08662 struct ast_channel *chan1;
08663 struct ast_channel *chan2;
08664 };
08665
08666 static void *iax_park_thread(void *stuff)
08667 {
08668 struct ast_channel *chan1, *chan2;
08669 struct iax_dual *d;
08670 struct ast_frame *f;
08671 int ext;
08672 int res;
08673 d = stuff;
08674 chan1 = d->chan1;
08675 chan2 = d->chan2;
08676 ast_free(d);
08677 f = ast_read(chan1);
08678 if (f)
08679 ast_frfree(f);
08680 res = ast_park_call(chan1, chan2, 0, &ext);
08681 ast_hangup(chan2);
08682 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
08683 return NULL;
08684 }
08685
08686 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
08687 {
08688 struct iax_dual *d;
08689 struct ast_channel *chan1m, *chan2m;
08690 pthread_t th;
08691 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
08692 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
08693 if (chan2m && chan1m) {
08694
08695 chan1m->readformat = chan1->readformat;
08696 chan1m->writeformat = chan1->writeformat;
08697 ast_channel_masquerade(chan1m, chan1);
08698
08699 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
08700 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
08701 chan1m->priority = chan1->priority;
08702
08703
08704
08705
08706 chan2m->readformat = chan2->readformat;
08707 chan2m->writeformat = chan2->writeformat;
08708 ast_channel_masquerade(chan2m, chan2);
08709
08710 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
08711 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
08712 chan2m->priority = chan2->priority;
08713 if (ast_do_masquerade(chan2m)) {
08714 ast_log(LOG_WARNING, "Masquerade failed :(\n");
08715 ast_hangup(chan2m);
08716 return -1;
08717 }
08718 } else {
08719 if (chan1m)
08720 ast_hangup(chan1m);
08721 if (chan2m)
08722 ast_hangup(chan2m);
08723 return -1;
08724 }
08725 if ((d = ast_calloc(1, sizeof(*d)))) {
08726 d->chan1 = chan1m;
08727 d->chan2 = chan2m;
08728 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
08729 return 0;
08730 }
08731 ast_free(d);
08732 }
08733 return -1;
08734 }
08735
08736
08737 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
08738
08739 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
08740 {
08741 unsigned int ourver;
08742 char rsi[80];
08743 snprintf(rsi, sizeof(rsi), "si-%s", si);
08744 if (iax_provision_version(&ourver, rsi, 1))
08745 return 0;
08746 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
08747 if (ourver != ver)
08748 iax2_provision(sin, sockfd, NULL, rsi, 1);
08749 return 0;
08750 }
08751
08752 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
08753 {
08754 jb_info stats;
08755 jb_getinfo(pvt->jb, &stats);
08756
08757 memset(iep, 0, sizeof(*iep));
08758
08759 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
08760 if(stats.frames_in == 0) stats.frames_in = 1;
08761 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
08762 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
08763 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
08764 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
08765 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
08766 }
08767
08768 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
08769 {
08770 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
08771 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
08772 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
08773 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
08774 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
08775 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
08776 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
08777 }
08778
08779 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
08780 {
08781 int i;
08782 unsigned int length, offset = 0;
08783 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
08784
08785 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
08786 length = ies->ospblocklength[i];
08787 if (length != 0) {
08788 if (length > IAX_MAX_OSPBLOCK_SIZE) {
08789
08790 offset = 0;
08791 break;
08792 } else {
08793 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
08794 offset += length;
08795 }
08796 } else {
08797 break;
08798 }
08799 }
08800 *(full_osptoken + offset) = '\0';
08801 if (strlen(full_osptoken) != offset) {
08802
08803 *full_osptoken = '\0';
08804 }
08805
08806 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
08807 }
08808
08809 static void log_jitterstats(unsigned short callno)
08810 {
08811 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
08812 jb_info jbinfo;
08813
08814 ast_mutex_lock(&iaxsl[callno]);
08815 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
08816 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
08817 jb_getinfo(iaxs[callno]->jb, &jbinfo);
08818 localjitter = jbinfo.jitter;
08819 localdelay = jbinfo.current - jbinfo.min;
08820 locallost = jbinfo.frames_lost;
08821 locallosspct = jbinfo.losspct/1000;
08822 localdropped = jbinfo.frames_dropped;
08823 localooo = jbinfo.frames_ooo;
08824 localpackets = jbinfo.frames_in;
08825 }
08826 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",
08827 iaxs[callno]->owner->name,
08828 iaxs[callno]->pingtime,
08829 localjitter,
08830 localdelay,
08831 locallost,
08832 locallosspct,
08833 localdropped,
08834 localooo,
08835 localpackets,
08836 iaxs[callno]->remote_rr.jitter,
08837 iaxs[callno]->remote_rr.delay,
08838 iaxs[callno]->remote_rr.losscnt,
08839 iaxs[callno]->remote_rr.losspct/1000,
08840 iaxs[callno]->remote_rr.dropped,
08841 iaxs[callno]->remote_rr.ooo,
08842 iaxs[callno]->remote_rr.packets);
08843 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",
08844 iaxs[callno]->owner->name,
08845 iaxs[callno]->pingtime,
08846 localjitter,
08847 localdelay,
08848 locallost,
08849 locallosspct,
08850 localdropped,
08851 localooo,
08852 localpackets,
08853 iaxs[callno]->remote_rr.jitter,
08854 iaxs[callno]->remote_rr.delay,
08855 iaxs[callno]->remote_rr.losscnt,
08856 iaxs[callno]->remote_rr.losspct/1000,
08857 iaxs[callno]->remote_rr.dropped,
08858 iaxs[callno]->remote_rr.ooo,
08859 iaxs[callno]->remote_rr.packets);
08860 }
08861 ast_mutex_unlock(&iaxsl[callno]);
08862 }
08863
08864 static int socket_process(struct iax2_thread *thread);
08865
08866
08867
08868
08869 static void handle_deferred_full_frames(struct iax2_thread *thread)
08870 {
08871 struct iax2_pkt_buf *pkt_buf;
08872
08873 ast_mutex_lock(&thread->lock);
08874
08875 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
08876 ast_mutex_unlock(&thread->lock);
08877
08878 thread->buf = pkt_buf->buf;
08879 thread->buf_len = pkt_buf->len;
08880 thread->buf_size = pkt_buf->len + 1;
08881
08882 socket_process(thread);
08883
08884 thread->buf = NULL;
08885 ast_free(pkt_buf);
08886
08887 ast_mutex_lock(&thread->lock);
08888 }
08889
08890 ast_mutex_unlock(&thread->lock);
08891 }
08892
08893
08894
08895
08896
08897
08898
08899 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
08900 {
08901 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
08902 struct ast_iax2_full_hdr *fh, *cur_fh;
08903
08904 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
08905 return;
08906
08907 pkt_buf->len = from_here->buf_len;
08908 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
08909
08910 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
08911 ast_mutex_lock(&to_here->lock);
08912 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
08913 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
08914 if (fh->oseqno < cur_fh->oseqno) {
08915 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
08916 break;
08917 }
08918 }
08919 AST_LIST_TRAVERSE_SAFE_END
08920
08921 if (!cur_pkt_buf)
08922 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
08923
08924 ast_mutex_unlock(&to_here->lock);
08925 }
08926
08927 static int socket_read(int *id, int fd, short events, void *cbdata)
08928 {
08929 struct iax2_thread *thread;
08930 socklen_t len;
08931 time_t t;
08932 static time_t last_errtime = 0;
08933 struct ast_iax2_full_hdr *fh;
08934
08935 if (!(thread = find_idle_thread())) {
08936 time(&t);
08937 if (t != last_errtime)
08938 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
08939 last_errtime = t;
08940 usleep(1);
08941 return 1;
08942 }
08943
08944 len = sizeof(thread->iosin);
08945 thread->iofd = fd;
08946 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
08947 thread->buf_size = sizeof(thread->readbuf);
08948 thread->buf = thread->readbuf;
08949 if (thread->buf_len < 0) {
08950 if (errno != ECONNREFUSED && errno != EAGAIN)
08951 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
08952 handle_error();
08953 thread->iostate = IAX_IOSTATE_IDLE;
08954 signal_condition(&thread->lock, &thread->cond);
08955 return 1;
08956 }
08957 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
08958 thread->iostate = IAX_IOSTATE_IDLE;
08959 signal_condition(&thread->lock, &thread->cond);
08960 return 1;
08961 }
08962
08963
08964
08965
08966 fh = (struct ast_iax2_full_hdr *) thread->buf;
08967 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
08968 struct iax2_thread *cur = NULL;
08969 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
08970
08971 AST_LIST_LOCK(&active_list);
08972 AST_LIST_TRAVERSE(&active_list, cur, list) {
08973 if ((cur->ffinfo.callno == callno) &&
08974 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
08975 break;
08976 }
08977 if (cur) {
08978
08979
08980 defer_full_frame(thread, cur);
08981 AST_LIST_UNLOCK(&active_list);
08982 thread->iostate = IAX_IOSTATE_IDLE;
08983 signal_condition(&thread->lock, &thread->cond);
08984 return 1;
08985 } else {
08986
08987 thread->ffinfo.callno = callno;
08988 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
08989 thread->ffinfo.type = fh->type;
08990 thread->ffinfo.csub = fh->csub;
08991 }
08992 AST_LIST_UNLOCK(&active_list);
08993 }
08994
08995
08996 thread->iostate = IAX_IOSTATE_READY;
08997 #ifdef DEBUG_SCHED_MULTITHREAD
08998 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
08999 #endif
09000 signal_condition(&thread->lock, &thread->cond);
09001
09002 return 1;
09003 }
09004
09005 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09006 struct iax_frame *fr)
09007 {
09008 unsigned char metatype;
09009 struct ast_iax2_meta_trunk_mini *mtm;
09010 struct ast_iax2_meta_trunk_hdr *mth;
09011 struct ast_iax2_meta_trunk_entry *mte;
09012 struct iax2_trunk_peer *tpeer;
09013 unsigned int ts;
09014 void *ptr;
09015 struct timeval rxtrunktime;
09016 struct ast_frame f = { 0, };
09017
09018 if (packet_len < sizeof(*meta)) {
09019 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09020 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09021 return 1;
09022 }
09023
09024 if (meta->metacmd != IAX_META_TRUNK)
09025 return 1;
09026
09027 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09028 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09029 (int) (sizeof(*meta) + sizeof(*mth)));
09030 return 1;
09031 }
09032 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09033 ts = ntohl(mth->ts);
09034 metatype = meta->cmddata;
09035 packet_len -= (sizeof(*meta) + sizeof(*mth));
09036 ptr = mth->data;
09037 tpeer = find_tpeer(sin, sockfd);
09038 if (!tpeer) {
09039 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09040 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09041 return 1;
09042 }
09043 tpeer->trunkact = ast_tvnow();
09044 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09045 tpeer->rxtrunktime = tpeer->trunkact;
09046 rxtrunktime = tpeer->rxtrunktime;
09047 ast_mutex_unlock(&tpeer->lock);
09048 while (packet_len >= sizeof(*mte)) {
09049
09050 unsigned short callno, trunked_ts, len;
09051
09052 if (metatype == IAX_META_TRUNK_MINI) {
09053 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09054 ptr += sizeof(*mtm);
09055 packet_len -= sizeof(*mtm);
09056 len = ntohs(mtm->len);
09057 callno = ntohs(mtm->mini.callno);
09058 trunked_ts = ntohs(mtm->mini.ts);
09059 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09060 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09061 ptr += sizeof(*mte);
09062 packet_len -= sizeof(*mte);
09063 len = ntohs(mte->len);
09064 callno = ntohs(mte->callno);
09065 trunked_ts = 0;
09066 } else {
09067 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09068 break;
09069 }
09070
09071 if (len > packet_len)
09072 break;
09073 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09074 if (!fr->callno)
09075 continue;
09076
09077
09078
09079
09080 memset(&f, 0, sizeof(f));
09081 f.frametype = AST_FRAME_VOICE;
09082 if (!iaxs[fr->callno]) {
09083
09084 } else if (iaxs[fr->callno]->voiceformat == 0) {
09085 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09086 iax2_vnak(fr->callno);
09087 } else {
09088 f.subclass = iaxs[fr->callno]->voiceformat;
09089 f.datalen = len;
09090 if (f.datalen >= 0) {
09091 if (f.datalen)
09092 f.data.ptr = ptr;
09093 else
09094 f.data.ptr = NULL;
09095 if (trunked_ts)
09096 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09097 else
09098 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09099
09100 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09101 struct iax_frame *duped_fr;
09102
09103
09104 f.src = "IAX2";
09105 f.mallocd = 0;
09106 f.offset = 0;
09107 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09108 f.samples = ast_codec_get_samples(&f);
09109 else
09110 f.samples = 0;
09111 fr->outoforder = 0;
09112 iax_frame_wrap(fr, &f);
09113 duped_fr = iaxfrdup2(fr);
09114 if (duped_fr)
09115 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09116 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09117 iaxs[fr->callno]->last = fr->ts;
09118 }
09119 } else {
09120 ast_log(LOG_WARNING, "Datalen < 0?\n");
09121 }
09122 }
09123 ast_mutex_unlock(&iaxsl[fr->callno]);
09124 ptr += len;
09125 packet_len -= len;
09126 }
09127
09128 return 1;
09129 }
09130
09131 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09132 {
09133 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09134 AST_LIST_HEAD(, ast_var_t) *varlist;
09135 struct ast_var_t *var;
09136
09137 if (!variablestore) {
09138 *buf = '\0';
09139 return 0;
09140 }
09141 varlist = variablestore->data;
09142
09143 AST_LIST_LOCK(varlist);
09144 AST_LIST_TRAVERSE(varlist, var, entries) {
09145 if (strcmp(var->name, data) == 0) {
09146 ast_copy_string(buf, var->value, len);
09147 break;
09148 }
09149 }
09150 AST_LIST_UNLOCK(varlist);
09151 return 0;
09152 }
09153
09154 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09155 {
09156 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09157 AST_LIST_HEAD(, ast_var_t) *varlist;
09158 struct ast_var_t *var;
09159
09160 if (!variablestore) {
09161 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09162 if (!variablestore) {
09163 ast_log(LOG_ERROR, "Memory allocation error\n");
09164 return -1;
09165 }
09166 varlist = ast_calloc(1, sizeof(*varlist));
09167 if (!varlist) {
09168 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09169 return -1;
09170 }
09171
09172 AST_LIST_HEAD_INIT(varlist);
09173 variablestore->data = varlist;
09174 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09175 ast_channel_datastore_add(chan, variablestore);
09176 } else
09177 varlist = variablestore->data;
09178
09179 AST_LIST_LOCK(varlist);
09180 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09181 if (strcmp(var->name, data) == 0) {
09182 AST_LIST_REMOVE_CURRENT(entries);
09183 ast_var_delete(var);
09184 break;
09185 }
09186 }
09187 AST_LIST_TRAVERSE_SAFE_END;
09188 var = ast_var_assign(data, value);
09189 if (var)
09190 AST_LIST_INSERT_TAIL(varlist, var, entries);
09191 else
09192 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09193 AST_LIST_UNLOCK(varlist);
09194 return 0;
09195 }
09196
09197 static struct ast_custom_function iaxvar_function = {
09198 .name = "IAXVAR",
09199 .synopsis = "Sets or retrieves a remote variable",
09200 .syntax = "IAXVAR(<varname>)",
09201 .read = acf_iaxvar_read,
09202 .write = acf_iaxvar_write,
09203 };
09204
09205 static int socket_process(struct iax2_thread *thread)
09206 {
09207 struct sockaddr_in sin;
09208 int res;
09209 int updatehistory=1;
09210 int new = NEW_PREVENT;
09211 int dcallno = 0;
09212 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09213 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09214 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09215 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09216 struct iax_frame *fr;
09217 struct iax_frame *cur;
09218 struct ast_frame f = { 0, };
09219 struct ast_channel *c = NULL;
09220 struct iax2_dpcache *dp;
09221 struct iax2_peer *peer;
09222 struct iax_ies ies;
09223 struct iax_ie_data ied0, ied1;
09224 int format;
09225 int fd;
09226 int exists;
09227 int minivid = 0;
09228 char empty[32]="";
09229 struct iax_frame *duped_fr;
09230 char host_pref_buf[128];
09231 char caller_pref_buf[128];
09232 struct ast_codec_pref pref;
09233 char *using_prefs = "mine";
09234
09235
09236 fr = alloca(sizeof(*fr) + 4096);
09237 memset(fr, 0, sizeof(*fr));
09238 fr->afdatalen = 4096;
09239
09240
09241 res = thread->buf_len;
09242 fd = thread->iofd;
09243 memcpy(&sin, &thread->iosin, sizeof(sin));
09244
09245 if (res < sizeof(*mh)) {
09246 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09247 return 1;
09248 }
09249 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09250 if (res < sizeof(*vh)) {
09251 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));
09252 return 1;
09253 }
09254
09255
09256 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09257 minivid = 1;
09258 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09259 return socket_process_meta(res, meta, &sin, fd, fr);
09260
09261 #ifdef DEBUG_SUPPORT
09262 if (res >= sizeof(*fh))
09263 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09264 #endif
09265 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09266 if (res < sizeof(*fh)) {
09267 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));
09268 return 1;
09269 }
09270
09271
09272 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09273
09274 f.frametype = fh->type;
09275 if (f.frametype == AST_FRAME_VIDEO) {
09276 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09277 } else {
09278 f.subclass = uncompress_subclass(fh->csub);
09279 }
09280
09281
09282 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
09283
09284 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09285 return 1;
09286 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
09287
09288 return 1;
09289 }
09290
09291 f.datalen = res - sizeof(*fh);
09292 if (f.datalen) {
09293 if (f.frametype == AST_FRAME_IAX) {
09294 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09295 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09296 return 1;
09297 }
09298 f.data.ptr = NULL;
09299 f.datalen = 0;
09300 } else {
09301 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09302 memset(&ies, 0, sizeof(ies));
09303 }
09304 } else {
09305 if (f.frametype == AST_FRAME_IAX)
09306 f.data.ptr = NULL;
09307 else
09308 f.data.ptr = empty;
09309 memset(&ies, 0, sizeof(ies));
09310 }
09311
09312 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) {
09313
09314 if (handle_call_token(fh, &ies, &sin, fd)) {
09315 return 1;
09316 }
09317
09318 if (ies.calltoken && ies.calltokendata) {
09319
09320
09321
09322
09323 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09324 } else {
09325 new = NEW_ALLOW;
09326 }
09327 }
09328 } else {
09329
09330 f.frametype = AST_FRAME_NULL;
09331 f.subclass = 0;
09332 }
09333
09334 if (!fr->callno) {
09335 int check_dcallno = 0;
09336
09337
09338
09339
09340
09341
09342
09343
09344
09345
09346
09347
09348
09349 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09350 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
09351 }
09352
09353 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09354 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) {
09355 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09356 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) {
09357 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09358 }
09359 return 1;
09360 }
09361 }
09362
09363 if (fr->callno > 0)
09364 ast_mutex_lock(&iaxsl[fr->callno]);
09365
09366 if (!fr->callno || !iaxs[fr->callno]) {
09367
09368
09369 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09370
09371 if (((f.subclass != IAX_COMMAND_INVAL) &&
09372 (f.subclass != IAX_COMMAND_TXCNT) &&
09373 (f.subclass != IAX_COMMAND_TXACC) &&
09374 (f.subclass != IAX_COMMAND_FWDOWNL))||
09375 (f.frametype != AST_FRAME_IAX))
09376 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09377 fd);
09378 }
09379 if (fr->callno > 0)
09380 ast_mutex_unlock(&iaxsl[fr->callno]);
09381 return 1;
09382 }
09383 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
09384 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09385 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09386 ast_mutex_unlock(&iaxsl[fr->callno]);
09387 return 1;
09388 }
09389 #ifdef DEBUG_SUPPORT
09390 else
09391 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
09392 #endif
09393 }
09394
09395
09396 iaxs[fr->callno]->frames_received++;
09397
09398 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
09399 f.subclass != IAX_COMMAND_TXCNT &&
09400 f.subclass != IAX_COMMAND_TXACC) {
09401 unsigned short new_peercallno;
09402
09403 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
09404 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
09405 if (iaxs[fr->callno]->peercallno) {
09406 remove_by_peercallno(iaxs[fr->callno]);
09407 }
09408 iaxs[fr->callno]->peercallno = new_peercallno;
09409 store_by_peercallno(iaxs[fr->callno]);
09410 }
09411 }
09412 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09413 if (iaxdebug)
09414 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
09415
09416 fr->oseqno = fh->oseqno;
09417 fr->iseqno = fh->iseqno;
09418 fr->ts = ntohl(fh->ts);
09419 #ifdef IAXTESTS
09420 if (test_resync) {
09421 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
09422 fr->ts += test_resync;
09423 }
09424 #endif
09425 #if 0
09426 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
09427 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
09428 (f.subclass == IAX_COMMAND_NEW ||
09429 f.subclass == IAX_COMMAND_AUTHREQ ||
09430 f.subclass == IAX_COMMAND_ACCEPT ||
09431 f.subclass == IAX_COMMAND_REJECT)) ) )
09432 #endif
09433 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
09434 updatehistory = 0;
09435 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
09436 (iaxs[fr->callno]->iseqno ||
09437 ((f.subclass != IAX_COMMAND_TXCNT) &&
09438 (f.subclass != IAX_COMMAND_TXREADY) &&
09439 (f.subclass != IAX_COMMAND_TXREL) &&
09440 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09441 (f.subclass != IAX_COMMAND_TXACC)) ||
09442 (f.frametype != AST_FRAME_IAX))) {
09443 if (
09444 ((f.subclass != IAX_COMMAND_ACK) &&
09445 (f.subclass != IAX_COMMAND_INVAL) &&
09446 (f.subclass != IAX_COMMAND_TXCNT) &&
09447 (f.subclass != IAX_COMMAND_TXREADY) &&
09448 (f.subclass != IAX_COMMAND_TXREL) &&
09449 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09450 (f.subclass != IAX_COMMAND_TXACC) &&
09451 (f.subclass != IAX_COMMAND_VNAK)) ||
09452 (f.frametype != AST_FRAME_IAX)) {
09453
09454 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
09455 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
09456
09457
09458 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
09459
09460 if ((f.frametype != AST_FRAME_IAX) ||
09461 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
09462 ast_debug(1, "Acking anyway\n");
09463
09464
09465 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09466 }
09467 } else {
09468
09469 iax2_vnak(fr->callno);
09470 }
09471 ast_mutex_unlock(&iaxsl[fr->callno]);
09472 return 1;
09473 }
09474 } else {
09475
09476 if (((f.subclass != IAX_COMMAND_ACK) &&
09477 (f.subclass != IAX_COMMAND_INVAL) &&
09478 (f.subclass != IAX_COMMAND_TXCNT) &&
09479 (f.subclass != IAX_COMMAND_TXACC) &&
09480 (f.subclass != IAX_COMMAND_VNAK)) ||
09481 (f.frametype != AST_FRAME_IAX))
09482 iaxs[fr->callno]->iseqno++;
09483 }
09484
09485 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
09486 if (res < thread->buf_size)
09487 thread->buf[res++] = '\0';
09488 else
09489 thread->buf[res - 1] = '\0';
09490 }
09491
09492
09493
09494 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09495 ((f.subclass != IAX_COMMAND_INVAL) ||
09496 (f.frametype != AST_FRAME_IAX))) {
09497 unsigned char x;
09498 int call_to_destroy;
09499
09500 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
09501 x = fr->iseqno;
09502 else
09503 x = iaxs[fr->callno]->oseqno;
09504 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
09505
09506
09507 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
09508
09509 if (iaxdebug)
09510 ast_debug(1, "Cancelling transmission of packet %d\n", x);
09511 call_to_destroy = 0;
09512 AST_LIST_LOCK(&frame_queue);
09513 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09514
09515 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
09516 cur->retries = -1;
09517
09518 if (cur->final)
09519 call_to_destroy = fr->callno;
09520 }
09521 }
09522 AST_LIST_UNLOCK(&frame_queue);
09523 if (call_to_destroy) {
09524 if (iaxdebug)
09525 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
09526 ast_mutex_lock(&iaxsl[call_to_destroy]);
09527 iax2_destroy(call_to_destroy);
09528 ast_mutex_unlock(&iaxsl[call_to_destroy]);
09529 }
09530 }
09531
09532 if (iaxs[fr->callno])
09533 iaxs[fr->callno]->rseqno = fr->iseqno;
09534 else {
09535
09536 ast_mutex_unlock(&iaxsl[fr->callno]);
09537 return 1;
09538 }
09539 } else {
09540 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
09541 }
09542 }
09543 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09544 ((f.frametype != AST_FRAME_IAX) ||
09545 ((f.subclass != IAX_COMMAND_TXACC) &&
09546 (f.subclass != IAX_COMMAND_TXCNT)))) {
09547
09548 ast_mutex_unlock(&iaxsl[fr->callno]);
09549 return 1;
09550 }
09551
09552
09553
09554
09555 if ((f.frametype == AST_FRAME_VOICE) ||
09556 (f.frametype == AST_FRAME_VIDEO) ||
09557 (f.frametype == AST_FRAME_IAX)) {
09558 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
09559 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
09560 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
09561 ast_mutex_unlock(&iaxsl[fr->callno]);
09562 return 1;
09563 }
09564 }
09565
09566 if (ies.vars) {
09567 struct ast_datastore *variablestore = NULL;
09568 struct ast_variable *var, *prev = NULL;
09569 AST_LIST_HEAD(, ast_var_t) *varlist;
09570 if ((c = iaxs[fr->callno]->owner)) {
09571 varlist = ast_calloc(1, sizeof(*varlist));
09572 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09573
09574 if (variablestore && varlist) {
09575 variablestore->data = varlist;
09576 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09577 AST_LIST_HEAD_INIT(varlist);
09578 ast_debug(1, "I can haz IAX vars?\n");
09579 for (var = ies.vars; var; var = var->next) {
09580 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09581 if (prev) {
09582 ast_free(prev);
09583 }
09584 prev = var;
09585 if (!newvar) {
09586
09587 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09588 } else {
09589 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09590 }
09591 }
09592 if (prev) {
09593 ast_free(prev);
09594 }
09595 ies.vars = NULL;
09596 ast_channel_datastore_add(c, variablestore);
09597 } else {
09598 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09599 if (variablestore) {
09600 ast_datastore_free(variablestore);
09601 }
09602 if (varlist) {
09603 ast_free(varlist);
09604 }
09605 }
09606 } else {
09607
09608
09609 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
09610 for (var = ies.vars; var && var->next; var = var->next);
09611 if (var) {
09612 var->next = iaxs[fr->callno]->iaxvars;
09613 iaxs[fr->callno]->iaxvars = ies.vars;
09614 ies.vars = NULL;
09615 }
09616 }
09617 }
09618
09619 if (ies.vars) {
09620 ast_debug(1, "I have IAX variables, but they were not processed\n");
09621 }
09622 }
09623
09624 if (f.frametype == AST_FRAME_VOICE) {
09625 if (f.subclass != iaxs[fr->callno]->voiceformat) {
09626 iaxs[fr->callno]->voiceformat = f.subclass;
09627 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
09628 if (iaxs[fr->callno]->owner) {
09629 int orignative;
09630 retryowner:
09631 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
09632 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09633 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
09634 }
09635 if (iaxs[fr->callno]) {
09636 if (iaxs[fr->callno]->owner) {
09637 orignative = iaxs[fr->callno]->owner->nativeformats;
09638 iaxs[fr->callno]->owner->nativeformats = f.subclass;
09639 if (iaxs[fr->callno]->owner->readformat)
09640 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
09641 iaxs[fr->callno]->owner->nativeformats = orignative;
09642 ast_channel_unlock(iaxs[fr->callno]->owner);
09643 }
09644 } else {
09645 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
09646
09647 if (ies.vars) {
09648 ast_variables_destroy(ies.vars);
09649 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
09650 ies.vars = NULL;
09651 }
09652 ast_mutex_unlock(&iaxsl[fr->callno]);
09653 return 1;
09654 }
09655 }
09656 }
09657 }
09658 if (f.frametype == AST_FRAME_VIDEO) {
09659 if (f.subclass != iaxs[fr->callno]->videoformat) {
09660 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
09661 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
09662 }
09663 }
09664 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
09665 if (f.subclass == AST_CONTROL_BUSY) {
09666 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
09667 } else if (f.subclass == AST_CONTROL_CONGESTION) {
09668 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
09669 }
09670 }
09671 if (f.frametype == AST_FRAME_IAX) {
09672 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
09673
09674 if (iaxdebug)
09675 ast_debug(1, "IAX subclass %d received\n", f.subclass);
09676
09677
09678 if (iaxs[fr->callno]->last < fr->ts &&
09679 f.subclass != IAX_COMMAND_ACK &&
09680 f.subclass != IAX_COMMAND_PONG &&
09681 f.subclass != IAX_COMMAND_LAGRP) {
09682 iaxs[fr->callno]->last = fr->ts;
09683 if (iaxdebug)
09684 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09685 }
09686 iaxs[fr->callno]->last_iax_message = f.subclass;
09687 if (!iaxs[fr->callno]->first_iax_message) {
09688 iaxs[fr->callno]->first_iax_message = f.subclass;
09689 }
09690 switch(f.subclass) {
09691 case IAX_COMMAND_ACK:
09692
09693 break;
09694 case IAX_COMMAND_QUELCH:
09695 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09696
09697 if (iaxs[fr->callno]->owner) {
09698 manager_event(EVENT_FLAG_CALL, "Hold",
09699 "Status: On\r\n"
09700 "Channel: %s\r\n"
09701 "Uniqueid: %s\r\n",
09702 iaxs[fr->callno]->owner->name,
09703 iaxs[fr->callno]->owner->uniqueid);
09704 }
09705
09706 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
09707 if (ies.musiconhold) {
09708 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
09709 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
09710 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
09711 S_OR(moh_suggest, NULL),
09712 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
09713 if (!iaxs[fr->callno]) {
09714 ast_mutex_unlock(&iaxsl[fr->callno]);
09715 return 1;
09716 }
09717 }
09718 }
09719 }
09720 break;
09721 case IAX_COMMAND_UNQUELCH:
09722 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09723
09724 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
09725 manager_event(EVENT_FLAG_CALL, "Hold",
09726 "Status: Off\r\n"
09727 "Channel: %s\r\n"
09728 "Uniqueid: %s\r\n",
09729 iaxs[fr->callno]->owner->name,
09730 iaxs[fr->callno]->owner->uniqueid);
09731 }
09732
09733 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
09734 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
09735 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
09736 if (!iaxs[fr->callno]) {
09737 ast_mutex_unlock(&iaxsl[fr->callno]);
09738 return 1;
09739 }
09740 }
09741 }
09742 break;
09743 case IAX_COMMAND_TXACC:
09744 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
09745
09746 AST_LIST_LOCK(&frame_queue);
09747 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09748
09749 if ((fr->callno == cur->callno) && (cur->transfer))
09750 cur->retries = -1;
09751 }
09752 AST_LIST_UNLOCK(&frame_queue);
09753 memset(&ied1, 0, sizeof(ied1));
09754 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
09755 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
09756 iaxs[fr->callno]->transferring = TRANSFER_READY;
09757 }
09758 break;
09759 case IAX_COMMAND_NEW:
09760
09761 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
09762 break;
09763 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
09764 ast_mutex_unlock(&iaxsl[fr->callno]);
09765 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
09766 ast_mutex_lock(&iaxsl[fr->callno]);
09767 if (!iaxs[fr->callno]) {
09768 ast_mutex_unlock(&iaxsl[fr->callno]);
09769 return 1;
09770 }
09771 }
09772
09773 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
09774 int new_callno;
09775 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
09776 fr->callno = new_callno;
09777 }
09778
09779 if (delayreject)
09780 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09781 if (check_access(fr->callno, &sin, &ies)) {
09782
09783 auth_fail(fr->callno, IAX_COMMAND_REJECT);
09784 if (authdebug)
09785 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);
09786 break;
09787 }
09788 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
09789 const char *context, *exten, *cid_num;
09790
09791 context = ast_strdupa(iaxs[fr->callno]->context);
09792 exten = ast_strdupa(iaxs[fr->callno]->exten);
09793 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
09794
09795
09796 ast_mutex_unlock(&iaxsl[fr->callno]);
09797 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
09798 ast_mutex_lock(&iaxsl[fr->callno]);
09799
09800 if (!iaxs[fr->callno]) {
09801 ast_mutex_unlock(&iaxsl[fr->callno]);
09802 return 1;
09803 }
09804 } else
09805 exists = 0;
09806
09807 save_osptoken(fr, &ies);
09808 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
09809 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
09810 memset(&ied0, 0, sizeof(ied0));
09811 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09812 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09813 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09814 if (!iaxs[fr->callno]) {
09815 ast_mutex_unlock(&iaxsl[fr->callno]);
09816 return 1;
09817 }
09818 if (authdebug)
09819 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);
09820 } else {
09821
09822
09823 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09824 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09825 using_prefs = "reqonly";
09826 } else {
09827 using_prefs = "disabled";
09828 }
09829 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
09830 memset(&pref, 0, sizeof(pref));
09831 strcpy(caller_pref_buf, "disabled");
09832 strcpy(host_pref_buf, "disabled");
09833 } else {
09834 using_prefs = "mine";
09835
09836 if (ies.codec_prefs)
09837 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
09838 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09839
09840 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09841 pref = iaxs[fr->callno]->rprefs;
09842 using_prefs = "caller";
09843 } else {
09844 pref = iaxs[fr->callno]->prefs;
09845 }
09846 } else
09847 pref = iaxs[fr->callno]->prefs;
09848
09849 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
09850 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
09851 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
09852 }
09853 if (!format) {
09854 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09855 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
09856 if (!format) {
09857 memset(&ied0, 0, sizeof(ied0));
09858 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09859 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09860 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09861 if (!iaxs[fr->callno]) {
09862 ast_mutex_unlock(&iaxsl[fr->callno]);
09863 return 1;
09864 }
09865 if (authdebug) {
09866 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09867 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);
09868 else
09869 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);
09870 }
09871 } else {
09872
09873 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09874 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
09875 format = 0;
09876 } else {
09877 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09878 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
09879 memset(&pref, 0, sizeof(pref));
09880 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09881 strcpy(caller_pref_buf,"disabled");
09882 strcpy(host_pref_buf,"disabled");
09883 } else {
09884 using_prefs = "mine";
09885 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09886
09887 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09888 pref = iaxs[fr->callno]->prefs;
09889 } else {
09890 pref = iaxs[fr->callno]->rprefs;
09891 using_prefs = "caller";
09892 }
09893 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
09894
09895 } else
09896 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09897 }
09898 }
09899
09900 if (!format) {
09901 memset(&ied0, 0, sizeof(ied0));
09902 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09903 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09904 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09905 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09906 if (!iaxs[fr->callno]) {
09907 ast_mutex_unlock(&iaxsl[fr->callno]);
09908 return 1;
09909 }
09910 if (authdebug)
09911 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);
09912 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09913 break;
09914 }
09915 }
09916 }
09917 if (format) {
09918
09919 memset(&ied1, 0, sizeof(ied1));
09920 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
09921 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
09922 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
09923 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09924 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
09925 "%srequested format = %s,\n"
09926 "%srequested prefs = %s,\n"
09927 "%sactual format = %s,\n"
09928 "%shost prefs = %s,\n"
09929 "%spriority = %s\n",
09930 ast_inet_ntoa(sin.sin_addr),
09931 VERBOSE_PREFIX_4,
09932 ast_getformatname(iaxs[fr->callno]->peerformat),
09933 VERBOSE_PREFIX_4,
09934 caller_pref_buf,
09935 VERBOSE_PREFIX_4,
09936 ast_getformatname(format),
09937 VERBOSE_PREFIX_4,
09938 host_pref_buf,
09939 VERBOSE_PREFIX_4,
09940 using_prefs);
09941
09942 iaxs[fr->callno]->chosenformat = format;
09943 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
09944 } else {
09945 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09946
09947 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
09948 }
09949 }
09950 }
09951 break;
09952 }
09953 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
09954 merge_encryption(iaxs[fr->callno],ies.encmethods);
09955 else
09956 iaxs[fr->callno]->encmethods = 0;
09957 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
09958 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
09959 if (!iaxs[fr->callno]) {
09960 ast_mutex_unlock(&iaxsl[fr->callno]);
09961 return 1;
09962 }
09963 break;
09964 case IAX_COMMAND_DPREQ:
09965
09966 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
09967 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
09968 if (iaxcompat) {
09969
09970 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
09971 } else {
09972
09973 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
09974 }
09975 }
09976 break;
09977 case IAX_COMMAND_HANGUP:
09978 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09979 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
09980
09981 if (ies.causecode && iaxs[fr->callno]->owner)
09982 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09983
09984 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09985 iax2_destroy(fr->callno);
09986 break;
09987 case IAX_COMMAND_REJECT:
09988
09989 if (ies.causecode && iaxs[fr->callno]->owner)
09990 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09991
09992 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09993 if (iaxs[fr->callno]->owner && authdebug)
09994 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
09995 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
09996 ies.cause ? ies.cause : "<Unknown>");
09997 ast_debug(1, "Immediately destroying %d, having received reject\n",
09998 fr->callno);
09999 }
10000
10001 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10002 fr->ts, NULL, 0, fr->iseqno);
10003 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
10004 iaxs[fr->callno]->error = EPERM;
10005 iax2_destroy(fr->callno);
10006 break;
10007 case IAX_COMMAND_TRANSFER:
10008 {
10009 struct ast_channel *bridged_chan;
10010
10011 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
10012
10013
10014 ast_mutex_unlock(&iaxsl[fr->callno]);
10015 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
10016 ast_mutex_lock(&iaxsl[fr->callno]);
10017 if (!iaxs[fr->callno]) {
10018 ast_mutex_unlock(&iaxsl[fr->callno]);
10019 return 1;
10020 }
10021
10022 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
10023 if (!strcmp(ies.called_number, ast_parking_ext())) {
10024 struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
10025 ast_mutex_unlock(&iaxsl[fr->callno]);
10026 if (iax_park(bridged_chan, saved_channel)) {
10027 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
10028 } else {
10029 ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
10030 }
10031 ast_mutex_lock(&iaxsl[fr->callno]);
10032 } else {
10033 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
10034 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
10035 ies.called_number, iaxs[fr->callno]->context);
10036 else {
10037 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
10038 ies.called_number, iaxs[fr->callno]->context);
10039 }
10040 }
10041 } else {
10042 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10043 }
10044
10045 break;
10046 }
10047 case IAX_COMMAND_ACCEPT:
10048
10049 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10050 break;
10051 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10052
10053 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10054 iax2_destroy(fr->callno);
10055 break;
10056 }
10057 if (ies.format) {
10058 iaxs[fr->callno]->peerformat = ies.format;
10059 } else {
10060 if (iaxs[fr->callno]->owner)
10061 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10062 else
10063 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10064 }
10065 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));
10066 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10067 memset(&ied0, 0, sizeof(ied0));
10068 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10069 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10070 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10071 if (!iaxs[fr->callno]) {
10072 ast_mutex_unlock(&iaxsl[fr->callno]);
10073 return 1;
10074 }
10075 if (authdebug)
10076 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);
10077 } else {
10078 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10079 if (iaxs[fr->callno]->owner) {
10080
10081 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10082 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10083 retryowner2:
10084 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
10085 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
10086 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
10087 }
10088
10089 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10090
10091 if (iaxs[fr->callno]->owner->writeformat)
10092 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10093 if (iaxs[fr->callno]->owner->readformat)
10094 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10095 ast_channel_unlock(iaxs[fr->callno]->owner);
10096 }
10097 }
10098 }
10099 if (iaxs[fr->callno]) {
10100 AST_LIST_LOCK(&dpcache);
10101 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10102 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10103 iax2_dprequest(dp, fr->callno);
10104 AST_LIST_UNLOCK(&dpcache);
10105 }
10106 break;
10107 case IAX_COMMAND_POKE:
10108
10109 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10110 if (!iaxs[fr->callno]) {
10111 ast_mutex_unlock(&iaxsl[fr->callno]);
10112 return 1;
10113 }
10114 break;
10115 case IAX_COMMAND_PING:
10116 {
10117 struct iax_ie_data pingied;
10118 construct_rr(iaxs[fr->callno], &pingied);
10119
10120 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10121 }
10122 break;
10123 case IAX_COMMAND_PONG:
10124
10125 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10126
10127 save_rr(fr, &ies);
10128
10129
10130 log_jitterstats(fr->callno);
10131
10132 if (iaxs[fr->callno]->peerpoke) {
10133 peer = iaxs[fr->callno]->peerpoke;
10134 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10135 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10136 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10137 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);
10138 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10139 }
10140 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10141 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10142 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10143 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);
10144 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10145 }
10146 }
10147 peer->lastms = iaxs[fr->callno]->pingtime;
10148 if (peer->smoothing && (peer->lastms > -1))
10149 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10150 else if (peer->smoothing && peer->lastms < 0)
10151 peer->historicms = (0 + peer->historicms) / 2;
10152 else
10153 peer->historicms = iaxs[fr->callno]->pingtime;
10154
10155
10156 if (peer->pokeexpire > -1) {
10157 if (!ast_sched_del(sched, peer->pokeexpire)) {
10158 peer_unref(peer);
10159 peer->pokeexpire = -1;
10160 }
10161 }
10162
10163 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10164 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10165 else
10166 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10167 if (peer->pokeexpire == -1)
10168 peer_unref(peer);
10169
10170 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10171
10172 iax2_destroy(fr->callno);
10173 peer->callno = 0;
10174 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10175 }
10176 break;
10177 case IAX_COMMAND_LAGRQ:
10178 case IAX_COMMAND_LAGRP:
10179 f.src = "LAGRQ";
10180 f.mallocd = 0;
10181 f.offset = 0;
10182 f.samples = 0;
10183 iax_frame_wrap(fr, &f);
10184 if(f.subclass == IAX_COMMAND_LAGRQ) {
10185
10186 fr->af.subclass = IAX_COMMAND_LAGRP;
10187 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10188 } else {
10189
10190 unsigned int ts;
10191
10192 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10193 iaxs[fr->callno]->lag = ts - fr->ts;
10194 if (iaxdebug)
10195 ast_debug(1, "Peer %s lag measured as %dms\n",
10196 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10197 }
10198 break;
10199 case IAX_COMMAND_AUTHREQ:
10200 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10201 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>");
10202 break;
10203 }
10204 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10205 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10206 .subclass = AST_CONTROL_HANGUP,
10207 };
10208 ast_log(LOG_WARNING,
10209 "I don't know how to authenticate %s to %s\n",
10210 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10211 iax2_queue_frame(fr->callno, &hangup_fr);
10212 }
10213 if (!iaxs[fr->callno]) {
10214 ast_mutex_unlock(&iaxsl[fr->callno]);
10215 return 1;
10216 }
10217 break;
10218 case IAX_COMMAND_AUTHREP:
10219
10220 if (delayreject)
10221 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10222
10223 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10224 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>");
10225 break;
10226 }
10227 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10228 if (authdebug)
10229 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);
10230 memset(&ied0, 0, sizeof(ied0));
10231 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10232 break;
10233 }
10234 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10235
10236 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10237 } else
10238 exists = 0;
10239 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10240 if (authdebug)
10241 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);
10242 memset(&ied0, 0, sizeof(ied0));
10243 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10244 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10245 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10246 if (!iaxs[fr->callno]) {
10247 ast_mutex_unlock(&iaxsl[fr->callno]);
10248 return 1;
10249 }
10250 } else {
10251
10252 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10253 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10254 using_prefs = "reqonly";
10255 } else {
10256 using_prefs = "disabled";
10257 }
10258 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10259 memset(&pref, 0, sizeof(pref));
10260 strcpy(caller_pref_buf, "disabled");
10261 strcpy(host_pref_buf, "disabled");
10262 } else {
10263 using_prefs = "mine";
10264 if (ies.codec_prefs)
10265 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10266 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10267 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10268 pref = iaxs[fr->callno]->rprefs;
10269 using_prefs = "caller";
10270 } else {
10271 pref = iaxs[fr->callno]->prefs;
10272 }
10273 } else
10274 pref = iaxs[fr->callno]->prefs;
10275
10276 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10277 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10278 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10279 }
10280 if (!format) {
10281 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10282 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);
10283 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10284 }
10285 if (!format) {
10286 if (authdebug) {
10287 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10288 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);
10289 else
10290 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);
10291 }
10292 memset(&ied0, 0, sizeof(ied0));
10293 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10294 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10295 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10296 if (!iaxs[fr->callno]) {
10297 ast_mutex_unlock(&iaxsl[fr->callno]);
10298 return 1;
10299 }
10300 } else {
10301
10302 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10303 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10304 format = 0;
10305 } else {
10306 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10307 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10308 memset(&pref, 0, sizeof(pref));
10309 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10310 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10311 strcpy(caller_pref_buf,"disabled");
10312 strcpy(host_pref_buf,"disabled");
10313 } else {
10314 using_prefs = "mine";
10315 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10316
10317 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10318 pref = iaxs[fr->callno]->prefs;
10319 } else {
10320 pref = iaxs[fr->callno]->rprefs;
10321 using_prefs = "caller";
10322 }
10323 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10324 } else
10325 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10326 }
10327 }
10328 if (!format) {
10329 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10330 if (authdebug) {
10331 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10332 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);
10333 else
10334 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);
10335 }
10336 memset(&ied0, 0, sizeof(ied0));
10337 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10338 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10339 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10340 if (!iaxs[fr->callno]) {
10341 ast_mutex_unlock(&iaxsl[fr->callno]);
10342 return 1;
10343 }
10344 }
10345 }
10346 }
10347 if (format) {
10348
10349 memset(&ied1, 0, sizeof(ied1));
10350 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10351 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10352 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10353 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10354 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
10355 "%srequested format = %s,\n"
10356 "%srequested prefs = %s,\n"
10357 "%sactual format = %s,\n"
10358 "%shost prefs = %s,\n"
10359 "%spriority = %s\n",
10360 ast_inet_ntoa(sin.sin_addr),
10361 VERBOSE_PREFIX_4,
10362 ast_getformatname(iaxs[fr->callno]->peerformat),
10363 VERBOSE_PREFIX_4,
10364 caller_pref_buf,
10365 VERBOSE_PREFIX_4,
10366 ast_getformatname(format),
10367 VERBOSE_PREFIX_4,
10368 host_pref_buf,
10369 VERBOSE_PREFIX_4,
10370 using_prefs);
10371
10372 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10373 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
10374 iax2_destroy(fr->callno);
10375 else if (ies.vars) {
10376 struct ast_datastore *variablestore;
10377 struct ast_variable *var, *prev = NULL;
10378 AST_LIST_HEAD(, ast_var_t) *varlist;
10379 varlist = ast_calloc(1, sizeof(*varlist));
10380 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10381 if (variablestore && varlist) {
10382 variablestore->data = varlist;
10383 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10384 AST_LIST_HEAD_INIT(varlist);
10385 ast_debug(1, "I can haz IAX vars? w00t\n");
10386 for (var = ies.vars; var; var = var->next) {
10387 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10388 if (prev)
10389 ast_free(prev);
10390 prev = var;
10391 if (!newvar) {
10392
10393 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10394 } else {
10395 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10396 }
10397 }
10398 if (prev)
10399 ast_free(prev);
10400 ies.vars = NULL;
10401 ast_channel_datastore_add(c, variablestore);
10402 } else {
10403 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10404 if (variablestore)
10405 ast_datastore_free(variablestore);
10406 if (varlist)
10407 ast_free(varlist);
10408 }
10409 }
10410 } else {
10411 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10412
10413 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10414 }
10415 }
10416 }
10417 break;
10418 case IAX_COMMAND_DIAL:
10419 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
10420 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10421 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
10422 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
10423 if (authdebug)
10424 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);
10425 memset(&ied0, 0, sizeof(ied0));
10426 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10427 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10428 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10429 if (!iaxs[fr->callno]) {
10430 ast_mutex_unlock(&iaxsl[fr->callno]);
10431 return 1;
10432 }
10433 } else {
10434 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10435 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
10436 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10437 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
10438 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
10439 iax2_destroy(fr->callno);
10440 else if (ies.vars) {
10441 struct ast_datastore *variablestore;
10442 struct ast_variable *var, *prev = NULL;
10443 AST_LIST_HEAD(, ast_var_t) *varlist;
10444 varlist = ast_calloc(1, sizeof(*varlist));
10445 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10446 ast_debug(1, "I can haz IAX vars? w00t\n");
10447 if (variablestore && varlist) {
10448 variablestore->data = varlist;
10449 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10450 AST_LIST_HEAD_INIT(varlist);
10451 for (var = ies.vars; var; var = var->next) {
10452 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10453 if (prev)
10454 ast_free(prev);
10455 prev = var;
10456 if (!newvar) {
10457
10458 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10459 } else {
10460 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10461 }
10462 }
10463 if (prev)
10464 ast_free(prev);
10465 ies.vars = NULL;
10466 ast_channel_datastore_add(c, variablestore);
10467 } else {
10468 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10469 if (variablestore)
10470 ast_datastore_free(variablestore);
10471 if (varlist)
10472 ast_free(varlist);
10473 }
10474 }
10475 }
10476 }
10477 break;
10478 case IAX_COMMAND_INVAL:
10479 iaxs[fr->callno]->error = ENOTCONN;
10480 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
10481 iax2_destroy(fr->callno);
10482 ast_debug(1, "Destroying call %d\n", fr->callno);
10483 break;
10484 case IAX_COMMAND_VNAK:
10485 ast_debug(1, "Received VNAK: resending outstanding frames\n");
10486
10487 vnak_retransmit(fr->callno, fr->iseqno);
10488 break;
10489 case IAX_COMMAND_REGREQ:
10490 case IAX_COMMAND_REGREL:
10491
10492 if (delayreject)
10493 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10494 if (register_verify(fr->callno, &sin, &ies)) {
10495 if (!iaxs[fr->callno]) {
10496 ast_mutex_unlock(&iaxsl[fr->callno]);
10497 return 1;
10498 }
10499
10500 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
10501 break;
10502 }
10503 if (!iaxs[fr->callno]) {
10504 ast_mutex_unlock(&iaxsl[fr->callno]);
10505 return 1;
10506 }
10507 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
10508 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
10509
10510 if (f.subclass == IAX_COMMAND_REGREL)
10511 memset(&sin, 0, sizeof(sin));
10512 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
10513 ast_log(LOG_WARNING, "Registry error\n");
10514 if (!iaxs[fr->callno]) {
10515 ast_mutex_unlock(&iaxsl[fr->callno]);
10516 return 1;
10517 }
10518 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10519 ast_mutex_unlock(&iaxsl[fr->callno]);
10520 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10521 ast_mutex_lock(&iaxsl[fr->callno]);
10522 if (!iaxs[fr->callno]) {
10523 ast_mutex_unlock(&iaxsl[fr->callno]);
10524 return 1;
10525 }
10526 }
10527 break;
10528 }
10529 registry_authrequest(fr->callno);
10530 if (!iaxs[fr->callno]) {
10531 ast_mutex_unlock(&iaxsl[fr->callno]);
10532 return 1;
10533 }
10534 break;
10535 case IAX_COMMAND_REGACK:
10536 if (iax2_ack_registry(&ies, &sin, fr->callno))
10537 ast_log(LOG_WARNING, "Registration failure\n");
10538
10539 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10540 iax2_destroy(fr->callno);
10541 break;
10542 case IAX_COMMAND_REGREJ:
10543 if (iaxs[fr->callno]->reg) {
10544 if (authdebug) {
10545 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));
10546 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>");
10547 }
10548 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
10549 }
10550
10551 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10552 iax2_destroy(fr->callno);
10553 break;
10554 case IAX_COMMAND_REGAUTH:
10555
10556 if (registry_rerequest(&ies, fr->callno, &sin)) {
10557 memset(&ied0, 0, sizeof(ied0));
10558 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
10559 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
10560 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10561 if (!iaxs[fr->callno]) {
10562 ast_mutex_unlock(&iaxsl[fr->callno]);
10563 return 1;
10564 }
10565 }
10566 break;
10567 case IAX_COMMAND_TXREJ:
10568 iaxs[fr->callno]->transferring = 0;
10569 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10570 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
10571 if (iaxs[fr->callno]->bridgecallno) {
10572 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
10573 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
10574 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
10575 }
10576 }
10577 break;
10578 case IAX_COMMAND_TXREADY:
10579 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
10580 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
10581 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
10582 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
10583 else
10584 iaxs[fr->callno]->transferring = TRANSFER_READY;
10585 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10586 if (iaxs[fr->callno]->bridgecallno) {
10587 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
10588 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
10589
10590 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
10591 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10592 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10593
10594 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
10595 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
10596
10597 memset(&ied0, 0, sizeof(ied0));
10598 memset(&ied1, 0, sizeof(ied1));
10599 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10600 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10601 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
10602 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
10603 } else {
10604 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10605 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10606
10607 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
10608 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
10609 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
10610 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10611
10612
10613 stop_stuff(fr->callno);
10614 stop_stuff(iaxs[fr->callno]->bridgecallno);
10615
10616 memset(&ied0, 0, sizeof(ied0));
10617 memset(&ied1, 0, sizeof(ied1));
10618 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10619 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10620 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
10621 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
10622 }
10623
10624 }
10625 }
10626 }
10627 break;
10628 case IAX_COMMAND_TXREQ:
10629 try_transfer(iaxs[fr->callno], &ies);
10630 break;
10631 case IAX_COMMAND_TXCNT:
10632 if (iaxs[fr->callno]->transferring)
10633 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
10634 break;
10635 case IAX_COMMAND_TXREL:
10636
10637 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10638 complete_transfer(fr->callno, &ies);
10639 stop_stuff(fr->callno);
10640 break;
10641 case IAX_COMMAND_TXMEDIA:
10642 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
10643 AST_LIST_LOCK(&frame_queue);
10644 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10645
10646 if ((fr->callno == cur->callno) && (cur->transfer))
10647 cur->retries = -1;
10648 }
10649 AST_LIST_UNLOCK(&frame_queue);
10650
10651 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
10652 }
10653 break;
10654 case IAX_COMMAND_RTKEY:
10655 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
10656 ast_log(LOG_WARNING,
10657 "we've been told to rotate our encryption key, "
10658 "but this isn't an encrypted call. bad things will happen.\n"
10659 );
10660 break;
10661 }
10662
10663 IAX_DEBUGDIGEST("Receiving", ies.challenge);
10664
10665 ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
10666 break;
10667 case IAX_COMMAND_DPREP:
10668 complete_dpreply(iaxs[fr->callno], &ies);
10669 break;
10670 case IAX_COMMAND_UNSUPPORT:
10671 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
10672 break;
10673 case IAX_COMMAND_FWDOWNL:
10674
10675 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
10676 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
10677 break;
10678 }
10679 memset(&ied0, 0, sizeof(ied0));
10680 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
10681 if (res < 0)
10682 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10683 else if (res > 0)
10684 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
10685 else
10686 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
10687 if (!iaxs[fr->callno]) {
10688 ast_mutex_unlock(&iaxsl[fr->callno]);
10689 return 1;
10690 }
10691 break;
10692 case IAX_COMMAND_CALLTOKEN:
10693 {
10694 struct iax_frame *cur;
10695 int found = 0;
10696 AST_LIST_LOCK(&frame_queue);
10697 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10698
10699
10700
10701 if (cur->callno == fr->callno) {
10702 found = 1;
10703 break;
10704 }
10705 }
10706 AST_LIST_UNLOCK(&frame_queue);
10707
10708
10709 if (cur && found && ies.calltoken && ies.calltokendata) {
10710 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
10711 }
10712 break;
10713 }
10714 default:
10715 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
10716 memset(&ied0, 0, sizeof(ied0));
10717 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
10718 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
10719 }
10720
10721 if (ies.vars) {
10722 ast_variables_destroy(ies.vars);
10723 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
10724 ies.vars = NULL;
10725 }
10726
10727
10728 if ((f.subclass != IAX_COMMAND_ACK) &&
10729 (f.subclass != IAX_COMMAND_TXCNT) &&
10730 (f.subclass != IAX_COMMAND_TXACC) &&
10731 (f.subclass != IAX_COMMAND_INVAL) &&
10732 (f.subclass != IAX_COMMAND_VNAK)) {
10733 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
10734 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10735 }
10736 ast_mutex_unlock(&iaxsl[fr->callno]);
10737 return 1;
10738 }
10739
10740 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
10741 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10742 } else if (minivid) {
10743 f.frametype = AST_FRAME_VIDEO;
10744 if (iaxs[fr->callno]->videoformat > 0)
10745 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
10746 else {
10747 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
10748 iax2_vnak(fr->callno);
10749 ast_mutex_unlock(&iaxsl[fr->callno]);
10750 return 1;
10751 }
10752 f.datalen = res - sizeof(*vh);
10753 if (f.datalen)
10754 f.data.ptr = thread->buf + sizeof(*vh);
10755 else
10756 f.data.ptr = NULL;
10757 #ifdef IAXTESTS
10758 if (test_resync) {
10759 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
10760 } else
10761 #endif
10762 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
10763 } else {
10764
10765 f.frametype = AST_FRAME_VOICE;
10766 if (iaxs[fr->callno]->voiceformat > 0)
10767 f.subclass = iaxs[fr->callno]->voiceformat;
10768 else {
10769 ast_debug(1, "Received mini frame before first full voice frame\n");
10770 iax2_vnak(fr->callno);
10771 ast_mutex_unlock(&iaxsl[fr->callno]);
10772 return 1;
10773 }
10774 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
10775 if (f.datalen < 0) {
10776 ast_log(LOG_WARNING, "Datalen < 0?\n");
10777 ast_mutex_unlock(&iaxsl[fr->callno]);
10778 return 1;
10779 }
10780 if (f.datalen)
10781 f.data.ptr = thread->buf + sizeof(*mh);
10782 else
10783 f.data.ptr = NULL;
10784 #ifdef IAXTESTS
10785 if (test_resync) {
10786 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
10787 } else
10788 #endif
10789 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
10790
10791 }
10792
10793 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10794 ast_mutex_unlock(&iaxsl[fr->callno]);
10795 return 1;
10796 }
10797
10798 f.src = "IAX2";
10799 f.mallocd = 0;
10800 f.offset = 0;
10801 f.len = 0;
10802 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
10803 f.samples = ast_codec_get_samples(&f);
10804
10805 if (f.subclass == AST_FORMAT_SLINEAR)
10806 ast_frame_byteswap_be(&f);
10807 } else
10808 f.samples = 0;
10809 iax_frame_wrap(fr, &f);
10810
10811
10812 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
10813
10814 fr->outoforder = 0;
10815 } else {
10816 if (iaxdebug && iaxs[fr->callno])
10817 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);
10818 fr->outoforder = -1;
10819 }
10820 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
10821 duped_fr = iaxfrdup2(fr);
10822 if (duped_fr) {
10823 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
10824 }
10825 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
10826 iaxs[fr->callno]->last = fr->ts;
10827 #if 1
10828 if (iaxdebug)
10829 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10830 #endif
10831 }
10832
10833
10834 ast_mutex_unlock(&iaxsl[fr->callno]);
10835 return 1;
10836 }
10837
10838
10839 static void iax2_process_thread_cleanup(void *data)
10840 {
10841 struct iax2_thread *thread = data;
10842 ast_mutex_destroy(&thread->lock);
10843 ast_cond_destroy(&thread->cond);
10844 ast_mutex_destroy(&thread->init_lock);
10845 ast_cond_destroy(&thread->init_cond);
10846 ast_free(thread);
10847 ast_atomic_dec_and_test(&iaxactivethreadcount);
10848 }
10849
10850 static void *iax2_process_thread(void *data)
10851 {
10852 struct iax2_thread *thread = data;
10853 struct timeval wait;
10854 struct timespec ts;
10855 int put_into_idle = 0;
10856 int first_time = 1;
10857
10858 ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
10859 pthread_cleanup_push(iax2_process_thread_cleanup, data);
10860 for(;;) {
10861
10862 ast_mutex_lock(&thread->lock);
10863
10864
10865 if (first_time) {
10866 signal_condition(&thread->init_lock, &thread->init_cond);
10867 first_time = 0;
10868 }
10869
10870
10871 if (put_into_idle)
10872 insert_idle_thread(thread);
10873
10874 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
10875 struct iax2_thread *t = NULL;
10876
10877 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
10878 ts.tv_sec = wait.tv_sec;
10879 ts.tv_nsec = wait.tv_usec * 1000;
10880 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
10881
10882
10883 if (!put_into_idle) {
10884 ast_mutex_unlock(&thread->lock);
10885 break;
10886 }
10887 AST_LIST_LOCK(&dynamic_list);
10888
10889 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
10890 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
10891 AST_LIST_UNLOCK(&dynamic_list);
10892 if (t) {
10893
10894
10895
10896 ast_mutex_unlock(&thread->lock);
10897 break;
10898 }
10899
10900
10901
10902 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
10903 ts.tv_sec = wait.tv_sec;
10904 ts.tv_nsec = wait.tv_usec * 1000;
10905 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
10906 {
10907 ast_mutex_unlock(&thread->lock);
10908 break;
10909 }
10910 }
10911 } else {
10912 ast_cond_wait(&thread->cond, &thread->lock);
10913 }
10914
10915
10916 put_into_idle = 1;
10917
10918 ast_mutex_unlock(&thread->lock);
10919
10920 if (thread->iostate == IAX_IOSTATE_IDLE)
10921 continue;
10922
10923
10924 AST_LIST_LOCK(&active_list);
10925 AST_LIST_INSERT_HEAD(&active_list, thread, list);
10926 AST_LIST_UNLOCK(&active_list);
10927
10928
10929 switch(thread->iostate) {
10930 case IAX_IOSTATE_READY:
10931 thread->actions++;
10932 thread->iostate = IAX_IOSTATE_PROCESSING;
10933 socket_process(thread);
10934 handle_deferred_full_frames(thread);
10935 break;
10936 case IAX_IOSTATE_SCHEDREADY:
10937 thread->actions++;
10938 thread->iostate = IAX_IOSTATE_PROCESSING;
10939 #ifdef SCHED_MULTITHREADED
10940 thread->schedfunc(thread->scheddata);
10941 #endif
10942 default:
10943 break;
10944 }
10945 time(&thread->checktime);
10946 thread->iostate = IAX_IOSTATE_IDLE;
10947 #ifdef DEBUG_SCHED_MULTITHREAD
10948 thread->curfunc[0]='\0';
10949 #endif
10950
10951
10952 AST_LIST_LOCK(&active_list);
10953 AST_LIST_REMOVE(&active_list, thread, list);
10954 AST_LIST_UNLOCK(&active_list);
10955
10956
10957 handle_deferred_full_frames(thread);
10958 }
10959
10960
10961
10962
10963
10964 AST_LIST_LOCK(&idle_list);
10965 AST_LIST_REMOVE(&idle_list, thread, list);
10966 AST_LIST_UNLOCK(&idle_list);
10967
10968 AST_LIST_LOCK(&dynamic_list);
10969 AST_LIST_REMOVE(&dynamic_list, thread, list);
10970 AST_LIST_UNLOCK(&dynamic_list);
10971
10972
10973
10974
10975 pthread_cleanup_pop(1);
10976 return NULL;
10977 }
10978
10979 static int iax2_do_register(struct iax2_registry *reg)
10980 {
10981 struct iax_ie_data ied;
10982 if (iaxdebug)
10983 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
10984
10985 if (reg->dnsmgr &&
10986 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
10987
10988 ast_dnsmgr_refresh(reg->dnsmgr);
10989 }
10990
10991
10992
10993
10994
10995 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
10996 int callno = reg->callno;
10997 ast_mutex_lock(&iaxsl[callno]);
10998 iax2_destroy(callno);
10999 ast_mutex_unlock(&iaxsl[callno]);
11000 reg->callno = 0;
11001 }
11002 if (!reg->addr.sin_addr.s_addr) {
11003 if (iaxdebug)
11004 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11005
11006 reg->expire = iax2_sched_replace(reg->expire, sched,
11007 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11008 return -1;
11009 }
11010
11011 if (!reg->callno) {
11012 ast_debug(3, "Allocate call number\n");
11013 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
11014 if (reg->callno < 1) {
11015 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11016 return -1;
11017 } else
11018 ast_debug(3, "Registration created on call %d\n", reg->callno);
11019 iaxs[reg->callno]->reg = reg;
11020 ast_mutex_unlock(&iaxsl[reg->callno]);
11021 }
11022
11023 reg->expire = iax2_sched_replace(reg->expire, sched,
11024 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11025
11026 memset(&ied, 0, sizeof(ied));
11027 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11028 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11029 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11030 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11031 reg->regstate = REG_STATE_REGSENT;
11032 return 0;
11033 }
11034
11035 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
11036 {
11037
11038
11039 struct iax_ie_data provdata;
11040 struct iax_ie_data ied;
11041 unsigned int sig;
11042 struct sockaddr_in sin;
11043 int callno;
11044 struct create_addr_info cai;
11045
11046 memset(&cai, 0, sizeof(cai));
11047
11048 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11049
11050 if (iax_provision_build(&provdata, &sig, template, force)) {
11051 ast_debug(1, "No provisioning found for template '%s'\n", template);
11052 return 0;
11053 }
11054
11055 if (end) {
11056 memcpy(&sin, end, sizeof(sin));
11057 cai.sockfd = sockfd;
11058 } else if (create_addr(dest, NULL, &sin, &cai))
11059 return -1;
11060
11061
11062 memset(&ied, 0, sizeof(ied));
11063 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11064
11065 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11066 if (!callno)
11067 return -1;
11068
11069 if (iaxs[callno]) {
11070
11071 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11072 sched, 15000, auto_hangup, (void *)(long)callno);
11073 ast_set_flag(iaxs[callno], IAX_PROVISION);
11074
11075 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11076 }
11077 ast_mutex_unlock(&iaxsl[callno]);
11078
11079 return 1;
11080 }
11081
11082 static char *papp = "IAX2Provision";
11083 static char *psyn = "Provision a calling IAXy with a given template";
11084 static char *pdescrip =
11085 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
11086 "the calling entity is in fact an IAXy) with the given template or\n"
11087 "default if one is not specified. Returns -1 on error or 0 on success.\n";
11088
11089
11090
11091
11092 static int iax2_prov_app(struct ast_channel *chan, void *data)
11093 {
11094 int res;
11095 char *sdata;
11096 char *opts;
11097 int force =0;
11098 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11099 if (ast_strlen_zero(data))
11100 data = "default";
11101 sdata = ast_strdupa(data);
11102 opts = strchr(sdata, '|');
11103 if (opts)
11104 *opts='\0';
11105
11106 if (chan->tech != &iax2_tech) {
11107 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11108 return -1;
11109 }
11110 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11111 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11112 return -1;
11113 }
11114 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11115 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11116 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11117 sdata, res);
11118 return res;
11119 }
11120
11121 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11122 {
11123 int force = 0;
11124 int res;
11125
11126 switch (cmd) {
11127 case CLI_INIT:
11128 e->command = "iax2 provision";
11129 e->usage =
11130 "Usage: iax2 provision <host> <template> [forced]\n"
11131 " Provisions the given peer or IP address using a template\n"
11132 " matching either 'template' or '*' if the template is not\n"
11133 " found. If 'forced' is specified, even empty provisioning\n"
11134 " fields will be provisioned as empty fields.\n";
11135 return NULL;
11136 case CLI_GENERATE:
11137 if (a->pos == 3)
11138 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11139 return NULL;
11140 }
11141
11142 if (a->argc < 4)
11143 return CLI_SHOWUSAGE;
11144 if (a->argc > 4) {
11145 if (!strcasecmp(a->argv[4], "forced"))
11146 force = 1;
11147 else
11148 return CLI_SHOWUSAGE;
11149 }
11150 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11151 if (res < 0)
11152 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11153 else if (res < 1)
11154 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11155 else
11156 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11157 return CLI_SUCCESS;
11158 }
11159
11160 static void __iax2_poke_noanswer(const void *data)
11161 {
11162 struct iax2_peer *peer = (struct iax2_peer *)data;
11163 int callno;
11164
11165 if (peer->lastms > -1) {
11166 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11167 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11168 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11169 }
11170 if ((callno = peer->callno) > 0) {
11171 ast_mutex_lock(&iaxsl[callno]);
11172 iax2_destroy(callno);
11173 ast_mutex_unlock(&iaxsl[callno]);
11174 }
11175 peer->callno = 0;
11176 peer->lastms = -1;
11177
11178 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11179 if (peer->pokeexpire == -1)
11180 peer_unref(peer);
11181 }
11182
11183 static int iax2_poke_noanswer(const void *data)
11184 {
11185 struct iax2_peer *peer = (struct iax2_peer *)data;
11186 peer->pokeexpire = -1;
11187 #ifdef SCHED_MULTITHREADED
11188 if (schedule_action(__iax2_poke_noanswer, data))
11189 #endif
11190 __iax2_poke_noanswer(data);
11191 peer_unref(peer);
11192 return 0;
11193 }
11194
11195 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11196 {
11197 struct iax2_peer *peer = obj;
11198
11199 iax2_poke_peer(peer, 0);
11200
11201 return 0;
11202 }
11203
11204 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11205 {
11206 int callno;
11207 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
11208
11209
11210 peer->lastms = 0;
11211 peer->historicms = 0;
11212 peer->pokeexpire = -1;
11213 peer->callno = 0;
11214 return 0;
11215 }
11216
11217
11218 if ((callno = peer->callno) > 0) {
11219 ast_log(LOG_NOTICE, "Still have a callno...\n");
11220 ast_mutex_lock(&iaxsl[callno]);
11221 iax2_destroy(callno);
11222 ast_mutex_unlock(&iaxsl[callno]);
11223 }
11224 if (heldcall)
11225 ast_mutex_unlock(&iaxsl[heldcall]);
11226 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
11227 if (heldcall)
11228 ast_mutex_lock(&iaxsl[heldcall]);
11229 if (peer->callno < 1) {
11230 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11231 return -1;
11232 }
11233
11234
11235 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11236 iaxs[peer->callno]->peerpoke = peer;
11237
11238 if (peer->pokeexpire > -1) {
11239 if (!ast_sched_del(sched, peer->pokeexpire)) {
11240 peer->pokeexpire = -1;
11241 peer_unref(peer);
11242 }
11243 }
11244
11245
11246
11247 if (peer->lastms < 0)
11248 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11249 else
11250 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11251
11252 if (peer->pokeexpire == -1)
11253 peer_unref(peer);
11254
11255
11256 ast_mutex_lock(&iaxsl[callno]);
11257 if (iaxs[callno]) {
11258 struct iax_ie_data ied = {
11259 .buf = { 0 },
11260 .pos = 0,
11261 };
11262 add_empty_calltoken_ie(iaxs[callno], &ied);
11263 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11264 }
11265 ast_mutex_unlock(&iaxsl[callno]);
11266
11267 return 0;
11268 }
11269
11270 static void free_context(struct iax2_context *con)
11271 {
11272 struct iax2_context *conl;
11273 while(con) {
11274 conl = con;
11275 con = con->next;
11276 ast_free(conl);
11277 }
11278 }
11279
11280 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
11281 {
11282 int callno;
11283 int res;
11284 int fmt, native;
11285 struct sockaddr_in sin;
11286 struct ast_channel *c;
11287 struct parsed_dial_string pds;
11288 struct create_addr_info cai;
11289 char *tmpstr;
11290
11291 memset(&pds, 0, sizeof(pds));
11292 tmpstr = ast_strdupa(data);
11293 parse_dial_string(tmpstr, &pds);
11294
11295 if (ast_strlen_zero(pds.peer)) {
11296 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
11297 return NULL;
11298 }
11299
11300 memset(&cai, 0, sizeof(cai));
11301 cai.capability = iax2_capability;
11302
11303 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11304
11305
11306 if (create_addr(pds.peer, NULL, &sin, &cai)) {
11307 *cause = AST_CAUSE_UNREGISTERED;
11308 return NULL;
11309 }
11310
11311 if (pds.port)
11312 sin.sin_port = htons(atoi(pds.port));
11313
11314 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11315 if (callno < 1) {
11316 ast_log(LOG_WARNING, "Unable to create call\n");
11317 *cause = AST_CAUSE_CONGESTION;
11318 return NULL;
11319 }
11320
11321
11322 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11323 if (ast_test_flag(&cai, IAX_TRUNK)) {
11324 int new_callno;
11325 if ((new_callno = make_trunk(callno, 1)) != -1)
11326 callno = new_callno;
11327 }
11328 iaxs[callno]->maxtime = cai.maxtime;
11329 if (cai.found)
11330 ast_string_field_set(iaxs[callno], host, pds.peer);
11331
11332 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
11333
11334 ast_mutex_unlock(&iaxsl[callno]);
11335
11336 if (c) {
11337
11338 if (c->nativeformats & format)
11339 c->nativeformats &= format;
11340 else {
11341 native = c->nativeformats;
11342 fmt = format;
11343 res = ast_translator_best_choice(&fmt, &native);
11344 if (res < 0) {
11345 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
11346 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
11347 ast_hangup(c);
11348 return NULL;
11349 }
11350 c->nativeformats = native;
11351 }
11352 c->readformat = ast_best_codec(c->nativeformats);
11353 c->writeformat = c->readformat;
11354 }
11355
11356 return c;
11357 }
11358
11359 static void *sched_thread(void *ignore)
11360 {
11361 int count;
11362 int res;
11363 struct timeval wait;
11364 struct timespec ts;
11365
11366 for (;;) {
11367 pthread_testcancel();
11368 ast_mutex_lock(&sched_lock);
11369 res = ast_sched_wait(sched);
11370 if ((res > 1000) || (res < 0))
11371 res = 1000;
11372 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
11373 ts.tv_sec = wait.tv_sec;
11374 ts.tv_nsec = wait.tv_usec * 1000;
11375 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
11376 ast_mutex_unlock(&sched_lock);
11377 pthread_testcancel();
11378
11379 count = ast_sched_runq(sched);
11380 if (count >= 20)
11381 ast_debug(1, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
11382 }
11383
11384 return NULL;
11385 }
11386
11387 static void *network_thread(void *ignore)
11388 {
11389
11390
11391 int res, count, wakeup;
11392 struct iax_frame *f;
11393
11394 if (timer)
11395 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
11396
11397 for(;;) {
11398 pthread_testcancel();
11399
11400
11401
11402 AST_LIST_LOCK(&frame_queue);
11403 count = 0;
11404 wakeup = -1;
11405 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
11406 if (f->sentyet)
11407 continue;
11408
11409
11410 if (ast_mutex_trylock(&iaxsl[f->callno])) {
11411 wakeup = 1;
11412 continue;
11413 }
11414
11415 f->sentyet = 1;
11416
11417 if (iaxs[f->callno]) {
11418 send_packet(f);
11419 count++;
11420 }
11421
11422 ast_mutex_unlock(&iaxsl[f->callno]);
11423
11424 if (f->retries < 0) {
11425
11426 AST_LIST_REMOVE_CURRENT(list);
11427
11428 iax_frame_free(f);
11429 } else {
11430
11431 f->retries++;
11432 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
11433 }
11434 }
11435 AST_LIST_TRAVERSE_SAFE_END;
11436 AST_LIST_UNLOCK(&frame_queue);
11437
11438 pthread_testcancel();
11439 if (count >= 20)
11440 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
11441
11442
11443 res = ast_io_wait(io, wakeup);
11444 if (res >= 0) {
11445 if (res >= 20)
11446 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
11447 }
11448 }
11449 return NULL;
11450 }
11451
11452 static int start_network_thread(void)
11453 {
11454 struct iax2_thread *thread;
11455 int threadcount = 0;
11456 int x;
11457 for (x = 0; x < iaxthreadcount; x++) {
11458 thread = ast_calloc(1, sizeof(*thread));
11459 if (thread) {
11460 thread->type = IAX_THREAD_TYPE_POOL;
11461 thread->threadnum = ++threadcount;
11462 ast_mutex_init(&thread->lock);
11463 ast_cond_init(&thread->cond, NULL);
11464 if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) {
11465 ast_log(LOG_WARNING, "Failed to create new thread!\n");
11466 ast_free(thread);
11467 thread = NULL;
11468 }
11469 AST_LIST_LOCK(&idle_list);
11470 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
11471 AST_LIST_UNLOCK(&idle_list);
11472 }
11473 }
11474 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
11475 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
11476 ast_verb(2, "%d helper threads started\n", threadcount);
11477 return 0;
11478 }
11479
11480 static struct iax2_context *build_context(const char *context)
11481 {
11482 struct iax2_context *con;
11483
11484 if ((con = ast_calloc(1, sizeof(*con))))
11485 ast_copy_string(con->context, context, sizeof(con->context));
11486
11487 return con;
11488 }
11489
11490 static int get_auth_methods(const char *value)
11491 {
11492 int methods = 0;
11493 if (strstr(value, "rsa"))
11494 methods |= IAX_AUTH_RSA;
11495 if (strstr(value, "md5"))
11496 methods |= IAX_AUTH_MD5;
11497 if (strstr(value, "plaintext"))
11498 methods |= IAX_AUTH_PLAINTEXT;
11499 return methods;
11500 }
11501
11502
11503
11504
11505
11506 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
11507 {
11508 int sd;
11509 int res;
11510
11511 sd = socket(AF_INET, SOCK_DGRAM, 0);
11512 if (sd < 0) {
11513 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
11514 return -1;
11515 }
11516
11517 res = bind(sd, sa, salen);
11518 if (res < 0) {
11519 ast_debug(1, "Can't bind: %s\n", strerror(errno));
11520 close(sd);
11521 return 1;
11522 }
11523
11524 close(sd);
11525 return 0;
11526 }
11527
11528
11529
11530
11531 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
11532 {
11533 struct sockaddr_in sin;
11534 int nonlocal = 1;
11535 int port = IAX_DEFAULT_PORTNO;
11536 int sockfd = defaultsockfd;
11537 char *tmp;
11538 char *addr;
11539 char *portstr;
11540
11541 if (!(tmp = ast_strdupa(srcaddr)))
11542 return -1;
11543
11544 addr = strsep(&tmp, ":");
11545 portstr = tmp;
11546
11547 if (portstr) {
11548 port = atoi(portstr);
11549 if (port < 1)
11550 port = IAX_DEFAULT_PORTNO;
11551 }
11552
11553 if (!ast_get_ip(&sin, addr)) {
11554 struct ast_netsock *sock;
11555 int res;
11556
11557 sin.sin_port = 0;
11558 sin.sin_family = AF_INET;
11559 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
11560 if (res == 0) {
11561
11562 sin.sin_port = htons(port);
11563 if (!(sock = ast_netsock_find(netsock, &sin)))
11564 sock = ast_netsock_find(outsock, &sin);
11565 if (sock) {
11566 sockfd = ast_netsock_sockfd(sock);
11567 nonlocal = 0;
11568 } else {
11569 unsigned int orig_saddr = sin.sin_addr.s_addr;
11570
11571 sin.sin_addr.s_addr = INADDR_ANY;
11572 if (ast_netsock_find(netsock, &sin)) {
11573 sin.sin_addr.s_addr = orig_saddr;
11574 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
11575 if (sock) {
11576 sockfd = ast_netsock_sockfd(sock);
11577 ast_netsock_unref(sock);
11578 nonlocal = 0;
11579 } else {
11580 nonlocal = 2;
11581 }
11582 }
11583 }
11584 }
11585 }
11586
11587 peer->sockfd = sockfd;
11588
11589 if (nonlocal == 1) {
11590 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
11591 srcaddr, peer->name);
11592 return -1;
11593 } else if (nonlocal == 2) {
11594 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
11595 srcaddr, peer->name);
11596 return -1;
11597 } else {
11598 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
11599 return 0;
11600 }
11601 }
11602
11603 static void peer_destructor(void *obj)
11604 {
11605 struct iax2_peer *peer = obj;
11606 int callno = peer->callno;
11607
11608 ast_free_ha(peer->ha);
11609
11610 if (callno > 0) {
11611 ast_mutex_lock(&iaxsl[callno]);
11612 iax2_destroy(callno);
11613 ast_mutex_unlock(&iaxsl[callno]);
11614 }
11615
11616 register_peer_exten(peer, 0);
11617
11618 if (peer->dnsmgr)
11619 ast_dnsmgr_release(peer->dnsmgr);
11620
11621 if (peer->mwi_event_sub)
11622 ast_event_unsubscribe(peer->mwi_event_sub);
11623
11624 ast_string_field_free_memory(peer);
11625 }
11626
11627
11628 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
11629 {
11630 struct iax2_peer *peer = NULL;
11631 struct ast_ha *oldha = NULL;
11632 int maskfound = 0;
11633 int found = 0;
11634 int firstpass = 1;
11635 struct iax2_peer tmp_peer = {
11636 .name = name,
11637 };
11638
11639 if (!temponly) {
11640 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
11641 if (peer && !ast_test_flag(peer, IAX_DELME))
11642 firstpass = 0;
11643 }
11644
11645 if (peer) {
11646 found++;
11647 if (firstpass) {
11648 oldha = peer->ha;
11649 peer->ha = NULL;
11650 }
11651 unlink_peer(peer);
11652 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
11653 peer->expire = -1;
11654 peer->pokeexpire = -1;
11655 peer->sockfd = defaultsockfd;
11656 if (ast_string_field_init(peer, 32))
11657 peer = peer_unref(peer);
11658 }
11659
11660 if (peer) {
11661 if (firstpass) {
11662 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11663 peer->encmethods = iax2_encryption;
11664 peer->adsi = adsi;
11665 ast_string_field_set(peer,secret,"");
11666 if (!found) {
11667 ast_string_field_set(peer, name, name);
11668 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11669 peer->expiry = min_reg_expire;
11670 }
11671 peer->prefs = prefs;
11672 peer->capability = iax2_capability;
11673 peer->smoothing = 0;
11674 peer->pokefreqok = DEFAULT_FREQ_OK;
11675 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
11676 peer->maxcallno = 0;
11677 peercnt_modify(0, 0, &peer->addr);
11678 peer->calltoken_required = CALLTOKEN_DEFAULT;
11679 ast_string_field_set(peer,context,"");
11680 ast_string_field_set(peer,peercontext,"");
11681 ast_clear_flag(peer, IAX_HASCALLERID);
11682 ast_string_field_set(peer, cid_name, "");
11683 ast_string_field_set(peer, cid_num, "");
11684 ast_string_field_set(peer, mohinterpret, mohinterpret);
11685 ast_string_field_set(peer, mohsuggest, mohsuggest);
11686 }
11687
11688 if (!v) {
11689 v = alt;
11690 alt = NULL;
11691 }
11692 while(v) {
11693 if (!strcasecmp(v->name, "secret")) {
11694 ast_string_field_set(peer, secret, v->value);
11695 } else if (!strcasecmp(v->name, "mailbox")) {
11696 ast_string_field_set(peer, mailbox, v->value);
11697 } else if (!strcasecmp(v->name, "hasvoicemail")) {
11698 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
11699 ast_string_field_set(peer, mailbox, name);
11700 }
11701 } else if (!strcasecmp(v->name, "mohinterpret")) {
11702 ast_string_field_set(peer, mohinterpret, v->value);
11703 } else if (!strcasecmp(v->name, "mohsuggest")) {
11704 ast_string_field_set(peer, mohsuggest, v->value);
11705 } else if (!strcasecmp(v->name, "dbsecret")) {
11706 ast_string_field_set(peer, dbsecret, v->value);
11707 } else if (!strcasecmp(v->name, "trunk")) {
11708 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
11709 if (ast_test_flag(peer, IAX_TRUNK) && !timer) {
11710 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
11711 ast_clear_flag(peer, IAX_TRUNK);
11712 }
11713 } else if (!strcasecmp(v->name, "auth")) {
11714 peer->authmethods = get_auth_methods(v->value);
11715 } else if (!strcasecmp(v->name, "encryption")) {
11716 peer->encmethods |= get_encrypt_methods(v->value);
11717 } else if (!strcasecmp(v->name, "transfer")) {
11718 if (!strcasecmp(v->value, "mediaonly")) {
11719 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
11720 } else if (ast_true(v->value)) {
11721 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11722 } else
11723 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11724 } else if (!strcasecmp(v->name, "jitterbuffer")) {
11725 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
11726 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
11727 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
11728 } else if (!strcasecmp(v->name, "host")) {
11729 if (!strcasecmp(v->value, "dynamic")) {
11730
11731 ast_set_flag(peer, IAX_DYNAMIC);
11732 if (!found) {
11733
11734
11735 memset(&peer->addr.sin_addr, 0, 4);
11736 if (peer->addr.sin_port) {
11737
11738 peer->defaddr.sin_port = peer->addr.sin_port;
11739 peer->addr.sin_port = 0;
11740 }
11741 }
11742 } else {
11743
11744 AST_SCHED_DEL(sched, peer->expire);
11745 ast_clear_flag(peer, IAX_DYNAMIC);
11746 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
11747 return peer_unref(peer);
11748 if (!peer->addr.sin_port)
11749 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11750 }
11751 if (!maskfound)
11752 inet_aton("255.255.255.255", &peer->mask);
11753 } else if (!strcasecmp(v->name, "defaultip")) {
11754 if (ast_get_ip(&peer->defaddr, v->value))
11755 return peer_unref(peer);
11756 } else if (!strcasecmp(v->name, "sourceaddress")) {
11757 peer_set_srcaddr(peer, v->value);
11758 } else if (!strcasecmp(v->name, "permit") ||
11759 !strcasecmp(v->name, "deny")) {
11760 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
11761 } else if (!strcasecmp(v->name, "mask")) {
11762 maskfound++;
11763 inet_aton(v->value, &peer->mask);
11764 } else if (!strcasecmp(v->name, "context")) {
11765 ast_string_field_set(peer, context, v->value);
11766 } else if (!strcasecmp(v->name, "regexten")) {
11767 ast_string_field_set(peer, regexten, v->value);
11768 } else if (!strcasecmp(v->name, "peercontext")) {
11769 ast_string_field_set(peer, peercontext, v->value);
11770 } else if (!strcasecmp(v->name, "port")) {
11771 if (ast_test_flag(peer, IAX_DYNAMIC))
11772 peer->defaddr.sin_port = htons(atoi(v->value));
11773 else
11774 peer->addr.sin_port = htons(atoi(v->value));
11775 } else if (!strcasecmp(v->name, "username")) {
11776 ast_string_field_set(peer, username, v->value);
11777 } else if (!strcasecmp(v->name, "allow")) {
11778 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
11779 } else if (!strcasecmp(v->name, "disallow")) {
11780 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
11781 } else if (!strcasecmp(v->name, "callerid")) {
11782 if (!ast_strlen_zero(v->value)) {
11783 char name2[80];
11784 char num2[80];
11785 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
11786 ast_string_field_set(peer, cid_name, name2);
11787 ast_string_field_set(peer, cid_num, num2);
11788 } else {
11789 ast_string_field_set(peer, cid_name, "");
11790 ast_string_field_set(peer, cid_num, "");
11791 }
11792 ast_set_flag(peer, IAX_HASCALLERID);
11793 } else if (!strcasecmp(v->name, "fullname")) {
11794 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
11795 ast_set_flag(peer, IAX_HASCALLERID);
11796 } else if (!strcasecmp(v->name, "cid_number")) {
11797 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
11798 ast_set_flag(peer, IAX_HASCALLERID);
11799 } else if (!strcasecmp(v->name, "sendani")) {
11800 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
11801 } else if (!strcasecmp(v->name, "inkeys")) {
11802 ast_string_field_set(peer, inkeys, v->value);
11803 } else if (!strcasecmp(v->name, "outkey")) {
11804 ast_string_field_set(peer, outkey, v->value);
11805 } else if (!strcasecmp(v->name, "qualify")) {
11806 if (!strcasecmp(v->value, "no")) {
11807 peer->maxms = 0;
11808 } else if (!strcasecmp(v->value, "yes")) {
11809 peer->maxms = DEFAULT_MAXMS;
11810 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
11811 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);
11812 peer->maxms = 0;
11813 }
11814 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
11815 peer->smoothing = ast_true(v->value);
11816 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
11817 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
11818 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);
11819 }
11820 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
11821 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
11822 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);
11823 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
11824 } else if (!strcasecmp(v->name, "timezone")) {
11825 ast_string_field_set(peer, zonetag, v->value);
11826 } else if (!strcasecmp(v->name, "adsi")) {
11827 peer->adsi = ast_true(v->value);
11828 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
11829 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
11830 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
11831 } else {
11832 peercnt_modify(1, peer->maxcallno, &peer->addr);
11833 }
11834 } else if (!strcasecmp(v->name, "requirecalltoken")) {
11835
11836 if (ast_false(v->value)) {
11837 peer->calltoken_required = CALLTOKEN_NO;
11838 } else if (!strcasecmp(v->value, "auto")) {
11839 peer->calltoken_required = CALLTOKEN_AUTO;
11840 } else if (ast_true(v->value)) {
11841 peer->calltoken_required = CALLTOKEN_YES;
11842 } else {
11843 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
11844 }
11845 }
11846
11847 v = v->next;
11848 if (!v) {
11849 v = alt;
11850 alt = NULL;
11851 }
11852 }
11853 if (!peer->authmethods)
11854 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11855 ast_clear_flag(peer, IAX_DELME);
11856
11857 peer->addr.sin_family = AF_INET;
11858 }
11859
11860 if (oldha)
11861 ast_free_ha(oldha);
11862
11863 if (!ast_strlen_zero(peer->mailbox)) {
11864 char *mailbox, *context;
11865 context = mailbox = ast_strdupa(peer->mailbox);
11866 strsep(&context, "@");
11867 if (ast_strlen_zero(context))
11868 context = "default";
11869 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
11870 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
11871 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
11872 AST_EVENT_IE_END);
11873 }
11874
11875 return peer;
11876 }
11877
11878 static void user_destructor(void *obj)
11879 {
11880 struct iax2_user *user = obj;
11881
11882 ast_free_ha(user->ha);
11883 free_context(user->contexts);
11884 if(user->vars) {
11885 ast_variables_destroy(user->vars);
11886 user->vars = NULL;
11887 }
11888 ast_string_field_free_memory(user);
11889 }
11890
11891
11892 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
11893 {
11894 struct iax2_user *user = NULL;
11895 struct iax2_context *con, *conl = NULL;
11896 struct ast_ha *oldha = NULL;
11897 struct iax2_context *oldcon = NULL;
11898 int format;
11899 int firstpass=1;
11900 int oldcurauthreq = 0;
11901 char *varname = NULL, *varval = NULL;
11902 struct ast_variable *tmpvar = NULL;
11903 struct iax2_user tmp_user = {
11904 .name = name,
11905 };
11906
11907 if (!temponly) {
11908 user = ao2_find(users, &tmp_user, OBJ_POINTER);
11909 if (user && !ast_test_flag(user, IAX_DELME))
11910 firstpass = 0;
11911 }
11912
11913 if (user) {
11914 if (firstpass) {
11915 oldcurauthreq = user->curauthreq;
11916 oldha = user->ha;
11917 oldcon = user->contexts;
11918 user->ha = NULL;
11919 user->contexts = NULL;
11920 }
11921
11922 ao2_unlink(users, user);
11923 } else {
11924 user = ao2_alloc(sizeof(*user), user_destructor);
11925 }
11926
11927 if (user) {
11928 if (firstpass) {
11929 ast_string_field_free_memory(user);
11930 memset(user, 0, sizeof(struct iax2_user));
11931 if (ast_string_field_init(user, 32)) {
11932 user = user_unref(user);
11933 goto cleanup;
11934 }
11935 user->maxauthreq = maxauthreq;
11936 user->curauthreq = oldcurauthreq;
11937 user->prefs = prefs;
11938 user->capability = iax2_capability;
11939 user->encmethods = iax2_encryption;
11940 user->adsi = adsi;
11941 user->calltoken_required = CALLTOKEN_DEFAULT;
11942 ast_string_field_set(user, name, name);
11943 ast_string_field_set(user, language, language);
11944 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
11945 ast_clear_flag(user, IAX_HASCALLERID);
11946 ast_string_field_set(user, cid_name, "");
11947 ast_string_field_set(user, cid_num, "");
11948 ast_string_field_set(user, accountcode, accountcode);
11949 ast_string_field_set(user, mohinterpret, mohinterpret);
11950 ast_string_field_set(user, mohsuggest, mohsuggest);
11951 }
11952 if (!v) {
11953 v = alt;
11954 alt = NULL;
11955 }
11956 while(v) {
11957 if (!strcasecmp(v->name, "context")) {
11958 con = build_context(v->value);
11959 if (con) {
11960 if (conl)
11961 conl->next = con;
11962 else
11963 user->contexts = con;
11964 conl = con;
11965 }
11966 } else if (!strcasecmp(v->name, "permit") ||
11967 !strcasecmp(v->name, "deny")) {
11968 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
11969 } else if (!strcasecmp(v->name, "setvar")) {
11970 varname = ast_strdupa(v->value);
11971 if (varname && (varval = strchr(varname,'='))) {
11972 *varval = '\0';
11973 varval++;
11974 if((tmpvar = ast_variable_new(varname, varval, ""))) {
11975 tmpvar->next = user->vars;
11976 user->vars = tmpvar;
11977 }
11978 }
11979 } else if (!strcasecmp(v->name, "allow")) {
11980 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
11981 } else if (!strcasecmp(v->name, "disallow")) {
11982 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
11983 } else if (!strcasecmp(v->name, "trunk")) {
11984 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
11985 if (ast_test_flag(user, IAX_TRUNK) && !timer) {
11986 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
11987 ast_clear_flag(user, IAX_TRUNK);
11988 }
11989 } else if (!strcasecmp(v->name, "auth")) {
11990 user->authmethods = get_auth_methods(v->value);
11991 } else if (!strcasecmp(v->name, "encryption")) {
11992 user->encmethods |= get_encrypt_methods(v->value);
11993 } else if (!strcasecmp(v->name, "transfer")) {
11994 if (!strcasecmp(v->value, "mediaonly")) {
11995 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
11996 } else if (ast_true(v->value)) {
11997 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11998 } else
11999 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12000 } else if (!strcasecmp(v->name, "codecpriority")) {
12001 if(!strcasecmp(v->value, "caller"))
12002 ast_set_flag(user, IAX_CODEC_USER_FIRST);
12003 else if(!strcasecmp(v->value, "disabled"))
12004 ast_set_flag(user, IAX_CODEC_NOPREFS);
12005 else if(!strcasecmp(v->value, "reqonly")) {
12006 ast_set_flag(user, IAX_CODEC_NOCAP);
12007 ast_set_flag(user, IAX_CODEC_NOPREFS);
12008 }
12009 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12010 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
12011 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12012 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12013 } else if (!strcasecmp(v->name, "dbsecret")) {
12014 ast_string_field_set(user, dbsecret, v->value);
12015 } else if (!strcasecmp(v->name, "secret")) {
12016 if (!ast_strlen_zero(user->secret)) {
12017 char *old = ast_strdupa(user->secret);
12018
12019 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12020 } else
12021 ast_string_field_set(user, secret, v->value);
12022 } else if (!strcasecmp(v->name, "callerid")) {
12023 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12024 char name2[80];
12025 char num2[80];
12026 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12027 ast_string_field_set(user, cid_name, name2);
12028 ast_string_field_set(user, cid_num, num2);
12029 ast_set_flag(user, IAX_HASCALLERID);
12030 } else {
12031 ast_clear_flag(user, IAX_HASCALLERID);
12032 ast_string_field_set(user, cid_name, "");
12033 ast_string_field_set(user, cid_num, "");
12034 }
12035 } else if (!strcasecmp(v->name, "fullname")) {
12036 if (!ast_strlen_zero(v->value)) {
12037 ast_string_field_set(user, cid_name, v->value);
12038 ast_set_flag(user, IAX_HASCALLERID);
12039 } else {
12040 ast_string_field_set(user, cid_name, "");
12041 if (ast_strlen_zero(user->cid_num))
12042 ast_clear_flag(user, IAX_HASCALLERID);
12043 }
12044 } else if (!strcasecmp(v->name, "cid_number")) {
12045 if (!ast_strlen_zero(v->value)) {
12046 ast_string_field_set(user, cid_num, v->value);
12047 ast_set_flag(user, IAX_HASCALLERID);
12048 } else {
12049 ast_string_field_set(user, cid_num, "");
12050 if (ast_strlen_zero(user->cid_name))
12051 ast_clear_flag(user, IAX_HASCALLERID);
12052 }
12053 } else if (!strcasecmp(v->name, "accountcode")) {
12054 ast_string_field_set(user, accountcode, v->value);
12055 } else if (!strcasecmp(v->name, "mohinterpret")) {
12056 ast_string_field_set(user, mohinterpret, v->value);
12057 } else if (!strcasecmp(v->name, "mohsuggest")) {
12058 ast_string_field_set(user, mohsuggest, v->value);
12059 } else if (!strcasecmp(v->name, "parkinglot")) {
12060 ast_string_field_set(user, parkinglot, v->value);
12061 } else if (!strcasecmp(v->name, "language")) {
12062 ast_string_field_set(user, language, v->value);
12063 } else if (!strcasecmp(v->name, "amaflags")) {
12064 format = ast_cdr_amaflags2int(v->value);
12065 if (format < 0) {
12066 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12067 } else {
12068 user->amaflags = format;
12069 }
12070 } else if (!strcasecmp(v->name, "inkeys")) {
12071 ast_string_field_set(user, inkeys, v->value);
12072 } else if (!strcasecmp(v->name, "maxauthreq")) {
12073 user->maxauthreq = atoi(v->value);
12074 if (user->maxauthreq < 0)
12075 user->maxauthreq = 0;
12076 } else if (!strcasecmp(v->name, "adsi")) {
12077 user->adsi = ast_true(v->value);
12078 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12079
12080 if (ast_false(v->value)) {
12081 user->calltoken_required = CALLTOKEN_NO;
12082 } else if (!strcasecmp(v->value, "auto")) {
12083 user->calltoken_required = CALLTOKEN_AUTO;
12084 } else if (ast_true(v->value)) {
12085 user->calltoken_required = CALLTOKEN_YES;
12086 } else {
12087 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12088 }
12089 }
12090
12091 v = v->next;
12092 if (!v) {
12093 v = alt;
12094 alt = NULL;
12095 }
12096 }
12097 if (!user->authmethods) {
12098 if (!ast_strlen_zero(user->secret)) {
12099 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12100 if (!ast_strlen_zero(user->inkeys))
12101 user->authmethods |= IAX_AUTH_RSA;
12102 } else if (!ast_strlen_zero(user->inkeys)) {
12103 user->authmethods = IAX_AUTH_RSA;
12104 } else {
12105 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12106 }
12107 }
12108 ast_clear_flag(user, IAX_DELME);
12109 }
12110 cleanup:
12111 if (oldha)
12112 ast_free_ha(oldha);
12113 if (oldcon)
12114 free_context(oldcon);
12115 return user;
12116 }
12117
12118 static int peer_delme_cb(void *obj, void *arg, int flags)
12119 {
12120 struct iax2_peer *peer = obj;
12121
12122 ast_set_flag(peer, IAX_DELME);
12123
12124 return 0;
12125 }
12126
12127 static int user_delme_cb(void *obj, void *arg, int flags)
12128 {
12129 struct iax2_user *user = obj;
12130
12131 ast_set_flag(user, IAX_DELME);
12132
12133 return 0;
12134 }
12135
12136 static void delete_users(void)
12137 {
12138 struct iax2_registry *reg;
12139
12140 ao2_callback(users, 0, user_delme_cb, NULL);
12141
12142 AST_LIST_LOCK(®istrations);
12143 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12144 AST_SCHED_DEL(sched, reg->expire);
12145 if (reg->callno) {
12146 int callno = reg->callno;
12147 ast_mutex_lock(&iaxsl[callno]);
12148 if (iaxs[callno]) {
12149 iaxs[callno]->reg = NULL;
12150 iax2_destroy(callno);
12151 }
12152 ast_mutex_unlock(&iaxsl[callno]);
12153 }
12154 if (reg->dnsmgr)
12155 ast_dnsmgr_release(reg->dnsmgr);
12156 ast_free(reg);
12157 }
12158 AST_LIST_UNLOCK(®istrations);
12159
12160 ao2_callback(peers, 0, peer_delme_cb, NULL);
12161 }
12162
12163 static void prune_users(void)
12164 {
12165 struct iax2_user *user;
12166 struct ao2_iterator i;
12167
12168 i = ao2_iterator_init(users, 0);
12169 while ((user = ao2_iterator_next(&i))) {
12170 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
12171 ao2_unlink(users, user);
12172 }
12173 user_unref(user);
12174 }
12175 }
12176
12177
12178 static void prune_peers(void)
12179 {
12180 struct iax2_peer *peer;
12181 struct ao2_iterator i;
12182
12183 i = ao2_iterator_init(peers, 0);
12184 while ((peer = ao2_iterator_next(&i))) {
12185 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
12186 unlink_peer(peer);
12187 }
12188 peer_unref(peer);
12189 }
12190 }
12191
12192 static void set_config_destroy(void)
12193 {
12194 strcpy(accountcode, "");
12195 strcpy(language, "");
12196 strcpy(mohinterpret, "default");
12197 strcpy(mohsuggest, "");
12198 trunkmaxsize = MAX_TRUNKDATA;
12199 amaflags = 0;
12200 delayreject = 0;
12201 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
12202 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
12203 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
12204 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
12205 delete_users();
12206 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12207 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12208 }
12209
12210
12211 static int set_config(const char *config_file, int reload)
12212 {
12213 struct ast_config *cfg, *ucfg;
12214 int capability=iax2_capability;
12215 struct ast_variable *v;
12216 char *cat;
12217 const char *utype;
12218 const char *tosval;
12219 int format;
12220 int portno = IAX_DEFAULT_PORTNO;
12221 int x;
12222 int mtuv;
12223 struct iax2_user *user;
12224 struct iax2_peer *peer;
12225 struct ast_netsock *ns;
12226 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12227 #if 0
12228 static unsigned short int last_port=0;
12229 #endif
12230
12231 cfg = ast_config_load(config_file, config_flags);
12232
12233 if (!cfg) {
12234 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12235 return -1;
12236 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12237 ucfg = ast_config_load("users.conf", config_flags);
12238 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12239 return 0;
12240
12241 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12242 cfg = ast_config_load(config_file, config_flags);
12243 } else {
12244 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12245 ucfg = ast_config_load("users.conf", config_flags);
12246 }
12247
12248 if (reload) {
12249 set_config_destroy();
12250 }
12251
12252
12253 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12254
12255
12256 memset(&globalflags, 0, sizeof(globalflags));
12257 ast_set_flag(&globalflags, IAX_RTUPDATE);
12258
12259
12260 iax2_encryption |= IAX_ENCRYPT_KEYROTATE;
12261 #ifdef SO_NO_CHECK
12262 nochecksums = 0;
12263 #endif
12264
12265 default_parkinglot[0] = '\0';
12266
12267 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12268 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12269 global_max_trunk_mtu = MAX_TRUNK_MTU;
12270 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12271 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12272
12273 maxauthreq = 3;
12274
12275 srvlookup = 0;
12276
12277 v = ast_variable_browse(cfg, "general");
12278
12279
12280 tosval = ast_variable_retrieve(cfg, "general", "tos");
12281 if (tosval) {
12282 if (ast_str2tos(tosval, &qos.tos))
12283 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
12284 }
12285
12286 tosval = ast_variable_retrieve(cfg, "general", "cos");
12287 if (tosval) {
12288 if (ast_str2cos(tosval, &qos.cos))
12289 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
12290 }
12291 while(v) {
12292 if (!strcasecmp(v->name, "bindport")){
12293 if (reload)
12294 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
12295 else
12296 portno = atoi(v->value);
12297 } else if (!strcasecmp(v->name, "pingtime"))
12298 ping_time = atoi(v->value);
12299 else if (!strcasecmp(v->name, "iaxthreadcount")) {
12300 if (reload) {
12301 if (atoi(v->value) != iaxthreadcount)
12302 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
12303 } else {
12304 iaxthreadcount = atoi(v->value);
12305 if (iaxthreadcount < 1) {
12306 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
12307 iaxthreadcount = 1;
12308 } else if (iaxthreadcount > 256) {
12309 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
12310 iaxthreadcount = 256;
12311 }
12312 }
12313 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
12314 if (reload) {
12315 AST_LIST_LOCK(&dynamic_list);
12316 iaxmaxthreadcount = atoi(v->value);
12317 AST_LIST_UNLOCK(&dynamic_list);
12318 } else {
12319 iaxmaxthreadcount = atoi(v->value);
12320 if (iaxmaxthreadcount < 0) {
12321 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
12322 iaxmaxthreadcount = 0;
12323 } else if (iaxmaxthreadcount > 256) {
12324 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
12325 iaxmaxthreadcount = 256;
12326 }
12327 }
12328 } else if (!strcasecmp(v->name, "nochecksums")) {
12329 #ifdef SO_NO_CHECK
12330 if (ast_true(v->value))
12331 nochecksums = 1;
12332 else
12333 nochecksums = 0;
12334 #else
12335 if (ast_true(v->value))
12336 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
12337 #endif
12338 }
12339 else if (!strcasecmp(v->name, "maxjitterbuffer"))
12340 maxjitterbuffer = atoi(v->value);
12341 else if (!strcasecmp(v->name, "resyncthreshold"))
12342 resyncthreshold = atoi(v->value);
12343 else if (!strcasecmp(v->name, "maxjitterinterps"))
12344 maxjitterinterps = atoi(v->value);
12345 else if (!strcasecmp(v->name, "jittertargetextra"))
12346 jittertargetextra = atoi(v->value);
12347 else if (!strcasecmp(v->name, "lagrqtime"))
12348 lagrq_time = atoi(v->value);
12349 else if (!strcasecmp(v->name, "maxregexpire"))
12350 max_reg_expire = atoi(v->value);
12351 else if (!strcasecmp(v->name, "minregexpire"))
12352 min_reg_expire = atoi(v->value);
12353 else if (!strcasecmp(v->name, "bindaddr")) {
12354 if (reload) {
12355 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
12356 } else {
12357 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
12358 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
12359 } else {
12360 if (strchr(v->value, ':'))
12361 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
12362 else
12363 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
12364 if (defaultsockfd < 0)
12365 defaultsockfd = ast_netsock_sockfd(ns);
12366 ast_netsock_unref(ns);
12367 }
12368 }
12369 } else if (!strcasecmp(v->name, "authdebug"))
12370 authdebug = ast_true(v->value);
12371 else if (!strcasecmp(v->name, "encryption"))
12372 iax2_encryption |= get_encrypt_methods(v->value);
12373 else if (!strcasecmp(v->name, "transfer")) {
12374 if (!strcasecmp(v->value, "mediaonly")) {
12375 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12376 } else if (ast_true(v->value)) {
12377 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12378 } else
12379 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12380 } else if (!strcasecmp(v->name, "codecpriority")) {
12381 if(!strcasecmp(v->value, "caller"))
12382 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
12383 else if(!strcasecmp(v->value, "disabled"))
12384 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12385 else if(!strcasecmp(v->value, "reqonly")) {
12386 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
12387 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12388 }
12389 } else if (!strcasecmp(v->name, "jitterbuffer"))
12390 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
12391 else if (!strcasecmp(v->name, "forcejitterbuffer"))
12392 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
12393 else if (!strcasecmp(v->name, "delayreject"))
12394 delayreject = ast_true(v->value);
12395 else if (!strcasecmp(v->name, "allowfwdownload"))
12396 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
12397 else if (!strcasecmp(v->name, "rtcachefriends"))
12398 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
12399 else if (!strcasecmp(v->name, "rtignoreregexpire"))
12400 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
12401 else if (!strcasecmp(v->name, "rtupdate"))
12402 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
12403 else if (!strcasecmp(v->name, "trunktimestamps"))
12404 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
12405 else if (!strcasecmp(v->name, "rtautoclear")) {
12406 int i = atoi(v->value);
12407 if(i > 0)
12408 global_rtautoclear = i;
12409 else
12410 i = 0;
12411 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
12412 } else if (!strcasecmp(v->name, "trunkfreq")) {
12413 trunkfreq = atoi(v->value);
12414 if (trunkfreq < 10)
12415 trunkfreq = 10;
12416 } else if (!strcasecmp(v->name, "trunkmtu")) {
12417 mtuv = atoi(v->value);
12418 if (mtuv == 0 )
12419 global_max_trunk_mtu = 0;
12420 else if (mtuv >= 172 && mtuv < 4000)
12421 global_max_trunk_mtu = mtuv;
12422 else
12423 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
12424 mtuv, v->lineno);
12425 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
12426 trunkmaxsize = atoi(v->value);
12427 if (trunkmaxsize == 0)
12428 trunkmaxsize = MAX_TRUNKDATA;
12429 } else if (!strcasecmp(v->name, "autokill")) {
12430 if (sscanf(v->value, "%30d", &x) == 1) {
12431 if (x >= 0)
12432 autokill = x;
12433 else
12434 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
12435 } else if (ast_true(v->value)) {
12436 autokill = DEFAULT_MAXMS;
12437 } else {
12438 autokill = 0;
12439 }
12440 } else if (!strcasecmp(v->name, "bandwidth")) {
12441 if (!strcasecmp(v->value, "low")) {
12442 capability = IAX_CAPABILITY_LOWBANDWIDTH;
12443 } else if (!strcasecmp(v->value, "medium")) {
12444 capability = IAX_CAPABILITY_MEDBANDWIDTH;
12445 } else if (!strcasecmp(v->value, "high")) {
12446 capability = IAX_CAPABILITY_FULLBANDWIDTH;
12447 } else
12448 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
12449 } else if (!strcasecmp(v->name, "allow")) {
12450 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
12451 } else if (!strcasecmp(v->name, "disallow")) {
12452 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
12453 } else if (!strcasecmp(v->name, "register")) {
12454 iax2_register(v->value, v->lineno);
12455 } else if (!strcasecmp(v->name, "iaxcompat")) {
12456 iaxcompat = ast_true(v->value);
12457 } else if (!strcasecmp(v->name, "regcontext")) {
12458 ast_copy_string(regcontext, v->value, sizeof(regcontext));
12459
12460 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
12461 } else if (!strcasecmp(v->name, "tos")) {
12462 if (ast_str2tos(v->value, &qos.tos))
12463 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
12464 } else if (!strcasecmp(v->name, "cos")) {
12465 if (ast_str2cos(v->value, &qos.cos))
12466 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
12467 } else if (!strcasecmp(v->name, "parkinglot")) {
12468 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
12469 } else if (!strcasecmp(v->name, "accountcode")) {
12470 ast_copy_string(accountcode, v->value, sizeof(accountcode));
12471 } else if (!strcasecmp(v->name, "mohinterpret")) {
12472 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
12473 } else if (!strcasecmp(v->name, "mohsuggest")) {
12474 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
12475 } else if (!strcasecmp(v->name, "amaflags")) {
12476 format = ast_cdr_amaflags2int(v->value);
12477 if (format < 0) {
12478 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12479 } else {
12480 amaflags = format;
12481 }
12482 } else if (!strcasecmp(v->name, "language")) {
12483 ast_copy_string(language, v->value, sizeof(language));
12484 } else if (!strcasecmp(v->name, "maxauthreq")) {
12485 maxauthreq = atoi(v->value);
12486 if (maxauthreq < 0)
12487 maxauthreq = 0;
12488 } else if (!strcasecmp(v->name, "adsi")) {
12489 adsi = ast_true(v->value);
12490 } else if (!strcasecmp(v->name, "srvlookup")) {
12491 srvlookup = ast_true(v->value);
12492 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12493 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
12494 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
12495 }
12496 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
12497 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
12498 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);
12499 }
12500 } else if(!strcasecmp(v->name, "calltokenoptional")) {
12501 if (add_calltoken_ignore(v->value)) {
12502 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
12503 }
12504 }
12505
12506 v = v->next;
12507 }
12508
12509 if (defaultsockfd < 0) {
12510 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
12511 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
12512 } else {
12513 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
12514 defaultsockfd = ast_netsock_sockfd(ns);
12515 ast_netsock_unref(ns);
12516 }
12517 }
12518 if (reload) {
12519 ast_netsock_release(outsock);
12520 outsock = ast_netsock_list_alloc();
12521 if (!outsock) {
12522 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12523 return -1;
12524 }
12525 ast_netsock_init(outsock);
12526 }
12527
12528 if (min_reg_expire > max_reg_expire) {
12529 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
12530 min_reg_expire, max_reg_expire, max_reg_expire);
12531 min_reg_expire = max_reg_expire;
12532 }
12533 iax2_capability = capability;
12534
12535 if (ucfg) {
12536 struct ast_variable *gen;
12537 int genhasiax;
12538 int genregisteriax;
12539 const char *hasiax, *registeriax;
12540
12541 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
12542 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
12543 gen = ast_variable_browse(ucfg, "general");
12544 cat = ast_category_browse(ucfg, NULL);
12545 while (cat) {
12546 if (strcasecmp(cat, "general")) {
12547 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
12548 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
12549 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
12550
12551 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
12552 if (user) {
12553 ao2_link(users, user);
12554 user = user_unref(user);
12555 }
12556 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
12557 if (peer) {
12558 if (ast_test_flag(peer, IAX_DYNAMIC))
12559 reg_source_db(peer);
12560 ao2_link(peers, peer);
12561 peer = peer_unref(peer);
12562 }
12563 }
12564 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
12565 char tmp[256];
12566 const char *host = ast_variable_retrieve(ucfg, cat, "host");
12567 const char *username = ast_variable_retrieve(ucfg, cat, "username");
12568 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
12569 if (!host)
12570 host = ast_variable_retrieve(ucfg, "general", "host");
12571 if (!username)
12572 username = ast_variable_retrieve(ucfg, "general", "username");
12573 if (!secret)
12574 secret = ast_variable_retrieve(ucfg, "general", "secret");
12575 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
12576 if (!ast_strlen_zero(secret))
12577 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
12578 else
12579 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
12580 iax2_register(tmp, 0);
12581 }
12582 }
12583 }
12584 cat = ast_category_browse(ucfg, cat);
12585 }
12586 ast_config_destroy(ucfg);
12587 }
12588
12589 cat = ast_category_browse(cfg, NULL);
12590 while(cat) {
12591 if (strcasecmp(cat, "general")) {
12592 utype = ast_variable_retrieve(cfg, cat, "type");
12593 if (!strcasecmp(cat, "callnumberlimits")) {
12594 build_callno_limits(ast_variable_browse(cfg, cat));
12595 } else if (utype) {
12596 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
12597 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
12598 if (user) {
12599 ao2_link(users, user);
12600 user = user_unref(user);
12601 }
12602 }
12603 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
12604 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
12605 if (peer) {
12606 if (ast_test_flag(peer, IAX_DYNAMIC))
12607 reg_source_db(peer);
12608 ao2_link(peers, peer);
12609 peer = peer_unref(peer);
12610 }
12611 } else if (strcasecmp(utype, "user")) {
12612 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
12613 }
12614 } else
12615 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
12616 }
12617 cat = ast_category_browse(cfg, cat);
12618 }
12619 ast_config_destroy(cfg);
12620 return 1;
12621 }
12622
12623 static void poke_all_peers(void)
12624 {
12625 struct ao2_iterator i;
12626 struct iax2_peer *peer;
12627
12628 i = ao2_iterator_init(peers, 0);
12629 while ((peer = ao2_iterator_next(&i))) {
12630 iax2_poke_peer(peer, 0);
12631 peer_unref(peer);
12632 }
12633 }
12634 static int reload_config(void)
12635 {
12636 static const char config[] = "iax.conf";
12637 struct iax2_registry *reg;
12638
12639 if (set_config(config, 1) > 0) {
12640 prune_peers();
12641 prune_users();
12642 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
12643 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
12644 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
12645 trunk_timed = trunk_untimed = 0;
12646 trunk_nmaxmtu = trunk_maxmtu = 0;
12647 memset(&debugaddr, '\0', sizeof(debugaddr));
12648
12649 AST_LIST_LOCK(®istrations);
12650 AST_LIST_TRAVERSE(®istrations, reg, entry)
12651 iax2_do_register(reg);
12652 AST_LIST_UNLOCK(®istrations);
12653
12654
12655 poke_all_peers();
12656 }
12657
12658 reload_firmware(0);
12659 iax_provision_reload(1);
12660 ast_unload_realtime("iaxpeers");
12661
12662 return 0;
12663 }
12664
12665 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
12666 {
12667 switch (cmd) {
12668 case CLI_INIT:
12669 e->command = "iax2 reload";
12670 e->usage =
12671 "Usage: iax2 reload\n"
12672 " Reloads IAX configuration from iax.conf\n";
12673 return NULL;
12674 case CLI_GENERATE:
12675 return NULL;
12676 }
12677
12678 reload_config();
12679
12680 return CLI_SUCCESS;
12681 }
12682
12683 static int reload(void)
12684 {
12685 return reload_config();
12686 }
12687
12688 static int cache_get_callno_locked(const char *data)
12689 {
12690 struct sockaddr_in sin;
12691 int x;
12692 int callno;
12693 struct iax_ie_data ied;
12694 struct create_addr_info cai;
12695 struct parsed_dial_string pds;
12696 char *tmpstr;
12697
12698 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12699
12700
12701 if (!ast_mutex_trylock(&iaxsl[x])) {
12702 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
12703 return x;
12704 ast_mutex_unlock(&iaxsl[x]);
12705 }
12706 }
12707
12708
12709
12710 memset(&cai, 0, sizeof(cai));
12711 memset(&ied, 0, sizeof(ied));
12712 memset(&pds, 0, sizeof(pds));
12713
12714 tmpstr = ast_strdupa(data);
12715 parse_dial_string(tmpstr, &pds);
12716
12717 if (ast_strlen_zero(pds.peer)) {
12718 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
12719 return -1;
12720 }
12721
12722
12723 if (create_addr(pds.peer, NULL, &sin, &cai))
12724 return -1;
12725
12726 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
12727 pds.peer, pds.username, pds.password, pds.context);
12728
12729 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12730 if (callno < 1) {
12731 ast_log(LOG_WARNING, "Unable to create call\n");
12732 return -1;
12733 }
12734
12735 ast_string_field_set(iaxs[callno], dproot, data);
12736 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
12737
12738 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
12739 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
12740
12741
12742
12743 if (pds.exten)
12744 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
12745 if (pds.username)
12746 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
12747 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
12748 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
12749
12750 if (pds.password)
12751 ast_string_field_set(iaxs[callno], secret, pds.password);
12752 if (pds.key)
12753 ast_string_field_set(iaxs[callno], outkey, pds.key);
12754
12755 add_empty_calltoken_ie(iaxs[callno], &ied);
12756 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
12757
12758 return callno;
12759 }
12760
12761 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
12762 {
12763 struct iax2_dpcache *dp = NULL;
12764 struct timeval now = ast_tvnow();
12765 int x, com[2], timeout, old = 0, outfd, doabort, callno;
12766 struct ast_channel *c = NULL;
12767 struct ast_frame *f = NULL;
12768
12769 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
12770 if (ast_tvcmp(now, dp->expiry) > 0) {
12771 AST_LIST_REMOVE_CURRENT(cache_list);
12772 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
12773 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
12774 else
12775 ast_free(dp);
12776 continue;
12777 }
12778 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
12779 break;
12780 }
12781 AST_LIST_TRAVERSE_SAFE_END;
12782
12783 if (!dp) {
12784
12785
12786 if ((callno = cache_get_callno_locked(data)) < 0) {
12787 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
12788 return NULL;
12789 }
12790 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
12791 ast_mutex_unlock(&iaxsl[callno]);
12792 return NULL;
12793 }
12794 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
12795 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
12796 dp->expiry = ast_tvnow();
12797 dp->orig = dp->expiry;
12798
12799 dp->expiry.tv_sec += iaxdefaultdpcache;
12800 dp->flags = CACHE_FLAG_PENDING;
12801 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
12802 dp->waiters[x] = -1;
12803
12804 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
12805 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
12806
12807 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
12808 iax2_dprequest(dp, callno);
12809 ast_mutex_unlock(&iaxsl[callno]);
12810 }
12811
12812
12813 if (dp->flags & CACHE_FLAG_PENDING) {
12814
12815
12816 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
12817
12818 if (dp->waiters[x] < 0)
12819 break;
12820 }
12821 if (x >= ARRAY_LEN(dp->waiters)) {
12822 ast_log(LOG_WARNING, "No more waiter positions available\n");
12823 return NULL;
12824 }
12825 if (pipe(com)) {
12826 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
12827 return NULL;
12828 }
12829 dp->waiters[x] = com[1];
12830
12831 timeout = iaxdefaulttimeout * 1000;
12832
12833 AST_LIST_UNLOCK(&dpcache);
12834
12835 if (chan)
12836 old = ast_channel_defer_dtmf(chan);
12837 doabort = 0;
12838 while(timeout) {
12839 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
12840 if (outfd > -1)
12841 break;
12842 if (!c)
12843 continue;
12844 if (!(f = ast_read(c))) {
12845 doabort = 1;
12846 break;
12847 }
12848 ast_frfree(f);
12849 }
12850 if (!timeout) {
12851 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
12852 }
12853 AST_LIST_LOCK(&dpcache);
12854 dp->waiters[x] = -1;
12855 close(com[1]);
12856 close(com[0]);
12857 if (doabort) {
12858
12859
12860 if (!old && chan)
12861 ast_channel_undefer_dtmf(chan);
12862 return NULL;
12863 }
12864 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
12865
12866 if (dp->flags & CACHE_FLAG_PENDING) {
12867
12868
12869 dp->flags &= ~CACHE_FLAG_PENDING;
12870 dp->flags |= CACHE_FLAG_TIMEOUT;
12871
12872
12873 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
12874 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
12875 if (dp->waiters[x] > -1) {
12876 if (write(dp->waiters[x], "asdf", 4) < 0) {
12877 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
12878 }
12879 }
12880 }
12881 }
12882 }
12883
12884 if (!old && chan)
12885 ast_channel_undefer_dtmf(chan);
12886 }
12887 return dp;
12888 }
12889
12890
12891 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
12892 {
12893 int res = 0;
12894 struct iax2_dpcache *dp = NULL;
12895 #if 0
12896 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
12897 #endif
12898 if ((priority != 1) && (priority != 2))
12899 return 0;
12900
12901 AST_LIST_LOCK(&dpcache);
12902 if ((dp = find_cache(chan, data, context, exten, priority))) {
12903 if (dp->flags & CACHE_FLAG_EXISTS)
12904 res = 1;
12905 } else {
12906 ast_log(LOG_WARNING, "Unable to make DP cache\n");
12907 }
12908 AST_LIST_UNLOCK(&dpcache);
12909
12910 return res;
12911 }
12912
12913
12914 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
12915 {
12916 int res = 0;
12917 struct iax2_dpcache *dp = NULL;
12918 #if 0
12919 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
12920 #endif
12921 if ((priority != 1) && (priority != 2))
12922 return 0;
12923
12924 AST_LIST_LOCK(&dpcache);
12925 if ((dp = find_cache(chan, data, context, exten, priority))) {
12926 if (dp->flags & CACHE_FLAG_CANEXIST)
12927 res = 1;
12928 } else {
12929 ast_log(LOG_WARNING, "Unable to make DP cache\n");
12930 }
12931 AST_LIST_UNLOCK(&dpcache);
12932
12933 return res;
12934 }
12935
12936
12937 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
12938 {
12939 int res = 0;
12940 struct iax2_dpcache *dp = NULL;
12941 #if 0
12942 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
12943 #endif
12944 if ((priority != 1) && (priority != 2))
12945 return 0;
12946
12947 AST_LIST_LOCK(&dpcache);
12948 if ((dp = find_cache(chan, data, context, exten, priority))) {
12949 if (dp->flags & CACHE_FLAG_MATCHMORE)
12950 res = 1;
12951 } else {
12952 ast_log(LOG_WARNING, "Unable to make DP cache\n");
12953 }
12954 AST_LIST_UNLOCK(&dpcache);
12955
12956 return res;
12957 }
12958
12959
12960 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
12961 {
12962 char odata[256];
12963 char req[256];
12964 char *ncontext;
12965 struct iax2_dpcache *dp = NULL;
12966 struct ast_app *dial = NULL;
12967 #if 0
12968 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);
12969 #endif
12970 if (priority == 2) {
12971
12972 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
12973 if (dialstatus) {
12974 dial = pbx_findapp(dialstatus);
12975 if (dial)
12976 pbx_exec(chan, dial, "");
12977 }
12978 return -1;
12979 } else if (priority != 1)
12980 return -1;
12981
12982 AST_LIST_LOCK(&dpcache);
12983 if ((dp = find_cache(chan, data, context, exten, priority))) {
12984 if (dp->flags & CACHE_FLAG_EXISTS) {
12985 ast_copy_string(odata, data, sizeof(odata));
12986 ncontext = strchr(odata, '/');
12987 if (ncontext) {
12988 *ncontext = '\0';
12989 ncontext++;
12990 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
12991 } else {
12992 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
12993 }
12994 ast_verb(3, "Executing Dial('%s')\n", req);
12995 } else {
12996 AST_LIST_UNLOCK(&dpcache);
12997 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
12998 return -1;
12999 }
13000 }
13001 AST_LIST_UNLOCK(&dpcache);
13002
13003 if ((dial = pbx_findapp("Dial")))
13004 return pbx_exec(chan, dial, req);
13005 else
13006 ast_log(LOG_WARNING, "No dial application registered\n");
13007
13008 return -1;
13009 }
13010
13011 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13012 {
13013 struct iax2_peer *peer;
13014 char *peername, *colname;
13015
13016 peername = ast_strdupa(data);
13017
13018
13019 if (!strcmp(peername,"CURRENTCHANNEL")) {
13020 unsigned short callno;
13021 if (chan->tech != &iax2_tech)
13022 return -1;
13023 callno = PTR_TO_CALLNO(chan->tech_pvt);
13024 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13025 return 0;
13026 }
13027
13028 if ((colname = strchr(peername, ',')))
13029 *colname++ = '\0';
13030 else
13031 colname = "ip";
13032
13033 if (!(peer = find_peer(peername, 1)))
13034 return -1;
13035
13036 if (!strcasecmp(colname, "ip")) {
13037 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
13038 } else if (!strcasecmp(colname, "status")) {
13039 peer_status(peer, buf, len);
13040 } else if (!strcasecmp(colname, "mailbox")) {
13041 ast_copy_string(buf, peer->mailbox, len);
13042 } else if (!strcasecmp(colname, "context")) {
13043 ast_copy_string(buf, peer->context, len);
13044 } else if (!strcasecmp(colname, "expire")) {
13045 snprintf(buf, len, "%d", peer->expire);
13046 } else if (!strcasecmp(colname, "dynamic")) {
13047 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13048 } else if (!strcasecmp(colname, "callerid_name")) {
13049 ast_copy_string(buf, peer->cid_name, len);
13050 } else if (!strcasecmp(colname, "callerid_num")) {
13051 ast_copy_string(buf, peer->cid_num, len);
13052 } else if (!strcasecmp(colname, "codecs")) {
13053 ast_getformatname_multiple(buf, len -1, peer->capability);
13054 } else if (!strncasecmp(colname, "codec[", 6)) {
13055 char *codecnum, *ptr;
13056 int codec = 0;
13057
13058 codecnum = strchr(colname, '[');
13059 *codecnum = '\0';
13060 codecnum++;
13061 if ((ptr = strchr(codecnum, ']'))) {
13062 *ptr = '\0';
13063 }
13064 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13065 ast_copy_string(buf, ast_getformatname(codec), len);
13066 } else {
13067 buf[0] = '\0';
13068 }
13069 } else {
13070 buf[0] = '\0';
13071 }
13072
13073 peer_unref(peer);
13074
13075 return 0;
13076 }
13077
13078 struct ast_custom_function iaxpeer_function = {
13079 .name = "IAXPEER",
13080 .synopsis = "Gets IAX peer information",
13081 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[,item])",
13082 .read = function_iaxpeer,
13083 .desc = "If peername specified, valid items are:\n"
13084 "- ip (default) The IP address.\n"
13085 "- status The peer's status (if qualify=yes)\n"
13086 "- mailbox The configured mailbox.\n"
13087 "- context The configured context.\n"
13088 "- expire The epoch time of the next expire.\n"
13089 "- dynamic Is it dynamic? (yes/no).\n"
13090 "- callerid_name The configured Caller ID name.\n"
13091 "- callerid_num The configured Caller ID number.\n"
13092 "- codecs The configured codecs.\n"
13093 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
13094 "\n"
13095 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
13096 "\n"
13097 };
13098
13099 static int acf_channel_write(struct ast_channel *chan, const char *function, char *args, const char *value)
13100 {
13101 struct chan_iax2_pvt *pvt;
13102 unsigned int callno;
13103 int res = 0;
13104
13105 if (!chan || chan->tech != &iax2_tech) {
13106 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13107 return -1;
13108 }
13109
13110 callno = PTR_TO_CALLNO(chan->tech_pvt);
13111 ast_mutex_lock(&iaxsl[callno]);
13112 if (!(pvt = iaxs[callno])) {
13113 ast_mutex_unlock(&iaxsl[callno]);
13114 return -1;
13115 }
13116
13117 if (!strcasecmp(args, "osptoken"))
13118 ast_string_field_set(pvt, osptoken, value);
13119 else
13120 res = -1;
13121
13122 ast_mutex_unlock(&iaxsl[callno]);
13123
13124 return res;
13125 }
13126
13127 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13128 {
13129 struct chan_iax2_pvt *pvt;
13130 unsigned int callno;
13131 int res = 0;
13132
13133 if (!chan || chan->tech != &iax2_tech) {
13134 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13135 return -1;
13136 }
13137
13138 callno = PTR_TO_CALLNO(chan->tech_pvt);
13139 ast_mutex_lock(&iaxsl[callno]);
13140 if (!(pvt = iaxs[callno])) {
13141 ast_mutex_unlock(&iaxsl[callno]);
13142 return -1;
13143 }
13144
13145 if (!strcasecmp(args, "osptoken")) {
13146 ast_copy_string(buf, pvt->osptoken, buflen);
13147 } else if (!strcasecmp(args, "peerip")) {
13148 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13149 } else if (!strcasecmp(args, "peername")) {
13150 ast_copy_string(buf, pvt->username, buflen);
13151 } else {
13152 res = -1;
13153 }
13154
13155 ast_mutex_unlock(&iaxsl[callno]);
13156
13157 return res;
13158 }
13159
13160
13161 static int iax2_devicestate(void *data)
13162 {
13163 struct parsed_dial_string pds;
13164 char *tmp = ast_strdupa(data);
13165 struct iax2_peer *p;
13166 int res = AST_DEVICE_INVALID;
13167
13168 memset(&pds, 0, sizeof(pds));
13169 parse_dial_string(tmp, &pds);
13170
13171 if (ast_strlen_zero(pds.peer)) {
13172 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13173 return res;
13174 }
13175
13176 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13177
13178
13179 if (!(p = find_peer(pds.peer, 1)))
13180 return res;
13181
13182 res = AST_DEVICE_UNAVAILABLE;
13183 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13184 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13185
13186 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
13187 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13188
13189
13190 if (p->historicms == 0 || p->historicms <= p->maxms)
13191
13192 res = AST_DEVICE_UNKNOWN;
13193 }
13194
13195 peer_unref(p);
13196
13197 return res;
13198 }
13199
13200 static struct ast_switch iax2_switch =
13201 {
13202 name: "IAX2",
13203 description: "IAX Remote Dialplan Switch",
13204 exists: iax2_exists,
13205 canmatch: iax2_canmatch,
13206 exec: iax2_exec,
13207 matchmore: iax2_matchmore,
13208 };
13209
13210
13211
13212
13213
13214
13215
13216
13217
13218
13219
13220
13221
13222
13223
13224
13225
13226
13227
13228
13229
13230
13231
13232
13233
13234
13235
13236
13237
13238
13239
13240
13241
13242
13243
13244
13245
13246
13247
13248
13249
13250
13251
13252
13253
13254
13255
13256
13257
13258
13259
13260
13261
13262
13263
13264
13265
13266
13267
13268
13269
13270
13271
13272
13273
13274
13275
13276
13277
13278
13279
13280
13281
13282
13283
13284
13285
13286
13287
13288
13289
13290
13291
13292
13293
13294
13295
13296
13297
13298
13299
13300
13301
13302
13303
13304
13305
13306
13307
13308
13309
13310
13311
13312
13313
13314 static struct ast_cli_entry cli_iax2[] = {
13315 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
13316 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
13317 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
13318 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
13319 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
13320 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
13321 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
13322 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
13323 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
13324 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
13325 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
13326 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
13327 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
13328 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
13329 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
13330 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
13331 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
13332 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
13333 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
13334 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
13335 #ifdef IAXTESTS
13336 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
13337 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
13338 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
13339 #endif
13340 };
13341
13342 static int __unload_module(void)
13343 {
13344 struct iax2_thread *thread = NULL;
13345 struct ast_context *con;
13346 int x;
13347
13348
13349
13350
13351
13352 if (netthreadid != AST_PTHREADT_NULL) {
13353 AST_LIST_LOCK(&frame_queue);
13354 ast_mutex_lock(&sched_lock);
13355 pthread_cancel(netthreadid);
13356 ast_cond_signal(&sched_cond);
13357 ast_mutex_unlock(&sched_lock);
13358 AST_LIST_UNLOCK(&frame_queue);
13359 pthread_join(netthreadid, NULL);
13360 }
13361 if (schedthreadid != AST_PTHREADT_NULL) {
13362 ast_mutex_lock(&sched_lock);
13363 pthread_cancel(schedthreadid);
13364 ast_cond_signal(&sched_cond);
13365 ast_mutex_unlock(&sched_lock);
13366 pthread_join(schedthreadid, NULL);
13367 }
13368
13369
13370 AST_LIST_LOCK(&idle_list);
13371 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list)))
13372 pthread_cancel(thread->threadid);
13373 AST_LIST_UNLOCK(&idle_list);
13374
13375 AST_LIST_LOCK(&active_list);
13376 while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list)))
13377 pthread_cancel(thread->threadid);
13378 AST_LIST_UNLOCK(&active_list);
13379
13380 AST_LIST_LOCK(&dynamic_list);
13381 while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list)))
13382 pthread_cancel(thread->threadid);
13383 AST_LIST_UNLOCK(&dynamic_list);
13384
13385
13386 while(0 < iaxactivethreadcount)
13387 usleep(10000);
13388
13389 ast_netsock_release(netsock);
13390 ast_netsock_release(outsock);
13391 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13392 if (iaxs[x]) {
13393 iax2_destroy(x);
13394 }
13395 }
13396 ast_manager_unregister( "IAXpeers" );
13397 ast_manager_unregister( "IAXpeerlist" );
13398 ast_manager_unregister( "IAXnetstats" );
13399 ast_unregister_application(papp);
13400 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
13401 ast_unregister_switch(&iax2_switch);
13402 ast_channel_unregister(&iax2_tech);
13403 delete_users();
13404 iax_provision_unload();
13405 sched_context_destroy(sched);
13406 reload_firmware(1);
13407
13408 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13409 ast_mutex_destroy(&iaxsl[x]);
13410 }
13411
13412 ao2_ref(peers, -1);
13413 ao2_ref(users, -1);
13414 ao2_ref(iax_peercallno_pvts, -1);
13415 ao2_ref(iax_transfercallno_pvts, -1);
13416 ao2_ref(peercnts, -1);
13417 ao2_ref(callno_limits, -1);
13418 ao2_ref(calltoken_ignores, -1);
13419 ao2_ref(callno_pool, -1);
13420 ao2_ref(callno_pool_trunk, -1);
13421 if (timer) {
13422 ast_timer_close(timer);
13423 }
13424
13425 con = ast_context_find(regcontext);
13426 if (con)
13427 ast_context_destroy(con, "IAX2");
13428 ast_unload_realtime("iaxpeers");
13429 return 0;
13430 }
13431
13432 static int unload_module(void)
13433 {
13434 ast_custom_function_unregister(&iaxpeer_function);
13435 ast_custom_function_unregister(&iaxvar_function);
13436 return __unload_module();
13437 }
13438
13439 static int peer_set_sock_cb(void *obj, void *arg, int flags)
13440 {
13441 struct iax2_peer *peer = obj;
13442
13443 if (peer->sockfd < 0)
13444 peer->sockfd = defaultsockfd;
13445
13446 return 0;
13447 }
13448
13449 static int pvt_hash_cb(const void *obj, const int flags)
13450 {
13451 const struct chan_iax2_pvt *pvt = obj;
13452
13453 return pvt->peercallno;
13454 }
13455
13456 static int pvt_cmp_cb(void *obj, void *arg, int flags)
13457 {
13458 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13459
13460
13461
13462
13463 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
13464 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13465 }
13466
13467 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
13468 {
13469 const struct chan_iax2_pvt *pvt = obj;
13470
13471 return pvt->transfercallno;
13472 }
13473
13474 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
13475 {
13476 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13477
13478
13479
13480
13481 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
13482 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13483 }
13484
13485 static int load_objects(void)
13486 {
13487 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
13488 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
13489
13490 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
13491 goto container_fail;
13492 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
13493 goto container_fail;
13494 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
13495 goto container_fail;
13496 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
13497 goto container_fail;
13498 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
13499 goto container_fail;
13500 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13501 goto container_fail;
13502 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13503 goto container_fail;
13504 } else if (create_callno_pools()) {
13505 goto container_fail;
13506 }
13507
13508 return 0;
13509
13510 container_fail:
13511 if (peers) {
13512 ao2_ref(peers, -1);
13513 }
13514 if (users) {
13515 ao2_ref(users, -1);
13516 }
13517 if (iax_peercallno_pvts) {
13518 ao2_ref(iax_peercallno_pvts, -1);
13519 }
13520 if (iax_transfercallno_pvts) {
13521 ao2_ref(iax_transfercallno_pvts, -1);
13522 }
13523 if (peercnts) {
13524 ao2_ref(peercnts, -1);
13525 }
13526 if (callno_limits) {
13527 ao2_ref(callno_limits, -1);
13528 }
13529 if (calltoken_ignores) {
13530 ao2_ref(calltoken_ignores, -1);
13531 }
13532 if (callno_pool) {
13533 ao2_ref(callno_pool, -1);
13534 }
13535 if (callno_pool_trunk) {
13536 ao2_ref(callno_pool_trunk, -1);
13537 }
13538 return AST_MODULE_LOAD_FAILURE;
13539 }
13540
13541
13542
13543
13544 static int load_module(void)
13545 {
13546
13547 static const char config[] = "iax.conf";
13548 int x = 0;
13549 struct iax2_registry *reg = NULL;
13550
13551 if (load_objects()) {
13552 return AST_MODULE_LOAD_FAILURE;
13553 }
13554
13555 randomcalltokendata = ast_random();
13556 ast_custom_function_register(&iaxpeer_function);
13557 ast_custom_function_register(&iaxvar_function);
13558
13559 iax_set_output(iax_debug_output);
13560 iax_set_error(iax_error_output);
13561 jb_setoutput(jb_error_output, jb_warning_output, NULL);
13562
13563 memset(iaxs, 0, sizeof(iaxs));
13564
13565 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13566 ast_mutex_init(&iaxsl[x]);
13567 }
13568
13569 ast_cond_init(&sched_cond, NULL);
13570
13571 if (!(sched = sched_context_create())) {
13572 ast_log(LOG_ERROR, "Failed to create scheduler context\n");
13573 return AST_MODULE_LOAD_FAILURE;
13574 }
13575
13576 if (!(io = io_context_create())) {
13577 ast_log(LOG_ERROR, "Failed to create I/O context\n");
13578 sched_context_destroy(sched);
13579 return AST_MODULE_LOAD_FAILURE;
13580 }
13581
13582 if (!(netsock = ast_netsock_list_alloc())) {
13583 ast_log(LOG_ERROR, "Failed to create netsock list\n");
13584 io_context_destroy(io);
13585 sched_context_destroy(sched);
13586 return AST_MODULE_LOAD_FAILURE;
13587 }
13588 ast_netsock_init(netsock);
13589
13590 outsock = ast_netsock_list_alloc();
13591 if (!outsock) {
13592 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13593 io_context_destroy(io);
13594 sched_context_destroy(sched);
13595 return AST_MODULE_LOAD_FAILURE;
13596 }
13597 ast_netsock_init(outsock);
13598
13599 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
13600
13601 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
13602
13603 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
13604 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
13605 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
13606
13607 if ((timer = ast_timer_open())) {
13608 ast_timer_set_rate(timer, trunkfreq);
13609 }
13610
13611 if (set_config(config, 0) == -1) {
13612 if (timer) {
13613 ast_timer_close(timer);
13614 }
13615 return AST_MODULE_LOAD_DECLINE;
13616 }
13617
13618 if (ast_channel_register(&iax2_tech)) {
13619 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
13620 __unload_module();
13621 return AST_MODULE_LOAD_FAILURE;
13622 }
13623
13624 if (ast_register_switch(&iax2_switch))
13625 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
13626
13627 if (start_network_thread()) {
13628 ast_log(LOG_ERROR, "Unable to start network thread\n");
13629 __unload_module();
13630 return AST_MODULE_LOAD_FAILURE;
13631 } else
13632 ast_verb(2, "IAX Ready and Listening\n");
13633
13634 AST_LIST_LOCK(®istrations);
13635 AST_LIST_TRAVERSE(®istrations, reg, entry)
13636 iax2_do_register(reg);
13637 AST_LIST_UNLOCK(®istrations);
13638
13639 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
13640 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
13641
13642
13643 reload_firmware(0);
13644 iax_provision_reload(0);
13645
13646 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
13647
13648 return AST_MODULE_LOAD_SUCCESS;
13649 }
13650
13651 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
13652 .load = load_module,
13653 .unload = unload_module,
13654 .reload = reload,
13655 );