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: 238430 $")
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 IAX_SHRINKCALLERID = (1 << 27),
00300 };
00301
00302 static int global_rtautoclear = 120;
00303
00304 static int reload_config(void);
00305
00306
00307
00308
00309 enum calltoken_peer_enum {
00310
00311 CALLTOKEN_DEFAULT = 0,
00312
00313 CALLTOKEN_YES = 1,
00314
00315
00316 CALLTOKEN_AUTO = 2,
00317
00318 CALLTOKEN_NO = 3,
00319 };
00320
00321 struct iax2_user {
00322 AST_DECLARE_STRING_FIELDS(
00323 AST_STRING_FIELD(name);
00324 AST_STRING_FIELD(secret);
00325 AST_STRING_FIELD(dbsecret);
00326 AST_STRING_FIELD(accountcode);
00327 AST_STRING_FIELD(mohinterpret);
00328 AST_STRING_FIELD(mohsuggest);
00329 AST_STRING_FIELD(inkeys);
00330 AST_STRING_FIELD(language);
00331 AST_STRING_FIELD(cid_num);
00332 AST_STRING_FIELD(cid_name);
00333 AST_STRING_FIELD(parkinglot);
00334 );
00335
00336 int authmethods;
00337 int encmethods;
00338 int amaflags;
00339 int adsi;
00340 unsigned int flags;
00341 int capability;
00342 int maxauthreq;
00343 int curauthreq;
00344 struct ast_codec_pref prefs;
00345 struct ast_ha *ha;
00346 struct iax2_context *contexts;
00347 struct ast_variable *vars;
00348 enum calltoken_peer_enum calltoken_required;
00349 };
00350
00351 struct iax2_peer {
00352 AST_DECLARE_STRING_FIELDS(
00353 AST_STRING_FIELD(name);
00354 AST_STRING_FIELD(username);
00355 AST_STRING_FIELD(secret);
00356 AST_STRING_FIELD(dbsecret);
00357 AST_STRING_FIELD(outkey);
00358
00359 AST_STRING_FIELD(regexten);
00360 AST_STRING_FIELD(context);
00361 AST_STRING_FIELD(peercontext);
00362 AST_STRING_FIELD(mailbox);
00363 AST_STRING_FIELD(mohinterpret);
00364 AST_STRING_FIELD(mohsuggest);
00365 AST_STRING_FIELD(inkeys);
00366
00367 AST_STRING_FIELD(cid_num);
00368 AST_STRING_FIELD(cid_name);
00369 AST_STRING_FIELD(zonetag);
00370 AST_STRING_FIELD(parkinglot);
00371 );
00372 struct ast_codec_pref prefs;
00373 struct ast_dnsmgr_entry *dnsmgr;
00374 struct sockaddr_in addr;
00375 int formats;
00376 int sockfd;
00377 struct in_addr mask;
00378 int adsi;
00379 unsigned int flags;
00380
00381
00382 struct sockaddr_in defaddr;
00383 int authmethods;
00384 int encmethods;
00385
00386 int expire;
00387 int expiry;
00388 int capability;
00389
00390
00391 int callno;
00392 int pokeexpire;
00393 int lastms;
00394 int maxms;
00395
00396 int pokefreqok;
00397 int pokefreqnotok;
00398 int historicms;
00399 int smoothing;
00400 uint16_t maxcallno;
00401
00402 struct ast_event_sub *mwi_event_sub;
00403
00404 struct ast_ha *ha;
00405 enum calltoken_peer_enum calltoken_required;
00406 };
00407
00408 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00409
00410 struct iax2_trunk_peer {
00411 ast_mutex_t lock;
00412 int sockfd;
00413 struct sockaddr_in addr;
00414 struct timeval txtrunktime;
00415 struct timeval rxtrunktime;
00416 struct timeval lasttxtime;
00417 struct timeval trunkact;
00418 unsigned int lastsent;
00419
00420 unsigned char *trunkdata;
00421 unsigned int trunkdatalen;
00422 unsigned int trunkdataalloc;
00423 int trunkmaxmtu;
00424 int trunkerror;
00425 int calls;
00426 AST_LIST_ENTRY(iax2_trunk_peer) list;
00427 };
00428
00429 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00430
00431 struct iax_firmware {
00432 AST_LIST_ENTRY(iax_firmware) list;
00433 int fd;
00434 int mmaplen;
00435 int dead;
00436 struct ast_iax2_firmware_header *fwh;
00437 unsigned char *buf;
00438 };
00439
00440 enum iax_reg_state {
00441 REG_STATE_UNREGISTERED = 0,
00442 REG_STATE_REGSENT,
00443 REG_STATE_AUTHSENT,
00444 REG_STATE_REGISTERED,
00445 REG_STATE_REJECTED,
00446 REG_STATE_TIMEOUT,
00447 REG_STATE_NOAUTH
00448 };
00449
00450 enum iax_transfer_state {
00451 TRANSFER_NONE = 0,
00452 TRANSFER_BEGIN,
00453 TRANSFER_READY,
00454 TRANSFER_RELEASED,
00455 TRANSFER_PASSTHROUGH,
00456 TRANSFER_MBEGIN,
00457 TRANSFER_MREADY,
00458 TRANSFER_MRELEASED,
00459 TRANSFER_MPASSTHROUGH,
00460 TRANSFER_MEDIA,
00461 TRANSFER_MEDIAPASS
00462 };
00463
00464 struct iax2_registry {
00465 struct sockaddr_in addr;
00466 char username[80];
00467 char secret[80];
00468 int expire;
00469 int refresh;
00470 enum iax_reg_state regstate;
00471 int messages;
00472 int callno;
00473 struct sockaddr_in us;
00474 struct ast_dnsmgr_entry *dnsmgr;
00475 AST_LIST_ENTRY(iax2_registry) entry;
00476 };
00477
00478 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00479
00480
00481 #define MIN_RETRY_TIME 100
00482 #define MAX_RETRY_TIME 10000
00483
00484 #define MAX_JITTER_BUFFER 50
00485 #define MIN_JITTER_BUFFER 10
00486
00487 #define DEFAULT_TRUNKDATA 640 * 10
00488
00489 #define MAX_TIMESTAMP_SKEW 160
00490
00491
00492 #define TS_GAP_FOR_JB_RESYNC 5000
00493
00494
00495 #define MARK_IAX_SUBCLASS_TX 0x8000
00496
00497 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00498 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00499 static int iaxdynamicthreadcount = 0;
00500 static int iaxdynamicthreadnum = 0;
00501 static int iaxactivethreadcount = 0;
00502
00503 struct iax_rr {
00504 int jitter;
00505 int losspct;
00506 int losscnt;
00507 int packets;
00508 int delay;
00509 int dropped;
00510 int ooo;
00511 };
00512
00513 struct iax2_pvt_ref;
00514
00515 struct chan_iax2_pvt {
00516
00517 int sockfd;
00518
00519 int voiceformat;
00520
00521 int videoformat;
00522
00523 int svoiceformat;
00524
00525 int svideoformat;
00526
00527 int capability;
00528
00529 unsigned int last;
00530
00531 unsigned int lastsent;
00532
00533 unsigned int lastvsent;
00534
00535 unsigned int nextpred;
00536
00537 int first_iax_message;
00538
00539 int last_iax_message;
00540
00541 unsigned int notsilenttx:1;
00542
00543 unsigned int pingtime;
00544
00545 int maxtime;
00546
00547 struct sockaddr_in addr;
00548
00549 struct ast_codec_pref prefs;
00550
00551 struct ast_codec_pref rprefs;
00552
00553 unsigned short callno;
00554
00555 struct callno_entry *callno_entry;
00556
00557 unsigned short peercallno;
00558
00559
00560
00561 int chosenformat;
00562
00563 int peerformat;
00564
00565 int peercapability;
00566
00567 struct timeval offset;
00568
00569 struct timeval rxcore;
00570
00571 jitterbuf *jb;
00572
00573 int jbid;
00574
00575 int lag;
00576
00577 int error;
00578
00579 struct ast_channel *owner;
00580
00581 struct ast_flags state;
00582
00583 int expiry;
00584
00585 unsigned char oseqno;
00586
00587 unsigned char rseqno;
00588
00589 unsigned char iseqno;
00590
00591 unsigned char aseqno;
00592
00593 AST_DECLARE_STRING_FIELDS(
00594
00595 AST_STRING_FIELD(peer);
00596
00597 AST_STRING_FIELD(context);
00598
00599 AST_STRING_FIELD(cid_num);
00600 AST_STRING_FIELD(cid_name);
00601
00602 AST_STRING_FIELD(ani);
00603
00604 AST_STRING_FIELD(dnid);
00605
00606 AST_STRING_FIELD(rdnis);
00607
00608 AST_STRING_FIELD(exten);
00609
00610 AST_STRING_FIELD(username);
00611
00612 AST_STRING_FIELD(secret);
00613
00614 AST_STRING_FIELD(challenge);
00615
00616 AST_STRING_FIELD(inkeys);
00617
00618 AST_STRING_FIELD(outkey);
00619
00620 AST_STRING_FIELD(language);
00621
00622 AST_STRING_FIELD(host);
00623
00624 AST_STRING_FIELD(dproot);
00625 AST_STRING_FIELD(accountcode);
00626 AST_STRING_FIELD(mohinterpret);
00627 AST_STRING_FIELD(mohsuggest);
00628
00629 AST_STRING_FIELD(osptoken);
00630
00631 AST_STRING_FIELD(parkinglot);
00632 );
00633
00634 int authrej;
00635
00636 int authmethods;
00637
00638 int encmethods;
00639
00640 ast_aes_encrypt_key ecx;
00641
00642 ast_aes_decrypt_key mydcx;
00643
00644 ast_aes_decrypt_key dcx;
00645
00646
00647 int keyrotateid;
00648
00649 unsigned char semirand[32];
00650
00651 struct iax2_registry *reg;
00652
00653 struct iax2_peer *peerpoke;
00654
00655 unsigned int flags;
00656 int adsi;
00657
00658
00659 enum iax_transfer_state transferring;
00660
00661 int transferid;
00662
00663 struct sockaddr_in transfer;
00664
00665 unsigned short transfercallno;
00666
00667 ast_aes_encrypt_key tdcx;
00668
00669
00670 int peeradsicpe;
00671
00672
00673 unsigned short bridgecallno;
00674
00675 int pingid;
00676 int lagid;
00677 int autoid;
00678 int authid;
00679 int authfail;
00680 int initid;
00681 int calling_ton;
00682 int calling_tns;
00683 int calling_pres;
00684 int amaflags;
00685 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00686
00687 struct ast_variable *vars;
00688
00689 struct ast_variable *iaxvars;
00690
00691 struct iax_rr remote_rr;
00692
00693 int min;
00694
00695 int frames_dropped;
00696
00697 int frames_received;
00698
00699 unsigned char calltoken_ie_len;
00700
00701 char hold_signaling;
00702
00703 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00704 };
00705
00706 struct signaling_queue_entry {
00707 struct ast_frame f;
00708 AST_LIST_ENTRY(signaling_queue_entry) next;
00709 };
00710
00711
00712 static struct ao2_container *callno_pool;
00713
00714
00715 static struct ao2_container *callno_pool_trunk;
00716
00717 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00718
00719
00720
00721
00722
00723
00724
00725
00726 static AST_LIST_HEAD_STATIC(frame_queue, iax_frame);
00727
00728 static int randomcalltokendata;
00729
00730 static const time_t MAX_CALLTOKEN_DELAY = 10;
00731
00732
00733
00734
00735
00736
00737
00738
00739 #ifdef LOW_MEMORY
00740 #define MAX_PEER_BUCKETS 17
00741 #else
00742 #define MAX_PEER_BUCKETS 563
00743 #endif
00744 static struct ao2_container *peers;
00745
00746 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00747 static struct ao2_container *users;
00748
00749
00750 static struct ao2_container *peercnts;
00751
00752
00753 static struct ao2_container *callno_limits;
00754
00755
00756 static struct ao2_container *calltoken_ignores;
00757
00758 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00759
00760 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00761
00762 static uint16_t global_maxcallno;
00763
00764
00765 static uint16_t global_maxcallno_nonval;
00766
00767 static uint16_t total_nonval_callno_used = 0;
00768
00769
00770
00771 struct peercnt {
00772
00773 unsigned long addr;
00774
00775 uint16_t cur;
00776
00777 uint16_t limit;
00778
00779
00780 unsigned char reg;
00781 };
00782
00783
00784 struct addr_range {
00785
00786 struct ast_ha ha;
00787
00788 uint16_t limit;
00789
00790 unsigned char delme;
00791 };
00792
00793 struct callno_entry {
00794
00795 uint16_t callno;
00796
00797 unsigned char validated;
00798 };
00799
00800 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00801
00802 enum {
00803
00804 CACHE_FLAG_EXISTS = (1 << 0),
00805
00806 CACHE_FLAG_NONEXISTENT = (1 << 1),
00807
00808 CACHE_FLAG_CANEXIST = (1 << 2),
00809
00810 CACHE_FLAG_PENDING = (1 << 3),
00811
00812 CACHE_FLAG_TIMEOUT = (1 << 4),
00813
00814 CACHE_FLAG_TRANSMITTED = (1 << 5),
00815
00816 CACHE_FLAG_UNKNOWN = (1 << 6),
00817
00818 CACHE_FLAG_MATCHMORE = (1 << 7),
00819 };
00820
00821 struct iax2_dpcache {
00822 char peercontext[AST_MAX_CONTEXT];
00823 char exten[AST_MAX_EXTENSION];
00824 struct timeval orig;
00825 struct timeval expiry;
00826 int flags;
00827 unsigned short callno;
00828 int waiters[256];
00829 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00830 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00831 };
00832
00833 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00834
00835 static void reg_source_db(struct iax2_peer *p);
00836 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00837 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00838
00839 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00840 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state);
00841 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00842
00843 enum iax2_thread_iostate {
00844 IAX_IOSTATE_IDLE,
00845 IAX_IOSTATE_READY,
00846 IAX_IOSTATE_PROCESSING,
00847 IAX_IOSTATE_SCHEDREADY,
00848 };
00849
00850 enum iax2_thread_type {
00851 IAX_THREAD_TYPE_POOL,
00852 IAX_THREAD_TYPE_DYNAMIC,
00853 };
00854
00855 struct iax2_pkt_buf {
00856 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00857 size_t len;
00858 unsigned char buf[1];
00859 };
00860
00861 struct iax2_thread {
00862 AST_LIST_ENTRY(iax2_thread) list;
00863 enum iax2_thread_type type;
00864 enum iax2_thread_iostate iostate;
00865 #ifdef SCHED_MULTITHREADED
00866 void (*schedfunc)(const void *);
00867 const void *scheddata;
00868 #endif
00869 #ifdef DEBUG_SCHED_MULTITHREAD
00870 char curfunc[80];
00871 #endif
00872 int actions;
00873 pthread_t threadid;
00874 int threadnum;
00875 struct sockaddr_in iosin;
00876 unsigned char readbuf[4096];
00877 unsigned char *buf;
00878 ssize_t buf_len;
00879 size_t buf_size;
00880 int iofd;
00881 time_t checktime;
00882 ast_mutex_t lock;
00883 ast_cond_t cond;
00884 ast_mutex_t init_lock;
00885 ast_cond_t init_cond;
00886
00887
00888
00889
00890 struct {
00891 unsigned short callno;
00892 struct sockaddr_in sin;
00893 unsigned char type;
00894 unsigned char csub;
00895 } ffinfo;
00896
00897
00898
00899 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00900 };
00901
00902
00903 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00904 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00905 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00906
00907 static void *iax2_process_thread(void *data);
00908 static void iax2_destroy(int callno);
00909
00910 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00911 {
00912 ast_mutex_lock(lock);
00913 ast_cond_signal(cond);
00914 ast_mutex_unlock(lock);
00915 }
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 static struct ao2_container *iax_peercallno_pvts;
00937
00938
00939
00940
00941
00942
00943
00944
00945 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00946
00947
00948
00949
00950
00951
00952 static struct ao2_container *iax_transfercallno_pvts;
00953
00954
00955
00956 #define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2
00957
00958
00959 static struct sockaddr_in debugaddr;
00960
00961 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
00962 {
00963 if (iaxdebug ||
00964 (sin && debugaddr.sin_addr.s_addr &&
00965 (!ntohs(debugaddr.sin_port) ||
00966 debugaddr.sin_port == sin->sin_port) &&
00967 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
00968 if (iaxdebug) {
00969 iax_showframe(f, fhi, rx, sin, datalen);
00970 } else {
00971 iaxdebug = 1;
00972 iax_showframe(f, fhi, rx, sin, datalen);
00973 iaxdebug = 0;
00974 }
00975 }
00976 }
00977
00978 static void iax_debug_output(const char *data)
00979 {
00980 if (iaxdebug)
00981 ast_verbose("%s", data);
00982 }
00983
00984 static void iax_error_output(const char *data)
00985 {
00986 ast_log(LOG_WARNING, "%s", data);
00987 }
00988
00989 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
00990 {
00991 va_list args;
00992 char buf[1024];
00993
00994 va_start(args, fmt);
00995 vsnprintf(buf, sizeof(buf), fmt, args);
00996 va_end(args);
00997
00998 ast_log(LOG_ERROR, "%s", buf);
00999 }
01000
01001 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01002 {
01003 va_list args;
01004 char buf[1024];
01005
01006 va_start(args, fmt);
01007 vsnprintf(buf, sizeof(buf), fmt, args);
01008 va_end(args);
01009
01010 ast_log(LOG_WARNING, "%s", buf);
01011 }
01012
01013 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01014 {
01015 va_list args;
01016 char buf[1024];
01017
01018 va_start(args, fmt);
01019 vsnprintf(buf, sizeof(buf), fmt, args);
01020 va_end(args);
01021
01022 ast_verbose("%s", buf);
01023 }
01024
01025 static int maxtrunkcall = TRUNK_CALL_START;
01026 static int maxnontrunkcall = 1;
01027
01028 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);
01029 static int expire_registry(const void *data);
01030 static int iax2_answer(struct ast_channel *c);
01031 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01032 static int iax2_devicestate(void *data);
01033 static int iax2_digit_begin(struct ast_channel *c, char digit);
01034 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01035 static int iax2_do_register(struct iax2_registry *reg);
01036 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01037 static int iax2_hangup(struct ast_channel *c);
01038 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01039 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01040 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
01041 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01042 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01043 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01044 static int iax2_sendtext(struct ast_channel *c, const char *text);
01045 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01046 static int iax2_transfer(struct ast_channel *c, const char *dest);
01047 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01048 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01049 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01050 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01051 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01052 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01053 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01054 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
01055 static struct ast_frame *iax2_read(struct ast_channel *c);
01056 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01057 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01058 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
01059 static void *iax2_dup_variable_datastore(void *);
01060 static void prune_peers(void);
01061 static void prune_users(void);
01062 static void iax2_free_variable_datastore(void *);
01063
01064 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01065 static int acf_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value);
01066 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01067 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01068 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01069 static void build_rand_pad(unsigned char *buf, ssize_t len);
01070 static struct callno_entry *get_unused_callno(int trunk, int validated);
01071 static int replace_callno(const void *obj);
01072 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01073
01074 static const struct ast_channel_tech iax2_tech = {
01075 .type = "IAX2",
01076 .description = tdesc,
01077 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01078 .properties = AST_CHAN_TP_WANTSJITTER,
01079 .requester = iax2_request,
01080 .devicestate = iax2_devicestate,
01081 .send_digit_begin = iax2_digit_begin,
01082 .send_digit_end = iax2_digit_end,
01083 .send_text = iax2_sendtext,
01084 .send_image = iax2_sendimage,
01085 .send_html = iax2_sendhtml,
01086 .call = iax2_call,
01087 .hangup = iax2_hangup,
01088 .answer = iax2_answer,
01089 .read = iax2_read,
01090 .write = iax2_write,
01091 .write_video = iax2_write,
01092 .indicate = iax2_indicate,
01093 .setoption = iax2_setoption,
01094 .bridge = iax2_bridge,
01095 .transfer = iax2_transfer,
01096 .fixup = iax2_fixup,
01097 .func_channel_read = acf_channel_read,
01098 .func_channel_write = acf_channel_write,
01099 };
01100
01101 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01102 {
01103
01104
01105
01106 }
01107
01108
01109
01110 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01111 {
01112 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01113 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01114 pvt->owner ? pvt->owner->name : "",
01115 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01116 }
01117
01118
01119 static struct ast_datastore_info iax2_variable_datastore_info = {
01120 .type = "IAX2_VARIABLE",
01121 .duplicate = iax2_dup_variable_datastore,
01122 .destroy = iax2_free_variable_datastore,
01123 };
01124
01125 static void *iax2_dup_variable_datastore(void *old)
01126 {
01127 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01128 struct ast_var_t *oldvar, *newvar;
01129
01130 newlist = ast_calloc(sizeof(*newlist), 1);
01131 if (!newlist) {
01132 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01133 return NULL;
01134 }
01135
01136 AST_LIST_HEAD_INIT(newlist);
01137 AST_LIST_LOCK(oldlist);
01138 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01139 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01140 if (newvar)
01141 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01142 else
01143 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01144 }
01145 AST_LIST_UNLOCK(oldlist);
01146 return newlist;
01147 }
01148
01149 static void iax2_free_variable_datastore(void *old)
01150 {
01151 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01152 struct ast_var_t *oldvar;
01153
01154 AST_LIST_LOCK(oldlist);
01155 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01156 ast_free(oldvar);
01157 }
01158 AST_LIST_UNLOCK(oldlist);
01159 AST_LIST_HEAD_DESTROY(oldlist);
01160 ast_free(oldlist);
01161 }
01162
01163
01164
01165
01166
01167 static void insert_idle_thread(struct iax2_thread *thread)
01168 {
01169 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01170 AST_LIST_LOCK(&dynamic_list);
01171 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01172 AST_LIST_UNLOCK(&dynamic_list);
01173 } else {
01174 AST_LIST_LOCK(&idle_list);
01175 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01176 AST_LIST_UNLOCK(&idle_list);
01177 }
01178
01179 return;
01180 }
01181
01182 static struct iax2_thread *find_idle_thread(void)
01183 {
01184 struct iax2_thread *thread = NULL;
01185
01186
01187 AST_LIST_LOCK(&idle_list);
01188 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01189 AST_LIST_UNLOCK(&idle_list);
01190
01191
01192 if (thread) {
01193 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01194 return thread;
01195 }
01196
01197
01198 AST_LIST_LOCK(&dynamic_list);
01199 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01200 AST_LIST_UNLOCK(&dynamic_list);
01201
01202
01203 if (thread) {
01204 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01205 return thread;
01206 }
01207
01208
01209 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01210 return NULL;
01211
01212
01213 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01214 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01215 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01216
01217
01218 ast_mutex_init(&thread->lock);
01219 ast_cond_init(&thread->cond, NULL);
01220 ast_mutex_init(&thread->init_lock);
01221 ast_cond_init(&thread->init_cond, NULL);
01222 ast_mutex_lock(&thread->init_lock);
01223
01224
01225 if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01226 ast_cond_destroy(&thread->cond);
01227 ast_mutex_destroy(&thread->lock);
01228 ast_free(thread);
01229 return NULL;
01230 }
01231
01232
01233
01234 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01235
01236
01237 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01238
01239
01240 ast_mutex_unlock(&thread->init_lock);
01241
01242 return thread;
01243 }
01244
01245 #ifdef SCHED_MULTITHREADED
01246 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01247 {
01248 struct iax2_thread *thread = NULL;
01249 static time_t lasterror;
01250 static time_t t;
01251
01252 thread = find_idle_thread();
01253
01254 if (thread != NULL) {
01255 thread->schedfunc = func;
01256 thread->scheddata = data;
01257 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01258 #ifdef DEBUG_SCHED_MULTITHREAD
01259 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01260 #endif
01261 signal_condition(&thread->lock, &thread->cond);
01262 return 0;
01263 }
01264 time(&t);
01265 if (t != lasterror)
01266 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01267 lasterror = t;
01268
01269 return -1;
01270 }
01271 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01272 #endif
01273
01274 static int iax2_sched_replace(int id, struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01275 {
01276 AST_SCHED_REPLACE(id, con, when, callback, data);
01277 signal_condition(&sched_lock, &sched_cond);
01278
01279 return id;
01280 }
01281
01282 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01283 {
01284 int res;
01285
01286 res = ast_sched_add(con, when, callback, data);
01287 signal_condition(&sched_lock, &sched_cond);
01288
01289 return res;
01290 }
01291
01292 static int send_ping(const void *data);
01293
01294 static void __send_ping(const void *data)
01295 {
01296 int callno = (long) data;
01297
01298 ast_mutex_lock(&iaxsl[callno]);
01299
01300 if (iaxs[callno]) {
01301 if (iaxs[callno]->peercallno) {
01302 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01303 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01304 } else {
01305
01306 iaxs[callno]->pingid = -1;
01307 }
01308 } else {
01309 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01310 }
01311
01312 ast_mutex_unlock(&iaxsl[callno]);
01313 }
01314
01315 static int send_ping(const void *data)
01316 {
01317 #ifdef SCHED_MULTITHREADED
01318 if (schedule_action(__send_ping, data))
01319 #endif
01320 __send_ping(data);
01321
01322 return 0;
01323 }
01324
01325 static int get_encrypt_methods(const char *s)
01326 {
01327 int e;
01328 if (!strcasecmp(s, "aes128"))
01329 e = IAX_ENCRYPT_AES128;
01330 else if (ast_true(s))
01331 e = IAX_ENCRYPT_AES128;
01332 else
01333 e = 0;
01334 return e;
01335 }
01336
01337 static int send_lagrq(const void *data);
01338
01339 static void __send_lagrq(const void *data)
01340 {
01341 int callno = (long) data;
01342
01343 ast_mutex_lock(&iaxsl[callno]);
01344
01345 if (iaxs[callno]) {
01346 if (iaxs[callno]->peercallno) {
01347 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01348 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01349 } else {
01350
01351 iaxs[callno]->lagid = -1;
01352 }
01353 } else {
01354 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01355 }
01356
01357 ast_mutex_unlock(&iaxsl[callno]);
01358 }
01359
01360 static int send_lagrq(const void *data)
01361 {
01362 #ifdef SCHED_MULTITHREADED
01363 if (schedule_action(__send_lagrq, data))
01364 #endif
01365 __send_lagrq(data);
01366
01367 return 0;
01368 }
01369
01370 static unsigned char compress_subclass(int subclass)
01371 {
01372 int x;
01373 int power=-1;
01374
01375 if (subclass < IAX_FLAG_SC_LOG)
01376 return subclass;
01377
01378 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01379 if (subclass & (1 << x)) {
01380 if (power > -1) {
01381 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01382 return 0;
01383 } else
01384 power = x;
01385 }
01386 }
01387 return power | IAX_FLAG_SC_LOG;
01388 }
01389
01390 static int uncompress_subclass(unsigned char csub)
01391 {
01392
01393 if (csub & IAX_FLAG_SC_LOG) {
01394
01395 if (csub == 0xff)
01396 return -1;
01397 else
01398 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01399 }
01400 else
01401 return csub;
01402 }
01403
01404
01405
01406
01407 static int peer_hash_cb(const void *obj, const int flags)
01408 {
01409 const struct iax2_peer *peer = obj;
01410
01411 return ast_str_hash(peer->name);
01412 }
01413
01414
01415
01416
01417 static int peer_cmp_cb(void *obj, void *arg, int flags)
01418 {
01419 struct iax2_peer *peer = obj, *peer2 = arg;
01420
01421 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01422 }
01423
01424
01425
01426
01427 static int user_hash_cb(const void *obj, const int flags)
01428 {
01429 const struct iax2_user *user = obj;
01430
01431 return ast_str_hash(user->name);
01432 }
01433
01434
01435
01436
01437 static int user_cmp_cb(void *obj, void *arg, int flags)
01438 {
01439 struct iax2_user *user = obj, *user2 = arg;
01440
01441 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01442 }
01443
01444
01445
01446
01447
01448 static struct iax2_peer *find_peer(const char *name, int realtime)
01449 {
01450 struct iax2_peer *peer = NULL;
01451 struct iax2_peer tmp_peer = {
01452 .name = name,
01453 };
01454
01455 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01456
01457
01458 if(!peer && realtime)
01459 peer = realtime_peer(name, NULL);
01460
01461 return peer;
01462 }
01463
01464 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01465 {
01466 ao2_ref(peer, +1);
01467 return peer;
01468 }
01469
01470 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01471 {
01472 ao2_ref(peer, -1);
01473 return NULL;
01474 }
01475
01476 static struct iax2_user *find_user(const char *name)
01477 {
01478 struct iax2_user tmp_user = {
01479 .name = name,
01480 };
01481
01482 return ao2_find(users, &tmp_user, OBJ_POINTER);
01483 }
01484 static inline struct iax2_user *user_ref(struct iax2_user *user)
01485 {
01486 ao2_ref(user, +1);
01487 return user;
01488 }
01489
01490 static inline struct iax2_user *user_unref(struct iax2_user *user)
01491 {
01492 ao2_ref(user, -1);
01493 return NULL;
01494 }
01495
01496 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01497 {
01498 struct iax2_peer *peer = NULL;
01499 int res = 0;
01500 struct ao2_iterator i;
01501
01502 i = ao2_iterator_init(peers, 0);
01503 while ((peer = ao2_iterator_next(&i))) {
01504 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01505 (peer->addr.sin_port == sin.sin_port)) {
01506 ast_copy_string(host, peer->name, len);
01507 peer_unref(peer);
01508 res = 1;
01509 break;
01510 }
01511 peer_unref(peer);
01512 }
01513 ao2_iterator_destroy(&i);
01514
01515 if (!peer) {
01516 peer = realtime_peer(NULL, &sin);
01517 if (peer) {
01518 ast_copy_string(host, peer->name, len);
01519 peer_unref(peer);
01520 res = 1;
01521 }
01522 }
01523
01524 return res;
01525 }
01526
01527
01528
01529 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01530 {
01531
01532 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01533 struct iax2_user *user;
01534 struct iax2_user tmp_user = {
01535 .name = pvt->username,
01536 };
01537
01538 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01539 if (user) {
01540 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01541 user_unref(user);
01542 }
01543
01544 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01545 }
01546
01547 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]);
01548 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]);
01549 AST_SCHED_DEL(sched, pvt->autoid);
01550 AST_SCHED_DEL(sched, pvt->authid);
01551 AST_SCHED_DEL(sched, pvt->initid);
01552 AST_SCHED_DEL(sched, pvt->jbid);
01553 AST_SCHED_DEL(sched, pvt->keyrotateid);
01554 }
01555
01556 static void iax2_frame_free(struct iax_frame *fr)
01557 {
01558 AST_SCHED_DEL(sched, fr->retrans);
01559 iax_frame_free(fr);
01560 }
01561
01562 static int scheduled_destroy(const void *vid)
01563 {
01564 unsigned short callno = PTR_TO_CALLNO(vid);
01565 ast_mutex_lock(&iaxsl[callno]);
01566 if (iaxs[callno]) {
01567 if (option_debug) {
01568 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01569 }
01570 iax2_destroy(callno);
01571 }
01572 ast_mutex_unlock(&iaxsl[callno]);
01573 return 0;
01574 }
01575
01576 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01577 {
01578 ast_free(s->f.data.ptr);
01579 ast_free(s);
01580 }
01581
01582
01583
01584 static void send_signaling(struct chan_iax2_pvt *pvt)
01585 {
01586 struct signaling_queue_entry *s = NULL;
01587
01588 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01589 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01590 free_signaling_queue_entry(s);
01591 }
01592 pvt->hold_signaling = 0;
01593 }
01594
01595
01596
01597 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01598 {
01599 struct signaling_queue_entry *new;
01600
01601 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01602 return 1;
01603 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01604 return -1;
01605 }
01606
01607 memcpy(&new->f, f, sizeof(new->f));
01608
01609 if (new->f.datalen) {
01610 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01611 free_signaling_queue_entry(new);
01612 return -1;
01613 }
01614 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01615 }
01616 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01617
01618 return 0;
01619 }
01620
01621 static void pvt_destructor(void *obj)
01622 {
01623 struct chan_iax2_pvt *pvt = obj;
01624 struct iax_frame *cur = NULL;
01625 struct signaling_queue_entry *s = NULL;
01626
01627 ast_mutex_lock(&iaxsl[pvt->callno]);
01628 iax2_destroy_helper(pvt);
01629 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01630 pvt->callno_entry = NULL;
01631 ast_mutex_unlock(&iaxsl[pvt->callno]);
01632
01633
01634 ast_set_flag(pvt, IAX_ALREADYGONE);
01635
01636 AST_LIST_LOCK(&frame_queue);
01637 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01638
01639 if (cur->callno == pvt->callno) {
01640 cur->retries = -1;
01641 }
01642 }
01643 AST_LIST_UNLOCK(&frame_queue);
01644
01645 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01646 free_signaling_queue_entry(s);
01647 }
01648
01649 if (pvt->reg) {
01650 pvt->reg->callno = 0;
01651 }
01652
01653 if (!pvt->owner) {
01654 jb_frame frame;
01655 if (pvt->vars) {
01656 ast_variables_destroy(pvt->vars);
01657 pvt->vars = NULL;
01658 }
01659
01660 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01661 iax2_frame_free(frame.data);
01662 }
01663
01664 jb_destroy(pvt->jb);
01665 ast_string_field_free_memory(pvt);
01666 }
01667 }
01668
01669 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01670 {
01671 struct chan_iax2_pvt *tmp;
01672 jb_conf jbconf;
01673
01674 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01675 return NULL;
01676 }
01677
01678 if (ast_string_field_init(tmp, 32)) {
01679 ao2_ref(tmp, -1);
01680 tmp = NULL;
01681 return NULL;
01682 }
01683
01684 tmp->prefs = prefs;
01685 tmp->pingid = -1;
01686 tmp->lagid = -1;
01687 tmp->autoid = -1;
01688 tmp->authid = -1;
01689 tmp->initid = -1;
01690 tmp->keyrotateid = -1;
01691
01692 ast_string_field_set(tmp,exten, "s");
01693 ast_string_field_set(tmp,host, host);
01694
01695 tmp->jb = jb_new();
01696 tmp->jbid = -1;
01697 jbconf.max_jitterbuf = maxjitterbuffer;
01698 jbconf.resync_threshold = resyncthreshold;
01699 jbconf.max_contig_interp = maxjitterinterps;
01700 jbconf.target_extra = jittertargetextra;
01701 jb_setconf(tmp->jb,&jbconf);
01702
01703 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01704
01705 tmp->hold_signaling = 1;
01706 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01707
01708 return tmp;
01709 }
01710
01711 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01712 {
01713 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01714 if (new) {
01715 size_t afdatalen = new->afdatalen;
01716 memcpy(new, fr, sizeof(*new));
01717 iax_frame_wrap(new, &fr->af);
01718 new->afdatalen = afdatalen;
01719 new->data = NULL;
01720 new->datalen = 0;
01721 new->direction = DIRECTION_INGRESS;
01722 new->retrans = -1;
01723 }
01724 return new;
01725 }
01726
01727
01728 enum {
01729
01730 NEW_PREVENT = 0,
01731
01732 NEW_ALLOW = 1,
01733
01734 NEW_FORCE = 2,
01735
01736
01737 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01738 };
01739
01740 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01741 {
01742 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01743 (cur->addr.sin_port == sin->sin_port)) {
01744
01745 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01746 (check_dcallno ? dcallno == cur->callno : 1) ) {
01747
01748 return 1;
01749 }
01750 }
01751 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01752 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01753
01754 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01755 return 1;
01756 }
01757 return 0;
01758 }
01759
01760 static void update_max_trunk(void)
01761 {
01762 int max = TRUNK_CALL_START;
01763 int x;
01764
01765
01766 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01767 if (iaxs[x]) {
01768 max = x + 1;
01769 }
01770 }
01771
01772 maxtrunkcall = max;
01773 if (iaxdebug)
01774 ast_debug(1, "New max trunk callno is %d\n", max);
01775 }
01776
01777 static void update_max_nontrunk(void)
01778 {
01779 int max = 1;
01780 int x;
01781
01782 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01783 if (iaxs[x])
01784 max = x + 1;
01785 }
01786 maxnontrunkcall = max;
01787 if (iaxdebug)
01788 ast_debug(1, "New max nontrunk callno is %d\n", max);
01789 }
01790
01791 static int make_trunk(unsigned short callno, int locked)
01792 {
01793 int x;
01794 int res= 0;
01795 struct callno_entry *callno_entry;
01796 if (iaxs[callno]->oseqno) {
01797 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01798 return -1;
01799 }
01800 if (callno & TRUNK_CALL_START) {
01801 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01802 return -1;
01803 }
01804
01805 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
01806 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01807 return -1;
01808 }
01809
01810 x = callno_entry->callno;
01811 ast_mutex_lock(&iaxsl[x]);
01812
01813
01814
01815
01816
01817 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01818 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01819 iaxs[x] = iaxs[callno];
01820 iaxs[x]->callno = x;
01821
01822
01823
01824 if (iaxs[x]->callno_entry) {
01825 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
01826 }
01827 iaxs[x]->callno_entry = callno_entry;
01828
01829 iaxs[callno] = NULL;
01830
01831 iaxs[x]->pingid = iax2_sched_add(sched,
01832 ping_time * 1000, send_ping, (void *)(long)x);
01833 iaxs[x]->lagid = iax2_sched_add(sched,
01834 lagrq_time * 1000, send_lagrq, (void *)(long)x);
01835
01836 if (locked)
01837 ast_mutex_unlock(&iaxsl[callno]);
01838 res = x;
01839 if (!locked)
01840 ast_mutex_unlock(&iaxsl[x]);
01841
01842 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01843
01844 update_max_trunk();
01845 update_max_nontrunk();
01846 return res;
01847 }
01848
01849 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01850 {
01851 if (!pvt->transfercallno) {
01852 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01853 return;
01854 }
01855
01856 ao2_link(iax_transfercallno_pvts, pvt);
01857 }
01858
01859 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01860 {
01861 if (!pvt->transfercallno) {
01862 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01863 return;
01864 }
01865
01866 ao2_unlink(iax_transfercallno_pvts, pvt);
01867 }
01868 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01869 {
01870 if (!pvt->peercallno) {
01871 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01872 return;
01873 }
01874
01875 ao2_link(iax_peercallno_pvts, pvt);
01876 }
01877
01878 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01879 {
01880 if (!pvt->peercallno) {
01881 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01882 return;
01883 }
01884
01885 ao2_unlink(iax_peercallno_pvts, pvt);
01886 }
01887
01888 static int addr_range_delme_cb(void *obj, void *arg, int flags)
01889 {
01890 struct addr_range *lim = obj;
01891 lim->delme = 1;
01892 return 0;
01893 }
01894
01895 static int addr_range_hash_cb(const void *obj, const int flags)
01896 {
01897 const struct addr_range *lim = obj;
01898 return abs((int) lim->ha.netaddr.s_addr);
01899 }
01900
01901 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
01902 {
01903 struct addr_range *lim1 = obj, *lim2 = arg;
01904 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
01905 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
01906 CMP_MATCH | CMP_STOP : 0;
01907 }
01908
01909 static int peercnt_hash_cb(const void *obj, const int flags)
01910 {
01911 const struct peercnt *peercnt = obj;
01912 return abs((int) peercnt->addr);
01913 }
01914
01915 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
01916 {
01917 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
01918 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
01919 }
01920
01921 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
01922 {
01923 struct addr_range *addr_range = obj;
01924 struct sockaddr_in *sin = arg;
01925
01926 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
01927 return CMP_MATCH | CMP_STOP;
01928 }
01929 return 0;
01930 }
01931
01932
01933
01934
01935
01936
01937 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
01938 {
01939 struct addr_range *addr_range;
01940 struct iax2_peer *peer = NULL;
01941 struct iax2_user *user = NULL;
01942
01943 const char *find = S_OR(name, "guest");
01944 int res = 1;
01945 int optional = 0;
01946 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
01947
01948
01949
01950
01951
01952
01953
01954 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
01955 ao2_ref(addr_range, -1);
01956 optional = 1;
01957 }
01958
01959
01960 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
01961 calltoken_required = user->calltoken_required;
01962 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
01963 calltoken_required = user->calltoken_required;
01964 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
01965 calltoken_required = peer->calltoken_required;
01966 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
01967 calltoken_required = peer->calltoken_required;
01968 }
01969
01970 if (peer) {
01971 peer_unref(peer);
01972 }
01973 if (user) {
01974 user_unref(user);
01975 }
01976
01977 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);
01978 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
01979 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
01980 res = 0;
01981 }
01982
01983 return res;
01984 }
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996 static void set_peercnt_limit(struct peercnt *peercnt)
01997 {
01998 uint16_t limit = global_maxcallno;
01999 struct addr_range *addr_range;
02000 struct sockaddr_in sin = {
02001 .sin_addr.s_addr = peercnt->addr,
02002 };
02003
02004
02005 if (peercnt->reg && peercnt->limit) {
02006 return;
02007 }
02008
02009 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02010 limit = addr_range->limit;
02011 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02012 ao2_ref(addr_range, -1);
02013 }
02014
02015 peercnt->limit = limit;
02016 }
02017
02018
02019
02020
02021
02022 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02023 {
02024 struct peercnt *peercnt = obj;
02025
02026 set_peercnt_limit(peercnt);
02027 ast_debug(1, "Reset limits for peercnts table\n");
02028
02029 return 0;
02030 }
02031
02032
02033
02034
02035
02036 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02037 {
02038 struct addr_range *addr_range = obj;
02039
02040 return addr_range->delme ? CMP_MATCH : 0;
02041 }
02042
02043
02044
02045
02046
02047 static void peercnt_modify(unsigned char reg, uint16_t limit, struct sockaddr_in *sin)
02048 {
02049
02050 struct peercnt *peercnt;
02051 struct peercnt tmp = {
02052 .addr = sin->sin_addr.s_addr,
02053 };
02054
02055 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02056 peercnt->reg = reg;
02057 if (limit) {
02058 peercnt->limit = limit;
02059 } else {
02060 set_peercnt_limit(peercnt);
02061 }
02062 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg);
02063 ao2_ref(peercnt, -1);
02064 }
02065 }
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075 static int peercnt_add(struct sockaddr_in *sin)
02076 {
02077 struct peercnt *peercnt;
02078 unsigned long addr = sin->sin_addr.s_addr;
02079 int res = 0;
02080 struct peercnt tmp = {
02081 .addr = addr,
02082 };
02083
02084
02085
02086
02087
02088
02089
02090 ao2_lock(peercnts);
02091 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02092 ao2_lock(peercnt);
02093 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02094 ao2_lock(peercnt);
02095
02096 peercnt->addr = addr;
02097 set_peercnt_limit(peercnt);
02098
02099
02100 ao2_link(peercnts, peercnt);
02101 } else {
02102 ao2_unlock(peercnts);
02103 return -1;
02104 }
02105
02106
02107 if (peercnt->limit > peercnt->cur) {
02108 peercnt->cur++;
02109 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02110 } else {
02111 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02112 res = -1;
02113 }
02114
02115
02116 ao2_unlock(peercnt);
02117 ao2_unlock(peercnts);
02118 ao2_ref(peercnt, -1);
02119
02120 return res;
02121 }
02122
02123
02124
02125
02126
02127 static void peercnt_remove(struct peercnt *peercnt)
02128 {
02129 struct sockaddr_in sin = {
02130 .sin_addr.s_addr = peercnt->addr,
02131 };
02132
02133 if (peercnt) {
02134
02135
02136
02137 ao2_lock(peercnts);
02138 peercnt->cur--;
02139 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02140
02141 if (peercnt->cur == 0) {
02142 ao2_unlink(peercnts, peercnt);
02143 }
02144 ao2_unlock(peercnts);
02145 }
02146 }
02147
02148
02149
02150
02151
02152 static int peercnt_remove_cb(const void *obj)
02153 {
02154 struct peercnt *peercnt = (struct peercnt *) obj;
02155
02156 peercnt_remove(peercnt);
02157 ao2_ref(peercnt, -1);
02158
02159 return 0;
02160 }
02161
02162
02163
02164
02165
02166 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02167 {
02168 struct peercnt *peercnt;
02169 struct peercnt tmp = {
02170 .addr = sin->sin_addr.s_addr,
02171 };
02172
02173 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02174 peercnt_remove(peercnt);
02175 ao2_ref(peercnt, -1);
02176 }
02177 return 0;
02178 }
02179
02180
02181
02182
02183
02184 static void build_callno_limits(struct ast_variable *v)
02185 {
02186 struct addr_range *addr_range = NULL;
02187 struct addr_range tmp;
02188 struct ast_ha *ha;
02189 int limit;
02190 int error;
02191 int found;
02192
02193 for (; v; v = v->next) {
02194 limit = -1;
02195 error = 0;
02196 found = 0;
02197 ha = ast_append_ha("permit", v->name, NULL, &error);
02198
02199
02200 if (error) {
02201 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02202 continue;
02203 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02204 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02205 ast_free_ha(ha);
02206 continue;
02207 }
02208
02209 ast_copy_ha(ha, &tmp.ha);
02210
02211 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02212 ao2_lock(addr_range);
02213 found = 1;
02214 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02215 ast_free_ha(ha);
02216 return;
02217 }
02218
02219
02220 ast_copy_ha(ha, &addr_range->ha);
02221 ast_free_ha(ha);
02222 addr_range->limit = limit;
02223 addr_range->delme = 0;
02224
02225
02226 if (found) {
02227 ao2_unlock(addr_range);
02228 } else {
02229 ao2_link(callno_limits, addr_range);
02230 }
02231 ao2_ref(addr_range, -1);
02232 }
02233 }
02234
02235
02236
02237
02238
02239 static int add_calltoken_ignore(const char *addr)
02240 {
02241 struct addr_range tmp;
02242 struct addr_range *addr_range = NULL;
02243 struct ast_ha *ha = NULL;
02244 int error = 0;
02245
02246 if (ast_strlen_zero(addr)) {
02247 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02248 return -1;
02249 }
02250
02251 ha = ast_append_ha("permit", addr, NULL, &error);
02252
02253
02254 if (error) {
02255 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02256 return -1;
02257 }
02258
02259 ast_copy_ha(ha, &tmp.ha);
02260
02261 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02262 ao2_lock(addr_range);
02263 addr_range->delme = 0;
02264 ao2_unlock(addr_range);
02265 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02266
02267 ast_copy_ha(ha, &addr_range->ha);
02268 ao2_link(calltoken_ignores, addr_range);
02269 } else {
02270 ast_free_ha(ha);
02271 return -1;
02272 }
02273
02274 ast_free_ha(ha);
02275 ao2_ref(addr_range, -1);
02276
02277 return 0;
02278 }
02279
02280 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02281 {
02282 struct ao2_iterator i;
02283 struct peercnt *peercnt;
02284 struct sockaddr_in sin;
02285 int found = 0;
02286
02287 switch (cmd) {
02288 case CLI_INIT:
02289 e->command = "iax2 show callnumber usage";
02290 e->usage =
02291 "Usage: iax2 show callnumber usage <ip address (optional)>\n"
02292 " Shows current ip addresses which are consuming iax2 call numbers\n";
02293 return NULL;
02294 case CLI_GENERATE:
02295 return NULL;
02296 case CLI_HANDLER:
02297 if (a->argc < 4 || a->argc > 5)
02298 return CLI_SHOWUSAGE;
02299
02300 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02301 i = ao2_iterator_init(peercnts, 0);
02302 while ((peercnt = ao2_iterator_next(&i))) {
02303 sin.sin_addr.s_addr = peercnt->addr;
02304 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02305 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02306 found = 1;
02307 break;
02308 } else {
02309 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02310 }
02311 ao2_ref(peercnt, -1);
02312 }
02313 ao2_iterator_destroy(&i);
02314
02315 if (a->argc == 4) {
02316 ast_cli(a->fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
02317 } else if (a->argc == 5 && !found) {
02318 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02319 }
02320
02321 return CLI_SUCCESS;
02322 default:
02323 return NULL;
02324 }
02325 }
02326
02327 static struct callno_entry *get_unused_callno(int trunk, int validated)
02328 {
02329 struct callno_entry *callno_entry = NULL;
02330 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02331 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02332
02333 return NULL;
02334 }
02335
02336
02337
02338 ao2_lock(callno_pool);
02339
02340
02341
02342
02343 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02344 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02345 ao2_unlock(callno_pool);
02346 return NULL;
02347 }
02348
02349
02350
02351 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02352
02353 if (callno_entry) {
02354 callno_entry->validated = validated;
02355 if (!validated) {
02356 total_nonval_callno_used++;
02357 }
02358 }
02359
02360 ao2_unlock(callno_pool);
02361 return callno_entry;
02362 }
02363
02364 static int replace_callno(const void *obj)
02365 {
02366 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02367
02368
02369
02370 ao2_lock(callno_pool);
02371
02372 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02373 total_nonval_callno_used--;
02374 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02375 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02376 }
02377
02378 if (callno_entry->callno < TRUNK_CALL_START) {
02379 ao2_link(callno_pool, callno_entry);
02380 } else {
02381 ao2_link(callno_pool_trunk, callno_entry);
02382 }
02383 ao2_ref(callno_entry, -1);
02384
02385 ao2_unlock(callno_pool);
02386 return 0;
02387 }
02388
02389 static int callno_hash(const void *obj, const int flags)
02390 {
02391 return abs(ast_random());
02392 }
02393
02394 static int create_callno_pools(void)
02395 {
02396 uint16_t i;
02397
02398 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02399 return -1;
02400 }
02401
02402 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02403 return -1;
02404 }
02405
02406
02407 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02408 struct callno_entry *callno_entry;
02409
02410 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02411 return -1;
02412 }
02413
02414 callno_entry->callno = i;
02415
02416 if (i < TRUNK_CALL_START) {
02417 ao2_link(callno_pool, callno_entry);
02418 } else {
02419 ao2_link(callno_pool_trunk, callno_entry);
02420 }
02421
02422 ao2_ref(callno_entry, -1);
02423 }
02424
02425 return 0;
02426 }
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02437 {
02438 int i;
02439 struct peercnt *peercnt;
02440 struct peercnt tmp = {
02441 .addr = sin->sin_addr.s_addr,
02442 };
02443
02444 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02445
02446 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02447 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02448 if (i == -1) {
02449 ao2_ref(peercnt, -1);
02450 }
02451 }
02452
02453 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02454 }
02455
02456
02457
02458
02459
02460
02461
02462
02463 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02464 {
02465 if (frametype != AST_FRAME_IAX) {
02466 return 0;
02467 }
02468 switch (subclass) {
02469 case IAX_COMMAND_NEW:
02470 case IAX_COMMAND_REGREQ:
02471 case IAX_COMMAND_FWDOWNL:
02472 case IAX_COMMAND_REGREL:
02473 return 1;
02474 case IAX_COMMAND_POKE:
02475 if (!inbound) {
02476 return 1;
02477 }
02478 break;
02479 }
02480 return 0;
02481 }
02482
02483
02484
02485
02486 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02487 {
02488 int res = 0;
02489 int x;
02490
02491
02492 int validated = (new > NEW_ALLOW) ? 1 : 0;
02493 char host[80];
02494
02495 if (new <= NEW_ALLOW) {
02496 if (callno) {
02497 struct chan_iax2_pvt *pvt;
02498 struct chan_iax2_pvt tmp_pvt = {
02499 .callno = dcallno,
02500 .peercallno = callno,
02501 .transfercallno = callno,
02502
02503 .frames_received = check_dcallno,
02504 };
02505
02506 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02507
02508 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02509 if (return_locked) {
02510 ast_mutex_lock(&iaxsl[pvt->callno]);
02511 }
02512 res = pvt->callno;
02513 ao2_ref(pvt, -1);
02514 pvt = NULL;
02515 return res;
02516 }
02517
02518 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02519 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02520 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02521 if (return_locked) {
02522 ast_mutex_lock(&iaxsl[pvt->callno]);
02523 }
02524 res = pvt->callno;
02525 ao2_ref(pvt, -1);
02526 pvt = NULL;
02527 return res;
02528 }
02529 }
02530
02531
02532 if (dcallno) {
02533 ast_mutex_lock(&iaxsl[dcallno]);
02534 }
02535 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02536 iaxs[dcallno]->peercallno = callno;
02537 res = dcallno;
02538 store_by_peercallno(iaxs[dcallno]);
02539 if (!res || !return_locked) {
02540 ast_mutex_unlock(&iaxsl[dcallno]);
02541 }
02542 return res;
02543 }
02544 if (dcallno) {
02545 ast_mutex_unlock(&iaxsl[dcallno]);
02546 }
02547 #ifdef IAX_OLD_FIND
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559 for (x = 1; !res && x < maxnontrunkcall; x++) {
02560 ast_mutex_lock(&iaxsl[x]);
02561 if (iaxs[x]) {
02562
02563 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02564 res = x;
02565 }
02566 }
02567 if (!res || !return_locked)
02568 ast_mutex_unlock(&iaxsl[x]);
02569 }
02570 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02571 ast_mutex_lock(&iaxsl[x]);
02572 if (iaxs[x]) {
02573
02574 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02575 res = x;
02576 }
02577 }
02578 if (!res || !return_locked)
02579 ast_mutex_unlock(&iaxsl[x]);
02580 }
02581 #endif
02582 }
02583 if (!res && (new >= NEW_ALLOW)) {
02584 struct callno_entry *callno_entry;
02585
02586
02587
02588
02589
02590
02591 if (!iax2_getpeername(*sin, host, sizeof(host)))
02592 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02593
02594 if (peercnt_add(sin)) {
02595
02596
02597 return 0;
02598 }
02599
02600 if (!(callno_entry = get_unused_callno(0, validated))) {
02601
02602
02603 peercnt_remove_by_addr(sin);
02604 ast_log(LOG_WARNING, "No more space\n");
02605 return 0;
02606 }
02607 x = callno_entry->callno;
02608 ast_mutex_lock(&iaxsl[x]);
02609
02610 iaxs[x] = new_iax(sin, host);
02611 update_max_nontrunk();
02612 if (iaxs[x]) {
02613 if (iaxdebug)
02614 ast_debug(1, "Creating new call structure %d\n", x);
02615 iaxs[x]->callno_entry = callno_entry;
02616 iaxs[x]->sockfd = sockfd;
02617 iaxs[x]->addr.sin_port = sin->sin_port;
02618 iaxs[x]->addr.sin_family = sin->sin_family;
02619 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02620 iaxs[x]->peercallno = callno;
02621 iaxs[x]->callno = x;
02622 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02623 iaxs[x]->expiry = min_reg_expire;
02624 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02625 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02626 iaxs[x]->amaflags = amaflags;
02627 ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02628
02629 ast_string_field_set(iaxs[x], accountcode, accountcode);
02630 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02631 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02632 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02633
02634 if (iaxs[x]->peercallno) {
02635 store_by_peercallno(iaxs[x]);
02636 }
02637 } else {
02638 ast_log(LOG_WARNING, "Out of resources\n");
02639 ast_mutex_unlock(&iaxsl[x]);
02640 replace_callno(callno_entry);
02641 return 0;
02642 }
02643 if (!return_locked)
02644 ast_mutex_unlock(&iaxsl[x]);
02645 res = x;
02646 }
02647 return res;
02648 }
02649
02650 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02651
02652 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02653 }
02654
02655 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02656
02657 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02658 }
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670 static int iax2_queue_frame(int callno, struct ast_frame *f)
02671 {
02672 for (;;) {
02673 if (iaxs[callno] && iaxs[callno]->owner) {
02674 if (ast_channel_trylock(iaxs[callno]->owner)) {
02675
02676 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02677 } else {
02678 ast_queue_frame(iaxs[callno]->owner, f);
02679 ast_channel_unlock(iaxs[callno]->owner);
02680 break;
02681 }
02682 } else
02683 break;
02684 }
02685 return 0;
02686 }
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701 static int iax2_queue_hangup(int callno)
02702 {
02703 for (;;) {
02704 if (iaxs[callno] && iaxs[callno]->owner) {
02705 if (ast_channel_trylock(iaxs[callno]->owner)) {
02706
02707 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02708 } else {
02709 ast_queue_hangup(iaxs[callno]->owner);
02710 ast_channel_unlock(iaxs[callno]->owner);
02711 break;
02712 }
02713 } else
02714 break;
02715 }
02716 return 0;
02717 }
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732 static int iax2_queue_control_data(int callno,
02733 enum ast_control_frame_type control, const void *data, size_t datalen)
02734 {
02735 for (;;) {
02736 if (iaxs[callno] && iaxs[callno]->owner) {
02737 if (ast_channel_trylock(iaxs[callno]->owner)) {
02738
02739 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02740 } else {
02741 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02742 ast_channel_unlock(iaxs[callno]->owner);
02743 break;
02744 }
02745 } else
02746 break;
02747 }
02748 return 0;
02749 }
02750 static void destroy_firmware(struct iax_firmware *cur)
02751 {
02752
02753 if (cur->fwh) {
02754 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02755 }
02756 close(cur->fd);
02757 ast_free(cur);
02758 }
02759
02760 static int try_firmware(char *s)
02761 {
02762 struct stat stbuf;
02763 struct iax_firmware *cur = NULL;
02764 int ifd, fd, res, len, chunk;
02765 struct ast_iax2_firmware_header *fwh, fwh2;
02766 struct MD5Context md5;
02767 unsigned char sum[16], buf[1024];
02768 char *s2, *last;
02769
02770 if (!(s2 = alloca(strlen(s) + 100))) {
02771 ast_log(LOG_WARNING, "Alloca failed!\n");
02772 return -1;
02773 }
02774
02775 last = strrchr(s, '/');
02776 if (last)
02777 last++;
02778 else
02779 last = s;
02780
02781 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02782
02783 if ((res = stat(s, &stbuf) < 0)) {
02784 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02785 return -1;
02786 }
02787
02788
02789 if (S_ISDIR(stbuf.st_mode))
02790 return -1;
02791 ifd = open(s, O_RDONLY);
02792 if (ifd < 0) {
02793 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02794 return -1;
02795 }
02796 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02797 if (fd < 0) {
02798 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02799 close(ifd);
02800 return -1;
02801 }
02802
02803 unlink(s2);
02804
02805
02806 len = stbuf.st_size;
02807 while(len) {
02808 chunk = len;
02809 if (chunk > sizeof(buf))
02810 chunk = sizeof(buf);
02811 res = read(ifd, buf, chunk);
02812 if (res != chunk) {
02813 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02814 close(ifd);
02815 close(fd);
02816 return -1;
02817 }
02818 res = write(fd, buf, chunk);
02819 if (res != chunk) {
02820 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02821 close(ifd);
02822 close(fd);
02823 return -1;
02824 }
02825 len -= chunk;
02826 }
02827 close(ifd);
02828
02829 lseek(fd, 0, SEEK_SET);
02830 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02831 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02832 close(fd);
02833 return -1;
02834 }
02835 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02836 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02837 close(fd);
02838 return -1;
02839 }
02840 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02841 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02842 close(fd);
02843 return -1;
02844 }
02845 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02846 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02847 close(fd);
02848 return -1;
02849 }
02850 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
02851 if (fwh == MAP_FAILED) {
02852 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02853 close(fd);
02854 return -1;
02855 }
02856 MD5Init(&md5);
02857 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02858 MD5Final(sum, &md5);
02859 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02860 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02861 munmap((void*)fwh, stbuf.st_size);
02862 close(fd);
02863 return -1;
02864 }
02865
02866 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02867 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02868
02869 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02870
02871 break;
02872
02873
02874 munmap((void*)fwh, stbuf.st_size);
02875 close(fd);
02876 return 0;
02877 }
02878 }
02879
02880 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02881 cur->fd = -1;
02882 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02883 }
02884
02885 if (cur) {
02886 if (cur->fwh)
02887 munmap((void*)cur->fwh, cur->mmaplen);
02888 if (cur->fd > -1)
02889 close(cur->fd);
02890 cur->fwh = fwh;
02891 cur->fd = fd;
02892 cur->mmaplen = stbuf.st_size;
02893 cur->dead = 0;
02894 }
02895
02896 return 0;
02897 }
02898
02899 static int iax_check_version(char *dev)
02900 {
02901 int res = 0;
02902 struct iax_firmware *cur = NULL;
02903
02904 if (ast_strlen_zero(dev))
02905 return 0;
02906
02907 AST_LIST_LOCK(&firmwares);
02908 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02909 if (!strcmp(dev, (char *)cur->fwh->devname)) {
02910 res = ntohs(cur->fwh->version);
02911 break;
02912 }
02913 }
02914 AST_LIST_UNLOCK(&firmwares);
02915
02916 return res;
02917 }
02918
02919 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
02920 {
02921 int res = -1;
02922 unsigned int bs = desc & 0xff;
02923 unsigned int start = (desc >> 8) & 0xffffff;
02924 unsigned int bytes;
02925 struct iax_firmware *cur;
02926
02927 if (ast_strlen_zero((char *)dev) || !bs)
02928 return -1;
02929
02930 start *= bs;
02931
02932 AST_LIST_LOCK(&firmwares);
02933 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02934 if (strcmp((char *)dev, (char *)cur->fwh->devname))
02935 continue;
02936 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02937 if (start < ntohl(cur->fwh->datalen)) {
02938 bytes = ntohl(cur->fwh->datalen) - start;
02939 if (bytes > bs)
02940 bytes = bs;
02941 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02942 } else {
02943 bytes = 0;
02944 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02945 }
02946 if (bytes == bs)
02947 res = 0;
02948 else
02949 res = 1;
02950 break;
02951 }
02952 AST_LIST_UNLOCK(&firmwares);
02953
02954 return res;
02955 }
02956
02957
02958 static void reload_firmware(int unload)
02959 {
02960 struct iax_firmware *cur = NULL;
02961 DIR *fwd;
02962 struct dirent *de;
02963 char dir[256], fn[256];
02964
02965 AST_LIST_LOCK(&firmwares);
02966
02967
02968 AST_LIST_TRAVERSE(&firmwares, cur, list)
02969 cur->dead = 1;
02970
02971
02972 if (!unload) {
02973 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
02974 fwd = opendir(dir);
02975 if (fwd) {
02976 while((de = readdir(fwd))) {
02977 if (de->d_name[0] != '.') {
02978 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02979 if (!try_firmware(fn)) {
02980 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
02981 }
02982 }
02983 }
02984 closedir(fwd);
02985 } else
02986 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02987 }
02988
02989
02990 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
02991 if (!cur->dead)
02992 continue;
02993 AST_LIST_REMOVE_CURRENT(list);
02994 destroy_firmware(cur);
02995 }
02996 AST_LIST_TRAVERSE_SAFE_END;
02997
02998 AST_LIST_UNLOCK(&firmwares);
02999 }
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009 static int __do_deliver(void *data)
03010 {
03011
03012
03013 struct iax_frame *fr = data;
03014 fr->retrans = -1;
03015 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03016 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
03017 iax2_queue_frame(fr->callno, &fr->af);
03018
03019 iax2_frame_free(fr);
03020
03021 return 0;
03022 }
03023
03024 static int handle_error(void)
03025 {
03026
03027
03028
03029 #if 0
03030 struct sockaddr_in *sin;
03031 int res;
03032 struct msghdr m;
03033 struct sock_extended_err e;
03034 m.msg_name = NULL;
03035 m.msg_namelen = 0;
03036 m.msg_iov = NULL;
03037 m.msg_control = &e;
03038 m.msg_controllen = sizeof(e);
03039 m.msg_flags = 0;
03040 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03041 if (res < 0)
03042 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03043 else {
03044 if (m.msg_controllen) {
03045 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03046 if (sin)
03047 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03048 else
03049 ast_log(LOG_WARNING, "No address detected??\n");
03050 } else {
03051 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03052 }
03053 }
03054 #endif
03055 return 0;
03056 }
03057
03058 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03059 {
03060 int res;
03061 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03062 sizeof(*sin));
03063 if (res < 0) {
03064 ast_debug(1, "Received error: %s\n", strerror(errno));
03065 handle_error();
03066 } else
03067 res = 0;
03068 return res;
03069 }
03070
03071 static int send_packet(struct iax_frame *f)
03072 {
03073 int res;
03074 int callno = f->callno;
03075
03076
03077 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03078 return -1;
03079
03080
03081 if (iaxdebug)
03082 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));
03083
03084 if (f->transfer) {
03085 if (iaxdebug)
03086 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03087 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03088 } else {
03089 if (iaxdebug)
03090 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03091 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03092 }
03093 if (res < 0) {
03094 if (iaxdebug)
03095 ast_debug(1, "Received error: %s\n", strerror(errno));
03096 handle_error();
03097 } else
03098 res = 0;
03099
03100 return res;
03101 }
03102
03103
03104
03105
03106
03107 static int iax2_predestroy(int callno)
03108 {
03109 struct ast_channel *c = NULL;
03110 struct chan_iax2_pvt *pvt = iaxs[callno];
03111
03112 if (!pvt)
03113 return -1;
03114
03115 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
03116 iax2_destroy_helper(pvt);
03117 ast_set_flag(pvt, IAX_ALREADYGONE);
03118 }
03119
03120 if ((c = pvt->owner)) {
03121 c->tech_pvt = NULL;
03122 iax2_queue_hangup(callno);
03123 pvt->owner = NULL;
03124 ast_module_unref(ast_module_info->self);
03125 }
03126
03127 return 0;
03128 }
03129
03130 static void iax2_destroy(int callno)
03131 {
03132 struct chan_iax2_pvt *pvt = NULL;
03133 struct ast_channel *owner = NULL;
03134
03135 retry:
03136 if ((pvt = iaxs[callno])) {
03137 iax2_destroy_helper(pvt);
03138 }
03139
03140 owner = pvt ? pvt->owner : NULL;
03141
03142 if (owner) {
03143 if (ast_channel_trylock(owner)) {
03144 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03145 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03146 goto retry;
03147 }
03148 }
03149
03150 if (!owner) {
03151 iaxs[callno] = NULL;
03152 }
03153
03154 if (pvt) {
03155 if (!owner) {
03156 pvt->owner = NULL;
03157 } else {
03158
03159
03160
03161 ast_queue_hangup(owner);
03162 }
03163
03164 if (pvt->peercallno) {
03165 remove_by_peercallno(pvt);
03166 }
03167
03168 if (pvt->transfercallno) {
03169 remove_by_transfercallno(pvt);
03170 }
03171
03172 if (!owner) {
03173 ao2_ref(pvt, -1);
03174 pvt = NULL;
03175 }
03176 }
03177
03178 if (owner) {
03179 ast_channel_unlock(owner);
03180 }
03181
03182 if (callno & 0x4000) {
03183 update_max_trunk();
03184 }
03185 }
03186
03187 static int update_packet(struct iax_frame *f)
03188 {
03189
03190 struct ast_iax2_full_hdr *fh = f->data;
03191 struct ast_frame af;
03192
03193
03194 if (f->encmethods) {
03195 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03196 }
03197
03198 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03199
03200 f->iseqno = iaxs[f->callno]->iseqno;
03201 fh->iseqno = f->iseqno;
03202
03203
03204 if (f->encmethods) {
03205
03206
03207 build_rand_pad(f->semirand, sizeof(f->semirand));
03208 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03209 }
03210 return 0;
03211 }
03212
03213 static int attempt_transmit(const void *data);
03214 static void __attempt_transmit(const void *data)
03215 {
03216
03217
03218 struct iax_frame *f = (struct iax_frame *)data;
03219 int freeme = 0;
03220 int callno = f->callno;
03221
03222 if (callno)
03223 ast_mutex_lock(&iaxsl[callno]);
03224 if (callno && iaxs[callno]) {
03225 if ((f->retries < 0) ||
03226 (f->retries >= max_retries) ) {
03227
03228 if (f->retries >= max_retries) {
03229 if (f->transfer) {
03230
03231 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03232 } else if (f->final) {
03233 if (f->final)
03234 iax2_destroy(callno);
03235 } else {
03236 if (iaxs[callno]->owner)
03237 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);
03238 iaxs[callno]->error = ETIMEDOUT;
03239 if (iaxs[callno]->owner) {
03240 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03241
03242 iax2_queue_frame(callno, &fr);
03243
03244 if (iaxs[callno] && iaxs[callno]->owner)
03245 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03246 } else {
03247 if (iaxs[callno]->reg) {
03248 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03249 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03250 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03251 }
03252 iax2_destroy(callno);
03253 }
03254 }
03255
03256 }
03257 freeme = 1;
03258 } else {
03259
03260 update_packet(f);
03261
03262 send_packet(f);
03263 f->retries++;
03264
03265 f->retrytime *= 10;
03266 if (f->retrytime > MAX_RETRY_TIME)
03267 f->retrytime = MAX_RETRY_TIME;
03268
03269 if (f->transfer && (f->retrytime > 1000))
03270 f->retrytime = 1000;
03271 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03272 }
03273 } else {
03274
03275 f->retries = -1;
03276 freeme = 1;
03277 }
03278 if (callno)
03279 ast_mutex_unlock(&iaxsl[callno]);
03280
03281 if (freeme) {
03282
03283 AST_LIST_LOCK(&frame_queue);
03284 AST_LIST_REMOVE(&frame_queue, f, list);
03285 AST_LIST_UNLOCK(&frame_queue);
03286 f->retrans = -1;
03287
03288 iax2_frame_free(f);
03289 }
03290 }
03291
03292 static int attempt_transmit(const void *data)
03293 {
03294 #ifdef SCHED_MULTITHREADED
03295 if (schedule_action(__attempt_transmit, data))
03296 #endif
03297 __attempt_transmit(data);
03298 return 0;
03299 }
03300
03301 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03302 {
03303 struct iax2_peer *peer = NULL;
03304 struct iax2_user *user = NULL;
03305
03306 switch (cmd) {
03307 case CLI_INIT:
03308 e->command = "iax2 prune realtime";
03309 e->usage =
03310 "Usage: iax2 prune realtime [<peername>|all]\n"
03311 " Prunes object(s) from the cache\n";
03312 return NULL;
03313 case CLI_GENERATE:
03314 if (a->pos == 3)
03315 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
03316 return NULL;
03317 }
03318 if (a->argc != 4)
03319 return CLI_SHOWUSAGE;
03320 if (!strcmp(a->argv[3], "all")) {
03321 prune_users();
03322 prune_peers();
03323 ast_cli(a->fd, "Cache flushed successfully.\n");
03324 return CLI_SUCCESS;
03325 }
03326 peer = find_peer(a->argv[3], 0);
03327 user = find_user(a->argv[3]);
03328 if (peer || user) {
03329 if (peer) {
03330 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
03331 ast_set_flag(peer, IAX_RTAUTOCLEAR);
03332 expire_registry(peer_ref(peer));
03333 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03334 } else {
03335 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03336 }
03337 peer_unref(peer);
03338 }
03339 if (user) {
03340 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
03341 ast_set_flag(user, IAX_RTAUTOCLEAR);
03342 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03343 } else {
03344 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03345 }
03346 ao2_unlink(users,user);
03347 user_unref(user);
03348 }
03349 } else {
03350 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03351 }
03352
03353 return CLI_SUCCESS;
03354 }
03355
03356 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03357 {
03358 switch (cmd) {
03359 case CLI_INIT:
03360 e->command = "iax2 test losspct";
03361 e->usage =
03362 "Usage: iax2 test losspct <percentage>\n"
03363 " For testing, throws away <percentage> percent of incoming packets\n";
03364 return NULL;
03365 case CLI_GENERATE:
03366 return NULL;
03367 }
03368 if (a->argc != 4)
03369 return CLI_SHOWUSAGE;
03370
03371 test_losspct = atoi(a->argv[3]);
03372
03373 return CLI_SUCCESS;
03374 }
03375
03376 #ifdef IAXTESTS
03377 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03378 {
03379 switch (cmd) {
03380 case CLI_INIT:
03381 e->command = "iax2 test late";
03382 e->usage =
03383 "Usage: iax2 test late <ms>\n"
03384 " For testing, count the next frame as <ms> ms late\n";
03385 return NULL;
03386 case CLI_GENERATE:
03387 return NULL;
03388 }
03389
03390 if (a->argc != 4)
03391 return CLI_SHOWUSAGE;
03392
03393 test_late = atoi(a->argv[3]);
03394
03395 return CLI_SUCCESS;
03396 }
03397
03398 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03399 {
03400 switch (cmd) {
03401 case CLI_INIT:
03402 e->command = "iax2 test resync";
03403 e->usage =
03404 "Usage: iax2 test resync <ms>\n"
03405 " For testing, adjust all future frames by <ms> ms\n";
03406 return NULL;
03407 case CLI_GENERATE:
03408 return NULL;
03409 }
03410
03411 if (a->argc != 4)
03412 return CLI_SHOWUSAGE;
03413
03414 test_resync = atoi(a->argv[3]);
03415
03416 return CLI_SUCCESS;
03417 }
03418
03419 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03420 {
03421 switch (cmd) {
03422 case CLI_INIT:
03423 e->command = "iax2 test jitter";
03424 e->usage =
03425 "Usage: iax2 test jitter <ms> <pct>\n"
03426 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03427 " percentage of packets. If <pct> is not specified, adds\n"
03428 " jitter to all packets.\n";
03429 return NULL;
03430 case CLI_GENERATE:
03431 return NULL;
03432 }
03433
03434 if (a->argc < 4 || a->argc > 5)
03435 return CLI_SHOWUSAGE;
03436
03437 test_jit = atoi(a->argv[3]);
03438 if (a->argc == 5)
03439 test_jitpct = atoi(a->argv[4]);
03440
03441 return CLI_SUCCESS;
03442 }
03443 #endif
03444
03445
03446
03447 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03448 {
03449 int res = 0;
03450 if (peer->maxms) {
03451 if (peer->lastms < 0) {
03452 ast_copy_string(status, "UNREACHABLE", statuslen);
03453 } else if (peer->lastms > peer->maxms) {
03454 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03455 res = 1;
03456 } else if (peer->lastms) {
03457 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03458 res = 1;
03459 } else {
03460 ast_copy_string(status, "UNKNOWN", statuslen);
03461 }
03462 } else {
03463 ast_copy_string(status, "Unmonitored", statuslen);
03464 res = -1;
03465 }
03466 return res;
03467 }
03468
03469
03470 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03471 {
03472 char status[30];
03473 char cbuf[256];
03474 struct iax2_peer *peer;
03475 char codec_buf[512];
03476 int x = 0, codec = 0, load_realtime = 0;
03477
03478 switch (cmd) {
03479 case CLI_INIT:
03480 e->command = "iax2 show peer";
03481 e->usage =
03482 "Usage: iax2 show peer <name>\n"
03483 " Display details on specific IAX peer\n";
03484 return NULL;
03485 case CLI_GENERATE:
03486 if (a->pos == 3)
03487 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
03488 return NULL;
03489 }
03490
03491 if (a->argc < 4)
03492 return CLI_SHOWUSAGE;
03493
03494 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03495
03496 peer = find_peer(a->argv[3], load_realtime);
03497 if (peer) {
03498 ast_cli(a->fd, "\n\n");
03499 ast_cli(a->fd, " * Name : %s\n", peer->name);
03500 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03501 ast_cli(a->fd, " Context : %s\n", peer->context);
03502 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03503 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03504 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
03505 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03506 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03507 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
03508 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03509 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03510 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03511 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));
03512 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03513 ast_cli(a->fd, " Username : %s\n", peer->username);
03514 ast_cli(a->fd, " Codecs : ");
03515 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03516 ast_cli(a->fd, "%s\n", codec_buf);
03517
03518 ast_cli(a->fd, " Codec Order : (");
03519 for(x = 0; x < 32 ; x++) {
03520 codec = ast_codec_pref_index(&peer->prefs,x);
03521 if(!codec)
03522 break;
03523 ast_cli(a->fd, "%s", ast_getformatname(codec));
03524 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03525 ast_cli(a->fd, "|");
03526 }
03527
03528 if (!x)
03529 ast_cli(a->fd, "none");
03530 ast_cli(a->fd, ")\n");
03531
03532 ast_cli(a->fd, " Status : ");
03533 peer_status(peer, status, sizeof(status));
03534 ast_cli(a->fd, "%s\n",status);
03535 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");
03536 ast_cli(a->fd, "\n");
03537 peer_unref(peer);
03538 } else {
03539 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03540 ast_cli(a->fd, "\n");
03541 }
03542
03543 return CLI_SUCCESS;
03544 }
03545
03546 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state)
03547 {
03548 int which = 0;
03549 struct iax2_peer *peer;
03550 char *res = NULL;
03551 int wordlen = strlen(word);
03552 struct ao2_iterator i;
03553
03554 i = ao2_iterator_init(peers, 0);
03555 while ((peer = ao2_iterator_next(&i))) {
03556 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
03557 res = ast_strdup(peer->name);
03558 peer_unref(peer);
03559 break;
03560 }
03561 peer_unref(peer);
03562 }
03563 ao2_iterator_destroy(&i);
03564
03565 return res;
03566 }
03567
03568 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03569 {
03570 struct iax_frame *cur;
03571 int cnt = 0, dead = 0, final = 0;
03572
03573 switch (cmd) {
03574 case CLI_INIT:
03575 e->command = "iax2 show stats";
03576 e->usage =
03577 "Usage: iax2 show stats\n"
03578 " Display statistics on IAX channel driver.\n";
03579 return NULL;
03580 case CLI_GENERATE:
03581 return NULL;
03582 }
03583
03584 if (a->argc != 3)
03585 return CLI_SHOWUSAGE;
03586
03587 AST_LIST_LOCK(&frame_queue);
03588 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
03589 if (cur->retries < 0)
03590 dead++;
03591 if (cur->final)
03592 final++;
03593 cnt++;
03594 }
03595 AST_LIST_UNLOCK(&frame_queue);
03596
03597 ast_cli(a->fd, " IAX Statistics\n");
03598 ast_cli(a->fd, "---------------------\n");
03599 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03600 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03601 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03602 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03603
03604 trunk_timed = trunk_untimed = 0;
03605 if (trunk_maxmtu > trunk_nmaxmtu)
03606 trunk_nmaxmtu = trunk_maxmtu;
03607
03608 return CLI_SUCCESS;
03609 }
03610
03611
03612 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03613 {
03614 int mtuv;
03615
03616 switch (cmd) {
03617 case CLI_INIT:
03618 e->command = "iax2 set mtu";
03619 e->usage =
03620 "Usage: iax2 set mtu <value>\n"
03621 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03622 " zero to disable. Disabling means that the operating system\n"
03623 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03624 " packet exceeds the UDP payload size. This is substantially\n"
03625 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03626 " greater for G.711 samples.\n";
03627 return NULL;
03628 case CLI_GENERATE:
03629 return NULL;
03630 }
03631
03632 if (a->argc != 4)
03633 return CLI_SHOWUSAGE;
03634 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03635 mtuv = MAX_TRUNK_MTU;
03636 else
03637 mtuv = atoi(a->argv[3]);
03638
03639 if (mtuv == 0) {
03640 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03641 global_max_trunk_mtu = 0;
03642 return CLI_SUCCESS;
03643 }
03644 if (mtuv < 172 || mtuv > 4000) {
03645 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03646 return CLI_SHOWUSAGE;
03647 }
03648 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03649 global_max_trunk_mtu = mtuv;
03650 return CLI_SUCCESS;
03651 }
03652
03653 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03654 {
03655 struct iax2_dpcache *dp = NULL;
03656 char tmp[1024], *pc = NULL;
03657 int s, x, y;
03658 struct timeval now = ast_tvnow();
03659
03660 switch (cmd) {
03661 case CLI_INIT:
03662 e->command = "iax2 show cache";
03663 e->usage =
03664 "Usage: iax2 show cache\n"
03665 " Display currently cached IAX Dialplan results.\n";
03666 return NULL;
03667 case CLI_GENERATE:
03668 return NULL;
03669 }
03670
03671 AST_LIST_LOCK(&dpcache);
03672
03673 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03674
03675 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03676 s = dp->expiry.tv_sec - now.tv_sec;
03677 tmp[0] = '\0';
03678 if (dp->flags & CACHE_FLAG_EXISTS)
03679 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03680 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03681 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03682 if (dp->flags & CACHE_FLAG_CANEXIST)
03683 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03684 if (dp->flags & CACHE_FLAG_PENDING)
03685 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03686 if (dp->flags & CACHE_FLAG_TIMEOUT)
03687 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03688 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03689 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03690 if (dp->flags & CACHE_FLAG_MATCHMORE)
03691 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03692 if (dp->flags & CACHE_FLAG_UNKNOWN)
03693 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03694
03695 if (!ast_strlen_zero(tmp)) {
03696 tmp[strlen(tmp) - 1] = '\0';
03697 } else {
03698 ast_copy_string(tmp, "(none)", sizeof(tmp));
03699 }
03700 y = 0;
03701 pc = strchr(dp->peercontext, '@');
03702 if (!pc) {
03703 pc = dp->peercontext;
03704 } else {
03705 pc++;
03706 }
03707 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03708 if (dp->waiters[x] > -1)
03709 y++;
03710 }
03711 if (s > 0) {
03712 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03713 } else {
03714 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03715 }
03716 }
03717
03718 AST_LIST_UNLOCK(&dpcache);
03719
03720 return CLI_SUCCESS;
03721 }
03722
03723 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03724
03725 static void unwrap_timestamp(struct iax_frame *fr)
03726 {
03727
03728
03729 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03730 const int lower_mask = (1 << ts_shift) - 1;
03731 const int upper_mask = ~lower_mask;
03732 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03733
03734 if ( (fr->ts & upper_mask) == last_upper ) {
03735 const int x = fr->ts - iaxs[fr->callno]->last;
03736 const int threshold = (ts_shift == 15) ? 25000 : 50000;
03737
03738 if (x < -threshold) {
03739
03740
03741
03742
03743 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
03744 if (iaxdebug)
03745 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
03746 } else if (x > threshold) {
03747
03748
03749
03750
03751 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03752 if (iaxdebug)
03753 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
03754 }
03755 }
03756 }
03757
03758 static int get_from_jb(const void *p);
03759
03760 static void update_jbsched(struct chan_iax2_pvt *pvt)
03761 {
03762 int when;
03763
03764 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03765
03766 when = jb_next(pvt->jb) - when;
03767
03768 if (when <= 0) {
03769
03770 when = 1;
03771 }
03772
03773 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
03774 CALLNO_TO_PTR(pvt->callno));
03775 }
03776
03777 static void __get_from_jb(const void *p)
03778 {
03779 int callno = PTR_TO_CALLNO(p);
03780 struct chan_iax2_pvt *pvt = NULL;
03781 struct iax_frame *fr;
03782 jb_frame frame;
03783 int ret;
03784 long ms;
03785 long next;
03786 struct timeval now = ast_tvnow();
03787
03788
03789 ast_mutex_lock(&iaxsl[callno]);
03790 pvt = iaxs[callno];
03791 if (!pvt) {
03792
03793 ast_mutex_unlock(&iaxsl[callno]);
03794 return;
03795 }
03796
03797 pvt->jbid = -1;
03798
03799
03800
03801
03802 now.tv_usec += 1000;
03803
03804 ms = ast_tvdiff_ms(now, pvt->rxcore);
03805
03806 if(ms >= (next = jb_next(pvt->jb))) {
03807 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
03808 switch(ret) {
03809 case JB_OK:
03810 fr = frame.data;
03811 __do_deliver(fr);
03812
03813 pvt = iaxs[callno];
03814 break;
03815 case JB_INTERP:
03816 {
03817 struct ast_frame af = { 0, };
03818
03819
03820 af.frametype = AST_FRAME_VOICE;
03821 af.subclass = pvt->voiceformat;
03822 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03823 af.src = "IAX2 JB interpolation";
03824 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03825 af.offset = AST_FRIENDLY_OFFSET;
03826
03827
03828
03829 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03830 iax2_queue_frame(callno, &af);
03831
03832 pvt = iaxs[callno];
03833 }
03834 }
03835 break;
03836 case JB_DROP:
03837 iax2_frame_free(frame.data);
03838 break;
03839 case JB_NOFRAME:
03840 case JB_EMPTY:
03841
03842 break;
03843 default:
03844
03845 break;
03846 }
03847 }
03848 if (pvt)
03849 update_jbsched(pvt);
03850 ast_mutex_unlock(&iaxsl[callno]);
03851 }
03852
03853 static int get_from_jb(const void *data)
03854 {
03855 #ifdef SCHED_MULTITHREADED
03856 if (schedule_action(__get_from_jb, data))
03857 #endif
03858 __get_from_jb(data);
03859 return 0;
03860 }
03861
03862
03863
03864
03865
03866
03867
03868 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03869 {
03870 int type, len;
03871 int ret;
03872 int needfree = 0;
03873 struct ast_channel *owner = NULL;
03874 struct ast_channel *bridge = NULL;
03875
03876
03877 unwrap_timestamp(fr);
03878
03879
03880 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03881 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03882 else {
03883 #if 0
03884 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03885 #endif
03886 fr->af.delivery = ast_tv(0,0);
03887 }
03888
03889 type = JB_TYPE_CONTROL;
03890 len = 0;
03891
03892 if(fr->af.frametype == AST_FRAME_VOICE) {
03893 type = JB_TYPE_VOICE;
03894 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
03895 } else if(fr->af.frametype == AST_FRAME_CNG) {
03896 type = JB_TYPE_SILENCE;
03897 }
03898
03899 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03900 if (tsout)
03901 *tsout = fr->ts;
03902 __do_deliver(fr);
03903 return -1;
03904 }
03905
03906 if ((owner = iaxs[fr->callno]->owner))
03907 bridge = ast_bridged_channel(owner);
03908
03909
03910
03911 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03912 jb_frame frame;
03913
03914
03915 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03916 __do_deliver(frame.data);
03917
03918 if (!iaxs[fr->callno])
03919 return -1;
03920 }
03921
03922 jb_reset(iaxs[fr->callno]->jb);
03923
03924 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03925
03926
03927 if (tsout)
03928 *tsout = fr->ts;
03929 __do_deliver(fr);
03930 return -1;
03931 }
03932
03933
03934
03935 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03936 calc_rxstamp(iaxs[fr->callno],fr->ts));
03937 if (ret == JB_DROP) {
03938 needfree++;
03939 } else if (ret == JB_SCHED) {
03940 update_jbsched(iaxs[fr->callno]);
03941 }
03942 if (tsout)
03943 *tsout = fr->ts;
03944 if (needfree) {
03945
03946 iax2_frame_free(fr);
03947 return -1;
03948 }
03949 return 0;
03950 }
03951
03952 static int iax2_transmit(struct iax_frame *fr)
03953 {
03954
03955
03956
03957 fr->sentyet = 0;
03958 AST_LIST_LOCK(&frame_queue);
03959 AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
03960 AST_LIST_UNLOCK(&frame_queue);
03961
03962 if (netthreadid != AST_PTHREADT_NULL)
03963 pthread_kill(netthreadid, SIGURG);
03964 signal_condition(&sched_lock, &sched_cond);
03965 return 0;
03966 }
03967
03968
03969
03970 static int iax2_digit_begin(struct ast_channel *c, char digit)
03971 {
03972 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03973 }
03974
03975 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
03976 {
03977 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03978 }
03979
03980 static int iax2_sendtext(struct ast_channel *c, const char *text)
03981 {
03982
03983 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03984 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03985 }
03986
03987 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
03988 {
03989 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1);
03990 }
03991
03992 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
03993 {
03994 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03995 }
03996
03997 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
03998 {
03999 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04000 ast_mutex_lock(&iaxsl[callno]);
04001 if (iaxs[callno])
04002 iaxs[callno]->owner = newchan;
04003 else
04004 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04005 ast_mutex_unlock(&iaxsl[callno]);
04006 return 0;
04007 }
04008
04009
04010
04011
04012
04013 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04014 {
04015 struct ast_variable *var = NULL;
04016 struct ast_variable *tmp;
04017 struct iax2_peer *peer=NULL;
04018 time_t regseconds = 0, nowtime;
04019 int dynamic=0;
04020
04021 if (peername) {
04022 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04023 if (!var && sin)
04024 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04025 } else if (sin) {
04026 char porta[25];
04027 sprintf(porta, "%d", ntohs(sin->sin_port));
04028 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04029 if (var) {
04030
04031 for (tmp = var; tmp; tmp = tmp->next) {
04032 if (!strcasecmp(tmp->name, "name"))
04033 peername = tmp->value;
04034 }
04035 }
04036 }
04037 if (!var && peername) {
04038 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04039
04040
04041
04042
04043
04044
04045 if (var && sin) {
04046 for (tmp = var; tmp; tmp = tmp->next) {
04047 if (!strcasecmp(tmp->name, "host")) {
04048 struct ast_hostent ahp;
04049 struct hostent *hp;
04050 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04051
04052 ast_variables_destroy(var);
04053 var = NULL;
04054 }
04055 break;
04056 }
04057 }
04058 }
04059 }
04060 if (!var)
04061 return NULL;
04062
04063 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04064
04065 if (!peer) {
04066 ast_variables_destroy(var);
04067 return NULL;
04068 }
04069
04070 for (tmp = var; tmp; tmp = tmp->next) {
04071
04072 if (!strcasecmp(tmp->name, "type")) {
04073 if (strcasecmp(tmp->value, "friend") &&
04074 strcasecmp(tmp->value, "peer")) {
04075
04076 peer = peer_unref(peer);
04077 break;
04078 }
04079 } else if (!strcasecmp(tmp->name, "regseconds")) {
04080 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04081 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04082 inet_aton(tmp->value, &(peer->addr.sin_addr));
04083 } else if (!strcasecmp(tmp->name, "port")) {
04084 peer->addr.sin_port = htons(atoi(tmp->value));
04085 } else if (!strcasecmp(tmp->name, "host")) {
04086 if (!strcasecmp(tmp->value, "dynamic"))
04087 dynamic = 1;
04088 }
04089 }
04090
04091 ast_variables_destroy(var);
04092
04093 if (!peer)
04094 return NULL;
04095
04096 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04097 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04098 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
04099 if (peer->expire > -1) {
04100 if (!ast_sched_del(sched, peer->expire)) {
04101 peer->expire = -1;
04102 peer_unref(peer);
04103 }
04104 }
04105 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04106 if (peer->expire == -1)
04107 peer_unref(peer);
04108 }
04109 ao2_link(peers, peer);
04110 if (ast_test_flag(peer, IAX_DYNAMIC))
04111 reg_source_db(peer);
04112 } else {
04113 ast_set_flag(peer, IAX_TEMPONLY);
04114 }
04115
04116 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04117 time(&nowtime);
04118 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04119 memset(&peer->addr, 0, sizeof(peer->addr));
04120 realtime_update_peer(peer->name, &peer->addr, 0);
04121 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04122 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04123 }
04124 else {
04125 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04126 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04127 }
04128 }
04129
04130 return peer;
04131 }
04132
04133 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04134 {
04135 struct ast_variable *var;
04136 struct ast_variable *tmp;
04137 struct iax2_user *user=NULL;
04138
04139 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04140 if (!var)
04141 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04142 if (!var && sin) {
04143 char porta[6];
04144 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04145 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04146 if (!var)
04147 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04148 }
04149 if (!var) {
04150 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04151
04152
04153
04154
04155
04156
04157 if (var) {
04158 for (tmp = var; tmp; tmp = tmp->next) {
04159 if (!strcasecmp(tmp->name, "host")) {
04160 struct ast_hostent ahp;
04161 struct hostent *hp;
04162 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04163
04164 ast_variables_destroy(var);
04165 var = NULL;
04166 }
04167 break;
04168 }
04169 }
04170 }
04171 }
04172 if (!var)
04173 return NULL;
04174
04175 tmp = var;
04176 while(tmp) {
04177
04178 if (!strcasecmp(tmp->name, "type")) {
04179 if (strcasecmp(tmp->value, "friend") &&
04180 strcasecmp(tmp->value, "user")) {
04181 return NULL;
04182 }
04183 }
04184 tmp = tmp->next;
04185 }
04186
04187 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
04188
04189 ast_variables_destroy(var);
04190
04191 if (!user)
04192 return NULL;
04193
04194 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04195 ast_set_flag(user, IAX_RTCACHEFRIENDS);
04196 ao2_link(users, user);
04197 } else {
04198 ast_set_flag(user, IAX_TEMPONLY);
04199 }
04200
04201 return user;
04202 }
04203
04204 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
04205 {
04206 char port[10];
04207 char regseconds[20];
04208
04209 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04210 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
04211 ast_update_realtime("iaxpeers", "name", peername,
04212 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
04213 "regseconds", regseconds, SENTINEL);
04214 }
04215
04216 struct create_addr_info {
04217 int capability;
04218 unsigned int flags;
04219 int maxtime;
04220 int encmethods;
04221 int found;
04222 int sockfd;
04223 int adsi;
04224 char username[80];
04225 char secret[80];
04226 char outkey[80];
04227 char timezone[80];
04228 char prefs[32];
04229 char context[AST_MAX_CONTEXT];
04230 char peercontext[AST_MAX_CONTEXT];
04231 char mohinterpret[MAX_MUSICCLASS];
04232 char mohsuggest[MAX_MUSICCLASS];
04233 };
04234
04235 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04236 {
04237 struct iax2_peer *peer;
04238 int res = -1;
04239 struct ast_codec_pref ourprefs;
04240
04241 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
04242 cai->sockfd = defaultsockfd;
04243 cai->maxtime = 0;
04244 sin->sin_family = AF_INET;
04245
04246 if (!(peer = find_peer(peername, 1))) {
04247 cai->found = 0;
04248 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
04249 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04250 return -1;
04251 }
04252 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04253
04254
04255 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04256 if (c)
04257 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04258 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04259 return 0;
04260 }
04261
04262 cai->found = 1;
04263
04264
04265 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
04266 goto return_unref;
04267
04268
04269 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04270 goto return_unref;
04271
04272 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
04273 cai->maxtime = peer->maxms;
04274 cai->capability = peer->capability;
04275 cai->encmethods = peer->encmethods;
04276 cai->sockfd = peer->sockfd;
04277 cai->adsi = peer->adsi;
04278 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04279
04280 if (c) {
04281 ast_debug(1, "prepending %x to prefs\n", c->nativeformats);
04282 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04283 }
04284 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04285 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04286 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04287 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04288 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04289 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04290 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04291 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04292 if (ast_strlen_zero(peer->dbsecret)) {
04293 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04294 } else {
04295 char *family;
04296 char *key = NULL;
04297
04298 family = ast_strdupa(peer->dbsecret);
04299 key = strchr(family, '/');
04300 if (key)
04301 *key++ = '\0';
04302 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04303 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04304 goto return_unref;
04305 }
04306 }
04307
04308 if (peer->addr.sin_addr.s_addr) {
04309 sin->sin_addr = peer->addr.sin_addr;
04310 sin->sin_port = peer->addr.sin_port;
04311 } else {
04312 sin->sin_addr = peer->defaddr.sin_addr;
04313 sin->sin_port = peer->defaddr.sin_port;
04314 }
04315
04316 res = 0;
04317
04318 return_unref:
04319 peer_unref(peer);
04320
04321 return res;
04322 }
04323
04324 static void __auto_congest(const void *nothing)
04325 {
04326 int callno = PTR_TO_CALLNO(nothing);
04327 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
04328 ast_mutex_lock(&iaxsl[callno]);
04329 if (iaxs[callno]) {
04330 iaxs[callno]->initid = -1;
04331 iax2_queue_frame(callno, &f);
04332 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04333 }
04334 ast_mutex_unlock(&iaxsl[callno]);
04335 }
04336
04337 static int auto_congest(const void *data)
04338 {
04339 #ifdef SCHED_MULTITHREADED
04340 if (schedule_action(__auto_congest, data))
04341 #endif
04342 __auto_congest(data);
04343 return 0;
04344 }
04345
04346 static unsigned int iax2_datetime(const char *tz)
04347 {
04348 struct timeval t = ast_tvnow();
04349 struct ast_tm tm;
04350 unsigned int tmp;
04351 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04352 tmp = (tm.tm_sec >> 1) & 0x1f;
04353 tmp |= (tm.tm_min & 0x3f) << 5;
04354 tmp |= (tm.tm_hour & 0x1f) << 11;
04355 tmp |= (tm.tm_mday & 0x1f) << 16;
04356 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04357 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04358 return tmp;
04359 }
04360
04361 struct parsed_dial_string {
04362 char *username;
04363 char *password;
04364 char *key;
04365 char *peer;
04366 char *port;
04367 char *exten;
04368 char *context;
04369 char *options;
04370 };
04371
04372 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04373 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04374 int sockfd, struct iax_ie_data *ied)
04375 {
04376 struct {
04377 struct ast_iax2_full_hdr f;
04378 struct iax_ie_data ied;
04379 } data;
04380 size_t size = sizeof(struct ast_iax2_full_hdr);
04381
04382 if (ied) {
04383 size += ied->pos;
04384 memcpy(&data.ied, ied->buf, ied->pos);
04385 }
04386
04387 data.f.scallno = htons(0x8000 | callno);
04388 data.f.dcallno = htons(dcallno);
04389 data.f.ts = htonl(ts);
04390 data.f.iseqno = seqno;
04391 data.f.oseqno = 0;
04392 data.f.type = AST_FRAME_IAX;
04393 data.f.csub = compress_subclass(command);
04394
04395 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04396 }
04397
04398 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04399 {
04400
04401 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04402 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04403 ied->buf[ied->pos++] = 0;
04404 pvt->calltoken_ie_len = 2;
04405 }
04406 }
04407
04408 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04409 {
04410 struct chan_iax2_pvt *pvt = iaxs[callno];
04411 int frametype = f->af.frametype;
04412 int subclass = f->af.subclass;
04413 struct {
04414 struct ast_iax2_full_hdr fh;
04415 struct iax_ie_data ied;
04416 } data = {
04417 .ied.buf = { 0 },
04418 .ied.pos = 0,
04419 };
04420
04421 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04422
04423 if (!pvt) {
04424 return;
04425 }
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04439 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04440 (f->datalen > sizeof(data))) {
04441
04442 return;
04443 }
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459 memcpy(&data, f->data, f->datalen);
04460 data.ied.pos = ie_data_pos;
04461
04462
04463
04464 data.ied.pos -= pvt->calltoken_ie_len;
04465 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04466
04467
04468 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04469
04470
04471 AST_LIST_LOCK(&frame_queue);
04472 AST_LIST_REMOVE(&frame_queue, f, list);
04473 AST_LIST_UNLOCK(&frame_queue);
04474
04475
04476 iax2_frame_free(f);
04477
04478
04479 pvt->oseqno = 0;
04480 pvt->rseqno = 0;
04481 pvt->iseqno = 0;
04482 pvt->aseqno = 0;
04483 if (pvt->peercallno) {
04484 remove_by_peercallno(pvt);
04485 pvt->peercallno = 0;
04486 }
04487
04488
04489 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04490 }
04491
04492 static void requirecalltoken_mark_auto(const char *name, int subclass)
04493 {
04494 struct iax2_user *user = NULL;
04495 struct iax2_peer *peer = NULL;
04496
04497 if (ast_strlen_zero(name)) {
04498 return;
04499 }
04500
04501 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04502 user->calltoken_required = CALLTOKEN_YES;
04503 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04504 peer->calltoken_required = CALLTOKEN_YES;
04505 }
04506
04507 if (peer) {
04508 peer_unref(peer);
04509 }
04510 if (user) {
04511 user_unref(user);
04512 }
04513 }
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530
04531
04532 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04533 struct sockaddr_in *sin, int fd)
04534 {
04535 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04536 #define CALLTOKEN_IE_FORMAT "%u?%s"
04537 struct ast_str *buf = ast_str_alloca(256);
04538 time_t t = time(NULL);
04539 char hash[41];
04540 int subclass = uncompress_subclass(fh->csub);
04541
04542
04543 if (ies->calltoken && !ies->calltokendata) {
04544 struct iax_ie_data ied = {
04545 .buf = { 0 },
04546 .pos = 0,
04547 };
04548
04549
04550 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04551 ast_sha1_hash(hash, ast_str_buffer(buf));
04552
04553 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04554 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04555 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04556
04557 return 1;
04558
04559
04560 } else if (ies->calltoken && ies->calltokendata) {
04561 char *rec_hash = NULL;
04562 char *rec_ts = NULL;
04563 unsigned int rec_time;
04564
04565
04566 rec_hash = strchr((char *) ies->calltokendata, '?');
04567 if (rec_hash) {
04568 *rec_hash++ = '\0';
04569 rec_ts = (char *) ies->calltokendata;
04570 }
04571
04572
04573 if (!rec_hash || !rec_ts) {
04574 goto reject;
04575 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04576 goto reject;
04577 }
04578
04579
04580 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04581 ast_sha1_hash(hash, ast_str_buffer(buf));
04582
04583
04584 if (strcmp(hash, rec_hash)) {
04585 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04586 goto reject;
04587 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04588 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04589 goto reject;
04590 }
04591
04592
04593
04594 requirecalltoken_mark_auto(ies->username, subclass);
04595 return 0;
04596
04597
04598 } else {
04599 if (calltoken_required(sin, ies->username, subclass)) {
04600 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest"));
04601 goto reject;
04602 }
04603 return 0;
04604 }
04605
04606 reject:
04607
04608 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04609 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04610 } else {
04611 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04612 }
04613
04614 return 1;
04615 }
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04636 {
04637 if (ast_strlen_zero(data))
04638 return;
04639
04640 pds->peer = strsep(&data, "/");
04641 pds->exten = strsep(&data, "/");
04642 pds->options = data;
04643
04644 if (pds->exten) {
04645 data = pds->exten;
04646 pds->exten = strsep(&data, "@");
04647 pds->context = data;
04648 }
04649
04650 if (strchr(pds->peer, '@')) {
04651 data = pds->peer;
04652 pds->username = strsep(&data, "@");
04653 pds->peer = data;
04654 }
04655
04656 if (pds->username) {
04657 data = pds->username;
04658 pds->username = strsep(&data, ":");
04659 pds->password = data;
04660 }
04661
04662 data = pds->peer;
04663 pds->peer = strsep(&data, ":");
04664 pds->port = data;
04665
04666
04667
04668
04669 if (pds->password && (pds->password[0] == '[')) {
04670 pds->key = ast_strip_quoted(pds->password, "[", "]");
04671 pds->password = NULL;
04672 }
04673 }
04674
04675 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04676 {
04677 struct sockaddr_in sin;
04678 char *l=NULL, *n=NULL, *tmpstr;
04679 struct iax_ie_data ied;
04680 char *defaultrdest = "s";
04681 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04682 struct parsed_dial_string pds;
04683 struct create_addr_info cai;
04684 struct ast_var_t *var;
04685 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04686 const char* osp_token_ptr;
04687 unsigned int osp_token_length;
04688 unsigned char osp_block_index;
04689 unsigned int osp_block_length;
04690 unsigned char osp_buffer[256];
04691
04692 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
04693 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
04694 return -1;
04695 }
04696
04697 memset(&cai, 0, sizeof(cai));
04698 cai.encmethods = iax2_encryption;
04699
04700 memset(&pds, 0, sizeof(pds));
04701 tmpstr = ast_strdupa(dest);
04702 parse_dial_string(tmpstr, &pds);
04703
04704 if (ast_strlen_zero(pds.peer)) {
04705 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
04706 return -1;
04707 }
04708
04709 if (!pds.exten) {
04710 pds.exten = defaultrdest;
04711 }
04712
04713 if (create_addr(pds.peer, c, &sin, &cai)) {
04714 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
04715 return -1;
04716 }
04717
04718 if (!pds.username && !ast_strlen_zero(cai.username))
04719 pds.username = cai.username;
04720 if (!pds.password && !ast_strlen_zero(cai.secret))
04721 pds.password = cai.secret;
04722 if (!pds.key && !ast_strlen_zero(cai.outkey))
04723 pds.key = cai.outkey;
04724 if (!pds.context && !ast_strlen_zero(cai.peercontext))
04725 pds.context = cai.peercontext;
04726
04727
04728 ast_copy_string(c->context, cai.context, sizeof(c->context));
04729
04730 if (pds.port)
04731 sin.sin_port = htons(atoi(pds.port));
04732
04733 l = c->cid.cid_num;
04734 n = c->cid.cid_name;
04735
04736
04737 memset(&ied, 0, sizeof(ied));
04738
04739
04740 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
04741 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
04742 if (pds.options && strchr(pds.options, 'a')) {
04743
04744 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
04745 }
04746
04747 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
04748
04749 if (l) {
04750 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
04751 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04752 } else {
04753 if (n)
04754 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04755 else
04756 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
04757 }
04758
04759 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
04760 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
04761
04762 if (n)
04763 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
04764 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
04765 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
04766
04767 if (!ast_strlen_zero(c->language))
04768 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
04769 if (!ast_strlen_zero(c->cid.cid_dnid))
04770 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
04771 if (!ast_strlen_zero(c->cid.cid_rdnis))
04772 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
04773
04774 if (pds.context)
04775 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
04776
04777 if (pds.username)
04778 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
04779
04780 if (cai.encmethods)
04781 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
04782
04783 ast_mutex_lock(&iaxsl[callno]);
04784
04785 if (!ast_strlen_zero(c->context))
04786 ast_string_field_set(iaxs[callno], context, c->context);
04787
04788 if (pds.username)
04789 ast_string_field_set(iaxs[callno], username, pds.username);
04790
04791 iaxs[callno]->encmethods = cai.encmethods;
04792
04793 iaxs[callno]->adsi = cai.adsi;
04794
04795 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
04796 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
04797
04798 if (pds.key)
04799 ast_string_field_set(iaxs[callno], outkey, pds.key);
04800 if (pds.password)
04801 ast_string_field_set(iaxs[callno], secret, pds.password);
04802
04803 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
04804 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
04805 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
04806 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
04807
04808 if (iaxs[callno]->maxtime) {
04809
04810 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
04811 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
04812 } else if (autokill) {
04813 iaxs[callno]->pingtime = autokill / 2;
04814 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
04815 }
04816
04817
04818 osp_token_ptr = iaxs[callno]->osptoken;
04819 if (!ast_strlen_zero(osp_token_ptr)) {
04820 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
04821 osp_block_index = 0;
04822 while (osp_token_length > 0) {
04823 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
04824 osp_buffer[0] = osp_block_index;
04825 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
04826 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
04827 osp_block_index++;
04828 osp_token_ptr += osp_block_length;
04829 osp_token_length -= osp_block_length;
04830 }
04831 } else
04832 ast_log(LOG_WARNING, "OSP token is too long\n");
04833 } else if (iaxdebug)
04834 ast_debug(1, "OSP token is undefined\n");
04835
04836
04837 iaxs[callno]->sockfd = cai.sockfd;
04838
04839
04840 if (variablestore) {
04841 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
04842 ast_debug(1, "Found an IAX variable store on this channel\n");
04843 AST_LIST_LOCK(variablelist);
04844 AST_LIST_TRAVERSE(variablelist, var, entries) {
04845 char tmp[256];
04846 int i;
04847 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
04848
04849 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
04850 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
04851 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
04852 }
04853 }
04854 AST_LIST_UNLOCK(variablelist);
04855 }
04856
04857
04858 add_empty_calltoken_ie(iaxs[callno], &ied);
04859 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
04860
04861 ast_mutex_unlock(&iaxsl[callno]);
04862 ast_setstate(c, AST_STATE_RINGING);
04863
04864 return 0;
04865 }
04866
04867 static int iax2_hangup(struct ast_channel *c)
04868 {
04869 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04870 struct iax_ie_data ied;
04871 int alreadygone;
04872 memset(&ied, 0, sizeof(ied));
04873 ast_mutex_lock(&iaxsl[callno]);
04874 if (callno && iaxs[callno]) {
04875 ast_debug(1, "We're hanging up %s now...\n", c->name);
04876 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
04877
04878 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
04879 if (!iaxs[callno]->error && !alreadygone) {
04880 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
04881 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
04882 }
04883 if (!iaxs[callno]) {
04884 ast_mutex_unlock(&iaxsl[callno]);
04885 return 0;
04886 }
04887 }
04888
04889 iax2_predestroy(callno);
04890
04891 if (iaxs[callno] && alreadygone) {
04892 ast_debug(1, "Really destroying %s now...\n", c->name);
04893 iax2_destroy(callno);
04894 } else if (iaxs[callno]) {
04895 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
04896 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
04897 iax2_destroy(callno);
04898 }
04899 }
04900 } else if (c->tech_pvt) {
04901
04902
04903
04904
04905 c->tech_pvt = NULL;
04906 }
04907 ast_mutex_unlock(&iaxsl[callno]);
04908 ast_verb(3, "Hungup '%s'\n", c->name);
04909 return 0;
04910 }
04911
04912
04913
04914
04915 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
04916 {
04917 unsigned short callno = pvt->callno;
04918
04919 if (!pvt->peercallno) {
04920
04921 int count = 10;
04922 while (count-- && pvt && !pvt->peercallno) {
04923 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
04924 pvt = iaxs[callno];
04925 }
04926 if (!pvt->peercallno) {
04927 return -1;
04928 }
04929 }
04930
04931 return 0;
04932 }
04933
04934 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
04935 {
04936 struct ast_option_header *h;
04937 int res;
04938
04939 switch (option) {
04940 case AST_OPTION_TXGAIN:
04941 case AST_OPTION_RXGAIN:
04942
04943 errno = ENOSYS;
04944 return -1;
04945 default:
04946 {
04947 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04948 struct chan_iax2_pvt *pvt;
04949
04950 ast_mutex_lock(&iaxsl[callno]);
04951 pvt = iaxs[callno];
04952
04953 if (wait_for_peercallno(pvt)) {
04954 ast_mutex_unlock(&iaxsl[callno]);
04955 return -1;
04956 }
04957
04958 ast_mutex_unlock(&iaxsl[callno]);
04959
04960 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
04961 return -1;
04962 }
04963
04964 h->flag = AST_OPTION_FLAG_REQUEST;
04965 h->option = htons(option);
04966 memcpy(h->data, data, datalen);
04967 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
04968 AST_CONTROL_OPTION, 0, (unsigned char *) h,
04969 datalen + sizeof(*h), -1);
04970 ast_free(h);
04971 return res;
04972 }
04973 }
04974 }
04975
04976 static struct ast_frame *iax2_read(struct ast_channel *c)
04977 {
04978 ast_log(LOG_NOTICE, "I should never be called!\n");
04979 return &ast_null_frame;
04980 }
04981
04982 static int iax2_key_rotate(const void *vpvt)
04983 {
04984 int res = 0;
04985 struct chan_iax2_pvt *pvt = (void *) vpvt;
04986 struct MD5Context md5;
04987 char key[17] = "";
04988 struct iax_ie_data ied = {
04989 .pos = 0,
04990 };
04991
04992 ast_mutex_lock(&iaxsl[pvt->callno]);
04993 pvt->keyrotateid =
04994 ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
04995
04996 snprintf(key, sizeof(key), "%lX", ast_random());
04997
04998 MD5Init(&md5);
04999 MD5Update(&md5, (unsigned char *) key, strlen(key));
05000 MD5Final((unsigned char *) key, &md5);
05001
05002 IAX_DEBUGDIGEST("Sending", key);
05003
05004 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05005
05006 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05007
05008 build_ecx_key((unsigned char *) key, pvt);
05009
05010 ast_mutex_unlock(&iaxsl[pvt->callno]);
05011
05012 return res;
05013 }
05014
05015 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05016 {
05017 int res;
05018 struct iax_ie_data ied0;
05019 struct iax_ie_data ied1;
05020 unsigned int transferid = (unsigned int)ast_random();
05021
05022 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05023 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05024 ast_set_flag(iaxs[callno0], IAX_NOTRANSFER);
05025 ast_set_flag(iaxs[callno1], IAX_NOTRANSFER);
05026 return 0;
05027 }
05028
05029 memset(&ied0, 0, sizeof(ied0));
05030 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05031 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05032 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05033
05034 memset(&ied1, 0, sizeof(ied1));
05035 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05036 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05037 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05038
05039 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05040 if (res)
05041 return -1;
05042 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05043 if (res)
05044 return -1;
05045 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05046 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05047 return 0;
05048 }
05049
05050 static void lock_both(unsigned short callno0, unsigned short callno1)
05051 {
05052 ast_mutex_lock(&iaxsl[callno0]);
05053 while (ast_mutex_trylock(&iaxsl[callno1])) {
05054 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05055 }
05056 }
05057
05058 static void unlock_both(unsigned short callno0, unsigned short callno1)
05059 {
05060 ast_mutex_unlock(&iaxsl[callno1]);
05061 ast_mutex_unlock(&iaxsl[callno0]);
05062 }
05063
05064 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)
05065 {
05066 struct ast_channel *cs[3];
05067 struct ast_channel *who, *other;
05068 int to = -1;
05069 int res = -1;
05070 int transferstarted=0;
05071 struct ast_frame *f;
05072 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05073 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05074 struct timeval waittimer = {0, 0};
05075
05076
05077 if (timeoutms > 0) {
05078 return AST_BRIDGE_FAILED;
05079 }
05080
05081 timeoutms = -1;
05082
05083 lock_both(callno0, callno1);
05084 if (!iaxs[callno0] || !iaxs[callno1]) {
05085 unlock_both(callno0, callno1);
05086 return AST_BRIDGE_FAILED;
05087 }
05088
05089 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05090 iaxs[callno0]->bridgecallno = callno1;
05091 iaxs[callno1]->bridgecallno = callno0;
05092 }
05093 unlock_both(callno0, callno1);
05094
05095
05096 cs[0] = c0;
05097 cs[1] = c1;
05098 for (;;) {
05099
05100 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05101 ast_verb(3, "Can't masquerade, we're different...\n");
05102
05103 if (c0->tech == &iax2_tech) {
05104 ast_mutex_lock(&iaxsl[callno0]);
05105 iaxs[callno0]->bridgecallno = 0;
05106 ast_mutex_unlock(&iaxsl[callno0]);
05107 }
05108 if (c1->tech == &iax2_tech) {
05109 ast_mutex_lock(&iaxsl[callno1]);
05110 iaxs[callno1]->bridgecallno = 0;
05111 ast_mutex_unlock(&iaxsl[callno1]);
05112 }
05113 return AST_BRIDGE_FAILED_NOWARN;
05114 }
05115 if (c0->nativeformats != c1->nativeformats) {
05116 char buf0[255];
05117 char buf1[255];
05118 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
05119 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
05120 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
05121
05122 lock_both(callno0, callno1);
05123 if (iaxs[callno0])
05124 iaxs[callno0]->bridgecallno = 0;
05125 if (iaxs[callno1])
05126 iaxs[callno1]->bridgecallno = 0;
05127 unlock_both(callno0, callno1);
05128 return AST_BRIDGE_FAILED_NOWARN;
05129 }
05130
05131 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
05132
05133 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05134 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
05135 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05136 transferstarted = 1;
05137 }
05138 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05139
05140 struct timeval now = ast_tvnow();
05141 if (ast_tvzero(waittimer)) {
05142 waittimer = now;
05143 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05144 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05145 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05146 *fo = NULL;
05147 *rc = c0;
05148 res = AST_BRIDGE_COMPLETE;
05149 break;
05150 }
05151 }
05152 to = 1000;
05153 who = ast_waitfor_n(cs, 2, &to);
05154 if (timeoutms > -1) {
05155 timeoutms -= (1000 - to);
05156 if (timeoutms < 0)
05157 timeoutms = 0;
05158 }
05159 if (!who) {
05160 if (!timeoutms) {
05161 res = AST_BRIDGE_RETRY;
05162 break;
05163 }
05164 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05165 res = AST_BRIDGE_FAILED;
05166 break;
05167 }
05168 continue;
05169 }
05170 f = ast_read(who);
05171 if (!f) {
05172 *fo = NULL;
05173 *rc = who;
05174 res = AST_BRIDGE_COMPLETE;
05175 break;
05176 }
05177 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
05178 *fo = f;
05179 *rc = who;
05180 res = AST_BRIDGE_COMPLETE;
05181 break;
05182 }
05183 other = (who == c0) ? c1 : c0;
05184 if ((f->frametype == AST_FRAME_VOICE) ||
05185 (f->frametype == AST_FRAME_TEXT) ||
05186 (f->frametype == AST_FRAME_VIDEO) ||
05187 (f->frametype == AST_FRAME_IMAGE) ||
05188 (f->frametype == AST_FRAME_DTMF) ||
05189 (f->frametype == AST_FRAME_CONTROL)) {
05190
05191
05192
05193 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05194 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05195 *rc = who;
05196 *fo = f;
05197 res = AST_BRIDGE_COMPLETE;
05198
05199 break;
05200 }
05201
05202 ast_write(other, f);
05203 }
05204 ast_frfree(f);
05205
05206 cs[2] = cs[0];
05207 cs[0] = cs[1];
05208 cs[1] = cs[2];
05209 }
05210 lock_both(callno0, callno1);
05211 if(iaxs[callno0])
05212 iaxs[callno0]->bridgecallno = 0;
05213 if(iaxs[callno1])
05214 iaxs[callno1]->bridgecallno = 0;
05215 unlock_both(callno0, callno1);
05216 return res;
05217 }
05218
05219 static int iax2_answer(struct ast_channel *c)
05220 {
05221 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05222 ast_debug(1, "Answering IAX2 call\n");
05223 ast_mutex_lock(&iaxsl[callno]);
05224 if (iaxs[callno])
05225 iax2_ami_channelupdate(iaxs[callno]);
05226 ast_mutex_unlock(&iaxsl[callno]);
05227 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05228 }
05229
05230 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05231 {
05232 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05233 struct chan_iax2_pvt *pvt;
05234 int res = 0;
05235
05236 if (iaxdebug)
05237 ast_debug(1, "Indicating condition %d\n", condition);
05238
05239 ast_mutex_lock(&iaxsl[callno]);
05240 pvt = iaxs[callno];
05241
05242 if (wait_for_peercallno(pvt)) {
05243 res = -1;
05244 goto done;
05245 }
05246
05247 switch (condition) {
05248 case AST_CONTROL_HOLD:
05249 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05250 ast_moh_start(c, data, pvt->mohinterpret);
05251 goto done;
05252 }
05253 break;
05254 case AST_CONTROL_UNHOLD:
05255 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05256 ast_moh_stop(c);
05257 goto done;
05258 }
05259 }
05260
05261 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05262
05263 done:
05264 ast_mutex_unlock(&iaxsl[callno]);
05265
05266 return res;
05267 }
05268
05269 static int iax2_transfer(struct ast_channel *c, const char *dest)
05270 {
05271 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05272 struct iax_ie_data ied = { "", };
05273 char tmp[256], *context;
05274 ast_copy_string(tmp, dest, sizeof(tmp));
05275 context = strchr(tmp, '@');
05276 if (context) {
05277 *context = '\0';
05278 context++;
05279 }
05280 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05281 if (context)
05282 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05283 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05284 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05285 }
05286
05287 static int iax2_getpeertrunk(struct sockaddr_in sin)
05288 {
05289 struct iax2_peer *peer;
05290 int res = 0;
05291 struct ao2_iterator i;
05292
05293 i = ao2_iterator_init(peers, 0);
05294 while ((peer = ao2_iterator_next(&i))) {
05295 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05296 (peer->addr.sin_port == sin.sin_port)) {
05297 res = ast_test_flag(peer, IAX_TRUNK);
05298 peer_unref(peer);
05299 break;
05300 }
05301 peer_unref(peer);
05302 }
05303 ao2_iterator_destroy(&i);
05304
05305 return res;
05306 }
05307
05308
05309 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
05310 {
05311 struct ast_channel *tmp;
05312 struct chan_iax2_pvt *i;
05313 struct ast_variable *v = NULL;
05314
05315 if (!(i = iaxs[callno])) {
05316 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05317 return NULL;
05318 }
05319
05320
05321 ast_mutex_unlock(&iaxsl[callno]);
05322 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);
05323 ast_mutex_lock(&iaxsl[callno]);
05324 if (i != iaxs[callno]) {
05325 if (tmp) {
05326
05327 ast_mutex_unlock(&iaxsl[callno]);
05328 ast_channel_free(tmp);
05329 ast_mutex_lock(&iaxsl[callno]);
05330 }
05331 return NULL;
05332 }
05333 iax2_ami_channelupdate(i);
05334 if (!tmp)
05335 return NULL;
05336 tmp->tech = &iax2_tech;
05337
05338 tmp->nativeformats = capability;
05339 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05340 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05341 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05342
05343 if (!ast_strlen_zero(i->parkinglot))
05344 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05345
05346
05347 if (!ast_strlen_zero(i->ani))
05348 tmp->cid.cid_ani = ast_strdup(i->ani);
05349 else
05350 tmp->cid.cid_ani = ast_strdup(i->cid_num);
05351 tmp->cid.cid_dnid = ast_strdup(i->dnid);
05352 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05353 tmp->cid.cid_pres = i->calling_pres;
05354 tmp->cid.cid_ton = i->calling_ton;
05355 tmp->cid.cid_tns = i->calling_tns;
05356 if (!ast_strlen_zero(i->language))
05357 ast_string_field_set(tmp, language, i->language);
05358 if (!ast_strlen_zero(i->accountcode))
05359 ast_string_field_set(tmp, accountcode, i->accountcode);
05360 if (i->amaflags)
05361 tmp->amaflags = i->amaflags;
05362 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05363 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05364 if (i->adsi)
05365 tmp->adsicpe = i->peeradsicpe;
05366 else
05367 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05368 i->owner = tmp;
05369 i->capability = capability;
05370
05371
05372 if (i->vars) {
05373 for (v = i->vars ; v ; v = v->next)
05374 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05375 }
05376 if (i->iaxvars) {
05377 struct ast_datastore *variablestore;
05378 struct ast_variable *var, *prev = NULL;
05379 AST_LIST_HEAD(, ast_var_t) *varlist;
05380 ast_debug(1, "Loading up the channel with IAXVARs\n");
05381 varlist = ast_calloc(1, sizeof(*varlist));
05382 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05383 if (variablestore && varlist) {
05384 variablestore->data = varlist;
05385 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05386 AST_LIST_HEAD_INIT(varlist);
05387 for (var = i->iaxvars; var; var = var->next) {
05388 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05389 if (prev)
05390 ast_free(prev);
05391 prev = var;
05392 if (!newvar) {
05393
05394 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05395 } else {
05396 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05397 }
05398 }
05399 if (prev)
05400 ast_free(prev);
05401 i->iaxvars = NULL;
05402 ast_channel_datastore_add(i->owner, variablestore);
05403 } else {
05404 if (variablestore) {
05405 ast_datastore_free(variablestore);
05406 }
05407 if (varlist) {
05408 ast_free(varlist);
05409 }
05410 }
05411 }
05412
05413 if (state != AST_STATE_DOWN) {
05414 if (ast_pbx_start(tmp)) {
05415 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05416 ast_hangup(tmp);
05417 i->owner = NULL;
05418 return NULL;
05419 }
05420 }
05421
05422 ast_module_ref(ast_module_info->self);
05423 return tmp;
05424 }
05425
05426 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05427 {
05428 unsigned long int mssincetx;
05429 long int ms, pred;
05430
05431 tpeer->trunkact = *now;
05432 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05433 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05434
05435 tpeer->txtrunktime = *now;
05436 tpeer->lastsent = 999999;
05437 }
05438
05439 tpeer->lasttxtime = *now;
05440
05441
05442 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05443
05444 pred = tpeer->lastsent + sampms;
05445 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05446 ms = pred;
05447
05448
05449 if (ms == tpeer->lastsent)
05450 ms = tpeer->lastsent + 1;
05451 tpeer->lastsent = ms;
05452 return ms;
05453 }
05454
05455 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05456 {
05457 long ms;
05458 if (ast_tvzero(iaxs[callno]->rxcore)) {
05459
05460 iaxs[callno]->rxcore = ast_tvnow();
05461
05462 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05463 }
05464
05465 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05466
05467 return ms + ts;
05468 }
05469
05470 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05471 {
05472 int ms;
05473 int voice = 0;
05474 int genuine = 0;
05475 int adjust;
05476 int rate = ast_format_rate(f->subclass) / 1000;
05477 struct timeval *delivery = NULL;
05478
05479
05480
05481
05482
05483
05484
05485
05486 if (f) {
05487 if (f->frametype == AST_FRAME_VOICE) {
05488 voice = 1;
05489 delivery = &f->delivery;
05490 } else if (f->frametype == AST_FRAME_IAX) {
05491 genuine = 1;
05492 } else if (f->frametype == AST_FRAME_CNG) {
05493 p->notsilenttx = 0;
05494 }
05495 }
05496 if (ast_tvzero(p->offset)) {
05497 p->offset = ast_tvnow();
05498
05499 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05500 }
05501
05502 if (ts)
05503 return ts;
05504
05505 if (delivery && !ast_tvzero(*delivery)) {
05506 ms = ast_tvdiff_ms(*delivery, p->offset);
05507 if (ms < 0) {
05508 ms = 0;
05509 }
05510 if (iaxdebug)
05511 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05512 } else {
05513 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05514 if (ms < 0)
05515 ms = 0;
05516 if (voice) {
05517
05518 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05519
05520
05521
05522
05523
05524
05525
05526
05527
05528
05529
05530
05531
05532
05533
05534
05535
05536
05537 adjust = (ms - p->nextpred);
05538 if (adjust < 0)
05539 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05540 else if (adjust > 0)
05541 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05542
05543 if (!p->nextpred) {
05544 p->nextpred = ms;
05545 if (p->nextpred <= p->lastsent)
05546 p->nextpred = p->lastsent + 3;
05547 }
05548 ms = p->nextpred;
05549 } else {
05550
05551
05552
05553
05554
05555
05556
05557
05558
05559 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05560 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05561 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05562
05563 if (f->samples >= rate)
05564 {
05565 int diff = ms % (f->samples / rate);
05566 if (diff)
05567 ms += f->samples/rate - diff;
05568 }
05569
05570 p->nextpred = ms;
05571 p->notsilenttx = 1;
05572 }
05573 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05574
05575
05576
05577
05578
05579
05580
05581
05582 if ( (unsigned int)ms < p->lastsent )
05583 ms = p->lastsent;
05584 } else {
05585
05586
05587 if (genuine) {
05588
05589 if (ms <= p->lastsent)
05590 ms = p->lastsent + 3;
05591 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05592
05593 ms = p->lastsent + 3;
05594 }
05595 }
05596 }
05597 p->lastsent = ms;
05598 if (voice)
05599 p->nextpred = p->nextpred + f->samples / rate;
05600 return ms;
05601 }
05602
05603 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05604 {
05605
05606
05607 int ms;
05608 #ifdef IAXTESTS
05609 int jit;
05610 #endif
05611
05612 if (ast_tvzero(p->rxcore)) {
05613 p->rxcore = ast_tvnow();
05614 if (iaxdebug)
05615 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05616 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05617 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05618 #if 1
05619 if (iaxdebug)
05620 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05621 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05622 #endif
05623 }
05624
05625 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05626 #ifdef IAXTESTS
05627 if (test_jit) {
05628 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05629 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05630 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05631 jit = -jit;
05632 ms += jit;
05633 }
05634 }
05635 if (test_late) {
05636 ms += test_late;
05637 test_late = 0;
05638 }
05639 #endif
05640 return ms;
05641 }
05642
05643 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
05644 {
05645 struct iax2_trunk_peer *tpeer = NULL;
05646
05647
05648 AST_LIST_LOCK(&tpeers);
05649
05650 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
05651 if (!inaddrcmp(&tpeer->addr, sin)) {
05652 ast_mutex_lock(&tpeer->lock);
05653 break;
05654 }
05655 }
05656
05657 if (!tpeer) {
05658 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
05659 ast_mutex_init(&tpeer->lock);
05660 tpeer->lastsent = 9999;
05661 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
05662 tpeer->trunkact = ast_tvnow();
05663 ast_mutex_lock(&tpeer->lock);
05664 tpeer->sockfd = fd;
05665 #ifdef SO_NO_CHECK
05666 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
05667 #endif
05668 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05669 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
05670 }
05671 }
05672
05673 AST_LIST_UNLOCK(&tpeers);
05674
05675 return tpeer;
05676 }
05677
05678 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
05679 {
05680 struct ast_frame *f;
05681 struct iax2_trunk_peer *tpeer;
05682 void *tmp, *ptr;
05683 struct timeval now;
05684 int res;
05685 struct ast_iax2_meta_trunk_entry *met;
05686 struct ast_iax2_meta_trunk_mini *mtm;
05687
05688 f = &fr->af;
05689 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
05690 if (tpeer) {
05691 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
05692
05693 if (tpeer->trunkdataalloc < trunkmaxsize) {
05694 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
05695 ast_mutex_unlock(&tpeer->lock);
05696 return -1;
05697 }
05698
05699 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
05700 tpeer->trunkdata = tmp;
05701 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);
05702 } else {
05703 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));
05704 ast_mutex_unlock(&tpeer->lock);
05705 return -1;
05706 }
05707 }
05708
05709
05710 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
05711 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
05712 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
05713 mtm->len = htons(f->datalen);
05714 mtm->mini.callno = htons(pvt->callno);
05715 mtm->mini.ts = htons(0xffff & fr->ts);
05716 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
05717 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
05718 } else {
05719 met = (struct ast_iax2_meta_trunk_entry *)ptr;
05720
05721 met->callno = htons(pvt->callno);
05722 met->len = htons(f->datalen);
05723
05724 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
05725 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
05726 }
05727
05728 memcpy(ptr, f->data.ptr, f->datalen);
05729 tpeer->trunkdatalen += f->datalen;
05730
05731 tpeer->calls++;
05732
05733
05734 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
05735 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
05736
05737
05738 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
05739 now = ast_tvnow();
05740 res = send_trunk(tpeer, &now);
05741 trunk_untimed ++;
05742 }
05743
05744 ast_mutex_unlock(&tpeer->lock);
05745 }
05746 return 0;
05747 }
05748
05749
05750
05751 static void build_rand_pad(unsigned char *buf, ssize_t len)
05752 {
05753 long tmp;
05754 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05755 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05756 buf += sizeof(tmp);
05757 len -= sizeof(tmp);
05758 }
05759 }
05760
05761 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05762 {
05763 build_ecx_key(digest, pvt);
05764 ast_aes_decrypt_key(digest, &pvt->dcx);
05765 }
05766
05767 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05768 {
05769
05770
05771
05772 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05773 ast_aes_encrypt_key(digest, &pvt->ecx);
05774 ast_aes_decrypt_key(digest, &pvt->mydcx);
05775 }
05776
05777 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
05778 {
05779 #if 0
05780
05781 int x;
05782 if (len % 16)
05783 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05784 for (x=0;x<len;x++)
05785 dst[x] = src[x] ^ 0xff;
05786 #else
05787 unsigned char lastblock[16] = { 0 };
05788 int x;
05789 while(len > 0) {
05790 ast_aes_decrypt(src, dst, dcx);
05791 for (x=0;x<16;x++)
05792 dst[x] ^= lastblock[x];
05793 memcpy(lastblock, src, sizeof(lastblock));
05794 dst += 16;
05795 src += 16;
05796 len -= 16;
05797 }
05798 #endif
05799 }
05800
05801 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
05802 {
05803 #if 0
05804
05805 int x;
05806 if (len % 16)
05807 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05808 for (x=0;x<len;x++)
05809 dst[x] = src[x] ^ 0xff;
05810 #else
05811 unsigned char curblock[16] = { 0 };
05812 int x;
05813 while(len > 0) {
05814 for (x=0;x<16;x++)
05815 curblock[x] ^= src[x];
05816 ast_aes_encrypt(curblock, dst, ecx);
05817 memcpy(curblock, dst, sizeof(curblock));
05818 dst += 16;
05819 src += 16;
05820 len -= 16;
05821 }
05822 #endif
05823 }
05824
05825 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05826 {
05827 int padding;
05828 unsigned char *workspace;
05829
05830 workspace = alloca(*datalen);
05831 memset(f, 0, sizeof(*f));
05832 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05833 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05834 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
05835 return -1;
05836
05837 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
05838
05839 padding = 16 + (workspace[15] & 0x0f);
05840 if (iaxdebug)
05841 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
05842 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
05843 return -1;
05844
05845 *datalen -= padding;
05846 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05847 f->frametype = fh->type;
05848 if (f->frametype == AST_FRAME_VIDEO) {
05849 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
05850 } else {
05851 f->subclass = uncompress_subclass(fh->csub);
05852 }
05853 } else {
05854 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05855 if (iaxdebug)
05856 ast_debug(1, "Decoding mini with length %d\n", *datalen);
05857 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
05858 return -1;
05859
05860 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
05861 padding = 16 + (workspace[15] & 0x0f);
05862 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
05863 return -1;
05864 *datalen -= padding;
05865 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05866 }
05867 return 0;
05868 }
05869
05870 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
05871 {
05872 int padding;
05873 unsigned char *workspace;
05874 workspace = alloca(*datalen + 32);
05875 if (!workspace)
05876 return -1;
05877 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05878 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05879 if (iaxdebug)
05880 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
05881 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
05882 padding = 16 + (padding & 0xf);
05883 memcpy(workspace, poo, padding);
05884 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05885 workspace[15] &= 0xf0;
05886 workspace[15] |= (padding & 0xf);
05887 if (iaxdebug)
05888 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
05889 *datalen += padding;
05890 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
05891 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
05892 memcpy(poo, workspace + *datalen - 32, 32);
05893 } else {
05894 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05895 if (iaxdebug)
05896 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
05897 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
05898 padding = 16 + (padding & 0xf);
05899 memcpy(workspace, poo, padding);
05900 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05901 workspace[15] &= 0xf0;
05902 workspace[15] |= (padding & 0x0f);
05903 *datalen += padding;
05904 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
05905 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
05906 memcpy(poo, workspace + *datalen - 32, 32);
05907 }
05908 return 0;
05909 }
05910
05911 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05912 {
05913 int res=-1;
05914 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
05915
05916 struct MD5Context md5;
05917 unsigned char digest[16];
05918 char *tmppw, *stringp;
05919
05920 tmppw = ast_strdupa(iaxs[callno]->secret);
05921 stringp = tmppw;
05922 while ((tmppw = strsep(&stringp, ";"))) {
05923 MD5Init(&md5);
05924 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05925 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05926 MD5Final(digest, &md5);
05927 build_encryption_keys(digest, iaxs[callno]);
05928 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05929 if (!res) {
05930 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
05931 break;
05932 }
05933 }
05934 } else
05935 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05936 return res;
05937 }
05938
05939 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
05940 {
05941
05942
05943
05944 struct ast_iax2_full_hdr *fh;
05945 struct ast_iax2_mini_hdr *mh;
05946 struct ast_iax2_video_hdr *vh;
05947 struct {
05948 struct iax_frame fr2;
05949 unsigned char buffer[4096];
05950 } frb;
05951 struct iax_frame *fr;
05952 int res;
05953 int sendmini=0;
05954 unsigned int lastsent;
05955 unsigned int fts;
05956
05957 frb.fr2.afdatalen = sizeof(frb.buffer);
05958
05959 if (!pvt) {
05960 ast_log(LOG_WARNING, "No private structure for packet?\n");
05961 return -1;
05962 }
05963
05964 lastsent = pvt->lastsent;
05965
05966
05967 fts = calc_timestamp(pvt, ts, f);
05968
05969
05970
05971
05972 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
05973 return 0;
05974 #if 0
05975 ast_log(LOG_NOTICE,
05976 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
05977 *("=!" + (f->frametype == AST_FRAME_VOICE)),
05978 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
05979 pvt->keyrotateid != -1 ? "" : "no "
05980 );
05981 #endif
05982 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
05983 iax2_key_rotate(pvt);
05984 }
05985
05986 if ((ast_test_flag(pvt, IAX_TRUNK) ||
05987 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
05988 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
05989 &&
05990 (f->frametype == AST_FRAME_VOICE)
05991 &&
05992 (f->subclass == pvt->svoiceformat)
05993 ) {
05994
05995 now = 1;
05996
05997 sendmini = 1;
05998 }
05999 if ( f->frametype == AST_FRAME_VIDEO ) {
06000
06001
06002
06003
06004
06005 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06006 ((f->subclass & ~0x1) == pvt->svideoformat)
06007 ) {
06008 now = 1;
06009 sendmini = 1;
06010 } else {
06011 now = 0;
06012 sendmini = 0;
06013 }
06014 pvt->lastvsent = fts;
06015 }
06016 if (f->frametype == AST_FRAME_IAX) {
06017
06018 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
06019 if (!pvt->first_iax_message) {
06020 pvt->first_iax_message = pvt->last_iax_message;
06021 }
06022 }
06023
06024 if (now) {
06025 fr = &frb.fr2;
06026 } else
06027 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));
06028 if (!fr) {
06029 ast_log(LOG_WARNING, "Out of memory\n");
06030 return -1;
06031 }
06032
06033 iax_frame_wrap(fr, f);
06034
06035 fr->ts = fts;
06036 fr->callno = pvt->callno;
06037 fr->transfer = transfer;
06038 fr->final = final;
06039 fr->encmethods = 0;
06040 if (!sendmini) {
06041
06042 if (seqno > -1)
06043 fr->oseqno = seqno;
06044 else
06045 fr->oseqno = pvt->oseqno++;
06046 fr->iseqno = pvt->iseqno;
06047 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06048 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06049 fh->ts = htonl(fr->ts);
06050 fh->oseqno = fr->oseqno;
06051 if (transfer) {
06052 fh->iseqno = 0;
06053 } else
06054 fh->iseqno = fr->iseqno;
06055
06056 if (!transfer)
06057 pvt->aseqno = fr->iseqno;
06058 fh->type = fr->af.frametype & 0xFF;
06059 if (fr->af.frametype == AST_FRAME_VIDEO)
06060 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
06061 else
06062 fh->csub = compress_subclass(fr->af.subclass);
06063 if (transfer) {
06064 fr->dcallno = pvt->transfercallno;
06065 } else
06066 fr->dcallno = pvt->peercallno;
06067 fh->dcallno = htons(fr->dcallno);
06068 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06069 fr->data = fh;
06070 fr->retries = 0;
06071
06072 fr->retrytime = pvt->pingtime * 2;
06073 if (fr->retrytime < MIN_RETRY_TIME)
06074 fr->retrytime = MIN_RETRY_TIME;
06075 if (fr->retrytime > MAX_RETRY_TIME)
06076 fr->retrytime = MAX_RETRY_TIME;
06077
06078 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
06079 fr->retries = -1;
06080 else if (f->frametype == AST_FRAME_VOICE)
06081 pvt->svoiceformat = f->subclass;
06082 else if (f->frametype == AST_FRAME_VIDEO)
06083 pvt->svideoformat = f->subclass & ~0x1;
06084 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06085 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06086 if (fr->transfer)
06087 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06088 else
06089 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06090 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06091 fr->encmethods = pvt->encmethods;
06092 fr->ecx = pvt->ecx;
06093 fr->mydcx = pvt->mydcx;
06094 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06095 } else
06096 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06097 }
06098
06099 if (now) {
06100 res = send_packet(fr);
06101 } else
06102 res = iax2_transmit(fr);
06103 } else {
06104 if (ast_test_flag(pvt, IAX_TRUNK)) {
06105 iax2_trunk_queue(pvt, fr);
06106 res = 0;
06107 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06108
06109 fr->oseqno = -1;
06110 fr->iseqno = -1;
06111 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06112 vh->zeros = 0;
06113 vh->callno = htons(0x8000 | fr->callno);
06114 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
06115 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06116 fr->data = vh;
06117 fr->retries = -1;
06118 res = send_packet(fr);
06119 } else {
06120
06121 fr->oseqno = -1;
06122 fr->iseqno = -1;
06123
06124 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06125 mh->callno = htons(fr->callno);
06126 mh->ts = htons(fr->ts & 0xFFFF);
06127 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06128 fr->data = mh;
06129 fr->retries = -1;
06130 if (pvt->transferring == TRANSFER_MEDIAPASS)
06131 fr->transfer = 1;
06132 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06133 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06134 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06135 } else
06136 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06137 }
06138 res = send_packet(fr);
06139 }
06140 }
06141 return res;
06142 }
06143
06144 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06145 {
06146 regex_t regexbuf;
06147 int havepattern = 0;
06148
06149 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06150 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06151
06152 struct iax2_user *user = NULL;
06153 char auth[90];
06154 char *pstr = "";
06155 struct ao2_iterator i;
06156
06157 switch (cmd) {
06158 case CLI_INIT:
06159 e->command = "iax2 show users [like]";
06160 e->usage =
06161 "Usage: iax2 show users [like <pattern>]\n"
06162 " Lists all known IAX2 users.\n"
06163 " Optional regular expression pattern is used to filter the user list.\n";
06164 return NULL;
06165 case CLI_GENERATE:
06166 return NULL;
06167 }
06168
06169 switch (a->argc) {
06170 case 5:
06171 if (!strcasecmp(a->argv[3], "like")) {
06172 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06173 return CLI_SHOWUSAGE;
06174 havepattern = 1;
06175 } else
06176 return CLI_SHOWUSAGE;
06177 case 3:
06178 break;
06179 default:
06180 return CLI_SHOWUSAGE;
06181 }
06182
06183 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06184 i = ao2_iterator_init(users, 0);
06185 for (user = ao2_iterator_next(&i); user;
06186 user_unref(user), user = ao2_iterator_next(&i)) {
06187 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06188 continue;
06189
06190 if (!ast_strlen_zero(user->secret)) {
06191 ast_copy_string(auth,user->secret, sizeof(auth));
06192 } else if (!ast_strlen_zero(user->inkeys)) {
06193 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06194 } else
06195 ast_copy_string(auth, "-no secret-", sizeof(auth));
06196
06197 if(ast_test_flag(user,IAX_CODEC_NOCAP))
06198 pstr = "REQ Only";
06199 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
06200 pstr = "Disabled";
06201 else
06202 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06203
06204 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06205 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06206 user->ha ? "Yes" : "No", pstr);
06207 }
06208 ao2_iterator_destroy(&i);
06209
06210 if (havepattern)
06211 regfree(®exbuf);
06212
06213 return CLI_SUCCESS;
06214 #undef FORMAT
06215 #undef FORMAT2
06216 }
06217
06218 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
06219 {
06220 regex_t regexbuf;
06221 int havepattern = 0;
06222 int total_peers = 0;
06223 int online_peers = 0;
06224 int offline_peers = 0;
06225 int unmonitored_peers = 0;
06226 struct ao2_iterator i;
06227
06228 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
06229 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
06230
06231 struct iax2_peer *peer = NULL;
06232 char name[256];
06233 int registeredonly=0;
06234 char *term = manager ? "\r\n" : "\n";
06235 char idtext[256] = "";
06236 switch (argc) {
06237 case 6:
06238 if (!strcasecmp(argv[3], "registered"))
06239 registeredonly = 1;
06240 else
06241 return RESULT_SHOWUSAGE;
06242 if (!strcasecmp(argv[4], "like")) {
06243 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06244 return RESULT_SHOWUSAGE;
06245 havepattern = 1;
06246 } else
06247 return RESULT_SHOWUSAGE;
06248 break;
06249 case 5:
06250 if (!strcasecmp(argv[3], "like")) {
06251 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06252 return RESULT_SHOWUSAGE;
06253 havepattern = 1;
06254 } else
06255 return RESULT_SHOWUSAGE;
06256 break;
06257 case 4:
06258 if (!strcasecmp(argv[3], "registered"))
06259 registeredonly = 1;
06260 else
06261 return RESULT_SHOWUSAGE;
06262 break;
06263 case 3:
06264 break;
06265 default:
06266 return RESULT_SHOWUSAGE;
06267 }
06268
06269
06270 if (!s)
06271 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
06272
06273 i = ao2_iterator_init(peers, 0);
06274 for (peer = ao2_iterator_next(&i); peer;
06275 peer_unref(peer), peer = ao2_iterator_next(&i)) {
06276 char nm[20];
06277 char status[20];
06278 char srch[2000];
06279 int retstatus;
06280
06281 if (registeredonly && !peer->addr.sin_addr.s_addr)
06282 continue;
06283 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
06284 continue;
06285
06286 if (!ast_strlen_zero(peer->username))
06287 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06288 else
06289 ast_copy_string(name, peer->name, sizeof(name));
06290
06291 retstatus = peer_status(peer, status, sizeof(status));
06292 if (retstatus > 0)
06293 online_peers++;
06294 else if (!retstatus)
06295 offline_peers++;
06296 else
06297 unmonitored_peers++;
06298
06299 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06300
06301 snprintf(srch, sizeof(srch), FORMAT, name,
06302 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06303 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06304 nm,
06305 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
06306 peer->encmethods ? "(E)" : " ", status, term);
06307
06308 if (s)
06309 astman_append(s,
06310 "Event: PeerEntry\r\n%s"
06311 "Channeltype: IAX2\r\n"
06312 "ChanObjectType: peer\r\n"
06313 "ObjectName: %s\r\n"
06314 "IPaddress: %s\r\n"
06315 "IPport: %d\r\n"
06316 "Dynamic: %s\r\n"
06317 "Status: %s\r\n\r\n",
06318 idtext,
06319 name,
06320 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
06321 ntohs(peer->addr.sin_port),
06322 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
06323 status);
06324
06325 else
06326 ast_cli(fd, FORMAT, name,
06327 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06328 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06329 nm,
06330 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
06331 peer->encmethods ? "(E)" : " ", status, term);
06332 total_peers++;
06333 }
06334 ao2_iterator_destroy(&i);
06335
06336 if (!s)
06337 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
06338
06339 if (havepattern)
06340 regfree(®exbuf);
06341
06342 return RESULT_SUCCESS;
06343 #undef FORMAT
06344 #undef FORMAT2
06345 }
06346
06347 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06348 {
06349 struct iax2_thread *thread = NULL;
06350 time_t t;
06351 int threadcount = 0, dynamiccount = 0;
06352 char type;
06353
06354 switch (cmd) {
06355 case CLI_INIT:
06356 e->command = "iax2 show threads";
06357 e->usage =
06358 "Usage: iax2 show threads\n"
06359 " Lists status of IAX helper threads\n";
06360 return NULL;
06361 case CLI_GENERATE:
06362 return NULL;
06363 }
06364 if (a->argc != 3)
06365 return CLI_SHOWUSAGE;
06366
06367 ast_cli(a->fd, "IAX2 Thread Information\n");
06368 time(&t);
06369 ast_cli(a->fd, "Idle Threads:\n");
06370 AST_LIST_LOCK(&idle_list);
06371 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06372 #ifdef DEBUG_SCHED_MULTITHREAD
06373 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06374 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06375 #else
06376 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06377 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06378 #endif
06379 threadcount++;
06380 }
06381 AST_LIST_UNLOCK(&idle_list);
06382 ast_cli(a->fd, "Active Threads:\n");
06383 AST_LIST_LOCK(&active_list);
06384 AST_LIST_TRAVERSE(&active_list, thread, list) {
06385 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06386 type = 'D';
06387 else
06388 type = 'P';
06389 #ifdef DEBUG_SCHED_MULTITHREAD
06390 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06391 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06392 #else
06393 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06394 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06395 #endif
06396 threadcount++;
06397 }
06398 AST_LIST_UNLOCK(&active_list);
06399 ast_cli(a->fd, "Dynamic Threads:\n");
06400 AST_LIST_LOCK(&dynamic_list);
06401 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06402 #ifdef DEBUG_SCHED_MULTITHREAD
06403 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06404 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06405 #else
06406 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06407 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06408 #endif
06409 dynamiccount++;
06410 }
06411 AST_LIST_UNLOCK(&dynamic_list);
06412 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06413 return CLI_SUCCESS;
06414 }
06415
06416 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06417 {
06418 struct iax2_peer *p;
06419
06420 switch (cmd) {
06421 case CLI_INIT:
06422 e->command = "iax2 unregister";
06423 e->usage =
06424 "Usage: iax2 unregister <peername>\n"
06425 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06426 return NULL;
06427 case CLI_GENERATE:
06428 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06429 }
06430
06431 if (a->argc != 3)
06432 return CLI_SHOWUSAGE;
06433
06434 p = find_peer(a->argv[2], 1);
06435 if (p) {
06436 if (p->expire > 0) {
06437 struct iax2_peer tmp_peer = {
06438 .name = a->argv[2],
06439 };
06440 struct iax2_peer *peer;
06441
06442 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06443 if (peer) {
06444 expire_registry(peer_ref(peer));
06445 peer_unref(peer);
06446 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06447 } else {
06448 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06449 }
06450 } else {
06451 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06452 }
06453 } else {
06454 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06455 }
06456 return CLI_SUCCESS;
06457 }
06458
06459 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06460 {
06461 int which = 0;
06462 struct iax2_peer *p = NULL;
06463 char *res = NULL;
06464 int wordlen = strlen(word);
06465
06466
06467 if (pos == 2) {
06468 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06469 while ((p = ao2_iterator_next(&i))) {
06470 if (!strncasecmp(p->name, word, wordlen) &&
06471 ++which > state && p->expire > 0) {
06472 res = ast_strdup(p->name);
06473 peer_unref(p);
06474 break;
06475 }
06476 peer_unref(p);
06477 }
06478 ao2_iterator_destroy(&i);
06479 }
06480
06481 return res;
06482 }
06483
06484 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06485 {
06486 switch (cmd) {
06487 case CLI_INIT:
06488 e->command = "iax2 show peers";
06489 e->usage =
06490 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06491 " Lists all known IAX2 peers.\n"
06492 " Optional 'registered' argument lists only peers with known addresses.\n"
06493 " Optional regular expression pattern is used to filter the peer list.\n";
06494 return NULL;
06495 case CLI_GENERATE:
06496 return NULL;
06497 }
06498
06499 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
06500 case RESULT_SHOWUSAGE:
06501 return CLI_SHOWUSAGE;
06502 case RESULT_FAILURE:
06503 return CLI_FAILURE;
06504 default:
06505 return CLI_SUCCESS;
06506 }
06507 }
06508
06509 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06510 {
06511 ast_cli_netstats(s, -1, 0);
06512 astman_append(s, "\r\n");
06513 return RESULT_SUCCESS;
06514 }
06515
06516 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06517 {
06518 struct iax_firmware *cur = NULL;
06519
06520 switch (cmd) {
06521 case CLI_INIT:
06522 e->command = "iax2 show firmware";
06523 e->usage =
06524 "Usage: iax2 show firmware\n"
06525 " Lists all known IAX firmware images.\n";
06526 return NULL;
06527 case CLI_GENERATE:
06528 return NULL;
06529 }
06530
06531 if (a->argc != 3 && a->argc != 4)
06532 return CLI_SHOWUSAGE;
06533
06534 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06535 AST_LIST_LOCK(&firmwares);
06536 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06537 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06538 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06539 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06540 }
06541 }
06542 AST_LIST_UNLOCK(&firmwares);
06543
06544 return CLI_SUCCESS;
06545 }
06546
06547
06548 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06549 {
06550 char *a[] = { "iax2", "show", "users" };
06551 const char *id = astman_get_header(m,"ActionID");
06552 char idtext[256] = "";
06553
06554 if (!ast_strlen_zero(id))
06555 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06556 astman_send_ack(s, m, "Peer status list will follow");
06557 return __iax2_show_peers(1, -1, s, 3, a );
06558 }
06559
06560
06561 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06562 {
06563 struct iax2_peer *peer = NULL;
06564 int peer_count = 0;
06565 char nm[20];
06566 char status[20];
06567 const char *id = astman_get_header(m,"ActionID");
06568 char idtext[256] = "";
06569 struct ao2_iterator i;
06570
06571 if (!ast_strlen_zero(id))
06572 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06573
06574 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06575
06576
06577 i = ao2_iterator_init(peers, 0);
06578 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06579
06580 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06581 if (!ast_strlen_zero(peer->username)) {
06582 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06583 } else {
06584 astman_append(s, "ObjectName: %s\r\n", peer->name);
06585 }
06586 astman_append(s, "ChanObjectType: peer\r\n");
06587 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
06588 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06589 astman_append(s, "Mask: %s\r\n", nm);
06590 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
06591 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
06592 peer_status(peer, status, sizeof(status));
06593 astman_append(s, "Status: %s\r\n\r\n", status);
06594 peer_count++;
06595 }
06596 ao2_iterator_destroy(&i);
06597
06598 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
06599 return RESULT_SUCCESS;
06600 }
06601
06602
06603 static char *regstate2str(int regstate)
06604 {
06605 switch(regstate) {
06606 case REG_STATE_UNREGISTERED:
06607 return "Unregistered";
06608 case REG_STATE_REGSENT:
06609 return "Request Sent";
06610 case REG_STATE_AUTHSENT:
06611 return "Auth. Sent";
06612 case REG_STATE_REGISTERED:
06613 return "Registered";
06614 case REG_STATE_REJECTED:
06615 return "Rejected";
06616 case REG_STATE_TIMEOUT:
06617 return "Timeout";
06618 case REG_STATE_NOAUTH:
06619 return "No Authentication";
06620 default:
06621 return "Unknown";
06622 }
06623 }
06624
06625 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06626 {
06627 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
06628 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
06629 struct iax2_registry *reg = NULL;
06630 char host[80];
06631 char perceived[80];
06632 int counter = 0;
06633
06634 switch (cmd) {
06635 case CLI_INIT:
06636 e->command = "iax2 show registry";
06637 e->usage =
06638 "Usage: iax2 show registry\n"
06639 " Lists all registration requests and status.\n";
06640 return NULL;
06641 case CLI_GENERATE:
06642 return NULL;
06643 }
06644 if (a->argc != 3)
06645 return CLI_SHOWUSAGE;
06646 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
06647 AST_LIST_LOCK(®istrations);
06648 AST_LIST_TRAVERSE(®istrations, reg, entry) {
06649 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06650 if (reg->us.sin_addr.s_addr)
06651 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06652 else
06653 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06654 ast_cli(a->fd, FORMAT, host,
06655 (reg->dnsmgr) ? "Y" : "N",
06656 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
06657 counter++;
06658 }
06659 AST_LIST_UNLOCK(®istrations);
06660 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
06661 return CLI_SUCCESS;
06662 #undef FORMAT
06663 #undef FORMAT2
06664 }
06665
06666 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06667 {
06668 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
06669 #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"
06670 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
06671 int x;
06672 int numchans = 0;
06673 char first_message[10] = { 0, };
06674 char last_message[10] = { 0, };
06675
06676 switch (cmd) {
06677 case CLI_INIT:
06678 e->command = "iax2 show channels";
06679 e->usage =
06680 "Usage: iax2 show channels\n"
06681 " Lists all currently active IAX channels.\n";
06682 return NULL;
06683 case CLI_GENERATE:
06684 return NULL;
06685 }
06686
06687 if (a->argc != 3)
06688 return CLI_SHOWUSAGE;
06689 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
06690 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06691 ast_mutex_lock(&iaxsl[x]);
06692 if (iaxs[x]) {
06693 int lag, jitter, localdelay;
06694 jb_info jbinfo;
06695 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06696 jb_getinfo(iaxs[x]->jb, &jbinfo);
06697 jitter = jbinfo.jitter;
06698 localdelay = jbinfo.current - jbinfo.min;
06699 } else {
06700 jitter = -1;
06701 localdelay = 0;
06702 }
06703
06704 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06705 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06706 lag = iaxs[x]->remote_rr.delay;
06707 ast_cli(a->fd, FORMAT,
06708 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06709 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
06710 S_OR(iaxs[x]->username, "(None)"),
06711 iaxs[x]->callno, iaxs[x]->peercallno,
06712 iaxs[x]->oseqno, iaxs[x]->iseqno,
06713 lag,
06714 jitter,
06715 localdelay,
06716 ast_getformatname(iaxs[x]->voiceformat),
06717 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06718 first_message,
06719 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06720 last_message);
06721 numchans++;
06722 }
06723 ast_mutex_unlock(&iaxsl[x]);
06724 }
06725 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06726 return CLI_SUCCESS;
06727 #undef FORMAT
06728 #undef FORMAT2
06729 #undef FORMATB
06730 }
06731
06732 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
06733 {
06734 int x;
06735 int numchans = 0;
06736 char first_message[10] = { 0, };
06737 char last_message[10] = { 0, };
06738 #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"
06739 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
06740 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06741 ast_mutex_lock(&iaxsl[x]);
06742 if (iaxs[x]) {
06743 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06744 jb_info jbinfo;
06745 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06746 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06747
06748 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06749 jb_getinfo(iaxs[x]->jb, &jbinfo);
06750 localjitter = jbinfo.jitter;
06751 localdelay = jbinfo.current - jbinfo.min;
06752 locallost = jbinfo.frames_lost;
06753 locallosspct = jbinfo.losspct/1000;
06754 localdropped = jbinfo.frames_dropped;
06755 localooo = jbinfo.frames_ooo;
06756 } else {
06757 localjitter = -1;
06758 localdelay = 0;
06759 locallost = -1;
06760 locallosspct = -1;
06761 localdropped = 0;
06762 localooo = -1;
06763 }
06764 if (s)
06765 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06766 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06767 iaxs[x]->pingtime,
06768 localjitter,
06769 localdelay,
06770 locallost,
06771 locallosspct,
06772 localdropped,
06773 localooo,
06774 iaxs[x]->frames_received/1000,
06775 iaxs[x]->remote_rr.jitter,
06776 iaxs[x]->remote_rr.delay,
06777 iaxs[x]->remote_rr.losscnt,
06778 iaxs[x]->remote_rr.losspct,
06779 iaxs[x]->remote_rr.dropped,
06780 iaxs[x]->remote_rr.ooo,
06781 iaxs[x]->remote_rr.packets/1000,
06782 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06783 first_message,
06784 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06785 last_message);
06786 else
06787 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06788 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06789 iaxs[x]->pingtime,
06790 localjitter,
06791 localdelay,
06792 locallost,
06793 locallosspct,
06794 localdropped,
06795 localooo,
06796 iaxs[x]->frames_received/1000,
06797 iaxs[x]->remote_rr.jitter,
06798 iaxs[x]->remote_rr.delay,
06799 iaxs[x]->remote_rr.losscnt,
06800 iaxs[x]->remote_rr.losspct,
06801 iaxs[x]->remote_rr.dropped,
06802 iaxs[x]->remote_rr.ooo,
06803 iaxs[x]->remote_rr.packets/1000,
06804 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06805 first_message,
06806 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06807 last_message);
06808 numchans++;
06809 }
06810 ast_mutex_unlock(&iaxsl[x]);
06811 }
06812
06813 return numchans;
06814 }
06815
06816 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06817 {
06818 int numchans = 0;
06819
06820 switch (cmd) {
06821 case CLI_INIT:
06822 e->command = "iax2 show netstats";
06823 e->usage =
06824 "Usage: iax2 show netstats\n"
06825 " Lists network status for all currently active IAX channels.\n";
06826 return NULL;
06827 case CLI_GENERATE:
06828 return NULL;
06829 }
06830 if (a->argc != 3)
06831 return CLI_SHOWUSAGE;
06832 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
06833 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
06834 numchans = ast_cli_netstats(NULL, a->fd, 1);
06835 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06836 return CLI_SUCCESS;
06837 }
06838
06839 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06840 {
06841 switch (cmd) {
06842 case CLI_INIT:
06843 e->command = "iax2 set debug {on|off|peer}";
06844 e->usage =
06845 "Usage: iax2 set debug {on|off|peer peername}\n"
06846 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
06847 return NULL;
06848 case CLI_GENERATE:
06849 if (a->pos == 4)
06850 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
06851 return NULL;
06852 }
06853
06854 if (a->argc < e->args || a->argc > e->args + 1)
06855 return CLI_SHOWUSAGE;
06856
06857 if (!strcasecmp(a->argv[3], "peer")) {
06858 struct iax2_peer *peer;
06859
06860 if (a->argc != e->args + 1)
06861 return CLI_SHOWUSAGE;
06862
06863 peer = find_peer(a->argv[4], 1);
06864
06865 if (!peer) {
06866 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
06867 return CLI_FAILURE;
06868 }
06869
06870 debugaddr.sin_addr = peer->addr.sin_addr;
06871 debugaddr.sin_port = peer->addr.sin_port;
06872
06873 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
06874 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
06875
06876 ao2_ref(peer, -1);
06877 } else if (!strncasecmp(a->argv[3], "on", 2)) {
06878 iaxdebug = 1;
06879 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
06880 } else {
06881 iaxdebug = 0;
06882 memset(&debugaddr, 0, sizeof(debugaddr));
06883 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
06884 }
06885 return CLI_SUCCESS;
06886 }
06887
06888 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06889 {
06890 switch (cmd) {
06891 case CLI_INIT:
06892 e->command = "iax2 set debug trunk {on|off}";
06893 e->usage =
06894 "Usage: iax2 set debug trunk {on|off}\n"
06895 " Enables/Disables debugging of IAX trunking\n";
06896 return NULL;
06897 case CLI_GENERATE:
06898 return NULL;
06899 }
06900
06901 if (a->argc != e->args)
06902 return CLI_SHOWUSAGE;
06903
06904 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
06905 iaxtrunkdebug = 1;
06906 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
06907 } else {
06908 iaxtrunkdebug = 0;
06909 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
06910 }
06911 return CLI_SUCCESS;
06912 }
06913
06914 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06915 {
06916 switch (cmd) {
06917 case CLI_INIT:
06918 e->command = "iax2 set debug jb {on|off}";
06919 e->usage =
06920 "Usage: iax2 set debug jb {on|off}\n"
06921 " Enables/Disables jitterbuffer debugging information\n";
06922 return NULL;
06923 case CLI_GENERATE:
06924 return NULL;
06925 }
06926
06927 if (a->argc != e->args)
06928 return CLI_SHOWUSAGE;
06929
06930 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
06931 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
06932 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
06933 } else {
06934 jb_setoutput(jb_error_output, jb_warning_output, NULL);
06935 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
06936 }
06937 return CLI_SUCCESS;
06938 }
06939
06940 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
06941 {
06942 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
06943 int res = -1;
06944 ast_mutex_lock(&iaxsl[callno]);
06945 if (iaxs[callno]) {
06946
06947 if (!iaxs[callno]->error) {
06948 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
06949 res = 0;
06950
06951 else if (f->frametype == AST_FRAME_NULL)
06952 res = 0;
06953 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
06954 res = 0;
06955 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
06956 res = 0;
06957 else
06958
06959 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
06960 } else {
06961 ast_debug(1, "Write error: %s\n", strerror(errno));
06962 }
06963 }
06964
06965 ast_mutex_unlock(&iaxsl[callno]);
06966 return res;
06967 }
06968
06969 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
06970 int now, int transfer, int final)
06971 {
06972 struct ast_frame f = { 0, };
06973 int res = 0;
06974
06975 f.frametype = type;
06976 f.subclass = command;
06977 f.datalen = datalen;
06978 f.src = __FUNCTION__;
06979 f.data.ptr = (void *) data;
06980
06981 if ((res = queue_signalling(i, &f)) <= 0) {
06982 return res;
06983 }
06984
06985 return iax2_send(i, &f, ts, seqno, now, transfer, final);
06986 }
06987
06988 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
06989 {
06990 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
06991 }
06992
06993 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
06994 {
06995 int res;
06996 ast_mutex_lock(&iaxsl[callno]);
06997 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
06998 ast_mutex_unlock(&iaxsl[callno]);
06999 return res;
07000 }
07001
07002
07003
07004
07005
07006
07007 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)
07008 {
07009 int call_num = i->callno;
07010
07011 iax2_predestroy(i->callno);
07012 if (!iaxs[call_num])
07013 return -1;
07014 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07015 }
07016
07017 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)
07018 {
07019 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07020 }
07021
07022 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07023 {
07024 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07025 }
07026
07027 static int apply_context(struct iax2_context *con, const char *context)
07028 {
07029 while(con) {
07030 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07031 return -1;
07032 con = con->next;
07033 }
07034 return 0;
07035 }
07036
07037
07038 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07039 {
07040
07041 int res = -1;
07042 int version = 2;
07043 struct iax2_user *user = NULL, *best = NULL;
07044 int bestscore = 0;
07045 int gotcapability = 0;
07046 struct ast_variable *v = NULL, *tmpvar = NULL;
07047 struct ao2_iterator i;
07048
07049 if (!iaxs[callno])
07050 return res;
07051 if (ies->called_number)
07052 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07053 if (ies->calling_number) {
07054 if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) {
07055 ast_shrink_phone_number(ies->calling_number);
07056 }
07057 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07058 }
07059 if (ies->calling_name)
07060 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07061 if (ies->calling_ani)
07062 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07063 if (ies->dnid)
07064 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07065 if (ies->rdnis)
07066 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07067 if (ies->called_context)
07068 ast_string_field_set(iaxs[callno], context, ies->called_context);
07069 if (ies->language)
07070 ast_string_field_set(iaxs[callno], language, ies->language);
07071 if (ies->username)
07072 ast_string_field_set(iaxs[callno], username, ies->username);
07073 if (ies->calling_ton > -1)
07074 iaxs[callno]->calling_ton = ies->calling_ton;
07075 if (ies->calling_tns > -1)
07076 iaxs[callno]->calling_tns = ies->calling_tns;
07077 if (ies->calling_pres > -1)
07078 iaxs[callno]->calling_pres = ies->calling_pres;
07079 if (ies->format)
07080 iaxs[callno]->peerformat = ies->format;
07081 if (ies->adsicpe)
07082 iaxs[callno]->peeradsicpe = ies->adsicpe;
07083 if (ies->capability) {
07084 gotcapability = 1;
07085 iaxs[callno]->peercapability = ies->capability;
07086 }
07087 if (ies->version)
07088 version = ies->version;
07089
07090
07091 if(ies->codec_prefs) {
07092 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07093 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07094 }
07095
07096 if (!gotcapability)
07097 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07098 if (version > IAX_PROTO_VERSION) {
07099 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07100 ast_inet_ntoa(sin->sin_addr), version);
07101 return res;
07102 }
07103
07104 i = ao2_iterator_init(users, 0);
07105 while ((user = ao2_iterator_next(&i))) {
07106 if ((ast_strlen_zero(iaxs[callno]->username) ||
07107 !strcmp(iaxs[callno]->username, user->name))
07108 && ast_apply_ha(user->ha, sin)
07109 && (ast_strlen_zero(iaxs[callno]->context) ||
07110 apply_context(user->contexts, iaxs[callno]->context))) {
07111 if (!ast_strlen_zero(iaxs[callno]->username)) {
07112
07113 if (best)
07114 user_unref(best);
07115 best = user;
07116 break;
07117 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07118
07119 if (user->ha) {
07120
07121 if (bestscore < 4) {
07122 bestscore = 4;
07123 if (best)
07124 user_unref(best);
07125 best = user;
07126 continue;
07127 }
07128 } else {
07129
07130 if (bestscore < 3) {
07131 bestscore = 3;
07132 if (best)
07133 user_unref(best);
07134 best = user;
07135 continue;
07136 }
07137 }
07138 } else {
07139 if (user->ha) {
07140
07141 if (bestscore < 2) {
07142 bestscore = 2;
07143 if (best)
07144 user_unref(best);
07145 best = user;
07146 continue;
07147 }
07148 } else {
07149
07150 if (bestscore < 1) {
07151 bestscore = 1;
07152 if (best)
07153 user_unref(best);
07154 best = user;
07155 continue;
07156 }
07157 }
07158 }
07159 }
07160 user_unref(user);
07161 }
07162 ao2_iterator_destroy(&i);
07163 user = best;
07164 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07165 user = realtime_user(iaxs[callno]->username, sin);
07166 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07167 !apply_context(user->contexts, iaxs[callno]->context)) {
07168 user = user_unref(user);
07169 }
07170 }
07171 if (user) {
07172
07173
07174 for (v = user->vars ; v ; v = v->next) {
07175 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07176 tmpvar->next = iaxs[callno]->vars;
07177 iaxs[callno]->vars = tmpvar;
07178 }
07179 }
07180
07181 if (user->maxauthreq > 0)
07182 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
07183 iaxs[callno]->prefs = user->prefs;
07184 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
07185 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
07186 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
07187 iaxs[callno]->encmethods = user->encmethods;
07188
07189 if (ast_strlen_zero(iaxs[callno]->username))
07190 ast_string_field_set(iaxs[callno], username, user->name);
07191
07192 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
07193 iaxs[callno]->capability = user->capability;
07194
07195 if (ast_strlen_zero(iaxs[callno]->context)) {
07196 if (user->contexts)
07197 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07198 else
07199 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07200 }
07201
07202 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07203
07204 iaxs[callno]->authmethods = user->authmethods;
07205 iaxs[callno]->adsi = user->adsi;
07206
07207 if (ast_test_flag(user, IAX_HASCALLERID)) {
07208 iaxs[callno]->calling_tns = 0;
07209 iaxs[callno]->calling_ton = 0;
07210 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07211 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07212 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07213 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07214 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07215 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07216 }
07217 if (!ast_strlen_zero(user->accountcode))
07218 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07219 if (!ast_strlen_zero(user->mohinterpret))
07220 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07221 if (!ast_strlen_zero(user->mohsuggest))
07222 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07223 if (!ast_strlen_zero(user->parkinglot))
07224 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07225 if (user->amaflags)
07226 iaxs[callno]->amaflags = user->amaflags;
07227 if (!ast_strlen_zero(user->language))
07228 ast_string_field_set(iaxs[callno], language, user->language);
07229 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07230
07231 if (!ast_strlen_zero(user->dbsecret)) {
07232 char *family, *key=NULL;
07233 char buf[80];
07234 family = ast_strdupa(user->dbsecret);
07235 key = strchr(family, '/');
07236 if (key) {
07237 *key = '\0';
07238 key++;
07239 }
07240 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07241 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07242 else
07243 ast_string_field_set(iaxs[callno], secret, buf);
07244 } else
07245 ast_string_field_set(iaxs[callno], secret, user->secret);
07246 res = 0;
07247 user = user_unref(user);
07248 } else {
07249
07250
07251
07252
07253 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07254 ast_string_field_set(iaxs[callno], secret, "badsecret");
07255 iaxs[callno]->authrej = 1;
07256 if (!ast_strlen_zero(iaxs[callno]->username)) {
07257
07258 res = 0;
07259 }
07260 }
07261 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07262 return res;
07263 }
07264
07265 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07266 {
07267 struct ast_iax2_full_hdr fh;
07268 fh.scallno = htons(src | IAX_FLAG_FULL);
07269 fh.dcallno = htons(dst);
07270 fh.ts = 0;
07271 fh.oseqno = 0;
07272 fh.iseqno = 0;
07273 fh.type = AST_FRAME_IAX;
07274 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07275 iax_outputframe(NULL, &fh, 0, sin, 0);
07276 #if 0
07277 if (option_debug)
07278 #endif
07279 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07280 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07281 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07282 }
07283
07284 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07285 {
07286
07287 p->encmethods &= enc;
07288 if (p->encmethods) {
07289 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07290 p->keyrotateid = -2;
07291 }
07292 if (p->encmethods & IAX_ENCRYPT_AES128)
07293 p->encmethods = IAX_ENCRYPT_AES128;
07294 else
07295 p->encmethods = 0;
07296 }
07297 }
07298
07299
07300
07301
07302
07303
07304
07305 static int authenticate_request(int call_num)
07306 {
07307 struct iax_ie_data ied;
07308 int res = -1, authreq_restrict = 0;
07309 char challenge[10];
07310 struct chan_iax2_pvt *p = iaxs[call_num];
07311
07312 memset(&ied, 0, sizeof(ied));
07313
07314
07315 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07316 struct iax2_user *user, tmp_user = {
07317 .name = p->username,
07318 };
07319
07320 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07321 if (user) {
07322 if (user->curauthreq == user->maxauthreq)
07323 authreq_restrict = 1;
07324 else
07325 user->curauthreq++;
07326 user = user_unref(user);
07327 }
07328 }
07329
07330
07331 if (authreq_restrict) {
07332 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07333 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07334 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07335 return 0;
07336 }
07337
07338 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07339 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07340 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07341 ast_string_field_set(p, challenge, challenge);
07342
07343 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07344 }
07345 if (p->encmethods)
07346 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07347
07348 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07349
07350 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07351
07352 if (p->encmethods)
07353 ast_set_flag(p, IAX_ENCRYPTED);
07354
07355 return res;
07356 }
07357
07358 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07359 {
07360 char requeststr[256];
07361 char md5secret[256] = "";
07362 char secret[256] = "";
07363 char rsasecret[256] = "";
07364 int res = -1;
07365 int x;
07366 struct iax2_user *user, tmp_user = {
07367 .name = p->username,
07368 };
07369
07370 if (p->authrej) {
07371 return res;
07372 }
07373 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07374 if (user) {
07375 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07376 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07377 ast_clear_flag(p, IAX_MAXAUTHREQ);
07378 }
07379 ast_string_field_set(p, host, user->name);
07380 user = user_unref(user);
07381 }
07382
07383 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07384 return res;
07385 if (ies->password)
07386 ast_copy_string(secret, ies->password, sizeof(secret));
07387 if (ies->md5_result)
07388 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07389 if (ies->rsa_result)
07390 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07391 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07392 struct ast_key *key;
07393 char *keyn;
07394 char tmpkey[256];
07395 char *stringp=NULL;
07396 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07397 stringp=tmpkey;
07398 keyn = strsep(&stringp, ":");
07399 while(keyn) {
07400 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07401 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07402 res = 0;
07403 break;
07404 } else if (!key)
07405 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07406 keyn = strsep(&stringp, ":");
07407 }
07408 } else if (p->authmethods & IAX_AUTH_MD5) {
07409 struct MD5Context md5;
07410 unsigned char digest[16];
07411 char *tmppw, *stringp;
07412
07413 tmppw = ast_strdupa(p->secret);
07414 stringp = tmppw;
07415 while((tmppw = strsep(&stringp, ";"))) {
07416 MD5Init(&md5);
07417 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07418 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07419 MD5Final(digest, &md5);
07420
07421 for (x=0;x<16;x++)
07422 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07423 if (!strcasecmp(requeststr, md5secret)) {
07424 res = 0;
07425 break;
07426 }
07427 }
07428 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07429 if (!strcmp(secret, p->secret))
07430 res = 0;
07431 }
07432 return res;
07433 }
07434
07435
07436 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07437 {
07438 char requeststr[256] = "";
07439 char peer[256] = "";
07440 char md5secret[256] = "";
07441 char rsasecret[256] = "";
07442 char secret[256] = "";
07443 struct iax2_peer *p = NULL;
07444 struct ast_key *key;
07445 char *keyn;
07446 int x;
07447 int expire = 0;
07448 int res = -1;
07449
07450 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07451
07452 if (ies->username)
07453 ast_copy_string(peer, ies->username, sizeof(peer));
07454 if (ies->password)
07455 ast_copy_string(secret, ies->password, sizeof(secret));
07456 if (ies->md5_result)
07457 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07458 if (ies->rsa_result)
07459 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07460 if (ies->refresh)
07461 expire = ies->refresh;
07462
07463 if (ast_strlen_zero(peer)) {
07464 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07465 return -1;
07466 }
07467
07468
07469 ast_mutex_unlock(&iaxsl[callno]);
07470 p = find_peer(peer, 1);
07471 ast_mutex_lock(&iaxsl[callno]);
07472 if (!p || !iaxs[callno]) {
07473 if (iaxs[callno]) {
07474 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07475
07476 ast_string_field_set(iaxs[callno], secret, "badsecret");
07477
07478
07479
07480
07481
07482
07483
07484
07485
07486 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07487 !(!ast_strlen_zero(secret) && plaintext)) {
07488
07489 res = 0;
07490 }
07491 }
07492 if (authdebug && !p)
07493 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07494 goto return_unref;
07495 }
07496
07497 if (!ast_test_flag(p, IAX_DYNAMIC)) {
07498 if (authdebug)
07499 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07500 goto return_unref;
07501 }
07502
07503 if (!ast_apply_ha(p->ha, sin)) {
07504 if (authdebug)
07505 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07506 goto return_unref;
07507 }
07508 ast_string_field_set(iaxs[callno], secret, p->secret);
07509 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07510
07511 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07512 if (!ast_strlen_zero(p->inkeys)) {
07513 char tmpkeys[256];
07514 char *stringp=NULL;
07515 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07516 stringp=tmpkeys;
07517 keyn = strsep(&stringp, ":");
07518 while(keyn) {
07519 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07520 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07521 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07522 break;
07523 } else if (!key)
07524 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
07525 keyn = strsep(&stringp, ":");
07526 }
07527 if (!keyn) {
07528 if (authdebug)
07529 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
07530 goto return_unref;
07531 }
07532 } else {
07533 if (authdebug)
07534 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
07535 goto return_unref;
07536 }
07537 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07538 struct MD5Context md5;
07539 unsigned char digest[16];
07540 char *tmppw, *stringp;
07541
07542 tmppw = ast_strdupa(p->secret);
07543 stringp = tmppw;
07544 while((tmppw = strsep(&stringp, ";"))) {
07545 MD5Init(&md5);
07546 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
07547 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07548 MD5Final(digest, &md5);
07549 for (x=0;x<16;x++)
07550 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07551 if (!strcasecmp(requeststr, md5secret))
07552 break;
07553 }
07554 if (tmppw) {
07555 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07556 } else {
07557 if (authdebug)
07558 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
07559 goto return_unref;
07560 }
07561 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
07562
07563 if (strcmp(secret, p->secret)) {
07564 if (authdebug)
07565 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07566 goto return_unref;
07567 } else
07568 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07569 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
07570
07571 goto return_unref;
07572 }
07573 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
07574
07575
07576 res = 0;
07577
07578 return_unref:
07579 if (iaxs[callno]) {
07580 ast_string_field_set(iaxs[callno], peer, peer);
07581
07582
07583 if (expire && (expire < iaxs[callno]->expiry)) {
07584 iaxs[callno]->expiry = expire;
07585 }
07586 }
07587
07588 if (p) {
07589 peer_unref(p);
07590 }
07591 return res;
07592 }
07593
07594 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)
07595 {
07596 int res = -1;
07597 int x;
07598 if (!ast_strlen_zero(keyn)) {
07599 if (!(authmethods & IAX_AUTH_RSA)) {
07600 if (ast_strlen_zero(secret))
07601 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));
07602 } else if (ast_strlen_zero(challenge)) {
07603 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
07604 } else {
07605 char sig[256];
07606 struct ast_key *key;
07607 key = ast_key_get(keyn, AST_KEY_PRIVATE);
07608 if (!key) {
07609 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
07610 } else {
07611 if (ast_sign(key, (char*)challenge, sig)) {
07612 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
07613 res = -1;
07614 } else {
07615 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
07616 res = 0;
07617 }
07618 }
07619 }
07620 }
07621
07622 if (res && !ast_strlen_zero(secret)) {
07623 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
07624 struct MD5Context md5;
07625 unsigned char digest[16];
07626 char digres[128];
07627 MD5Init(&md5);
07628 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
07629 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
07630 MD5Final(digest, &md5);
07631
07632 for (x=0;x<16;x++)
07633 sprintf(digres + (x << 1), "%2.2x", digest[x]);
07634 if (pvt) {
07635 build_encryption_keys(digest, pvt);
07636 }
07637 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
07638 res = 0;
07639 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
07640 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
07641 res = 0;
07642 } else
07643 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
07644 }
07645 return res;
07646 }
07647
07648
07649
07650
07651
07652 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
07653 {
07654 struct iax2_peer *peer = NULL;
07655
07656 int res = -1;
07657 int authmethods = 0;
07658 struct iax_ie_data ied;
07659 uint16_t callno = p->callno;
07660
07661 memset(&ied, 0, sizeof(ied));
07662
07663 if (ies->username)
07664 ast_string_field_set(p, username, ies->username);
07665 if (ies->challenge)
07666 ast_string_field_set(p, challenge, ies->challenge);
07667 if (ies->authmethods)
07668 authmethods = ies->authmethods;
07669 if (authmethods & IAX_AUTH_MD5)
07670 merge_encryption(p, ies->encmethods);
07671 else
07672 p->encmethods = 0;
07673
07674
07675 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
07676
07677 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
07678 } else {
07679 struct ao2_iterator i = ao2_iterator_init(peers, 0);
07680 while ((peer = ao2_iterator_next(&i))) {
07681 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
07682
07683 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
07684
07685 && (!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)))
07686
07687 ) {
07688 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
07689 if (!res) {
07690 peer_unref(peer);
07691 break;
07692 }
07693 }
07694 peer_unref(peer);
07695 }
07696 ao2_iterator_destroy(&i);
07697 if (!peer) {
07698
07699
07700 const char *peer_name = ast_strdupa(p->peer);
07701 ast_mutex_unlock(&iaxsl[callno]);
07702 if ((peer = realtime_peer(peer_name, NULL))) {
07703 ast_mutex_lock(&iaxsl[callno]);
07704 if (!(p = iaxs[callno])) {
07705 peer_unref(peer);
07706 return -1;
07707 }
07708 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
07709 peer_unref(peer);
07710 }
07711 if (!peer) {
07712 ast_mutex_lock(&iaxsl[callno]);
07713 if (!(p = iaxs[callno]))
07714 return -1;
07715 }
07716 }
07717 }
07718 if (ies->encmethods)
07719 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
07720 if (!res) {
07721 struct ast_datastore *variablestore;
07722 struct ast_variable *var, *prev = NULL;
07723 AST_LIST_HEAD(, ast_var_t) *varlist;
07724 varlist = ast_calloc(1, sizeof(*varlist));
07725 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
07726 if (variablestore && varlist && p->owner) {
07727 variablestore->data = varlist;
07728 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
07729 AST_LIST_HEAD_INIT(varlist);
07730 for (var = ies->vars; var; var = var->next) {
07731 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
07732 if (prev)
07733 ast_free(prev);
07734 prev = var;
07735 if (!newvar) {
07736
07737 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07738 } else {
07739 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
07740 }
07741 }
07742 if (prev)
07743 ast_free(prev);
07744 ies->vars = NULL;
07745 ast_channel_datastore_add(p->owner, variablestore);
07746 } else {
07747 if (p->owner)
07748 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07749 if (variablestore)
07750 ast_datastore_free(variablestore);
07751 if (varlist)
07752 ast_free(varlist);
07753 }
07754 }
07755
07756 if (!res)
07757 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
07758 return res;
07759 }
07760
07761 static int iax2_do_register(struct iax2_registry *reg);
07762
07763 static void __iax2_do_register_s(const void *data)
07764 {
07765 struct iax2_registry *reg = (struct iax2_registry *)data;
07766 reg->expire = -1;
07767 iax2_do_register(reg);
07768 }
07769
07770 static int iax2_do_register_s(const void *data)
07771 {
07772 #ifdef SCHED_MULTITHREADED
07773 if (schedule_action(__iax2_do_register_s, data))
07774 #endif
07775 __iax2_do_register_s(data);
07776 return 0;
07777 }
07778
07779 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07780 {
07781 int newcall = 0;
07782 char newip[256];
07783 struct iax_ie_data ied;
07784 struct sockaddr_in new;
07785
07786
07787 memset(&ied, 0, sizeof(ied));
07788 if (ies->apparent_addr)
07789 memmove(&new, ies->apparent_addr, sizeof(new));
07790 if (ies->callno)
07791 newcall = ies->callno;
07792 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
07793 ast_log(LOG_WARNING, "Invalid transfer request\n");
07794 return -1;
07795 }
07796 pvt->transfercallno = newcall;
07797 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
07798 inet_aton(newip, &pvt->transfer.sin_addr);
07799 pvt->transfer.sin_family = AF_INET;
07800 pvt->transferring = TRANSFER_BEGIN;
07801 pvt->transferid = ies->transferid;
07802 store_by_transfercallno(pvt);
07803 if (ies->transferid)
07804 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
07805 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
07806 return 0;
07807 }
07808
07809 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07810 {
07811 char exten[256] = "";
07812 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
07813 struct iax2_dpcache *dp = NULL;
07814
07815 if (ies->called_number)
07816 ast_copy_string(exten, ies->called_number, sizeof(exten));
07817
07818 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
07819 status = CACHE_FLAG_EXISTS;
07820 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
07821 status = CACHE_FLAG_CANEXIST;
07822 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
07823 status = CACHE_FLAG_NONEXISTENT;
07824
07825 if (ies->refresh)
07826 expiry = ies->refresh;
07827 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
07828 matchmore = CACHE_FLAG_MATCHMORE;
07829
07830 AST_LIST_LOCK(&dpcache);
07831 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
07832 if (strcmp(dp->exten, exten))
07833 continue;
07834 AST_LIST_REMOVE_CURRENT(peer_list);
07835 dp->callno = 0;
07836 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
07837 if (dp->flags & CACHE_FLAG_PENDING) {
07838 dp->flags &= ~CACHE_FLAG_PENDING;
07839 dp->flags |= status;
07840 dp->flags |= matchmore;
07841 }
07842
07843 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
07844 if (dp->waiters[x] > -1) {
07845 if (write(dp->waiters[x], "asdf", 4) < 0) {
07846 }
07847 }
07848 }
07849 }
07850 AST_LIST_TRAVERSE_SAFE_END;
07851 AST_LIST_UNLOCK(&dpcache);
07852
07853 return 0;
07854 }
07855
07856 static int complete_transfer(int callno, struct iax_ies *ies)
07857 {
07858 int peercallno = 0;
07859 struct chan_iax2_pvt *pvt = iaxs[callno];
07860 struct iax_frame *cur;
07861 jb_frame frame;
07862
07863 if (ies->callno)
07864 peercallno = ies->callno;
07865
07866 if (peercallno < 1) {
07867 ast_log(LOG_WARNING, "Invalid transfer request\n");
07868 return -1;
07869 }
07870 remove_by_transfercallno(pvt);
07871
07872
07873
07874 peercnt_remove_by_addr(&pvt->addr);
07875 peercnt_add(&pvt->transfer);
07876
07877 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
07878 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
07879
07880 pvt->oseqno = 0;
07881 pvt->rseqno = 0;
07882 pvt->iseqno = 0;
07883 pvt->aseqno = 0;
07884
07885 if (pvt->peercallno) {
07886 remove_by_peercallno(pvt);
07887 }
07888 pvt->peercallno = peercallno;
07889
07890 store_by_peercallno(pvt);
07891 pvt->transferring = TRANSFER_NONE;
07892 pvt->svoiceformat = -1;
07893 pvt->voiceformat = 0;
07894 pvt->svideoformat = -1;
07895 pvt->videoformat = 0;
07896 pvt->transfercallno = -1;
07897 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
07898 memset(&pvt->offset, 0, sizeof(pvt->offset));
07899
07900 while(jb_getall(pvt->jb,&frame) == JB_OK)
07901 iax2_frame_free(frame.data);
07902 jb_reset(pvt->jb);
07903 pvt->lag = 0;
07904 pvt->last = 0;
07905 pvt->lastsent = 0;
07906 pvt->nextpred = 0;
07907 pvt->pingtime = DEFAULT_RETRY_TIME;
07908 AST_LIST_LOCK(&frame_queue);
07909 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
07910
07911
07912
07913 if (callno == cur->callno)
07914 cur->retries = -1;
07915 }
07916 AST_LIST_UNLOCK(&frame_queue);
07917 return 0;
07918 }
07919
07920
07921 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
07922 {
07923 struct iax2_registry *reg;
07924
07925 char peer[256] = "";
07926 char msgstatus[60];
07927 int refresh = 60;
07928 char ourip[256] = "<Unspecified>";
07929 struct sockaddr_in oldus;
07930 struct sockaddr_in us;
07931 int oldmsgs;
07932
07933 memset(&us, 0, sizeof(us));
07934 if (ies->apparent_addr)
07935 memmove(&us, ies->apparent_addr, sizeof(us));
07936 if (ies->username)
07937 ast_copy_string(peer, ies->username, sizeof(peer));
07938 if (ies->refresh)
07939 refresh = ies->refresh;
07940 if (ies->calling_number) {
07941
07942 }
07943 reg = iaxs[callno]->reg;
07944 if (!reg) {
07945 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
07946 return -1;
07947 }
07948 memcpy(&oldus, ®->us, sizeof(oldus));
07949 oldmsgs = reg->messages;
07950 if (inaddrcmp(®->addr, sin)) {
07951 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07952 return -1;
07953 }
07954 memcpy(®->us, &us, sizeof(reg->us));
07955 if (ies->msgcount >= 0)
07956 reg->messages = ies->msgcount & 0xffff;
07957
07958
07959
07960 reg->refresh = refresh;
07961 reg->expire = iax2_sched_replace(reg->expire, sched,
07962 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07963 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
07964 if (reg->messages > 255)
07965 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
07966 else if (reg->messages > 1)
07967 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
07968 else if (reg->messages > 0)
07969 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
07970 else
07971 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
07972 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07973 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
07974 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
07975 }
07976 reg->regstate = REG_STATE_REGISTERED;
07977 return 0;
07978 }
07979
07980 static int iax2_append_register(const char *hostname, const char *username,
07981 const char *secret, const char *porta)
07982 {
07983 struct iax2_registry *reg;
07984
07985 if (!(reg = ast_calloc(1, sizeof(*reg))))
07986 return -1;
07987
07988 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
07989 ast_free(reg);
07990 return -1;
07991 }
07992
07993 ast_copy_string(reg->username, username, sizeof(reg->username));
07994
07995 if (secret)
07996 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
07997
07998 reg->expire = -1;
07999 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08000 reg->addr.sin_family = AF_INET;
08001 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
08002
08003 AST_LIST_LOCK(®istrations);
08004 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08005 AST_LIST_UNLOCK(®istrations);
08006
08007 return 0;
08008 }
08009
08010 static int iax2_register(const char *value, int lineno)
08011 {
08012 char copy[256];
08013 char *username, *hostname, *secret;
08014 char *porta;
08015 char *stringp=NULL;
08016
08017 if (!value)
08018 return -1;
08019
08020 ast_copy_string(copy, value, sizeof(copy));
08021 stringp = copy;
08022 username = strsep(&stringp, "@");
08023 hostname = strsep(&stringp, "@");
08024
08025 if (!hostname) {
08026 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08027 return -1;
08028 }
08029
08030 stringp = username;
08031 username = strsep(&stringp, ":");
08032 secret = strsep(&stringp, ":");
08033 stringp = hostname;
08034 hostname = strsep(&stringp, ":");
08035 porta = strsep(&stringp, ":");
08036
08037 if (porta && !atoi(porta)) {
08038 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08039 return -1;
08040 }
08041
08042 return iax2_append_register(hostname, username, secret, porta);
08043 }
08044
08045
08046 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08047 {
08048 char multi[256];
08049 char *stringp, *ext;
08050 if (!ast_strlen_zero(regcontext)) {
08051 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08052 stringp = multi;
08053 while((ext = strsep(&stringp, "&"))) {
08054 if (onoff) {
08055 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08056 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08057 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08058 } else
08059 ast_context_remove_extension(regcontext, ext, 1, NULL);
08060 }
08061 }
08062 }
08063 static void prune_peers(void);
08064
08065 static void unlink_peer(struct iax2_peer *peer)
08066 {
08067 if (peer->expire > -1) {
08068 if (!ast_sched_del(sched, peer->expire)) {
08069 peer->expire = -1;
08070 peer_unref(peer);
08071 }
08072 }
08073
08074 if (peer->pokeexpire > -1) {
08075 if (!ast_sched_del(sched, peer->pokeexpire)) {
08076 peer->pokeexpire = -1;
08077 peer_unref(peer);
08078 }
08079 }
08080
08081 ao2_unlink(peers, peer);
08082 }
08083
08084 static void __expire_registry(const void *data)
08085 {
08086 struct iax2_peer *peer = (struct iax2_peer *) data;
08087
08088 if (!peer)
08089 return;
08090
08091 peer->expire = -1;
08092
08093 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08094 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08095 realtime_update_peer(peer->name, &peer->addr, 0);
08096 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08097
08098 peercnt_modify(0, 0, &peer->addr);
08099
08100 memset(&peer->addr, 0, sizeof(peer->addr));
08101
08102 peer->expiry = min_reg_expire;
08103 if (!ast_test_flag(peer, IAX_TEMPONLY))
08104 ast_db_del("IAX/Registry", peer->name);
08105 register_peer_exten(peer, 0);
08106 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08107 if (iax2_regfunk)
08108 iax2_regfunk(peer->name, 0);
08109
08110 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
08111 unlink_peer(peer);
08112
08113 peer_unref(peer);
08114 }
08115
08116 static int expire_registry(const void *data)
08117 {
08118 #ifdef SCHED_MULTITHREADED
08119 if (schedule_action(__expire_registry, data))
08120 #endif
08121 __expire_registry(data);
08122 return 0;
08123 }
08124
08125 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08126
08127 static void reg_source_db(struct iax2_peer *p)
08128 {
08129 char data[80];
08130 struct in_addr in;
08131 char *c, *d;
08132 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
08133 c = strchr(data, ':');
08134 if (c) {
08135 *c = '\0';
08136 c++;
08137 if (inet_aton(data, &in)) {
08138 d = strchr(c, ':');
08139 if (d) {
08140 *d = '\0';
08141 d++;
08142 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
08143 ast_inet_ntoa(in), atoi(c), atoi(d));
08144 iax2_poke_peer(p, 0);
08145 p->expiry = atoi(d);
08146 memset(&p->addr, 0, sizeof(p->addr));
08147 p->addr.sin_family = AF_INET;
08148 p->addr.sin_addr = in;
08149 p->addr.sin_port = htons(atoi(c));
08150 if (p->expire > -1) {
08151 if (!ast_sched_del(sched, p->expire)) {
08152 p->expire = -1;
08153 peer_unref(p);
08154 }
08155 }
08156 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08157 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08158 if (p->expire == -1)
08159 peer_unref(p);
08160 if (iax2_regfunk)
08161 iax2_regfunk(p->name, 1);
08162 register_peer_exten(p, 1);
08163 }
08164
08165 }
08166 }
08167 }
08168 }
08169
08170
08171
08172
08173
08174
08175
08176 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08177 {
08178
08179 struct iax_ie_data ied;
08180 struct iax2_peer *p;
08181 int msgcount;
08182 char data[80];
08183 int version;
08184 const char *peer_name;
08185 int res = -1;
08186
08187 memset(&ied, 0, sizeof(ied));
08188
08189 peer_name = ast_strdupa(iaxs[callno]->peer);
08190
08191
08192 ast_mutex_unlock(&iaxsl[callno]);
08193 if (!(p = find_peer(peer_name, 1))) {
08194 ast_mutex_lock(&iaxsl[callno]);
08195 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08196 return -1;
08197 }
08198 ast_mutex_lock(&iaxsl[callno]);
08199 if (!iaxs[callno])
08200 goto return_unref;
08201
08202 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08203 if (sin->sin_addr.s_addr) {
08204 time_t nowtime;
08205 time(&nowtime);
08206 realtime_update_peer(peer_name, sin, nowtime);
08207 } else {
08208 realtime_update_peer(peer_name, sin, 0);
08209 }
08210 }
08211 if (inaddrcmp(&p->addr, sin)) {
08212 if (iax2_regfunk)
08213 iax2_regfunk(p->name, 1);
08214
08215
08216 peercnt_modify(0, 0, &p->addr);
08217
08218
08219 memcpy(&p->addr, sin, sizeof(p->addr));
08220
08221 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08222 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08223 ast_db_put("IAX/Registry", p->name, data);
08224 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08225 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08226 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08227 register_peer_exten(p, 1);
08228 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08229 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
08230 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08231 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08232 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08233 register_peer_exten(p, 0);
08234 ast_db_del("IAX/Registry", p->name);
08235 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08236 }
08237
08238
08239 iax2_poke_peer(p, callno);
08240 }
08241
08242
08243 if (p->maxcallno) {
08244 peercnt_modify(1, p->maxcallno, &p->addr);
08245 }
08246
08247
08248 if (!iaxs[callno]) {
08249 res = -1;
08250 goto return_unref;
08251 }
08252
08253
08254 p->sockfd = fd;
08255
08256 if (p->expire > -1) {
08257 if (!ast_sched_del(sched, p->expire)) {
08258 p->expire = -1;
08259 peer_unref(p);
08260 }
08261 }
08262
08263 if (!refresh)
08264 refresh = min_reg_expire;
08265 if (refresh > max_reg_expire) {
08266 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08267 p->name, max_reg_expire, refresh);
08268 p->expiry = max_reg_expire;
08269 } else if (refresh < min_reg_expire) {
08270 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08271 p->name, min_reg_expire, refresh);
08272 p->expiry = min_reg_expire;
08273 } else {
08274 p->expiry = refresh;
08275 }
08276 if (p->expiry && sin->sin_addr.s_addr) {
08277 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08278 if (p->expire == -1)
08279 peer_unref(p);
08280 }
08281 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08282 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08283 if (sin->sin_addr.s_addr) {
08284 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08285 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
08286 if (!ast_strlen_zero(p->mailbox)) {
08287 struct ast_event *event;
08288 int new, old;
08289 char *mailbox, *context;
08290
08291 context = mailbox = ast_strdupa(p->mailbox);
08292 strsep(&context, "@");
08293 if (ast_strlen_zero(context))
08294 context = "default";
08295
08296 event = ast_event_get_cached(AST_EVENT_MWI,
08297 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08298 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08299 AST_EVENT_IE_END);
08300 if (event) {
08301 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08302 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08303 ast_event_destroy(event);
08304 } else {
08305 ast_app_inboxcount(p->mailbox, &new, &old);
08306 }
08307
08308 if (new > 255) {
08309 new = 255;
08310 }
08311 if (old > 255) {
08312 old = 255;
08313 }
08314 msgcount = (old << 8) | new;
08315
08316 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08317 }
08318 if (ast_test_flag(p, IAX_HASCALLERID)) {
08319 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08320 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08321 }
08322 }
08323 version = iax_check_version(devtype);
08324 if (version)
08325 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08326
08327 res = 0;
08328
08329 return_unref:
08330 peer_unref(p);
08331
08332 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08333 }
08334
08335 static int registry_authrequest(int callno)
08336 {
08337 struct iax_ie_data ied;
08338 struct iax2_peer *p;
08339 char challenge[10];
08340 const char *peer_name;
08341 int sentauthmethod;
08342
08343 peer_name = ast_strdupa(iaxs[callno]->peer);
08344
08345
08346 ast_mutex_unlock(&iaxsl[callno]);
08347 if ((p = find_peer(peer_name, 1))) {
08348 last_authmethod = p->authmethods;
08349 }
08350
08351 ast_mutex_lock(&iaxsl[callno]);
08352 if (!iaxs[callno])
08353 goto return_unref;
08354
08355 memset(&ied, 0, sizeof(ied));
08356
08357
08358
08359
08360
08361
08362 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08363 if (!p) {
08364 iaxs[callno]->authmethods = sentauthmethod;
08365 }
08366 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08367 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08368
08369 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08370 ast_string_field_set(iaxs[callno], challenge, challenge);
08371 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08372 }
08373 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08374
08375 return_unref:
08376 if (p) {
08377 peer_unref(p);
08378 }
08379
08380 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08381 }
08382
08383 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08384 {
08385 struct iax2_registry *reg;
08386
08387 struct iax_ie_data ied;
08388 char peer[256] = "";
08389 char challenge[256] = "";
08390 int res;
08391 int authmethods = 0;
08392 if (ies->authmethods)
08393 authmethods = ies->authmethods;
08394 if (ies->username)
08395 ast_copy_string(peer, ies->username, sizeof(peer));
08396 if (ies->challenge)
08397 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08398 memset(&ied, 0, sizeof(ied));
08399 reg = iaxs[callno]->reg;
08400 if (reg) {
08401 if (inaddrcmp(®->addr, sin)) {
08402 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08403 return -1;
08404 }
08405 if (ast_strlen_zero(reg->secret)) {
08406 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08407 reg->regstate = REG_STATE_NOAUTH;
08408 return -1;
08409 }
08410 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08411 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08412 if (reg->secret[0] == '[') {
08413 char tmpkey[256];
08414 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08415 tmpkey[strlen(tmpkey) - 1] = '\0';
08416 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08417 } else
08418 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08419 if (!res) {
08420 reg->regstate = REG_STATE_AUTHSENT;
08421 add_empty_calltoken_ie(iaxs[callno], &ied);
08422 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08423 } else
08424 return -1;
08425 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08426 } else
08427 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08428 return -1;
08429 }
08430
08431 static void stop_stuff(int callno)
08432 {
08433 iax2_destroy_helper(iaxs[callno]);
08434 }
08435
08436 static void __auth_reject(const void *nothing)
08437 {
08438
08439 int callno = (int)(long)(nothing);
08440 struct iax_ie_data ied;
08441 ast_mutex_lock(&iaxsl[callno]);
08442 if (iaxs[callno]) {
08443 memset(&ied, 0, sizeof(ied));
08444 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08445 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08446 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08447 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08448 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08449 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08450 }
08451 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08452 }
08453 ast_mutex_unlock(&iaxsl[callno]);
08454 }
08455
08456 static int auth_reject(const void *data)
08457 {
08458 int callno = (int)(long)(data);
08459 ast_mutex_lock(&iaxsl[callno]);
08460 if (iaxs[callno])
08461 iaxs[callno]->authid = -1;
08462 ast_mutex_unlock(&iaxsl[callno]);
08463 #ifdef SCHED_MULTITHREADED
08464 if (schedule_action(__auth_reject, data))
08465 #endif
08466 __auth_reject(data);
08467 return 0;
08468 }
08469
08470 static int auth_fail(int callno, int failcode)
08471 {
08472
08473
08474 if (iaxs[callno]) {
08475 iaxs[callno]->authfail = failcode;
08476 if (delayreject) {
08477 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08478 sched, 1000, auth_reject, (void *)(long)callno);
08479 } else
08480 auth_reject((void *)(long)callno);
08481 }
08482 return 0;
08483 }
08484
08485 static void __auto_hangup(const void *nothing)
08486 {
08487
08488 int callno = (int)(long)(nothing);
08489 struct iax_ie_data ied;
08490 ast_mutex_lock(&iaxsl[callno]);
08491 if (iaxs[callno]) {
08492 memset(&ied, 0, sizeof(ied));
08493 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08494 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
08495 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
08496 }
08497 ast_mutex_unlock(&iaxsl[callno]);
08498 }
08499
08500 static int auto_hangup(const void *data)
08501 {
08502 int callno = (int)(long)(data);
08503 ast_mutex_lock(&iaxsl[callno]);
08504 if (iaxs[callno]) {
08505 iaxs[callno]->autoid = -1;
08506 }
08507 ast_mutex_unlock(&iaxsl[callno]);
08508 #ifdef SCHED_MULTITHREADED
08509 if (schedule_action(__auto_hangup, data))
08510 #endif
08511 __auto_hangup(data);
08512 return 0;
08513 }
08514
08515 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
08516 {
08517 struct iax_ie_data ied;
08518
08519 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
08520 sched, 30000, auto_hangup, (void *)(long)callno);
08521 memset(&ied, 0, sizeof(ied));
08522 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
08523 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
08524 dp->flags |= CACHE_FLAG_TRANSMITTED;
08525 }
08526
08527 static int iax2_vnak(int callno)
08528 {
08529 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
08530 }
08531
08532 static void vnak_retransmit(int callno, int last)
08533 {
08534 struct iax_frame *f;
08535
08536 AST_LIST_LOCK(&frame_queue);
08537 AST_LIST_TRAVERSE(&frame_queue, f, list) {
08538
08539 if ((f->callno == callno) && iaxs[f->callno] &&
08540 ((unsigned char ) (f->oseqno - last) < 128) &&
08541 (f->retries >= 0)) {
08542 send_packet(f);
08543 }
08544 }
08545 AST_LIST_UNLOCK(&frame_queue);
08546 }
08547
08548 static void __iax2_poke_peer_s(const void *data)
08549 {
08550 struct iax2_peer *peer = (struct iax2_peer *)data;
08551 iax2_poke_peer(peer, 0);
08552 peer_unref(peer);
08553 }
08554
08555 static int iax2_poke_peer_s(const void *data)
08556 {
08557 struct iax2_peer *peer = (struct iax2_peer *)data;
08558 peer->pokeexpire = -1;
08559 #ifdef SCHED_MULTITHREADED
08560 if (schedule_action(__iax2_poke_peer_s, data))
08561 #endif
08562 __iax2_poke_peer_s(data);
08563 return 0;
08564 }
08565
08566 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
08567 {
08568 int res = 0;
08569 struct iax_frame *fr;
08570 struct ast_iax2_meta_hdr *meta;
08571 struct ast_iax2_meta_trunk_hdr *mth;
08572 int calls = 0;
08573
08574
08575 fr = (struct iax_frame *)tpeer->trunkdata;
08576
08577 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
08578 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
08579 if (tpeer->trunkdatalen) {
08580
08581 meta->zeros = 0;
08582 meta->metacmd = IAX_META_TRUNK;
08583 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
08584 meta->cmddata = IAX_META_TRUNK_MINI;
08585 else
08586 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
08587 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
08588
08589 fr->direction = DIRECTION_OUTGRESS;
08590 fr->retrans = -1;
08591 fr->transfer = 0;
08592
08593 fr->data = fr->afdata;
08594 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
08595 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
08596 calls = tpeer->calls;
08597 #if 0
08598 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));
08599 #endif
08600
08601 tpeer->trunkdatalen = 0;
08602 tpeer->calls = 0;
08603 }
08604 if (res < 0)
08605 return res;
08606 return calls;
08607 }
08608
08609 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
08610 {
08611
08612 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
08613 return 1;
08614 return 0;
08615 }
08616
08617 static int timing_read(int *id, int fd, short events, void *cbdata)
08618 {
08619 int res, processed = 0, totalcalls = 0;
08620 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
08621 struct timeval now = ast_tvnow();
08622
08623 if (iaxtrunkdebug)
08624 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
08625
08626 if (timer) {
08627 ast_timer_ack(timer, 1);
08628 }
08629
08630
08631 AST_LIST_LOCK(&tpeers);
08632 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
08633 processed++;
08634 res = 0;
08635 ast_mutex_lock(&tpeer->lock);
08636
08637
08638 if (!drop && iax2_trunk_expired(tpeer, &now)) {
08639
08640
08641 AST_LIST_REMOVE_CURRENT(list);
08642 drop = tpeer;
08643 } else {
08644 res = send_trunk(tpeer, &now);
08645 trunk_timed++;
08646 if (iaxtrunkdebug)
08647 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);
08648 }
08649 totalcalls += res;
08650 res = 0;
08651 ast_mutex_unlock(&tpeer->lock);
08652 }
08653 AST_LIST_TRAVERSE_SAFE_END;
08654 AST_LIST_UNLOCK(&tpeers);
08655
08656 if (drop) {
08657 ast_mutex_lock(&drop->lock);
08658
08659
08660 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
08661 if (drop->trunkdata) {
08662 ast_free(drop->trunkdata);
08663 drop->trunkdata = NULL;
08664 }
08665 ast_mutex_unlock(&drop->lock);
08666 ast_mutex_destroy(&drop->lock);
08667 ast_free(drop);
08668
08669 }
08670
08671 if (iaxtrunkdebug)
08672 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
08673 iaxtrunkdebug = 0;
08674
08675 return 1;
08676 }
08677
08678 struct dpreq_data {
08679 int callno;
08680 char context[AST_MAX_EXTENSION];
08681 char callednum[AST_MAX_EXTENSION];
08682 char *callerid;
08683 };
08684
08685 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
08686 {
08687 unsigned short dpstatus = 0;
08688 struct iax_ie_data ied1;
08689 int mm;
08690
08691 memset(&ied1, 0, sizeof(ied1));
08692 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
08693
08694 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
08695 dpstatus = IAX_DPSTATUS_EXISTS;
08696 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
08697 dpstatus = IAX_DPSTATUS_CANEXIST;
08698 } else {
08699 dpstatus = IAX_DPSTATUS_NONEXISTENT;
08700 }
08701 if (ast_ignore_pattern(context, callednum))
08702 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
08703 if (mm)
08704 dpstatus |= IAX_DPSTATUS_MATCHMORE;
08705 if (!skiplock)
08706 ast_mutex_lock(&iaxsl[callno]);
08707 if (iaxs[callno]) {
08708 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
08709 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
08710 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
08711 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
08712 }
08713 if (!skiplock)
08714 ast_mutex_unlock(&iaxsl[callno]);
08715 }
08716
08717 static void *dp_lookup_thread(void *data)
08718 {
08719
08720 struct dpreq_data *dpr = data;
08721 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
08722 if (dpr->callerid)
08723 ast_free(dpr->callerid);
08724 ast_free(dpr);
08725 return NULL;
08726 }
08727
08728 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
08729 {
08730 pthread_t newthread;
08731 struct dpreq_data *dpr;
08732
08733 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
08734 return;
08735
08736 dpr->callno = callno;
08737 ast_copy_string(dpr->context, context, sizeof(dpr->context));
08738 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
08739 if (callerid)
08740 dpr->callerid = ast_strdup(callerid);
08741 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
08742 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
08743 }
08744 }
08745
08746 struct iax_dual {
08747 struct ast_channel *chan1;
08748 struct ast_channel *chan2;
08749 };
08750
08751 static void *iax_park_thread(void *stuff)
08752 {
08753 struct ast_channel *chan1, *chan2;
08754 struct iax_dual *d;
08755 struct ast_frame *f;
08756 int ext;
08757 int res;
08758 d = stuff;
08759 chan1 = d->chan1;
08760 chan2 = d->chan2;
08761 ast_free(d);
08762 f = ast_read(chan1);
08763 if (f)
08764 ast_frfree(f);
08765 res = ast_park_call(chan1, chan2, 0, &ext);
08766 ast_hangup(chan2);
08767 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
08768 return NULL;
08769 }
08770
08771 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
08772 {
08773 struct iax_dual *d;
08774 struct ast_channel *chan1m, *chan2m;
08775 pthread_t th;
08776 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
08777 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
08778 if (chan2m && chan1m) {
08779
08780 chan1m->readformat = chan1->readformat;
08781 chan1m->writeformat = chan1->writeformat;
08782 ast_channel_masquerade(chan1m, chan1);
08783
08784 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
08785 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
08786 chan1m->priority = chan1->priority;
08787
08788
08789
08790
08791 chan2m->readformat = chan2->readformat;
08792 chan2m->writeformat = chan2->writeformat;
08793 ast_channel_masquerade(chan2m, chan2);
08794
08795 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
08796 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
08797 chan2m->priority = chan2->priority;
08798 if (ast_do_masquerade(chan2m)) {
08799 ast_log(LOG_WARNING, "Masquerade failed :(\n");
08800 ast_hangup(chan2m);
08801 return -1;
08802 }
08803 } else {
08804 if (chan1m)
08805 ast_hangup(chan1m);
08806 if (chan2m)
08807 ast_hangup(chan2m);
08808 return -1;
08809 }
08810 if ((d = ast_calloc(1, sizeof(*d)))) {
08811 d->chan1 = chan1m;
08812 d->chan2 = chan2m;
08813 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
08814 return 0;
08815 }
08816 ast_free(d);
08817 }
08818 return -1;
08819 }
08820
08821
08822 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
08823
08824 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
08825 {
08826 unsigned int ourver;
08827 char rsi[80];
08828 snprintf(rsi, sizeof(rsi), "si-%s", si);
08829 if (iax_provision_version(&ourver, rsi, 1))
08830 return 0;
08831 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
08832 if (ourver != ver)
08833 iax2_provision(sin, sockfd, NULL, rsi, 1);
08834 return 0;
08835 }
08836
08837 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
08838 {
08839 jb_info stats;
08840 jb_getinfo(pvt->jb, &stats);
08841
08842 memset(iep, 0, sizeof(*iep));
08843
08844 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
08845 if(stats.frames_in == 0) stats.frames_in = 1;
08846 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
08847 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
08848 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
08849 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
08850 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
08851 }
08852
08853 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
08854 {
08855 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
08856 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
08857 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
08858 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
08859 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
08860 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
08861 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
08862 }
08863
08864 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
08865 {
08866 int i;
08867 unsigned int length, offset = 0;
08868 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
08869
08870 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
08871 length = ies->ospblocklength[i];
08872 if (length != 0) {
08873 if (length > IAX_MAX_OSPBLOCK_SIZE) {
08874
08875 offset = 0;
08876 break;
08877 } else {
08878 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
08879 offset += length;
08880 }
08881 } else {
08882 break;
08883 }
08884 }
08885 *(full_osptoken + offset) = '\0';
08886 if (strlen(full_osptoken) != offset) {
08887
08888 *full_osptoken = '\0';
08889 }
08890
08891 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
08892 }
08893
08894 static void log_jitterstats(unsigned short callno)
08895 {
08896 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
08897 jb_info jbinfo;
08898
08899 ast_mutex_lock(&iaxsl[callno]);
08900 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
08901 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
08902 jb_getinfo(iaxs[callno]->jb, &jbinfo);
08903 localjitter = jbinfo.jitter;
08904 localdelay = jbinfo.current - jbinfo.min;
08905 locallost = jbinfo.frames_lost;
08906 locallosspct = jbinfo.losspct/1000;
08907 localdropped = jbinfo.frames_dropped;
08908 localooo = jbinfo.frames_ooo;
08909 localpackets = jbinfo.frames_in;
08910 }
08911 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",
08912 iaxs[callno]->owner->name,
08913 iaxs[callno]->pingtime,
08914 localjitter,
08915 localdelay,
08916 locallost,
08917 locallosspct,
08918 localdropped,
08919 localooo,
08920 localpackets,
08921 iaxs[callno]->remote_rr.jitter,
08922 iaxs[callno]->remote_rr.delay,
08923 iaxs[callno]->remote_rr.losscnt,
08924 iaxs[callno]->remote_rr.losspct/1000,
08925 iaxs[callno]->remote_rr.dropped,
08926 iaxs[callno]->remote_rr.ooo,
08927 iaxs[callno]->remote_rr.packets);
08928 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",
08929 iaxs[callno]->owner->name,
08930 iaxs[callno]->pingtime,
08931 localjitter,
08932 localdelay,
08933 locallost,
08934 locallosspct,
08935 localdropped,
08936 localooo,
08937 localpackets,
08938 iaxs[callno]->remote_rr.jitter,
08939 iaxs[callno]->remote_rr.delay,
08940 iaxs[callno]->remote_rr.losscnt,
08941 iaxs[callno]->remote_rr.losspct/1000,
08942 iaxs[callno]->remote_rr.dropped,
08943 iaxs[callno]->remote_rr.ooo,
08944 iaxs[callno]->remote_rr.packets);
08945 }
08946 ast_mutex_unlock(&iaxsl[callno]);
08947 }
08948
08949 static int socket_process(struct iax2_thread *thread);
08950
08951
08952
08953
08954 static void handle_deferred_full_frames(struct iax2_thread *thread)
08955 {
08956 struct iax2_pkt_buf *pkt_buf;
08957
08958 ast_mutex_lock(&thread->lock);
08959
08960 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
08961 ast_mutex_unlock(&thread->lock);
08962
08963 thread->buf = pkt_buf->buf;
08964 thread->buf_len = pkt_buf->len;
08965 thread->buf_size = pkt_buf->len + 1;
08966
08967 socket_process(thread);
08968
08969 thread->buf = NULL;
08970 ast_free(pkt_buf);
08971
08972 ast_mutex_lock(&thread->lock);
08973 }
08974
08975 ast_mutex_unlock(&thread->lock);
08976 }
08977
08978
08979
08980
08981
08982
08983
08984 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
08985 {
08986 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
08987 struct ast_iax2_full_hdr *fh, *cur_fh;
08988
08989 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
08990 return;
08991
08992 pkt_buf->len = from_here->buf_len;
08993 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
08994
08995 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
08996 ast_mutex_lock(&to_here->lock);
08997 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
08998 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
08999 if (fh->oseqno < cur_fh->oseqno) {
09000 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09001 break;
09002 }
09003 }
09004 AST_LIST_TRAVERSE_SAFE_END
09005
09006 if (!cur_pkt_buf)
09007 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09008
09009 ast_mutex_unlock(&to_here->lock);
09010 }
09011
09012 static int socket_read(int *id, int fd, short events, void *cbdata)
09013 {
09014 struct iax2_thread *thread;
09015 socklen_t len;
09016 time_t t;
09017 static time_t last_errtime = 0;
09018 struct ast_iax2_full_hdr *fh;
09019
09020 if (!(thread = find_idle_thread())) {
09021 time(&t);
09022 if (t != last_errtime)
09023 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09024 last_errtime = t;
09025 usleep(1);
09026 return 1;
09027 }
09028
09029 len = sizeof(thread->iosin);
09030 thread->iofd = fd;
09031 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09032 thread->buf_size = sizeof(thread->readbuf);
09033 thread->buf = thread->readbuf;
09034 if (thread->buf_len < 0) {
09035 if (errno != ECONNREFUSED && errno != EAGAIN)
09036 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09037 handle_error();
09038 thread->iostate = IAX_IOSTATE_IDLE;
09039 signal_condition(&thread->lock, &thread->cond);
09040 return 1;
09041 }
09042 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09043 thread->iostate = IAX_IOSTATE_IDLE;
09044 signal_condition(&thread->lock, &thread->cond);
09045 return 1;
09046 }
09047
09048
09049
09050
09051 fh = (struct ast_iax2_full_hdr *) thread->buf;
09052 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09053 struct iax2_thread *cur = NULL;
09054 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09055
09056 AST_LIST_LOCK(&active_list);
09057 AST_LIST_TRAVERSE(&active_list, cur, list) {
09058 if ((cur->ffinfo.callno == callno) &&
09059 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09060 break;
09061 }
09062 if (cur) {
09063
09064
09065 defer_full_frame(thread, cur);
09066 AST_LIST_UNLOCK(&active_list);
09067 thread->iostate = IAX_IOSTATE_IDLE;
09068 signal_condition(&thread->lock, &thread->cond);
09069 return 1;
09070 } else {
09071
09072 thread->ffinfo.callno = callno;
09073 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09074 thread->ffinfo.type = fh->type;
09075 thread->ffinfo.csub = fh->csub;
09076 }
09077 AST_LIST_UNLOCK(&active_list);
09078 }
09079
09080
09081 thread->iostate = IAX_IOSTATE_READY;
09082 #ifdef DEBUG_SCHED_MULTITHREAD
09083 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09084 #endif
09085 signal_condition(&thread->lock, &thread->cond);
09086
09087 return 1;
09088 }
09089
09090 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09091 struct iax_frame *fr)
09092 {
09093 unsigned char metatype;
09094 struct ast_iax2_meta_trunk_mini *mtm;
09095 struct ast_iax2_meta_trunk_hdr *mth;
09096 struct ast_iax2_meta_trunk_entry *mte;
09097 struct iax2_trunk_peer *tpeer;
09098 unsigned int ts;
09099 void *ptr;
09100 struct timeval rxtrunktime;
09101 struct ast_frame f = { 0, };
09102
09103 if (packet_len < sizeof(*meta)) {
09104 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09105 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09106 return 1;
09107 }
09108
09109 if (meta->metacmd != IAX_META_TRUNK)
09110 return 1;
09111
09112 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09113 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09114 (int) (sizeof(*meta) + sizeof(*mth)));
09115 return 1;
09116 }
09117 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09118 ts = ntohl(mth->ts);
09119 metatype = meta->cmddata;
09120 packet_len -= (sizeof(*meta) + sizeof(*mth));
09121 ptr = mth->data;
09122 tpeer = find_tpeer(sin, sockfd);
09123 if (!tpeer) {
09124 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09125 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09126 return 1;
09127 }
09128 tpeer->trunkact = ast_tvnow();
09129 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09130 tpeer->rxtrunktime = tpeer->trunkact;
09131 rxtrunktime = tpeer->rxtrunktime;
09132 ast_mutex_unlock(&tpeer->lock);
09133 while (packet_len >= sizeof(*mte)) {
09134
09135 unsigned short callno, trunked_ts, len;
09136
09137 if (metatype == IAX_META_TRUNK_MINI) {
09138 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09139 ptr += sizeof(*mtm);
09140 packet_len -= sizeof(*mtm);
09141 len = ntohs(mtm->len);
09142 callno = ntohs(mtm->mini.callno);
09143 trunked_ts = ntohs(mtm->mini.ts);
09144 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09145 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09146 ptr += sizeof(*mte);
09147 packet_len -= sizeof(*mte);
09148 len = ntohs(mte->len);
09149 callno = ntohs(mte->callno);
09150 trunked_ts = 0;
09151 } else {
09152 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09153 break;
09154 }
09155
09156 if (len > packet_len)
09157 break;
09158 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09159 if (!fr->callno)
09160 continue;
09161
09162
09163
09164
09165 memset(&f, 0, sizeof(f));
09166 f.frametype = AST_FRAME_VOICE;
09167 if (!iaxs[fr->callno]) {
09168
09169 } else if (iaxs[fr->callno]->voiceformat == 0) {
09170 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09171 iax2_vnak(fr->callno);
09172 } else {
09173 f.subclass = iaxs[fr->callno]->voiceformat;
09174 f.datalen = len;
09175 if (f.datalen >= 0) {
09176 if (f.datalen)
09177 f.data.ptr = ptr;
09178 else
09179 f.data.ptr = NULL;
09180 if (trunked_ts)
09181 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09182 else
09183 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09184
09185 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09186 struct iax_frame *duped_fr;
09187
09188
09189 f.src = "IAX2";
09190 f.mallocd = 0;
09191 f.offset = 0;
09192 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09193 f.samples = ast_codec_get_samples(&f);
09194 else
09195 f.samples = 0;
09196 fr->outoforder = 0;
09197 iax_frame_wrap(fr, &f);
09198 duped_fr = iaxfrdup2(fr);
09199 if (duped_fr)
09200 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09201 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09202 iaxs[fr->callno]->last = fr->ts;
09203 }
09204 } else {
09205 ast_log(LOG_WARNING, "Datalen < 0?\n");
09206 }
09207 }
09208 ast_mutex_unlock(&iaxsl[fr->callno]);
09209 ptr += len;
09210 packet_len -= len;
09211 }
09212
09213 return 1;
09214 }
09215
09216 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09217 {
09218 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09219 AST_LIST_HEAD(, ast_var_t) *varlist;
09220 struct ast_var_t *var;
09221
09222 if (!variablestore) {
09223 *buf = '\0';
09224 return 0;
09225 }
09226 varlist = variablestore->data;
09227
09228 AST_LIST_LOCK(varlist);
09229 AST_LIST_TRAVERSE(varlist, var, entries) {
09230 if (strcmp(var->name, data) == 0) {
09231 ast_copy_string(buf, var->value, len);
09232 break;
09233 }
09234 }
09235 AST_LIST_UNLOCK(varlist);
09236 return 0;
09237 }
09238
09239 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09240 {
09241 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09242 AST_LIST_HEAD(, ast_var_t) *varlist;
09243 struct ast_var_t *var;
09244
09245 if (!variablestore) {
09246 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09247 if (!variablestore) {
09248 ast_log(LOG_ERROR, "Memory allocation error\n");
09249 return -1;
09250 }
09251 varlist = ast_calloc(1, sizeof(*varlist));
09252 if (!varlist) {
09253 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09254 return -1;
09255 }
09256
09257 AST_LIST_HEAD_INIT(varlist);
09258 variablestore->data = varlist;
09259 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09260 ast_channel_datastore_add(chan, variablestore);
09261 } else
09262 varlist = variablestore->data;
09263
09264 AST_LIST_LOCK(varlist);
09265 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09266 if (strcmp(var->name, data) == 0) {
09267 AST_LIST_REMOVE_CURRENT(entries);
09268 ast_var_delete(var);
09269 break;
09270 }
09271 }
09272 AST_LIST_TRAVERSE_SAFE_END;
09273 var = ast_var_assign(data, value);
09274 if (var)
09275 AST_LIST_INSERT_TAIL(varlist, var, entries);
09276 else
09277 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09278 AST_LIST_UNLOCK(varlist);
09279 return 0;
09280 }
09281
09282 static struct ast_custom_function iaxvar_function = {
09283 .name = "IAXVAR",
09284 .synopsis = "Sets or retrieves a remote variable",
09285 .syntax = "IAXVAR(<varname>)",
09286 .read = acf_iaxvar_read,
09287 .write = acf_iaxvar_write,
09288 };
09289
09290 static int socket_process(struct iax2_thread *thread)
09291 {
09292 struct sockaddr_in sin;
09293 int res;
09294 int updatehistory=1;
09295 int new = NEW_PREVENT;
09296 int dcallno = 0;
09297 char decrypted = 0;
09298 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09299 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09300 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09301 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09302 struct iax_frame *fr;
09303 struct iax_frame *cur;
09304 struct ast_frame f = { 0, };
09305 struct ast_channel *c = NULL;
09306 struct iax2_dpcache *dp;
09307 struct iax2_peer *peer;
09308 struct iax_ies ies;
09309 struct iax_ie_data ied0, ied1;
09310 int format;
09311 int fd;
09312 int exists;
09313 int minivid = 0;
09314 char empty[32]="";
09315 struct iax_frame *duped_fr;
09316 char host_pref_buf[128];
09317 char caller_pref_buf[128];
09318 struct ast_codec_pref pref;
09319 char *using_prefs = "mine";
09320
09321
09322 fr = alloca(sizeof(*fr) + 4096);
09323 memset(fr, 0, sizeof(*fr));
09324 fr->afdatalen = 4096;
09325
09326
09327 res = thread->buf_len;
09328 fd = thread->iofd;
09329 memcpy(&sin, &thread->iosin, sizeof(sin));
09330
09331 if (res < sizeof(*mh)) {
09332 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09333 return 1;
09334 }
09335 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09336 if (res < sizeof(*vh)) {
09337 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));
09338 return 1;
09339 }
09340
09341
09342 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09343 minivid = 1;
09344 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09345 return socket_process_meta(res, meta, &sin, fd, fr);
09346
09347 #ifdef DEBUG_SUPPORT
09348 if (res >= sizeof(*fh))
09349 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09350 #endif
09351 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09352 if (res < sizeof(*fh)) {
09353 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));
09354 return 1;
09355 }
09356
09357
09358 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09359
09360
09361
09362
09363
09364
09365 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09366 ast_mutex_lock(&iaxsl[fr->callno]);
09367 if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
09368 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09369 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09370 ast_mutex_unlock(&iaxsl[fr->callno]);
09371 return 1;
09372 }
09373 decrypted = 1;
09374 }
09375 ast_mutex_unlock(&iaxsl[fr->callno]);
09376 }
09377
09378
09379 f.frametype = fh->type;
09380 if (f.frametype == AST_FRAME_VIDEO) {
09381 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09382 } else {
09383 f.subclass = uncompress_subclass(fh->csub);
09384 }
09385
09386
09387 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
09388
09389 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09390 return 1;
09391 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
09392
09393 return 1;
09394 }
09395
09396 f.datalen = res - sizeof(*fh);
09397 if (f.datalen) {
09398 if (f.frametype == AST_FRAME_IAX) {
09399 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09400 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09401 return 1;
09402 }
09403 f.data.ptr = NULL;
09404 f.datalen = 0;
09405 } else {
09406 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09407 memset(&ies, 0, sizeof(ies));
09408 }
09409 } else {
09410 if (f.frametype == AST_FRAME_IAX)
09411 f.data.ptr = NULL;
09412 else
09413 f.data.ptr = empty;
09414 memset(&ies, 0, sizeof(ies));
09415 }
09416
09417 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) {
09418
09419 if (handle_call_token(fh, &ies, &sin, fd)) {
09420 return 1;
09421 }
09422
09423 if (ies.calltoken && ies.calltokendata) {
09424
09425
09426
09427
09428 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09429 } else {
09430 new = NEW_ALLOW;
09431 }
09432 }
09433 } else {
09434
09435 f.frametype = AST_FRAME_NULL;
09436 f.subclass = 0;
09437 }
09438
09439 if (!fr->callno) {
09440 int check_dcallno = 0;
09441
09442
09443
09444
09445
09446
09447
09448
09449
09450 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) {
09451 check_dcallno = 1;
09452 }
09453
09454 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09455 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) {
09456 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09457 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) {
09458 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09459 }
09460 return 1;
09461 }
09462 }
09463
09464 if (fr->callno > 0)
09465 ast_mutex_lock(&iaxsl[fr->callno]);
09466
09467 if (!fr->callno || !iaxs[fr->callno]) {
09468
09469
09470 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09471
09472 if (((f.subclass != IAX_COMMAND_INVAL) &&
09473 (f.subclass != IAX_COMMAND_TXCNT) &&
09474 (f.subclass != IAX_COMMAND_TXACC) &&
09475 (f.subclass != IAX_COMMAND_FWDOWNL))||
09476 (f.frametype != AST_FRAME_IAX))
09477 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09478 fd);
09479 }
09480 if (fr->callno > 0)
09481 ast_mutex_unlock(&iaxsl[fr->callno]);
09482 return 1;
09483 }
09484 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
09485 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09486 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09487 ast_mutex_unlock(&iaxsl[fr->callno]);
09488 return 1;
09489 }
09490 decrypted = 1;
09491 }
09492 #ifdef DEBUG_SUPPORT
09493 if (decrypted) {
09494 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
09495 }
09496 #endif
09497
09498
09499 iaxs[fr->callno]->frames_received++;
09500
09501 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
09502 f.subclass != IAX_COMMAND_TXCNT &&
09503 f.subclass != IAX_COMMAND_TXACC) {
09504 unsigned short new_peercallno;
09505
09506 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
09507 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
09508 if (iaxs[fr->callno]->peercallno) {
09509 remove_by_peercallno(iaxs[fr->callno]);
09510 }
09511 iaxs[fr->callno]->peercallno = new_peercallno;
09512 store_by_peercallno(iaxs[fr->callno]);
09513 }
09514 }
09515 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09516 if (iaxdebug)
09517 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
09518
09519 fr->oseqno = fh->oseqno;
09520 fr->iseqno = fh->iseqno;
09521 fr->ts = ntohl(fh->ts);
09522 #ifdef IAXTESTS
09523 if (test_resync) {
09524 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
09525 fr->ts += test_resync;
09526 }
09527 #endif
09528 #if 0
09529 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
09530 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
09531 (f.subclass == IAX_COMMAND_NEW ||
09532 f.subclass == IAX_COMMAND_AUTHREQ ||
09533 f.subclass == IAX_COMMAND_ACCEPT ||
09534 f.subclass == IAX_COMMAND_REJECT)) ) )
09535 #endif
09536 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
09537 updatehistory = 0;
09538 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
09539 (iaxs[fr->callno]->iseqno ||
09540 ((f.subclass != IAX_COMMAND_TXCNT) &&
09541 (f.subclass != IAX_COMMAND_TXREADY) &&
09542 (f.subclass != IAX_COMMAND_TXREL) &&
09543 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09544 (f.subclass != IAX_COMMAND_TXACC)) ||
09545 (f.frametype != AST_FRAME_IAX))) {
09546 if (
09547 ((f.subclass != IAX_COMMAND_ACK) &&
09548 (f.subclass != IAX_COMMAND_INVAL) &&
09549 (f.subclass != IAX_COMMAND_TXCNT) &&
09550 (f.subclass != IAX_COMMAND_TXREADY) &&
09551 (f.subclass != IAX_COMMAND_TXREL) &&
09552 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09553 (f.subclass != IAX_COMMAND_TXACC) &&
09554 (f.subclass != IAX_COMMAND_VNAK)) ||
09555 (f.frametype != AST_FRAME_IAX)) {
09556
09557 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
09558 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
09559
09560
09561 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
09562
09563 if ((f.frametype != AST_FRAME_IAX) ||
09564 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
09565 ast_debug(1, "Acking anyway\n");
09566
09567
09568 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09569 }
09570 } else {
09571
09572 iax2_vnak(fr->callno);
09573 }
09574 ast_mutex_unlock(&iaxsl[fr->callno]);
09575 return 1;
09576 }
09577 } else {
09578
09579 if (((f.subclass != IAX_COMMAND_ACK) &&
09580 (f.subclass != IAX_COMMAND_INVAL) &&
09581 (f.subclass != IAX_COMMAND_TXCNT) &&
09582 (f.subclass != IAX_COMMAND_TXACC) &&
09583 (f.subclass != IAX_COMMAND_VNAK)) ||
09584 (f.frametype != AST_FRAME_IAX))
09585 iaxs[fr->callno]->iseqno++;
09586 }
09587
09588 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
09589 if (res < thread->buf_size)
09590 thread->buf[res++] = '\0';
09591 else
09592 thread->buf[res - 1] = '\0';
09593 }
09594
09595
09596
09597 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09598 ((f.subclass != IAX_COMMAND_INVAL) ||
09599 (f.frametype != AST_FRAME_IAX))) {
09600 unsigned char x;
09601 int call_to_destroy;
09602
09603 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
09604 x = fr->iseqno;
09605 else
09606 x = iaxs[fr->callno]->oseqno;
09607 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
09608
09609
09610 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
09611
09612 if (iaxdebug)
09613 ast_debug(1, "Cancelling transmission of packet %d\n", x);
09614 call_to_destroy = 0;
09615 AST_LIST_LOCK(&frame_queue);
09616 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09617
09618 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
09619 cur->retries = -1;
09620
09621 if (cur->final)
09622 call_to_destroy = fr->callno;
09623 }
09624 }
09625 AST_LIST_UNLOCK(&frame_queue);
09626 if (call_to_destroy) {
09627 if (iaxdebug)
09628 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
09629 ast_mutex_lock(&iaxsl[call_to_destroy]);
09630 iax2_destroy(call_to_destroy);
09631 ast_mutex_unlock(&iaxsl[call_to_destroy]);
09632 }
09633 }
09634
09635 if (iaxs[fr->callno])
09636 iaxs[fr->callno]->rseqno = fr->iseqno;
09637 else {
09638
09639 ast_mutex_unlock(&iaxsl[fr->callno]);
09640 return 1;
09641 }
09642 } else {
09643 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
09644 }
09645 }
09646 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09647 ((f.frametype != AST_FRAME_IAX) ||
09648 ((f.subclass != IAX_COMMAND_TXACC) &&
09649 (f.subclass != IAX_COMMAND_TXCNT)))) {
09650
09651 ast_mutex_unlock(&iaxsl[fr->callno]);
09652 return 1;
09653 }
09654
09655
09656
09657
09658 if ((f.frametype == AST_FRAME_VOICE) ||
09659 (f.frametype == AST_FRAME_VIDEO) ||
09660 (f.frametype == AST_FRAME_IAX)) {
09661 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
09662 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
09663 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
09664 ast_mutex_unlock(&iaxsl[fr->callno]);
09665 return 1;
09666 }
09667 }
09668
09669 if (ies.vars) {
09670 struct ast_datastore *variablestore = NULL;
09671 struct ast_variable *var, *prev = NULL;
09672 AST_LIST_HEAD(, ast_var_t) *varlist;
09673 if ((c = iaxs[fr->callno]->owner)) {
09674 varlist = ast_calloc(1, sizeof(*varlist));
09675 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09676
09677 if (variablestore && varlist) {
09678 variablestore->data = varlist;
09679 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09680 AST_LIST_HEAD_INIT(varlist);
09681 ast_debug(1, "I can haz IAX vars?\n");
09682 for (var = ies.vars; var; var = var->next) {
09683 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09684 if (prev) {
09685 ast_free(prev);
09686 }
09687 prev = var;
09688 if (!newvar) {
09689
09690 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09691 } else {
09692 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09693 }
09694 }
09695 if (prev) {
09696 ast_free(prev);
09697 }
09698 ies.vars = NULL;
09699 ast_channel_datastore_add(c, variablestore);
09700 } else {
09701 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09702 if (variablestore) {
09703 ast_datastore_free(variablestore);
09704 }
09705 if (varlist) {
09706 ast_free(varlist);
09707 }
09708 }
09709 } else {
09710
09711
09712 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
09713 for (var = ies.vars; var && var->next; var = var->next);
09714 if (var) {
09715 var->next = iaxs[fr->callno]->iaxvars;
09716 iaxs[fr->callno]->iaxvars = ies.vars;
09717 ies.vars = NULL;
09718 }
09719 }
09720 }
09721
09722 if (ies.vars) {
09723 ast_debug(1, "I have IAX variables, but they were not processed\n");
09724 }
09725 }
09726
09727
09728
09729 if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
09730 send_signaling(iaxs[fr->callno]);
09731 }
09732
09733 if (f.frametype == AST_FRAME_VOICE) {
09734 if (f.subclass != iaxs[fr->callno]->voiceformat) {
09735 iaxs[fr->callno]->voiceformat = f.subclass;
09736 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
09737 if (iaxs[fr->callno]->owner) {
09738 int orignative;
09739 retryowner:
09740 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
09741 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09742 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
09743 }
09744 if (iaxs[fr->callno]) {
09745 if (iaxs[fr->callno]->owner) {
09746 orignative = iaxs[fr->callno]->owner->nativeformats;
09747 iaxs[fr->callno]->owner->nativeformats = f.subclass;
09748 if (iaxs[fr->callno]->owner->readformat)
09749 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
09750 iaxs[fr->callno]->owner->nativeformats = orignative;
09751 ast_channel_unlock(iaxs[fr->callno]->owner);
09752 }
09753 } else {
09754 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
09755
09756 if (ies.vars) {
09757 ast_variables_destroy(ies.vars);
09758 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
09759 ies.vars = NULL;
09760 }
09761 ast_mutex_unlock(&iaxsl[fr->callno]);
09762 return 1;
09763 }
09764 }
09765 }
09766 }
09767 if (f.frametype == AST_FRAME_VIDEO) {
09768 if (f.subclass != iaxs[fr->callno]->videoformat) {
09769 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
09770 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
09771 }
09772 }
09773 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
09774 if (f.subclass == AST_CONTROL_BUSY) {
09775 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
09776 } else if (f.subclass == AST_CONTROL_CONGESTION) {
09777 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
09778 }
09779 }
09780 if (f.frametype == AST_FRAME_IAX) {
09781 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
09782
09783 if (iaxdebug)
09784 ast_debug(1, "IAX subclass %d received\n", f.subclass);
09785
09786
09787 if (iaxs[fr->callno]->last < fr->ts &&
09788 f.subclass != IAX_COMMAND_ACK &&
09789 f.subclass != IAX_COMMAND_PONG &&
09790 f.subclass != IAX_COMMAND_LAGRP) {
09791 iaxs[fr->callno]->last = fr->ts;
09792 if (iaxdebug)
09793 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09794 }
09795 iaxs[fr->callno]->last_iax_message = f.subclass;
09796 if (!iaxs[fr->callno]->first_iax_message) {
09797 iaxs[fr->callno]->first_iax_message = f.subclass;
09798 }
09799 switch(f.subclass) {
09800 case IAX_COMMAND_ACK:
09801
09802 break;
09803 case IAX_COMMAND_QUELCH:
09804 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09805
09806 if (iaxs[fr->callno]->owner) {
09807 manager_event(EVENT_FLAG_CALL, "Hold",
09808 "Status: On\r\n"
09809 "Channel: %s\r\n"
09810 "Uniqueid: %s\r\n",
09811 iaxs[fr->callno]->owner->name,
09812 iaxs[fr->callno]->owner->uniqueid);
09813 }
09814
09815 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
09816 if (ies.musiconhold) {
09817 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
09818 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
09819 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
09820 S_OR(moh_suggest, NULL),
09821 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
09822 if (!iaxs[fr->callno]) {
09823 ast_mutex_unlock(&iaxsl[fr->callno]);
09824 return 1;
09825 }
09826 }
09827 }
09828 }
09829 break;
09830 case IAX_COMMAND_UNQUELCH:
09831 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09832
09833 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
09834 manager_event(EVENT_FLAG_CALL, "Hold",
09835 "Status: Off\r\n"
09836 "Channel: %s\r\n"
09837 "Uniqueid: %s\r\n",
09838 iaxs[fr->callno]->owner->name,
09839 iaxs[fr->callno]->owner->uniqueid);
09840 }
09841
09842 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
09843 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
09844 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
09845 if (!iaxs[fr->callno]) {
09846 ast_mutex_unlock(&iaxsl[fr->callno]);
09847 return 1;
09848 }
09849 }
09850 }
09851 break;
09852 case IAX_COMMAND_TXACC:
09853 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
09854
09855 AST_LIST_LOCK(&frame_queue);
09856 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09857
09858 if ((fr->callno == cur->callno) && (cur->transfer))
09859 cur->retries = -1;
09860 }
09861 AST_LIST_UNLOCK(&frame_queue);
09862 memset(&ied1, 0, sizeof(ied1));
09863 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
09864 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
09865 iaxs[fr->callno]->transferring = TRANSFER_READY;
09866 }
09867 break;
09868 case IAX_COMMAND_NEW:
09869
09870 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
09871 break;
09872 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
09873 ast_mutex_unlock(&iaxsl[fr->callno]);
09874 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
09875 ast_mutex_lock(&iaxsl[fr->callno]);
09876 if (!iaxs[fr->callno]) {
09877 ast_mutex_unlock(&iaxsl[fr->callno]);
09878 return 1;
09879 }
09880 }
09881
09882 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
09883 int new_callno;
09884 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
09885 fr->callno = new_callno;
09886 }
09887
09888 if (delayreject)
09889 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09890 if (check_access(fr->callno, &sin, &ies)) {
09891
09892 auth_fail(fr->callno, IAX_COMMAND_REJECT);
09893 if (authdebug)
09894 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);
09895 break;
09896 }
09897 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
09898 const char *context, *exten, *cid_num;
09899
09900 context = ast_strdupa(iaxs[fr->callno]->context);
09901 exten = ast_strdupa(iaxs[fr->callno]->exten);
09902 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
09903
09904
09905 ast_mutex_unlock(&iaxsl[fr->callno]);
09906 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
09907 ast_mutex_lock(&iaxsl[fr->callno]);
09908
09909 if (!iaxs[fr->callno]) {
09910 ast_mutex_unlock(&iaxsl[fr->callno]);
09911 return 1;
09912 }
09913 } else
09914 exists = 0;
09915
09916 save_osptoken(fr, &ies);
09917 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
09918 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
09919 memset(&ied0, 0, sizeof(ied0));
09920 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09921 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09922 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09923 if (!iaxs[fr->callno]) {
09924 ast_mutex_unlock(&iaxsl[fr->callno]);
09925 return 1;
09926 }
09927 if (authdebug)
09928 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);
09929 } else {
09930
09931
09932 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09933 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09934 using_prefs = "reqonly";
09935 } else {
09936 using_prefs = "disabled";
09937 }
09938 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
09939 memset(&pref, 0, sizeof(pref));
09940 strcpy(caller_pref_buf, "disabled");
09941 strcpy(host_pref_buf, "disabled");
09942 } else {
09943 using_prefs = "mine";
09944
09945 if (ies.codec_prefs)
09946 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
09947 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09948
09949 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09950 pref = iaxs[fr->callno]->rprefs;
09951 using_prefs = "caller";
09952 } else {
09953 pref = iaxs[fr->callno]->prefs;
09954 }
09955 } else
09956 pref = iaxs[fr->callno]->prefs;
09957
09958 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
09959 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
09960 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
09961 }
09962 if (!format) {
09963 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09964 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
09965 if (!format) {
09966 memset(&ied0, 0, sizeof(ied0));
09967 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09968 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09969 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09970 if (!iaxs[fr->callno]) {
09971 ast_mutex_unlock(&iaxsl[fr->callno]);
09972 return 1;
09973 }
09974 if (authdebug) {
09975 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09976 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);
09977 else
09978 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);
09979 }
09980 } else {
09981
09982 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09983 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
09984 format = 0;
09985 } else {
09986 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09987 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
09988 memset(&pref, 0, sizeof(pref));
09989 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09990 strcpy(caller_pref_buf,"disabled");
09991 strcpy(host_pref_buf,"disabled");
09992 } else {
09993 using_prefs = "mine";
09994 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09995
09996 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09997 pref = iaxs[fr->callno]->prefs;
09998 } else {
09999 pref = iaxs[fr->callno]->rprefs;
10000 using_prefs = "caller";
10001 }
10002 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10003
10004 } else
10005 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10006 }
10007 }
10008
10009 if (!format) {
10010 memset(&ied0, 0, sizeof(ied0));
10011 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10012 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10013 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10014 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10015 if (!iaxs[fr->callno]) {
10016 ast_mutex_unlock(&iaxsl[fr->callno]);
10017 return 1;
10018 }
10019 if (authdebug)
10020 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);
10021 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10022 break;
10023 }
10024 }
10025 }
10026 if (format) {
10027
10028 memset(&ied1, 0, sizeof(ied1));
10029 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10030 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10031 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10032 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10033 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10034 "%srequested format = %s,\n"
10035 "%srequested prefs = %s,\n"
10036 "%sactual format = %s,\n"
10037 "%shost prefs = %s,\n"
10038 "%spriority = %s\n",
10039 ast_inet_ntoa(sin.sin_addr),
10040 VERBOSE_PREFIX_4,
10041 ast_getformatname(iaxs[fr->callno]->peerformat),
10042 VERBOSE_PREFIX_4,
10043 caller_pref_buf,
10044 VERBOSE_PREFIX_4,
10045 ast_getformatname(format),
10046 VERBOSE_PREFIX_4,
10047 host_pref_buf,
10048 VERBOSE_PREFIX_4,
10049 using_prefs);
10050
10051 iaxs[fr->callno]->chosenformat = format;
10052 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
10053 } else {
10054 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10055
10056 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10057 }
10058 }
10059 }
10060 break;
10061 }
10062 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10063 merge_encryption(iaxs[fr->callno],ies.encmethods);
10064 else
10065 iaxs[fr->callno]->encmethods = 0;
10066 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10067 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10068 if (!iaxs[fr->callno]) {
10069 ast_mutex_unlock(&iaxsl[fr->callno]);
10070 return 1;
10071 }
10072 break;
10073 case IAX_COMMAND_DPREQ:
10074
10075 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10076 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10077 if (iaxcompat) {
10078
10079 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10080 } else {
10081
10082 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10083 }
10084 }
10085 break;
10086 case IAX_COMMAND_HANGUP:
10087 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10088 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10089
10090 if (ies.causecode && iaxs[fr->callno]->owner)
10091 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10092
10093 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10094 iax2_destroy(fr->callno);
10095 break;
10096 case IAX_COMMAND_REJECT:
10097
10098 if (ies.causecode && iaxs[fr->callno]->owner)
10099 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10100
10101 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10102 if (iaxs[fr->callno]->owner && authdebug)
10103 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10104 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10105 ies.cause ? ies.cause : "<Unknown>");
10106 ast_debug(1, "Immediately destroying %d, having received reject\n",
10107 fr->callno);
10108 }
10109
10110 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10111 fr->ts, NULL, 0, fr->iseqno);
10112 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
10113 iaxs[fr->callno]->error = EPERM;
10114 iax2_destroy(fr->callno);
10115 break;
10116 case IAX_COMMAND_TRANSFER:
10117 {
10118 struct ast_channel *bridged_chan;
10119
10120 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
10121
10122
10123 ast_mutex_unlock(&iaxsl[fr->callno]);
10124 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
10125 ast_mutex_lock(&iaxsl[fr->callno]);
10126 if (!iaxs[fr->callno]) {
10127 ast_mutex_unlock(&iaxsl[fr->callno]);
10128 return 1;
10129 }
10130
10131 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
10132 if (!strcmp(ies.called_number, ast_parking_ext())) {
10133 struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
10134 ast_mutex_unlock(&iaxsl[fr->callno]);
10135 if (iax_park(bridged_chan, saved_channel)) {
10136 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
10137 } else {
10138 ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
10139 }
10140 ast_mutex_lock(&iaxsl[fr->callno]);
10141 } else {
10142 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
10143 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
10144 ies.called_number, iaxs[fr->callno]->context);
10145 else {
10146 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
10147 ies.called_number, iaxs[fr->callno]->context);
10148 }
10149 }
10150 } else {
10151 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10152 }
10153
10154 break;
10155 }
10156 case IAX_COMMAND_ACCEPT:
10157
10158 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10159 break;
10160 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10161
10162 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10163 iax2_destroy(fr->callno);
10164 break;
10165 }
10166 if (ies.format) {
10167 iaxs[fr->callno]->peerformat = ies.format;
10168 } else {
10169 if (iaxs[fr->callno]->owner)
10170 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10171 else
10172 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10173 }
10174 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));
10175 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10176 memset(&ied0, 0, sizeof(ied0));
10177 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10178 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10179 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10180 if (!iaxs[fr->callno]) {
10181 ast_mutex_unlock(&iaxsl[fr->callno]);
10182 return 1;
10183 }
10184 if (authdebug)
10185 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);
10186 } else {
10187 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10188 if (iaxs[fr->callno]->owner) {
10189
10190 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10191 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10192 retryowner2:
10193 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
10194 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
10195 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
10196 }
10197
10198 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10199
10200 if (iaxs[fr->callno]->owner->writeformat)
10201 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10202 if (iaxs[fr->callno]->owner->readformat)
10203 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10204 ast_channel_unlock(iaxs[fr->callno]->owner);
10205 }
10206 }
10207 }
10208 if (iaxs[fr->callno]) {
10209 AST_LIST_LOCK(&dpcache);
10210 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10211 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10212 iax2_dprequest(dp, fr->callno);
10213 AST_LIST_UNLOCK(&dpcache);
10214 }
10215 break;
10216 case IAX_COMMAND_POKE:
10217
10218 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10219 if (!iaxs[fr->callno]) {
10220 ast_mutex_unlock(&iaxsl[fr->callno]);
10221 return 1;
10222 }
10223 break;
10224 case IAX_COMMAND_PING:
10225 {
10226 struct iax_ie_data pingied;
10227 construct_rr(iaxs[fr->callno], &pingied);
10228
10229 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10230 }
10231 break;
10232 case IAX_COMMAND_PONG:
10233
10234 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10235
10236 save_rr(fr, &ies);
10237
10238
10239 log_jitterstats(fr->callno);
10240
10241 if (iaxs[fr->callno]->peerpoke) {
10242 peer = iaxs[fr->callno]->peerpoke;
10243 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10244 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10245 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10246 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);
10247 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10248 }
10249 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10250 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10251 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10252 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);
10253 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10254 }
10255 }
10256 peer->lastms = iaxs[fr->callno]->pingtime;
10257 if (peer->smoothing && (peer->lastms > -1))
10258 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10259 else if (peer->smoothing && peer->lastms < 0)
10260 peer->historicms = (0 + peer->historicms) / 2;
10261 else
10262 peer->historicms = iaxs[fr->callno]->pingtime;
10263
10264
10265 if (peer->pokeexpire > -1) {
10266 if (!ast_sched_del(sched, peer->pokeexpire)) {
10267 peer_unref(peer);
10268 peer->pokeexpire = -1;
10269 }
10270 }
10271
10272 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10273 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10274 else
10275 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10276 if (peer->pokeexpire == -1)
10277 peer_unref(peer);
10278
10279 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10280
10281 iax2_destroy(fr->callno);
10282 peer->callno = 0;
10283 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10284 }
10285 break;
10286 case IAX_COMMAND_LAGRQ:
10287 case IAX_COMMAND_LAGRP:
10288 f.src = "LAGRQ";
10289 f.mallocd = 0;
10290 f.offset = 0;
10291 f.samples = 0;
10292 iax_frame_wrap(fr, &f);
10293 if(f.subclass == IAX_COMMAND_LAGRQ) {
10294
10295 fr->af.subclass = IAX_COMMAND_LAGRP;
10296 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10297 } else {
10298
10299 unsigned int ts;
10300
10301 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10302 iaxs[fr->callno]->lag = ts - fr->ts;
10303 if (iaxdebug)
10304 ast_debug(1, "Peer %s lag measured as %dms\n",
10305 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10306 }
10307 break;
10308 case IAX_COMMAND_AUTHREQ:
10309 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10310 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>");
10311 break;
10312 }
10313 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10314 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10315 .subclass = AST_CONTROL_HANGUP,
10316 };
10317 ast_log(LOG_WARNING,
10318 "I don't know how to authenticate %s to %s\n",
10319 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10320 iax2_queue_frame(fr->callno, &hangup_fr);
10321 }
10322 if (!iaxs[fr->callno]) {
10323 ast_mutex_unlock(&iaxsl[fr->callno]);
10324 return 1;
10325 }
10326 break;
10327 case IAX_COMMAND_AUTHREP:
10328
10329 if (delayreject)
10330 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10331
10332 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10333 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>");
10334 break;
10335 }
10336 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10337 if (authdebug)
10338 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);
10339 memset(&ied0, 0, sizeof(ied0));
10340 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10341 break;
10342 }
10343 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10344
10345 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10346 } else
10347 exists = 0;
10348 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10349 if (authdebug)
10350 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);
10351 memset(&ied0, 0, sizeof(ied0));
10352 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10353 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10354 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10355 if (!iaxs[fr->callno]) {
10356 ast_mutex_unlock(&iaxsl[fr->callno]);
10357 return 1;
10358 }
10359 } else {
10360
10361 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10362 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10363 using_prefs = "reqonly";
10364 } else {
10365 using_prefs = "disabled";
10366 }
10367 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10368 memset(&pref, 0, sizeof(pref));
10369 strcpy(caller_pref_buf, "disabled");
10370 strcpy(host_pref_buf, "disabled");
10371 } else {
10372 using_prefs = "mine";
10373 if (ies.codec_prefs)
10374 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10375 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10376 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10377 pref = iaxs[fr->callno]->rprefs;
10378 using_prefs = "caller";
10379 } else {
10380 pref = iaxs[fr->callno]->prefs;
10381 }
10382 } else
10383 pref = iaxs[fr->callno]->prefs;
10384
10385 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10386 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10387 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10388 }
10389 if (!format) {
10390 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10391 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);
10392 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10393 }
10394 if (!format) {
10395 if (authdebug) {
10396 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10397 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);
10398 else
10399 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);
10400 }
10401 memset(&ied0, 0, sizeof(ied0));
10402 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10403 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10404 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10405 if (!iaxs[fr->callno]) {
10406 ast_mutex_unlock(&iaxsl[fr->callno]);
10407 return 1;
10408 }
10409 } else {
10410
10411 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10412 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10413 format = 0;
10414 } else {
10415 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10416 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10417 memset(&pref, 0, sizeof(pref));
10418 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10419 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10420 strcpy(caller_pref_buf,"disabled");
10421 strcpy(host_pref_buf,"disabled");
10422 } else {
10423 using_prefs = "mine";
10424 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10425
10426 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10427 pref = iaxs[fr->callno]->prefs;
10428 } else {
10429 pref = iaxs[fr->callno]->rprefs;
10430 using_prefs = "caller";
10431 }
10432 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10433 } else
10434 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10435 }
10436 }
10437 if (!format) {
10438 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10439 if (authdebug) {
10440 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10441 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);
10442 else
10443 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);
10444 }
10445 memset(&ied0, 0, sizeof(ied0));
10446 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10447 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10448 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10449 if (!iaxs[fr->callno]) {
10450 ast_mutex_unlock(&iaxsl[fr->callno]);
10451 return 1;
10452 }
10453 }
10454 }
10455 }
10456 if (format) {
10457
10458 memset(&ied1, 0, sizeof(ied1));
10459 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10460 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10461 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10462 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10463 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
10464 "%srequested format = %s,\n"
10465 "%srequested prefs = %s,\n"
10466 "%sactual format = %s,\n"
10467 "%shost prefs = %s,\n"
10468 "%spriority = %s\n",
10469 ast_inet_ntoa(sin.sin_addr),
10470 VERBOSE_PREFIX_4,
10471 ast_getformatname(iaxs[fr->callno]->peerformat),
10472 VERBOSE_PREFIX_4,
10473 caller_pref_buf,
10474 VERBOSE_PREFIX_4,
10475 ast_getformatname(format),
10476 VERBOSE_PREFIX_4,
10477 host_pref_buf,
10478 VERBOSE_PREFIX_4,
10479 using_prefs);
10480
10481 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10482 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
10483 iax2_destroy(fr->callno);
10484 else if (ies.vars) {
10485 struct ast_datastore *variablestore;
10486 struct ast_variable *var, *prev = NULL;
10487 AST_LIST_HEAD(, ast_var_t) *varlist;
10488 varlist = ast_calloc(1, sizeof(*varlist));
10489 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10490 if (variablestore && varlist) {
10491 variablestore->data = varlist;
10492 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10493 AST_LIST_HEAD_INIT(varlist);
10494 ast_debug(1, "I can haz IAX vars? w00t\n");
10495 for (var = ies.vars; var; var = var->next) {
10496 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10497 if (prev)
10498 ast_free(prev);
10499 prev = var;
10500 if (!newvar) {
10501
10502 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10503 } else {
10504 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10505 }
10506 }
10507 if (prev)
10508 ast_free(prev);
10509 ies.vars = NULL;
10510 ast_channel_datastore_add(c, variablestore);
10511 } else {
10512 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10513 if (variablestore)
10514 ast_datastore_free(variablestore);
10515 if (varlist)
10516 ast_free(varlist);
10517 }
10518 }
10519 } else {
10520 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10521
10522 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10523 }
10524 }
10525 }
10526 break;
10527 case IAX_COMMAND_DIAL:
10528 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
10529 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10530 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
10531 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
10532 if (authdebug)
10533 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);
10534 memset(&ied0, 0, sizeof(ied0));
10535 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10536 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10537 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10538 if (!iaxs[fr->callno]) {
10539 ast_mutex_unlock(&iaxsl[fr->callno]);
10540 return 1;
10541 }
10542 } else {
10543 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10544 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
10545 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10546 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
10547 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
10548 iax2_destroy(fr->callno);
10549 else if (ies.vars) {
10550 struct ast_datastore *variablestore;
10551 struct ast_variable *var, *prev = NULL;
10552 AST_LIST_HEAD(, ast_var_t) *varlist;
10553 varlist = ast_calloc(1, sizeof(*varlist));
10554 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10555 ast_debug(1, "I can haz IAX vars? w00t\n");
10556 if (variablestore && varlist) {
10557 variablestore->data = varlist;
10558 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10559 AST_LIST_HEAD_INIT(varlist);
10560 for (var = ies.vars; var; var = var->next) {
10561 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10562 if (prev)
10563 ast_free(prev);
10564 prev = var;
10565 if (!newvar) {
10566
10567 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10568 } else {
10569 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10570 }
10571 }
10572 if (prev)
10573 ast_free(prev);
10574 ies.vars = NULL;
10575 ast_channel_datastore_add(c, variablestore);
10576 } else {
10577 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10578 if (variablestore)
10579 ast_datastore_free(variablestore);
10580 if (varlist)
10581 ast_free(varlist);
10582 }
10583 }
10584 }
10585 }
10586 break;
10587 case IAX_COMMAND_INVAL:
10588 iaxs[fr->callno]->error = ENOTCONN;
10589 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
10590 iax2_destroy(fr->callno);
10591 ast_debug(1, "Destroying call %d\n", fr->callno);
10592 break;
10593 case IAX_COMMAND_VNAK:
10594 ast_debug(1, "Received VNAK: resending outstanding frames\n");
10595
10596 vnak_retransmit(fr->callno, fr->iseqno);
10597 break;
10598 case IAX_COMMAND_REGREQ:
10599 case IAX_COMMAND_REGREL:
10600
10601 if (delayreject)
10602 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10603 if (register_verify(fr->callno, &sin, &ies)) {
10604 if (!iaxs[fr->callno]) {
10605 ast_mutex_unlock(&iaxsl[fr->callno]);
10606 return 1;
10607 }
10608
10609 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
10610 break;
10611 }
10612 if (!iaxs[fr->callno]) {
10613 ast_mutex_unlock(&iaxsl[fr->callno]);
10614 return 1;
10615 }
10616 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
10617 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
10618
10619 if (f.subclass == IAX_COMMAND_REGREL)
10620 memset(&sin, 0, sizeof(sin));
10621 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
10622 ast_log(LOG_WARNING, "Registry error\n");
10623 if (!iaxs[fr->callno]) {
10624 ast_mutex_unlock(&iaxsl[fr->callno]);
10625 return 1;
10626 }
10627 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10628 ast_mutex_unlock(&iaxsl[fr->callno]);
10629 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10630 ast_mutex_lock(&iaxsl[fr->callno]);
10631 if (!iaxs[fr->callno]) {
10632 ast_mutex_unlock(&iaxsl[fr->callno]);
10633 return 1;
10634 }
10635 }
10636 break;
10637 }
10638 registry_authrequest(fr->callno);
10639 if (!iaxs[fr->callno]) {
10640 ast_mutex_unlock(&iaxsl[fr->callno]);
10641 return 1;
10642 }
10643 break;
10644 case IAX_COMMAND_REGACK:
10645 if (iax2_ack_registry(&ies, &sin, fr->callno))
10646 ast_log(LOG_WARNING, "Registration failure\n");
10647
10648 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10649 iax2_destroy(fr->callno);
10650 break;
10651 case IAX_COMMAND_REGREJ:
10652 if (iaxs[fr->callno]->reg) {
10653 if (authdebug) {
10654 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));
10655 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>");
10656 }
10657 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
10658 }
10659
10660 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10661 iax2_destroy(fr->callno);
10662 break;
10663 case IAX_COMMAND_REGAUTH:
10664
10665 if (registry_rerequest(&ies, fr->callno, &sin)) {
10666 memset(&ied0, 0, sizeof(ied0));
10667 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
10668 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
10669 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10670 if (!iaxs[fr->callno]) {
10671 ast_mutex_unlock(&iaxsl[fr->callno]);
10672 return 1;
10673 }
10674 }
10675 break;
10676 case IAX_COMMAND_TXREJ:
10677 iaxs[fr->callno]->transferring = 0;
10678 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10679 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
10680 if (iaxs[fr->callno]->bridgecallno) {
10681 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
10682 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
10683 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
10684 }
10685 }
10686 break;
10687 case IAX_COMMAND_TXREADY:
10688 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
10689 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
10690 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
10691 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
10692 else
10693 iaxs[fr->callno]->transferring = TRANSFER_READY;
10694 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10695 if (iaxs[fr->callno]->bridgecallno) {
10696 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
10697 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
10698
10699 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
10700 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10701 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10702
10703 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
10704 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
10705
10706 memset(&ied0, 0, sizeof(ied0));
10707 memset(&ied1, 0, sizeof(ied1));
10708 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10709 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10710 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
10711 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
10712 } else {
10713 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10714 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10715
10716 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
10717 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
10718 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
10719 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10720
10721
10722 stop_stuff(fr->callno);
10723 stop_stuff(iaxs[fr->callno]->bridgecallno);
10724
10725 memset(&ied0, 0, sizeof(ied0));
10726 memset(&ied1, 0, sizeof(ied1));
10727 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10728 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10729 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
10730 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
10731 }
10732
10733 }
10734 }
10735 }
10736 break;
10737 case IAX_COMMAND_TXREQ:
10738 try_transfer(iaxs[fr->callno], &ies);
10739 break;
10740 case IAX_COMMAND_TXCNT:
10741 if (iaxs[fr->callno]->transferring)
10742 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
10743 break;
10744 case IAX_COMMAND_TXREL:
10745
10746 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10747 complete_transfer(fr->callno, &ies);
10748 stop_stuff(fr->callno);
10749 break;
10750 case IAX_COMMAND_TXMEDIA:
10751 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
10752 AST_LIST_LOCK(&frame_queue);
10753 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10754
10755 if ((fr->callno == cur->callno) && (cur->transfer))
10756 cur->retries = -1;
10757 }
10758 AST_LIST_UNLOCK(&frame_queue);
10759
10760 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
10761 }
10762 break;
10763 case IAX_COMMAND_RTKEY:
10764 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
10765 ast_log(LOG_WARNING,
10766 "we've been told to rotate our encryption key, "
10767 "but this isn't an encrypted call. bad things will happen.\n"
10768 );
10769 break;
10770 }
10771
10772 IAX_DEBUGDIGEST("Receiving", ies.challenge);
10773
10774 ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
10775 break;
10776 case IAX_COMMAND_DPREP:
10777 complete_dpreply(iaxs[fr->callno], &ies);
10778 break;
10779 case IAX_COMMAND_UNSUPPORT:
10780 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
10781 break;
10782 case IAX_COMMAND_FWDOWNL:
10783
10784 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
10785 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
10786 break;
10787 }
10788 memset(&ied0, 0, sizeof(ied0));
10789 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
10790 if (res < 0)
10791 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10792 else if (res > 0)
10793 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
10794 else
10795 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
10796 if (!iaxs[fr->callno]) {
10797 ast_mutex_unlock(&iaxsl[fr->callno]);
10798 return 1;
10799 }
10800 break;
10801 case IAX_COMMAND_CALLTOKEN:
10802 {
10803 struct iax_frame *cur;
10804 int found = 0;
10805 AST_LIST_LOCK(&frame_queue);
10806 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10807
10808
10809
10810 if (cur->callno == fr->callno) {
10811 found = 1;
10812 break;
10813 }
10814 }
10815 AST_LIST_UNLOCK(&frame_queue);
10816
10817
10818 if (cur && found && ies.calltoken && ies.calltokendata) {
10819 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
10820 }
10821 break;
10822 }
10823 default:
10824 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
10825 memset(&ied0, 0, sizeof(ied0));
10826 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
10827 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
10828 }
10829
10830 if (ies.vars) {
10831 ast_variables_destroy(ies.vars);
10832 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
10833 ies.vars = NULL;
10834 }
10835
10836
10837 if ((f.subclass != IAX_COMMAND_ACK) &&
10838 (f.subclass != IAX_COMMAND_TXCNT) &&
10839 (f.subclass != IAX_COMMAND_TXACC) &&
10840 (f.subclass != IAX_COMMAND_INVAL) &&
10841 (f.subclass != IAX_COMMAND_VNAK)) {
10842 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
10843 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10844 }
10845 ast_mutex_unlock(&iaxsl[fr->callno]);
10846 return 1;
10847 }
10848
10849 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
10850 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10851 } else if (minivid) {
10852 f.frametype = AST_FRAME_VIDEO;
10853 if (iaxs[fr->callno]->videoformat > 0)
10854 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
10855 else {
10856 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
10857 iax2_vnak(fr->callno);
10858 ast_mutex_unlock(&iaxsl[fr->callno]);
10859 return 1;
10860 }
10861 f.datalen = res - sizeof(*vh);
10862 if (f.datalen)
10863 f.data.ptr = thread->buf + sizeof(*vh);
10864 else
10865 f.data.ptr = NULL;
10866 #ifdef IAXTESTS
10867 if (test_resync) {
10868 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
10869 } else
10870 #endif
10871 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
10872 } else {
10873
10874 f.frametype = AST_FRAME_VOICE;
10875 if (iaxs[fr->callno]->voiceformat > 0)
10876 f.subclass = iaxs[fr->callno]->voiceformat;
10877 else {
10878 ast_debug(1, "Received mini frame before first full voice frame\n");
10879 iax2_vnak(fr->callno);
10880 ast_mutex_unlock(&iaxsl[fr->callno]);
10881 return 1;
10882 }
10883 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
10884 if (f.datalen < 0) {
10885 ast_log(LOG_WARNING, "Datalen < 0?\n");
10886 ast_mutex_unlock(&iaxsl[fr->callno]);
10887 return 1;
10888 }
10889 if (f.datalen)
10890 f.data.ptr = thread->buf + sizeof(*mh);
10891 else
10892 f.data.ptr = NULL;
10893 #ifdef IAXTESTS
10894 if (test_resync) {
10895 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
10896 } else
10897 #endif
10898 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
10899
10900 }
10901
10902 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10903 ast_mutex_unlock(&iaxsl[fr->callno]);
10904 return 1;
10905 }
10906
10907 f.src = "IAX2";
10908 f.mallocd = 0;
10909 f.offset = 0;
10910 f.len = 0;
10911 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
10912 f.samples = ast_codec_get_samples(&f);
10913
10914 if (f.subclass == AST_FORMAT_SLINEAR)
10915 ast_frame_byteswap_be(&f);
10916 } else
10917 f.samples = 0;
10918 iax_frame_wrap(fr, &f);
10919
10920
10921 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
10922
10923 fr->outoforder = 0;
10924 } else {
10925 if (iaxdebug && iaxs[fr->callno])
10926 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);
10927 fr->outoforder = -1;
10928 }
10929 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
10930 duped_fr = iaxfrdup2(fr);
10931 if (duped_fr) {
10932 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
10933 }
10934 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
10935 iaxs[fr->callno]->last = fr->ts;
10936 #if 1
10937 if (iaxdebug)
10938 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10939 #endif
10940 }
10941
10942
10943 ast_mutex_unlock(&iaxsl[fr->callno]);
10944 return 1;
10945 }
10946
10947
10948 static void iax2_process_thread_cleanup(void *data)
10949 {
10950 struct iax2_thread *thread = data;
10951 ast_mutex_destroy(&thread->lock);
10952 ast_cond_destroy(&thread->cond);
10953 ast_mutex_destroy(&thread->init_lock);
10954 ast_cond_destroy(&thread->init_cond);
10955 ast_free(thread);
10956 ast_atomic_dec_and_test(&iaxactivethreadcount);
10957 }
10958
10959 static void *iax2_process_thread(void *data)
10960 {
10961 struct iax2_thread *thread = data;
10962 struct timeval wait;
10963 struct timespec ts;
10964 int put_into_idle = 0;
10965 int first_time = 1;
10966
10967 ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
10968 pthread_cleanup_push(iax2_process_thread_cleanup, data);
10969 for(;;) {
10970
10971 ast_mutex_lock(&thread->lock);
10972
10973
10974 if (first_time) {
10975 signal_condition(&thread->init_lock, &thread->init_cond);
10976 first_time = 0;
10977 }
10978
10979
10980 if (put_into_idle)
10981 insert_idle_thread(thread);
10982
10983 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
10984 struct iax2_thread *t = NULL;
10985
10986 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
10987 ts.tv_sec = wait.tv_sec;
10988 ts.tv_nsec = wait.tv_usec * 1000;
10989 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
10990
10991
10992 if (!put_into_idle) {
10993 ast_mutex_unlock(&thread->lock);
10994 break;
10995 }
10996 AST_LIST_LOCK(&dynamic_list);
10997
10998 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
10999 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11000 AST_LIST_UNLOCK(&dynamic_list);
11001 if (t) {
11002
11003
11004
11005 ast_mutex_unlock(&thread->lock);
11006 break;
11007 }
11008
11009
11010
11011 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11012 ts.tv_sec = wait.tv_sec;
11013 ts.tv_nsec = wait.tv_usec * 1000;
11014 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
11015 {
11016 ast_mutex_unlock(&thread->lock);
11017 break;
11018 }
11019 }
11020 } else {
11021 ast_cond_wait(&thread->cond, &thread->lock);
11022 }
11023
11024
11025 put_into_idle = 1;
11026
11027 ast_mutex_unlock(&thread->lock);
11028
11029 if (thread->iostate == IAX_IOSTATE_IDLE)
11030 continue;
11031
11032
11033 AST_LIST_LOCK(&active_list);
11034 AST_LIST_INSERT_HEAD(&active_list, thread, list);
11035 AST_LIST_UNLOCK(&active_list);
11036
11037
11038 switch(thread->iostate) {
11039 case IAX_IOSTATE_READY:
11040 thread->actions++;
11041 thread->iostate = IAX_IOSTATE_PROCESSING;
11042 socket_process(thread);
11043 handle_deferred_full_frames(thread);
11044 break;
11045 case IAX_IOSTATE_SCHEDREADY:
11046 thread->actions++;
11047 thread->iostate = IAX_IOSTATE_PROCESSING;
11048 #ifdef SCHED_MULTITHREADED
11049 thread->schedfunc(thread->scheddata);
11050 #endif
11051 default:
11052 break;
11053 }
11054 time(&thread->checktime);
11055 thread->iostate = IAX_IOSTATE_IDLE;
11056 #ifdef DEBUG_SCHED_MULTITHREAD
11057 thread->curfunc[0]='\0';
11058 #endif
11059
11060
11061 AST_LIST_LOCK(&active_list);
11062 AST_LIST_REMOVE(&active_list, thread, list);
11063 AST_LIST_UNLOCK(&active_list);
11064
11065
11066 handle_deferred_full_frames(thread);
11067 }
11068
11069
11070
11071
11072
11073 AST_LIST_LOCK(&idle_list);
11074 AST_LIST_REMOVE(&idle_list, thread, list);
11075 AST_LIST_UNLOCK(&idle_list);
11076
11077 AST_LIST_LOCK(&dynamic_list);
11078 AST_LIST_REMOVE(&dynamic_list, thread, list);
11079 AST_LIST_UNLOCK(&dynamic_list);
11080
11081
11082
11083
11084 pthread_cleanup_pop(1);
11085 return NULL;
11086 }
11087
11088 static int iax2_do_register(struct iax2_registry *reg)
11089 {
11090 struct iax_ie_data ied;
11091 if (iaxdebug)
11092 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11093
11094 if (reg->dnsmgr &&
11095 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
11096
11097 ast_dnsmgr_refresh(reg->dnsmgr);
11098 }
11099
11100
11101
11102
11103
11104 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11105 int callno = reg->callno;
11106 ast_mutex_lock(&iaxsl[callno]);
11107 iax2_destroy(callno);
11108 ast_mutex_unlock(&iaxsl[callno]);
11109 reg->callno = 0;
11110 }
11111 if (!reg->addr.sin_addr.s_addr) {
11112 if (iaxdebug)
11113 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11114
11115 reg->expire = iax2_sched_replace(reg->expire, sched,
11116 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11117 return -1;
11118 }
11119
11120 if (!reg->callno) {
11121 ast_debug(3, "Allocate call number\n");
11122 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
11123 if (reg->callno < 1) {
11124 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11125 return -1;
11126 } else
11127 ast_debug(3, "Registration created on call %d\n", reg->callno);
11128 iaxs[reg->callno]->reg = reg;
11129 ast_mutex_unlock(&iaxsl[reg->callno]);
11130 }
11131
11132 reg->expire = iax2_sched_replace(reg->expire, sched,
11133 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11134
11135 memset(&ied, 0, sizeof(ied));
11136 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11137 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11138 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11139 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11140 reg->regstate = REG_STATE_REGSENT;
11141 return 0;
11142 }
11143
11144 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
11145 {
11146
11147
11148 struct iax_ie_data provdata;
11149 struct iax_ie_data ied;
11150 unsigned int sig;
11151 struct sockaddr_in sin;
11152 int callno;
11153 struct create_addr_info cai;
11154
11155 memset(&cai, 0, sizeof(cai));
11156
11157 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11158
11159 if (iax_provision_build(&provdata, &sig, template, force)) {
11160 ast_debug(1, "No provisioning found for template '%s'\n", template);
11161 return 0;
11162 }
11163
11164 if (end) {
11165 memcpy(&sin, end, sizeof(sin));
11166 cai.sockfd = sockfd;
11167 } else if (create_addr(dest, NULL, &sin, &cai))
11168 return -1;
11169
11170
11171 memset(&ied, 0, sizeof(ied));
11172 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11173
11174 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11175 if (!callno)
11176 return -1;
11177
11178 if (iaxs[callno]) {
11179
11180 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11181 sched, 15000, auto_hangup, (void *)(long)callno);
11182 ast_set_flag(iaxs[callno], IAX_PROVISION);
11183
11184 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11185 }
11186 ast_mutex_unlock(&iaxsl[callno]);
11187
11188 return 1;
11189 }
11190
11191 static char *papp = "IAX2Provision";
11192 static char *psyn = "Provision a calling IAXy with a given template";
11193 static char *pdescrip =
11194 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
11195 "the calling entity is in fact an IAXy) with the given template or\n"
11196 "default if one is not specified. Returns -1 on error or 0 on success.\n";
11197
11198
11199
11200
11201 static int iax2_prov_app(struct ast_channel *chan, void *data)
11202 {
11203 int res;
11204 char *sdata;
11205 char *opts;
11206 int force =0;
11207 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11208 if (ast_strlen_zero(data))
11209 data = "default";
11210 sdata = ast_strdupa(data);
11211 opts = strchr(sdata, '|');
11212 if (opts)
11213 *opts='\0';
11214
11215 if (chan->tech != &iax2_tech) {
11216 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11217 return -1;
11218 }
11219 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11220 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11221 return -1;
11222 }
11223 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11224 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11225 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11226 sdata, res);
11227 return res;
11228 }
11229
11230 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11231 {
11232 int force = 0;
11233 int res;
11234
11235 switch (cmd) {
11236 case CLI_INIT:
11237 e->command = "iax2 provision";
11238 e->usage =
11239 "Usage: iax2 provision <host> <template> [forced]\n"
11240 " Provisions the given peer or IP address using a template\n"
11241 " matching either 'template' or '*' if the template is not\n"
11242 " found. If 'forced' is specified, even empty provisioning\n"
11243 " fields will be provisioned as empty fields.\n";
11244 return NULL;
11245 case CLI_GENERATE:
11246 if (a->pos == 3)
11247 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11248 return NULL;
11249 }
11250
11251 if (a->argc < 4)
11252 return CLI_SHOWUSAGE;
11253 if (a->argc > 4) {
11254 if (!strcasecmp(a->argv[4], "forced"))
11255 force = 1;
11256 else
11257 return CLI_SHOWUSAGE;
11258 }
11259 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11260 if (res < 0)
11261 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11262 else if (res < 1)
11263 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11264 else
11265 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11266 return CLI_SUCCESS;
11267 }
11268
11269 static void __iax2_poke_noanswer(const void *data)
11270 {
11271 struct iax2_peer *peer = (struct iax2_peer *)data;
11272 int callno;
11273
11274 if (peer->lastms > -1) {
11275 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11276 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11277 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11278 }
11279 if ((callno = peer->callno) > 0) {
11280 ast_mutex_lock(&iaxsl[callno]);
11281 iax2_destroy(callno);
11282 ast_mutex_unlock(&iaxsl[callno]);
11283 }
11284 peer->callno = 0;
11285 peer->lastms = -1;
11286
11287 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11288 if (peer->pokeexpire == -1)
11289 peer_unref(peer);
11290 }
11291
11292 static int iax2_poke_noanswer(const void *data)
11293 {
11294 struct iax2_peer *peer = (struct iax2_peer *)data;
11295 peer->pokeexpire = -1;
11296 #ifdef SCHED_MULTITHREADED
11297 if (schedule_action(__iax2_poke_noanswer, data))
11298 #endif
11299 __iax2_poke_noanswer(data);
11300 peer_unref(peer);
11301 return 0;
11302 }
11303
11304 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11305 {
11306 struct iax2_peer *peer = obj;
11307
11308 iax2_poke_peer(peer, 0);
11309
11310 return 0;
11311 }
11312
11313 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11314 {
11315 int callno;
11316 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
11317
11318
11319 peer->lastms = 0;
11320 peer->historicms = 0;
11321 peer->pokeexpire = -1;
11322 peer->callno = 0;
11323 return 0;
11324 }
11325
11326
11327 if ((callno = peer->callno) > 0) {
11328 ast_log(LOG_NOTICE, "Still have a callno...\n");
11329 ast_mutex_lock(&iaxsl[callno]);
11330 iax2_destroy(callno);
11331 ast_mutex_unlock(&iaxsl[callno]);
11332 }
11333 if (heldcall)
11334 ast_mutex_unlock(&iaxsl[heldcall]);
11335 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
11336 if (heldcall)
11337 ast_mutex_lock(&iaxsl[heldcall]);
11338 if (peer->callno < 1) {
11339 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11340 return -1;
11341 }
11342
11343
11344 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11345 iaxs[peer->callno]->peerpoke = peer;
11346
11347 if (peer->pokeexpire > -1) {
11348 if (!ast_sched_del(sched, peer->pokeexpire)) {
11349 peer->pokeexpire = -1;
11350 peer_unref(peer);
11351 }
11352 }
11353
11354
11355
11356 if (peer->lastms < 0)
11357 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11358 else
11359 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11360
11361 if (peer->pokeexpire == -1)
11362 peer_unref(peer);
11363
11364
11365 ast_mutex_lock(&iaxsl[callno]);
11366 if (iaxs[callno]) {
11367 struct iax_ie_data ied = {
11368 .buf = { 0 },
11369 .pos = 0,
11370 };
11371 add_empty_calltoken_ie(iaxs[callno], &ied);
11372 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11373 }
11374 ast_mutex_unlock(&iaxsl[callno]);
11375
11376 return 0;
11377 }
11378
11379 static void free_context(struct iax2_context *con)
11380 {
11381 struct iax2_context *conl;
11382 while(con) {
11383 conl = con;
11384 con = con->next;
11385 ast_free(conl);
11386 }
11387 }
11388
11389 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
11390 {
11391 int callno;
11392 int res;
11393 int fmt, native;
11394 struct sockaddr_in sin;
11395 struct ast_channel *c;
11396 struct parsed_dial_string pds;
11397 struct create_addr_info cai;
11398 char *tmpstr;
11399
11400 memset(&pds, 0, sizeof(pds));
11401 tmpstr = ast_strdupa(data);
11402 parse_dial_string(tmpstr, &pds);
11403
11404 if (ast_strlen_zero(pds.peer)) {
11405 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
11406 return NULL;
11407 }
11408
11409 memset(&cai, 0, sizeof(cai));
11410 cai.capability = iax2_capability;
11411
11412 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11413
11414
11415 if (create_addr(pds.peer, NULL, &sin, &cai)) {
11416 *cause = AST_CAUSE_UNREGISTERED;
11417 return NULL;
11418 }
11419
11420 if (pds.port)
11421 sin.sin_port = htons(atoi(pds.port));
11422
11423 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11424 if (callno < 1) {
11425 ast_log(LOG_WARNING, "Unable to create call\n");
11426 *cause = AST_CAUSE_CONGESTION;
11427 return NULL;
11428 }
11429
11430
11431 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11432 if (ast_test_flag(&cai, IAX_TRUNK)) {
11433 int new_callno;
11434 if ((new_callno = make_trunk(callno, 1)) != -1)
11435 callno = new_callno;
11436 }
11437 iaxs[callno]->maxtime = cai.maxtime;
11438 if (cai.found)
11439 ast_string_field_set(iaxs[callno], host, pds.peer);
11440
11441 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
11442
11443 ast_mutex_unlock(&iaxsl[callno]);
11444
11445 if (c) {
11446
11447 if (c->nativeformats & format)
11448 c->nativeformats &= format;
11449 else {
11450 native = c->nativeformats;
11451 fmt = format;
11452 res = ast_translator_best_choice(&fmt, &native);
11453 if (res < 0) {
11454 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
11455 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
11456 ast_hangup(c);
11457 return NULL;
11458 }
11459 c->nativeformats = native;
11460 }
11461 c->readformat = ast_best_codec(c->nativeformats);
11462 c->writeformat = c->readformat;
11463 }
11464
11465 return c;
11466 }
11467
11468 static void *sched_thread(void *ignore)
11469 {
11470 int count;
11471 int res;
11472 struct timeval wait;
11473 struct timespec ts;
11474
11475 for (;;) {
11476 pthread_testcancel();
11477 ast_mutex_lock(&sched_lock);
11478 res = ast_sched_wait(sched);
11479 if ((res > 1000) || (res < 0))
11480 res = 1000;
11481 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
11482 ts.tv_sec = wait.tv_sec;
11483 ts.tv_nsec = wait.tv_usec * 1000;
11484 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
11485 ast_mutex_unlock(&sched_lock);
11486 pthread_testcancel();
11487
11488 count = ast_sched_runq(sched);
11489 if (count >= 20)
11490 ast_debug(1, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
11491 }
11492
11493 return NULL;
11494 }
11495
11496 static void *network_thread(void *ignore)
11497 {
11498
11499
11500 int res, count, wakeup;
11501 struct iax_frame *f;
11502
11503 if (timer)
11504 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
11505
11506 for(;;) {
11507 pthread_testcancel();
11508
11509
11510
11511 AST_LIST_LOCK(&frame_queue);
11512 count = 0;
11513 wakeup = -1;
11514 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
11515 if (f->sentyet)
11516 continue;
11517
11518
11519 if (ast_mutex_trylock(&iaxsl[f->callno])) {
11520 wakeup = 1;
11521 continue;
11522 }
11523
11524 f->sentyet = 1;
11525
11526 if (iaxs[f->callno]) {
11527 send_packet(f);
11528 count++;
11529 }
11530
11531 ast_mutex_unlock(&iaxsl[f->callno]);
11532
11533 if (f->retries < 0) {
11534
11535 AST_LIST_REMOVE_CURRENT(list);
11536
11537 iax_frame_free(f);
11538 } else {
11539
11540 f->retries++;
11541 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
11542 }
11543 }
11544 AST_LIST_TRAVERSE_SAFE_END;
11545 AST_LIST_UNLOCK(&frame_queue);
11546
11547 pthread_testcancel();
11548 if (count >= 20)
11549 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
11550
11551
11552 res = ast_io_wait(io, wakeup);
11553 if (res >= 0) {
11554 if (res >= 20)
11555 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
11556 }
11557 }
11558 return NULL;
11559 }
11560
11561 static int start_network_thread(void)
11562 {
11563 struct iax2_thread *thread;
11564 int threadcount = 0;
11565 int x;
11566 for (x = 0; x < iaxthreadcount; x++) {
11567 thread = ast_calloc(1, sizeof(*thread));
11568 if (thread) {
11569 thread->type = IAX_THREAD_TYPE_POOL;
11570 thread->threadnum = ++threadcount;
11571 ast_mutex_init(&thread->lock);
11572 ast_cond_init(&thread->cond, NULL);
11573 if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) {
11574 ast_log(LOG_WARNING, "Failed to create new thread!\n");
11575 ast_free(thread);
11576 thread = NULL;
11577 }
11578 AST_LIST_LOCK(&idle_list);
11579 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
11580 AST_LIST_UNLOCK(&idle_list);
11581 }
11582 }
11583 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
11584 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
11585 ast_verb(2, "%d helper threads started\n", threadcount);
11586 return 0;
11587 }
11588
11589 static struct iax2_context *build_context(const char *context)
11590 {
11591 struct iax2_context *con;
11592
11593 if ((con = ast_calloc(1, sizeof(*con))))
11594 ast_copy_string(con->context, context, sizeof(con->context));
11595
11596 return con;
11597 }
11598
11599 static int get_auth_methods(const char *value)
11600 {
11601 int methods = 0;
11602 if (strstr(value, "rsa"))
11603 methods |= IAX_AUTH_RSA;
11604 if (strstr(value, "md5"))
11605 methods |= IAX_AUTH_MD5;
11606 if (strstr(value, "plaintext"))
11607 methods |= IAX_AUTH_PLAINTEXT;
11608 return methods;
11609 }
11610
11611
11612
11613
11614
11615 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
11616 {
11617 int sd;
11618 int res;
11619
11620 sd = socket(AF_INET, SOCK_DGRAM, 0);
11621 if (sd < 0) {
11622 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
11623 return -1;
11624 }
11625
11626 res = bind(sd, sa, salen);
11627 if (res < 0) {
11628 ast_debug(1, "Can't bind: %s\n", strerror(errno));
11629 close(sd);
11630 return 1;
11631 }
11632
11633 close(sd);
11634 return 0;
11635 }
11636
11637
11638
11639
11640 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
11641 {
11642 struct sockaddr_in sin;
11643 int nonlocal = 1;
11644 int port = IAX_DEFAULT_PORTNO;
11645 int sockfd = defaultsockfd;
11646 char *tmp;
11647 char *addr;
11648 char *portstr;
11649
11650 if (!(tmp = ast_strdupa(srcaddr)))
11651 return -1;
11652
11653 addr = strsep(&tmp, ":");
11654 portstr = tmp;
11655
11656 if (portstr) {
11657 port = atoi(portstr);
11658 if (port < 1)
11659 port = IAX_DEFAULT_PORTNO;
11660 }
11661
11662 if (!ast_get_ip(&sin, addr)) {
11663 struct ast_netsock *sock;
11664 int res;
11665
11666 sin.sin_port = 0;
11667 sin.sin_family = AF_INET;
11668 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
11669 if (res == 0) {
11670
11671 sin.sin_port = htons(port);
11672 if (!(sock = ast_netsock_find(netsock, &sin)))
11673 sock = ast_netsock_find(outsock, &sin);
11674 if (sock) {
11675 sockfd = ast_netsock_sockfd(sock);
11676 nonlocal = 0;
11677 } else {
11678 unsigned int orig_saddr = sin.sin_addr.s_addr;
11679
11680 sin.sin_addr.s_addr = INADDR_ANY;
11681 if (ast_netsock_find(netsock, &sin)) {
11682 sin.sin_addr.s_addr = orig_saddr;
11683 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
11684 if (sock) {
11685 sockfd = ast_netsock_sockfd(sock);
11686 ast_netsock_unref(sock);
11687 nonlocal = 0;
11688 } else {
11689 nonlocal = 2;
11690 }
11691 }
11692 }
11693 }
11694 }
11695
11696 peer->sockfd = sockfd;
11697
11698 if (nonlocal == 1) {
11699 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
11700 srcaddr, peer->name);
11701 return -1;
11702 } else if (nonlocal == 2) {
11703 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
11704 srcaddr, peer->name);
11705 return -1;
11706 } else {
11707 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
11708 return 0;
11709 }
11710 }
11711
11712 static void peer_destructor(void *obj)
11713 {
11714 struct iax2_peer *peer = obj;
11715 int callno = peer->callno;
11716
11717 ast_free_ha(peer->ha);
11718
11719 if (callno > 0) {
11720 ast_mutex_lock(&iaxsl[callno]);
11721 iax2_destroy(callno);
11722 ast_mutex_unlock(&iaxsl[callno]);
11723 }
11724
11725 register_peer_exten(peer, 0);
11726
11727 if (peer->dnsmgr)
11728 ast_dnsmgr_release(peer->dnsmgr);
11729
11730 if (peer->mwi_event_sub)
11731 ast_event_unsubscribe(peer->mwi_event_sub);
11732
11733 ast_string_field_free_memory(peer);
11734 }
11735
11736
11737 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
11738 {
11739 struct iax2_peer *peer = NULL;
11740 struct ast_ha *oldha = NULL;
11741 int maskfound = 0;
11742 int found = 0;
11743 int firstpass = 1;
11744 struct iax2_peer tmp_peer = {
11745 .name = name,
11746 };
11747
11748 if (!temponly) {
11749 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
11750 if (peer && !ast_test_flag(peer, IAX_DELME))
11751 firstpass = 0;
11752 }
11753
11754 if (peer) {
11755 found++;
11756 if (firstpass) {
11757 oldha = peer->ha;
11758 peer->ha = NULL;
11759 }
11760 unlink_peer(peer);
11761 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
11762 peer->expire = -1;
11763 peer->pokeexpire = -1;
11764 peer->sockfd = defaultsockfd;
11765 if (ast_string_field_init(peer, 32))
11766 peer = peer_unref(peer);
11767 }
11768
11769 if (peer) {
11770 if (firstpass) {
11771 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11772 peer->encmethods = iax2_encryption;
11773 peer->adsi = adsi;
11774 ast_string_field_set(peer,secret,"");
11775 if (!found) {
11776 ast_string_field_set(peer, name, name);
11777 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11778 peer->expiry = min_reg_expire;
11779 }
11780 peer->prefs = prefs;
11781 peer->capability = iax2_capability;
11782 peer->smoothing = 0;
11783 peer->pokefreqok = DEFAULT_FREQ_OK;
11784 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
11785 peer->maxcallno = 0;
11786 peercnt_modify(0, 0, &peer->addr);
11787 peer->calltoken_required = CALLTOKEN_DEFAULT;
11788 ast_string_field_set(peer,context,"");
11789 ast_string_field_set(peer,peercontext,"");
11790 ast_clear_flag(peer, IAX_HASCALLERID);
11791 ast_string_field_set(peer, cid_name, "");
11792 ast_string_field_set(peer, cid_num, "");
11793 ast_string_field_set(peer, mohinterpret, mohinterpret);
11794 ast_string_field_set(peer, mohsuggest, mohsuggest);
11795 }
11796
11797 if (!v) {
11798 v = alt;
11799 alt = NULL;
11800 }
11801 while(v) {
11802 if (!strcasecmp(v->name, "secret")) {
11803 ast_string_field_set(peer, secret, v->value);
11804 } else if (!strcasecmp(v->name, "mailbox")) {
11805 ast_string_field_set(peer, mailbox, v->value);
11806 } else if (!strcasecmp(v->name, "hasvoicemail")) {
11807 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
11808 ast_string_field_set(peer, mailbox, name);
11809 }
11810 } else if (!strcasecmp(v->name, "mohinterpret")) {
11811 ast_string_field_set(peer, mohinterpret, v->value);
11812 } else if (!strcasecmp(v->name, "mohsuggest")) {
11813 ast_string_field_set(peer, mohsuggest, v->value);
11814 } else if (!strcasecmp(v->name, "dbsecret")) {
11815 ast_string_field_set(peer, dbsecret, v->value);
11816 } else if (!strcasecmp(v->name, "trunk")) {
11817 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
11818 if (ast_test_flag(peer, IAX_TRUNK) && !timer) {
11819 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
11820 ast_clear_flag(peer, IAX_TRUNK);
11821 }
11822 } else if (!strcasecmp(v->name, "auth")) {
11823 peer->authmethods = get_auth_methods(v->value);
11824 } else if (!strcasecmp(v->name, "encryption")) {
11825 peer->encmethods |= get_encrypt_methods(v->value);
11826 } else if (!strcasecmp(v->name, "transfer")) {
11827 if (!strcasecmp(v->value, "mediaonly")) {
11828 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
11829 } else if (ast_true(v->value)) {
11830 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11831 } else
11832 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11833 } else if (!strcasecmp(v->name, "jitterbuffer")) {
11834 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
11835 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
11836 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
11837 } else if (!strcasecmp(v->name, "host")) {
11838 if (!strcasecmp(v->value, "dynamic")) {
11839
11840 ast_set_flag(peer, IAX_DYNAMIC);
11841 if (!found) {
11842
11843
11844 memset(&peer->addr.sin_addr, 0, 4);
11845 if (peer->addr.sin_port) {
11846
11847 peer->defaddr.sin_port = peer->addr.sin_port;
11848 peer->addr.sin_port = 0;
11849 }
11850 }
11851 } else {
11852
11853 AST_SCHED_DEL(sched, peer->expire);
11854 ast_clear_flag(peer, IAX_DYNAMIC);
11855 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
11856 return peer_unref(peer);
11857 if (!peer->addr.sin_port)
11858 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11859 }
11860 if (!maskfound)
11861 inet_aton("255.255.255.255", &peer->mask);
11862 } else if (!strcasecmp(v->name, "defaultip")) {
11863 if (ast_get_ip(&peer->defaddr, v->value))
11864 return peer_unref(peer);
11865 } else if (!strcasecmp(v->name, "sourceaddress")) {
11866 peer_set_srcaddr(peer, v->value);
11867 } else if (!strcasecmp(v->name, "permit") ||
11868 !strcasecmp(v->name, "deny")) {
11869 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
11870 } else if (!strcasecmp(v->name, "mask")) {
11871 maskfound++;
11872 inet_aton(v->value, &peer->mask);
11873 } else if (!strcasecmp(v->name, "context")) {
11874 ast_string_field_set(peer, context, v->value);
11875 } else if (!strcasecmp(v->name, "regexten")) {
11876 ast_string_field_set(peer, regexten, v->value);
11877 } else if (!strcasecmp(v->name, "peercontext")) {
11878 ast_string_field_set(peer, peercontext, v->value);
11879 } else if (!strcasecmp(v->name, "port")) {
11880 if (ast_test_flag(peer, IAX_DYNAMIC))
11881 peer->defaddr.sin_port = htons(atoi(v->value));
11882 else
11883 peer->addr.sin_port = htons(atoi(v->value));
11884 } else if (!strcasecmp(v->name, "username")) {
11885 ast_string_field_set(peer, username, v->value);
11886 } else if (!strcasecmp(v->name, "allow")) {
11887 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
11888 } else if (!strcasecmp(v->name, "disallow")) {
11889 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
11890 } else if (!strcasecmp(v->name, "callerid")) {
11891 if (!ast_strlen_zero(v->value)) {
11892 char name2[80];
11893 char num2[80];
11894 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
11895 ast_string_field_set(peer, cid_name, name2);
11896 ast_string_field_set(peer, cid_num, num2);
11897 } else {
11898 ast_string_field_set(peer, cid_name, "");
11899 ast_string_field_set(peer, cid_num, "");
11900 }
11901 ast_set_flag(peer, IAX_HASCALLERID);
11902 } else if (!strcasecmp(v->name, "fullname")) {
11903 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
11904 ast_set_flag(peer, IAX_HASCALLERID);
11905 } else if (!strcasecmp(v->name, "cid_number")) {
11906 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
11907 ast_set_flag(peer, IAX_HASCALLERID);
11908 } else if (!strcasecmp(v->name, "sendani")) {
11909 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
11910 } else if (!strcasecmp(v->name, "inkeys")) {
11911 ast_string_field_set(peer, inkeys, v->value);
11912 } else if (!strcasecmp(v->name, "outkey")) {
11913 ast_string_field_set(peer, outkey, v->value);
11914 } else if (!strcasecmp(v->name, "qualify")) {
11915 if (!strcasecmp(v->value, "no")) {
11916 peer->maxms = 0;
11917 } else if (!strcasecmp(v->value, "yes")) {
11918 peer->maxms = DEFAULT_MAXMS;
11919 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
11920 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);
11921 peer->maxms = 0;
11922 }
11923 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
11924 peer->smoothing = ast_true(v->value);
11925 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
11926 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
11927 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);
11928 }
11929 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
11930 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
11931 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);
11932 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
11933 } else if (!strcasecmp(v->name, "timezone")) {
11934 ast_string_field_set(peer, zonetag, v->value);
11935 } else if (!strcasecmp(v->name, "adsi")) {
11936 peer->adsi = ast_true(v->value);
11937 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
11938 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
11939 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
11940 } else {
11941 peercnt_modify(1, peer->maxcallno, &peer->addr);
11942 }
11943 } else if (!strcasecmp(v->name, "requirecalltoken")) {
11944
11945 if (ast_false(v->value)) {
11946 peer->calltoken_required = CALLTOKEN_NO;
11947 } else if (!strcasecmp(v->value, "auto")) {
11948 peer->calltoken_required = CALLTOKEN_AUTO;
11949 } else if (ast_true(v->value)) {
11950 peer->calltoken_required = CALLTOKEN_YES;
11951 } else {
11952 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
11953 }
11954 }
11955
11956 v = v->next;
11957 if (!v) {
11958 v = alt;
11959 alt = NULL;
11960 }
11961 }
11962 if (!peer->authmethods)
11963 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11964 ast_clear_flag(peer, IAX_DELME);
11965
11966 peer->addr.sin_family = AF_INET;
11967 }
11968
11969 if (oldha)
11970 ast_free_ha(oldha);
11971
11972 if (!ast_strlen_zero(peer->mailbox)) {
11973 char *mailbox, *context;
11974 context = mailbox = ast_strdupa(peer->mailbox);
11975 strsep(&context, "@");
11976 if (ast_strlen_zero(context))
11977 context = "default";
11978 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
11979 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
11980 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
11981 AST_EVENT_IE_END);
11982 }
11983
11984 return peer;
11985 }
11986
11987 static void user_destructor(void *obj)
11988 {
11989 struct iax2_user *user = obj;
11990
11991 ast_free_ha(user->ha);
11992 free_context(user->contexts);
11993 if(user->vars) {
11994 ast_variables_destroy(user->vars);
11995 user->vars = NULL;
11996 }
11997 ast_string_field_free_memory(user);
11998 }
11999
12000
12001 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12002 {
12003 struct iax2_user *user = NULL;
12004 struct iax2_context *con, *conl = NULL;
12005 struct ast_ha *oldha = NULL;
12006 struct iax2_context *oldcon = NULL;
12007 int format;
12008 int firstpass=1;
12009 int oldcurauthreq = 0;
12010 char *varname = NULL, *varval = NULL;
12011 struct ast_variable *tmpvar = NULL;
12012 struct iax2_user tmp_user = {
12013 .name = name,
12014 };
12015
12016 if (!temponly) {
12017 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12018 if (user && !ast_test_flag(user, IAX_DELME))
12019 firstpass = 0;
12020 }
12021
12022 if (user) {
12023 if (firstpass) {
12024 oldcurauthreq = user->curauthreq;
12025 oldha = user->ha;
12026 oldcon = user->contexts;
12027 user->ha = NULL;
12028 user->contexts = NULL;
12029 }
12030
12031 ao2_unlink(users, user);
12032 } else {
12033 user = ao2_alloc(sizeof(*user), user_destructor);
12034 }
12035
12036 if (user) {
12037 if (firstpass) {
12038 ast_string_field_free_memory(user);
12039 memset(user, 0, sizeof(struct iax2_user));
12040 if (ast_string_field_init(user, 32)) {
12041 user = user_unref(user);
12042 goto cleanup;
12043 }
12044 user->maxauthreq = maxauthreq;
12045 user->curauthreq = oldcurauthreq;
12046 user->prefs = prefs;
12047 user->capability = iax2_capability;
12048 user->encmethods = iax2_encryption;
12049 user->adsi = adsi;
12050 user->calltoken_required = CALLTOKEN_DEFAULT;
12051 ast_string_field_set(user, name, name);
12052 ast_string_field_set(user, language, language);
12053 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
12054 ast_clear_flag(user, IAX_HASCALLERID);
12055 ast_string_field_set(user, cid_name, "");
12056 ast_string_field_set(user, cid_num, "");
12057 ast_string_field_set(user, accountcode, accountcode);
12058 ast_string_field_set(user, mohinterpret, mohinterpret);
12059 ast_string_field_set(user, mohsuggest, mohsuggest);
12060 }
12061 if (!v) {
12062 v = alt;
12063 alt = NULL;
12064 }
12065 while(v) {
12066 if (!strcasecmp(v->name, "context")) {
12067 con = build_context(v->value);
12068 if (con) {
12069 if (conl)
12070 conl->next = con;
12071 else
12072 user->contexts = con;
12073 conl = con;
12074 }
12075 } else if (!strcasecmp(v->name, "permit") ||
12076 !strcasecmp(v->name, "deny")) {
12077 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12078 } else if (!strcasecmp(v->name, "setvar")) {
12079 varname = ast_strdupa(v->value);
12080 if (varname && (varval = strchr(varname,'='))) {
12081 *varval = '\0';
12082 varval++;
12083 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12084 tmpvar->next = user->vars;
12085 user->vars = tmpvar;
12086 }
12087 }
12088 } else if (!strcasecmp(v->name, "allow")) {
12089 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12090 } else if (!strcasecmp(v->name, "disallow")) {
12091 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12092 } else if (!strcasecmp(v->name, "trunk")) {
12093 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
12094 if (ast_test_flag(user, IAX_TRUNK) && !timer) {
12095 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12096 ast_clear_flag(user, IAX_TRUNK);
12097 }
12098 } else if (!strcasecmp(v->name, "auth")) {
12099 user->authmethods = get_auth_methods(v->value);
12100 } else if (!strcasecmp(v->name, "encryption")) {
12101 user->encmethods |= get_encrypt_methods(v->value);
12102 } else if (!strcasecmp(v->name, "transfer")) {
12103 if (!strcasecmp(v->value, "mediaonly")) {
12104 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12105 } else if (ast_true(v->value)) {
12106 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12107 } else
12108 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12109 } else if (!strcasecmp(v->name, "codecpriority")) {
12110 if(!strcasecmp(v->value, "caller"))
12111 ast_set_flag(user, IAX_CODEC_USER_FIRST);
12112 else if(!strcasecmp(v->value, "disabled"))
12113 ast_set_flag(user, IAX_CODEC_NOPREFS);
12114 else if(!strcasecmp(v->value, "reqonly")) {
12115 ast_set_flag(user, IAX_CODEC_NOCAP);
12116 ast_set_flag(user, IAX_CODEC_NOPREFS);
12117 }
12118 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12119 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
12120 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12121 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12122 } else if (!strcasecmp(v->name, "dbsecret")) {
12123 ast_string_field_set(user, dbsecret, v->value);
12124 } else if (!strcasecmp(v->name, "secret")) {
12125 if (!ast_strlen_zero(user->secret)) {
12126 char *old = ast_strdupa(user->secret);
12127
12128 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12129 } else
12130 ast_string_field_set(user, secret, v->value);
12131 } else if (!strcasecmp(v->name, "callerid")) {
12132 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12133 char name2[80];
12134 char num2[80];
12135 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12136 ast_string_field_set(user, cid_name, name2);
12137 ast_string_field_set(user, cid_num, num2);
12138 ast_set_flag(user, IAX_HASCALLERID);
12139 } else {
12140 ast_clear_flag(user, IAX_HASCALLERID);
12141 ast_string_field_set(user, cid_name, "");
12142 ast_string_field_set(user, cid_num, "");
12143 }
12144 } else if (!strcasecmp(v->name, "fullname")) {
12145 if (!ast_strlen_zero(v->value)) {
12146 ast_string_field_set(user, cid_name, v->value);
12147 ast_set_flag(user, IAX_HASCALLERID);
12148 } else {
12149 ast_string_field_set(user, cid_name, "");
12150 if (ast_strlen_zero(user->cid_num))
12151 ast_clear_flag(user, IAX_HASCALLERID);
12152 }
12153 } else if (!strcasecmp(v->name, "cid_number")) {
12154 if (!ast_strlen_zero(v->value)) {
12155 ast_string_field_set(user, cid_num, v->value);
12156 ast_set_flag(user, IAX_HASCALLERID);
12157 } else {
12158 ast_string_field_set(user, cid_num, "");
12159 if (ast_strlen_zero(user->cid_name))
12160 ast_clear_flag(user, IAX_HASCALLERID);
12161 }
12162 } else if (!strcasecmp(v->name, "accountcode")) {
12163 ast_string_field_set(user, accountcode, v->value);
12164 } else if (!strcasecmp(v->name, "mohinterpret")) {
12165 ast_string_field_set(user, mohinterpret, v->value);
12166 } else if (!strcasecmp(v->name, "mohsuggest")) {
12167 ast_string_field_set(user, mohsuggest, v->value);
12168 } else if (!strcasecmp(v->name, "parkinglot")) {
12169 ast_string_field_set(user, parkinglot, v->value);
12170 } else if (!strcasecmp(v->name, "language")) {
12171 ast_string_field_set(user, language, v->value);
12172 } else if (!strcasecmp(v->name, "amaflags")) {
12173 format = ast_cdr_amaflags2int(v->value);
12174 if (format < 0) {
12175 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12176 } else {
12177 user->amaflags = format;
12178 }
12179 } else if (!strcasecmp(v->name, "inkeys")) {
12180 ast_string_field_set(user, inkeys, v->value);
12181 } else if (!strcasecmp(v->name, "maxauthreq")) {
12182 user->maxauthreq = atoi(v->value);
12183 if (user->maxauthreq < 0)
12184 user->maxauthreq = 0;
12185 } else if (!strcasecmp(v->name, "adsi")) {
12186 user->adsi = ast_true(v->value);
12187 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12188
12189 if (ast_false(v->value)) {
12190 user->calltoken_required = CALLTOKEN_NO;
12191 } else if (!strcasecmp(v->value, "auto")) {
12192 user->calltoken_required = CALLTOKEN_AUTO;
12193 } else if (ast_true(v->value)) {
12194 user->calltoken_required = CALLTOKEN_YES;
12195 } else {
12196 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12197 }
12198 }
12199
12200 v = v->next;
12201 if (!v) {
12202 v = alt;
12203 alt = NULL;
12204 }
12205 }
12206 if (!user->authmethods) {
12207 if (!ast_strlen_zero(user->secret)) {
12208 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12209 if (!ast_strlen_zero(user->inkeys))
12210 user->authmethods |= IAX_AUTH_RSA;
12211 } else if (!ast_strlen_zero(user->inkeys)) {
12212 user->authmethods = IAX_AUTH_RSA;
12213 } else {
12214 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12215 }
12216 }
12217 ast_clear_flag(user, IAX_DELME);
12218 }
12219 cleanup:
12220 if (oldha)
12221 ast_free_ha(oldha);
12222 if (oldcon)
12223 free_context(oldcon);
12224 return user;
12225 }
12226
12227 static int peer_delme_cb(void *obj, void *arg, int flags)
12228 {
12229 struct iax2_peer *peer = obj;
12230
12231 ast_set_flag(peer, IAX_DELME);
12232
12233 return 0;
12234 }
12235
12236 static int user_delme_cb(void *obj, void *arg, int flags)
12237 {
12238 struct iax2_user *user = obj;
12239
12240 ast_set_flag(user, IAX_DELME);
12241
12242 return 0;
12243 }
12244
12245 static void delete_users(void)
12246 {
12247 struct iax2_registry *reg;
12248
12249 ao2_callback(users, 0, user_delme_cb, NULL);
12250
12251 AST_LIST_LOCK(®istrations);
12252 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12253 AST_SCHED_DEL(sched, reg->expire);
12254 if (reg->callno) {
12255 int callno = reg->callno;
12256 ast_mutex_lock(&iaxsl[callno]);
12257 if (iaxs[callno]) {
12258 iaxs[callno]->reg = NULL;
12259 iax2_destroy(callno);
12260 }
12261 ast_mutex_unlock(&iaxsl[callno]);
12262 }
12263 if (reg->dnsmgr)
12264 ast_dnsmgr_release(reg->dnsmgr);
12265 ast_free(reg);
12266 }
12267 AST_LIST_UNLOCK(®istrations);
12268
12269 ao2_callback(peers, 0, peer_delme_cb, NULL);
12270 }
12271
12272 static void prune_users(void)
12273 {
12274 struct iax2_user *user;
12275 struct ao2_iterator i;
12276
12277 i = ao2_iterator_init(users, 0);
12278 while ((user = ao2_iterator_next(&i))) {
12279 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
12280 ao2_unlink(users, user);
12281 }
12282 user_unref(user);
12283 }
12284 ao2_iterator_destroy(&i);
12285 }
12286
12287
12288 static void prune_peers(void)
12289 {
12290 struct iax2_peer *peer;
12291 struct ao2_iterator i;
12292
12293 i = ao2_iterator_init(peers, 0);
12294 while ((peer = ao2_iterator_next(&i))) {
12295 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
12296 unlink_peer(peer);
12297 }
12298 peer_unref(peer);
12299 }
12300 ao2_iterator_destroy(&i);
12301 }
12302
12303 static void set_config_destroy(void)
12304 {
12305 strcpy(accountcode, "");
12306 strcpy(language, "");
12307 strcpy(mohinterpret, "default");
12308 strcpy(mohsuggest, "");
12309 trunkmaxsize = MAX_TRUNKDATA;
12310 amaflags = 0;
12311 delayreject = 0;
12312 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
12313 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
12314 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
12315 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
12316 delete_users();
12317 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12318 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12319 }
12320
12321
12322 static int set_config(const char *config_file, int reload)
12323 {
12324 struct ast_config *cfg, *ucfg;
12325 int capability=iax2_capability;
12326 struct ast_variable *v;
12327 char *cat;
12328 const char *utype;
12329 const char *tosval;
12330 int format;
12331 int portno = IAX_DEFAULT_PORTNO;
12332 int x;
12333 int mtuv;
12334 struct iax2_user *user;
12335 struct iax2_peer *peer;
12336 struct ast_netsock *ns;
12337 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12338 #if 0
12339 static unsigned short int last_port=0;
12340 #endif
12341
12342 cfg = ast_config_load(config_file, config_flags);
12343
12344 if (!cfg) {
12345 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12346 return -1;
12347 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12348 ucfg = ast_config_load("users.conf", config_flags);
12349 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12350 return 0;
12351
12352 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12353 cfg = ast_config_load(config_file, config_flags);
12354 } else {
12355 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12356 ucfg = ast_config_load("users.conf", config_flags);
12357 }
12358
12359 if (reload) {
12360 set_config_destroy();
12361 }
12362
12363
12364 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12365
12366
12367 memset(&globalflags, 0, sizeof(globalflags));
12368 ast_set_flag(&globalflags, IAX_RTUPDATE);
12369 ast_set_flag(&globalflags, IAX_SHRINKCALLERID);
12370
12371
12372 iax2_encryption |= IAX_ENCRYPT_KEYROTATE;
12373 #ifdef SO_NO_CHECK
12374 nochecksums = 0;
12375 #endif
12376
12377 default_parkinglot[0] = '\0';
12378
12379 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12380 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12381 global_max_trunk_mtu = MAX_TRUNK_MTU;
12382 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12383 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12384
12385 maxauthreq = 3;
12386
12387 srvlookup = 0;
12388
12389 v = ast_variable_browse(cfg, "general");
12390
12391
12392 tosval = ast_variable_retrieve(cfg, "general", "tos");
12393 if (tosval) {
12394 if (ast_str2tos(tosval, &qos.tos))
12395 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
12396 }
12397
12398 tosval = ast_variable_retrieve(cfg, "general", "cos");
12399 if (tosval) {
12400 if (ast_str2cos(tosval, &qos.cos))
12401 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
12402 }
12403 while(v) {
12404 if (!strcasecmp(v->name, "bindport")){
12405 if (reload)
12406 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
12407 else
12408 portno = atoi(v->value);
12409 } else if (!strcasecmp(v->name, "pingtime"))
12410 ping_time = atoi(v->value);
12411 else if (!strcasecmp(v->name, "iaxthreadcount")) {
12412 if (reload) {
12413 if (atoi(v->value) != iaxthreadcount)
12414 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
12415 } else {
12416 iaxthreadcount = atoi(v->value);
12417 if (iaxthreadcount < 1) {
12418 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
12419 iaxthreadcount = 1;
12420 } else if (iaxthreadcount > 256) {
12421 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
12422 iaxthreadcount = 256;
12423 }
12424 }
12425 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
12426 if (reload) {
12427 AST_LIST_LOCK(&dynamic_list);
12428 iaxmaxthreadcount = atoi(v->value);
12429 AST_LIST_UNLOCK(&dynamic_list);
12430 } else {
12431 iaxmaxthreadcount = atoi(v->value);
12432 if (iaxmaxthreadcount < 0) {
12433 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
12434 iaxmaxthreadcount = 0;
12435 } else if (iaxmaxthreadcount > 256) {
12436 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
12437 iaxmaxthreadcount = 256;
12438 }
12439 }
12440 } else if (!strcasecmp(v->name, "nochecksums")) {
12441 #ifdef SO_NO_CHECK
12442 if (ast_true(v->value))
12443 nochecksums = 1;
12444 else
12445 nochecksums = 0;
12446 #else
12447 if (ast_true(v->value))
12448 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
12449 #endif
12450 }
12451 else if (!strcasecmp(v->name, "maxjitterbuffer"))
12452 maxjitterbuffer = atoi(v->value);
12453 else if (!strcasecmp(v->name, "resyncthreshold"))
12454 resyncthreshold = atoi(v->value);
12455 else if (!strcasecmp(v->name, "maxjitterinterps"))
12456 maxjitterinterps = atoi(v->value);
12457 else if (!strcasecmp(v->name, "jittertargetextra"))
12458 jittertargetextra = atoi(v->value);
12459 else if (!strcasecmp(v->name, "lagrqtime"))
12460 lagrq_time = atoi(v->value);
12461 else if (!strcasecmp(v->name, "maxregexpire"))
12462 max_reg_expire = atoi(v->value);
12463 else if (!strcasecmp(v->name, "minregexpire"))
12464 min_reg_expire = atoi(v->value);
12465 else if (!strcasecmp(v->name, "bindaddr")) {
12466 if (reload) {
12467 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
12468 } else {
12469 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
12470 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
12471 } else {
12472 if (strchr(v->value, ':'))
12473 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
12474 else
12475 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
12476 if (defaultsockfd < 0)
12477 defaultsockfd = ast_netsock_sockfd(ns);
12478 ast_netsock_unref(ns);
12479 }
12480 }
12481 } else if (!strcasecmp(v->name, "authdebug"))
12482 authdebug = ast_true(v->value);
12483 else if (!strcasecmp(v->name, "encryption"))
12484 iax2_encryption |= get_encrypt_methods(v->value);
12485 else if (!strcasecmp(v->name, "transfer")) {
12486 if (!strcasecmp(v->value, "mediaonly")) {
12487 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12488 } else if (ast_true(v->value)) {
12489 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12490 } else
12491 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12492 } else if (!strcasecmp(v->name, "codecpriority")) {
12493 if(!strcasecmp(v->value, "caller"))
12494 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
12495 else if(!strcasecmp(v->value, "disabled"))
12496 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12497 else if(!strcasecmp(v->value, "reqonly")) {
12498 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
12499 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12500 }
12501 } else if (!strcasecmp(v->name, "jitterbuffer"))
12502 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
12503 else if (!strcasecmp(v->name, "forcejitterbuffer"))
12504 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
12505 else if (!strcasecmp(v->name, "delayreject"))
12506 delayreject = ast_true(v->value);
12507 else if (!strcasecmp(v->name, "allowfwdownload"))
12508 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
12509 else if (!strcasecmp(v->name, "rtcachefriends"))
12510 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
12511 else if (!strcasecmp(v->name, "rtignoreregexpire"))
12512 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
12513 else if (!strcasecmp(v->name, "rtupdate"))
12514 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
12515 else if (!strcasecmp(v->name, "trunktimestamps"))
12516 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
12517 else if (!strcasecmp(v->name, "rtautoclear")) {
12518 int i = atoi(v->value);
12519 if(i > 0)
12520 global_rtautoclear = i;
12521 else
12522 i = 0;
12523 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
12524 } else if (!strcasecmp(v->name, "trunkfreq")) {
12525 trunkfreq = atoi(v->value);
12526 if (trunkfreq < 10)
12527 trunkfreq = 10;
12528 } else if (!strcasecmp(v->name, "trunkmtu")) {
12529 mtuv = atoi(v->value);
12530 if (mtuv == 0 )
12531 global_max_trunk_mtu = 0;
12532 else if (mtuv >= 172 && mtuv < 4000)
12533 global_max_trunk_mtu = mtuv;
12534 else
12535 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
12536 mtuv, v->lineno);
12537 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
12538 trunkmaxsize = atoi(v->value);
12539 if (trunkmaxsize == 0)
12540 trunkmaxsize = MAX_TRUNKDATA;
12541 } else if (!strcasecmp(v->name, "autokill")) {
12542 if (sscanf(v->value, "%30d", &x) == 1) {
12543 if (x >= 0)
12544 autokill = x;
12545 else
12546 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
12547 } else if (ast_true(v->value)) {
12548 autokill = DEFAULT_MAXMS;
12549 } else {
12550 autokill = 0;
12551 }
12552 } else if (!strcasecmp(v->name, "bandwidth")) {
12553 if (!strcasecmp(v->value, "low")) {
12554 capability = IAX_CAPABILITY_LOWBANDWIDTH;
12555 } else if (!strcasecmp(v->value, "medium")) {
12556 capability = IAX_CAPABILITY_MEDBANDWIDTH;
12557 } else if (!strcasecmp(v->value, "high")) {
12558 capability = IAX_CAPABILITY_FULLBANDWIDTH;
12559 } else
12560 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
12561 } else if (!strcasecmp(v->name, "allow")) {
12562 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
12563 } else if (!strcasecmp(v->name, "disallow")) {
12564 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
12565 } else if (!strcasecmp(v->name, "register")) {
12566 iax2_register(v->value, v->lineno);
12567 } else if (!strcasecmp(v->name, "iaxcompat")) {
12568 iaxcompat = ast_true(v->value);
12569 } else if (!strcasecmp(v->name, "regcontext")) {
12570 ast_copy_string(regcontext, v->value, sizeof(regcontext));
12571
12572 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
12573 } else if (!strcasecmp(v->name, "tos")) {
12574 if (ast_str2tos(v->value, &qos.tos))
12575 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
12576 } else if (!strcasecmp(v->name, "cos")) {
12577 if (ast_str2cos(v->value, &qos.cos))
12578 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
12579 } else if (!strcasecmp(v->name, "parkinglot")) {
12580 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
12581 } else if (!strcasecmp(v->name, "accountcode")) {
12582 ast_copy_string(accountcode, v->value, sizeof(accountcode));
12583 } else if (!strcasecmp(v->name, "mohinterpret")) {
12584 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
12585 } else if (!strcasecmp(v->name, "mohsuggest")) {
12586 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
12587 } else if (!strcasecmp(v->name, "amaflags")) {
12588 format = ast_cdr_amaflags2int(v->value);
12589 if (format < 0) {
12590 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12591 } else {
12592 amaflags = format;
12593 }
12594 } else if (!strcasecmp(v->name, "language")) {
12595 ast_copy_string(language, v->value, sizeof(language));
12596 } else if (!strcasecmp(v->name, "maxauthreq")) {
12597 maxauthreq = atoi(v->value);
12598 if (maxauthreq < 0)
12599 maxauthreq = 0;
12600 } else if (!strcasecmp(v->name, "adsi")) {
12601 adsi = ast_true(v->value);
12602 } else if (!strcasecmp(v->name, "srvlookup")) {
12603 srvlookup = ast_true(v->value);
12604 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12605 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
12606 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
12607 }
12608 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
12609 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
12610 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);
12611 }
12612 } else if (!strcasecmp(v->name, "calltokenoptional")) {
12613 if (add_calltoken_ignore(v->value)) {
12614 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
12615 }
12616 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
12617 if (ast_true(v->value)) {
12618 ast_set_flag((&globalflags), IAX_SHRINKCALLERID);
12619 } else if (ast_false(v->value)) {
12620 ast_clear_flag((&globalflags), IAX_SHRINKCALLERID);
12621 } else {
12622 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
12623 }
12624 }
12625
12626 v = v->next;
12627 }
12628
12629 if (defaultsockfd < 0) {
12630 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
12631 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
12632 } else {
12633 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
12634 defaultsockfd = ast_netsock_sockfd(ns);
12635 ast_netsock_unref(ns);
12636 }
12637 }
12638 if (reload) {
12639 ast_netsock_release(outsock);
12640 outsock = ast_netsock_list_alloc();
12641 if (!outsock) {
12642 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12643 return -1;
12644 }
12645 ast_netsock_init(outsock);
12646 }
12647
12648 if (min_reg_expire > max_reg_expire) {
12649 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
12650 min_reg_expire, max_reg_expire, max_reg_expire);
12651 min_reg_expire = max_reg_expire;
12652 }
12653 iax2_capability = capability;
12654
12655 if (ucfg) {
12656 struct ast_variable *gen;
12657 int genhasiax;
12658 int genregisteriax;
12659 const char *hasiax, *registeriax;
12660
12661 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
12662 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
12663 gen = ast_variable_browse(ucfg, "general");
12664 cat = ast_category_browse(ucfg, NULL);
12665 while (cat) {
12666 if (strcasecmp(cat, "general")) {
12667 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
12668 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
12669 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
12670
12671 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
12672 if (user) {
12673 ao2_link(users, user);
12674 user = user_unref(user);
12675 }
12676 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
12677 if (peer) {
12678 if (ast_test_flag(peer, IAX_DYNAMIC))
12679 reg_source_db(peer);
12680 ao2_link(peers, peer);
12681 peer = peer_unref(peer);
12682 }
12683 }
12684 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
12685 char tmp[256];
12686 const char *host = ast_variable_retrieve(ucfg, cat, "host");
12687 const char *username = ast_variable_retrieve(ucfg, cat, "username");
12688 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
12689 if (!host)
12690 host = ast_variable_retrieve(ucfg, "general", "host");
12691 if (!username)
12692 username = ast_variable_retrieve(ucfg, "general", "username");
12693 if (!secret)
12694 secret = ast_variable_retrieve(ucfg, "general", "secret");
12695 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
12696 if (!ast_strlen_zero(secret))
12697 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
12698 else
12699 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
12700 iax2_register(tmp, 0);
12701 }
12702 }
12703 }
12704 cat = ast_category_browse(ucfg, cat);
12705 }
12706 ast_config_destroy(ucfg);
12707 }
12708
12709 cat = ast_category_browse(cfg, NULL);
12710 while(cat) {
12711 if (strcasecmp(cat, "general")) {
12712 utype = ast_variable_retrieve(cfg, cat, "type");
12713 if (!strcasecmp(cat, "callnumberlimits")) {
12714 build_callno_limits(ast_variable_browse(cfg, cat));
12715 } else if (utype) {
12716 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
12717 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
12718 if (user) {
12719 ao2_link(users, user);
12720 user = user_unref(user);
12721 }
12722 }
12723 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
12724 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
12725 if (peer) {
12726 if (ast_test_flag(peer, IAX_DYNAMIC))
12727 reg_source_db(peer);
12728 ao2_link(peers, peer);
12729 peer = peer_unref(peer);
12730 }
12731 } else if (strcasecmp(utype, "user")) {
12732 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
12733 }
12734 } else
12735 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
12736 }
12737 cat = ast_category_browse(cfg, cat);
12738 }
12739 ast_config_destroy(cfg);
12740 return 1;
12741 }
12742
12743 static void poke_all_peers(void)
12744 {
12745 struct ao2_iterator i;
12746 struct iax2_peer *peer;
12747
12748 i = ao2_iterator_init(peers, 0);
12749 while ((peer = ao2_iterator_next(&i))) {
12750 iax2_poke_peer(peer, 0);
12751 peer_unref(peer);
12752 }
12753 ao2_iterator_destroy(&i);
12754 }
12755 static int reload_config(void)
12756 {
12757 static const char config[] = "iax.conf";
12758 struct iax2_registry *reg;
12759
12760 if (set_config(config, 1) > 0) {
12761 prune_peers();
12762 prune_users();
12763 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
12764 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
12765 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
12766 trunk_timed = trunk_untimed = 0;
12767 trunk_nmaxmtu = trunk_maxmtu = 0;
12768 memset(&debugaddr, '\0', sizeof(debugaddr));
12769
12770 AST_LIST_LOCK(®istrations);
12771 AST_LIST_TRAVERSE(®istrations, reg, entry)
12772 iax2_do_register(reg);
12773 AST_LIST_UNLOCK(®istrations);
12774
12775
12776 poke_all_peers();
12777 }
12778
12779 reload_firmware(0);
12780 iax_provision_reload(1);
12781 ast_unload_realtime("iaxpeers");
12782
12783 return 0;
12784 }
12785
12786 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
12787 {
12788 switch (cmd) {
12789 case CLI_INIT:
12790 e->command = "iax2 reload";
12791 e->usage =
12792 "Usage: iax2 reload\n"
12793 " Reloads IAX configuration from iax.conf\n";
12794 return NULL;
12795 case CLI_GENERATE:
12796 return NULL;
12797 }
12798
12799 reload_config();
12800
12801 return CLI_SUCCESS;
12802 }
12803
12804 static int reload(void)
12805 {
12806 return reload_config();
12807 }
12808
12809 static int cache_get_callno_locked(const char *data)
12810 {
12811 struct sockaddr_in sin;
12812 int x;
12813 int callno;
12814 struct iax_ie_data ied;
12815 struct create_addr_info cai;
12816 struct parsed_dial_string pds;
12817 char *tmpstr;
12818
12819 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12820
12821
12822 if (!ast_mutex_trylock(&iaxsl[x])) {
12823 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
12824 return x;
12825 ast_mutex_unlock(&iaxsl[x]);
12826 }
12827 }
12828
12829
12830
12831 memset(&cai, 0, sizeof(cai));
12832 memset(&ied, 0, sizeof(ied));
12833 memset(&pds, 0, sizeof(pds));
12834
12835 tmpstr = ast_strdupa(data);
12836 parse_dial_string(tmpstr, &pds);
12837
12838 if (ast_strlen_zero(pds.peer)) {
12839 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
12840 return -1;
12841 }
12842
12843
12844 if (create_addr(pds.peer, NULL, &sin, &cai))
12845 return -1;
12846
12847 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
12848 pds.peer, pds.username, pds.password, pds.context);
12849
12850 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12851 if (callno < 1) {
12852 ast_log(LOG_WARNING, "Unable to create call\n");
12853 return -1;
12854 }
12855
12856 ast_string_field_set(iaxs[callno], dproot, data);
12857 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
12858
12859 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
12860 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
12861
12862
12863
12864 if (pds.exten)
12865 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
12866 if (pds.username)
12867 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
12868 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
12869 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
12870
12871 if (pds.password)
12872 ast_string_field_set(iaxs[callno], secret, pds.password);
12873 if (pds.key)
12874 ast_string_field_set(iaxs[callno], outkey, pds.key);
12875
12876 add_empty_calltoken_ie(iaxs[callno], &ied);
12877 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
12878
12879 return callno;
12880 }
12881
12882 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
12883 {
12884 struct iax2_dpcache *dp = NULL;
12885 struct timeval now = ast_tvnow();
12886 int x, com[2], timeout, old = 0, outfd, doabort, callno;
12887 struct ast_channel *c = NULL;
12888 struct ast_frame *f = NULL;
12889
12890 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
12891 if (ast_tvcmp(now, dp->expiry) > 0) {
12892 AST_LIST_REMOVE_CURRENT(cache_list);
12893 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
12894 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
12895 else
12896 ast_free(dp);
12897 continue;
12898 }
12899 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
12900 break;
12901 }
12902 AST_LIST_TRAVERSE_SAFE_END;
12903
12904 if (!dp) {
12905
12906
12907 if ((callno = cache_get_callno_locked(data)) < 0) {
12908 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
12909 return NULL;
12910 }
12911 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
12912 ast_mutex_unlock(&iaxsl[callno]);
12913 return NULL;
12914 }
12915 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
12916 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
12917 dp->expiry = ast_tvnow();
12918 dp->orig = dp->expiry;
12919
12920 dp->expiry.tv_sec += iaxdefaultdpcache;
12921 dp->flags = CACHE_FLAG_PENDING;
12922 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
12923 dp->waiters[x] = -1;
12924
12925 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
12926 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
12927
12928 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
12929 iax2_dprequest(dp, callno);
12930 ast_mutex_unlock(&iaxsl[callno]);
12931 }
12932
12933
12934 if (dp->flags & CACHE_FLAG_PENDING) {
12935
12936
12937 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
12938
12939 if (dp->waiters[x] < 0)
12940 break;
12941 }
12942 if (x >= ARRAY_LEN(dp->waiters)) {
12943 ast_log(LOG_WARNING, "No more waiter positions available\n");
12944 return NULL;
12945 }
12946 if (pipe(com)) {
12947 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
12948 return NULL;
12949 }
12950 dp->waiters[x] = com[1];
12951
12952 timeout = iaxdefaulttimeout * 1000;
12953
12954 AST_LIST_UNLOCK(&dpcache);
12955
12956 if (chan)
12957 old = ast_channel_defer_dtmf(chan);
12958 doabort = 0;
12959 while(timeout) {
12960 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
12961 if (outfd > -1)
12962 break;
12963 if (!c)
12964 continue;
12965 if (!(f = ast_read(c))) {
12966 doabort = 1;
12967 break;
12968 }
12969 ast_frfree(f);
12970 }
12971 if (!timeout) {
12972 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
12973 }
12974 AST_LIST_LOCK(&dpcache);
12975 dp->waiters[x] = -1;
12976 close(com[1]);
12977 close(com[0]);
12978 if (doabort) {
12979
12980
12981 if (!old && chan)
12982 ast_channel_undefer_dtmf(chan);
12983 return NULL;
12984 }
12985 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
12986
12987 if (dp->flags & CACHE_FLAG_PENDING) {
12988
12989
12990 dp->flags &= ~CACHE_FLAG_PENDING;
12991 dp->flags |= CACHE_FLAG_TIMEOUT;
12992
12993
12994 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
12995 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
12996 if (dp->waiters[x] > -1) {
12997 if (write(dp->waiters[x], "asdf", 4) < 0) {
12998 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
12999 }
13000 }
13001 }
13002 }
13003 }
13004
13005 if (!old && chan)
13006 ast_channel_undefer_dtmf(chan);
13007 }
13008 return dp;
13009 }
13010
13011
13012 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13013 {
13014 int res = 0;
13015 struct iax2_dpcache *dp = NULL;
13016 #if 0
13017 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13018 #endif
13019 if ((priority != 1) && (priority != 2))
13020 return 0;
13021
13022 AST_LIST_LOCK(&dpcache);
13023 if ((dp = find_cache(chan, data, context, exten, priority))) {
13024 if (dp->flags & CACHE_FLAG_EXISTS)
13025 res = 1;
13026 } else {
13027 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13028 }
13029 AST_LIST_UNLOCK(&dpcache);
13030
13031 return res;
13032 }
13033
13034
13035 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13036 {
13037 int res = 0;
13038 struct iax2_dpcache *dp = NULL;
13039 #if 0
13040 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13041 #endif
13042 if ((priority != 1) && (priority != 2))
13043 return 0;
13044
13045 AST_LIST_LOCK(&dpcache);
13046 if ((dp = find_cache(chan, data, context, exten, priority))) {
13047 if (dp->flags & CACHE_FLAG_CANEXIST)
13048 res = 1;
13049 } else {
13050 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13051 }
13052 AST_LIST_UNLOCK(&dpcache);
13053
13054 return res;
13055 }
13056
13057
13058 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13059 {
13060 int res = 0;
13061 struct iax2_dpcache *dp = NULL;
13062 #if 0
13063 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13064 #endif
13065 if ((priority != 1) && (priority != 2))
13066 return 0;
13067
13068 AST_LIST_LOCK(&dpcache);
13069 if ((dp = find_cache(chan, data, context, exten, priority))) {
13070 if (dp->flags & CACHE_FLAG_MATCHMORE)
13071 res = 1;
13072 } else {
13073 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13074 }
13075 AST_LIST_UNLOCK(&dpcache);
13076
13077 return res;
13078 }
13079
13080
13081 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13082 {
13083 char odata[256];
13084 char req[256];
13085 char *ncontext;
13086 struct iax2_dpcache *dp = NULL;
13087 struct ast_app *dial = NULL;
13088 #if 0
13089 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);
13090 #endif
13091 if (priority == 2) {
13092
13093 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13094 if (dialstatus) {
13095 dial = pbx_findapp(dialstatus);
13096 if (dial)
13097 pbx_exec(chan, dial, "");
13098 }
13099 return -1;
13100 } else if (priority != 1)
13101 return -1;
13102
13103 AST_LIST_LOCK(&dpcache);
13104 if ((dp = find_cache(chan, data, context, exten, priority))) {
13105 if (dp->flags & CACHE_FLAG_EXISTS) {
13106 ast_copy_string(odata, data, sizeof(odata));
13107 ncontext = strchr(odata, '/');
13108 if (ncontext) {
13109 *ncontext = '\0';
13110 ncontext++;
13111 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13112 } else {
13113 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13114 }
13115 ast_verb(3, "Executing Dial('%s')\n", req);
13116 } else {
13117 AST_LIST_UNLOCK(&dpcache);
13118 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13119 return -1;
13120 }
13121 }
13122 AST_LIST_UNLOCK(&dpcache);
13123
13124 if ((dial = pbx_findapp("Dial")))
13125 return pbx_exec(chan, dial, req);
13126 else
13127 ast_log(LOG_WARNING, "No dial application registered\n");
13128
13129 return -1;
13130 }
13131
13132 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13133 {
13134 struct iax2_peer *peer;
13135 char *peername, *colname;
13136
13137 peername = ast_strdupa(data);
13138
13139
13140 if (!strcmp(peername,"CURRENTCHANNEL")) {
13141 unsigned short callno;
13142 if (chan->tech != &iax2_tech)
13143 return -1;
13144 callno = PTR_TO_CALLNO(chan->tech_pvt);
13145 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13146 return 0;
13147 }
13148
13149 if ((colname = strchr(peername, ',')))
13150 *colname++ = '\0';
13151 else
13152 colname = "ip";
13153
13154 if (!(peer = find_peer(peername, 1)))
13155 return -1;
13156
13157 if (!strcasecmp(colname, "ip")) {
13158 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
13159 } else if (!strcasecmp(colname, "status")) {
13160 peer_status(peer, buf, len);
13161 } else if (!strcasecmp(colname, "mailbox")) {
13162 ast_copy_string(buf, peer->mailbox, len);
13163 } else if (!strcasecmp(colname, "context")) {
13164 ast_copy_string(buf, peer->context, len);
13165 } else if (!strcasecmp(colname, "expire")) {
13166 snprintf(buf, len, "%d", peer->expire);
13167 } else if (!strcasecmp(colname, "dynamic")) {
13168 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13169 } else if (!strcasecmp(colname, "callerid_name")) {
13170 ast_copy_string(buf, peer->cid_name, len);
13171 } else if (!strcasecmp(colname, "callerid_num")) {
13172 ast_copy_string(buf, peer->cid_num, len);
13173 } else if (!strcasecmp(colname, "codecs")) {
13174 ast_getformatname_multiple(buf, len -1, peer->capability);
13175 } else if (!strncasecmp(colname, "codec[", 6)) {
13176 char *codecnum, *ptr;
13177 int codec = 0;
13178
13179 codecnum = strchr(colname, '[');
13180 *codecnum = '\0';
13181 codecnum++;
13182 if ((ptr = strchr(codecnum, ']'))) {
13183 *ptr = '\0';
13184 }
13185 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13186 ast_copy_string(buf, ast_getformatname(codec), len);
13187 } else {
13188 buf[0] = '\0';
13189 }
13190 } else {
13191 buf[0] = '\0';
13192 }
13193
13194 peer_unref(peer);
13195
13196 return 0;
13197 }
13198
13199 struct ast_custom_function iaxpeer_function = {
13200 .name = "IAXPEER",
13201 .synopsis = "Gets IAX peer information",
13202 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[,item])",
13203 .read = function_iaxpeer,
13204 .desc = "If peername specified, valid items are:\n"
13205 "- ip (default) The IP address.\n"
13206 "- status The peer's status (if qualify=yes)\n"
13207 "- mailbox The configured mailbox.\n"
13208 "- context The configured context.\n"
13209 "- expire The epoch time of the next expire.\n"
13210 "- dynamic Is it dynamic? (yes/no).\n"
13211 "- callerid_name The configured Caller ID name.\n"
13212 "- callerid_num The configured Caller ID number.\n"
13213 "- codecs The configured codecs.\n"
13214 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
13215 "\n"
13216 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
13217 "\n"
13218 };
13219
13220 static int acf_channel_write(struct ast_channel *chan, const char *function, char *args, const char *value)
13221 {
13222 struct chan_iax2_pvt *pvt;
13223 unsigned int callno;
13224 int res = 0;
13225
13226 if (!chan || chan->tech != &iax2_tech) {
13227 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13228 return -1;
13229 }
13230
13231 callno = PTR_TO_CALLNO(chan->tech_pvt);
13232 ast_mutex_lock(&iaxsl[callno]);
13233 if (!(pvt = iaxs[callno])) {
13234 ast_mutex_unlock(&iaxsl[callno]);
13235 return -1;
13236 }
13237
13238 if (!strcasecmp(args, "osptoken"))
13239 ast_string_field_set(pvt, osptoken, value);
13240 else
13241 res = -1;
13242
13243 ast_mutex_unlock(&iaxsl[callno]);
13244
13245 return res;
13246 }
13247
13248 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13249 {
13250 struct chan_iax2_pvt *pvt;
13251 unsigned int callno;
13252 int res = 0;
13253
13254 if (!chan || chan->tech != &iax2_tech) {
13255 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13256 return -1;
13257 }
13258
13259 callno = PTR_TO_CALLNO(chan->tech_pvt);
13260 ast_mutex_lock(&iaxsl[callno]);
13261 if (!(pvt = iaxs[callno])) {
13262 ast_mutex_unlock(&iaxsl[callno]);
13263 return -1;
13264 }
13265
13266 if (!strcasecmp(args, "osptoken")) {
13267 ast_copy_string(buf, pvt->osptoken, buflen);
13268 } else if (!strcasecmp(args, "peerip")) {
13269 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13270 } else if (!strcasecmp(args, "peername")) {
13271 ast_copy_string(buf, pvt->username, buflen);
13272 } else {
13273 res = -1;
13274 }
13275
13276 ast_mutex_unlock(&iaxsl[callno]);
13277
13278 return res;
13279 }
13280
13281
13282 static int iax2_devicestate(void *data)
13283 {
13284 struct parsed_dial_string pds;
13285 char *tmp = ast_strdupa(data);
13286 struct iax2_peer *p;
13287 int res = AST_DEVICE_INVALID;
13288
13289 memset(&pds, 0, sizeof(pds));
13290 parse_dial_string(tmp, &pds);
13291
13292 if (ast_strlen_zero(pds.peer)) {
13293 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13294 return res;
13295 }
13296
13297 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13298
13299
13300 if (!(p = find_peer(pds.peer, 1)))
13301 return res;
13302
13303 res = AST_DEVICE_UNAVAILABLE;
13304 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13305 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13306
13307 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
13308 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13309
13310
13311 if (p->historicms == 0 || p->historicms <= p->maxms)
13312
13313 res = AST_DEVICE_UNKNOWN;
13314 }
13315
13316 peer_unref(p);
13317
13318 return res;
13319 }
13320
13321 static struct ast_switch iax2_switch =
13322 {
13323 name: "IAX2",
13324 description: "IAX Remote Dialplan Switch",
13325 exists: iax2_exists,
13326 canmatch: iax2_canmatch,
13327 exec: iax2_exec,
13328 matchmore: iax2_matchmore,
13329 };
13330
13331
13332
13333
13334
13335
13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361
13362
13363
13364
13365
13366
13367
13368
13369
13370
13371
13372
13373
13374
13375
13376
13377
13378
13379
13380
13381
13382
13383
13384
13385
13386
13387
13388
13389
13390
13391
13392
13393
13394
13395
13396
13397
13398
13399
13400
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419
13420
13421
13422
13423
13424
13425
13426
13427
13428
13429
13430
13431
13432
13433
13434
13435 static struct ast_cli_entry cli_iax2[] = {
13436 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
13437 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
13438 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
13439 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
13440 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
13441 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
13442 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
13443 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
13444 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
13445 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
13446 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
13447 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
13448 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
13449 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
13450 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
13451 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
13452 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
13453 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
13454 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
13455 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
13456 #ifdef IAXTESTS
13457 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
13458 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
13459 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
13460 #endif
13461 };
13462
13463 static int __unload_module(void)
13464 {
13465 struct iax2_thread *thread = NULL;
13466 struct ast_context *con;
13467 int x;
13468
13469
13470
13471
13472
13473 if (netthreadid != AST_PTHREADT_NULL) {
13474 AST_LIST_LOCK(&frame_queue);
13475 ast_mutex_lock(&sched_lock);
13476 pthread_cancel(netthreadid);
13477 ast_cond_signal(&sched_cond);
13478 ast_mutex_unlock(&sched_lock);
13479 AST_LIST_UNLOCK(&frame_queue);
13480 pthread_join(netthreadid, NULL);
13481 }
13482 if (schedthreadid != AST_PTHREADT_NULL) {
13483 ast_mutex_lock(&sched_lock);
13484 pthread_cancel(schedthreadid);
13485 ast_cond_signal(&sched_cond);
13486 ast_mutex_unlock(&sched_lock);
13487 pthread_join(schedthreadid, NULL);
13488 }
13489
13490
13491 AST_LIST_LOCK(&idle_list);
13492 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list)))
13493 pthread_cancel(thread->threadid);
13494 AST_LIST_UNLOCK(&idle_list);
13495
13496 AST_LIST_LOCK(&active_list);
13497 while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list)))
13498 pthread_cancel(thread->threadid);
13499 AST_LIST_UNLOCK(&active_list);
13500
13501 AST_LIST_LOCK(&dynamic_list);
13502 while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list)))
13503 pthread_cancel(thread->threadid);
13504 AST_LIST_UNLOCK(&dynamic_list);
13505
13506
13507 while(0 < iaxactivethreadcount)
13508 usleep(10000);
13509
13510 ast_netsock_release(netsock);
13511 ast_netsock_release(outsock);
13512 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13513 if (iaxs[x]) {
13514 iax2_destroy(x);
13515 }
13516 }
13517 ast_manager_unregister( "IAXpeers" );
13518 ast_manager_unregister( "IAXpeerlist" );
13519 ast_manager_unregister( "IAXnetstats" );
13520 ast_unregister_application(papp);
13521 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
13522 ast_unregister_switch(&iax2_switch);
13523 ast_channel_unregister(&iax2_tech);
13524 delete_users();
13525 iax_provision_unload();
13526 sched_context_destroy(sched);
13527 reload_firmware(1);
13528
13529 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13530 ast_mutex_destroy(&iaxsl[x]);
13531 }
13532
13533 ao2_ref(peers, -1);
13534 ao2_ref(users, -1);
13535 ao2_ref(iax_peercallno_pvts, -1);
13536 ao2_ref(iax_transfercallno_pvts, -1);
13537 ao2_ref(peercnts, -1);
13538 ao2_ref(callno_limits, -1);
13539 ao2_ref(calltoken_ignores, -1);
13540 ao2_ref(callno_pool, -1);
13541 ao2_ref(callno_pool_trunk, -1);
13542 if (timer) {
13543 ast_timer_close(timer);
13544 }
13545
13546 con = ast_context_find(regcontext);
13547 if (con)
13548 ast_context_destroy(con, "IAX2");
13549 ast_unload_realtime("iaxpeers");
13550 return 0;
13551 }
13552
13553 static int unload_module(void)
13554 {
13555 ast_custom_function_unregister(&iaxpeer_function);
13556 ast_custom_function_unregister(&iaxvar_function);
13557 return __unload_module();
13558 }
13559
13560 static int peer_set_sock_cb(void *obj, void *arg, int flags)
13561 {
13562 struct iax2_peer *peer = obj;
13563
13564 if (peer->sockfd < 0)
13565 peer->sockfd = defaultsockfd;
13566
13567 return 0;
13568 }
13569
13570 static int pvt_hash_cb(const void *obj, const int flags)
13571 {
13572 const struct chan_iax2_pvt *pvt = obj;
13573
13574 return pvt->peercallno;
13575 }
13576
13577 static int pvt_cmp_cb(void *obj, void *arg, int flags)
13578 {
13579 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13580
13581
13582
13583
13584 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
13585 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13586 }
13587
13588 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
13589 {
13590 const struct chan_iax2_pvt *pvt = obj;
13591
13592 return pvt->transfercallno;
13593 }
13594
13595 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
13596 {
13597 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13598
13599
13600
13601
13602 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
13603 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13604 }
13605
13606 static int load_objects(void)
13607 {
13608 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
13609 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
13610
13611 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
13612 goto container_fail;
13613 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
13614 goto container_fail;
13615 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
13616 goto container_fail;
13617 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
13618 goto container_fail;
13619 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
13620 goto container_fail;
13621 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13622 goto container_fail;
13623 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13624 goto container_fail;
13625 } else if (create_callno_pools()) {
13626 goto container_fail;
13627 }
13628
13629 return 0;
13630
13631 container_fail:
13632 if (peers) {
13633 ao2_ref(peers, -1);
13634 }
13635 if (users) {
13636 ao2_ref(users, -1);
13637 }
13638 if (iax_peercallno_pvts) {
13639 ao2_ref(iax_peercallno_pvts, -1);
13640 }
13641 if (iax_transfercallno_pvts) {
13642 ao2_ref(iax_transfercallno_pvts, -1);
13643 }
13644 if (peercnts) {
13645 ao2_ref(peercnts, -1);
13646 }
13647 if (callno_limits) {
13648 ao2_ref(callno_limits, -1);
13649 }
13650 if (calltoken_ignores) {
13651 ao2_ref(calltoken_ignores, -1);
13652 }
13653 if (callno_pool) {
13654 ao2_ref(callno_pool, -1);
13655 }
13656 if (callno_pool_trunk) {
13657 ao2_ref(callno_pool_trunk, -1);
13658 }
13659 return AST_MODULE_LOAD_FAILURE;
13660 }
13661
13662
13663
13664
13665 static int load_module(void)
13666 {
13667
13668 static const char config[] = "iax.conf";
13669 int x = 0;
13670 struct iax2_registry *reg = NULL;
13671
13672 if (load_objects()) {
13673 return AST_MODULE_LOAD_FAILURE;
13674 }
13675
13676 randomcalltokendata = ast_random();
13677 ast_custom_function_register(&iaxpeer_function);
13678 ast_custom_function_register(&iaxvar_function);
13679
13680 iax_set_output(iax_debug_output);
13681 iax_set_error(iax_error_output);
13682 jb_setoutput(jb_error_output, jb_warning_output, NULL);
13683
13684 memset(iaxs, 0, sizeof(iaxs));
13685
13686 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13687 ast_mutex_init(&iaxsl[x]);
13688 }
13689
13690 ast_cond_init(&sched_cond, NULL);
13691
13692 if (!(sched = sched_context_create())) {
13693 ast_log(LOG_ERROR, "Failed to create scheduler context\n");
13694 return AST_MODULE_LOAD_FAILURE;
13695 }
13696
13697 if (!(io = io_context_create())) {
13698 ast_log(LOG_ERROR, "Failed to create I/O context\n");
13699 sched_context_destroy(sched);
13700 return AST_MODULE_LOAD_FAILURE;
13701 }
13702
13703 if (!(netsock = ast_netsock_list_alloc())) {
13704 ast_log(LOG_ERROR, "Failed to create netsock list\n");
13705 io_context_destroy(io);
13706 sched_context_destroy(sched);
13707 return AST_MODULE_LOAD_FAILURE;
13708 }
13709 ast_netsock_init(netsock);
13710
13711 outsock = ast_netsock_list_alloc();
13712 if (!outsock) {
13713 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13714 io_context_destroy(io);
13715 sched_context_destroy(sched);
13716 return AST_MODULE_LOAD_FAILURE;
13717 }
13718 ast_netsock_init(outsock);
13719
13720 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
13721
13722 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
13723
13724 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
13725 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
13726 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
13727
13728 if ((timer = ast_timer_open())) {
13729 ast_timer_set_rate(timer, trunkfreq);
13730 }
13731
13732 if (set_config(config, 0) == -1) {
13733 if (timer) {
13734 ast_timer_close(timer);
13735 }
13736 return AST_MODULE_LOAD_DECLINE;
13737 }
13738
13739 if (ast_channel_register(&iax2_tech)) {
13740 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
13741 __unload_module();
13742 return AST_MODULE_LOAD_FAILURE;
13743 }
13744
13745 if (ast_register_switch(&iax2_switch))
13746 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
13747
13748 if (start_network_thread()) {
13749 ast_log(LOG_ERROR, "Unable to start network thread\n");
13750 __unload_module();
13751 return AST_MODULE_LOAD_FAILURE;
13752 } else
13753 ast_verb(2, "IAX Ready and Listening\n");
13754
13755 AST_LIST_LOCK(®istrations);
13756 AST_LIST_TRAVERSE(®istrations, reg, entry)
13757 iax2_do_register(reg);
13758 AST_LIST_UNLOCK(®istrations);
13759
13760 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
13761 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
13762
13763
13764 reload_firmware(0);
13765 iax_provision_reload(0);
13766
13767 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
13768
13769 return AST_MODULE_LOAD_SUCCESS;
13770 }
13771
13772 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
13773 .load = load_module,
13774 .unload = unload_module,
13775 .reload = reload,
13776 );