00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "asterisk.h"
00039
00040 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 324634 $")
00041
00042 #include <sys/mman.h>
00043 #include <dirent.h>
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 #include <arpa/inet.h>
00047 #include <netinet/in_systm.h>
00048 #include <netinet/ip.h>
00049 #include <sys/time.h>
00050 #include <sys/signal.h>
00051 #include <signal.h>
00052 #include <strings.h>
00053 #include <netdb.h>
00054 #include <fcntl.h>
00055 #include <sys/stat.h>
00056 #include <regex.h>
00057
00058 #include "asterisk/paths.h"
00059
00060 #include "asterisk/lock.h"
00061 #include "asterisk/frame.h"
00062 #include "asterisk/channel.h"
00063 #include "asterisk/module.h"
00064 #include "asterisk/pbx.h"
00065 #include "asterisk/sched.h"
00066 #include "asterisk/io.h"
00067 #include "asterisk/config.h"
00068 #include "asterisk/cli.h"
00069 #include "asterisk/translate.h"
00070 #include "asterisk/md5.h"
00071 #include "asterisk/cdr.h"
00072 #include "asterisk/crypto.h"
00073 #include "asterisk/acl.h"
00074 #include "asterisk/manager.h"
00075 #include "asterisk/callerid.h"
00076 #include "asterisk/app.h"
00077 #include "asterisk/astdb.h"
00078 #include "asterisk/musiconhold.h"
00079 #include "asterisk/features.h"
00080 #include "asterisk/utils.h"
00081 #include "asterisk/causes.h"
00082 #include "asterisk/localtime.h"
00083 #include "asterisk/aes.h"
00084 #include "asterisk/dnsmgr.h"
00085 #include "asterisk/devicestate.h"
00086 #include "asterisk/netsock.h"
00087 #include "asterisk/stringfields.h"
00088 #include "asterisk/linkedlists.h"
00089 #include "asterisk/event.h"
00090 #include "asterisk/astobj2.h"
00091 #include "asterisk/timing.h"
00092
00093 #include "iax2.h"
00094 #include "iax2-parser.h"
00095 #include "iax2-provision.h"
00096 #include "jitterbuf.h"
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 #define SCHED_MULTITHREADED
00183
00184
00185
00186 #define DEBUG_SCHED_MULTITHREAD
00187
00188
00189 #ifdef SO_NO_CHECK
00190 static int nochecksums = 0;
00191 #endif
00192
00193 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00194 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00195
00196 #define DEFAULT_THREAD_COUNT 10
00197 #define DEFAULT_MAX_THREAD_COUNT 100
00198 #define DEFAULT_RETRY_TIME 1000
00199 #define MEMORY_SIZE 100
00200 #define DEFAULT_DROP 3
00201
00202 #define DEBUG_SUPPORT
00203
00204 #define MIN_REUSE_TIME 60
00205
00206
00207 #define GAMMA (0.01)
00208
00209 static struct ast_codec_pref prefs;
00210
00211 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00212
00213
00214
00215
00216 #define MAX_TRUNK_MTU 1240
00217
00218 static int global_max_trunk_mtu;
00219 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00220
00221 #define DEFAULT_CONTEXT "default"
00222
00223 static char default_parkinglot[AST_MAX_CONTEXT];
00224
00225 static char language[MAX_LANGUAGE] = "";
00226 static char regcontext[AST_MAX_CONTEXT] = "";
00227
00228 static int maxauthreq = 3;
00229 static int max_retries = 4;
00230 static int ping_time = 21;
00231 static int lagrq_time = 10;
00232 static int maxjitterbuffer=1000;
00233 static int resyncthreshold=1000;
00234 static int maxjitterinterps=10;
00235 static int jittertargetextra = 40;
00236
00237 #define MAX_TRUNKDATA 640 * 200
00238
00239 static int trunkfreq = 20;
00240 static int trunkmaxsize = MAX_TRUNKDATA;
00241
00242 static int authdebug = 1;
00243 static int autokill = 0;
00244 static int iaxcompat = 0;
00245 static int last_authmethod = 0;
00246
00247 static int iaxdefaultdpcache=10 * 60;
00248
00249 static int iaxdefaulttimeout = 5;
00250
00251 static struct {
00252 unsigned int tos;
00253 unsigned int cos;
00254 } qos = { 0, 0 };
00255
00256 static int min_reg_expire;
00257 static int max_reg_expire;
00258
00259 static int srvlookup = 0;
00260
00261 static struct ast_timer *timer;
00262
00263 static struct ast_netsock_list *netsock;
00264 static struct ast_netsock_list *outsock;
00265 static int defaultsockfd = -1;
00266
00267 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00268
00269
00270 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00271
00272 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00273 ~AST_FORMAT_SLINEAR & \
00274 ~AST_FORMAT_SLINEAR16 & \
00275 ~AST_FORMAT_SIREN7 & \
00276 ~AST_FORMAT_SIREN14 & \
00277 ~AST_FORMAT_ULAW & \
00278 ~AST_FORMAT_ALAW & \
00279 ~AST_FORMAT_G722)
00280
00281 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00282 ~AST_FORMAT_G726 & \
00283 ~AST_FORMAT_G726_AAL2 & \
00284 ~AST_FORMAT_ADPCM)
00285
00286 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00287 ~AST_FORMAT_G723_1)
00288
00289
00290 #define DEFAULT_MAXMS 2000
00291 #define DEFAULT_FREQ_OK 60 * 1000
00292 #define DEFAULT_FREQ_NOTOK 10 * 1000
00293
00294
00295 #define IAX_CALLENCRYPTED(pvt) \
00296 (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED))
00297
00298 #define IAX_DEBUGDIGEST(msg, key) do { \
00299 int idx; \
00300 char digest[33] = ""; \
00301 \
00302 if (!iaxdebug) \
00303 break; \
00304 \
00305 for (idx = 0; idx < 16; idx++) \
00306 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00307 \
00308 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00309 } while(0)
00310
00311 static struct io_context *io;
00312 static struct ast_sched_thread *sched;
00313
00314 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00315
00316 static int iaxdebug = 0;
00317
00318 static int iaxtrunkdebug = 0;
00319
00320 static int test_losspct = 0;
00321 #ifdef IAXTESTS
00322 static int test_late = 0;
00323 static int test_resync = 0;
00324 static int test_jit = 0;
00325 static int test_jitpct = 0;
00326 #endif
00327
00328 static char accountcode[AST_MAX_ACCOUNT_CODE];
00329 static char mohinterpret[MAX_MUSICCLASS];
00330 static char mohsuggest[MAX_MUSICCLASS];
00331 static int amaflags = 0;
00332 static int adsi = 0;
00333 static int delayreject = 0;
00334 static int iax2_encryption = 0;
00335
00336 static struct ast_flags globalflags = { 0 };
00337
00338 static pthread_t netthreadid = AST_PTHREADT_NULL;
00339
00340 enum iax2_state {
00341 IAX_STATE_STARTED = (1 << 0),
00342 IAX_STATE_AUTHENTICATED = (1 << 1),
00343 IAX_STATE_TBD = (1 << 2),
00344 };
00345
00346 struct iax2_context {
00347 char context[AST_MAX_CONTEXT];
00348 struct iax2_context *next;
00349 };
00350
00351 enum iax2_flags {
00352 IAX_HASCALLERID = (1 << 0),
00353 IAX_DELME = (1 << 1),
00354 IAX_TEMPONLY = (1 << 2),
00355 IAX_TRUNK = (1 << 3),
00356 IAX_NOTRANSFER = (1 << 4),
00357 IAX_USEJITTERBUF = (1 << 5),
00358 IAX_DYNAMIC = (1 << 6),
00359 IAX_SENDANI = (1 << 7),
00360
00361 IAX_ALREADYGONE = (1 << 9),
00362 IAX_PROVISION = (1 << 10),
00363 IAX_QUELCH = (1 << 11),
00364 IAX_ENCRYPTED = (1 << 12),
00365 IAX_KEYPOPULATED = (1 << 13),
00366 IAX_CODEC_USER_FIRST = (1 << 14),
00367 IAX_CODEC_NOPREFS = (1 << 15),
00368 IAX_CODEC_NOCAP = (1 << 16),
00369 IAX_RTCACHEFRIENDS = (1 << 17),
00370 IAX_RTUPDATE = (1 << 18),
00371 IAX_RTAUTOCLEAR = (1 << 19),
00372 IAX_FORCEJITTERBUF = (1 << 20),
00373 IAX_RTIGNOREREGEXPIRE = (1 << 21),
00374 IAX_TRUNKTIMESTAMPS = (1 << 22),
00375 IAX_TRANSFERMEDIA = (1 << 23),
00376 IAX_MAXAUTHREQ = (1 << 24),
00377 IAX_DELAYPBXSTART = (1 << 25),
00378
00379
00380 IAX_ALLOWFWDOWNLOAD = (1 << 26),
00381 IAX_IMMEDIATE = (1 << 27),
00382 IAX_FORCE_ENCRYPT = (1 << 28),
00383 IAX_SHRINKCALLERID = (1 << 29),
00384 };
00385
00386 static int global_rtautoclear = 120;
00387
00388 static int reload_config(void);
00389
00390
00391
00392
00393 enum calltoken_peer_enum {
00394
00395 CALLTOKEN_DEFAULT = 0,
00396
00397 CALLTOKEN_YES = 1,
00398
00399
00400 CALLTOKEN_AUTO = 2,
00401
00402 CALLTOKEN_NO = 3,
00403 };
00404
00405 struct iax2_user {
00406 AST_DECLARE_STRING_FIELDS(
00407 AST_STRING_FIELD(name);
00408 AST_STRING_FIELD(secret);
00409 AST_STRING_FIELD(dbsecret);
00410 AST_STRING_FIELD(accountcode);
00411 AST_STRING_FIELD(mohinterpret);
00412 AST_STRING_FIELD(mohsuggest);
00413 AST_STRING_FIELD(inkeys);
00414 AST_STRING_FIELD(language);
00415 AST_STRING_FIELD(cid_num);
00416 AST_STRING_FIELD(cid_name);
00417 AST_STRING_FIELD(parkinglot);
00418 );
00419
00420 int authmethods;
00421 int encmethods;
00422 int amaflags;
00423 int adsi;
00424 unsigned int flags;
00425 int capability;
00426 int maxauthreq;
00427 int curauthreq;
00428 struct ast_codec_pref prefs;
00429 struct ast_ha *ha;
00430 struct iax2_context *contexts;
00431 struct ast_variable *vars;
00432 enum calltoken_peer_enum calltoken_required;
00433 };
00434
00435 struct iax2_peer {
00436 AST_DECLARE_STRING_FIELDS(
00437 AST_STRING_FIELD(name);
00438 AST_STRING_FIELD(username);
00439 AST_STRING_FIELD(secret);
00440 AST_STRING_FIELD(dbsecret);
00441 AST_STRING_FIELD(outkey);
00442
00443 AST_STRING_FIELD(regexten);
00444 AST_STRING_FIELD(context);
00445 AST_STRING_FIELD(peercontext);
00446 AST_STRING_FIELD(mailbox);
00447 AST_STRING_FIELD(mohinterpret);
00448 AST_STRING_FIELD(mohsuggest);
00449 AST_STRING_FIELD(inkeys);
00450
00451 AST_STRING_FIELD(cid_num);
00452 AST_STRING_FIELD(cid_name);
00453 AST_STRING_FIELD(zonetag);
00454 AST_STRING_FIELD(parkinglot);
00455 );
00456 struct ast_codec_pref prefs;
00457 struct ast_dnsmgr_entry *dnsmgr;
00458 struct sockaddr_in addr;
00459 int formats;
00460 int sockfd;
00461 struct in_addr mask;
00462 int adsi;
00463 unsigned int flags;
00464
00465
00466 struct sockaddr_in defaddr;
00467 int authmethods;
00468 int encmethods;
00469
00470 int expire;
00471 int expiry;
00472 int capability;
00473
00474
00475 int callno;
00476 int pokeexpire;
00477 int lastms;
00478 int maxms;
00479
00480 int pokefreqok;
00481 int pokefreqnotok;
00482 int historicms;
00483 int smoothing;
00484 uint16_t maxcallno;
00485
00486 struct ast_event_sub *mwi_event_sub;
00487
00488 struct ast_ha *ha;
00489 enum calltoken_peer_enum calltoken_required;
00490 };
00491
00492 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00493
00494 struct iax2_trunk_peer {
00495 ast_mutex_t lock;
00496 int sockfd;
00497 struct sockaddr_in addr;
00498 struct timeval txtrunktime;
00499 struct timeval rxtrunktime;
00500 struct timeval lasttxtime;
00501 struct timeval trunkact;
00502 unsigned int lastsent;
00503
00504 unsigned char *trunkdata;
00505 unsigned int trunkdatalen;
00506 unsigned int trunkdataalloc;
00507 int trunkmaxmtu;
00508 int trunkerror;
00509 int calls;
00510 AST_LIST_ENTRY(iax2_trunk_peer) list;
00511 };
00512
00513 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00514
00515 struct iax_firmware {
00516 AST_LIST_ENTRY(iax_firmware) list;
00517 int fd;
00518 int mmaplen;
00519 int dead;
00520 struct ast_iax2_firmware_header *fwh;
00521 unsigned char *buf;
00522 };
00523
00524 enum iax_reg_state {
00525 REG_STATE_UNREGISTERED = 0,
00526 REG_STATE_REGSENT,
00527 REG_STATE_AUTHSENT,
00528 REG_STATE_REGISTERED,
00529 REG_STATE_REJECTED,
00530 REG_STATE_TIMEOUT,
00531 REG_STATE_NOAUTH
00532 };
00533
00534 enum iax_transfer_state {
00535 TRANSFER_NONE = 0,
00536 TRANSFER_BEGIN,
00537 TRANSFER_READY,
00538 TRANSFER_RELEASED,
00539 TRANSFER_PASSTHROUGH,
00540 TRANSFER_MBEGIN,
00541 TRANSFER_MREADY,
00542 TRANSFER_MRELEASED,
00543 TRANSFER_MPASSTHROUGH,
00544 TRANSFER_MEDIA,
00545 TRANSFER_MEDIAPASS
00546 };
00547
00548 struct iax2_registry {
00549 struct sockaddr_in addr;
00550 char username[80];
00551 char secret[80];
00552 int expire;
00553 int refresh;
00554 enum iax_reg_state regstate;
00555 int messages;
00556 int callno;
00557 struct sockaddr_in us;
00558 struct ast_dnsmgr_entry *dnsmgr;
00559 AST_LIST_ENTRY(iax2_registry) entry;
00560 };
00561
00562 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00563
00564
00565 #define MIN_RETRY_TIME 100
00566 #define MAX_RETRY_TIME 10000
00567
00568 #define MAX_JITTER_BUFFER 50
00569 #define MIN_JITTER_BUFFER 10
00570
00571 #define DEFAULT_TRUNKDATA 640 * 10
00572
00573 #define MAX_TIMESTAMP_SKEW 160
00574
00575
00576 #define TS_GAP_FOR_JB_RESYNC 5000
00577
00578
00579 #define MARK_IAX_SUBCLASS_TX 0x8000
00580
00581 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00582 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00583 static int iaxdynamicthreadcount = 0;
00584 static int iaxdynamicthreadnum = 0;
00585 static int iaxactivethreadcount = 0;
00586
00587 struct iax_rr {
00588 int jitter;
00589 int losspct;
00590 int losscnt;
00591 int packets;
00592 int delay;
00593 int dropped;
00594 int ooo;
00595 };
00596
00597 struct iax2_pvt_ref;
00598
00599 struct chan_iax2_pvt {
00600
00601 int sockfd;
00602
00603 int voiceformat;
00604
00605 int videoformat;
00606
00607 int svoiceformat;
00608
00609 int svideoformat;
00610
00611 int capability;
00612
00613 unsigned int last;
00614
00615 unsigned int lastsent;
00616
00617 unsigned int lastvsent;
00618
00619 unsigned int nextpred;
00620
00621 int first_iax_message;
00622
00623 int last_iax_message;
00624
00625 unsigned int notsilenttx:1;
00626
00627 unsigned int pingtime;
00628
00629 int maxtime;
00630
00631 struct sockaddr_in addr;
00632
00633 struct ast_codec_pref prefs;
00634
00635 struct ast_codec_pref rprefs;
00636
00637 unsigned short callno;
00638
00639 struct callno_entry *callno_entry;
00640
00641 unsigned short peercallno;
00642
00643
00644
00645 int chosenformat;
00646
00647 int peerformat;
00648
00649 int peercapability;
00650
00651 struct timeval offset;
00652
00653 struct timeval rxcore;
00654
00655 jitterbuf *jb;
00656
00657 int jbid;
00658
00659 int lag;
00660
00661 int error;
00662
00663 struct ast_channel *owner;
00664
00665 struct ast_flags state;
00666
00667 int expiry;
00668
00669 unsigned char oseqno;
00670
00671 unsigned char rseqno;
00672
00673 unsigned char iseqno;
00674
00675 unsigned char aseqno;
00676
00677 AST_DECLARE_STRING_FIELDS(
00678
00679 AST_STRING_FIELD(peer);
00680
00681 AST_STRING_FIELD(context);
00682
00683 AST_STRING_FIELD(cid_num);
00684 AST_STRING_FIELD(cid_name);
00685
00686 AST_STRING_FIELD(ani);
00687
00688 AST_STRING_FIELD(dnid);
00689
00690 AST_STRING_FIELD(rdnis);
00691
00692 AST_STRING_FIELD(exten);
00693
00694 AST_STRING_FIELD(username);
00695
00696 AST_STRING_FIELD(secret);
00697
00698 AST_STRING_FIELD(challenge);
00699
00700 AST_STRING_FIELD(inkeys);
00701
00702 AST_STRING_FIELD(outkey);
00703
00704 AST_STRING_FIELD(language);
00705
00706 AST_STRING_FIELD(host);
00707
00708 AST_STRING_FIELD(dproot);
00709 AST_STRING_FIELD(accountcode);
00710 AST_STRING_FIELD(mohinterpret);
00711 AST_STRING_FIELD(mohsuggest);
00712
00713 AST_STRING_FIELD(osptoken);
00714
00715 AST_STRING_FIELD(parkinglot);
00716 );
00717
00718 int authrej;
00719
00720 int authmethods;
00721
00722 int encmethods;
00723
00724 ast_aes_encrypt_key ecx;
00725
00726 ast_aes_decrypt_key mydcx;
00727
00728 ast_aes_decrypt_key dcx;
00729
00730
00731 int keyrotateid;
00732
00733 unsigned char semirand[32];
00734
00735 struct iax2_registry *reg;
00736
00737 struct iax2_peer *peerpoke;
00738
00739 unsigned int flags;
00740 int adsi;
00741
00742
00743 enum iax_transfer_state transferring;
00744
00745 int transferid;
00746
00747 struct sockaddr_in transfer;
00748
00749 unsigned short transfercallno;
00750
00751 ast_aes_encrypt_key tdcx;
00752
00753
00754 int peeradsicpe;
00755
00756
00757 unsigned short bridgecallno;
00758
00759 int pingid;
00760 int lagid;
00761 int autoid;
00762 int authid;
00763 int authfail;
00764 int initid;
00765 int calling_ton;
00766 int calling_tns;
00767 int calling_pres;
00768 int amaflags;
00769 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00770
00771 struct ast_variable *vars;
00772
00773 struct ast_variable *iaxvars;
00774
00775 struct iax_rr remote_rr;
00776
00777 int min;
00778
00779 int frames_dropped;
00780
00781 int frames_received;
00782
00783 unsigned char calltoken_ie_len;
00784
00785 char hold_signaling;
00786
00787 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00788 };
00789
00790 struct signaling_queue_entry {
00791 struct ast_frame f;
00792 AST_LIST_ENTRY(signaling_queue_entry) next;
00793 };
00794
00795
00796 static struct ao2_container *callno_pool;
00797
00798
00799 static struct ao2_container *callno_pool_trunk;
00800
00801 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00802
00803
00804
00805
00806
00807
00808
00809
00810 static AST_LIST_HEAD_STATIC(frame_queue, iax_frame);
00811
00812 static int randomcalltokendata;
00813
00814 static const time_t MAX_CALLTOKEN_DELAY = 10;
00815
00816
00817
00818
00819
00820
00821
00822
00823 #ifdef LOW_MEMORY
00824 #define MAX_PEER_BUCKETS 17
00825 #else
00826 #define MAX_PEER_BUCKETS 563
00827 #endif
00828 static struct ao2_container *peers;
00829
00830 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00831 static struct ao2_container *users;
00832
00833
00834 static struct ao2_container *peercnts;
00835
00836
00837 static struct ao2_container *callno_limits;
00838
00839
00840 static struct ao2_container *calltoken_ignores;
00841
00842 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00843
00844 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00845
00846 static uint16_t global_maxcallno;
00847
00848
00849 static uint16_t global_maxcallno_nonval;
00850
00851 static uint16_t total_nonval_callno_used = 0;
00852
00853
00854
00855 struct peercnt {
00856
00857 unsigned long addr;
00858
00859 uint16_t cur;
00860
00861 uint16_t limit;
00862
00863
00864 unsigned char reg;
00865 };
00866
00867
00868 struct addr_range {
00869
00870 struct ast_ha ha;
00871
00872 uint16_t limit;
00873
00874 unsigned char delme;
00875 };
00876
00877 struct callno_entry {
00878
00879 uint16_t callno;
00880
00881 unsigned char validated;
00882 };
00883
00884 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00885
00886 enum {
00887
00888 CACHE_FLAG_EXISTS = (1 << 0),
00889
00890 CACHE_FLAG_NONEXISTENT = (1 << 1),
00891
00892 CACHE_FLAG_CANEXIST = (1 << 2),
00893
00894 CACHE_FLAG_PENDING = (1 << 3),
00895
00896 CACHE_FLAG_TIMEOUT = (1 << 4),
00897
00898 CACHE_FLAG_TRANSMITTED = (1 << 5),
00899
00900 CACHE_FLAG_UNKNOWN = (1 << 6),
00901
00902 CACHE_FLAG_MATCHMORE = (1 << 7),
00903 };
00904
00905 struct iax2_dpcache {
00906 char peercontext[AST_MAX_CONTEXT];
00907 char exten[AST_MAX_EXTENSION];
00908 struct timeval orig;
00909 struct timeval expiry;
00910 int flags;
00911 unsigned short callno;
00912 int waiters[256];
00913 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00914 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00915 };
00916
00917 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00918
00919 static void reg_source_db(struct iax2_peer *p);
00920 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00921 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00922
00923 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00924 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, int flags);
00925 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00926
00927 enum iax2_thread_iostate {
00928 IAX_IOSTATE_IDLE,
00929 IAX_IOSTATE_READY,
00930 IAX_IOSTATE_PROCESSING,
00931 IAX_IOSTATE_SCHEDREADY,
00932 };
00933
00934 enum iax2_thread_type {
00935 IAX_THREAD_TYPE_POOL,
00936 IAX_THREAD_TYPE_DYNAMIC,
00937 };
00938
00939 struct iax2_pkt_buf {
00940 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00941 size_t len;
00942 unsigned char buf[1];
00943 };
00944
00945 struct iax2_thread {
00946 AST_LIST_ENTRY(iax2_thread) list;
00947 enum iax2_thread_type type;
00948 enum iax2_thread_iostate iostate;
00949 #ifdef SCHED_MULTITHREADED
00950 void (*schedfunc)(const void *);
00951 const void *scheddata;
00952 #endif
00953 #ifdef DEBUG_SCHED_MULTITHREAD
00954 char curfunc[80];
00955 #endif
00956 int actions;
00957 pthread_t threadid;
00958 int threadnum;
00959 struct sockaddr_in iosin;
00960 unsigned char readbuf[4096];
00961 unsigned char *buf;
00962 ssize_t buf_len;
00963 size_t buf_size;
00964 int iofd;
00965 time_t checktime;
00966 ast_mutex_t lock;
00967 ast_cond_t cond;
00968 ast_mutex_t init_lock;
00969 ast_cond_t init_cond;
00970
00971
00972
00973
00974 struct {
00975 unsigned short callno;
00976 struct sockaddr_in sin;
00977 unsigned char type;
00978 unsigned char csub;
00979 } ffinfo;
00980
00981
00982
00983 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00984 unsigned char stop;
00985 };
00986
00987
00988 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00989 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00990 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00991
00992 static void *iax2_process_thread(void *data);
00993 static void iax2_destroy(int callno);
00994
00995 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00996 {
00997 ast_mutex_lock(lock);
00998 ast_cond_signal(cond);
00999 ast_mutex_unlock(lock);
01000 }
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS + 1];
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021 static struct ao2_container *iax_peercallno_pvts;
01022
01023
01024
01025
01026
01027
01028
01029
01030 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
01031
01032
01033
01034
01035
01036
01037 static struct ao2_container *iax_transfercallno_pvts;
01038
01039
01040
01041 #define TRUNK_CALL_START IAX_MAX_CALLS / 2
01042
01043
01044 static struct sockaddr_in debugaddr;
01045
01046 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
01047 {
01048 if (iaxdebug ||
01049 (sin && debugaddr.sin_addr.s_addr &&
01050 (!ntohs(debugaddr.sin_port) ||
01051 debugaddr.sin_port == sin->sin_port) &&
01052 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01053 if (iaxdebug) {
01054 iax_showframe(f, fhi, rx, sin, datalen);
01055 } else {
01056 iaxdebug = 1;
01057 iax_showframe(f, fhi, rx, sin, datalen);
01058 iaxdebug = 0;
01059 }
01060 }
01061 }
01062
01063 static void iax_debug_output(const char *data)
01064 {
01065 if (iaxdebug)
01066 ast_verbose("%s", data);
01067 }
01068
01069 static void iax_error_output(const char *data)
01070 {
01071 ast_log(LOG_WARNING, "%s", data);
01072 }
01073
01074 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
01075 {
01076 va_list args;
01077 char buf[1024];
01078
01079 va_start(args, fmt);
01080 vsnprintf(buf, sizeof(buf), fmt, args);
01081 va_end(args);
01082
01083 ast_log(LOG_ERROR, "%s", buf);
01084 }
01085
01086 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01087 {
01088 va_list args;
01089 char buf[1024];
01090
01091 va_start(args, fmt);
01092 vsnprintf(buf, sizeof(buf), fmt, args);
01093 va_end(args);
01094
01095 ast_log(LOG_WARNING, "%s", buf);
01096 }
01097
01098 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01099 {
01100 va_list args;
01101 char buf[1024];
01102
01103 va_start(args, fmt);
01104 vsnprintf(buf, sizeof(buf), fmt, args);
01105 va_end(args);
01106
01107 ast_verbose("%s", buf);
01108 }
01109
01110 static int maxtrunkcall = TRUNK_CALL_START;
01111 static int maxnontrunkcall = 1;
01112
01113 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);
01114 static int expire_registry(const void *data);
01115 static int iax2_answer(struct ast_channel *c);
01116 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01117 static int iax2_devicestate(void *data);
01118 static int iax2_digit_begin(struct ast_channel *c, char digit);
01119 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01120 static int iax2_do_register(struct iax2_registry *reg);
01121 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01122 static int iax2_hangup(struct ast_channel *c);
01123 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01124 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01125 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
01126 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01127 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01128 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01129 static int iax2_sendtext(struct ast_channel *c, const char *text);
01130 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01131 static int iax2_transfer(struct ast_channel *c, const char *dest);
01132 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01133 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01134 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01135 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01136 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01137 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01138 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01139 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
01140 static struct ast_frame *iax2_read(struct ast_channel *c);
01141 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01142 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01143 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
01144 static void *iax2_dup_variable_datastore(void *);
01145 static void prune_peers(void);
01146 static void prune_users(void);
01147 static void iax2_free_variable_datastore(void *);
01148
01149 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01150 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01151 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01152 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01153 static void build_rand_pad(unsigned char *buf, ssize_t len);
01154 static struct callno_entry *get_unused_callno(int trunk, int validated);
01155 static int replace_callno(const void *obj);
01156 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01157
01158 static const struct ast_channel_tech iax2_tech = {
01159 .type = "IAX2",
01160 .description = tdesc,
01161 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01162 .properties = AST_CHAN_TP_WANTSJITTER,
01163 .requester = iax2_request,
01164 .devicestate = iax2_devicestate,
01165 .send_digit_begin = iax2_digit_begin,
01166 .send_digit_end = iax2_digit_end,
01167 .send_text = iax2_sendtext,
01168 .send_image = iax2_sendimage,
01169 .send_html = iax2_sendhtml,
01170 .call = iax2_call,
01171 .hangup = iax2_hangup,
01172 .answer = iax2_answer,
01173 .read = iax2_read,
01174 .write = iax2_write,
01175 .write_video = iax2_write,
01176 .indicate = iax2_indicate,
01177 .setoption = iax2_setoption,
01178 .bridge = iax2_bridge,
01179 .transfer = iax2_transfer,
01180 .fixup = iax2_fixup,
01181 .func_channel_read = acf_channel_read,
01182 };
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201 static void iax2_lock_owner(int callno)
01202 {
01203 for (;;) {
01204 if (!iaxs[callno] || !iaxs[callno]->owner) {
01205
01206 break;
01207 }
01208 if (!ast_channel_trylock(iaxs[callno]->owner)) {
01209
01210 break;
01211 }
01212
01213 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01214 }
01215 }
01216
01217 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01218 {
01219
01220
01221
01222 }
01223
01224
01225
01226 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01227 {
01228 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01229 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01230 pvt->owner ? pvt->owner->name : "",
01231 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01232 }
01233
01234
01235 static struct ast_datastore_info iax2_variable_datastore_info = {
01236 .type = "IAX2_VARIABLE",
01237 .duplicate = iax2_dup_variable_datastore,
01238 .destroy = iax2_free_variable_datastore,
01239 };
01240
01241 static void *iax2_dup_variable_datastore(void *old)
01242 {
01243 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01244 struct ast_var_t *oldvar, *newvar;
01245
01246 newlist = ast_calloc(sizeof(*newlist), 1);
01247 if (!newlist) {
01248 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01249 return NULL;
01250 }
01251
01252 AST_LIST_HEAD_INIT(newlist);
01253 AST_LIST_LOCK(oldlist);
01254 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01255 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01256 if (newvar)
01257 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01258 else
01259 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01260 }
01261 AST_LIST_UNLOCK(oldlist);
01262 return newlist;
01263 }
01264
01265 static void iax2_free_variable_datastore(void *old)
01266 {
01267 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01268 struct ast_var_t *oldvar;
01269
01270 AST_LIST_LOCK(oldlist);
01271 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01272 ast_free(oldvar);
01273 }
01274 AST_LIST_UNLOCK(oldlist);
01275 AST_LIST_HEAD_DESTROY(oldlist);
01276 ast_free(oldlist);
01277 }
01278
01279
01280
01281
01282
01283 static void insert_idle_thread(struct iax2_thread *thread)
01284 {
01285 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01286 AST_LIST_LOCK(&dynamic_list);
01287 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01288 AST_LIST_UNLOCK(&dynamic_list);
01289 } else {
01290 AST_LIST_LOCK(&idle_list);
01291 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01292 AST_LIST_UNLOCK(&idle_list);
01293 }
01294
01295 return;
01296 }
01297
01298 static struct iax2_thread *find_idle_thread(void)
01299 {
01300 struct iax2_thread *thread = NULL;
01301
01302
01303 AST_LIST_LOCK(&idle_list);
01304 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01305 AST_LIST_UNLOCK(&idle_list);
01306
01307
01308 if (thread) {
01309 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01310 return thread;
01311 }
01312
01313
01314 AST_LIST_LOCK(&dynamic_list);
01315 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01316 AST_LIST_UNLOCK(&dynamic_list);
01317
01318
01319 if (thread) {
01320 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01321 return thread;
01322 }
01323
01324
01325 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01326 return NULL;
01327
01328
01329 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01330 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01331 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01332
01333
01334 ast_mutex_init(&thread->lock);
01335 ast_cond_init(&thread->cond, NULL);
01336 ast_mutex_init(&thread->init_lock);
01337 ast_cond_init(&thread->init_cond, NULL);
01338 ast_mutex_lock(&thread->init_lock);
01339
01340
01341 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01342 ast_cond_destroy(&thread->cond);
01343 ast_mutex_destroy(&thread->lock);
01344 ast_mutex_unlock(&thread->init_lock);
01345 ast_cond_destroy(&thread->init_cond);
01346 ast_mutex_destroy(&thread->init_lock);
01347 ast_free(thread);
01348 return NULL;
01349 }
01350
01351
01352
01353 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01354
01355
01356 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01357
01358
01359 ast_mutex_unlock(&thread->init_lock);
01360
01361 return thread;
01362 }
01363
01364 #ifdef SCHED_MULTITHREADED
01365 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01366 {
01367 struct iax2_thread *thread = NULL;
01368 static time_t lasterror;
01369 static time_t t;
01370
01371 thread = find_idle_thread();
01372
01373 if (thread != NULL) {
01374 thread->schedfunc = func;
01375 thread->scheddata = data;
01376 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01377 #ifdef DEBUG_SCHED_MULTITHREAD
01378 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01379 #endif
01380 signal_condition(&thread->lock, &thread->cond);
01381 return 0;
01382 }
01383 time(&t);
01384 if (t != lasterror)
01385 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01386 lasterror = t;
01387
01388 return -1;
01389 }
01390 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01391 #endif
01392
01393 static int iax2_sched_replace(int id, struct ast_sched_thread *st, int when,
01394 ast_sched_cb callback, const void *data)
01395 {
01396 ast_sched_thread_del(st, id);
01397
01398 return ast_sched_thread_add(st, when, callback, data);
01399 }
01400
01401 static int iax2_sched_add(struct ast_sched_thread *st, int when,
01402 ast_sched_cb callback, const void *data)
01403 {
01404 return ast_sched_thread_add(st, when, callback, data);
01405 }
01406
01407 static int send_ping(const void *data);
01408
01409 static void __send_ping(const void *data)
01410 {
01411 int callno = (long) data;
01412
01413 ast_mutex_lock(&iaxsl[callno]);
01414
01415 if (iaxs[callno]) {
01416 if (iaxs[callno]->peercallno) {
01417 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01418 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01419 } else {
01420
01421 iaxs[callno]->pingid = -1;
01422 }
01423 } else {
01424 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01425 }
01426
01427 ast_mutex_unlock(&iaxsl[callno]);
01428 }
01429
01430 static int send_ping(const void *data)
01431 {
01432 #ifdef SCHED_MULTITHREADED
01433 if (schedule_action(__send_ping, data))
01434 #endif
01435 __send_ping(data);
01436
01437 return 0;
01438 }
01439
01440 static void encmethods_to_str(int e, struct ast_str *buf)
01441 {
01442 ast_str_set(&buf, 0, "(");
01443 if (e & IAX_ENCRYPT_AES128) {
01444 ast_str_append(&buf, 0, "aes128");
01445 }
01446 if (e & IAX_ENCRYPT_KEYROTATE) {
01447 ast_str_append(&buf, 0, ",keyrotate");
01448 }
01449 if (ast_str_strlen(buf) > 1) {
01450 ast_str_append(&buf, 0, ")");
01451 } else {
01452 ast_str_set(&buf, 0, "No");
01453 }
01454 }
01455
01456 static int get_encrypt_methods(const char *s)
01457 {
01458 int e;
01459 if (!strcasecmp(s, "aes128"))
01460 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01461 else if (ast_true(s))
01462 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01463 else
01464 e = 0;
01465 return e;
01466 }
01467
01468 static int send_lagrq(const void *data);
01469
01470 static void __send_lagrq(const void *data)
01471 {
01472 int callno = (long) data;
01473
01474 ast_mutex_lock(&iaxsl[callno]);
01475
01476 if (iaxs[callno]) {
01477 if (iaxs[callno]->peercallno) {
01478 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01479 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01480 } else {
01481
01482 iaxs[callno]->lagid = -1;
01483 }
01484 } else {
01485 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01486 }
01487
01488 ast_mutex_unlock(&iaxsl[callno]);
01489 }
01490
01491 static int send_lagrq(const void *data)
01492 {
01493 #ifdef SCHED_MULTITHREADED
01494 if (schedule_action(__send_lagrq, data))
01495 #endif
01496 __send_lagrq(data);
01497
01498 return 0;
01499 }
01500
01501 static unsigned char compress_subclass(int subclass)
01502 {
01503 int x;
01504 int power=-1;
01505
01506 if (subclass < IAX_FLAG_SC_LOG)
01507 return subclass;
01508
01509 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01510 if (subclass & (1 << x)) {
01511 if (power > -1) {
01512 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01513 return 0;
01514 } else
01515 power = x;
01516 }
01517 }
01518 return power | IAX_FLAG_SC_LOG;
01519 }
01520
01521 static int uncompress_subclass(unsigned char csub)
01522 {
01523
01524 if (csub & IAX_FLAG_SC_LOG) {
01525
01526 if (csub == 0xff)
01527 return -1;
01528 else
01529 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01530 }
01531 else
01532 return csub;
01533 }
01534
01535
01536
01537
01538 static int peer_hash_cb(const void *obj, const int flags)
01539 {
01540 const struct iax2_peer *peer = obj;
01541
01542 return ast_str_hash(peer->name);
01543 }
01544
01545
01546
01547
01548 static int peer_cmp_cb(void *obj, void *arg, int flags)
01549 {
01550 struct iax2_peer *peer = obj, *peer2 = arg;
01551
01552 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01553 }
01554
01555
01556
01557
01558 static int user_hash_cb(const void *obj, const int flags)
01559 {
01560 const struct iax2_user *user = obj;
01561
01562 return ast_str_hash(user->name);
01563 }
01564
01565
01566
01567
01568 static int user_cmp_cb(void *obj, void *arg, int flags)
01569 {
01570 struct iax2_user *user = obj, *user2 = arg;
01571
01572 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01573 }
01574
01575
01576
01577
01578
01579 static struct iax2_peer *find_peer(const char *name, int realtime)
01580 {
01581 struct iax2_peer *peer = NULL;
01582 struct iax2_peer tmp_peer = {
01583 .name = name,
01584 };
01585
01586 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01587
01588
01589 if(!peer && realtime)
01590 peer = realtime_peer(name, NULL);
01591
01592 return peer;
01593 }
01594
01595 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01596 {
01597 ao2_ref(peer, +1);
01598 return peer;
01599 }
01600
01601 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01602 {
01603 ao2_ref(peer, -1);
01604 return NULL;
01605 }
01606
01607 static struct iax2_user *find_user(const char *name)
01608 {
01609 struct iax2_user tmp_user = {
01610 .name = name,
01611 };
01612
01613 return ao2_find(users, &tmp_user, OBJ_POINTER);
01614 }
01615 static inline struct iax2_user *user_ref(struct iax2_user *user)
01616 {
01617 ao2_ref(user, +1);
01618 return user;
01619 }
01620
01621 static inline struct iax2_user *user_unref(struct iax2_user *user)
01622 {
01623 ao2_ref(user, -1);
01624 return NULL;
01625 }
01626
01627 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01628 {
01629 struct iax2_peer *peer = NULL;
01630 int res = 0;
01631 struct ao2_iterator i;
01632
01633 i = ao2_iterator_init(peers, 0);
01634 while ((peer = ao2_iterator_next(&i))) {
01635 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01636 (peer->addr.sin_port == sin.sin_port)) {
01637 ast_copy_string(host, peer->name, len);
01638 peer_unref(peer);
01639 res = 1;
01640 break;
01641 }
01642 peer_unref(peer);
01643 }
01644 ao2_iterator_destroy(&i);
01645
01646 if (!peer) {
01647 peer = realtime_peer(NULL, &sin);
01648 if (peer) {
01649 ast_copy_string(host, peer->name, len);
01650 peer_unref(peer);
01651 res = 1;
01652 }
01653 }
01654
01655 return res;
01656 }
01657
01658
01659
01660 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01661 {
01662
01663 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01664 struct iax2_user *user;
01665 struct iax2_user tmp_user = {
01666 .name = pvt->username,
01667 };
01668
01669 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01670 if (user) {
01671 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01672 user_unref(user);
01673 }
01674
01675 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01676 }
01677
01678 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01679 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01680 ast_sched_thread_del(sched, pvt->autoid);
01681 ast_sched_thread_del(sched, pvt->authid);
01682 ast_sched_thread_del(sched, pvt->initid);
01683 ast_sched_thread_del(sched, pvt->jbid);
01684 ast_sched_thread_del(sched, pvt->keyrotateid);
01685 }
01686
01687 static void iax2_frame_free(struct iax_frame *fr)
01688 {
01689 ast_sched_thread_del(sched, fr->retrans);
01690 iax_frame_free(fr);
01691 }
01692
01693 static int scheduled_destroy(const void *vid)
01694 {
01695 unsigned short callno = PTR_TO_CALLNO(vid);
01696 ast_mutex_lock(&iaxsl[callno]);
01697 if (iaxs[callno]) {
01698 if (option_debug) {
01699 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01700 }
01701 iax2_destroy(callno);
01702 }
01703 ast_mutex_unlock(&iaxsl[callno]);
01704 return 0;
01705 }
01706
01707 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01708 {
01709 ast_free(s->f.data.ptr);
01710 ast_free(s);
01711 }
01712
01713
01714
01715 static void send_signaling(struct chan_iax2_pvt *pvt)
01716 {
01717 struct signaling_queue_entry *s = NULL;
01718
01719 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01720 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01721 free_signaling_queue_entry(s);
01722 }
01723 pvt->hold_signaling = 0;
01724 }
01725
01726
01727
01728 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01729 {
01730 struct signaling_queue_entry *new;
01731
01732 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01733 return 1;
01734 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01735 return -1;
01736 }
01737
01738 memcpy(&new->f, f, sizeof(new->f));
01739
01740 if (new->f.datalen) {
01741 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01742 free_signaling_queue_entry(new);
01743 return -1;
01744 }
01745 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01746 }
01747 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01748
01749 return 0;
01750 }
01751
01752 static void pvt_destructor(void *obj)
01753 {
01754 struct chan_iax2_pvt *pvt = obj;
01755 struct iax_frame *cur = NULL;
01756 struct signaling_queue_entry *s = NULL;
01757
01758 ast_mutex_lock(&iaxsl[pvt->callno]);
01759 iax2_destroy_helper(pvt);
01760 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01761 pvt->callno_entry = NULL;
01762 ast_mutex_unlock(&iaxsl[pvt->callno]);
01763
01764
01765 ast_set_flag(pvt, IAX_ALREADYGONE);
01766
01767 AST_LIST_LOCK(&frame_queue);
01768 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01769
01770 if (cur->callno == pvt->callno) {
01771 cur->retries = -1;
01772 }
01773 }
01774 AST_LIST_UNLOCK(&frame_queue);
01775
01776 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01777 free_signaling_queue_entry(s);
01778 }
01779
01780 if (pvt->reg) {
01781 pvt->reg->callno = 0;
01782 }
01783
01784 if (!pvt->owner) {
01785 jb_frame frame;
01786 if (pvt->vars) {
01787 ast_variables_destroy(pvt->vars);
01788 pvt->vars = NULL;
01789 }
01790
01791 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01792 iax2_frame_free(frame.data);
01793 }
01794
01795 jb_destroy(pvt->jb);
01796 ast_string_field_free_memory(pvt);
01797 }
01798 }
01799
01800 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01801 {
01802 struct chan_iax2_pvt *tmp;
01803 jb_conf jbconf;
01804
01805 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01806 return NULL;
01807 }
01808
01809 if (ast_string_field_init(tmp, 32)) {
01810 ao2_ref(tmp, -1);
01811 tmp = NULL;
01812 return NULL;
01813 }
01814
01815 tmp->prefs = prefs;
01816 tmp->pingid = -1;
01817 tmp->lagid = -1;
01818 tmp->autoid = -1;
01819 tmp->authid = -1;
01820 tmp->initid = -1;
01821 tmp->keyrotateid = -1;
01822
01823 ast_string_field_set(tmp,exten, "s");
01824 ast_string_field_set(tmp,host, host);
01825
01826 tmp->jb = jb_new();
01827 tmp->jbid = -1;
01828 jbconf.max_jitterbuf = maxjitterbuffer;
01829 jbconf.resync_threshold = resyncthreshold;
01830 jbconf.max_contig_interp = maxjitterinterps;
01831 jbconf.target_extra = jittertargetextra;
01832 jb_setconf(tmp->jb,&jbconf);
01833
01834 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01835
01836 tmp->hold_signaling = 1;
01837 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01838
01839 return tmp;
01840 }
01841
01842 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01843 {
01844 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01845 if (new) {
01846 size_t afdatalen = new->afdatalen;
01847 memcpy(new, fr, sizeof(*new));
01848 iax_frame_wrap(new, &fr->af);
01849 new->afdatalen = afdatalen;
01850 new->data = NULL;
01851 new->datalen = 0;
01852 new->direction = DIRECTION_INGRESS;
01853 new->retrans = -1;
01854 }
01855 return new;
01856 }
01857
01858
01859 enum {
01860
01861 NEW_PREVENT = 0,
01862
01863 NEW_ALLOW = 1,
01864
01865 NEW_FORCE = 2,
01866
01867
01868 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01869 };
01870
01871 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01872 {
01873 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01874 (cur->addr.sin_port == sin->sin_port)) {
01875
01876 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01877 (check_dcallno ? dcallno == cur->callno : 1) ) {
01878
01879 return 1;
01880 }
01881 }
01882 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01883 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01884
01885 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01886 return 1;
01887 }
01888 return 0;
01889 }
01890
01891 static void update_max_trunk(void)
01892 {
01893 int max = TRUNK_CALL_START;
01894 int x;
01895
01896
01897 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01898 if (iaxs[x]) {
01899 max = x + 1;
01900 }
01901 }
01902
01903 maxtrunkcall = max;
01904 if (iaxdebug)
01905 ast_debug(1, "New max trunk callno is %d\n", max);
01906 }
01907
01908 static void update_max_nontrunk(void)
01909 {
01910 int max = 1;
01911 int x;
01912
01913 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01914 if (iaxs[x])
01915 max = x + 1;
01916 }
01917 maxnontrunkcall = max;
01918 if (iaxdebug)
01919 ast_debug(1, "New max nontrunk callno is %d\n", max);
01920 }
01921
01922 static int make_trunk(unsigned short callno, int locked)
01923 {
01924 int x;
01925 int res= 0;
01926 struct callno_entry *callno_entry;
01927 if (iaxs[callno]->oseqno) {
01928 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01929 return -1;
01930 }
01931 if (callno & TRUNK_CALL_START) {
01932 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01933 return -1;
01934 }
01935
01936 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
01937 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01938 return -1;
01939 }
01940
01941 x = callno_entry->callno;
01942 ast_mutex_lock(&iaxsl[x]);
01943
01944
01945
01946
01947
01948 ast_sched_thread_del(sched, iaxs[callno]->pingid);
01949 ast_sched_thread_del(sched, iaxs[callno]->lagid);
01950 iaxs[x] = iaxs[callno];
01951 iaxs[x]->callno = x;
01952
01953
01954
01955 if (iaxs[x]->callno_entry) {
01956 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
01957 }
01958 iaxs[x]->callno_entry = callno_entry;
01959
01960 iaxs[callno] = NULL;
01961
01962 iaxs[x]->pingid = iax2_sched_add(sched,
01963 ping_time * 1000, send_ping, (void *)(long)x);
01964 iaxs[x]->lagid = iax2_sched_add(sched,
01965 lagrq_time * 1000, send_lagrq, (void *)(long)x);
01966
01967 if (locked)
01968 ast_mutex_unlock(&iaxsl[callno]);
01969 res = x;
01970 if (!locked)
01971 ast_mutex_unlock(&iaxsl[x]);
01972
01973 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01974
01975 update_max_trunk();
01976 update_max_nontrunk();
01977 return res;
01978 }
01979
01980 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01981 {
01982 if (!pvt->transfercallno) {
01983 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01984 return;
01985 }
01986
01987 ao2_link(iax_transfercallno_pvts, pvt);
01988 }
01989
01990 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01991 {
01992 if (!pvt->transfercallno) {
01993 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01994 return;
01995 }
01996
01997 ao2_unlink(iax_transfercallno_pvts, pvt);
01998 }
01999 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
02000 {
02001 if (!pvt->peercallno) {
02002 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02003 return;
02004 }
02005
02006 ao2_link(iax_peercallno_pvts, pvt);
02007 }
02008
02009 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
02010 {
02011 if (!pvt->peercallno) {
02012 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02013 return;
02014 }
02015
02016 ao2_unlink(iax_peercallno_pvts, pvt);
02017 }
02018
02019 static int addr_range_delme_cb(void *obj, void *arg, int flags)
02020 {
02021 struct addr_range *lim = obj;
02022 lim->delme = 1;
02023 return 0;
02024 }
02025
02026 static int addr_range_hash_cb(const void *obj, const int flags)
02027 {
02028 const struct addr_range *lim = obj;
02029 return abs((int) lim->ha.netaddr.s_addr);
02030 }
02031
02032 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
02033 {
02034 struct addr_range *lim1 = obj, *lim2 = arg;
02035 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
02036 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
02037 CMP_MATCH | CMP_STOP : 0;
02038 }
02039
02040 static int peercnt_hash_cb(const void *obj, const int flags)
02041 {
02042 const struct peercnt *peercnt = obj;
02043 return abs((int) peercnt->addr);
02044 }
02045
02046 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
02047 {
02048 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02049 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02050 }
02051
02052 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
02053 {
02054 struct addr_range *addr_range = obj;
02055 struct sockaddr_in *sin = arg;
02056
02057 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
02058 return CMP_MATCH | CMP_STOP;
02059 }
02060 return 0;
02061 }
02062
02063
02064
02065
02066
02067
02068 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
02069 {
02070 struct addr_range *addr_range;
02071 struct iax2_peer *peer = NULL;
02072 struct iax2_user *user = NULL;
02073
02074 const char *find = S_OR(name, "guest");
02075 int res = 1;
02076 int optional = 0;
02077 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02078
02079
02080
02081
02082
02083
02084
02085 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02086 ao2_ref(addr_range, -1);
02087 optional = 1;
02088 }
02089
02090
02091 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02092 calltoken_required = user->calltoken_required;
02093 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02094 calltoken_required = user->calltoken_required;
02095 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02096 calltoken_required = peer->calltoken_required;
02097 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02098 calltoken_required = peer->calltoken_required;
02099 }
02100
02101 if (peer) {
02102 peer_unref(peer);
02103 }
02104 if (user) {
02105 user_unref(user);
02106 }
02107
02108 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);
02109 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02110 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02111 res = 0;
02112 }
02113
02114 return res;
02115 }
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127 static void set_peercnt_limit(struct peercnt *peercnt)
02128 {
02129 uint16_t limit = global_maxcallno;
02130 struct addr_range *addr_range;
02131 struct sockaddr_in sin = {
02132 .sin_addr.s_addr = peercnt->addr,
02133 };
02134
02135
02136 if (peercnt->reg && peercnt->limit) {
02137 return;
02138 }
02139
02140 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02141 limit = addr_range->limit;
02142 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02143 ao2_ref(addr_range, -1);
02144 }
02145
02146 peercnt->limit = limit;
02147 }
02148
02149
02150
02151
02152
02153 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02154 {
02155 struct peercnt *peercnt = obj;
02156
02157 set_peercnt_limit(peercnt);
02158 ast_debug(1, "Reset limits for peercnts table\n");
02159
02160 return 0;
02161 }
02162
02163
02164
02165
02166
02167 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02168 {
02169 struct addr_range *addr_range = obj;
02170
02171 return addr_range->delme ? CMP_MATCH : 0;
02172 }
02173
02174
02175
02176
02177
02178 static void peercnt_modify(unsigned char reg, uint16_t limit, struct sockaddr_in *sin)
02179 {
02180
02181 struct peercnt *peercnt;
02182 struct peercnt tmp = {
02183 .addr = sin->sin_addr.s_addr,
02184 };
02185
02186 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02187 peercnt->reg = reg;
02188 if (limit) {
02189 peercnt->limit = limit;
02190 } else {
02191 set_peercnt_limit(peercnt);
02192 }
02193 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg);
02194 ao2_ref(peercnt, -1);
02195 }
02196 }
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206 static int peercnt_add(struct sockaddr_in *sin)
02207 {
02208 struct peercnt *peercnt;
02209 unsigned long addr = sin->sin_addr.s_addr;
02210 int res = 0;
02211 struct peercnt tmp = {
02212 .addr = addr,
02213 };
02214
02215
02216
02217
02218
02219
02220
02221 ao2_lock(peercnts);
02222 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02223 ao2_lock(peercnt);
02224 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02225 ao2_lock(peercnt);
02226
02227 peercnt->addr = addr;
02228 set_peercnt_limit(peercnt);
02229
02230
02231 ao2_link(peercnts, peercnt);
02232 } else {
02233 ao2_unlock(peercnts);
02234 return -1;
02235 }
02236
02237
02238 if (peercnt->limit > peercnt->cur) {
02239 peercnt->cur++;
02240 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02241 } else {
02242 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02243 res = -1;
02244 }
02245
02246
02247 ao2_unlock(peercnt);
02248 ao2_unlock(peercnts);
02249 ao2_ref(peercnt, -1);
02250
02251 return res;
02252 }
02253
02254
02255
02256
02257
02258 static void peercnt_remove(struct peercnt *peercnt)
02259 {
02260 struct sockaddr_in sin = {
02261 .sin_addr.s_addr = peercnt->addr,
02262 };
02263
02264 if (peercnt) {
02265
02266
02267
02268 ao2_lock(peercnts);
02269 peercnt->cur--;
02270 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02271
02272 if (peercnt->cur == 0) {
02273 ao2_unlink(peercnts, peercnt);
02274 }
02275 ao2_unlock(peercnts);
02276 }
02277 }
02278
02279
02280
02281
02282
02283 static int peercnt_remove_cb(const void *obj)
02284 {
02285 struct peercnt *peercnt = (struct peercnt *) obj;
02286
02287 peercnt_remove(peercnt);
02288 ao2_ref(peercnt, -1);
02289
02290 return 0;
02291 }
02292
02293
02294
02295
02296
02297 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02298 {
02299 struct peercnt *peercnt;
02300 struct peercnt tmp = {
02301 .addr = sin->sin_addr.s_addr,
02302 };
02303
02304 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02305 peercnt_remove(peercnt);
02306 ao2_ref(peercnt, -1);
02307 }
02308 return 0;
02309 }
02310
02311
02312
02313
02314
02315 static void build_callno_limits(struct ast_variable *v)
02316 {
02317 struct addr_range *addr_range = NULL;
02318 struct addr_range tmp;
02319 struct ast_ha *ha;
02320 int limit;
02321 int error;
02322 int found;
02323
02324 for (; v; v = v->next) {
02325 limit = -1;
02326 error = 0;
02327 found = 0;
02328 ha = ast_append_ha("permit", v->name, NULL, &error);
02329
02330
02331 if (error) {
02332 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02333 continue;
02334 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02335 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02336 ast_free_ha(ha);
02337 continue;
02338 }
02339
02340 ast_copy_ha(ha, &tmp.ha);
02341
02342 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02343 ao2_lock(addr_range);
02344 found = 1;
02345 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02346 ast_free_ha(ha);
02347 return;
02348 }
02349
02350
02351 ast_copy_ha(ha, &addr_range->ha);
02352 ast_free_ha(ha);
02353 addr_range->limit = limit;
02354 addr_range->delme = 0;
02355
02356
02357 if (found) {
02358 ao2_unlock(addr_range);
02359 } else {
02360 ao2_link(callno_limits, addr_range);
02361 }
02362 ao2_ref(addr_range, -1);
02363 }
02364 }
02365
02366
02367
02368
02369
02370 static int add_calltoken_ignore(const char *addr)
02371 {
02372 struct addr_range tmp;
02373 struct addr_range *addr_range = NULL;
02374 struct ast_ha *ha = NULL;
02375 int error = 0;
02376
02377 if (ast_strlen_zero(addr)) {
02378 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02379 return -1;
02380 }
02381
02382 ha = ast_append_ha("permit", addr, NULL, &error);
02383
02384
02385 if (error) {
02386 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02387 return -1;
02388 }
02389
02390 ast_copy_ha(ha, &tmp.ha);
02391
02392 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02393 ao2_lock(addr_range);
02394 addr_range->delme = 0;
02395 ao2_unlock(addr_range);
02396 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02397
02398 ast_copy_ha(ha, &addr_range->ha);
02399 ao2_link(calltoken_ignores, addr_range);
02400 } else {
02401 ast_free_ha(ha);
02402 return -1;
02403 }
02404
02405 ast_free_ha(ha);
02406 ao2_ref(addr_range, -1);
02407
02408 return 0;
02409 }
02410
02411 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02412 {
02413 struct ao2_iterator i;
02414 struct peercnt *peercnt;
02415 struct sockaddr_in sin;
02416 int found = 0;
02417
02418 switch (cmd) {
02419 case CLI_INIT:
02420 e->command = "iax2 show callnumber usage";
02421 e->usage =
02422 "Usage: iax2 show callnumber usage <ip address (optional)>\n"
02423 " Shows current ip addresses which are consuming iax2 call numbers\n";
02424 return NULL;
02425 case CLI_GENERATE:
02426 return NULL;
02427 case CLI_HANDLER:
02428 if (a->argc < 4 || a->argc > 5)
02429 return CLI_SHOWUSAGE;
02430
02431 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02432 i = ao2_iterator_init(peercnts, 0);
02433 while ((peercnt = ao2_iterator_next(&i))) {
02434 sin.sin_addr.s_addr = peercnt->addr;
02435 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02436 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02437 found = 1;
02438 break;
02439 } else {
02440 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02441 }
02442 ao2_ref(peercnt, -1);
02443 }
02444 ao2_iterator_destroy(&i);
02445
02446 if (a->argc == 4) {
02447 ast_cli(a->fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
02448 } else if (a->argc == 5 && !found) {
02449 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02450 }
02451
02452 return CLI_SUCCESS;
02453 default:
02454 return NULL;
02455 }
02456 }
02457
02458 static struct callno_entry *get_unused_callno(int trunk, int validated)
02459 {
02460 struct callno_entry *callno_entry = NULL;
02461 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02462 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02463
02464 return NULL;
02465 }
02466
02467
02468
02469 ao2_lock(callno_pool);
02470
02471
02472
02473
02474 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02475 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02476 ao2_unlock(callno_pool);
02477 return NULL;
02478 }
02479
02480
02481
02482 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02483
02484 if (callno_entry) {
02485 callno_entry->validated = validated;
02486 if (!validated) {
02487 total_nonval_callno_used++;
02488 }
02489 }
02490
02491 ao2_unlock(callno_pool);
02492 return callno_entry;
02493 }
02494
02495 static int replace_callno(const void *obj)
02496 {
02497 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02498
02499
02500
02501 ao2_lock(callno_pool);
02502
02503 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02504 total_nonval_callno_used--;
02505 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02506 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02507 }
02508
02509 if (callno_entry->callno < TRUNK_CALL_START) {
02510 ao2_link(callno_pool, callno_entry);
02511 } else {
02512 ao2_link(callno_pool_trunk, callno_entry);
02513 }
02514 ao2_ref(callno_entry, -1);
02515
02516 ao2_unlock(callno_pool);
02517 return 0;
02518 }
02519
02520 static int callno_hash(const void *obj, const int flags)
02521 {
02522 return abs(ast_random());
02523 }
02524
02525 static int create_callno_pools(void)
02526 {
02527 uint16_t i;
02528
02529 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02530 return -1;
02531 }
02532
02533 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02534 return -1;
02535 }
02536
02537
02538 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02539 struct callno_entry *callno_entry;
02540
02541 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02542 return -1;
02543 }
02544
02545 callno_entry->callno = i;
02546
02547 if (i < TRUNK_CALL_START) {
02548 ao2_link(callno_pool, callno_entry);
02549 } else {
02550 ao2_link(callno_pool_trunk, callno_entry);
02551 }
02552
02553 ao2_ref(callno_entry, -1);
02554 }
02555
02556 return 0;
02557 }
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02568 {
02569 int i;
02570 struct peercnt *peercnt;
02571 struct peercnt tmp = {
02572 .addr = sin->sin_addr.s_addr,
02573 };
02574
02575 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02576
02577 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02578 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02579 if (i == -1) {
02580 ao2_ref(peercnt, -1);
02581 }
02582 }
02583
02584 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02585 }
02586
02587
02588
02589
02590
02591
02592
02593
02594 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02595 {
02596 if (frametype != AST_FRAME_IAX) {
02597 return 0;
02598 }
02599 switch (subclass) {
02600 case IAX_COMMAND_NEW:
02601 case IAX_COMMAND_REGREQ:
02602 case IAX_COMMAND_FWDOWNL:
02603 case IAX_COMMAND_REGREL:
02604 return 1;
02605 case IAX_COMMAND_POKE:
02606 if (!inbound) {
02607 return 1;
02608 }
02609 break;
02610 }
02611 return 0;
02612 }
02613
02614
02615
02616
02617 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02618 {
02619 int res = 0;
02620 int x;
02621
02622
02623 int validated = (new > NEW_ALLOW) ? 1 : 0;
02624 char host[80];
02625
02626 if (new <= NEW_ALLOW) {
02627 if (callno) {
02628 struct chan_iax2_pvt *pvt;
02629 struct chan_iax2_pvt tmp_pvt = {
02630 .callno = dcallno,
02631 .peercallno = callno,
02632 .transfercallno = callno,
02633
02634 .frames_received = check_dcallno,
02635 };
02636
02637 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02638
02639 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02640 if (return_locked) {
02641 ast_mutex_lock(&iaxsl[pvt->callno]);
02642 }
02643 res = pvt->callno;
02644 ao2_ref(pvt, -1);
02645 pvt = NULL;
02646 return res;
02647 }
02648
02649 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02650 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02651 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02652 if (return_locked) {
02653 ast_mutex_lock(&iaxsl[pvt->callno]);
02654 }
02655 res = pvt->callno;
02656 ao2_ref(pvt, -1);
02657 pvt = NULL;
02658 return res;
02659 }
02660 }
02661
02662
02663 if (dcallno) {
02664 ast_mutex_lock(&iaxsl[dcallno]);
02665 }
02666 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02667 iaxs[dcallno]->peercallno = callno;
02668 res = dcallno;
02669 store_by_peercallno(iaxs[dcallno]);
02670 if (!res || !return_locked) {
02671 ast_mutex_unlock(&iaxsl[dcallno]);
02672 }
02673 return res;
02674 }
02675 if (dcallno) {
02676 ast_mutex_unlock(&iaxsl[dcallno]);
02677 }
02678 #ifdef IAX_OLD_FIND
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690 for (x = 1; !res && x < maxnontrunkcall; x++) {
02691 ast_mutex_lock(&iaxsl[x]);
02692 if (iaxs[x]) {
02693
02694 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02695 res = x;
02696 }
02697 }
02698 if (!res || !return_locked)
02699 ast_mutex_unlock(&iaxsl[x]);
02700 }
02701 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02702 ast_mutex_lock(&iaxsl[x]);
02703 if (iaxs[x]) {
02704
02705 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02706 res = x;
02707 }
02708 }
02709 if (!res || !return_locked)
02710 ast_mutex_unlock(&iaxsl[x]);
02711 }
02712 #endif
02713 }
02714 if (!res && (new >= NEW_ALLOW)) {
02715 struct callno_entry *callno_entry;
02716
02717
02718
02719
02720
02721
02722 if (!iax2_getpeername(*sin, host, sizeof(host)))
02723 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02724
02725 if (peercnt_add(sin)) {
02726
02727
02728 return 0;
02729 }
02730
02731 if (!(callno_entry = get_unused_callno(0, validated))) {
02732
02733
02734 peercnt_remove_by_addr(sin);
02735 ast_log(LOG_WARNING, "No more space\n");
02736 return 0;
02737 }
02738 x = callno_entry->callno;
02739 ast_mutex_lock(&iaxsl[x]);
02740
02741 iaxs[x] = new_iax(sin, host);
02742 update_max_nontrunk();
02743 if (iaxs[x]) {
02744 if (iaxdebug)
02745 ast_debug(1, "Creating new call structure %d\n", x);
02746 iaxs[x]->callno_entry = callno_entry;
02747 iaxs[x]->sockfd = sockfd;
02748 iaxs[x]->addr.sin_port = sin->sin_port;
02749 iaxs[x]->addr.sin_family = sin->sin_family;
02750 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02751 iaxs[x]->peercallno = callno;
02752 iaxs[x]->callno = x;
02753 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02754 iaxs[x]->expiry = min_reg_expire;
02755 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02756 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02757 iaxs[x]->amaflags = amaflags;
02758 ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT);
02759 ast_string_field_set(iaxs[x], accountcode, accountcode);
02760 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02761 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02762 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02763
02764 if (iaxs[x]->peercallno) {
02765 store_by_peercallno(iaxs[x]);
02766 }
02767 } else {
02768 ast_log(LOG_WARNING, "Out of resources\n");
02769 ast_mutex_unlock(&iaxsl[x]);
02770 replace_callno(callno_entry);
02771 return 0;
02772 }
02773 if (!return_locked)
02774 ast_mutex_unlock(&iaxsl[x]);
02775 res = x;
02776 }
02777 return res;
02778 }
02779
02780 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02781
02782 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02783 }
02784
02785 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02786
02787 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02788 }
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800 static int iax2_queue_frame(int callno, struct ast_frame *f)
02801 {
02802 iax2_lock_owner(callno);
02803 if (iaxs[callno] && iaxs[callno]->owner) {
02804 ast_queue_frame(iaxs[callno]->owner, f);
02805 ast_channel_unlock(iaxs[callno]->owner);
02806 }
02807 return 0;
02808 }
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823 static int iax2_queue_hangup(int callno)
02824 {
02825 iax2_lock_owner(callno);
02826 if (iaxs[callno] && iaxs[callno]->owner) {
02827 ast_queue_hangup(iaxs[callno]->owner);
02828 ast_channel_unlock(iaxs[callno]->owner);
02829 }
02830 return 0;
02831 }
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846 static int iax2_queue_control_data(int callno,
02847 enum ast_control_frame_type control, const void *data, size_t datalen)
02848 {
02849 iax2_lock_owner(callno);
02850 if (iaxs[callno] && iaxs[callno]->owner) {
02851 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02852 ast_channel_unlock(iaxs[callno]->owner);
02853 }
02854 return 0;
02855 }
02856 static void destroy_firmware(struct iax_firmware *cur)
02857 {
02858
02859 if (cur->fwh) {
02860 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02861 }
02862 close(cur->fd);
02863 ast_free(cur);
02864 }
02865
02866 static int try_firmware(char *s)
02867 {
02868 struct stat stbuf;
02869 struct iax_firmware *cur = NULL;
02870 int ifd, fd, res, len, chunk;
02871 struct ast_iax2_firmware_header *fwh, fwh2;
02872 struct MD5Context md5;
02873 unsigned char sum[16], buf[1024];
02874 char *s2, *last;
02875
02876 if (!(s2 = alloca(strlen(s) + 100))) {
02877 ast_log(LOG_WARNING, "Alloca failed!\n");
02878 return -1;
02879 }
02880
02881 last = strrchr(s, '/');
02882 if (last)
02883 last++;
02884 else
02885 last = s;
02886
02887 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02888
02889 if ((res = stat(s, &stbuf) < 0)) {
02890 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02891 return -1;
02892 }
02893
02894
02895 if (S_ISDIR(stbuf.st_mode))
02896 return -1;
02897 ifd = open(s, O_RDONLY);
02898 if (ifd < 0) {
02899 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02900 return -1;
02901 }
02902 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02903 if (fd < 0) {
02904 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02905 close(ifd);
02906 return -1;
02907 }
02908
02909 unlink(s2);
02910
02911
02912 len = stbuf.st_size;
02913 while(len) {
02914 chunk = len;
02915 if (chunk > sizeof(buf))
02916 chunk = sizeof(buf);
02917 res = read(ifd, buf, chunk);
02918 if (res != chunk) {
02919 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02920 close(ifd);
02921 close(fd);
02922 return -1;
02923 }
02924 res = write(fd, buf, chunk);
02925 if (res != chunk) {
02926 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02927 close(ifd);
02928 close(fd);
02929 return -1;
02930 }
02931 len -= chunk;
02932 }
02933 close(ifd);
02934
02935 lseek(fd, 0, SEEK_SET);
02936 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02937 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02938 close(fd);
02939 return -1;
02940 }
02941 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02942 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02943 close(fd);
02944 return -1;
02945 }
02946 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02947 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02948 close(fd);
02949 return -1;
02950 }
02951 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02952 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02953 close(fd);
02954 return -1;
02955 }
02956 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
02957 if (fwh == (void *) -1) {
02958 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02959 close(fd);
02960 return -1;
02961 }
02962 MD5Init(&md5);
02963 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02964 MD5Final(sum, &md5);
02965 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02966 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02967 munmap((void*)fwh, stbuf.st_size);
02968 close(fd);
02969 return -1;
02970 }
02971
02972 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02973 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02974
02975 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02976
02977 break;
02978
02979
02980 munmap((void*)fwh, stbuf.st_size);
02981 close(fd);
02982 return 0;
02983 }
02984 }
02985
02986 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02987 cur->fd = -1;
02988 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02989 }
02990
02991 if (cur) {
02992 if (cur->fwh)
02993 munmap((void*)cur->fwh, cur->mmaplen);
02994 if (cur->fd > -1)
02995 close(cur->fd);
02996 cur->fwh = fwh;
02997 cur->fd = fd;
02998 cur->mmaplen = stbuf.st_size;
02999 cur->dead = 0;
03000 }
03001
03002 return 0;
03003 }
03004
03005 static int iax_check_version(char *dev)
03006 {
03007 int res = 0;
03008 struct iax_firmware *cur = NULL;
03009
03010 if (ast_strlen_zero(dev))
03011 return 0;
03012
03013 AST_LIST_LOCK(&firmwares);
03014 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03015 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03016 res = ntohs(cur->fwh->version);
03017 break;
03018 }
03019 }
03020 AST_LIST_UNLOCK(&firmwares);
03021
03022 return res;
03023 }
03024
03025 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03026 {
03027 int res = -1;
03028 unsigned int bs = desc & 0xff;
03029 unsigned int start = (desc >> 8) & 0xffffff;
03030 unsigned int bytes;
03031 struct iax_firmware *cur;
03032
03033 if (ast_strlen_zero((char *)dev) || !bs)
03034 return -1;
03035
03036 start *= bs;
03037
03038 AST_LIST_LOCK(&firmwares);
03039 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03040 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03041 continue;
03042 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03043 if (start < ntohl(cur->fwh->datalen)) {
03044 bytes = ntohl(cur->fwh->datalen) - start;
03045 if (bytes > bs)
03046 bytes = bs;
03047 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03048 } else {
03049 bytes = 0;
03050 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03051 }
03052 if (bytes == bs)
03053 res = 0;
03054 else
03055 res = 1;
03056 break;
03057 }
03058 AST_LIST_UNLOCK(&firmwares);
03059
03060 return res;
03061 }
03062
03063
03064 static void reload_firmware(int unload)
03065 {
03066 struct iax_firmware *cur = NULL;
03067 DIR *fwd;
03068 struct dirent *de;
03069 char dir[256], fn[256];
03070
03071 AST_LIST_LOCK(&firmwares);
03072
03073
03074 AST_LIST_TRAVERSE(&firmwares, cur, list)
03075 cur->dead = 1;
03076
03077
03078 if (!unload) {
03079 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03080 fwd = opendir(dir);
03081 if (fwd) {
03082 while((de = readdir(fwd))) {
03083 if (de->d_name[0] != '.') {
03084 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03085 if (!try_firmware(fn)) {
03086 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03087 }
03088 }
03089 }
03090 closedir(fwd);
03091 } else
03092 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03093 }
03094
03095
03096 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03097 if (!cur->dead)
03098 continue;
03099 AST_LIST_REMOVE_CURRENT(list);
03100 destroy_firmware(cur);
03101 }
03102 AST_LIST_TRAVERSE_SAFE_END;
03103
03104 AST_LIST_UNLOCK(&firmwares);
03105 }
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115 static int __do_deliver(void *data)
03116 {
03117
03118
03119 struct iax_frame *fr = data;
03120 fr->retrans = -1;
03121 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03122 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
03123 iax2_queue_frame(fr->callno, &fr->af);
03124
03125 iax2_frame_free(fr);
03126
03127 return 0;
03128 }
03129
03130 static int handle_error(void)
03131 {
03132
03133
03134
03135 #if 0
03136 struct sockaddr_in *sin;
03137 int res;
03138 struct msghdr m;
03139 struct sock_extended_err e;
03140 m.msg_name = NULL;
03141 m.msg_namelen = 0;
03142 m.msg_iov = NULL;
03143 m.msg_control = &e;
03144 m.msg_controllen = sizeof(e);
03145 m.msg_flags = 0;
03146 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03147 if (res < 0)
03148 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03149 else {
03150 if (m.msg_controllen) {
03151 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03152 if (sin)
03153 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03154 else
03155 ast_log(LOG_WARNING, "No address detected??\n");
03156 } else {
03157 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03158 }
03159 }
03160 #endif
03161 return 0;
03162 }
03163
03164 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03165 {
03166 int res;
03167 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03168 sizeof(*sin));
03169 if (res < 0) {
03170 ast_debug(1, "Received error: %s\n", strerror(errno));
03171 handle_error();
03172 } else
03173 res = 0;
03174 return res;
03175 }
03176
03177 static int send_packet(struct iax_frame *f)
03178 {
03179 int res;
03180 int callno = f->callno;
03181
03182
03183 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03184 return -1;
03185
03186
03187 if (iaxdebug)
03188 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));
03189
03190 if (f->transfer) {
03191 if (iaxdebug)
03192 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03193 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03194 } else {
03195 if (iaxdebug)
03196 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03197 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03198 }
03199 if (res < 0) {
03200 if (iaxdebug)
03201 ast_debug(1, "Received error: %s\n", strerror(errno));
03202 handle_error();
03203 } else
03204 res = 0;
03205
03206 return res;
03207 }
03208
03209
03210
03211
03212
03213 static int iax2_predestroy(int callno)
03214 {
03215 struct ast_channel *c = NULL;
03216 struct chan_iax2_pvt *pvt = iaxs[callno];
03217
03218 if (!pvt)
03219 return -1;
03220
03221 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
03222 iax2_destroy_helper(pvt);
03223 ast_set_flag(pvt, IAX_ALREADYGONE);
03224 }
03225
03226 if ((c = pvt->owner)) {
03227 c->tech_pvt = NULL;
03228 iax2_queue_hangup(callno);
03229 pvt->owner = NULL;
03230 ast_module_unref(ast_module_info->self);
03231 }
03232
03233 return 0;
03234 }
03235
03236 static void iax2_destroy(int callno)
03237 {
03238 struct chan_iax2_pvt *pvt = NULL;
03239 struct ast_channel *owner = NULL;
03240
03241 retry:
03242 if ((pvt = iaxs[callno])) {
03243 #if 0
03244
03245
03246
03247
03248
03249
03250
03251 iax2_destroy_helper(pvt);
03252 #endif
03253 }
03254
03255 owner = pvt ? pvt->owner : NULL;
03256
03257 if (owner) {
03258 if (ast_channel_trylock(owner)) {
03259 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03260 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03261 goto retry;
03262 }
03263 }
03264
03265 if (!owner) {
03266 iaxs[callno] = NULL;
03267 }
03268
03269 if (pvt) {
03270 if (!owner) {
03271 pvt->owner = NULL;
03272 } else {
03273
03274
03275
03276 ast_queue_hangup(owner);
03277 }
03278
03279 if (pvt->peercallno) {
03280 remove_by_peercallno(pvt);
03281 }
03282
03283 if (pvt->transfercallno) {
03284 remove_by_transfercallno(pvt);
03285 }
03286
03287 if (!owner) {
03288 ao2_ref(pvt, -1);
03289 pvt = NULL;
03290 }
03291 }
03292
03293 if (owner) {
03294 ast_channel_unlock(owner);
03295 }
03296
03297 if (callno & 0x4000) {
03298 update_max_trunk();
03299 }
03300 }
03301
03302 static int update_packet(struct iax_frame *f)
03303 {
03304
03305 struct ast_iax2_full_hdr *fh = f->data;
03306 struct ast_frame af;
03307
03308
03309 if (f->encmethods) {
03310 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03311 }
03312
03313 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03314
03315 f->iseqno = iaxs[f->callno]->iseqno;
03316 fh->iseqno = f->iseqno;
03317
03318
03319 if (f->encmethods) {
03320
03321
03322 build_rand_pad(f->semirand, sizeof(f->semirand));
03323 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03324 }
03325 return 0;
03326 }
03327
03328 static int attempt_transmit(const void *data);
03329 static void __attempt_transmit(const void *data)
03330 {
03331
03332
03333 struct iax_frame *f = (struct iax_frame *)data;
03334 int freeme = 0;
03335 int callno = f->callno;
03336
03337 if (callno)
03338 ast_mutex_lock(&iaxsl[callno]);
03339 if (callno && iaxs[callno]) {
03340 if ((f->retries < 0) ||
03341 (f->retries >= max_retries) ) {
03342
03343 if (f->retries >= max_retries) {
03344 if (f->transfer) {
03345
03346 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03347 } else if (f->final) {
03348 iax2_destroy(callno);
03349 } else {
03350 if (iaxs[callno]->owner)
03351 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);
03352 iaxs[callno]->error = ETIMEDOUT;
03353 if (iaxs[callno]->owner) {
03354 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03355
03356 iax2_queue_frame(callno, &fr);
03357
03358 if (iaxs[callno] && iaxs[callno]->owner)
03359 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03360 } else {
03361 if (iaxs[callno]->reg) {
03362 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03363 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03364 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03365 }
03366 iax2_destroy(callno);
03367 }
03368 }
03369
03370 }
03371 freeme = 1;
03372 } else {
03373
03374 update_packet(f);
03375
03376 send_packet(f);
03377 f->retries++;
03378
03379 f->retrytime *= 10;
03380 if (f->retrytime > MAX_RETRY_TIME)
03381 f->retrytime = MAX_RETRY_TIME;
03382
03383 if (f->transfer && (f->retrytime > 1000))
03384 f->retrytime = 1000;
03385 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03386 }
03387 } else {
03388
03389 f->retries = -1;
03390 freeme = 1;
03391 }
03392 if (callno)
03393 ast_mutex_unlock(&iaxsl[callno]);
03394
03395 if (freeme) {
03396
03397 AST_LIST_LOCK(&frame_queue);
03398 AST_LIST_REMOVE(&frame_queue, f, list);
03399 AST_LIST_UNLOCK(&frame_queue);
03400 f->retrans = -1;
03401
03402 iax2_frame_free(f);
03403 }
03404 }
03405
03406 static int attempt_transmit(const void *data)
03407 {
03408 #ifdef SCHED_MULTITHREADED
03409 if (schedule_action(__attempt_transmit, data))
03410 #endif
03411 __attempt_transmit(data);
03412 return 0;
03413 }
03414
03415 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03416 {
03417 struct iax2_peer *peer = NULL;
03418 struct iax2_user *user = NULL;
03419 static char *choices[] = { "all", NULL };
03420 char *cmplt;
03421
03422 switch (cmd) {
03423 case CLI_INIT:
03424 e->command = "iax2 prune realtime";
03425 e->usage =
03426 "Usage: iax2 prune realtime [<peername>|all]\n"
03427 " Prunes object(s) from the cache\n";
03428 return NULL;
03429 case CLI_GENERATE:
03430 if (a->pos == 3) {
03431 cmplt = ast_cli_complete(a->word, choices, a->n);
03432 if (!cmplt)
03433 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03434 return cmplt;
03435 }
03436 return NULL;
03437 }
03438 if (a->argc != 4)
03439 return CLI_SHOWUSAGE;
03440 if (!strcmp(a->argv[3], "all")) {
03441 prune_users();
03442 prune_peers();
03443 ast_cli(a->fd, "Cache flushed successfully.\n");
03444 return CLI_SUCCESS;
03445 }
03446 peer = find_peer(a->argv[3], 0);
03447 user = find_user(a->argv[3]);
03448 if (peer || user) {
03449 if (peer) {
03450 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
03451 ast_set_flag(peer, IAX_RTAUTOCLEAR);
03452 expire_registry(peer_ref(peer));
03453 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03454 } else {
03455 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03456 }
03457 peer_unref(peer);
03458 }
03459 if (user) {
03460 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
03461 ast_set_flag(user, IAX_RTAUTOCLEAR);
03462 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03463 } else {
03464 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03465 }
03466 ao2_unlink(users,user);
03467 user_unref(user);
03468 }
03469 } else {
03470 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03471 }
03472
03473 return CLI_SUCCESS;
03474 }
03475
03476 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03477 {
03478 switch (cmd) {
03479 case CLI_INIT:
03480 e->command = "iax2 test losspct";
03481 e->usage =
03482 "Usage: iax2 test losspct <percentage>\n"
03483 " For testing, throws away <percentage> percent of incoming packets\n";
03484 return NULL;
03485 case CLI_GENERATE:
03486 return NULL;
03487 }
03488 if (a->argc != 4)
03489 return CLI_SHOWUSAGE;
03490
03491 test_losspct = atoi(a->argv[3]);
03492
03493 return CLI_SUCCESS;
03494 }
03495
03496 #ifdef IAXTESTS
03497 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03498 {
03499 switch (cmd) {
03500 case CLI_INIT:
03501 e->command = "iax2 test late";
03502 e->usage =
03503 "Usage: iax2 test late <ms>\n"
03504 " For testing, count the next frame as <ms> ms late\n";
03505 return NULL;
03506 case CLI_GENERATE:
03507 return NULL;
03508 }
03509
03510 if (a->argc != 4)
03511 return CLI_SHOWUSAGE;
03512
03513 test_late = atoi(a->argv[3]);
03514
03515 return CLI_SUCCESS;
03516 }
03517
03518 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03519 {
03520 switch (cmd) {
03521 case CLI_INIT:
03522 e->command = "iax2 test resync";
03523 e->usage =
03524 "Usage: iax2 test resync <ms>\n"
03525 " For testing, adjust all future frames by <ms> ms\n";
03526 return NULL;
03527 case CLI_GENERATE:
03528 return NULL;
03529 }
03530
03531 if (a->argc != 4)
03532 return CLI_SHOWUSAGE;
03533
03534 test_resync = atoi(a->argv[3]);
03535
03536 return CLI_SUCCESS;
03537 }
03538
03539 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03540 {
03541 switch (cmd) {
03542 case CLI_INIT:
03543 e->command = "iax2 test jitter";
03544 e->usage =
03545 "Usage: iax2 test jitter <ms> <pct>\n"
03546 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03547 " percentage of packets. If <pct> is not specified, adds\n"
03548 " jitter to all packets.\n";
03549 return NULL;
03550 case CLI_GENERATE:
03551 return NULL;
03552 }
03553
03554 if (a->argc < 4 || a->argc > 5)
03555 return CLI_SHOWUSAGE;
03556
03557 test_jit = atoi(a->argv[3]);
03558 if (a->argc == 5)
03559 test_jitpct = atoi(a->argv[4]);
03560
03561 return CLI_SUCCESS;
03562 }
03563 #endif
03564
03565
03566
03567 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03568 {
03569 int res = 0;
03570 if (peer->maxms) {
03571 if (peer->lastms < 0) {
03572 ast_copy_string(status, "UNREACHABLE", statuslen);
03573 } else if (peer->lastms > peer->maxms) {
03574 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03575 res = 1;
03576 } else if (peer->lastms) {
03577 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03578 res = 1;
03579 } else {
03580 ast_copy_string(status, "UNKNOWN", statuslen);
03581 }
03582 } else {
03583 ast_copy_string(status, "Unmonitored", statuslen);
03584 res = -1;
03585 }
03586 return res;
03587 }
03588
03589
03590 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03591 {
03592 char status[30];
03593 char cbuf[256];
03594 struct iax2_peer *peer;
03595 char codec_buf[512];
03596 struct ast_str *encmethods = ast_str_alloca(256);
03597 int x = 0, codec = 0, load_realtime = 0;
03598
03599 switch (cmd) {
03600 case CLI_INIT:
03601 e->command = "iax2 show peer";
03602 e->usage =
03603 "Usage: iax2 show peer <name>\n"
03604 " Display details on specific IAX peer\n";
03605 return NULL;
03606 case CLI_GENERATE:
03607 if (a->pos == 3)
03608 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03609 return NULL;
03610 }
03611
03612 if (a->argc < 4)
03613 return CLI_SHOWUSAGE;
03614
03615 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03616
03617 peer = find_peer(a->argv[3], load_realtime);
03618 if (peer) {
03619 encmethods_to_str(peer->encmethods, encmethods);
03620 ast_cli(a->fd, "\n\n");
03621 ast_cli(a->fd, " * Name : %s\n", peer->name);
03622 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03623 ast_cli(a->fd, " Context : %s\n", peer->context);
03624 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03625 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03626 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
03627 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03628 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03629 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
03630 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03631 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03632 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03633 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03634 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));
03635 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03636 ast_cli(a->fd, " Username : %s\n", peer->username);
03637 ast_cli(a->fd, " Codecs : ");
03638 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03639 ast_cli(a->fd, "%s\n", codec_buf);
03640
03641 ast_cli(a->fd, " Codec Order : (");
03642 for(x = 0; x < 32 ; x++) {
03643 codec = ast_codec_pref_index(&peer->prefs,x);
03644 if(!codec)
03645 break;
03646 ast_cli(a->fd, "%s", ast_getformatname(codec));
03647 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03648 ast_cli(a->fd, "|");
03649 }
03650
03651 if (!x)
03652 ast_cli(a->fd, "none");
03653 ast_cli(a->fd, ")\n");
03654
03655 ast_cli(a->fd, " Status : ");
03656 peer_status(peer, status, sizeof(status));
03657 ast_cli(a->fd, "%s\n",status);
03658 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");
03659 ast_cli(a->fd, "\n");
03660 peer_unref(peer);
03661 } else {
03662 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03663 ast_cli(a->fd, "\n");
03664 }
03665
03666 return CLI_SUCCESS;
03667 }
03668
03669 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, int flags)
03670 {
03671 int which = 0;
03672 struct iax2_peer *peer;
03673 char *res = NULL;
03674 int wordlen = strlen(word);
03675 struct ao2_iterator i;
03676
03677 i = ao2_iterator_init(peers, 0);
03678 while ((peer = ao2_iterator_next(&i))) {
03679 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03680 && (!flags || ast_test_flag(peer, flags))) {
03681 res = ast_strdup(peer->name);
03682 peer_unref(peer);
03683 break;
03684 }
03685 peer_unref(peer);
03686 }
03687 ao2_iterator_destroy(&i);
03688
03689 return res;
03690 }
03691
03692 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03693 {
03694 struct iax_frame *cur;
03695 int cnt = 0, dead = 0, final = 0;
03696
03697 switch (cmd) {
03698 case CLI_INIT:
03699 e->command = "iax2 show stats";
03700 e->usage =
03701 "Usage: iax2 show stats\n"
03702 " Display statistics on IAX channel driver.\n";
03703 return NULL;
03704 case CLI_GENERATE:
03705 return NULL;
03706 }
03707
03708 if (a->argc != 3)
03709 return CLI_SHOWUSAGE;
03710
03711 AST_LIST_LOCK(&frame_queue);
03712 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
03713 if (cur->retries < 0)
03714 dead++;
03715 if (cur->final)
03716 final++;
03717 cnt++;
03718 }
03719 AST_LIST_UNLOCK(&frame_queue);
03720
03721 ast_cli(a->fd, " IAX Statistics\n");
03722 ast_cli(a->fd, "---------------------\n");
03723 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03724 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03725 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03726 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03727
03728 trunk_timed = trunk_untimed = 0;
03729 if (trunk_maxmtu > trunk_nmaxmtu)
03730 trunk_nmaxmtu = trunk_maxmtu;
03731
03732 return CLI_SUCCESS;
03733 }
03734
03735
03736 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03737 {
03738 int mtuv;
03739
03740 switch (cmd) {
03741 case CLI_INIT:
03742 e->command = "iax2 set mtu";
03743 e->usage =
03744 "Usage: iax2 set mtu <value>\n"
03745 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03746 " zero to disable. Disabling means that the operating system\n"
03747 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03748 " packet exceeds the UDP payload size. This is substantially\n"
03749 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03750 " greater for G.711 samples.\n";
03751 return NULL;
03752 case CLI_GENERATE:
03753 return NULL;
03754 }
03755
03756 if (a->argc != 4)
03757 return CLI_SHOWUSAGE;
03758 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03759 mtuv = MAX_TRUNK_MTU;
03760 else
03761 mtuv = atoi(a->argv[3]);
03762
03763 if (mtuv == 0) {
03764 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03765 global_max_trunk_mtu = 0;
03766 return CLI_SUCCESS;
03767 }
03768 if (mtuv < 172 || mtuv > 4000) {
03769 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03770 return CLI_SHOWUSAGE;
03771 }
03772 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03773 global_max_trunk_mtu = mtuv;
03774 return CLI_SUCCESS;
03775 }
03776
03777 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03778 {
03779 struct iax2_dpcache *dp = NULL;
03780 char tmp[1024], *pc = NULL;
03781 int s, x, y;
03782 struct timeval now = ast_tvnow();
03783
03784 switch (cmd) {
03785 case CLI_INIT:
03786 e->command = "iax2 show cache";
03787 e->usage =
03788 "Usage: iax2 show cache\n"
03789 " Display currently cached IAX Dialplan results.\n";
03790 return NULL;
03791 case CLI_GENERATE:
03792 return NULL;
03793 }
03794
03795 AST_LIST_LOCK(&dpcache);
03796
03797 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03798
03799 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03800 s = dp->expiry.tv_sec - now.tv_sec;
03801 tmp[0] = '\0';
03802 if (dp->flags & CACHE_FLAG_EXISTS)
03803 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03804 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03805 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03806 if (dp->flags & CACHE_FLAG_CANEXIST)
03807 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03808 if (dp->flags & CACHE_FLAG_PENDING)
03809 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03810 if (dp->flags & CACHE_FLAG_TIMEOUT)
03811 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03812 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03813 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03814 if (dp->flags & CACHE_FLAG_MATCHMORE)
03815 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03816 if (dp->flags & CACHE_FLAG_UNKNOWN)
03817 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03818
03819 if (!ast_strlen_zero(tmp)) {
03820 tmp[strlen(tmp) - 1] = '\0';
03821 } else {
03822 ast_copy_string(tmp, "(none)", sizeof(tmp));
03823 }
03824 y = 0;
03825 pc = strchr(dp->peercontext, '@');
03826 if (!pc) {
03827 pc = dp->peercontext;
03828 } else {
03829 pc++;
03830 }
03831 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03832 if (dp->waiters[x] > -1)
03833 y++;
03834 }
03835 if (s > 0) {
03836 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03837 } else {
03838 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03839 }
03840 }
03841
03842 AST_LIST_UNLOCK(&dpcache);
03843
03844 return CLI_SUCCESS;
03845 }
03846
03847 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03848
03849 static void unwrap_timestamp(struct iax_frame *fr)
03850 {
03851
03852
03853 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03854 const int lower_mask = (1 << ts_shift) - 1;
03855 const int upper_mask = ~lower_mask;
03856 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03857
03858 if ( (fr->ts & upper_mask) == last_upper ) {
03859 const int x = fr->ts - iaxs[fr->callno]->last;
03860 const int threshold = (ts_shift == 15) ? 25000 : 50000;
03861
03862 if (x < -threshold) {
03863
03864
03865
03866
03867 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
03868 if (iaxdebug)
03869 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
03870 } else if (x > threshold) {
03871
03872
03873
03874
03875 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03876 if (iaxdebug)
03877 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
03878 }
03879 }
03880 }
03881
03882 static int get_from_jb(const void *p);
03883
03884 static void update_jbsched(struct chan_iax2_pvt *pvt)
03885 {
03886 int when;
03887
03888 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03889
03890 when = jb_next(pvt->jb) - when;
03891
03892 if (when <= 0) {
03893
03894 when = 1;
03895 }
03896
03897 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
03898 CALLNO_TO_PTR(pvt->callno));
03899 }
03900
03901 static void __get_from_jb(const void *p)
03902 {
03903 int callno = PTR_TO_CALLNO(p);
03904 struct chan_iax2_pvt *pvt = NULL;
03905 struct iax_frame *fr;
03906 jb_frame frame;
03907 int ret;
03908 long ms;
03909 long next;
03910 struct timeval now = ast_tvnow();
03911
03912
03913 ast_mutex_lock(&iaxsl[callno]);
03914 pvt = iaxs[callno];
03915 if (!pvt) {
03916
03917 ast_mutex_unlock(&iaxsl[callno]);
03918 return;
03919 }
03920
03921 pvt->jbid = -1;
03922
03923
03924
03925
03926 now.tv_usec += 1000;
03927
03928 ms = ast_tvdiff_ms(now, pvt->rxcore);
03929
03930 if(ms >= (next = jb_next(pvt->jb))) {
03931 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
03932 switch(ret) {
03933 case JB_OK:
03934 fr = frame.data;
03935 __do_deliver(fr);
03936
03937 pvt = iaxs[callno];
03938 break;
03939 case JB_INTERP:
03940 {
03941 struct ast_frame af = { 0, };
03942
03943
03944 af.frametype = AST_FRAME_VOICE;
03945 af.subclass = pvt->voiceformat;
03946 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03947 af.src = "IAX2 JB interpolation";
03948 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03949 af.offset = AST_FRIENDLY_OFFSET;
03950
03951
03952
03953 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03954 iax2_queue_frame(callno, &af);
03955
03956 pvt = iaxs[callno];
03957 }
03958 }
03959 break;
03960 case JB_DROP:
03961 iax2_frame_free(frame.data);
03962 break;
03963 case JB_NOFRAME:
03964 case JB_EMPTY:
03965
03966 break;
03967 default:
03968
03969 break;
03970 }
03971 }
03972 if (pvt)
03973 update_jbsched(pvt);
03974 ast_mutex_unlock(&iaxsl[callno]);
03975 }
03976
03977 static int get_from_jb(const void *data)
03978 {
03979 #ifdef SCHED_MULTITHREADED
03980 if (schedule_action(__get_from_jb, data))
03981 #endif
03982 __get_from_jb(data);
03983 return 0;
03984 }
03985
03986
03987
03988
03989
03990
03991
03992 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03993 {
03994 int type, len;
03995 int ret;
03996 int needfree = 0;
03997 struct ast_channel *owner = NULL;
03998 struct ast_channel *bridge = NULL;
03999
04000
04001 unwrap_timestamp(fr);
04002
04003
04004 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04005 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04006 else {
04007 #if 0
04008 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04009 #endif
04010 fr->af.delivery = ast_tv(0,0);
04011 }
04012
04013 type = JB_TYPE_CONTROL;
04014 len = 0;
04015
04016 if(fr->af.frametype == AST_FRAME_VOICE) {
04017 type = JB_TYPE_VOICE;
04018 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
04019 } else if(fr->af.frametype == AST_FRAME_CNG) {
04020 type = JB_TYPE_SILENCE;
04021 }
04022
04023 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04024 if (tsout)
04025 *tsout = fr->ts;
04026 __do_deliver(fr);
04027 return -1;
04028 }
04029
04030 iax2_lock_owner(fr->callno);
04031 if (!iaxs[fr->callno]) {
04032
04033 iax2_frame_free(fr);
04034 return -1;
04035 }
04036 if ((owner = iaxs[fr->callno]->owner))
04037 bridge = ast_bridged_channel(owner);
04038
04039
04040
04041 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04042 jb_frame frame;
04043
04044 ast_channel_unlock(owner);
04045
04046
04047 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04048 __do_deliver(frame.data);
04049
04050 if (!iaxs[fr->callno])
04051 return -1;
04052 }
04053
04054 jb_reset(iaxs[fr->callno]->jb);
04055
04056 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04057
04058
04059 if (tsout)
04060 *tsout = fr->ts;
04061 __do_deliver(fr);
04062 return -1;
04063 }
04064 if (owner) {
04065 ast_channel_unlock(owner);
04066 }
04067
04068
04069
04070 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04071 calc_rxstamp(iaxs[fr->callno],fr->ts));
04072 if (ret == JB_DROP) {
04073 needfree++;
04074 } else if (ret == JB_SCHED) {
04075 update_jbsched(iaxs[fr->callno]);
04076 }
04077 if (tsout)
04078 *tsout = fr->ts;
04079 if (needfree) {
04080
04081 iax2_frame_free(fr);
04082 return -1;
04083 }
04084 return 0;
04085 }
04086
04087 static int iax2_transmit(struct iax_frame *fr)
04088 {
04089
04090
04091
04092 fr->sentyet = 0;
04093 AST_LIST_LOCK(&frame_queue);
04094 AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
04095 AST_LIST_UNLOCK(&frame_queue);
04096
04097 if (netthreadid != AST_PTHREADT_NULL)
04098 pthread_kill(netthreadid, SIGURG);
04099 ast_sched_thread_poke(sched);
04100 return 0;
04101 }
04102
04103
04104
04105 static int iax2_digit_begin(struct ast_channel *c, char digit)
04106 {
04107 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04108 }
04109
04110 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04111 {
04112 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04113 }
04114
04115 static int iax2_sendtext(struct ast_channel *c, const char *text)
04116 {
04117
04118 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04119 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04120 }
04121
04122 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04123 {
04124 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1);
04125 }
04126
04127 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04128 {
04129 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04130 }
04131
04132 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04133 {
04134 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04135 ast_mutex_lock(&iaxsl[callno]);
04136 if (iaxs[callno])
04137 iaxs[callno]->owner = newchan;
04138 else
04139 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04140 ast_mutex_unlock(&iaxsl[callno]);
04141 return 0;
04142 }
04143
04144
04145
04146
04147
04148 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04149 {
04150 struct ast_variable *var = NULL;
04151 struct ast_variable *tmp;
04152 struct iax2_peer *peer=NULL;
04153 time_t regseconds = 0, nowtime;
04154 int dynamic=0;
04155
04156 if (peername) {
04157 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04158 if (!var && sin)
04159 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04160 } else if (sin) {
04161 char porta[25];
04162 sprintf(porta, "%d", ntohs(sin->sin_port));
04163 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04164 if (var) {
04165
04166 for (tmp = var; tmp; tmp = tmp->next) {
04167 if (!strcasecmp(tmp->name, "name"))
04168 peername = tmp->value;
04169 }
04170 }
04171 }
04172 if (!var && peername) {
04173 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04174
04175
04176
04177
04178
04179
04180 if (var && sin) {
04181 for (tmp = var; tmp; tmp = tmp->next) {
04182 if (!strcasecmp(tmp->name, "host")) {
04183 struct ast_hostent ahp;
04184 struct hostent *hp;
04185 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04186
04187 ast_variables_destroy(var);
04188 var = NULL;
04189 }
04190 break;
04191 }
04192 }
04193 }
04194 }
04195 if (!var)
04196 return NULL;
04197
04198 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04199
04200 if (!peer) {
04201 ast_variables_destroy(var);
04202 return NULL;
04203 }
04204
04205 for (tmp = var; tmp; tmp = tmp->next) {
04206
04207 if (!strcasecmp(tmp->name, "type")) {
04208 if (strcasecmp(tmp->value, "friend") &&
04209 strcasecmp(tmp->value, "peer")) {
04210
04211 peer = peer_unref(peer);
04212 break;
04213 }
04214 } else if (!strcasecmp(tmp->name, "regseconds")) {
04215 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04216 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04217 inet_aton(tmp->value, &(peer->addr.sin_addr));
04218 } else if (!strcasecmp(tmp->name, "port")) {
04219 peer->addr.sin_port = htons(atoi(tmp->value));
04220 } else if (!strcasecmp(tmp->name, "host")) {
04221 if (!strcasecmp(tmp->value, "dynamic"))
04222 dynamic = 1;
04223 }
04224 }
04225
04226 ast_variables_destroy(var);
04227
04228 if (!peer)
04229 return NULL;
04230
04231 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04232 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04233 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
04234 if (peer->expire > -1) {
04235 if (!ast_sched_thread_del(sched, peer->expire)) {
04236 peer->expire = -1;
04237 peer_unref(peer);
04238 }
04239 }
04240 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04241 if (peer->expire == -1)
04242 peer_unref(peer);
04243 }
04244 ao2_link(peers, peer);
04245 if (ast_test_flag(peer, IAX_DYNAMIC))
04246 reg_source_db(peer);
04247 } else {
04248 ast_set_flag(peer, IAX_TEMPONLY);
04249 }
04250
04251 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04252 time(&nowtime);
04253 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04254 memset(&peer->addr, 0, sizeof(peer->addr));
04255 realtime_update_peer(peer->name, &peer->addr, 0);
04256 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04257 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04258 }
04259 else {
04260 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04261 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04262 }
04263 }
04264
04265 return peer;
04266 }
04267
04268 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04269 {
04270 struct ast_variable *var;
04271 struct ast_variable *tmp;
04272 struct iax2_user *user=NULL;
04273
04274 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04275 if (!var)
04276 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04277 if (!var && sin) {
04278 char porta[6];
04279 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04280 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04281 if (!var)
04282 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04283 }
04284 if (!var) {
04285 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04286
04287
04288
04289
04290
04291
04292 if (var) {
04293 for (tmp = var; tmp; tmp = tmp->next) {
04294 if (!strcasecmp(tmp->name, "host")) {
04295 struct ast_hostent ahp;
04296 struct hostent *hp;
04297 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04298
04299 ast_variables_destroy(var);
04300 var = NULL;
04301 }
04302 break;
04303 }
04304 }
04305 }
04306 }
04307 if (!var)
04308 return NULL;
04309
04310 tmp = var;
04311 while(tmp) {
04312
04313 if (!strcasecmp(tmp->name, "type")) {
04314 if (strcasecmp(tmp->value, "friend") &&
04315 strcasecmp(tmp->value, "user")) {
04316 return NULL;
04317 }
04318 }
04319 tmp = tmp->next;
04320 }
04321
04322 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
04323
04324 ast_variables_destroy(var);
04325
04326 if (!user)
04327 return NULL;
04328
04329 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04330 ast_set_flag(user, IAX_RTCACHEFRIENDS);
04331 ao2_link(users, user);
04332 } else {
04333 ast_set_flag(user, IAX_TEMPONLY);
04334 }
04335
04336 return user;
04337 }
04338
04339 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
04340 {
04341 char port[10];
04342 char regseconds[20];
04343
04344 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04345 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
04346 ast_update_realtime("iaxpeers", "name", peername,
04347 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
04348 "regseconds", regseconds, SENTINEL);
04349 }
04350
04351 struct create_addr_info {
04352 int capability;
04353 unsigned int flags;
04354 int maxtime;
04355 int encmethods;
04356 int found;
04357 int sockfd;
04358 int adsi;
04359 char username[80];
04360 char secret[80];
04361 char outkey[80];
04362 char timezone[80];
04363 char prefs[32];
04364 char context[AST_MAX_CONTEXT];
04365 char peercontext[AST_MAX_CONTEXT];
04366 char mohinterpret[MAX_MUSICCLASS];
04367 char mohsuggest[MAX_MUSICCLASS];
04368 };
04369
04370 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04371 {
04372 struct iax2_peer *peer;
04373 int res = -1;
04374 struct ast_codec_pref ourprefs;
04375
04376 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
04377 cai->sockfd = defaultsockfd;
04378 cai->maxtime = 0;
04379 sin->sin_family = AF_INET;
04380
04381 if (!(peer = find_peer(peername, 1))) {
04382 cai->found = 0;
04383 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
04384 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04385 return -1;
04386 }
04387 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04388
04389
04390 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04391 if (c)
04392 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04393 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04394 return 0;
04395 }
04396
04397 cai->found = 1;
04398
04399
04400 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
04401 goto return_unref;
04402
04403
04404 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04405 goto return_unref;
04406
04407 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT);
04408 cai->maxtime = peer->maxms;
04409 cai->capability = peer->capability;
04410 cai->encmethods = peer->encmethods;
04411 cai->sockfd = peer->sockfd;
04412 cai->adsi = peer->adsi;
04413 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04414
04415 if (c) {
04416 ast_debug(1, "prepending %x to prefs\n", c->nativeformats);
04417 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04418 }
04419 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04420 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04421 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04422 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04423 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04424 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04425 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04426 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04427 if (ast_strlen_zero(peer->dbsecret)) {
04428 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04429 } else {
04430 char *family;
04431 char *key = NULL;
04432
04433 family = ast_strdupa(peer->dbsecret);
04434 key = strchr(family, '/');
04435 if (key)
04436 *key++ = '\0';
04437 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04438 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04439 goto return_unref;
04440 }
04441 }
04442
04443 if (peer->addr.sin_addr.s_addr) {
04444 sin->sin_addr = peer->addr.sin_addr;
04445 sin->sin_port = peer->addr.sin_port;
04446 } else {
04447 sin->sin_addr = peer->defaddr.sin_addr;
04448 sin->sin_port = peer->defaddr.sin_port;
04449 }
04450
04451 res = 0;
04452
04453 return_unref:
04454 peer_unref(peer);
04455
04456 return res;
04457 }
04458
04459 static void __auto_congest(const void *nothing)
04460 {
04461 int callno = PTR_TO_CALLNO(nothing);
04462 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
04463 ast_mutex_lock(&iaxsl[callno]);
04464 if (iaxs[callno]) {
04465 iaxs[callno]->initid = -1;
04466 iax2_queue_frame(callno, &f);
04467 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04468 }
04469 ast_mutex_unlock(&iaxsl[callno]);
04470 }
04471
04472 static int auto_congest(const void *data)
04473 {
04474 #ifdef SCHED_MULTITHREADED
04475 if (schedule_action(__auto_congest, data))
04476 #endif
04477 __auto_congest(data);
04478 return 0;
04479 }
04480
04481 static unsigned int iax2_datetime(const char *tz)
04482 {
04483 struct timeval t = ast_tvnow();
04484 struct ast_tm tm;
04485 unsigned int tmp;
04486 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04487 tmp = (tm.tm_sec >> 1) & 0x1f;
04488 tmp |= (tm.tm_min & 0x3f) << 5;
04489 tmp |= (tm.tm_hour & 0x1f) << 11;
04490 tmp |= (tm.tm_mday & 0x1f) << 16;
04491 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04492 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04493 return tmp;
04494 }
04495
04496 struct parsed_dial_string {
04497 char *username;
04498 char *password;
04499 char *key;
04500 char *peer;
04501 char *port;
04502 char *exten;
04503 char *context;
04504 char *options;
04505 };
04506
04507 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04508 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04509 int sockfd, struct iax_ie_data *ied)
04510 {
04511 struct {
04512 struct ast_iax2_full_hdr f;
04513 struct iax_ie_data ied;
04514 } data;
04515 size_t size = sizeof(struct ast_iax2_full_hdr);
04516
04517 if (ied) {
04518 size += ied->pos;
04519 memcpy(&data.ied, ied->buf, ied->pos);
04520 }
04521
04522 data.f.scallno = htons(0x8000 | callno);
04523 data.f.dcallno = htons(dcallno);
04524 data.f.ts = htonl(ts);
04525 data.f.iseqno = seqno;
04526 data.f.oseqno = 0;
04527 data.f.type = AST_FRAME_IAX;
04528 data.f.csub = compress_subclass(command);
04529
04530 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04531 }
04532
04533 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04534 {
04535
04536 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04537 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04538 ied->buf[ied->pos++] = 0;
04539 pvt->calltoken_ie_len = 2;
04540 }
04541 }
04542
04543 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04544 {
04545 struct chan_iax2_pvt *pvt = iaxs[callno];
04546 int frametype = f->af.frametype;
04547 int subclass = f->af.subclass;
04548 struct {
04549 struct ast_iax2_full_hdr fh;
04550 struct iax_ie_data ied;
04551 } data = {
04552 .ied.buf = { 0 },
04553 .ied.pos = 0,
04554 };
04555
04556 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04557
04558 if (!pvt) {
04559 return;
04560 }
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04574 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04575 (f->datalen > sizeof(data))) {
04576
04577 return;
04578 }
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594 memcpy(&data, f->data, f->datalen);
04595 data.ied.pos = ie_data_pos;
04596
04597
04598
04599 data.ied.pos -= pvt->calltoken_ie_len;
04600 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04601
04602
04603 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04604
04605
04606 AST_LIST_LOCK(&frame_queue);
04607 AST_LIST_REMOVE(&frame_queue, f, list);
04608 AST_LIST_UNLOCK(&frame_queue);
04609
04610
04611 iax2_frame_free(f);
04612
04613
04614 pvt->oseqno = 0;
04615 pvt->rseqno = 0;
04616 pvt->iseqno = 0;
04617 pvt->aseqno = 0;
04618 if (pvt->peercallno) {
04619 remove_by_peercallno(pvt);
04620 pvt->peercallno = 0;
04621 }
04622
04623
04624 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04625 }
04626
04627 static void requirecalltoken_mark_auto(const char *name, int subclass)
04628 {
04629 struct iax2_user *user = NULL;
04630 struct iax2_peer *peer = NULL;
04631
04632 if (ast_strlen_zero(name)) {
04633 return;
04634 }
04635
04636 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04637 user->calltoken_required = CALLTOKEN_YES;
04638 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04639 peer->calltoken_required = CALLTOKEN_YES;
04640 }
04641
04642 if (peer) {
04643 peer_unref(peer);
04644 }
04645 if (user) {
04646 user_unref(user);
04647 }
04648 }
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664
04665
04666
04667 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04668 struct sockaddr_in *sin, int fd)
04669 {
04670 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04671 #define CALLTOKEN_IE_FORMAT "%u?%s"
04672 struct ast_str *buf = ast_str_alloca(256);
04673 time_t t = time(NULL);
04674 char hash[41];
04675 int subclass = uncompress_subclass(fh->csub);
04676
04677
04678 if (ies->calltoken && !ies->calltokendata) {
04679 struct iax_ie_data ied = {
04680 .buf = { 0 },
04681 .pos = 0,
04682 };
04683
04684
04685 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04686 ast_sha1_hash(hash, ast_str_buffer(buf));
04687
04688 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04689 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04690 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04691
04692 return 1;
04693
04694
04695 } else if (ies->calltoken && ies->calltokendata) {
04696 char *rec_hash = NULL;
04697 char *rec_ts = NULL;
04698 unsigned int rec_time;
04699
04700
04701 rec_hash = strchr((char *) ies->calltokendata, '?');
04702 if (rec_hash) {
04703 *rec_hash++ = '\0';
04704 rec_ts = (char *) ies->calltokendata;
04705 }
04706
04707
04708 if (!rec_hash || !rec_ts) {
04709 goto reject;
04710 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04711 goto reject;
04712 }
04713
04714
04715 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04716 ast_sha1_hash(hash, ast_str_buffer(buf));
04717
04718
04719 if (strcmp(hash, rec_hash)) {
04720 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04721 goto reject;
04722 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04723 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04724 goto reject;
04725 }
04726
04727
04728
04729 requirecalltoken_mark_auto(ies->username, subclass);
04730 return 0;
04731
04732
04733 } else {
04734 if (calltoken_required(sin, ies->username, subclass)) {
04735 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"));
04736 goto reject;
04737 }
04738 return 0;
04739 }
04740
04741 reject:
04742
04743 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04744 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04745 } else {
04746 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04747 }
04748
04749 return 1;
04750 }
04751
04752
04753
04754
04755
04756
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04771 {
04772 if (ast_strlen_zero(data))
04773 return;
04774
04775 pds->peer = strsep(&data, "/");
04776 pds->exten = strsep(&data, "/");
04777 pds->options = data;
04778
04779 if (pds->exten) {
04780 data = pds->exten;
04781 pds->exten = strsep(&data, "@");
04782 pds->context = data;
04783 }
04784
04785 if (strchr(pds->peer, '@')) {
04786 data = pds->peer;
04787 pds->username = strsep(&data, "@");
04788 pds->peer = data;
04789 }
04790
04791 if (pds->username) {
04792 data = pds->username;
04793 pds->username = strsep(&data, ":");
04794 pds->password = data;
04795 }
04796
04797 data = pds->peer;
04798 pds->peer = strsep(&data, ":");
04799 pds->port = data;
04800
04801
04802
04803
04804 if (pds->password && (pds->password[0] == '[')) {
04805 pds->key = ast_strip_quoted(pds->password, "[", "]");
04806 pds->password = NULL;
04807 }
04808 }
04809
04810 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04811 {
04812 struct sockaddr_in sin;
04813 char *l=NULL, *n=NULL, *tmpstr;
04814 struct iax_ie_data ied;
04815 char *defaultrdest = "s";
04816 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04817 struct parsed_dial_string pds;
04818 struct create_addr_info cai;
04819 struct ast_var_t *var;
04820 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04821 const char* osp_token_ptr;
04822 unsigned int osp_token_length;
04823 unsigned char osp_block_index;
04824 unsigned int osp_block_length;
04825 unsigned char osp_buffer[256];
04826
04827 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
04828 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
04829 return -1;
04830 }
04831
04832 memset(&cai, 0, sizeof(cai));
04833 cai.encmethods = iax2_encryption;
04834
04835 memset(&pds, 0, sizeof(pds));
04836 tmpstr = ast_strdupa(dest);
04837 parse_dial_string(tmpstr, &pds);
04838
04839 if (ast_strlen_zero(pds.peer)) {
04840 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
04841 return -1;
04842 }
04843 if (!pds.exten) {
04844 pds.exten = defaultrdest;
04845 }
04846 if (create_addr(pds.peer, c, &sin, &cai)) {
04847 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
04848 return -1;
04849 }
04850 if (ast_strlen_zero(cai.secret) && ast_test_flag(iaxs[callno], IAX_FORCE_ENCRYPT)) {
04851 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
04852 return -1;
04853 }
04854 if (!pds.username && !ast_strlen_zero(cai.username))
04855 pds.username = cai.username;
04856 if (!pds.password && !ast_strlen_zero(cai.secret))
04857 pds.password = cai.secret;
04858 if (!pds.key && !ast_strlen_zero(cai.outkey))
04859 pds.key = cai.outkey;
04860 if (!pds.context && !ast_strlen_zero(cai.peercontext))
04861 pds.context = cai.peercontext;
04862
04863
04864 ast_copy_string(c->context, cai.context, sizeof(c->context));
04865
04866 if (pds.port)
04867 sin.sin_port = htons(atoi(pds.port));
04868
04869 l = c->cid.cid_num;
04870 n = c->cid.cid_name;
04871
04872
04873 memset(&ied, 0, sizeof(ied));
04874
04875
04876 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
04877 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
04878 if (pds.options && strchr(pds.options, 'a')) {
04879
04880 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
04881 }
04882
04883 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
04884
04885 if (l) {
04886 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
04887 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04888 } else {
04889 if (n)
04890 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04891 else
04892 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
04893 }
04894
04895 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
04896 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
04897
04898 if (n)
04899 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
04900 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
04901 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
04902
04903 if (!ast_strlen_zero(c->language))
04904 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
04905 if (!ast_strlen_zero(c->cid.cid_dnid))
04906 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
04907 if (!ast_strlen_zero(c->cid.cid_rdnis))
04908 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
04909
04910 if (pds.context)
04911 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
04912
04913 if (pds.username)
04914 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
04915
04916 if (cai.encmethods)
04917 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
04918
04919 ast_mutex_lock(&iaxsl[callno]);
04920
04921 if (!ast_strlen_zero(c->context))
04922 ast_string_field_set(iaxs[callno], context, c->context);
04923
04924 if (pds.username)
04925 ast_string_field_set(iaxs[callno], username, pds.username);
04926
04927 iaxs[callno]->encmethods = cai.encmethods;
04928
04929 iaxs[callno]->adsi = cai.adsi;
04930
04931 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
04932 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
04933
04934 if (pds.key)
04935 ast_string_field_set(iaxs[callno], outkey, pds.key);
04936 if (pds.password)
04937 ast_string_field_set(iaxs[callno], secret, pds.password);
04938
04939 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
04940 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
04941 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
04942 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
04943
04944 if (iaxs[callno]->maxtime) {
04945
04946 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
04947 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
04948 } else if (autokill) {
04949 iaxs[callno]->pingtime = autokill / 2;
04950 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
04951 }
04952
04953
04954 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
04955 if (!ast_strlen_zero(osp_token_ptr)) {
04956 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
04957 osp_block_index = 0;
04958 while (osp_token_length > 0) {
04959 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
04960 osp_buffer[0] = osp_block_index;
04961 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
04962 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
04963 osp_block_index++;
04964 osp_token_ptr += osp_block_length;
04965 osp_token_length -= osp_block_length;
04966 }
04967 } else
04968 ast_log(LOG_WARNING, "OSP token is too long\n");
04969 } else if (iaxdebug)
04970 ast_debug(1, "OSP token is undefined\n");
04971
04972
04973 iaxs[callno]->sockfd = cai.sockfd;
04974
04975
04976 if (variablestore) {
04977 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
04978 ast_debug(1, "Found an IAX variable store on this channel\n");
04979 AST_LIST_LOCK(variablelist);
04980 AST_LIST_TRAVERSE(variablelist, var, entries) {
04981 char tmp[256];
04982 int i;
04983 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
04984
04985 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
04986 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
04987 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
04988 }
04989 }
04990 AST_LIST_UNLOCK(variablelist);
04991 }
04992
04993
04994 add_empty_calltoken_ie(iaxs[callno], &ied);
04995 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
04996
04997 ast_mutex_unlock(&iaxsl[callno]);
04998 ast_setstate(c, AST_STATE_RINGING);
04999
05000 return 0;
05001 }
05002
05003 static int iax2_hangup(struct ast_channel *c)
05004 {
05005 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05006 struct iax_ie_data ied;
05007 int alreadygone;
05008 memset(&ied, 0, sizeof(ied));
05009 ast_mutex_lock(&iaxsl[callno]);
05010 if (callno && iaxs[callno]) {
05011 ast_debug(1, "We're hanging up %s now...\n", c->name);
05012 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
05013
05014 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05015 if (!iaxs[callno]->error && !alreadygone) {
05016 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05017 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05018 }
05019 if (!iaxs[callno]) {
05020 ast_mutex_unlock(&iaxsl[callno]);
05021 return 0;
05022 }
05023 }
05024
05025 iax2_predestroy(callno);
05026
05027 if (iaxs[callno] && alreadygone) {
05028 ast_debug(1, "Really destroying %s now...\n", c->name);
05029 iax2_destroy(callno);
05030 } else if (iaxs[callno]) {
05031 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05032 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05033 iax2_destroy(callno);
05034 }
05035 }
05036 } else if (c->tech_pvt) {
05037
05038
05039
05040
05041 c->tech_pvt = NULL;
05042 }
05043 ast_mutex_unlock(&iaxsl[callno]);
05044 ast_verb(3, "Hungup '%s'\n", c->name);
05045 return 0;
05046 }
05047
05048
05049
05050
05051 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05052 {
05053 unsigned short callno = pvt->callno;
05054
05055 if (!pvt->peercallno) {
05056
05057 int count = 10;
05058 while (count-- && pvt && !pvt->peercallno) {
05059 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05060 pvt = iaxs[callno];
05061 }
05062 if (!pvt->peercallno) {
05063 return -1;
05064 }
05065 }
05066
05067 return 0;
05068 }
05069
05070 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05071 {
05072 struct ast_option_header *h;
05073 int res;
05074
05075 switch (option) {
05076 case AST_OPTION_TXGAIN:
05077 case AST_OPTION_RXGAIN:
05078
05079 errno = ENOSYS;
05080 return -1;
05081 case AST_OPTION_OPRMODE:
05082 errno = EINVAL;
05083 return -1;
05084
05085
05086
05087
05088 case AST_OPTION_TONE_VERIFY:
05089 case AST_OPTION_TDD:
05090 case AST_OPTION_RELAXDTMF:
05091 case AST_OPTION_AUDIO_MODE:
05092 {
05093 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05094 struct chan_iax2_pvt *pvt;
05095
05096 ast_mutex_lock(&iaxsl[callno]);
05097 pvt = iaxs[callno];
05098
05099 if (wait_for_peercallno(pvt)) {
05100 ast_mutex_unlock(&iaxsl[callno]);
05101 return -1;
05102 }
05103
05104 ast_mutex_unlock(&iaxsl[callno]);
05105
05106 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05107 return -1;
05108 }
05109
05110 h->flag = AST_OPTION_FLAG_REQUEST;
05111 h->option = htons(option);
05112 memcpy(h->data, data, datalen);
05113 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05114 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05115 datalen + sizeof(*h), -1);
05116 ast_free(h);
05117 return res;
05118 }
05119 default:
05120 return -1;
05121 }
05122
05123
05124 return -1;
05125 }
05126
05127 static struct ast_frame *iax2_read(struct ast_channel *c)
05128 {
05129 ast_log(LOG_NOTICE, "I should never be called!\n");
05130 return &ast_null_frame;
05131 }
05132
05133 static int iax2_key_rotate(const void *vpvt)
05134 {
05135 int res = 0;
05136 struct chan_iax2_pvt *pvt = (void *) vpvt;
05137 struct MD5Context md5;
05138 char key[17] = "";
05139 struct iax_ie_data ied = {
05140 .pos = 0,
05141 };
05142
05143 ast_mutex_lock(&iaxsl[pvt->callno]);
05144 pvt->keyrotateid =
05145 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05146
05147 snprintf(key, sizeof(key), "%lX", ast_random());
05148
05149 MD5Init(&md5);
05150 MD5Update(&md5, (unsigned char *) key, strlen(key));
05151 MD5Final((unsigned char *) key, &md5);
05152
05153 IAX_DEBUGDIGEST("Sending", key);
05154
05155 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05156
05157 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05158
05159 build_ecx_key((unsigned char *) key, pvt);
05160
05161 ast_mutex_unlock(&iaxsl[pvt->callno]);
05162
05163 return res;
05164 }
05165
05166 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05167 {
05168 int res;
05169 struct iax_ie_data ied0;
05170 struct iax_ie_data ied1;
05171 unsigned int transferid = (unsigned int)ast_random();
05172
05173 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05174 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05175 ast_set_flag(iaxs[callno0], IAX_NOTRANSFER);
05176 ast_set_flag(iaxs[callno1], IAX_NOTRANSFER);
05177 return 0;
05178 }
05179
05180 memset(&ied0, 0, sizeof(ied0));
05181 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05182 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05183 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05184
05185 memset(&ied1, 0, sizeof(ied1));
05186 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05187 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05188 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05189
05190 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05191 if (res)
05192 return -1;
05193 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05194 if (res)
05195 return -1;
05196 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05197 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05198 return 0;
05199 }
05200
05201 static void lock_both(unsigned short callno0, unsigned short callno1)
05202 {
05203 ast_mutex_lock(&iaxsl[callno0]);
05204 while (ast_mutex_trylock(&iaxsl[callno1])) {
05205 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05206 }
05207 }
05208
05209 static void unlock_both(unsigned short callno0, unsigned short callno1)
05210 {
05211 ast_mutex_unlock(&iaxsl[callno1]);
05212 ast_mutex_unlock(&iaxsl[callno0]);
05213 }
05214
05215 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)
05216 {
05217 struct ast_channel *cs[3];
05218 struct ast_channel *who, *other;
05219 int to = -1;
05220 int res = -1;
05221 int transferstarted=0;
05222 struct ast_frame *f;
05223 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05224 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05225 struct timeval waittimer = {0, 0};
05226
05227
05228 if (timeoutms > 0) {
05229 return AST_BRIDGE_FAILED;
05230 }
05231
05232 timeoutms = -1;
05233
05234 lock_both(callno0, callno1);
05235 if (!iaxs[callno0] || !iaxs[callno1]) {
05236 unlock_both(callno0, callno1);
05237 return AST_BRIDGE_FAILED;
05238 }
05239
05240 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05241 iaxs[callno0]->bridgecallno = callno1;
05242 iaxs[callno1]->bridgecallno = callno0;
05243 }
05244 unlock_both(callno0, callno1);
05245
05246
05247 cs[0] = c0;
05248 cs[1] = c1;
05249 for (;;) {
05250
05251 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05252 ast_verb(3, "Can't masquerade, we're different...\n");
05253
05254 if (c0->tech == &iax2_tech) {
05255 ast_mutex_lock(&iaxsl[callno0]);
05256 iaxs[callno0]->bridgecallno = 0;
05257 ast_mutex_unlock(&iaxsl[callno0]);
05258 }
05259 if (c1->tech == &iax2_tech) {
05260 ast_mutex_lock(&iaxsl[callno1]);
05261 iaxs[callno1]->bridgecallno = 0;
05262 ast_mutex_unlock(&iaxsl[callno1]);
05263 }
05264 return AST_BRIDGE_FAILED_NOWARN;
05265 }
05266 if (c0->nativeformats != c1->nativeformats) {
05267 char buf0[255];
05268 char buf1[255];
05269 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
05270 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
05271 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
05272
05273 lock_both(callno0, callno1);
05274 if (iaxs[callno0])
05275 iaxs[callno0]->bridgecallno = 0;
05276 if (iaxs[callno1])
05277 iaxs[callno1]->bridgecallno = 0;
05278 unlock_both(callno0, callno1);
05279 return AST_BRIDGE_FAILED_NOWARN;
05280 }
05281
05282 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
05283
05284 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05285 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
05286 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05287 transferstarted = 1;
05288 }
05289 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05290
05291 struct timeval now = ast_tvnow();
05292 if (ast_tvzero(waittimer)) {
05293 waittimer = now;
05294 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05295 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05296 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05297 *fo = NULL;
05298 *rc = c0;
05299 res = AST_BRIDGE_COMPLETE;
05300 break;
05301 }
05302 }
05303 to = 1000;
05304 who = ast_waitfor_n(cs, 2, &to);
05305 if (timeoutms > -1) {
05306 timeoutms -= (1000 - to);
05307 if (timeoutms < 0)
05308 timeoutms = 0;
05309 }
05310 if (!who) {
05311 if (!timeoutms) {
05312 res = AST_BRIDGE_RETRY;
05313 break;
05314 }
05315 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05316 res = AST_BRIDGE_FAILED;
05317 break;
05318 }
05319 continue;
05320 }
05321 f = ast_read(who);
05322 if (!f) {
05323 *fo = NULL;
05324 *rc = who;
05325 res = AST_BRIDGE_COMPLETE;
05326 break;
05327 }
05328 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
05329 *fo = f;
05330 *rc = who;
05331 res = AST_BRIDGE_COMPLETE;
05332 break;
05333 }
05334 other = (who == c0) ? c1 : c0;
05335 if ((f->frametype == AST_FRAME_VOICE) ||
05336 (f->frametype == AST_FRAME_TEXT) ||
05337 (f->frametype == AST_FRAME_VIDEO) ||
05338 (f->frametype == AST_FRAME_IMAGE) ||
05339 (f->frametype == AST_FRAME_DTMF) ||
05340 (f->frametype == AST_FRAME_CONTROL)) {
05341
05342
05343
05344 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05345 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05346 *rc = who;
05347 *fo = f;
05348 res = AST_BRIDGE_COMPLETE;
05349
05350 break;
05351 }
05352
05353 ast_write(other, f);
05354 }
05355 ast_frfree(f);
05356
05357 cs[2] = cs[0];
05358 cs[0] = cs[1];
05359 cs[1] = cs[2];
05360 }
05361 lock_both(callno0, callno1);
05362 if(iaxs[callno0])
05363 iaxs[callno0]->bridgecallno = 0;
05364 if(iaxs[callno1])
05365 iaxs[callno1]->bridgecallno = 0;
05366 unlock_both(callno0, callno1);
05367 return res;
05368 }
05369
05370 static int iax2_answer(struct ast_channel *c)
05371 {
05372 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05373 ast_debug(1, "Answering IAX2 call\n");
05374 ast_mutex_lock(&iaxsl[callno]);
05375 if (iaxs[callno])
05376 iax2_ami_channelupdate(iaxs[callno]);
05377 ast_mutex_unlock(&iaxsl[callno]);
05378 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05379 }
05380
05381 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05382 {
05383 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05384 struct chan_iax2_pvt *pvt;
05385 int res = 0;
05386
05387 if (iaxdebug)
05388 ast_debug(1, "Indicating condition %d\n", condition);
05389
05390 ast_mutex_lock(&iaxsl[callno]);
05391 pvt = iaxs[callno];
05392
05393 if (wait_for_peercallno(pvt)) {
05394 res = -1;
05395 goto done;
05396 }
05397
05398 switch (condition) {
05399 case AST_CONTROL_HOLD:
05400 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05401 ast_moh_start(c, data, pvt->mohinterpret);
05402 goto done;
05403 }
05404 break;
05405 case AST_CONTROL_UNHOLD:
05406 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05407 ast_moh_stop(c);
05408 goto done;
05409 }
05410 }
05411
05412 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05413
05414 done:
05415 ast_mutex_unlock(&iaxsl[callno]);
05416
05417 return res;
05418 }
05419
05420 static int iax2_transfer(struct ast_channel *c, const char *dest)
05421 {
05422 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05423 struct iax_ie_data ied = { "", };
05424 char tmp[256], *context;
05425 ast_copy_string(tmp, dest, sizeof(tmp));
05426 context = strchr(tmp, '@');
05427 if (context) {
05428 *context = '\0';
05429 context++;
05430 }
05431 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05432 if (context)
05433 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05434 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05435 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05436 }
05437
05438 static int iax2_getpeertrunk(struct sockaddr_in sin)
05439 {
05440 struct iax2_peer *peer;
05441 int res = 0;
05442 struct ao2_iterator i;
05443
05444 i = ao2_iterator_init(peers, 0);
05445 while ((peer = ao2_iterator_next(&i))) {
05446 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05447 (peer->addr.sin_port == sin.sin_port)) {
05448 res = ast_test_flag(peer, IAX_TRUNK);
05449 peer_unref(peer);
05450 break;
05451 }
05452 peer_unref(peer);
05453 }
05454 ao2_iterator_destroy(&i);
05455
05456 return res;
05457 }
05458
05459
05460 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
05461 {
05462 struct ast_channel *tmp;
05463 struct chan_iax2_pvt *i;
05464 struct ast_variable *v = NULL;
05465
05466 if (!(i = iaxs[callno])) {
05467 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05468 return NULL;
05469 }
05470
05471
05472 ast_mutex_unlock(&iaxsl[callno]);
05473 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);
05474 ast_mutex_lock(&iaxsl[callno]);
05475 if (i != iaxs[callno]) {
05476 if (tmp) {
05477
05478 ast_mutex_unlock(&iaxsl[callno]);
05479 ast_channel_free(tmp);
05480 ast_mutex_lock(&iaxsl[callno]);
05481 }
05482 return NULL;
05483 }
05484 iax2_ami_channelupdate(i);
05485 if (!tmp)
05486 return NULL;
05487 tmp->tech = &iax2_tech;
05488
05489 tmp->nativeformats = capability;
05490 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05491 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05492 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05493
05494 if (!ast_strlen_zero(i->parkinglot))
05495 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05496
05497
05498 if (!ast_strlen_zero(i->ani))
05499 tmp->cid.cid_ani = ast_strdup(i->ani);
05500 else
05501 tmp->cid.cid_ani = ast_strdup(i->cid_num);
05502 tmp->cid.cid_dnid = ast_strdup(i->dnid);
05503 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05504 tmp->cid.cid_pres = i->calling_pres;
05505 tmp->cid.cid_ton = i->calling_ton;
05506 tmp->cid.cid_tns = i->calling_tns;
05507 if (!ast_strlen_zero(i->language))
05508 ast_string_field_set(tmp, language, i->language);
05509 if (!ast_strlen_zero(i->accountcode))
05510 ast_string_field_set(tmp, accountcode, i->accountcode);
05511 if (i->amaflags)
05512 tmp->amaflags = i->amaflags;
05513 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05514 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05515 if (i->adsi)
05516 tmp->adsicpe = i->peeradsicpe;
05517 else
05518 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05519 i->owner = tmp;
05520 i->capability = capability;
05521
05522
05523 if (i->vars) {
05524 for (v = i->vars ; v ; v = v->next)
05525 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05526 }
05527 if (i->iaxvars) {
05528 struct ast_datastore *variablestore;
05529 struct ast_variable *var, *prev = NULL;
05530 AST_LIST_HEAD(, ast_var_t) *varlist;
05531 ast_debug(1, "Loading up the channel with IAXVARs\n");
05532 varlist = ast_calloc(1, sizeof(*varlist));
05533 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05534 if (variablestore && varlist) {
05535 variablestore->data = varlist;
05536 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05537 AST_LIST_HEAD_INIT(varlist);
05538 for (var = i->iaxvars; var; var = var->next) {
05539 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05540 if (prev)
05541 ast_free(prev);
05542 prev = var;
05543 if (!newvar) {
05544
05545 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05546 } else {
05547 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05548 }
05549 }
05550 if (prev)
05551 ast_free(prev);
05552 i->iaxvars = NULL;
05553 ast_channel_datastore_add(i->owner, variablestore);
05554 } else {
05555 if (variablestore) {
05556 ast_datastore_free(variablestore);
05557 }
05558 if (varlist) {
05559 ast_free(varlist);
05560 }
05561 }
05562 }
05563
05564 if (state != AST_STATE_DOWN) {
05565 if (ast_pbx_start(tmp)) {
05566 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05567 ast_hangup(tmp);
05568 i->owner = NULL;
05569 return NULL;
05570 }
05571 }
05572
05573 ast_module_ref(ast_module_info->self);
05574 return tmp;
05575 }
05576
05577 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05578 {
05579 unsigned long int mssincetx;
05580 long int ms, pred;
05581
05582 tpeer->trunkact = *now;
05583 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05584 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05585
05586 tpeer->txtrunktime = *now;
05587 tpeer->lastsent = 999999;
05588 }
05589
05590 tpeer->lasttxtime = *now;
05591
05592
05593 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05594
05595 pred = tpeer->lastsent + sampms;
05596 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05597 ms = pred;
05598
05599
05600 if (ms == tpeer->lastsent)
05601 ms = tpeer->lastsent + 1;
05602 tpeer->lastsent = ms;
05603 return ms;
05604 }
05605
05606 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05607 {
05608 long ms;
05609 if (ast_tvzero(iaxs[callno]->rxcore)) {
05610
05611 iaxs[callno]->rxcore = ast_tvnow();
05612
05613 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05614 }
05615
05616 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05617
05618 return ms + ts;
05619 }
05620
05621 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05622 {
05623 int ms;
05624 int voice = 0;
05625 int genuine = 0;
05626 int adjust;
05627 int rate = ast_format_rate(f->subclass) / 1000;
05628 struct timeval *delivery = NULL;
05629
05630
05631
05632
05633
05634
05635
05636
05637 if (f) {
05638 if (f->frametype == AST_FRAME_VOICE) {
05639 voice = 1;
05640 delivery = &f->delivery;
05641 } else if (f->frametype == AST_FRAME_IAX) {
05642 genuine = 1;
05643 } else if (f->frametype == AST_FRAME_CNG) {
05644 p->notsilenttx = 0;
05645 }
05646 }
05647 if (ast_tvzero(p->offset)) {
05648 p->offset = ast_tvnow();
05649
05650 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05651 }
05652
05653 if (ts)
05654 return ts;
05655
05656 if (delivery && !ast_tvzero(*delivery)) {
05657 ms = ast_tvdiff_ms(*delivery, p->offset);
05658 if (ms < 0) {
05659 ms = 0;
05660 }
05661 if (iaxdebug)
05662 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05663 } else {
05664 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05665 if (ms < 0)
05666 ms = 0;
05667 if (voice) {
05668
05669 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05670
05671
05672
05673
05674
05675
05676
05677
05678
05679
05680
05681
05682
05683
05684
05685
05686
05687
05688 adjust = (ms - p->nextpred);
05689 if (adjust < 0)
05690 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05691 else if (adjust > 0)
05692 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05693
05694 if (!p->nextpred) {
05695 p->nextpred = ms;
05696 if (p->nextpred <= p->lastsent)
05697 p->nextpred = p->lastsent + 3;
05698 }
05699 ms = p->nextpred;
05700 } else {
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05711 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05712 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05713
05714 if (f->samples >= rate)
05715 {
05716 int diff = ms % (f->samples / rate);
05717 if (diff)
05718 ms += f->samples/rate - diff;
05719 }
05720
05721 p->nextpred = ms;
05722 p->notsilenttx = 1;
05723 }
05724 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05725
05726
05727
05728
05729
05730
05731
05732
05733 if ( (unsigned int)ms < p->lastsent )
05734 ms = p->lastsent;
05735 } else {
05736
05737
05738 if (genuine) {
05739
05740 if (ms <= p->lastsent)
05741 ms = p->lastsent + 3;
05742 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05743
05744 ms = p->lastsent + 3;
05745 }
05746 }
05747 }
05748 p->lastsent = ms;
05749 if (voice)
05750 p->nextpred = p->nextpred + f->samples / rate;
05751 return ms;
05752 }
05753
05754 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05755 {
05756
05757
05758 int ms;
05759 #ifdef IAXTESTS
05760 int jit;
05761 #endif
05762
05763 if (ast_tvzero(p->rxcore)) {
05764 p->rxcore = ast_tvnow();
05765 if (iaxdebug)
05766 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05767 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05768 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05769 #if 1
05770 if (iaxdebug)
05771 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05772 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05773 #endif
05774 }
05775
05776 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05777 #ifdef IAXTESTS
05778 if (test_jit) {
05779 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05780 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05781 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05782 jit = -jit;
05783 ms += jit;
05784 }
05785 }
05786 if (test_late) {
05787 ms += test_late;
05788 test_late = 0;
05789 }
05790 #endif
05791 return ms;
05792 }
05793
05794 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
05795 {
05796 struct iax2_trunk_peer *tpeer = NULL;
05797
05798
05799 AST_LIST_LOCK(&tpeers);
05800
05801 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
05802 if (!inaddrcmp(&tpeer->addr, sin)) {
05803 ast_mutex_lock(&tpeer->lock);
05804 break;
05805 }
05806 }
05807
05808 if (!tpeer) {
05809 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
05810 ast_mutex_init(&tpeer->lock);
05811 tpeer->lastsent = 9999;
05812 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
05813 tpeer->trunkact = ast_tvnow();
05814 ast_mutex_lock(&tpeer->lock);
05815 tpeer->sockfd = fd;
05816 #ifdef SO_NO_CHECK
05817 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
05818 #endif
05819 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05820 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
05821 }
05822 }
05823
05824 AST_LIST_UNLOCK(&tpeers);
05825
05826 return tpeer;
05827 }
05828
05829 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
05830 {
05831 struct ast_frame *f;
05832 struct iax2_trunk_peer *tpeer;
05833 void *tmp, *ptr;
05834 struct timeval now;
05835 int res;
05836 struct ast_iax2_meta_trunk_entry *met;
05837 struct ast_iax2_meta_trunk_mini *mtm;
05838
05839 f = &fr->af;
05840 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
05841 if (tpeer) {
05842 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
05843
05844 if (tpeer->trunkdataalloc < trunkmaxsize) {
05845 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
05846 ast_mutex_unlock(&tpeer->lock);
05847 return -1;
05848 }
05849
05850 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
05851 tpeer->trunkdata = tmp;
05852 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);
05853 } else {
05854 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));
05855 ast_mutex_unlock(&tpeer->lock);
05856 return -1;
05857 }
05858 }
05859
05860
05861 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
05862 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
05863 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
05864 mtm->len = htons(f->datalen);
05865 mtm->mini.callno = htons(pvt->callno);
05866 mtm->mini.ts = htons(0xffff & fr->ts);
05867 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
05868 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
05869 } else {
05870 met = (struct ast_iax2_meta_trunk_entry *)ptr;
05871
05872 met->callno = htons(pvt->callno);
05873 met->len = htons(f->datalen);
05874
05875 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
05876 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
05877 }
05878
05879 memcpy(ptr, f->data.ptr, f->datalen);
05880 tpeer->trunkdatalen += f->datalen;
05881
05882 tpeer->calls++;
05883
05884
05885 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
05886 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
05887
05888
05889 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
05890 now = ast_tvnow();
05891 res = send_trunk(tpeer, &now);
05892 trunk_untimed ++;
05893 }
05894
05895 ast_mutex_unlock(&tpeer->lock);
05896 }
05897 return 0;
05898 }
05899
05900
05901
05902 static void build_rand_pad(unsigned char *buf, ssize_t len)
05903 {
05904 long tmp;
05905 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05906 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05907 buf += sizeof(tmp);
05908 len -= sizeof(tmp);
05909 }
05910 }
05911
05912 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05913 {
05914 build_ecx_key(digest, pvt);
05915 ast_aes_decrypt_key(digest, &pvt->dcx);
05916 }
05917
05918 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05919 {
05920
05921
05922
05923 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05924 ast_aes_encrypt_key(digest, &pvt->ecx);
05925 ast_aes_decrypt_key(digest, &pvt->mydcx);
05926 }
05927
05928 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
05929 {
05930 #if 0
05931
05932 int x;
05933 if (len % 16)
05934 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05935 for (x=0;x<len;x++)
05936 dst[x] = src[x] ^ 0xff;
05937 #else
05938 unsigned char lastblock[16] = { 0 };
05939 int x;
05940 while(len > 0) {
05941 ast_aes_decrypt(src, dst, dcx);
05942 for (x=0;x<16;x++)
05943 dst[x] ^= lastblock[x];
05944 memcpy(lastblock, src, sizeof(lastblock));
05945 dst += 16;
05946 src += 16;
05947 len -= 16;
05948 }
05949 #endif
05950 }
05951
05952 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
05953 {
05954 #if 0
05955
05956 int x;
05957 if (len % 16)
05958 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05959 for (x=0;x<len;x++)
05960 dst[x] = src[x] ^ 0xff;
05961 #else
05962 unsigned char curblock[16] = { 0 };
05963 int x;
05964 while(len > 0) {
05965 for (x=0;x<16;x++)
05966 curblock[x] ^= src[x];
05967 ast_aes_encrypt(curblock, dst, ecx);
05968 memcpy(curblock, dst, sizeof(curblock));
05969 dst += 16;
05970 src += 16;
05971 len -= 16;
05972 }
05973 #endif
05974 }
05975
05976 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05977 {
05978 int padding;
05979 unsigned char *workspace;
05980
05981 workspace = alloca(*datalen);
05982 memset(f, 0, sizeof(*f));
05983 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05984 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05985 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
05986 return -1;
05987
05988 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
05989
05990 padding = 16 + (workspace[15] & 0x0f);
05991 if (iaxdebug)
05992 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
05993 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
05994 return -1;
05995
05996 *datalen -= padding;
05997 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05998 f->frametype = fh->type;
05999 if (f->frametype == AST_FRAME_VIDEO) {
06000 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06001 } else {
06002 f->subclass = uncompress_subclass(fh->csub);
06003 }
06004 } else {
06005 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06006 if (iaxdebug)
06007 ast_debug(1, "Decoding mini with length %d\n", *datalen);
06008 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06009 return -1;
06010
06011 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06012 padding = 16 + (workspace[15] & 0x0f);
06013 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06014 return -1;
06015 *datalen -= padding;
06016 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06017 }
06018 return 0;
06019 }
06020
06021 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06022 {
06023 int padding;
06024 unsigned char *workspace;
06025 workspace = alloca(*datalen + 32);
06026 if (!workspace)
06027 return -1;
06028 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06029 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06030 if (iaxdebug)
06031 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06032 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06033 padding = 16 + (padding & 0xf);
06034 memcpy(workspace, poo, padding);
06035 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06036 workspace[15] &= 0xf0;
06037 workspace[15] |= (padding & 0xf);
06038 if (iaxdebug)
06039 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06040 *datalen += padding;
06041 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06042 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06043 memcpy(poo, workspace + *datalen - 32, 32);
06044 } else {
06045 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06046 if (iaxdebug)
06047 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06048 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06049 padding = 16 + (padding & 0xf);
06050 memcpy(workspace, poo, padding);
06051 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06052 workspace[15] &= 0xf0;
06053 workspace[15] |= (padding & 0x0f);
06054 *datalen += padding;
06055 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06056 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06057 memcpy(poo, workspace + *datalen - 32, 32);
06058 }
06059 return 0;
06060 }
06061
06062 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06063 {
06064 int res=-1;
06065 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
06066
06067 struct MD5Context md5;
06068 unsigned char digest[16];
06069 char *tmppw, *stringp;
06070
06071 tmppw = ast_strdupa(iaxs[callno]->secret);
06072 stringp = tmppw;
06073 while ((tmppw = strsep(&stringp, ";"))) {
06074 MD5Init(&md5);
06075 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06076 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06077 MD5Final(digest, &md5);
06078 build_encryption_keys(digest, iaxs[callno]);
06079 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06080 if (!res) {
06081 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
06082 break;
06083 }
06084 }
06085 } else
06086 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06087 return res;
06088 }
06089
06090 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06091 {
06092
06093
06094
06095 struct ast_iax2_full_hdr *fh;
06096 struct ast_iax2_mini_hdr *mh;
06097 struct ast_iax2_video_hdr *vh;
06098 struct {
06099 struct iax_frame fr2;
06100 unsigned char buffer[4096];
06101 } frb;
06102 struct iax_frame *fr;
06103 int res;
06104 int sendmini=0;
06105 unsigned int lastsent;
06106 unsigned int fts;
06107
06108 frb.fr2.afdatalen = sizeof(frb.buffer);
06109
06110 if (!pvt) {
06111 ast_log(LOG_WARNING, "No private structure for packet?\n");
06112 return -1;
06113 }
06114
06115 lastsent = pvt->lastsent;
06116
06117
06118 fts = calc_timestamp(pvt, ts, f);
06119
06120
06121
06122
06123 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06124 return 0;
06125 #if 0
06126 ast_log(LOG_NOTICE,
06127 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06128 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06129 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06130 pvt->keyrotateid != -1 ? "" : "no "
06131 );
06132 #endif
06133 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06134 iax2_key_rotate(pvt);
06135 }
06136
06137 if ((ast_test_flag(pvt, IAX_TRUNK) ||
06138 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06139 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06140 &&
06141 (f->frametype == AST_FRAME_VOICE)
06142 &&
06143 (f->subclass == pvt->svoiceformat)
06144 ) {
06145
06146 now = 1;
06147
06148 sendmini = 1;
06149 }
06150 if ( f->frametype == AST_FRAME_VIDEO ) {
06151
06152
06153
06154
06155
06156 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06157 ((f->subclass & ~0x1) == pvt->svideoformat)
06158 ) {
06159 now = 1;
06160 sendmini = 1;
06161 } else {
06162 now = 0;
06163 sendmini = 0;
06164 }
06165 pvt->lastvsent = fts;
06166 }
06167 if (f->frametype == AST_FRAME_IAX) {
06168
06169 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
06170 if (!pvt->first_iax_message) {
06171 pvt->first_iax_message = pvt->last_iax_message;
06172 }
06173 }
06174
06175 if (now) {
06176 fr = &frb.fr2;
06177 } else
06178 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));
06179 if (!fr) {
06180 ast_log(LOG_WARNING, "Out of memory\n");
06181 return -1;
06182 }
06183
06184 iax_frame_wrap(fr, f);
06185
06186 fr->ts = fts;
06187 fr->callno = pvt->callno;
06188 fr->transfer = transfer;
06189 fr->final = final;
06190 fr->encmethods = 0;
06191 if (!sendmini) {
06192
06193 if (seqno > -1)
06194 fr->oseqno = seqno;
06195 else
06196 fr->oseqno = pvt->oseqno++;
06197 fr->iseqno = pvt->iseqno;
06198 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06199 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06200 fh->ts = htonl(fr->ts);
06201 fh->oseqno = fr->oseqno;
06202 if (transfer) {
06203 fh->iseqno = 0;
06204 } else
06205 fh->iseqno = fr->iseqno;
06206
06207 if (!transfer)
06208 pvt->aseqno = fr->iseqno;
06209 fh->type = fr->af.frametype & 0xFF;
06210 if (fr->af.frametype == AST_FRAME_VIDEO)
06211 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
06212 else
06213 fh->csub = compress_subclass(fr->af.subclass);
06214 if (transfer) {
06215 fr->dcallno = pvt->transfercallno;
06216 } else
06217 fr->dcallno = pvt->peercallno;
06218 fh->dcallno = htons(fr->dcallno);
06219 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06220 fr->data = fh;
06221 fr->retries = 0;
06222
06223 fr->retrytime = pvt->pingtime * 2;
06224 if (fr->retrytime < MIN_RETRY_TIME)
06225 fr->retrytime = MIN_RETRY_TIME;
06226 if (fr->retrytime > MAX_RETRY_TIME)
06227 fr->retrytime = MAX_RETRY_TIME;
06228
06229 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
06230 fr->retries = -1;
06231 else if (f->frametype == AST_FRAME_VOICE)
06232 pvt->svoiceformat = f->subclass;
06233 else if (f->frametype == AST_FRAME_VIDEO)
06234 pvt->svideoformat = f->subclass & ~0x1;
06235 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06236 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06237 if (fr->transfer)
06238 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06239 else
06240 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06241 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06242 fr->encmethods = pvt->encmethods;
06243 fr->ecx = pvt->ecx;
06244 fr->mydcx = pvt->mydcx;
06245 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06246 } else
06247 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06248 }
06249
06250 if (now) {
06251 res = send_packet(fr);
06252 } else
06253 res = iax2_transmit(fr);
06254 } else {
06255 if (ast_test_flag(pvt, IAX_TRUNK)) {
06256 iax2_trunk_queue(pvt, fr);
06257 res = 0;
06258 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06259
06260 fr->oseqno = -1;
06261 fr->iseqno = -1;
06262 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06263 vh->zeros = 0;
06264 vh->callno = htons(0x8000 | fr->callno);
06265 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
06266 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06267 fr->data = vh;
06268 fr->retries = -1;
06269 res = send_packet(fr);
06270 } else {
06271
06272 fr->oseqno = -1;
06273 fr->iseqno = -1;
06274
06275 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06276 mh->callno = htons(fr->callno);
06277 mh->ts = htons(fr->ts & 0xFFFF);
06278 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06279 fr->data = mh;
06280 fr->retries = -1;
06281 if (pvt->transferring == TRANSFER_MEDIAPASS)
06282 fr->transfer = 1;
06283 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06284 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06285 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06286 } else
06287 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06288 }
06289 res = send_packet(fr);
06290 }
06291 }
06292 return res;
06293 }
06294
06295 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06296 {
06297 regex_t regexbuf;
06298 int havepattern = 0;
06299
06300 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06301 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06302
06303 struct iax2_user *user = NULL;
06304 char auth[90];
06305 char *pstr = "";
06306 struct ao2_iterator i;
06307
06308 switch (cmd) {
06309 case CLI_INIT:
06310 e->command = "iax2 show users [like]";
06311 e->usage =
06312 "Usage: iax2 show users [like <pattern>]\n"
06313 " Lists all known IAX2 users.\n"
06314 " Optional regular expression pattern is used to filter the user list.\n";
06315 return NULL;
06316 case CLI_GENERATE:
06317 return NULL;
06318 }
06319
06320 switch (a->argc) {
06321 case 5:
06322 if (!strcasecmp(a->argv[3], "like")) {
06323 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06324 return CLI_SHOWUSAGE;
06325 havepattern = 1;
06326 } else
06327 return CLI_SHOWUSAGE;
06328 case 3:
06329 break;
06330 default:
06331 return CLI_SHOWUSAGE;
06332 }
06333
06334 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06335 i = ao2_iterator_init(users, 0);
06336 for (user = ao2_iterator_next(&i); user;
06337 user_unref(user), user = ao2_iterator_next(&i)) {
06338 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06339 continue;
06340
06341 if (!ast_strlen_zero(user->secret)) {
06342 ast_copy_string(auth,user->secret, sizeof(auth));
06343 } else if (!ast_strlen_zero(user->inkeys)) {
06344 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06345 } else
06346 ast_copy_string(auth, "-no secret-", sizeof(auth));
06347
06348 if(ast_test_flag(user,IAX_CODEC_NOCAP))
06349 pstr = "REQ Only";
06350 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
06351 pstr = "Disabled";
06352 else
06353 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06354
06355 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06356 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06357 user->ha ? "Yes" : "No", pstr);
06358 }
06359 ao2_iterator_destroy(&i);
06360
06361 if (havepattern)
06362 regfree(®exbuf);
06363
06364 return CLI_SUCCESS;
06365 #undef FORMAT
06366 #undef FORMAT2
06367 }
06368
06369 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
06370 {
06371 regex_t regexbuf;
06372 int havepattern = 0;
06373 int total_peers = 0;
06374 int online_peers = 0;
06375 int offline_peers = 0;
06376 int unmonitored_peers = 0;
06377 struct ao2_iterator i;
06378
06379 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
06380 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
06381
06382 struct iax2_peer *peer = NULL;
06383 char name[256];
06384 struct ast_str *encmethods = ast_str_alloca(256);
06385 int registeredonly=0;
06386 char *term = manager ? "\r\n" : "\n";
06387 char idtext[256] = "";
06388 switch (argc) {
06389 case 6:
06390 if (!strcasecmp(argv[3], "registered"))
06391 registeredonly = 1;
06392 else
06393 return RESULT_SHOWUSAGE;
06394 if (!strcasecmp(argv[4], "like")) {
06395 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06396 return RESULT_SHOWUSAGE;
06397 havepattern = 1;
06398 } else
06399 return RESULT_SHOWUSAGE;
06400 break;
06401 case 5:
06402 if (!strcasecmp(argv[3], "like")) {
06403 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06404 return RESULT_SHOWUSAGE;
06405 havepattern = 1;
06406 } else
06407 return RESULT_SHOWUSAGE;
06408 break;
06409 case 4:
06410 if (!strcasecmp(argv[3], "registered"))
06411 registeredonly = 1;
06412 else
06413 return RESULT_SHOWUSAGE;
06414 break;
06415 case 3:
06416 break;
06417 default:
06418 return RESULT_SHOWUSAGE;
06419 }
06420
06421
06422 if (!s)
06423 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
06424
06425 i = ao2_iterator_init(peers, 0);
06426 for (peer = ao2_iterator_next(&i); peer;
06427 peer_unref(peer), peer = ao2_iterator_next(&i)) {
06428 char nm[20];
06429 char status[20];
06430 int retstatus;
06431
06432 if (registeredonly && !peer->addr.sin_addr.s_addr)
06433 continue;
06434 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
06435 continue;
06436
06437 if (!ast_strlen_zero(peer->username))
06438 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06439 else
06440 ast_copy_string(name, peer->name, sizeof(name));
06441
06442 encmethods_to_str(peer->encmethods, encmethods);
06443 retstatus = peer_status(peer, status, sizeof(status));
06444 if (retstatus > 0)
06445 online_peers++;
06446 else if (!retstatus)
06447 offline_peers++;
06448 else
06449 unmonitored_peers++;
06450
06451 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06452
06453 if (s) {
06454 astman_append(s,
06455 "Event: PeerEntry\r\n%s"
06456 "Channeltype: IAX2\r\n"
06457 "ChanObjectType: peer\r\n"
06458 "ObjectName: %s\r\n"
06459 "IPaddress: %s\r\n"
06460 "IPport: %d\r\n"
06461 "Dynamic: %s\r\n"
06462 "Trunk: %s\r\n"
06463 "Encryption: %s\r\n"
06464 "Status: %s\r\n\r\n",
06465 idtext,
06466 name,
06467 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
06468 ntohs(peer->addr.sin_port),
06469 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
06470 ast_test_flag(peer, IAX_TRUNK) ? "yes" : "no",
06471 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06472 status);
06473 } else {
06474 ast_cli(fd, FORMAT, name,
06475 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06476 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06477 nm,
06478 ntohs(peer->addr.sin_port),
06479 ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
06480 peer->encmethods ? "(E)" : " ",
06481 status,
06482 term);
06483 }
06484 total_peers++;
06485 }
06486 ao2_iterator_destroy(&i);
06487
06488 if (!s)
06489 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
06490
06491 if (havepattern)
06492 regfree(®exbuf);
06493
06494 return RESULT_SUCCESS;
06495 #undef FORMAT
06496 #undef FORMAT2
06497 }
06498
06499 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06500 {
06501 struct iax2_thread *thread = NULL;
06502 time_t t;
06503 int threadcount = 0, dynamiccount = 0;
06504 char type;
06505
06506 switch (cmd) {
06507 case CLI_INIT:
06508 e->command = "iax2 show threads";
06509 e->usage =
06510 "Usage: iax2 show threads\n"
06511 " Lists status of IAX helper threads\n";
06512 return NULL;
06513 case CLI_GENERATE:
06514 return NULL;
06515 }
06516 if (a->argc != 3)
06517 return CLI_SHOWUSAGE;
06518
06519 ast_cli(a->fd, "IAX2 Thread Information\n");
06520 time(&t);
06521 ast_cli(a->fd, "Idle Threads:\n");
06522 AST_LIST_LOCK(&idle_list);
06523 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06524 #ifdef DEBUG_SCHED_MULTITHREAD
06525 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06526 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06527 #else
06528 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06529 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06530 #endif
06531 threadcount++;
06532 }
06533 AST_LIST_UNLOCK(&idle_list);
06534 ast_cli(a->fd, "Active Threads:\n");
06535 AST_LIST_LOCK(&active_list);
06536 AST_LIST_TRAVERSE(&active_list, thread, list) {
06537 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06538 type = 'D';
06539 else
06540 type = 'P';
06541 #ifdef DEBUG_SCHED_MULTITHREAD
06542 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06543 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06544 #else
06545 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06546 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06547 #endif
06548 threadcount++;
06549 }
06550 AST_LIST_UNLOCK(&active_list);
06551 ast_cli(a->fd, "Dynamic Threads:\n");
06552 AST_LIST_LOCK(&dynamic_list);
06553 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06554 #ifdef DEBUG_SCHED_MULTITHREAD
06555 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06556 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06557 #else
06558 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06559 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06560 #endif
06561 dynamiccount++;
06562 }
06563 AST_LIST_UNLOCK(&dynamic_list);
06564 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06565 return CLI_SUCCESS;
06566 }
06567
06568 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06569 {
06570 struct iax2_peer *p;
06571
06572 switch (cmd) {
06573 case CLI_INIT:
06574 e->command = "iax2 unregister";
06575 e->usage =
06576 "Usage: iax2 unregister <peername>\n"
06577 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06578 return NULL;
06579 case CLI_GENERATE:
06580 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06581 }
06582
06583 if (a->argc != 3)
06584 return CLI_SHOWUSAGE;
06585
06586 p = find_peer(a->argv[2], 1);
06587 if (p) {
06588 if (p->expire > 0) {
06589 struct iax2_peer tmp_peer = {
06590 .name = a->argv[2],
06591 };
06592 struct iax2_peer *peer;
06593
06594 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06595 if (peer) {
06596 expire_registry(peer_ref(peer));
06597 peer_unref(peer);
06598 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06599 } else {
06600 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06601 }
06602 } else {
06603 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06604 }
06605 } else {
06606 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06607 }
06608 return CLI_SUCCESS;
06609 }
06610
06611 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06612 {
06613 int which = 0;
06614 struct iax2_peer *p = NULL;
06615 char *res = NULL;
06616 int wordlen = strlen(word);
06617
06618
06619 if (pos == 2) {
06620 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06621 while ((p = ao2_iterator_next(&i))) {
06622 if (!strncasecmp(p->name, word, wordlen) &&
06623 ++which > state && p->expire > 0) {
06624 res = ast_strdup(p->name);
06625 peer_unref(p);
06626 break;
06627 }
06628 peer_unref(p);
06629 }
06630 ao2_iterator_destroy(&i);
06631 }
06632
06633 return res;
06634 }
06635
06636 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06637 {
06638 switch (cmd) {
06639 case CLI_INIT:
06640 e->command = "iax2 show peers";
06641 e->usage =
06642 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06643 " Lists all known IAX2 peers.\n"
06644 " Optional 'registered' argument lists only peers with known addresses.\n"
06645 " Optional regular expression pattern is used to filter the peer list.\n";
06646 return NULL;
06647 case CLI_GENERATE:
06648 return NULL;
06649 }
06650
06651 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
06652 case RESULT_SHOWUSAGE:
06653 return CLI_SHOWUSAGE;
06654 case RESULT_FAILURE:
06655 return CLI_FAILURE;
06656 default:
06657 return CLI_SUCCESS;
06658 }
06659 }
06660
06661 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06662 {
06663 ast_cli_netstats(s, -1, 0);
06664 astman_append(s, "\r\n");
06665 return RESULT_SUCCESS;
06666 }
06667
06668 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06669 {
06670 struct iax_firmware *cur = NULL;
06671
06672 switch (cmd) {
06673 case CLI_INIT:
06674 e->command = "iax2 show firmware";
06675 e->usage =
06676 "Usage: iax2 show firmware\n"
06677 " Lists all known IAX firmware images.\n";
06678 return NULL;
06679 case CLI_GENERATE:
06680 return NULL;
06681 }
06682
06683 if (a->argc != 3 && a->argc != 4)
06684 return CLI_SHOWUSAGE;
06685
06686 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06687 AST_LIST_LOCK(&firmwares);
06688 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06689 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06690 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06691 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06692 }
06693 }
06694 AST_LIST_UNLOCK(&firmwares);
06695
06696 return CLI_SUCCESS;
06697 }
06698
06699
06700 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06701 {
06702 char *a[] = { "iax2", "show", "users" };
06703 const char *id = astman_get_header(m,"ActionID");
06704 char idtext[256] = "";
06705
06706 if (!ast_strlen_zero(id))
06707 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06708 astman_send_ack(s, m, "Peer status list will follow");
06709 return __iax2_show_peers(1, -1, s, 3, a );
06710 }
06711
06712
06713 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06714 {
06715 struct iax2_peer *peer = NULL;
06716 int peer_count = 0;
06717 char nm[20];
06718 char status[20];
06719 const char *id = astman_get_header(m,"ActionID");
06720 char idtext[256] = "";
06721 struct ast_str *encmethods = ast_str_alloca(256);
06722 struct ao2_iterator i;
06723
06724 if (!ast_strlen_zero(id))
06725 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06726
06727 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06728
06729
06730 i = ao2_iterator_init(peers, 0);
06731 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06732 encmethods_to_str(peer->encmethods, encmethods);
06733 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06734 if (!ast_strlen_zero(peer->username)) {
06735 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06736 } else {
06737 astman_append(s, "ObjectName: %s\r\n", peer->name);
06738 }
06739 astman_append(s, "ChanObjectType: peer\r\n");
06740 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
06741 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06742 astman_append(s, "Mask: %s\r\n", nm);
06743 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
06744 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
06745 astman_append(s, "Trunk: %s\r\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
06746 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
06747 peer_status(peer, status, sizeof(status));
06748 astman_append(s, "Status: %s\r\n\r\n", status);
06749 peer_count++;
06750 }
06751 ao2_iterator_destroy(&i);
06752
06753 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
06754 return RESULT_SUCCESS;
06755 }
06756
06757
06758 static char *regstate2str(int regstate)
06759 {
06760 switch(regstate) {
06761 case REG_STATE_UNREGISTERED:
06762 return "Unregistered";
06763 case REG_STATE_REGSENT:
06764 return "Request Sent";
06765 case REG_STATE_AUTHSENT:
06766 return "Auth. Sent";
06767 case REG_STATE_REGISTERED:
06768 return "Registered";
06769 case REG_STATE_REJECTED:
06770 return "Rejected";
06771 case REG_STATE_TIMEOUT:
06772 return "Timeout";
06773 case REG_STATE_NOAUTH:
06774 return "No Authentication";
06775 default:
06776 return "Unknown";
06777 }
06778 }
06779
06780 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06781 {
06782 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
06783 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
06784 struct iax2_registry *reg = NULL;
06785 char host[80];
06786 char perceived[80];
06787 int counter = 0;
06788
06789 switch (cmd) {
06790 case CLI_INIT:
06791 e->command = "iax2 show registry";
06792 e->usage =
06793 "Usage: iax2 show registry\n"
06794 " Lists all registration requests and status.\n";
06795 return NULL;
06796 case CLI_GENERATE:
06797 return NULL;
06798 }
06799 if (a->argc != 3)
06800 return CLI_SHOWUSAGE;
06801 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
06802 AST_LIST_LOCK(®istrations);
06803 AST_LIST_TRAVERSE(®istrations, reg, entry) {
06804 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06805 if (reg->us.sin_addr.s_addr)
06806 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06807 else
06808 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06809 ast_cli(a->fd, FORMAT, host,
06810 (reg->dnsmgr) ? "Y" : "N",
06811 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
06812 counter++;
06813 }
06814 AST_LIST_UNLOCK(®istrations);
06815 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
06816 return CLI_SUCCESS;
06817 #undef FORMAT
06818 #undef FORMAT2
06819 }
06820
06821 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
06822 {
06823 const char *id = astman_get_header(m, "ActionID");
06824 struct iax2_registry *reg = NULL;
06825 char idtext[256] = "";
06826 char host[80] = "";
06827 char perceived[80] = "";
06828 int total = 0;
06829
06830 if (!ast_strlen_zero(id))
06831 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06832
06833 astman_send_listack(s, m, "Registrations will follow", "start");
06834
06835 AST_LIST_LOCK(®istrations);
06836 AST_LIST_TRAVERSE(®istrations, reg, entry) {
06837 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06838
06839 if (reg->us.sin_addr.s_addr) {
06840 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06841 } else {
06842 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06843 }
06844
06845 astman_append(s,
06846 "Event: RegistryEntry\r\n"
06847 "%s"
06848 "Host: %s\r\n"
06849 "DNSmanager: %s\r\n"
06850 "Username: %s\r\n"
06851 "Perceived: %s\r\n"
06852 "Refresh: %d\r\n"
06853 "State: %s\r\n"
06854 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
06855 reg->refresh, regstate2str(reg->regstate));
06856
06857 total++;
06858 }
06859 AST_LIST_UNLOCK(®istrations);
06860
06861 astman_append(s,
06862 "Event: RegistrationsComplete\r\n"
06863 "EventList: Complete\r\n"
06864 "ListItems: %d\r\n"
06865 "%s"
06866 "\r\n", total, idtext);
06867
06868 return 0;
06869 }
06870
06871 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06872 {
06873 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
06874 #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"
06875 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
06876 int x;
06877 int numchans = 0;
06878 char first_message[10] = { 0, };
06879 char last_message[10] = { 0, };
06880
06881 switch (cmd) {
06882 case CLI_INIT:
06883 e->command = "iax2 show channels";
06884 e->usage =
06885 "Usage: iax2 show channels\n"
06886 " Lists all currently active IAX channels.\n";
06887 return NULL;
06888 case CLI_GENERATE:
06889 return NULL;
06890 }
06891
06892 if (a->argc != 3)
06893 return CLI_SHOWUSAGE;
06894 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
06895 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06896 ast_mutex_lock(&iaxsl[x]);
06897 if (iaxs[x]) {
06898 int lag, jitter, localdelay;
06899 jb_info jbinfo;
06900 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06901 jb_getinfo(iaxs[x]->jb, &jbinfo);
06902 jitter = jbinfo.jitter;
06903 localdelay = jbinfo.current - jbinfo.min;
06904 } else {
06905 jitter = -1;
06906 localdelay = 0;
06907 }
06908
06909 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06910 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06911 lag = iaxs[x]->remote_rr.delay;
06912 ast_cli(a->fd, FORMAT,
06913 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06914 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
06915 S_OR(iaxs[x]->username, "(None)"),
06916 iaxs[x]->callno, iaxs[x]->peercallno,
06917 iaxs[x]->oseqno, iaxs[x]->iseqno,
06918 lag,
06919 jitter,
06920 localdelay,
06921 ast_getformatname(iaxs[x]->voiceformat),
06922 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06923 first_message,
06924 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06925 last_message);
06926 numchans++;
06927 }
06928 ast_mutex_unlock(&iaxsl[x]);
06929 }
06930 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06931 return CLI_SUCCESS;
06932 #undef FORMAT
06933 #undef FORMAT2
06934 #undef FORMATB
06935 }
06936
06937 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
06938 {
06939 int x;
06940 int numchans = 0;
06941 char first_message[10] = { 0, };
06942 char last_message[10] = { 0, };
06943 #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"
06944 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
06945 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06946 ast_mutex_lock(&iaxsl[x]);
06947 if (iaxs[x]) {
06948 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06949 jb_info jbinfo;
06950 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06951 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06952
06953 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06954 jb_getinfo(iaxs[x]->jb, &jbinfo);
06955 localjitter = jbinfo.jitter;
06956 localdelay = jbinfo.current - jbinfo.min;
06957 locallost = jbinfo.frames_lost;
06958 locallosspct = jbinfo.losspct/1000;
06959 localdropped = jbinfo.frames_dropped;
06960 localooo = jbinfo.frames_ooo;
06961 } else {
06962 localjitter = -1;
06963 localdelay = 0;
06964 locallost = -1;
06965 locallosspct = -1;
06966 localdropped = 0;
06967 localooo = -1;
06968 }
06969 if (s)
06970 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06971 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06972 iaxs[x]->pingtime,
06973 localjitter,
06974 localdelay,
06975 locallost,
06976 locallosspct,
06977 localdropped,
06978 localooo,
06979 iaxs[x]->frames_received/1000,
06980 iaxs[x]->remote_rr.jitter,
06981 iaxs[x]->remote_rr.delay,
06982 iaxs[x]->remote_rr.losscnt,
06983 iaxs[x]->remote_rr.losspct,
06984 iaxs[x]->remote_rr.dropped,
06985 iaxs[x]->remote_rr.ooo,
06986 iaxs[x]->remote_rr.packets/1000,
06987 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06988 first_message,
06989 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06990 last_message);
06991 else
06992 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06993 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06994 iaxs[x]->pingtime,
06995 localjitter,
06996 localdelay,
06997 locallost,
06998 locallosspct,
06999 localdropped,
07000 localooo,
07001 iaxs[x]->frames_received/1000,
07002 iaxs[x]->remote_rr.jitter,
07003 iaxs[x]->remote_rr.delay,
07004 iaxs[x]->remote_rr.losscnt,
07005 iaxs[x]->remote_rr.losspct,
07006 iaxs[x]->remote_rr.dropped,
07007 iaxs[x]->remote_rr.ooo,
07008 iaxs[x]->remote_rr.packets/1000,
07009 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07010 first_message,
07011 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07012 last_message);
07013 numchans++;
07014 }
07015 ast_mutex_unlock(&iaxsl[x]);
07016 }
07017
07018 return numchans;
07019 }
07020
07021 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07022 {
07023 int numchans = 0;
07024
07025 switch (cmd) {
07026 case CLI_INIT:
07027 e->command = "iax2 show netstats";
07028 e->usage =
07029 "Usage: iax2 show netstats\n"
07030 " Lists network status for all currently active IAX channels.\n";
07031 return NULL;
07032 case CLI_GENERATE:
07033 return NULL;
07034 }
07035 if (a->argc != 3)
07036 return CLI_SHOWUSAGE;
07037 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07038 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07039 numchans = ast_cli_netstats(NULL, a->fd, 1);
07040 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07041 return CLI_SUCCESS;
07042 }
07043
07044 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07045 {
07046 switch (cmd) {
07047 case CLI_INIT:
07048 e->command = "iax2 set debug {on|off|peer}";
07049 e->usage =
07050 "Usage: iax2 set debug {on|off|peer peername}\n"
07051 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07052 return NULL;
07053 case CLI_GENERATE:
07054 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07055 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07056 return NULL;
07057 }
07058
07059 if (a->argc < e->args || a->argc > e->args + 1)
07060 return CLI_SHOWUSAGE;
07061
07062 if (!strcasecmp(a->argv[3], "peer")) {
07063 struct iax2_peer *peer;
07064
07065 if (a->argc != e->args + 1)
07066 return CLI_SHOWUSAGE;
07067
07068 peer = find_peer(a->argv[4], 1);
07069
07070 if (!peer) {
07071 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07072 return CLI_FAILURE;
07073 }
07074
07075 debugaddr.sin_addr = peer->addr.sin_addr;
07076 debugaddr.sin_port = peer->addr.sin_port;
07077
07078 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07079 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07080
07081 ao2_ref(peer, -1);
07082 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07083 iaxdebug = 1;
07084 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07085 } else {
07086 iaxdebug = 0;
07087 memset(&debugaddr, 0, sizeof(debugaddr));
07088 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07089 }
07090 return CLI_SUCCESS;
07091 }
07092
07093 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07094 {
07095 switch (cmd) {
07096 case CLI_INIT:
07097 e->command = "iax2 set debug trunk {on|off}";
07098 e->usage =
07099 "Usage: iax2 set debug trunk {on|off}\n"
07100 " Enables/Disables debugging of IAX trunking\n";
07101 return NULL;
07102 case CLI_GENERATE:
07103 return NULL;
07104 }
07105
07106 if (a->argc != e->args)
07107 return CLI_SHOWUSAGE;
07108
07109 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07110 iaxtrunkdebug = 1;
07111 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07112 } else {
07113 iaxtrunkdebug = 0;
07114 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07115 }
07116 return CLI_SUCCESS;
07117 }
07118
07119 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07120 {
07121 switch (cmd) {
07122 case CLI_INIT:
07123 e->command = "iax2 set debug jb {on|off}";
07124 e->usage =
07125 "Usage: iax2 set debug jb {on|off}\n"
07126 " Enables/Disables jitterbuffer debugging information\n";
07127 return NULL;
07128 case CLI_GENERATE:
07129 return NULL;
07130 }
07131
07132 if (a->argc != e->args)
07133 return CLI_SHOWUSAGE;
07134
07135 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07136 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07137 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07138 } else {
07139 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07140 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07141 }
07142 return CLI_SUCCESS;
07143 }
07144
07145 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07146 {
07147 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07148 int res = -1;
07149 ast_mutex_lock(&iaxsl[callno]);
07150 if (iaxs[callno]) {
07151
07152 if (!iaxs[callno]->error) {
07153 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
07154 res = 0;
07155
07156 else if (f->frametype == AST_FRAME_NULL)
07157 res = 0;
07158 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
07159 res = 0;
07160 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07161 res = 0;
07162 else
07163
07164 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07165 } else {
07166 ast_debug(1, "Write error: %s\n", strerror(errno));
07167 }
07168 }
07169
07170 ast_mutex_unlock(&iaxsl[callno]);
07171 return res;
07172 }
07173
07174 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07175 int now, int transfer, int final)
07176 {
07177 struct ast_frame f = { 0, };
07178 int res = 0;
07179
07180 f.frametype = type;
07181 f.subclass = command;
07182 f.datalen = datalen;
07183 f.src = __FUNCTION__;
07184 f.data.ptr = (void *) data;
07185
07186 if ((res = queue_signalling(i, &f)) <= 0) {
07187 return res;
07188 }
07189
07190 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07191 }
07192
07193 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07194 {
07195 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07196 }
07197
07198 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07199 {
07200 int res;
07201 ast_mutex_lock(&iaxsl[callno]);
07202 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07203 ast_mutex_unlock(&iaxsl[callno]);
07204 return res;
07205 }
07206
07207
07208
07209
07210
07211
07212 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)
07213 {
07214 int call_num = i->callno;
07215
07216 iax2_predestroy(i->callno);
07217 if (!iaxs[call_num])
07218 return -1;
07219 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07220 }
07221
07222 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)
07223 {
07224 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07225 }
07226
07227 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07228 {
07229 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07230 }
07231
07232 static int apply_context(struct iax2_context *con, const char *context)
07233 {
07234 while(con) {
07235 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07236 return -1;
07237 con = con->next;
07238 }
07239 return 0;
07240 }
07241
07242
07243 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07244 {
07245
07246 int res = -1;
07247 int version = 2;
07248 struct iax2_user *user = NULL, *best = NULL;
07249 int bestscore = 0;
07250 int gotcapability = 0;
07251 struct ast_variable *v = NULL, *tmpvar = NULL;
07252 struct ao2_iterator i;
07253
07254 if (!iaxs[callno])
07255 return res;
07256 if (ies->called_number)
07257 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07258 if (ies->calling_number) {
07259 if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) {
07260 ast_shrink_phone_number(ies->calling_number);
07261 }
07262 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07263 }
07264 if (ies->calling_name)
07265 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07266 if (ies->calling_ani)
07267 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07268 if (ies->dnid)
07269 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07270 if (ies->rdnis)
07271 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07272 if (ies->called_context)
07273 ast_string_field_set(iaxs[callno], context, ies->called_context);
07274 if (ies->language)
07275 ast_string_field_set(iaxs[callno], language, ies->language);
07276 if (ies->username)
07277 ast_string_field_set(iaxs[callno], username, ies->username);
07278 if (ies->calling_ton > -1)
07279 iaxs[callno]->calling_ton = ies->calling_ton;
07280 if (ies->calling_tns > -1)
07281 iaxs[callno]->calling_tns = ies->calling_tns;
07282 if (ies->calling_pres > -1)
07283 iaxs[callno]->calling_pres = ies->calling_pres;
07284 if (ies->format)
07285 iaxs[callno]->peerformat = ies->format;
07286 if (ies->adsicpe)
07287 iaxs[callno]->peeradsicpe = ies->adsicpe;
07288 if (ies->capability) {
07289 gotcapability = 1;
07290 iaxs[callno]->peercapability = ies->capability;
07291 }
07292 if (ies->version)
07293 version = ies->version;
07294
07295
07296 if(ies->codec_prefs) {
07297 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07298 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07299 }
07300
07301 if (!gotcapability)
07302 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07303 if (version > IAX_PROTO_VERSION) {
07304 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07305 ast_inet_ntoa(sin->sin_addr), version);
07306 return res;
07307 }
07308
07309 i = ao2_iterator_init(users, 0);
07310 while ((user = ao2_iterator_next(&i))) {
07311 if ((ast_strlen_zero(iaxs[callno]->username) ||
07312 !strcmp(iaxs[callno]->username, user->name))
07313 && ast_apply_ha(user->ha, sin)
07314 && (ast_strlen_zero(iaxs[callno]->context) ||
07315 apply_context(user->contexts, iaxs[callno]->context))) {
07316 if (!ast_strlen_zero(iaxs[callno]->username)) {
07317
07318 if (best)
07319 user_unref(best);
07320 best = user;
07321 break;
07322 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07323
07324 if (user->ha) {
07325
07326 if (bestscore < 4) {
07327 bestscore = 4;
07328 if (best)
07329 user_unref(best);
07330 best = user;
07331 continue;
07332 }
07333 } else {
07334
07335 if (bestscore < 3) {
07336 bestscore = 3;
07337 if (best)
07338 user_unref(best);
07339 best = user;
07340 continue;
07341 }
07342 }
07343 } else {
07344 if (user->ha) {
07345
07346 if (bestscore < 2) {
07347 bestscore = 2;
07348 if (best)
07349 user_unref(best);
07350 best = user;
07351 continue;
07352 }
07353 } else {
07354
07355 if (bestscore < 1) {
07356 bestscore = 1;
07357 if (best)
07358 user_unref(best);
07359 best = user;
07360 continue;
07361 }
07362 }
07363 }
07364 }
07365 user_unref(user);
07366 }
07367 ao2_iterator_destroy(&i);
07368 user = best;
07369 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07370 user = realtime_user(iaxs[callno]->username, sin);
07371 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07372 !apply_context(user->contexts, iaxs[callno]->context)) {
07373 user = user_unref(user);
07374 }
07375 }
07376 if (user) {
07377
07378
07379 for (v = user->vars ; v ; v = v->next) {
07380 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07381 tmpvar->next = iaxs[callno]->vars;
07382 iaxs[callno]->vars = tmpvar;
07383 }
07384 }
07385
07386 if (user->maxauthreq > 0)
07387 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
07388 iaxs[callno]->prefs = user->prefs;
07389 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07390 iaxs[callno]->encmethods = user->encmethods;
07391
07392 if (ast_strlen_zero(iaxs[callno]->username))
07393 ast_string_field_set(iaxs[callno], username, user->name);
07394
07395 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
07396 iaxs[callno]->capability = user->capability;
07397
07398 if (ast_strlen_zero(iaxs[callno]->context)) {
07399 if (user->contexts)
07400 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07401 else
07402 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07403 }
07404
07405 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07406
07407 iaxs[callno]->authmethods = user->authmethods;
07408 iaxs[callno]->adsi = user->adsi;
07409
07410 if (ast_test_flag(user, IAX_HASCALLERID)) {
07411 iaxs[callno]->calling_tns = 0;
07412 iaxs[callno]->calling_ton = 0;
07413 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07414 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07415 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07416 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07417 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07418 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07419 }
07420 if (!ast_strlen_zero(user->accountcode))
07421 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07422 if (!ast_strlen_zero(user->mohinterpret))
07423 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07424 if (!ast_strlen_zero(user->mohsuggest))
07425 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07426 if (!ast_strlen_zero(user->parkinglot))
07427 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07428 if (user->amaflags)
07429 iaxs[callno]->amaflags = user->amaflags;
07430 if (!ast_strlen_zero(user->language))
07431 ast_string_field_set(iaxs[callno], language, user->language);
07432 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07433
07434 if (!ast_strlen_zero(user->dbsecret)) {
07435 char *family, *key=NULL;
07436 char buf[80];
07437 family = ast_strdupa(user->dbsecret);
07438 key = strchr(family, '/');
07439 if (key) {
07440 *key = '\0';
07441 key++;
07442 }
07443 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07444 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07445 else
07446 ast_string_field_set(iaxs[callno], secret, buf);
07447 } else
07448 ast_string_field_set(iaxs[callno], secret, user->secret);
07449 res = 0;
07450 user = user_unref(user);
07451 } else {
07452
07453
07454
07455
07456 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07457 ast_string_field_set(iaxs[callno], secret, "badsecret");
07458 iaxs[callno]->authrej = 1;
07459 if (!ast_strlen_zero(iaxs[callno]->username)) {
07460
07461 res = 0;
07462 }
07463 }
07464 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07465 return res;
07466 }
07467
07468 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07469 {
07470 struct ast_iax2_full_hdr fh;
07471 fh.scallno = htons(src | IAX_FLAG_FULL);
07472 fh.dcallno = htons(dst);
07473 fh.ts = 0;
07474 fh.oseqno = 0;
07475 fh.iseqno = 0;
07476 fh.type = AST_FRAME_IAX;
07477 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07478 iax_outputframe(NULL, &fh, 0, sin, 0);
07479 #if 0
07480 if (option_debug)
07481 #endif
07482 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07483 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07484 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07485 }
07486
07487 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07488 {
07489
07490 p->encmethods &= enc;
07491 if (p->encmethods) {
07492 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07493 p->keyrotateid = -2;
07494 }
07495 if (p->encmethods & IAX_ENCRYPT_AES128)
07496 p->encmethods = IAX_ENCRYPT_AES128;
07497 else
07498 p->encmethods = 0;
07499 }
07500 }
07501
07502
07503
07504
07505
07506
07507
07508 static int authenticate_request(int call_num)
07509 {
07510 struct iax_ie_data ied;
07511 int res = -1, authreq_restrict = 0;
07512 char challenge[10];
07513 struct chan_iax2_pvt *p = iaxs[call_num];
07514
07515 memset(&ied, 0, sizeof(ied));
07516
07517
07518 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07519 struct iax2_user *user, tmp_user = {
07520 .name = p->username,
07521 };
07522
07523 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07524 if (user) {
07525 if (user->curauthreq == user->maxauthreq)
07526 authreq_restrict = 1;
07527 else
07528 user->curauthreq++;
07529 user = user_unref(user);
07530 }
07531 }
07532
07533
07534 if (authreq_restrict) {
07535 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07536 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07537 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07538 return 0;
07539 }
07540
07541 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07542 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07543 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07544 ast_string_field_set(p, challenge, challenge);
07545
07546 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07547 }
07548 if (p->encmethods)
07549 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07550
07551 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07552
07553 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07554
07555 if (p->encmethods)
07556 ast_set_flag(p, IAX_ENCRYPTED);
07557
07558 return res;
07559 }
07560
07561 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07562 {
07563 char requeststr[256];
07564 char md5secret[256] = "";
07565 char secret[256] = "";
07566 char rsasecret[256] = "";
07567 int res = -1;
07568 int x;
07569 struct iax2_user *user, tmp_user = {
07570 .name = p->username,
07571 };
07572
07573 if (p->authrej) {
07574 return res;
07575 }
07576 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07577 if (user) {
07578 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07579 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07580 ast_clear_flag(p, IAX_MAXAUTHREQ);
07581 }
07582 ast_string_field_set(p, host, user->name);
07583 user = user_unref(user);
07584 }
07585 if (ast_test_flag(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07586 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07587 return res;
07588 }
07589 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07590 return res;
07591 if (ies->password)
07592 ast_copy_string(secret, ies->password, sizeof(secret));
07593 if (ies->md5_result)
07594 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07595 if (ies->rsa_result)
07596 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07597 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07598 struct ast_key *key;
07599 char *keyn;
07600 char tmpkey[256];
07601 char *stringp=NULL;
07602 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07603 stringp=tmpkey;
07604 keyn = strsep(&stringp, ":");
07605 while(keyn) {
07606 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07607 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07608 res = 0;
07609 break;
07610 } else if (!key)
07611 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07612 keyn = strsep(&stringp, ":");
07613 }
07614 } else if (p->authmethods & IAX_AUTH_MD5) {
07615 struct MD5Context md5;
07616 unsigned char digest[16];
07617 char *tmppw, *stringp;
07618
07619 tmppw = ast_strdupa(p->secret);
07620 stringp = tmppw;
07621 while((tmppw = strsep(&stringp, ";"))) {
07622 MD5Init(&md5);
07623 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07624 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07625 MD5Final(digest, &md5);
07626
07627 for (x=0;x<16;x++)
07628 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07629 if (!strcasecmp(requeststr, md5secret)) {
07630 res = 0;
07631 break;
07632 }
07633 }
07634 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07635 if (!strcmp(secret, p->secret))
07636 res = 0;
07637 }
07638 return res;
07639 }
07640
07641
07642 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07643 {
07644 char requeststr[256] = "";
07645 char peer[256] = "";
07646 char md5secret[256] = "";
07647 char rsasecret[256] = "";
07648 char secret[256] = "";
07649 struct iax2_peer *p = NULL;
07650 struct ast_key *key;
07651 char *keyn;
07652 int x;
07653 int expire = 0;
07654 int res = -1;
07655
07656 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07657
07658 if (ies->username)
07659 ast_copy_string(peer, ies->username, sizeof(peer));
07660 if (ies->password)
07661 ast_copy_string(secret, ies->password, sizeof(secret));
07662 if (ies->md5_result)
07663 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07664 if (ies->rsa_result)
07665 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07666 if (ies->refresh)
07667 expire = ies->refresh;
07668
07669 if (ast_strlen_zero(peer)) {
07670 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07671 return -1;
07672 }
07673
07674
07675 ast_mutex_unlock(&iaxsl[callno]);
07676 p = find_peer(peer, 1);
07677 ast_mutex_lock(&iaxsl[callno]);
07678 if (!p || !iaxs[callno]) {
07679 if (iaxs[callno]) {
07680 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07681
07682 ast_string_field_set(iaxs[callno], secret, "badsecret");
07683
07684
07685
07686
07687
07688
07689
07690
07691
07692 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07693 !(!ast_strlen_zero(secret) && plaintext)) {
07694
07695 res = 0;
07696 }
07697 }
07698 if (authdebug && !p)
07699 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07700 goto return_unref;
07701 }
07702
07703 if (!ast_test_flag(p, IAX_DYNAMIC)) {
07704 if (authdebug)
07705 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07706 goto return_unref;
07707 }
07708
07709 if (!ast_apply_ha(p->ha, sin)) {
07710 if (authdebug)
07711 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07712 goto return_unref;
07713 }
07714 ast_string_field_set(iaxs[callno], secret, p->secret);
07715 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07716
07717 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07718 if (!ast_strlen_zero(p->inkeys)) {
07719 char tmpkeys[256];
07720 char *stringp=NULL;
07721 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07722 stringp=tmpkeys;
07723 keyn = strsep(&stringp, ":");
07724 while(keyn) {
07725 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07726 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07727 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07728 break;
07729 } else if (!key)
07730 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
07731 keyn = strsep(&stringp, ":");
07732 }
07733 if (!keyn) {
07734 if (authdebug)
07735 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
07736 goto return_unref;
07737 }
07738 } else {
07739 if (authdebug)
07740 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
07741 goto return_unref;
07742 }
07743 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07744 struct MD5Context md5;
07745 unsigned char digest[16];
07746 char *tmppw, *stringp;
07747
07748 tmppw = ast_strdupa(p->secret);
07749 stringp = tmppw;
07750 while((tmppw = strsep(&stringp, ";"))) {
07751 MD5Init(&md5);
07752 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
07753 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07754 MD5Final(digest, &md5);
07755 for (x=0;x<16;x++)
07756 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07757 if (!strcasecmp(requeststr, md5secret))
07758 break;
07759 }
07760 if (tmppw) {
07761 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07762 } else {
07763 if (authdebug)
07764 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
07765 goto return_unref;
07766 }
07767 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
07768
07769 if (strcmp(secret, p->secret)) {
07770 if (authdebug)
07771 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07772 goto return_unref;
07773 } else
07774 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07775 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
07776
07777 goto return_unref;
07778 }
07779 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
07780
07781
07782 res = 0;
07783
07784 return_unref:
07785 if (iaxs[callno]) {
07786 ast_string_field_set(iaxs[callno], peer, peer);
07787
07788
07789 if (expire && (expire < iaxs[callno]->expiry)) {
07790 iaxs[callno]->expiry = expire;
07791 }
07792 }
07793
07794 if (p) {
07795 peer_unref(p);
07796 }
07797 return res;
07798 }
07799
07800 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)
07801 {
07802 int res = -1;
07803 int x;
07804 if (!ast_strlen_zero(keyn)) {
07805 if (!(authmethods & IAX_AUTH_RSA)) {
07806 if (ast_strlen_zero(secret))
07807 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));
07808 } else if (ast_strlen_zero(challenge)) {
07809 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
07810 } else {
07811 char sig[256];
07812 struct ast_key *key;
07813 key = ast_key_get(keyn, AST_KEY_PRIVATE);
07814 if (!key) {
07815 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
07816 } else {
07817 if (ast_sign(key, (char*)challenge, sig)) {
07818 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
07819 res = -1;
07820 } else {
07821 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
07822 res = 0;
07823 }
07824 }
07825 }
07826 }
07827
07828 if (res && !ast_strlen_zero(secret)) {
07829 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
07830 struct MD5Context md5;
07831 unsigned char digest[16];
07832 char digres[128];
07833 MD5Init(&md5);
07834 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
07835 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
07836 MD5Final(digest, &md5);
07837
07838 for (x=0;x<16;x++)
07839 sprintf(digres + (x << 1), "%2.2x", digest[x]);
07840 if (pvt) {
07841 build_encryption_keys(digest, pvt);
07842 }
07843 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
07844 res = 0;
07845 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
07846 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
07847 res = 0;
07848 } else
07849 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
07850 }
07851 return res;
07852 }
07853
07854
07855
07856
07857
07858 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
07859 {
07860 struct iax2_peer *peer = NULL;
07861
07862 int res = -1;
07863 int authmethods = 0;
07864 struct iax_ie_data ied;
07865 uint16_t callno = p->callno;
07866
07867 memset(&ied, 0, sizeof(ied));
07868
07869 if (ies->username)
07870 ast_string_field_set(p, username, ies->username);
07871 if (ies->challenge)
07872 ast_string_field_set(p, challenge, ies->challenge);
07873 if (ies->authmethods)
07874 authmethods = ies->authmethods;
07875 if (authmethods & IAX_AUTH_MD5)
07876 merge_encryption(p, ies->encmethods);
07877 else
07878 p->encmethods = 0;
07879
07880
07881 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
07882
07883 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
07884 } else {
07885 struct ao2_iterator i = ao2_iterator_init(peers, 0);
07886 while ((peer = ao2_iterator_next(&i))) {
07887 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
07888
07889 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
07890
07891 && (!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)))
07892
07893 ) {
07894 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
07895 if (!res) {
07896 peer_unref(peer);
07897 break;
07898 }
07899 }
07900 peer_unref(peer);
07901 }
07902 ao2_iterator_destroy(&i);
07903 if (!peer) {
07904
07905
07906 const char *peer_name = ast_strdupa(p->peer);
07907 ast_mutex_unlock(&iaxsl[callno]);
07908 if ((peer = realtime_peer(peer_name, NULL))) {
07909 ast_mutex_lock(&iaxsl[callno]);
07910 if (!(p = iaxs[callno])) {
07911 peer_unref(peer);
07912 return -1;
07913 }
07914 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
07915 peer_unref(peer);
07916 }
07917 if (!peer) {
07918 ast_mutex_lock(&iaxsl[callno]);
07919 if (!(p = iaxs[callno]))
07920 return -1;
07921 }
07922 }
07923 }
07924
07925 if (ies->encmethods) {
07926 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
07927 } else if (ast_test_flag(iaxs[callno], IAX_FORCE_ENCRYPT)) {
07928 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
07929 return -1;
07930 }
07931 if (!res) {
07932 struct ast_datastore *variablestore;
07933 struct ast_variable *var, *prev = NULL;
07934 AST_LIST_HEAD(, ast_var_t) *varlist;
07935 varlist = ast_calloc(1, sizeof(*varlist));
07936 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
07937 if (variablestore && varlist && p->owner) {
07938 variablestore->data = varlist;
07939 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
07940 AST_LIST_HEAD_INIT(varlist);
07941 for (var = ies->vars; var; var = var->next) {
07942 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
07943 if (prev)
07944 ast_free(prev);
07945 prev = var;
07946 if (!newvar) {
07947
07948 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07949 } else {
07950 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
07951 }
07952 }
07953 if (prev)
07954 ast_free(prev);
07955 ies->vars = NULL;
07956 ast_channel_datastore_add(p->owner, variablestore);
07957 } else {
07958 if (p->owner)
07959 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07960 if (variablestore)
07961 ast_datastore_free(variablestore);
07962 if (varlist)
07963 ast_free(varlist);
07964 }
07965 }
07966
07967 if (!res)
07968 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
07969 return res;
07970 }
07971
07972 static int iax2_do_register(struct iax2_registry *reg);
07973
07974 static void __iax2_do_register_s(const void *data)
07975 {
07976 struct iax2_registry *reg = (struct iax2_registry *)data;
07977 reg->expire = -1;
07978 iax2_do_register(reg);
07979 }
07980
07981 static int iax2_do_register_s(const void *data)
07982 {
07983 #ifdef SCHED_MULTITHREADED
07984 if (schedule_action(__iax2_do_register_s, data))
07985 #endif
07986 __iax2_do_register_s(data);
07987 return 0;
07988 }
07989
07990 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07991 {
07992 int newcall = 0;
07993 char newip[256];
07994 struct iax_ie_data ied;
07995 struct sockaddr_in new;
07996
07997
07998 memset(&ied, 0, sizeof(ied));
07999 if (ies->apparent_addr)
08000 memmove(&new, ies->apparent_addr, sizeof(new));
08001 if (ies->callno)
08002 newcall = ies->callno;
08003 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08004 ast_log(LOG_WARNING, "Invalid transfer request\n");
08005 return -1;
08006 }
08007 pvt->transfercallno = newcall;
08008 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08009 inet_aton(newip, &pvt->transfer.sin_addr);
08010 pvt->transfer.sin_family = AF_INET;
08011 pvt->transferid = ies->transferid;
08012
08013
08014 if (pvt->transferring == TRANSFER_NONE) {
08015 store_by_transfercallno(pvt);
08016 }
08017 pvt->transferring = TRANSFER_BEGIN;
08018
08019 if (ies->transferid)
08020 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08021 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08022 return 0;
08023 }
08024
08025 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08026 {
08027 char exten[256] = "";
08028 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08029 struct iax2_dpcache *dp = NULL;
08030
08031 if (ies->called_number)
08032 ast_copy_string(exten, ies->called_number, sizeof(exten));
08033
08034 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08035 status = CACHE_FLAG_EXISTS;
08036 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08037 status = CACHE_FLAG_CANEXIST;
08038 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08039 status = CACHE_FLAG_NONEXISTENT;
08040
08041 if (ies->refresh)
08042 expiry = ies->refresh;
08043 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08044 matchmore = CACHE_FLAG_MATCHMORE;
08045
08046 AST_LIST_LOCK(&dpcache);
08047 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08048 if (strcmp(dp->exten, exten))
08049 continue;
08050 AST_LIST_REMOVE_CURRENT(peer_list);
08051 dp->callno = 0;
08052 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08053 if (dp->flags & CACHE_FLAG_PENDING) {
08054 dp->flags &= ~CACHE_FLAG_PENDING;
08055 dp->flags |= status;
08056 dp->flags |= matchmore;
08057 }
08058
08059 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08060 if (dp->waiters[x] > -1) {
08061 if (write(dp->waiters[x], "asdf", 4) < 0) {
08062 }
08063 }
08064 }
08065 }
08066 AST_LIST_TRAVERSE_SAFE_END;
08067 AST_LIST_UNLOCK(&dpcache);
08068
08069 return 0;
08070 }
08071
08072 static int complete_transfer(int callno, struct iax_ies *ies)
08073 {
08074 int peercallno = 0;
08075 struct chan_iax2_pvt *pvt = iaxs[callno];
08076 struct iax_frame *cur;
08077 jb_frame frame;
08078
08079 if (ies->callno)
08080 peercallno = ies->callno;
08081
08082 if (peercallno < 1) {
08083 ast_log(LOG_WARNING, "Invalid transfer request\n");
08084 return -1;
08085 }
08086 remove_by_transfercallno(pvt);
08087
08088
08089
08090 peercnt_remove_by_addr(&pvt->addr);
08091 peercnt_add(&pvt->transfer);
08092
08093 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08094 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08095
08096 pvt->oseqno = 0;
08097 pvt->rseqno = 0;
08098 pvt->iseqno = 0;
08099 pvt->aseqno = 0;
08100
08101 if (pvt->peercallno) {
08102 remove_by_peercallno(pvt);
08103 }
08104 pvt->peercallno = peercallno;
08105
08106 store_by_peercallno(pvt);
08107 pvt->transferring = TRANSFER_NONE;
08108 pvt->svoiceformat = -1;
08109 pvt->voiceformat = 0;
08110 pvt->svideoformat = -1;
08111 pvt->videoformat = 0;
08112 pvt->transfercallno = 0;
08113 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08114 memset(&pvt->offset, 0, sizeof(pvt->offset));
08115
08116 while(jb_getall(pvt->jb,&frame) == JB_OK)
08117 iax2_frame_free(frame.data);
08118 jb_reset(pvt->jb);
08119 pvt->lag = 0;
08120 pvt->last = 0;
08121 pvt->lastsent = 0;
08122 pvt->nextpred = 0;
08123 pvt->pingtime = DEFAULT_RETRY_TIME;
08124 AST_LIST_LOCK(&frame_queue);
08125 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08126
08127
08128
08129 if (callno == cur->callno)
08130 cur->retries = -1;
08131 }
08132 AST_LIST_UNLOCK(&frame_queue);
08133 return 0;
08134 }
08135
08136
08137 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08138 {
08139 struct iax2_registry *reg;
08140
08141 char peer[256] = "";
08142 char msgstatus[60];
08143 int refresh = 60;
08144 char ourip[256] = "<Unspecified>";
08145 struct sockaddr_in oldus;
08146 struct sockaddr_in us;
08147 int oldmsgs;
08148
08149 memset(&us, 0, sizeof(us));
08150 if (ies->apparent_addr)
08151 memmove(&us, ies->apparent_addr, sizeof(us));
08152 if (ies->username)
08153 ast_copy_string(peer, ies->username, sizeof(peer));
08154 if (ies->refresh)
08155 refresh = ies->refresh;
08156 if (ies->calling_number) {
08157
08158 }
08159 reg = iaxs[callno]->reg;
08160 if (!reg) {
08161 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08162 return -1;
08163 }
08164 memcpy(&oldus, ®->us, sizeof(oldus));
08165 oldmsgs = reg->messages;
08166 if (inaddrcmp(®->addr, sin)) {
08167 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08168 return -1;
08169 }
08170 memcpy(®->us, &us, sizeof(reg->us));
08171 if (ies->msgcount >= 0)
08172 reg->messages = ies->msgcount & 0xffff;
08173
08174
08175
08176 reg->refresh = refresh;
08177 reg->expire = iax2_sched_replace(reg->expire, sched,
08178 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08179 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08180 if (reg->messages > 255)
08181 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08182 else if (reg->messages > 1)
08183 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
08184 else if (reg->messages > 0)
08185 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
08186 else
08187 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
08188 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08189 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08190 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08191 }
08192 reg->regstate = REG_STATE_REGISTERED;
08193 return 0;
08194 }
08195
08196 static int iax2_append_register(const char *hostname, const char *username,
08197 const char *secret, const char *porta)
08198 {
08199 struct iax2_registry *reg;
08200
08201 if (!(reg = ast_calloc(1, sizeof(*reg))))
08202 return -1;
08203
08204 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08205 ast_free(reg);
08206 return -1;
08207 }
08208
08209 ast_copy_string(reg->username, username, sizeof(reg->username));
08210
08211 if (secret)
08212 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08213
08214 reg->expire = -1;
08215 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08216 reg->addr.sin_family = AF_INET;
08217 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
08218
08219 AST_LIST_LOCK(®istrations);
08220 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08221 AST_LIST_UNLOCK(®istrations);
08222
08223 return 0;
08224 }
08225
08226 static int iax2_register(const char *value, int lineno)
08227 {
08228 char copy[256];
08229 char *username, *hostname, *secret;
08230 char *porta;
08231 char *stringp=NULL;
08232
08233 if (!value)
08234 return -1;
08235
08236 ast_copy_string(copy, value, sizeof(copy));
08237 stringp = copy;
08238 username = strsep(&stringp, "@");
08239 hostname = strsep(&stringp, "@");
08240
08241 if (!hostname) {
08242 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08243 return -1;
08244 }
08245
08246 stringp = username;
08247 username = strsep(&stringp, ":");
08248 secret = strsep(&stringp, ":");
08249 stringp = hostname;
08250 hostname = strsep(&stringp, ":");
08251 porta = strsep(&stringp, ":");
08252
08253 if (porta && !atoi(porta)) {
08254 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08255 return -1;
08256 }
08257
08258 return iax2_append_register(hostname, username, secret, porta);
08259 }
08260
08261
08262 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08263 {
08264 char multi[256];
08265 char *stringp, *ext;
08266 if (!ast_strlen_zero(regcontext)) {
08267 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08268 stringp = multi;
08269 while((ext = strsep(&stringp, "&"))) {
08270 if (onoff) {
08271 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08272 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08273 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08274 } else
08275 ast_context_remove_extension(regcontext, ext, 1, NULL);
08276 }
08277 }
08278 }
08279 static void prune_peers(void);
08280
08281 static void unlink_peer(struct iax2_peer *peer)
08282 {
08283 if (peer->expire > -1) {
08284 if (!ast_sched_thread_del(sched, peer->expire)) {
08285 peer->expire = -1;
08286 peer_unref(peer);
08287 }
08288 }
08289
08290 if (peer->pokeexpire > -1) {
08291 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08292 peer->pokeexpire = -1;
08293 peer_unref(peer);
08294 }
08295 }
08296
08297 ao2_unlink(peers, peer);
08298 }
08299
08300 static void __expire_registry(const void *data)
08301 {
08302 struct iax2_peer *peer = (struct iax2_peer *) data;
08303
08304 if (!peer)
08305 return;
08306
08307 peer->expire = -1;
08308
08309 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08310 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08311 realtime_update_peer(peer->name, &peer->addr, 0);
08312 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08313
08314 peercnt_modify(0, 0, &peer->addr);
08315
08316 memset(&peer->addr, 0, sizeof(peer->addr));
08317
08318 peer->expiry = min_reg_expire;
08319 if (!ast_test_flag(peer, IAX_TEMPONLY))
08320 ast_db_del("IAX/Registry", peer->name);
08321 register_peer_exten(peer, 0);
08322 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08323 if (iax2_regfunk)
08324 iax2_regfunk(peer->name, 0);
08325
08326 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
08327 unlink_peer(peer);
08328
08329 peer_unref(peer);
08330 }
08331
08332 static int expire_registry(const void *data)
08333 {
08334 #ifdef SCHED_MULTITHREADED
08335 if (schedule_action(__expire_registry, data))
08336 #endif
08337 __expire_registry(data);
08338 return 0;
08339 }
08340
08341 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08342
08343 static void reg_source_db(struct iax2_peer *p)
08344 {
08345 char data[80];
08346 struct in_addr in;
08347 char *c, *d;
08348 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
08349 c = strchr(data, ':');
08350 if (c) {
08351 *c = '\0';
08352 c++;
08353 if (inet_aton(data, &in)) {
08354 d = strchr(c, ':');
08355 if (d) {
08356 *d = '\0';
08357 d++;
08358 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
08359 ast_inet_ntoa(in), atoi(c), atoi(d));
08360 iax2_poke_peer(p, 0);
08361 p->expiry = atoi(d);
08362 memset(&p->addr, 0, sizeof(p->addr));
08363 p->addr.sin_family = AF_INET;
08364 p->addr.sin_addr = in;
08365 p->addr.sin_port = htons(atoi(c));
08366 if (p->expire > -1) {
08367 if (!ast_sched_thread_del(sched, p->expire)) {
08368 p->expire = -1;
08369 peer_unref(p);
08370 }
08371 }
08372 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08373 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08374 if (p->expire == -1)
08375 peer_unref(p);
08376 if (iax2_regfunk)
08377 iax2_regfunk(p->name, 1);
08378 register_peer_exten(p, 1);
08379 }
08380
08381 }
08382 }
08383 }
08384 }
08385
08386
08387
08388
08389
08390
08391
08392 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08393 {
08394
08395 struct iax_ie_data ied;
08396 struct iax2_peer *p;
08397 int msgcount;
08398 char data[80];
08399 int version;
08400 const char *peer_name;
08401 int res = -1;
08402
08403 memset(&ied, 0, sizeof(ied));
08404
08405 peer_name = ast_strdupa(iaxs[callno]->peer);
08406
08407
08408 ast_mutex_unlock(&iaxsl[callno]);
08409 if (!(p = find_peer(peer_name, 1))) {
08410 ast_mutex_lock(&iaxsl[callno]);
08411 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08412 return -1;
08413 }
08414 ast_mutex_lock(&iaxsl[callno]);
08415 if (!iaxs[callno])
08416 goto return_unref;
08417
08418 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08419 if (sin->sin_addr.s_addr) {
08420 time_t nowtime;
08421 time(&nowtime);
08422 realtime_update_peer(peer_name, sin, nowtime);
08423 } else {
08424 realtime_update_peer(peer_name, sin, 0);
08425 }
08426 }
08427 if (inaddrcmp(&p->addr, sin)) {
08428 if (iax2_regfunk)
08429 iax2_regfunk(p->name, 1);
08430
08431
08432 peercnt_modify(0, 0, &p->addr);
08433
08434
08435 memcpy(&p->addr, sin, sizeof(p->addr));
08436
08437 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08438 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08439 ast_db_put("IAX/Registry", p->name, data);
08440 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08441 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08442 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08443 register_peer_exten(p, 1);
08444 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08445 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
08446 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08447 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08448 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08449 register_peer_exten(p, 0);
08450 ast_db_del("IAX/Registry", p->name);
08451 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08452 }
08453
08454
08455 iax2_poke_peer(p, callno);
08456 }
08457
08458
08459 if (p->maxcallno) {
08460 peercnt_modify(1, p->maxcallno, &p->addr);
08461 }
08462
08463
08464 if (!iaxs[callno]) {
08465 res = -1;
08466 goto return_unref;
08467 }
08468
08469
08470 p->sockfd = fd;
08471
08472 if (p->expire > -1) {
08473 if (!ast_sched_thread_del(sched, p->expire)) {
08474 p->expire = -1;
08475 peer_unref(p);
08476 }
08477 }
08478
08479 if (!refresh)
08480 refresh = min_reg_expire;
08481 if (refresh > max_reg_expire) {
08482 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08483 p->name, max_reg_expire, refresh);
08484 p->expiry = max_reg_expire;
08485 } else if (refresh < min_reg_expire) {
08486 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08487 p->name, min_reg_expire, refresh);
08488 p->expiry = min_reg_expire;
08489 } else {
08490 p->expiry = refresh;
08491 }
08492 if (p->expiry && sin->sin_addr.s_addr) {
08493 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08494 if (p->expire == -1)
08495 peer_unref(p);
08496 }
08497 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08498 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08499 if (sin->sin_addr.s_addr) {
08500 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08501 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
08502 if (!ast_strlen_zero(p->mailbox)) {
08503 struct ast_event *event;
08504 int new, old;
08505 char *mailbox, *context;
08506
08507 context = mailbox = ast_strdupa(p->mailbox);
08508 strsep(&context, "@");
08509 if (ast_strlen_zero(context))
08510 context = "default";
08511
08512 event = ast_event_get_cached(AST_EVENT_MWI,
08513 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08514 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08515 AST_EVENT_IE_END);
08516 if (event) {
08517 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08518 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08519 ast_event_destroy(event);
08520 } else {
08521 ast_app_inboxcount(p->mailbox, &new, &old);
08522 }
08523
08524 if (new > 255) {
08525 new = 255;
08526 }
08527 if (old > 255) {
08528 old = 255;
08529 }
08530 msgcount = (old << 8) | new;
08531
08532 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08533 }
08534 if (ast_test_flag(p, IAX_HASCALLERID)) {
08535 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08536 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08537 }
08538 }
08539 version = iax_check_version(devtype);
08540 if (version)
08541 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08542
08543 res = 0;
08544
08545 return_unref:
08546 peer_unref(p);
08547
08548 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08549 }
08550
08551 static int registry_authrequest(int callno)
08552 {
08553 struct iax_ie_data ied;
08554 struct iax2_peer *p;
08555 char challenge[10];
08556 const char *peer_name;
08557 int sentauthmethod;
08558
08559 peer_name = ast_strdupa(iaxs[callno]->peer);
08560
08561
08562 ast_mutex_unlock(&iaxsl[callno]);
08563 if ((p = find_peer(peer_name, 1))) {
08564 last_authmethod = p->authmethods;
08565 }
08566
08567 ast_mutex_lock(&iaxsl[callno]);
08568 if (!iaxs[callno])
08569 goto return_unref;
08570
08571 memset(&ied, 0, sizeof(ied));
08572
08573
08574
08575
08576
08577
08578 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08579 if (!p) {
08580 iaxs[callno]->authmethods = sentauthmethod;
08581 }
08582 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08583 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08584
08585 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08586 ast_string_field_set(iaxs[callno], challenge, challenge);
08587 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08588 }
08589 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08590
08591 return_unref:
08592 if (p) {
08593 peer_unref(p);
08594 }
08595
08596 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08597 }
08598
08599 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08600 {
08601 struct iax2_registry *reg;
08602
08603 struct iax_ie_data ied;
08604 char peer[256] = "";
08605 char challenge[256] = "";
08606 int res;
08607 int authmethods = 0;
08608 if (ies->authmethods)
08609 authmethods = ies->authmethods;
08610 if (ies->username)
08611 ast_copy_string(peer, ies->username, sizeof(peer));
08612 if (ies->challenge)
08613 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08614 memset(&ied, 0, sizeof(ied));
08615 reg = iaxs[callno]->reg;
08616 if (reg) {
08617 if (inaddrcmp(®->addr, sin)) {
08618 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08619 return -1;
08620 }
08621 if (ast_strlen_zero(reg->secret)) {
08622 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08623 reg->regstate = REG_STATE_NOAUTH;
08624 return -1;
08625 }
08626 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08627 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08628 if (reg->secret[0] == '[') {
08629 char tmpkey[256];
08630 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08631 tmpkey[strlen(tmpkey) - 1] = '\0';
08632 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08633 } else
08634 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08635 if (!res) {
08636 reg->regstate = REG_STATE_AUTHSENT;
08637 add_empty_calltoken_ie(iaxs[callno], &ied);
08638 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08639 } else
08640 return -1;
08641 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08642 } else
08643 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08644 return -1;
08645 }
08646
08647 static void stop_stuff(int callno)
08648 {
08649 iax2_destroy_helper(iaxs[callno]);
08650 }
08651
08652 static void __auth_reject(const void *nothing)
08653 {
08654
08655 int callno = (int)(long)(nothing);
08656 struct iax_ie_data ied;
08657 ast_mutex_lock(&iaxsl[callno]);
08658 if (iaxs[callno]) {
08659 memset(&ied, 0, sizeof(ied));
08660 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08661 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08662 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08663 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08664 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08665 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08666 }
08667 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08668 }
08669 ast_mutex_unlock(&iaxsl[callno]);
08670 }
08671
08672 static int auth_reject(const void *data)
08673 {
08674 int callno = (int)(long)(data);
08675 ast_mutex_lock(&iaxsl[callno]);
08676 if (iaxs[callno])
08677 iaxs[callno]->authid = -1;
08678 ast_mutex_unlock(&iaxsl[callno]);
08679 #ifdef SCHED_MULTITHREADED
08680 if (schedule_action(__auth_reject, data))
08681 #endif
08682 __auth_reject(data);
08683 return 0;
08684 }
08685
08686 static int auth_fail(int callno, int failcode)
08687 {
08688
08689
08690 if (iaxs[callno]) {
08691 iaxs[callno]->authfail = failcode;
08692 if (delayreject) {
08693 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08694 sched, 1000, auth_reject, (void *)(long)callno);
08695 } else
08696 auth_reject((void *)(long)callno);
08697 }
08698 return 0;
08699 }
08700
08701 static void __auto_hangup(const void *nothing)
08702 {
08703
08704 int callno = (int)(long)(nothing);
08705 struct iax_ie_data ied;
08706 ast_mutex_lock(&iaxsl[callno]);
08707 if (iaxs[callno]) {
08708 memset(&ied, 0, sizeof(ied));
08709 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08710 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
08711 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
08712 }
08713 ast_mutex_unlock(&iaxsl[callno]);
08714 }
08715
08716 static int auto_hangup(const void *data)
08717 {
08718 int callno = (int)(long)(data);
08719 ast_mutex_lock(&iaxsl[callno]);
08720 if (iaxs[callno]) {
08721 iaxs[callno]->autoid = -1;
08722 }
08723 ast_mutex_unlock(&iaxsl[callno]);
08724 #ifdef SCHED_MULTITHREADED
08725 if (schedule_action(__auto_hangup, data))
08726 #endif
08727 __auto_hangup(data);
08728 return 0;
08729 }
08730
08731 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
08732 {
08733 struct iax_ie_data ied;
08734
08735 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
08736 sched, 30000, auto_hangup, (void *)(long)callno);
08737 memset(&ied, 0, sizeof(ied));
08738 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
08739 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
08740 dp->flags |= CACHE_FLAG_TRANSMITTED;
08741 }
08742
08743 static int iax2_vnak(int callno)
08744 {
08745 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
08746 }
08747
08748 static void vnak_retransmit(int callno, int last)
08749 {
08750 struct iax_frame *f;
08751
08752 AST_LIST_LOCK(&frame_queue);
08753 AST_LIST_TRAVERSE(&frame_queue, f, list) {
08754
08755 if ((f->callno == callno) && iaxs[f->callno] &&
08756 ((unsigned char ) (f->oseqno - last) < 128) &&
08757 (f->retries >= 0)) {
08758 send_packet(f);
08759 }
08760 }
08761 AST_LIST_UNLOCK(&frame_queue);
08762 }
08763
08764 static void __iax2_poke_peer_s(const void *data)
08765 {
08766 struct iax2_peer *peer = (struct iax2_peer *)data;
08767 iax2_poke_peer(peer, 0);
08768 peer_unref(peer);
08769 }
08770
08771 static int iax2_poke_peer_s(const void *data)
08772 {
08773 struct iax2_peer *peer = (struct iax2_peer *)data;
08774 peer->pokeexpire = -1;
08775 #ifdef SCHED_MULTITHREADED
08776 if (schedule_action(__iax2_poke_peer_s, data))
08777 #endif
08778 __iax2_poke_peer_s(data);
08779 return 0;
08780 }
08781
08782 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
08783 {
08784 int res = 0;
08785 struct iax_frame *fr;
08786 struct ast_iax2_meta_hdr *meta;
08787 struct ast_iax2_meta_trunk_hdr *mth;
08788 int calls = 0;
08789
08790
08791 fr = (struct iax_frame *)tpeer->trunkdata;
08792
08793 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
08794 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
08795 if (tpeer->trunkdatalen) {
08796
08797 meta->zeros = 0;
08798 meta->metacmd = IAX_META_TRUNK;
08799 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
08800 meta->cmddata = IAX_META_TRUNK_MINI;
08801 else
08802 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
08803 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
08804
08805 fr->direction = DIRECTION_OUTGRESS;
08806 fr->retrans = -1;
08807 fr->transfer = 0;
08808
08809 fr->data = fr->afdata;
08810 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
08811 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
08812 calls = tpeer->calls;
08813 #if 0
08814 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));
08815 #endif
08816
08817 tpeer->trunkdatalen = 0;
08818 tpeer->calls = 0;
08819 }
08820 if (res < 0)
08821 return res;
08822 return calls;
08823 }
08824
08825 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
08826 {
08827
08828 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
08829 return 1;
08830 return 0;
08831 }
08832
08833 static int timing_read(int *id, int fd, short events, void *cbdata)
08834 {
08835 int res, processed = 0, totalcalls = 0;
08836 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
08837 struct timeval now = ast_tvnow();
08838
08839 if (iaxtrunkdebug)
08840 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
08841
08842 if (timer) {
08843 ast_timer_ack(timer, 1);
08844 }
08845
08846
08847 AST_LIST_LOCK(&tpeers);
08848 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
08849 processed++;
08850 res = 0;
08851 ast_mutex_lock(&tpeer->lock);
08852
08853
08854 if (!drop && iax2_trunk_expired(tpeer, &now)) {
08855
08856
08857 AST_LIST_REMOVE_CURRENT(list);
08858 drop = tpeer;
08859 } else {
08860 res = send_trunk(tpeer, &now);
08861 trunk_timed++;
08862 if (iaxtrunkdebug)
08863 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);
08864 }
08865 totalcalls += res;
08866 res = 0;
08867 ast_mutex_unlock(&tpeer->lock);
08868 }
08869 AST_LIST_TRAVERSE_SAFE_END;
08870 AST_LIST_UNLOCK(&tpeers);
08871
08872 if (drop) {
08873 ast_mutex_lock(&drop->lock);
08874
08875
08876 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
08877 if (drop->trunkdata) {
08878 ast_free(drop->trunkdata);
08879 drop->trunkdata = NULL;
08880 }
08881 ast_mutex_unlock(&drop->lock);
08882 ast_mutex_destroy(&drop->lock);
08883 ast_free(drop);
08884
08885 }
08886
08887 if (iaxtrunkdebug)
08888 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
08889 iaxtrunkdebug = 0;
08890
08891 return 1;
08892 }
08893
08894 struct dpreq_data {
08895 int callno;
08896 char context[AST_MAX_EXTENSION];
08897 char callednum[AST_MAX_EXTENSION];
08898 char *callerid;
08899 };
08900
08901 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
08902 {
08903 unsigned short dpstatus = 0;
08904 struct iax_ie_data ied1;
08905 int mm;
08906
08907 memset(&ied1, 0, sizeof(ied1));
08908 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
08909
08910 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
08911 dpstatus = IAX_DPSTATUS_EXISTS;
08912 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
08913 dpstatus = IAX_DPSTATUS_CANEXIST;
08914 } else {
08915 dpstatus = IAX_DPSTATUS_NONEXISTENT;
08916 }
08917 if (ast_ignore_pattern(context, callednum))
08918 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
08919 if (mm)
08920 dpstatus |= IAX_DPSTATUS_MATCHMORE;
08921 if (!skiplock)
08922 ast_mutex_lock(&iaxsl[callno]);
08923 if (iaxs[callno]) {
08924 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
08925 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
08926 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
08927 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
08928 }
08929 if (!skiplock)
08930 ast_mutex_unlock(&iaxsl[callno]);
08931 }
08932
08933 static void *dp_lookup_thread(void *data)
08934 {
08935
08936 struct dpreq_data *dpr = data;
08937 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
08938 if (dpr->callerid)
08939 ast_free(dpr->callerid);
08940 ast_free(dpr);
08941 return NULL;
08942 }
08943
08944 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
08945 {
08946 pthread_t newthread;
08947 struct dpreq_data *dpr;
08948
08949 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
08950 return;
08951
08952 dpr->callno = callno;
08953 ast_copy_string(dpr->context, context, sizeof(dpr->context));
08954 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
08955 if (callerid)
08956 dpr->callerid = ast_strdup(callerid);
08957 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
08958 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
08959 }
08960 }
08961
08962 struct iax_dual {
08963 struct ast_channel *chan1;
08964 struct ast_channel *chan2;
08965 };
08966
08967 static void *iax_park_thread(void *stuff)
08968 {
08969 struct ast_channel *chan1, *chan2;
08970 struct iax_dual *d;
08971 struct ast_frame *f;
08972 int ext;
08973 int res;
08974 d = stuff;
08975 chan1 = d->chan1;
08976 chan2 = d->chan2;
08977 ast_free(d);
08978 f = ast_read(chan1);
08979 if (f)
08980 ast_frfree(f);
08981 res = ast_park_call(chan1, chan2, 0, &ext);
08982 ast_hangup(chan2);
08983 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
08984 return NULL;
08985 }
08986
08987 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
08988 {
08989 struct iax_dual *d;
08990 struct ast_channel *chan1m, *chan2m;
08991 pthread_t th;
08992 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
08993 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
08994 if (chan2m && chan1m) {
08995
08996 chan1m->readformat = chan1->readformat;
08997 chan1m->writeformat = chan1->writeformat;
08998 ast_channel_masquerade(chan1m, chan1);
08999
09000 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09001 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09002 chan1m->priority = chan1->priority;
09003
09004
09005
09006
09007 chan2m->readformat = chan2->readformat;
09008 chan2m->writeformat = chan2->writeformat;
09009 ast_channel_masquerade(chan2m, chan2);
09010
09011 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09012 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09013 chan2m->priority = chan2->priority;
09014 if (ast_do_masquerade(chan2m)) {
09015 ast_log(LOG_WARNING, "Masquerade failed :(\n");
09016 ast_hangup(chan2m);
09017 return -1;
09018 }
09019 } else {
09020 if (chan1m)
09021 ast_hangup(chan1m);
09022 if (chan2m)
09023 ast_hangup(chan2m);
09024 return -1;
09025 }
09026 if ((d = ast_calloc(1, sizeof(*d)))) {
09027 d->chan1 = chan1m;
09028 d->chan2 = chan2m;
09029 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
09030 return 0;
09031 }
09032 ast_free(d);
09033 }
09034 return -1;
09035 }
09036
09037
09038 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
09039
09040 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09041 {
09042 unsigned int ourver;
09043 char rsi[80];
09044 snprintf(rsi, sizeof(rsi), "si-%s", si);
09045 if (iax_provision_version(&ourver, rsi, 1))
09046 return 0;
09047 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09048 if (ourver != ver)
09049 iax2_provision(sin, sockfd, NULL, rsi, 1);
09050 return 0;
09051 }
09052
09053 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09054 {
09055 jb_info stats;
09056 jb_getinfo(pvt->jb, &stats);
09057
09058 memset(iep, 0, sizeof(*iep));
09059
09060 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09061 if(stats.frames_in == 0) stats.frames_in = 1;
09062 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09063 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09064 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09065 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09066 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09067 }
09068
09069 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09070 {
09071 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09072 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09073 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09074 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09075 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09076 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09077 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09078 }
09079
09080 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09081 {
09082 int i;
09083 unsigned int length, offset = 0;
09084 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09085
09086 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09087 length = ies->ospblocklength[i];
09088 if (length != 0) {
09089 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09090
09091 offset = 0;
09092 break;
09093 } else {
09094 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09095 offset += length;
09096 }
09097 } else {
09098 break;
09099 }
09100 }
09101 *(full_osptoken + offset) = '\0';
09102 if (strlen(full_osptoken) != offset) {
09103
09104 *full_osptoken = '\0';
09105 }
09106
09107 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09108 }
09109
09110 static void log_jitterstats(unsigned short callno)
09111 {
09112 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09113 jb_info jbinfo;
09114
09115 ast_mutex_lock(&iaxsl[callno]);
09116 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09117 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
09118 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09119 localjitter = jbinfo.jitter;
09120 localdelay = jbinfo.current - jbinfo.min;
09121 locallost = jbinfo.frames_lost;
09122 locallosspct = jbinfo.losspct/1000;
09123 localdropped = jbinfo.frames_dropped;
09124 localooo = jbinfo.frames_ooo;
09125 localpackets = jbinfo.frames_in;
09126 }
09127 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",
09128 iaxs[callno]->owner->name,
09129 iaxs[callno]->pingtime,
09130 localjitter,
09131 localdelay,
09132 locallost,
09133 locallosspct,
09134 localdropped,
09135 localooo,
09136 localpackets,
09137 iaxs[callno]->remote_rr.jitter,
09138 iaxs[callno]->remote_rr.delay,
09139 iaxs[callno]->remote_rr.losscnt,
09140 iaxs[callno]->remote_rr.losspct/1000,
09141 iaxs[callno]->remote_rr.dropped,
09142 iaxs[callno]->remote_rr.ooo,
09143 iaxs[callno]->remote_rr.packets);
09144 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",
09145 iaxs[callno]->owner->name,
09146 iaxs[callno]->pingtime,
09147 localjitter,
09148 localdelay,
09149 locallost,
09150 locallosspct,
09151 localdropped,
09152 localooo,
09153 localpackets,
09154 iaxs[callno]->remote_rr.jitter,
09155 iaxs[callno]->remote_rr.delay,
09156 iaxs[callno]->remote_rr.losscnt,
09157 iaxs[callno]->remote_rr.losspct/1000,
09158 iaxs[callno]->remote_rr.dropped,
09159 iaxs[callno]->remote_rr.ooo,
09160 iaxs[callno]->remote_rr.packets);
09161 }
09162 ast_mutex_unlock(&iaxsl[callno]);
09163 }
09164
09165 static int socket_process(struct iax2_thread *thread);
09166
09167
09168
09169
09170 static void handle_deferred_full_frames(struct iax2_thread *thread)
09171 {
09172 struct iax2_pkt_buf *pkt_buf;
09173
09174 ast_mutex_lock(&thread->lock);
09175
09176 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09177 ast_mutex_unlock(&thread->lock);
09178
09179 thread->buf = pkt_buf->buf;
09180 thread->buf_len = pkt_buf->len;
09181 thread->buf_size = pkt_buf->len + 1;
09182
09183 socket_process(thread);
09184
09185 thread->buf = NULL;
09186 ast_free(pkt_buf);
09187
09188 ast_mutex_lock(&thread->lock);
09189 }
09190
09191 ast_mutex_unlock(&thread->lock);
09192 }
09193
09194
09195
09196
09197
09198
09199
09200 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09201 {
09202 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09203 struct ast_iax2_full_hdr *fh, *cur_fh;
09204
09205 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09206 return;
09207
09208 pkt_buf->len = from_here->buf_len;
09209 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09210
09211 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09212 ast_mutex_lock(&to_here->lock);
09213 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09214 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09215 if (fh->oseqno < cur_fh->oseqno) {
09216 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09217 break;
09218 }
09219 }
09220 AST_LIST_TRAVERSE_SAFE_END
09221
09222 if (!cur_pkt_buf)
09223 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09224
09225 ast_mutex_unlock(&to_here->lock);
09226 }
09227
09228 static int socket_read(int *id, int fd, short events, void *cbdata)
09229 {
09230 struct iax2_thread *thread;
09231 socklen_t len;
09232 time_t t;
09233 static time_t last_errtime = 0;
09234 struct ast_iax2_full_hdr *fh;
09235
09236 if (!(thread = find_idle_thread())) {
09237 time(&t);
09238 if (t != last_errtime)
09239 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09240 last_errtime = t;
09241 usleep(1);
09242 return 1;
09243 }
09244
09245 len = sizeof(thread->iosin);
09246 thread->iofd = fd;
09247 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09248 thread->buf_size = sizeof(thread->readbuf);
09249 thread->buf = thread->readbuf;
09250 if (thread->buf_len < 0) {
09251 if (errno != ECONNREFUSED && errno != EAGAIN)
09252 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09253 handle_error();
09254 thread->iostate = IAX_IOSTATE_IDLE;
09255 signal_condition(&thread->lock, &thread->cond);
09256 return 1;
09257 }
09258 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09259 thread->iostate = IAX_IOSTATE_IDLE;
09260 signal_condition(&thread->lock, &thread->cond);
09261 return 1;
09262 }
09263
09264
09265
09266
09267 fh = (struct ast_iax2_full_hdr *) thread->buf;
09268 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09269 struct iax2_thread *cur = NULL;
09270 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09271
09272 AST_LIST_LOCK(&active_list);
09273 AST_LIST_TRAVERSE(&active_list, cur, list) {
09274 if ((cur->ffinfo.callno == callno) &&
09275 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09276 break;
09277 }
09278 if (cur) {
09279
09280
09281 defer_full_frame(thread, cur);
09282 AST_LIST_UNLOCK(&active_list);
09283 thread->iostate = IAX_IOSTATE_IDLE;
09284 signal_condition(&thread->lock, &thread->cond);
09285 return 1;
09286 } else {
09287
09288 thread->ffinfo.callno = callno;
09289 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09290 thread->ffinfo.type = fh->type;
09291 thread->ffinfo.csub = fh->csub;
09292 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09293 }
09294 AST_LIST_UNLOCK(&active_list);
09295 }
09296
09297
09298 thread->iostate = IAX_IOSTATE_READY;
09299 #ifdef DEBUG_SCHED_MULTITHREAD
09300 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09301 #endif
09302 signal_condition(&thread->lock, &thread->cond);
09303
09304 return 1;
09305 }
09306
09307 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09308 struct iax_frame *fr)
09309 {
09310 unsigned char metatype;
09311 struct ast_iax2_meta_trunk_mini *mtm;
09312 struct ast_iax2_meta_trunk_hdr *mth;
09313 struct ast_iax2_meta_trunk_entry *mte;
09314 struct iax2_trunk_peer *tpeer;
09315 unsigned int ts;
09316 void *ptr;
09317 struct timeval rxtrunktime;
09318 struct ast_frame f = { 0, };
09319
09320 if (packet_len < sizeof(*meta)) {
09321 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09322 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09323 return 1;
09324 }
09325
09326 if (meta->metacmd != IAX_META_TRUNK)
09327 return 1;
09328
09329 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09330 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09331 (int) (sizeof(*meta) + sizeof(*mth)));
09332 return 1;
09333 }
09334 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09335 ts = ntohl(mth->ts);
09336 metatype = meta->cmddata;
09337 packet_len -= (sizeof(*meta) + sizeof(*mth));
09338 ptr = mth->data;
09339 tpeer = find_tpeer(sin, sockfd);
09340 if (!tpeer) {
09341 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09342 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09343 return 1;
09344 }
09345 tpeer->trunkact = ast_tvnow();
09346 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09347 tpeer->rxtrunktime = tpeer->trunkact;
09348 rxtrunktime = tpeer->rxtrunktime;
09349 ast_mutex_unlock(&tpeer->lock);
09350 while (packet_len >= sizeof(*mte)) {
09351
09352 unsigned short callno, trunked_ts, len;
09353
09354 if (metatype == IAX_META_TRUNK_MINI) {
09355 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09356 ptr += sizeof(*mtm);
09357 packet_len -= sizeof(*mtm);
09358 len = ntohs(mtm->len);
09359 callno = ntohs(mtm->mini.callno);
09360 trunked_ts = ntohs(mtm->mini.ts);
09361 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09362 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09363 ptr += sizeof(*mte);
09364 packet_len -= sizeof(*mte);
09365 len = ntohs(mte->len);
09366 callno = ntohs(mte->callno);
09367 trunked_ts = 0;
09368 } else {
09369 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09370 break;
09371 }
09372
09373 if (len > packet_len)
09374 break;
09375 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09376 if (!fr->callno)
09377 continue;
09378
09379
09380
09381
09382 memset(&f, 0, sizeof(f));
09383 f.frametype = AST_FRAME_VOICE;
09384 if (!iaxs[fr->callno]) {
09385
09386 } else if (iaxs[fr->callno]->voiceformat == 0) {
09387 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09388 iax2_vnak(fr->callno);
09389 } else {
09390 f.subclass = iaxs[fr->callno]->voiceformat;
09391 f.datalen = len;
09392 if (f.datalen >= 0) {
09393 if (f.datalen)
09394 f.data.ptr = ptr;
09395 else
09396 f.data.ptr = NULL;
09397 if (trunked_ts)
09398 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09399 else
09400 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09401
09402 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09403 struct iax_frame *duped_fr;
09404
09405
09406 f.src = "IAX2";
09407 f.mallocd = 0;
09408 f.offset = 0;
09409 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09410 f.samples = ast_codec_get_samples(&f);
09411 else
09412 f.samples = 0;
09413 fr->outoforder = 0;
09414 iax_frame_wrap(fr, &f);
09415 duped_fr = iaxfrdup2(fr);
09416 if (duped_fr)
09417 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09418 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09419 iaxs[fr->callno]->last = fr->ts;
09420 }
09421 } else {
09422 ast_log(LOG_WARNING, "Datalen < 0?\n");
09423 }
09424 }
09425 ast_mutex_unlock(&iaxsl[fr->callno]);
09426 ptr += len;
09427 packet_len -= len;
09428 }
09429
09430 return 1;
09431 }
09432
09433 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09434 {
09435 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09436 AST_LIST_HEAD(, ast_var_t) *varlist;
09437 struct ast_var_t *var;
09438
09439 if (!variablestore) {
09440 *buf = '\0';
09441 return 0;
09442 }
09443 varlist = variablestore->data;
09444
09445 AST_LIST_LOCK(varlist);
09446 AST_LIST_TRAVERSE(varlist, var, entries) {
09447 if (strcmp(var->name, data) == 0) {
09448 ast_copy_string(buf, var->value, len);
09449 break;
09450 }
09451 }
09452 AST_LIST_UNLOCK(varlist);
09453 return 0;
09454 }
09455
09456 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09457 {
09458 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09459 AST_LIST_HEAD(, ast_var_t) *varlist;
09460 struct ast_var_t *var;
09461
09462 if (!variablestore) {
09463 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09464 if (!variablestore) {
09465 ast_log(LOG_ERROR, "Memory allocation error\n");
09466 return -1;
09467 }
09468 varlist = ast_calloc(1, sizeof(*varlist));
09469 if (!varlist) {
09470 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09471 return -1;
09472 }
09473
09474 AST_LIST_HEAD_INIT(varlist);
09475 variablestore->data = varlist;
09476 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09477 ast_channel_datastore_add(chan, variablestore);
09478 } else
09479 varlist = variablestore->data;
09480
09481 AST_LIST_LOCK(varlist);
09482 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09483 if (strcmp(var->name, data) == 0) {
09484 AST_LIST_REMOVE_CURRENT(entries);
09485 ast_var_delete(var);
09486 break;
09487 }
09488 }
09489 AST_LIST_TRAVERSE_SAFE_END;
09490 var = ast_var_assign(data, value);
09491 if (var)
09492 AST_LIST_INSERT_TAIL(varlist, var, entries);
09493 else
09494 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09495 AST_LIST_UNLOCK(varlist);
09496 return 0;
09497 }
09498
09499 static struct ast_custom_function iaxvar_function = {
09500 .name = "IAXVAR",
09501 .read = acf_iaxvar_read,
09502 .write = acf_iaxvar_write,
09503 };
09504
09505 static int socket_process(struct iax2_thread *thread)
09506 {
09507 struct sockaddr_in sin;
09508 int res;
09509 int updatehistory=1;
09510 int new = NEW_PREVENT;
09511 int dcallno = 0;
09512 char decrypted = 0;
09513 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09514 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09515 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09516 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09517 struct iax_frame *fr;
09518 struct iax_frame *cur;
09519 struct ast_frame f = { 0, };
09520 struct ast_channel *c = NULL;
09521 struct iax2_dpcache *dp;
09522 struct iax2_peer *peer;
09523 struct iax_ies ies;
09524 struct iax_ie_data ied0, ied1;
09525 int format;
09526 int fd;
09527 int exists;
09528 int minivid = 0;
09529 char empty[32]="";
09530 struct iax_frame *duped_fr;
09531 char host_pref_buf[128];
09532 char caller_pref_buf[128];
09533 struct ast_codec_pref pref;
09534 char *using_prefs = "mine";
09535
09536
09537 fr = alloca(sizeof(*fr) + 4096);
09538 memset(fr, 0, sizeof(*fr));
09539 fr->afdatalen = 4096;
09540
09541
09542 res = thread->buf_len;
09543 fd = thread->iofd;
09544 memcpy(&sin, &thread->iosin, sizeof(sin));
09545
09546 if (res < sizeof(*mh)) {
09547 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09548 return 1;
09549 }
09550 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09551 if (res < sizeof(*vh)) {
09552 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));
09553 return 1;
09554 }
09555
09556
09557 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09558 minivid = 1;
09559 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09560 return socket_process_meta(res, meta, &sin, fd, fr);
09561
09562 #ifdef DEBUG_SUPPORT
09563 if (res >= sizeof(*fh))
09564 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09565 #endif
09566 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09567 if (res < sizeof(*fh)) {
09568 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));
09569 return 1;
09570 }
09571
09572
09573 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09574
09575
09576
09577
09578
09579
09580 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09581 ast_mutex_lock(&iaxsl[fr->callno]);
09582 if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
09583 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09584 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09585 ast_mutex_unlock(&iaxsl[fr->callno]);
09586 return 1;
09587 }
09588 decrypted = 1;
09589 }
09590 ast_mutex_unlock(&iaxsl[fr->callno]);
09591 }
09592
09593
09594 f.frametype = fh->type;
09595 if (f.frametype == AST_FRAME_VIDEO) {
09596 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09597 } else {
09598 f.subclass = uncompress_subclass(fh->csub);
09599 }
09600
09601
09602 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
09603
09604 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09605 return 1;
09606 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
09607
09608 return 1;
09609 }
09610
09611 f.datalen = res - sizeof(*fh);
09612 if (f.datalen) {
09613 if (f.frametype == AST_FRAME_IAX) {
09614 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09615 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09616 ast_variables_destroy(ies.vars);
09617 return 1;
09618 }
09619 f.data.ptr = NULL;
09620 f.datalen = 0;
09621 } else {
09622 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09623 memset(&ies, 0, sizeof(ies));
09624 }
09625 } else {
09626 if (f.frametype == AST_FRAME_IAX)
09627 f.data.ptr = NULL;
09628 else
09629 f.data.ptr = empty;
09630 memset(&ies, 0, sizeof(ies));
09631 }
09632
09633 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) {
09634
09635 if (handle_call_token(fh, &ies, &sin, fd)) {
09636 ast_variables_destroy(ies.vars);
09637 return 1;
09638 }
09639
09640 if (ies.calltoken && ies.calltokendata) {
09641
09642
09643
09644
09645 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09646 } else {
09647 new = NEW_ALLOW;
09648 }
09649 }
09650 } else {
09651
09652 f.frametype = AST_FRAME_NULL;
09653 f.subclass = 0;
09654 memset(&ies, 0, sizeof(ies));
09655 }
09656
09657 if (!fr->callno) {
09658 int check_dcallno = 0;
09659
09660
09661
09662
09663
09664
09665
09666
09667
09668 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) {
09669 check_dcallno = 1;
09670 }
09671
09672 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09673 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) {
09674 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09675 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) {
09676 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09677 }
09678 ast_variables_destroy(ies.vars);
09679 return 1;
09680 }
09681 }
09682
09683 if (fr->callno > 0)
09684 ast_mutex_lock(&iaxsl[fr->callno]);
09685
09686 if (!fr->callno || !iaxs[fr->callno]) {
09687
09688
09689 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09690
09691 if (((f.subclass != IAX_COMMAND_INVAL) &&
09692 (f.subclass != IAX_COMMAND_TXCNT) &&
09693 (f.subclass != IAX_COMMAND_TXACC) &&
09694 (f.subclass != IAX_COMMAND_FWDOWNL))||
09695 (f.frametype != AST_FRAME_IAX))
09696 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09697 fd);
09698 }
09699 if (fr->callno > 0)
09700 ast_mutex_unlock(&iaxsl[fr->callno]);
09701 ast_variables_destroy(ies.vars);
09702 return 1;
09703 }
09704 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
09705 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09706 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09707 ast_variables_destroy(ies.vars);
09708 ast_mutex_unlock(&iaxsl[fr->callno]);
09709 return 1;
09710 }
09711 decrypted = 1;
09712 }
09713 #ifdef DEBUG_SUPPORT
09714 if (decrypted) {
09715 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
09716 }
09717 #endif
09718
09719
09720 iaxs[fr->callno]->frames_received++;
09721
09722 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
09723 f.subclass != IAX_COMMAND_TXCNT &&
09724 f.subclass != IAX_COMMAND_TXACC) {
09725 unsigned short new_peercallno;
09726
09727 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
09728 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
09729 if (iaxs[fr->callno]->peercallno) {
09730 remove_by_peercallno(iaxs[fr->callno]);
09731 }
09732 iaxs[fr->callno]->peercallno = new_peercallno;
09733 store_by_peercallno(iaxs[fr->callno]);
09734 }
09735 }
09736 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09737 if (iaxdebug)
09738 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
09739
09740 fr->oseqno = fh->oseqno;
09741 fr->iseqno = fh->iseqno;
09742 fr->ts = ntohl(fh->ts);
09743 #ifdef IAXTESTS
09744 if (test_resync) {
09745 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
09746 fr->ts += test_resync;
09747 }
09748 #endif
09749 #if 0
09750 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
09751 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
09752 (f.subclass == IAX_COMMAND_NEW ||
09753 f.subclass == IAX_COMMAND_AUTHREQ ||
09754 f.subclass == IAX_COMMAND_ACCEPT ||
09755 f.subclass == IAX_COMMAND_REJECT)) ) )
09756 #endif
09757 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
09758 updatehistory = 0;
09759 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
09760 (iaxs[fr->callno]->iseqno ||
09761 ((f.subclass != IAX_COMMAND_TXCNT) &&
09762 (f.subclass != IAX_COMMAND_TXREADY) &&
09763 (f.subclass != IAX_COMMAND_TXREL) &&
09764 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09765 (f.subclass != IAX_COMMAND_TXACC)) ||
09766 (f.frametype != AST_FRAME_IAX))) {
09767 if (
09768 ((f.subclass != IAX_COMMAND_ACK) &&
09769 (f.subclass != IAX_COMMAND_INVAL) &&
09770 (f.subclass != IAX_COMMAND_TXCNT) &&
09771 (f.subclass != IAX_COMMAND_TXREADY) &&
09772 (f.subclass != IAX_COMMAND_TXREL) &&
09773 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09774 (f.subclass != IAX_COMMAND_TXACC) &&
09775 (f.subclass != IAX_COMMAND_VNAK)) ||
09776 (f.frametype != AST_FRAME_IAX)) {
09777
09778 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
09779 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
09780
09781
09782 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
09783
09784 if ((f.frametype != AST_FRAME_IAX) ||
09785 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
09786 ast_debug(1, "Acking anyway\n");
09787
09788
09789 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09790 }
09791 } else {
09792
09793 iax2_vnak(fr->callno);
09794 }
09795 ast_variables_destroy(ies.vars);
09796 ast_mutex_unlock(&iaxsl[fr->callno]);
09797 return 1;
09798 }
09799 } else {
09800
09801 if (((f.subclass != IAX_COMMAND_ACK) &&
09802 (f.subclass != IAX_COMMAND_INVAL) &&
09803 (f.subclass != IAX_COMMAND_TXCNT) &&
09804 (f.subclass != IAX_COMMAND_TXACC) &&
09805 (f.subclass != IAX_COMMAND_VNAK)) ||
09806 (f.frametype != AST_FRAME_IAX))
09807 iaxs[fr->callno]->iseqno++;
09808 }
09809
09810 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
09811 if (res < thread->buf_size)
09812 thread->buf[res++] = '\0';
09813 else
09814 thread->buf[res - 1] = '\0';
09815 }
09816
09817
09818
09819 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09820 ((f.subclass != IAX_COMMAND_INVAL) ||
09821 (f.frametype != AST_FRAME_IAX))) {
09822 unsigned char x;
09823 int call_to_destroy;
09824
09825 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
09826 x = fr->iseqno;
09827 else
09828 x = iaxs[fr->callno]->oseqno;
09829 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
09830
09831
09832 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
09833
09834 if (iaxdebug)
09835 ast_debug(1, "Cancelling transmission of packet %d\n", x);
09836 call_to_destroy = 0;
09837 AST_LIST_LOCK(&frame_queue);
09838 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09839
09840 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
09841 cur->retries = -1;
09842
09843 if (cur->final)
09844 call_to_destroy = fr->callno;
09845 }
09846 }
09847 AST_LIST_UNLOCK(&frame_queue);
09848 if (call_to_destroy) {
09849 if (iaxdebug)
09850 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
09851 ast_mutex_lock(&iaxsl[call_to_destroy]);
09852 iax2_destroy(call_to_destroy);
09853 ast_mutex_unlock(&iaxsl[call_to_destroy]);
09854 }
09855 }
09856
09857 if (iaxs[fr->callno])
09858 iaxs[fr->callno]->rseqno = fr->iseqno;
09859 else {
09860
09861 ast_variables_destroy(ies.vars);
09862 ast_mutex_unlock(&iaxsl[fr->callno]);
09863 return 1;
09864 }
09865 } else {
09866 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
09867 }
09868 }
09869 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09870 ((f.frametype != AST_FRAME_IAX) ||
09871 ((f.subclass != IAX_COMMAND_TXACC) &&
09872 (f.subclass != IAX_COMMAND_TXCNT)))) {
09873
09874 ast_variables_destroy(ies.vars);
09875 ast_mutex_unlock(&iaxsl[fr->callno]);
09876 return 1;
09877 }
09878
09879
09880
09881
09882 if ((f.frametype == AST_FRAME_VOICE) ||
09883 (f.frametype == AST_FRAME_VIDEO) ||
09884 (f.frametype == AST_FRAME_IAX)) {
09885 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
09886 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
09887 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
09888 ast_variables_destroy(ies.vars);
09889 ast_mutex_unlock(&iaxsl[fr->callno]);
09890 return 1;
09891 }
09892 }
09893
09894 if (ies.vars) {
09895 struct ast_datastore *variablestore = NULL;
09896 struct ast_variable *var, *prev = NULL;
09897 AST_LIST_HEAD(, ast_var_t) *varlist;
09898
09899 iax2_lock_owner(fr->callno);
09900 if (!iaxs[fr->callno]) {
09901 ast_variables_destroy(ies.vars);
09902 ast_mutex_unlock(&iaxsl[fr->callno]);
09903 return 1;
09904 }
09905 if ((c = iaxs[fr->callno]->owner)) {
09906 varlist = ast_calloc(1, sizeof(*varlist));
09907 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09908
09909 if (variablestore && varlist) {
09910 variablestore->data = varlist;
09911 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09912 AST_LIST_HEAD_INIT(varlist);
09913 ast_debug(1, "I can haz IAX vars?\n");
09914 for (var = ies.vars; var; var = var->next) {
09915 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09916 if (prev) {
09917 ast_free(prev);
09918 }
09919 prev = var;
09920 if (!newvar) {
09921
09922 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09923 } else {
09924 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09925 }
09926 }
09927 if (prev) {
09928 ast_free(prev);
09929 }
09930 ies.vars = NULL;
09931 ast_channel_datastore_add(c, variablestore);
09932 } else {
09933 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09934 if (variablestore) {
09935 ast_datastore_free(variablestore);
09936 }
09937 if (varlist) {
09938 ast_free(varlist);
09939 }
09940 }
09941 ast_channel_unlock(c);
09942 } else {
09943
09944
09945 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
09946 for (var = ies.vars; var && var->next; var = var->next);
09947 if (var) {
09948 var->next = iaxs[fr->callno]->iaxvars;
09949 iaxs[fr->callno]->iaxvars = ies.vars;
09950 ies.vars = NULL;
09951 }
09952 }
09953 }
09954
09955 if (ies.vars) {
09956 ast_debug(1, "I have IAX variables, but they were not processed\n");
09957 }
09958 }
09959
09960
09961
09962 if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
09963 send_signaling(iaxs[fr->callno]);
09964 }
09965
09966 if (f.frametype == AST_FRAME_VOICE) {
09967 if (f.subclass != iaxs[fr->callno]->voiceformat) {
09968 iaxs[fr->callno]->voiceformat = f.subclass;
09969 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
09970 if (iaxs[fr->callno]->owner) {
09971 iax2_lock_owner(fr->callno);
09972 if (iaxs[fr->callno]) {
09973 if (iaxs[fr->callno]->owner) {
09974 int orignative;
09975
09976 orignative = iaxs[fr->callno]->owner->nativeformats;
09977 iaxs[fr->callno]->owner->nativeformats = f.subclass;
09978 if (iaxs[fr->callno]->owner->readformat)
09979 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
09980 iaxs[fr->callno]->owner->nativeformats = orignative;
09981 ast_channel_unlock(iaxs[fr->callno]->owner);
09982 }
09983 } else {
09984 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
09985
09986 if (ies.vars) {
09987 ast_variables_destroy(ies.vars);
09988 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
09989 ies.vars = NULL;
09990 }
09991 ast_mutex_unlock(&iaxsl[fr->callno]);
09992 return 1;
09993 }
09994 }
09995 }
09996 }
09997 if (f.frametype == AST_FRAME_VIDEO) {
09998 if (f.subclass != iaxs[fr->callno]->videoformat) {
09999 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
10000 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
10001 }
10002 }
10003 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10004 if (f.subclass == AST_CONTROL_BUSY) {
10005 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10006 } else if (f.subclass == AST_CONTROL_CONGESTION) {
10007 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10008 }
10009 }
10010 if (f.frametype == AST_FRAME_IAX) {
10011 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10012
10013 if (iaxdebug)
10014 ast_debug(1, "IAX subclass %d received\n", f.subclass);
10015
10016
10017 if (iaxs[fr->callno]->last < fr->ts &&
10018 f.subclass != IAX_COMMAND_ACK &&
10019 f.subclass != IAX_COMMAND_PONG &&
10020 f.subclass != IAX_COMMAND_LAGRP) {
10021 iaxs[fr->callno]->last = fr->ts;
10022 if (iaxdebug)
10023 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10024 }
10025 iaxs[fr->callno]->last_iax_message = f.subclass;
10026 if (!iaxs[fr->callno]->first_iax_message) {
10027 iaxs[fr->callno]->first_iax_message = f.subclass;
10028 }
10029 switch(f.subclass) {
10030 case IAX_COMMAND_ACK:
10031
10032 break;
10033 case IAX_COMMAND_QUELCH:
10034 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10035
10036 if (iaxs[fr->callno]->owner) {
10037 manager_event(EVENT_FLAG_CALL, "Hold",
10038 "Status: On\r\n"
10039 "Channel: %s\r\n"
10040 "Uniqueid: %s\r\n",
10041 iaxs[fr->callno]->owner->name,
10042 iaxs[fr->callno]->owner->uniqueid);
10043 }
10044
10045 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
10046 if (ies.musiconhold) {
10047 iax2_lock_owner(fr->callno);
10048 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10049 break;
10050 }
10051 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10052 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10053
10054
10055
10056
10057
10058 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10059 S_OR(moh_suggest, NULL),
10060 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10061 }
10062 ast_channel_unlock(iaxs[fr->callno]->owner);
10063 }
10064 }
10065 break;
10066 case IAX_COMMAND_UNQUELCH:
10067 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10068 iax2_lock_owner(fr->callno);
10069 if (!iaxs[fr->callno]) {
10070 break;
10071 }
10072
10073 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
10074 manager_event(EVENT_FLAG_CALL, "Hold",
10075 "Status: Off\r\n"
10076 "Channel: %s\r\n"
10077 "Uniqueid: %s\r\n",
10078 iaxs[fr->callno]->owner->name,
10079 iaxs[fr->callno]->owner->uniqueid);
10080 }
10081
10082 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
10083 if (!iaxs[fr->callno]->owner) {
10084 break;
10085 }
10086 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10087
10088
10089
10090
10091 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10092 }
10093 ast_channel_unlock(iaxs[fr->callno]->owner);
10094 }
10095 break;
10096 case IAX_COMMAND_TXACC:
10097 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10098
10099 AST_LIST_LOCK(&frame_queue);
10100 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10101
10102 if ((fr->callno == cur->callno) && (cur->transfer))
10103 cur->retries = -1;
10104 }
10105 AST_LIST_UNLOCK(&frame_queue);
10106 memset(&ied1, 0, sizeof(ied1));
10107 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10108 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10109 iaxs[fr->callno]->transferring = TRANSFER_READY;
10110 }
10111 break;
10112 case IAX_COMMAND_NEW:
10113
10114 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10115 break;
10116 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10117 ast_mutex_unlock(&iaxsl[fr->callno]);
10118 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10119 ast_mutex_lock(&iaxsl[fr->callno]);
10120 if (!iaxs[fr->callno]) {
10121 break;
10122 }
10123 }
10124
10125 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
10126 int new_callno;
10127 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10128 fr->callno = new_callno;
10129 }
10130
10131 if (delayreject)
10132 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10133 if (check_access(fr->callno, &sin, &ies)) {
10134
10135 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10136 if (authdebug)
10137 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);
10138 break;
10139 }
10140 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10141 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10142 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10143 break;
10144 }
10145 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10146 const char *context, *exten, *cid_num;
10147
10148 context = ast_strdupa(iaxs[fr->callno]->context);
10149 exten = ast_strdupa(iaxs[fr->callno]->exten);
10150 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10151
10152
10153 ast_mutex_unlock(&iaxsl[fr->callno]);
10154 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10155 ast_mutex_lock(&iaxsl[fr->callno]);
10156
10157 if (!iaxs[fr->callno]) {
10158 break;
10159 }
10160 } else
10161 exists = 0;
10162
10163 save_osptoken(fr, &ies);
10164 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10165 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10166 memset(&ied0, 0, sizeof(ied0));
10167 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10168 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10169 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10170 if (!iaxs[fr->callno]) {
10171 break;
10172 }
10173 if (authdebug)
10174 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);
10175 } else {
10176
10177
10178 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10179 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10180 using_prefs = "reqonly";
10181 } else {
10182 using_prefs = "disabled";
10183 }
10184 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10185 memset(&pref, 0, sizeof(pref));
10186 strcpy(caller_pref_buf, "disabled");
10187 strcpy(host_pref_buf, "disabled");
10188 } else {
10189 using_prefs = "mine";
10190
10191 if (ies.codec_prefs)
10192 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10193 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10194
10195 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10196 pref = iaxs[fr->callno]->rprefs;
10197 using_prefs = "caller";
10198 } else {
10199 pref = iaxs[fr->callno]->prefs;
10200 }
10201 } else
10202 pref = iaxs[fr->callno]->prefs;
10203
10204 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10205 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10206 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10207 }
10208 if (!format) {
10209 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10210 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10211 if (!format) {
10212 memset(&ied0, 0, sizeof(ied0));
10213 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10214 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10215 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10216 if (!iaxs[fr->callno]) {
10217 break;
10218 }
10219 if (authdebug) {
10220 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10221 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);
10222 else
10223 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);
10224 }
10225 } else {
10226
10227 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10228 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10229 format = 0;
10230 } else {
10231 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10232 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10233 memset(&pref, 0, sizeof(pref));
10234 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10235 strcpy(caller_pref_buf,"disabled");
10236 strcpy(host_pref_buf,"disabled");
10237 } else {
10238 using_prefs = "mine";
10239 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10240
10241 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10242 pref = iaxs[fr->callno]->prefs;
10243 } else {
10244 pref = iaxs[fr->callno]->rprefs;
10245 using_prefs = "caller";
10246 }
10247 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10248
10249 } else
10250 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10251 }
10252 }
10253
10254 if (!format) {
10255 memset(&ied0, 0, sizeof(ied0));
10256 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10257 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10258 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10259 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10260 if (!iaxs[fr->callno]) {
10261 break;
10262 }
10263 if (authdebug)
10264 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);
10265 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10266 break;
10267 }
10268 }
10269 }
10270 if (format) {
10271
10272 memset(&ied1, 0, sizeof(ied1));
10273 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10274 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10275 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10276 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10277 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10278 "%srequested format = %s,\n"
10279 "%srequested prefs = %s,\n"
10280 "%sactual format = %s,\n"
10281 "%shost prefs = %s,\n"
10282 "%spriority = %s\n",
10283 ast_inet_ntoa(sin.sin_addr),
10284 VERBOSE_PREFIX_4,
10285 ast_getformatname(iaxs[fr->callno]->peerformat),
10286 VERBOSE_PREFIX_4,
10287 caller_pref_buf,
10288 VERBOSE_PREFIX_4,
10289 ast_getformatname(format),
10290 VERBOSE_PREFIX_4,
10291 host_pref_buf,
10292 VERBOSE_PREFIX_4,
10293 using_prefs);
10294
10295 iaxs[fr->callno]->chosenformat = format;
10296 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
10297 } else {
10298 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10299
10300 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10301 }
10302 }
10303 }
10304 break;
10305 }
10306 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10307 merge_encryption(iaxs[fr->callno],ies.encmethods);
10308 else
10309 iaxs[fr->callno]->encmethods = 0;
10310 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10311 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10312 break;
10313 case IAX_COMMAND_DPREQ:
10314
10315 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10316 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10317 if (iaxcompat) {
10318
10319 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10320 } else {
10321
10322 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10323 }
10324 }
10325 break;
10326 case IAX_COMMAND_HANGUP:
10327 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10328 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10329
10330 if (ies.causecode && iaxs[fr->callno]->owner)
10331 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10332
10333 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10334 iax2_destroy(fr->callno);
10335 break;
10336 case IAX_COMMAND_REJECT:
10337
10338 if (ies.causecode && iaxs[fr->callno]->owner)
10339 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10340
10341 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10342 if (iaxs[fr->callno]->owner && authdebug)
10343 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10344 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10345 ies.cause ? ies.cause : "<Unknown>");
10346 ast_debug(1, "Immediately destroying %d, having received reject\n",
10347 fr->callno);
10348 }
10349
10350 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10351 fr->ts, NULL, 0, fr->iseqno);
10352 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
10353 iaxs[fr->callno]->error = EPERM;
10354 iax2_destroy(fr->callno);
10355 break;
10356 case IAX_COMMAND_TRANSFER:
10357 {
10358 struct ast_channel *bridged_chan;
10359 struct ast_channel *owner;
10360
10361 iax2_lock_owner(fr->callno);
10362 if (!iaxs[fr->callno]) {
10363
10364 break;
10365 }
10366 owner = iaxs[fr->callno]->owner;
10367 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10368 if (bridged_chan && ies.called_number) {
10369 ast_mutex_unlock(&iaxsl[fr->callno]);
10370
10371
10372 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10373 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10374
10375 if (!strcmp(ies.called_number, ast_parking_ext())) {
10376 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10377 if (iax_park(bridged_chan, owner)) {
10378 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10379 bridged_chan->name);
10380 }
10381 ast_mutex_lock(&iaxsl[fr->callno]);
10382 } else {
10383 ast_mutex_lock(&iaxsl[fr->callno]);
10384
10385 if (iaxs[fr->callno]) {
10386 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context,
10387 ies.called_number, 1)) {
10388 ast_log(LOG_WARNING,
10389 "Async goto of '%s' to '%s@%s' failed\n",
10390 bridged_chan->name, ies.called_number,
10391 iaxs[fr->callno]->context);
10392 } else {
10393 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10394 bridged_chan->name, ies.called_number,
10395 iaxs[fr->callno]->context);
10396 }
10397 } else {
10398
10399 }
10400 }
10401 } else {
10402 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10403 }
10404 if (owner) {
10405 ast_channel_unlock(owner);
10406 }
10407
10408 break;
10409 }
10410 case IAX_COMMAND_ACCEPT:
10411
10412 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10413 break;
10414 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10415
10416 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10417 iax2_destroy(fr->callno);
10418 break;
10419 }
10420 if (ies.format) {
10421 iaxs[fr->callno]->peerformat = ies.format;
10422 } else {
10423 if (iaxs[fr->callno]->owner)
10424 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10425 else
10426 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10427 }
10428 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));
10429 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10430 memset(&ied0, 0, sizeof(ied0));
10431 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10432 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10433 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10434 if (!iaxs[fr->callno]) {
10435 break;
10436 }
10437 if (authdebug)
10438 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);
10439 } else {
10440 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10441 iax2_lock_owner(fr->callno);
10442 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10443
10444 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10445 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10446
10447
10448 if (iaxs[fr->callno]->owner->writeformat)
10449 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10450 if (iaxs[fr->callno]->owner->readformat)
10451 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10452 ast_channel_unlock(iaxs[fr->callno]->owner);
10453 }
10454 }
10455 if (iaxs[fr->callno]) {
10456 AST_LIST_LOCK(&dpcache);
10457 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10458 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10459 iax2_dprequest(dp, fr->callno);
10460 AST_LIST_UNLOCK(&dpcache);
10461 }
10462 break;
10463 case IAX_COMMAND_POKE:
10464
10465 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10466 break;
10467 case IAX_COMMAND_PING:
10468 {
10469 struct iax_ie_data pingied;
10470 construct_rr(iaxs[fr->callno], &pingied);
10471
10472 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10473 }
10474 break;
10475 case IAX_COMMAND_PONG:
10476
10477 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10478
10479 save_rr(fr, &ies);
10480
10481
10482 log_jitterstats(fr->callno);
10483
10484 if (iaxs[fr->callno]->peerpoke) {
10485 peer = iaxs[fr->callno]->peerpoke;
10486 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10487 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10488 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10489 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);
10490 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10491 }
10492 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10493 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10494 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10495 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);
10496 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10497 }
10498 }
10499 peer->lastms = iaxs[fr->callno]->pingtime;
10500 if (peer->smoothing && (peer->lastms > -1))
10501 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10502 else if (peer->smoothing && peer->lastms < 0)
10503 peer->historicms = (0 + peer->historicms) / 2;
10504 else
10505 peer->historicms = iaxs[fr->callno]->pingtime;
10506
10507
10508 if (peer->pokeexpire > -1) {
10509 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10510 peer_unref(peer);
10511 peer->pokeexpire = -1;
10512 }
10513 }
10514
10515 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10516 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10517 else
10518 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10519 if (peer->pokeexpire == -1)
10520 peer_unref(peer);
10521
10522 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10523
10524 iax2_destroy(fr->callno);
10525 peer->callno = 0;
10526 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10527 }
10528 break;
10529 case IAX_COMMAND_LAGRQ:
10530 case IAX_COMMAND_LAGRP:
10531 f.src = "LAGRQ";
10532 f.mallocd = 0;
10533 f.offset = 0;
10534 f.samples = 0;
10535 iax_frame_wrap(fr, &f);
10536 if(f.subclass == IAX_COMMAND_LAGRQ) {
10537
10538 fr->af.subclass = IAX_COMMAND_LAGRP;
10539 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10540 } else {
10541
10542 unsigned int ts;
10543
10544 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10545 iaxs[fr->callno]->lag = ts - fr->ts;
10546 if (iaxdebug)
10547 ast_debug(1, "Peer %s lag measured as %dms\n",
10548 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10549 }
10550 break;
10551 case IAX_COMMAND_AUTHREQ:
10552 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10553 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>");
10554 break;
10555 }
10556 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10557 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10558 .subclass = AST_CONTROL_HANGUP,
10559 };
10560 ast_log(LOG_WARNING,
10561 "I don't know how to authenticate %s to %s\n",
10562 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10563 iax2_queue_frame(fr->callno, &hangup_fr);
10564 }
10565 break;
10566 case IAX_COMMAND_AUTHREP:
10567
10568 if (delayreject)
10569 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10570
10571 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10572 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>");
10573 break;
10574 }
10575 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10576 if (authdebug)
10577 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);
10578 memset(&ied0, 0, sizeof(ied0));
10579 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10580 break;
10581 }
10582 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10583
10584 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10585 } else
10586 exists = 0;
10587 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10588 if (authdebug)
10589 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);
10590 memset(&ied0, 0, sizeof(ied0));
10591 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10592 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10593 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10594 if (!iaxs[fr->callno]) {
10595 break;
10596 }
10597 } else {
10598
10599 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10600 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10601 using_prefs = "reqonly";
10602 } else {
10603 using_prefs = "disabled";
10604 }
10605 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10606 memset(&pref, 0, sizeof(pref));
10607 strcpy(caller_pref_buf, "disabled");
10608 strcpy(host_pref_buf, "disabled");
10609 } else {
10610 using_prefs = "mine";
10611 if (ies.codec_prefs)
10612 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10613 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10614 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10615 pref = iaxs[fr->callno]->rprefs;
10616 using_prefs = "caller";
10617 } else {
10618 pref = iaxs[fr->callno]->prefs;
10619 }
10620 } else
10621 pref = iaxs[fr->callno]->prefs;
10622
10623 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10624 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10625 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10626 }
10627 if (!format) {
10628 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10629 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);
10630 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10631 }
10632 if (!format) {
10633 if (authdebug) {
10634 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10635 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);
10636 else
10637 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);
10638 }
10639 memset(&ied0, 0, sizeof(ied0));
10640 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10641 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10642 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10643 if (!iaxs[fr->callno]) {
10644 break;
10645 }
10646 } else {
10647
10648 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10649 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10650 format = 0;
10651 } else {
10652 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10653 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10654 memset(&pref, 0, sizeof(pref));
10655 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10656 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10657 strcpy(caller_pref_buf,"disabled");
10658 strcpy(host_pref_buf,"disabled");
10659 } else {
10660 using_prefs = "mine";
10661 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10662
10663 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10664 pref = iaxs[fr->callno]->prefs;
10665 } else {
10666 pref = iaxs[fr->callno]->rprefs;
10667 using_prefs = "caller";
10668 }
10669 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10670 } else
10671 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10672 }
10673 }
10674 if (!format) {
10675 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10676 if (authdebug) {
10677 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10678 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);
10679 else
10680 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);
10681 }
10682 memset(&ied0, 0, sizeof(ied0));
10683 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10684 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10685 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10686 if (!iaxs[fr->callno]) {
10687 break;
10688 }
10689 }
10690 }
10691 }
10692 if (format) {
10693
10694 memset(&ied1, 0, sizeof(ied1));
10695 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10696 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10697 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10698 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10699 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
10700 "%srequested format = %s,\n"
10701 "%srequested prefs = %s,\n"
10702 "%sactual format = %s,\n"
10703 "%shost prefs = %s,\n"
10704 "%spriority = %s\n",
10705 ast_inet_ntoa(sin.sin_addr),
10706 VERBOSE_PREFIX_4,
10707 ast_getformatname(iaxs[fr->callno]->peerformat),
10708 VERBOSE_PREFIX_4,
10709 caller_pref_buf,
10710 VERBOSE_PREFIX_4,
10711 ast_getformatname(format),
10712 VERBOSE_PREFIX_4,
10713 host_pref_buf,
10714 VERBOSE_PREFIX_4,
10715 using_prefs);
10716
10717 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10718 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
10719 iax2_destroy(fr->callno);
10720 else if (ies.vars) {
10721 struct ast_datastore *variablestore;
10722 struct ast_variable *var, *prev = NULL;
10723 AST_LIST_HEAD(, ast_var_t) *varlist;
10724 varlist = ast_calloc(1, sizeof(*varlist));
10725 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10726 if (variablestore && varlist) {
10727 variablestore->data = varlist;
10728 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10729 AST_LIST_HEAD_INIT(varlist);
10730 ast_debug(1, "I can haz IAX vars? w00t\n");
10731 for (var = ies.vars; var; var = var->next) {
10732 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10733 if (prev)
10734 ast_free(prev);
10735 prev = var;
10736 if (!newvar) {
10737
10738 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10739 } else {
10740 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10741 }
10742 }
10743 if (prev)
10744 ast_free(prev);
10745 ies.vars = NULL;
10746 ast_channel_datastore_add(c, variablestore);
10747 } else {
10748 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10749 if (variablestore)
10750 ast_datastore_free(variablestore);
10751 if (varlist)
10752 ast_free(varlist);
10753 }
10754 }
10755 } else {
10756 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10757
10758 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10759 if (ast_test_flag(iaxs[fr->callno], IAX_IMMEDIATE)) {
10760 goto immediatedial;
10761 }
10762 }
10763 }
10764 }
10765 break;
10766 case IAX_COMMAND_DIAL:
10767 immediatedial:
10768 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
10769 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10770 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
10771 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
10772 if (authdebug)
10773 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);
10774 memset(&ied0, 0, sizeof(ied0));
10775 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10776 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10777 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10778 if (!iaxs[fr->callno]) {
10779 break;
10780 }
10781 } else {
10782 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10783 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
10784 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10785 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
10786 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
10787 iax2_destroy(fr->callno);
10788 else if (ies.vars) {
10789 struct ast_datastore *variablestore;
10790 struct ast_variable *var, *prev = NULL;
10791 AST_LIST_HEAD(, ast_var_t) *varlist;
10792 varlist = ast_calloc(1, sizeof(*varlist));
10793 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10794 ast_debug(1, "I can haz IAX vars? w00t\n");
10795 if (variablestore && varlist) {
10796 variablestore->data = varlist;
10797 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10798 AST_LIST_HEAD_INIT(varlist);
10799 for (var = ies.vars; var; var = var->next) {
10800 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10801 if (prev)
10802 ast_free(prev);
10803 prev = var;
10804 if (!newvar) {
10805
10806 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10807 } else {
10808 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10809 }
10810 }
10811 if (prev)
10812 ast_free(prev);
10813 ies.vars = NULL;
10814 ast_channel_datastore_add(c, variablestore);
10815 } else {
10816 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10817 if (variablestore)
10818 ast_datastore_free(variablestore);
10819 if (varlist)
10820 ast_free(varlist);
10821 }
10822 }
10823 }
10824 }
10825 break;
10826 case IAX_COMMAND_INVAL:
10827 iaxs[fr->callno]->error = ENOTCONN;
10828 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
10829 iax2_destroy(fr->callno);
10830 ast_debug(1, "Destroying call %d\n", fr->callno);
10831 break;
10832 case IAX_COMMAND_VNAK:
10833 ast_debug(1, "Received VNAK: resending outstanding frames\n");
10834
10835 vnak_retransmit(fr->callno, fr->iseqno);
10836 break;
10837 case IAX_COMMAND_REGREQ:
10838 case IAX_COMMAND_REGREL:
10839
10840 if (delayreject)
10841 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10842 if (register_verify(fr->callno, &sin, &ies)) {
10843 if (!iaxs[fr->callno]) {
10844 break;
10845 }
10846
10847 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
10848 break;
10849 }
10850 if (!iaxs[fr->callno]) {
10851 break;
10852 }
10853 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
10854 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
10855
10856 if (f.subclass == IAX_COMMAND_REGREL)
10857 memset(&sin, 0, sizeof(sin));
10858 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
10859 ast_log(LOG_WARNING, "Registry error\n");
10860 if (!iaxs[fr->callno]) {
10861 break;
10862 }
10863 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10864 ast_mutex_unlock(&iaxsl[fr->callno]);
10865 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10866 ast_mutex_lock(&iaxsl[fr->callno]);
10867 }
10868 break;
10869 }
10870 registry_authrequest(fr->callno);
10871 break;
10872 case IAX_COMMAND_REGACK:
10873 if (iax2_ack_registry(&ies, &sin, fr->callno))
10874 ast_log(LOG_WARNING, "Registration failure\n");
10875
10876 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10877 iax2_destroy(fr->callno);
10878 break;
10879 case IAX_COMMAND_REGREJ:
10880 if (iaxs[fr->callno]->reg) {
10881 if (authdebug) {
10882 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));
10883 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>");
10884 }
10885 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
10886 }
10887
10888 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10889 iax2_destroy(fr->callno);
10890 break;
10891 case IAX_COMMAND_REGAUTH:
10892
10893 if (registry_rerequest(&ies, fr->callno, &sin)) {
10894 memset(&ied0, 0, sizeof(ied0));
10895 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
10896 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
10897 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10898 }
10899 break;
10900 case IAX_COMMAND_TXREJ:
10901 iaxs[fr->callno]->transferring = 0;
10902 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10903 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
10904 if (iaxs[fr->callno]->bridgecallno) {
10905 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
10906 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
10907 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
10908 }
10909 }
10910 break;
10911 case IAX_COMMAND_TXREADY:
10912 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
10913 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
10914 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
10915 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
10916 else
10917 iaxs[fr->callno]->transferring = TRANSFER_READY;
10918 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10919 if (iaxs[fr->callno]->bridgecallno) {
10920 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
10921 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
10922
10923 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
10924 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10925 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10926
10927 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
10928 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
10929
10930 memset(&ied0, 0, sizeof(ied0));
10931 memset(&ied1, 0, sizeof(ied1));
10932 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10933 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10934 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
10935 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
10936 } else {
10937 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10938 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10939
10940 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
10941 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
10942 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
10943 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10944
10945
10946 stop_stuff(fr->callno);
10947 stop_stuff(iaxs[fr->callno]->bridgecallno);
10948
10949 memset(&ied0, 0, sizeof(ied0));
10950 memset(&ied1, 0, sizeof(ied1));
10951 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10952 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10953 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
10954 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
10955 }
10956
10957 }
10958 }
10959 }
10960 break;
10961 case IAX_COMMAND_TXREQ:
10962 try_transfer(iaxs[fr->callno], &ies);
10963 break;
10964 case IAX_COMMAND_TXCNT:
10965 if (iaxs[fr->callno]->transferring)
10966 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
10967 break;
10968 case IAX_COMMAND_TXREL:
10969
10970 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10971 complete_transfer(fr->callno, &ies);
10972 stop_stuff(fr->callno);
10973 break;
10974 case IAX_COMMAND_TXMEDIA:
10975 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
10976 AST_LIST_LOCK(&frame_queue);
10977 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10978
10979 if ((fr->callno == cur->callno) && (cur->transfer))
10980 cur->retries = -1;
10981 }
10982 AST_LIST_UNLOCK(&frame_queue);
10983
10984 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
10985 }
10986 break;
10987 case IAX_COMMAND_RTKEY:
10988 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
10989 ast_log(LOG_WARNING,
10990 "we've been told to rotate our encryption key, "
10991 "but this isn't an encrypted call. bad things will happen.\n"
10992 );
10993 break;
10994 }
10995
10996 IAX_DEBUGDIGEST("Receiving", ies.challenge);
10997
10998 ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
10999 break;
11000 case IAX_COMMAND_DPREP:
11001 complete_dpreply(iaxs[fr->callno], &ies);
11002 break;
11003 case IAX_COMMAND_UNSUPPORT:
11004 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11005 break;
11006 case IAX_COMMAND_FWDOWNL:
11007
11008 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11009 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11010 break;
11011 }
11012 memset(&ied0, 0, sizeof(ied0));
11013 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11014 if (res < 0)
11015 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11016 else if (res > 0)
11017 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11018 else
11019 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11020 break;
11021 case IAX_COMMAND_CALLTOKEN:
11022 {
11023 struct iax_frame *cur;
11024 int found = 0;
11025 AST_LIST_LOCK(&frame_queue);
11026 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
11027
11028
11029
11030 if (cur->callno == fr->callno) {
11031 found = 1;
11032 break;
11033 }
11034 }
11035 AST_LIST_UNLOCK(&frame_queue);
11036
11037
11038 if (cur && found && ies.calltoken && ies.calltokendata) {
11039 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11040 }
11041 break;
11042 }
11043 default:
11044 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
11045 memset(&ied0, 0, sizeof(ied0));
11046 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
11047 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11048 }
11049
11050 if (ies.vars) {
11051 ast_variables_destroy(ies.vars);
11052 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11053 ies.vars = NULL;
11054 }
11055
11056
11057 if ((f.subclass != IAX_COMMAND_ACK) &&
11058 (f.subclass != IAX_COMMAND_TXCNT) &&
11059 (f.subclass != IAX_COMMAND_TXACC) &&
11060 (f.subclass != IAX_COMMAND_INVAL) &&
11061 (f.subclass != IAX_COMMAND_VNAK)) {
11062 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11063 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11064 }
11065 ast_mutex_unlock(&iaxsl[fr->callno]);
11066 return 1;
11067 }
11068
11069 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11070 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11071 } else if (minivid) {
11072 f.frametype = AST_FRAME_VIDEO;
11073 if (iaxs[fr->callno]->videoformat > 0)
11074 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
11075 else {
11076 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11077 iax2_vnak(fr->callno);
11078 ast_variables_destroy(ies.vars);
11079 ast_mutex_unlock(&iaxsl[fr->callno]);
11080 return 1;
11081 }
11082 f.datalen = res - sizeof(*vh);
11083 if (f.datalen)
11084 f.data.ptr = thread->buf + sizeof(*vh);
11085 else
11086 f.data.ptr = NULL;
11087 #ifdef IAXTESTS
11088 if (test_resync) {
11089 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11090 } else
11091 #endif
11092 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11093 } else {
11094
11095 f.frametype = AST_FRAME_VOICE;
11096 if (iaxs[fr->callno]->voiceformat > 0)
11097 f.subclass = iaxs[fr->callno]->voiceformat;
11098 else {
11099 ast_debug(1, "Received mini frame before first full voice frame\n");
11100 iax2_vnak(fr->callno);
11101 ast_variables_destroy(ies.vars);
11102 ast_mutex_unlock(&iaxsl[fr->callno]);
11103 return 1;
11104 }
11105 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11106 if (f.datalen < 0) {
11107 ast_log(LOG_WARNING, "Datalen < 0?\n");
11108 ast_variables_destroy(ies.vars);
11109 ast_mutex_unlock(&iaxsl[fr->callno]);
11110 return 1;
11111 }
11112 if (f.datalen)
11113 f.data.ptr = thread->buf + sizeof(*mh);
11114 else
11115 f.data.ptr = NULL;
11116 #ifdef IAXTESTS
11117 if (test_resync) {
11118 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11119 } else
11120 #endif
11121 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11122
11123 }
11124
11125 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11126 ast_variables_destroy(ies.vars);
11127 ast_mutex_unlock(&iaxsl[fr->callno]);
11128 return 1;
11129 }
11130
11131 f.src = "IAX2";
11132 f.mallocd = 0;
11133 f.offset = 0;
11134 f.len = 0;
11135 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11136 f.samples = ast_codec_get_samples(&f);
11137
11138 if (f.subclass == AST_FORMAT_SLINEAR)
11139 ast_frame_byteswap_be(&f);
11140 } else
11141 f.samples = 0;
11142 iax_frame_wrap(fr, &f);
11143
11144
11145 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11146
11147 fr->outoforder = 0;
11148 } else {
11149 if (iaxdebug && iaxs[fr->callno])
11150 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);
11151 fr->outoforder = -1;
11152 }
11153 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11154 duped_fr = iaxfrdup2(fr);
11155 if (duped_fr) {
11156 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11157 }
11158 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11159 iaxs[fr->callno]->last = fr->ts;
11160 #if 1
11161 if (iaxdebug)
11162 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11163 #endif
11164 }
11165
11166
11167 ast_variables_destroy(ies.vars);
11168 ast_mutex_unlock(&iaxsl[fr->callno]);
11169 return 1;
11170 }
11171
11172
11173 static void iax2_process_thread_cleanup(void *data)
11174 {
11175 struct iax2_thread *thread = data;
11176 ast_mutex_destroy(&thread->lock);
11177 ast_cond_destroy(&thread->cond);
11178 ast_mutex_destroy(&thread->init_lock);
11179 ast_cond_destroy(&thread->init_cond);
11180 ast_free(thread);
11181 ast_atomic_dec_and_test(&iaxactivethreadcount);
11182 }
11183
11184 static void *iax2_process_thread(void *data)
11185 {
11186 struct iax2_thread *thread = data;
11187 struct timeval wait;
11188 struct timespec ts;
11189 int put_into_idle = 0;
11190 int first_time = 1;
11191 int old_state;
11192
11193 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11194
11195 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11196 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11197
11198 for (;;) {
11199
11200 ast_mutex_lock(&thread->lock);
11201
11202 if (thread->stop) {
11203 ast_mutex_unlock(&thread->lock);
11204 break;
11205 }
11206
11207
11208 if (first_time) {
11209 signal_condition(&thread->init_lock, &thread->init_cond);
11210 first_time = 0;
11211 }
11212
11213
11214 if (put_into_idle) {
11215 insert_idle_thread(thread);
11216 }
11217
11218 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11219 struct iax2_thread *t = NULL;
11220
11221 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11222 ts.tv_sec = wait.tv_sec;
11223 ts.tv_nsec = wait.tv_usec * 1000;
11224 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11225
11226
11227 if (!put_into_idle || thread->stop) {
11228 ast_mutex_unlock(&thread->lock);
11229 break;
11230 }
11231 AST_LIST_LOCK(&dynamic_list);
11232
11233 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11234 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11235 AST_LIST_UNLOCK(&dynamic_list);
11236 if (t) {
11237
11238
11239
11240 ast_mutex_unlock(&thread->lock);
11241 break;
11242 }
11243
11244
11245
11246 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11247 ts.tv_sec = wait.tv_sec;
11248 ts.tv_nsec = wait.tv_usec * 1000;
11249 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11250 ast_mutex_unlock(&thread->lock);
11251 break;
11252 }
11253 }
11254 } else {
11255 ast_cond_wait(&thread->cond, &thread->lock);
11256 }
11257
11258
11259 put_into_idle = 1;
11260
11261 ast_mutex_unlock(&thread->lock);
11262
11263 if (thread->stop) {
11264 break;
11265 }
11266
11267 if (thread->iostate == IAX_IOSTATE_IDLE)
11268 continue;
11269
11270
11271 switch (thread->iostate) {
11272 case IAX_IOSTATE_READY:
11273 thread->actions++;
11274 thread->iostate = IAX_IOSTATE_PROCESSING;
11275 socket_process(thread);
11276 handle_deferred_full_frames(thread);
11277 break;
11278 case IAX_IOSTATE_SCHEDREADY:
11279 thread->actions++;
11280 thread->iostate = IAX_IOSTATE_PROCESSING;
11281 #ifdef SCHED_MULTITHREADED
11282 thread->schedfunc(thread->scheddata);
11283 #endif
11284 default:
11285 break;
11286 }
11287 time(&thread->checktime);
11288 thread->iostate = IAX_IOSTATE_IDLE;
11289 #ifdef DEBUG_SCHED_MULTITHREAD
11290 thread->curfunc[0]='\0';
11291 #endif
11292
11293
11294
11295
11296 AST_LIST_LOCK(&active_list);
11297 AST_LIST_REMOVE(&active_list, thread, list);
11298 AST_LIST_UNLOCK(&active_list);
11299
11300
11301 handle_deferred_full_frames(thread);
11302 }
11303
11304
11305
11306
11307
11308 AST_LIST_LOCK(&idle_list);
11309 AST_LIST_REMOVE(&idle_list, thread, list);
11310 AST_LIST_UNLOCK(&idle_list);
11311
11312 AST_LIST_LOCK(&dynamic_list);
11313 AST_LIST_REMOVE(&dynamic_list, thread, list);
11314 AST_LIST_UNLOCK(&dynamic_list);
11315
11316
11317
11318
11319 pthread_cleanup_pop(1);
11320 return NULL;
11321 }
11322
11323 static int iax2_do_register(struct iax2_registry *reg)
11324 {
11325 struct iax_ie_data ied;
11326 if (iaxdebug)
11327 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11328
11329 if (reg->dnsmgr &&
11330 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
11331
11332 ast_dnsmgr_refresh(reg->dnsmgr);
11333 }
11334
11335
11336
11337
11338
11339 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11340 int callno = reg->callno;
11341 ast_mutex_lock(&iaxsl[callno]);
11342 iax2_destroy(callno);
11343 ast_mutex_unlock(&iaxsl[callno]);
11344 reg->callno = 0;
11345 }
11346 if (!reg->addr.sin_addr.s_addr) {
11347 if (iaxdebug)
11348 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11349
11350 reg->expire = iax2_sched_replace(reg->expire, sched,
11351 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11352 return -1;
11353 }
11354
11355 if (!reg->callno) {
11356 ast_debug(3, "Allocate call number\n");
11357 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
11358 if (reg->callno < 1) {
11359 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11360 return -1;
11361 } else
11362 ast_debug(3, "Registration created on call %d\n", reg->callno);
11363 iaxs[reg->callno]->reg = reg;
11364 ast_mutex_unlock(&iaxsl[reg->callno]);
11365 }
11366
11367 reg->expire = iax2_sched_replace(reg->expire, sched,
11368 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11369
11370 memset(&ied, 0, sizeof(ied));
11371 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11372 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11373 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11374 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11375 reg->regstate = REG_STATE_REGSENT;
11376 return 0;
11377 }
11378
11379 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
11380 {
11381
11382
11383 struct iax_ie_data provdata;
11384 struct iax_ie_data ied;
11385 unsigned int sig;
11386 struct sockaddr_in sin;
11387 int callno;
11388 struct create_addr_info cai;
11389
11390 memset(&cai, 0, sizeof(cai));
11391
11392 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11393
11394 if (iax_provision_build(&provdata, &sig, template, force)) {
11395 ast_debug(1, "No provisioning found for template '%s'\n", template);
11396 return 0;
11397 }
11398
11399 if (end) {
11400 memcpy(&sin, end, sizeof(sin));
11401 cai.sockfd = sockfd;
11402 } else if (create_addr(dest, NULL, &sin, &cai))
11403 return -1;
11404
11405
11406 memset(&ied, 0, sizeof(ied));
11407 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11408
11409 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11410 if (!callno)
11411 return -1;
11412
11413 if (iaxs[callno]) {
11414
11415 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11416 sched, 15000, auto_hangup, (void *)(long)callno);
11417 ast_set_flag(iaxs[callno], IAX_PROVISION);
11418
11419 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11420 }
11421 ast_mutex_unlock(&iaxsl[callno]);
11422
11423 return 1;
11424 }
11425
11426 static char *papp = "IAX2Provision";
11427
11428
11429
11430
11431 static int iax2_prov_app(struct ast_channel *chan, void *data)
11432 {
11433 int res;
11434 char *sdata;
11435 char *opts;
11436 int force =0;
11437 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11438 if (ast_strlen_zero(data))
11439 data = "default";
11440 sdata = ast_strdupa(data);
11441 opts = strchr(sdata, '|');
11442 if (opts)
11443 *opts='\0';
11444
11445 if (chan->tech != &iax2_tech) {
11446 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11447 return -1;
11448 }
11449 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11450 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11451 return -1;
11452 }
11453 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11454 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11455 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11456 sdata, res);
11457 return res;
11458 }
11459
11460 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11461 {
11462 int force = 0;
11463 int res;
11464
11465 switch (cmd) {
11466 case CLI_INIT:
11467 e->command = "iax2 provision";
11468 e->usage =
11469 "Usage: iax2 provision <host> <template> [forced]\n"
11470 " Provisions the given peer or IP address using a template\n"
11471 " matching either 'template' or '*' if the template is not\n"
11472 " found. If 'forced' is specified, even empty provisioning\n"
11473 " fields will be provisioned as empty fields.\n";
11474 return NULL;
11475 case CLI_GENERATE:
11476 if (a->pos == 3)
11477 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11478 return NULL;
11479 }
11480
11481 if (a->argc < 4)
11482 return CLI_SHOWUSAGE;
11483 if (a->argc > 4) {
11484 if (!strcasecmp(a->argv[4], "forced"))
11485 force = 1;
11486 else
11487 return CLI_SHOWUSAGE;
11488 }
11489 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11490 if (res < 0)
11491 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11492 else if (res < 1)
11493 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11494 else
11495 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11496 return CLI_SUCCESS;
11497 }
11498
11499 static void __iax2_poke_noanswer(const void *data)
11500 {
11501 struct iax2_peer *peer = (struct iax2_peer *)data;
11502 int callno;
11503
11504 if (peer->lastms > -1) {
11505 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11506 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11507 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11508 }
11509 if ((callno = peer->callno) > 0) {
11510 ast_mutex_lock(&iaxsl[callno]);
11511 iax2_destroy(callno);
11512 ast_mutex_unlock(&iaxsl[callno]);
11513 }
11514 peer->callno = 0;
11515 peer->lastms = -1;
11516
11517 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11518 if (peer->pokeexpire == -1)
11519 peer_unref(peer);
11520 }
11521
11522 static int iax2_poke_noanswer(const void *data)
11523 {
11524 struct iax2_peer *peer = (struct iax2_peer *)data;
11525 peer->pokeexpire = -1;
11526 #ifdef SCHED_MULTITHREADED
11527 if (schedule_action(__iax2_poke_noanswer, data))
11528 #endif
11529 __iax2_poke_noanswer(data);
11530 peer_unref(peer);
11531 return 0;
11532 }
11533
11534 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11535 {
11536 struct iax2_peer *peer = obj;
11537
11538 iax2_poke_peer(peer, 0);
11539
11540 return 0;
11541 }
11542
11543 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11544 {
11545 int callno;
11546 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
11547
11548
11549 peer->lastms = 0;
11550 peer->historicms = 0;
11551 peer->pokeexpire = -1;
11552 peer->callno = 0;
11553 return 0;
11554 }
11555
11556
11557 if ((callno = peer->callno) > 0) {
11558 ast_log(LOG_NOTICE, "Still have a callno...\n");
11559 ast_mutex_lock(&iaxsl[callno]);
11560 iax2_destroy(callno);
11561 ast_mutex_unlock(&iaxsl[callno]);
11562 }
11563 if (heldcall)
11564 ast_mutex_unlock(&iaxsl[heldcall]);
11565 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
11566 if (heldcall)
11567 ast_mutex_lock(&iaxsl[heldcall]);
11568 if (peer->callno < 1) {
11569 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11570 return -1;
11571 }
11572
11573
11574 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11575 iaxs[peer->callno]->peerpoke = peer;
11576
11577 if (peer->pokeexpire > -1) {
11578 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
11579 peer->pokeexpire = -1;
11580 peer_unref(peer);
11581 }
11582 }
11583
11584
11585
11586 if (peer->lastms < 0)
11587 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11588 else
11589 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11590
11591 if (peer->pokeexpire == -1)
11592 peer_unref(peer);
11593
11594
11595 ast_mutex_lock(&iaxsl[callno]);
11596 if (iaxs[callno]) {
11597 struct iax_ie_data ied = {
11598 .buf = { 0 },
11599 .pos = 0,
11600 };
11601 add_empty_calltoken_ie(iaxs[callno], &ied);
11602 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11603 }
11604 ast_mutex_unlock(&iaxsl[callno]);
11605
11606 return 0;
11607 }
11608
11609 static void free_context(struct iax2_context *con)
11610 {
11611 struct iax2_context *conl;
11612 while(con) {
11613 conl = con;
11614 con = con->next;
11615 ast_free(conl);
11616 }
11617 }
11618
11619 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
11620 {
11621 int callno;
11622 int res;
11623 int fmt, native;
11624 struct sockaddr_in sin;
11625 struct ast_channel *c;
11626 struct parsed_dial_string pds;
11627 struct create_addr_info cai;
11628 char *tmpstr;
11629
11630 memset(&pds, 0, sizeof(pds));
11631 tmpstr = ast_strdupa(data);
11632 parse_dial_string(tmpstr, &pds);
11633
11634 if (ast_strlen_zero(pds.peer)) {
11635 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
11636 return NULL;
11637 }
11638
11639 memset(&cai, 0, sizeof(cai));
11640 cai.capability = iax2_capability;
11641
11642 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11643
11644
11645 if (create_addr(pds.peer, NULL, &sin, &cai)) {
11646 *cause = AST_CAUSE_UNREGISTERED;
11647 return NULL;
11648 }
11649
11650 if (pds.port)
11651 sin.sin_port = htons(atoi(pds.port));
11652
11653 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11654 if (callno < 1) {
11655 ast_log(LOG_WARNING, "Unable to create call\n");
11656 *cause = AST_CAUSE_CONGESTION;
11657 return NULL;
11658 }
11659
11660
11661 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11662 if (ast_test_flag(&cai, IAX_TRUNK)) {
11663 int new_callno;
11664 if ((new_callno = make_trunk(callno, 1)) != -1)
11665 callno = new_callno;
11666 }
11667 iaxs[callno]->maxtime = cai.maxtime;
11668 if (cai.found)
11669 ast_string_field_set(iaxs[callno], host, pds.peer);
11670
11671 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
11672
11673 ast_mutex_unlock(&iaxsl[callno]);
11674
11675 if (c) {
11676
11677 if (c->nativeformats & format)
11678 c->nativeformats &= format;
11679 else {
11680 native = c->nativeformats;
11681 fmt = format;
11682 res = ast_translator_best_choice(&fmt, &native);
11683 if (res < 0) {
11684 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
11685 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
11686 ast_hangup(c);
11687 return NULL;
11688 }
11689 c->nativeformats = native;
11690 }
11691 c->readformat = ast_best_codec(c->nativeformats);
11692 c->writeformat = c->readformat;
11693 }
11694
11695 return c;
11696 }
11697
11698 static void *network_thread(void *ignore)
11699 {
11700
11701
11702 int res, count, wakeup;
11703 struct iax_frame *f;
11704
11705 if (timer)
11706 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
11707
11708 for(;;) {
11709 pthread_testcancel();
11710
11711
11712
11713 AST_LIST_LOCK(&frame_queue);
11714 count = 0;
11715 wakeup = -1;
11716 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
11717 if (f->sentyet)
11718 continue;
11719
11720
11721 if (ast_mutex_trylock(&iaxsl[f->callno])) {
11722 wakeup = 1;
11723 continue;
11724 }
11725
11726 f->sentyet = 1;
11727
11728 if (iaxs[f->callno]) {
11729 send_packet(f);
11730 count++;
11731 }
11732
11733 ast_mutex_unlock(&iaxsl[f->callno]);
11734
11735 if (f->retries < 0) {
11736
11737 AST_LIST_REMOVE_CURRENT(list);
11738
11739 iax_frame_free(f);
11740 } else {
11741
11742 f->retries++;
11743 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
11744 }
11745 }
11746 AST_LIST_TRAVERSE_SAFE_END;
11747 AST_LIST_UNLOCK(&frame_queue);
11748
11749 pthread_testcancel();
11750 if (count >= 20)
11751 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
11752
11753
11754 res = ast_io_wait(io, wakeup);
11755 if (res >= 0) {
11756 if (res >= 20)
11757 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
11758 }
11759 }
11760 return NULL;
11761 }
11762
11763 static int start_network_thread(void)
11764 {
11765 struct iax2_thread *thread;
11766 int threadcount = 0;
11767 int x;
11768 for (x = 0; x < iaxthreadcount; x++) {
11769 thread = ast_calloc(1, sizeof(*thread));
11770 if (thread) {
11771 thread->type = IAX_THREAD_TYPE_POOL;
11772 thread->threadnum = ++threadcount;
11773 ast_mutex_init(&thread->lock);
11774 ast_cond_init(&thread->cond, NULL);
11775 ast_mutex_init(&thread->init_lock);
11776 ast_cond_init(&thread->init_cond, NULL);
11777 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
11778 ast_log(LOG_WARNING, "Failed to create new thread!\n");
11779 ast_mutex_destroy(&thread->lock);
11780 ast_cond_destroy(&thread->cond);
11781 ast_mutex_destroy(&thread->init_lock);
11782 ast_cond_destroy(&thread->init_cond);
11783 ast_free(thread);
11784 thread = NULL;
11785 continue;
11786 }
11787 AST_LIST_LOCK(&idle_list);
11788 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
11789 AST_LIST_UNLOCK(&idle_list);
11790 }
11791 }
11792 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
11793 ast_verb(2, "%d helper threads started\n", threadcount);
11794 return 0;
11795 }
11796
11797 static struct iax2_context *build_context(const char *context)
11798 {
11799 struct iax2_context *con;
11800
11801 if ((con = ast_calloc(1, sizeof(*con))))
11802 ast_copy_string(con->context, context, sizeof(con->context));
11803
11804 return con;
11805 }
11806
11807 static int get_auth_methods(const char *value)
11808 {
11809 int methods = 0;
11810 if (strstr(value, "rsa"))
11811 methods |= IAX_AUTH_RSA;
11812 if (strstr(value, "md5"))
11813 methods |= IAX_AUTH_MD5;
11814 if (strstr(value, "plaintext"))
11815 methods |= IAX_AUTH_PLAINTEXT;
11816 return methods;
11817 }
11818
11819
11820
11821
11822
11823 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
11824 {
11825 int sd;
11826 int res;
11827
11828 sd = socket(AF_INET, SOCK_DGRAM, 0);
11829 if (sd < 0) {
11830 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
11831 return -1;
11832 }
11833
11834 res = bind(sd, sa, salen);
11835 if (res < 0) {
11836 ast_debug(1, "Can't bind: %s\n", strerror(errno));
11837 close(sd);
11838 return 1;
11839 }
11840
11841 close(sd);
11842 return 0;
11843 }
11844
11845
11846
11847
11848 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
11849 {
11850 struct sockaddr_in sin;
11851 int nonlocal = 1;
11852 int port = IAX_DEFAULT_PORTNO;
11853 int sockfd = defaultsockfd;
11854 char *tmp;
11855 char *addr;
11856 char *portstr;
11857
11858 if (!(tmp = ast_strdupa(srcaddr)))
11859 return -1;
11860
11861 addr = strsep(&tmp, ":");
11862 portstr = tmp;
11863
11864 if (portstr) {
11865 port = atoi(portstr);
11866 if (port < 1)
11867 port = IAX_DEFAULT_PORTNO;
11868 }
11869
11870 if (!ast_get_ip(&sin, addr)) {
11871 struct ast_netsock *sock;
11872 int res;
11873
11874 sin.sin_port = 0;
11875 sin.sin_family = AF_INET;
11876 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
11877 if (res == 0) {
11878
11879 sin.sin_port = htons(port);
11880 if (!(sock = ast_netsock_find(netsock, &sin)))
11881 sock = ast_netsock_find(outsock, &sin);
11882 if (sock) {
11883 sockfd = ast_netsock_sockfd(sock);
11884 nonlocal = 0;
11885 } else {
11886 unsigned int orig_saddr = sin.sin_addr.s_addr;
11887
11888 sin.sin_addr.s_addr = INADDR_ANY;
11889 if (ast_netsock_find(netsock, &sin)) {
11890 sin.sin_addr.s_addr = orig_saddr;
11891 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
11892 if (sock) {
11893 sockfd = ast_netsock_sockfd(sock);
11894 ast_netsock_unref(sock);
11895 nonlocal = 0;
11896 } else {
11897 nonlocal = 2;
11898 }
11899 }
11900 }
11901 }
11902 }
11903
11904 peer->sockfd = sockfd;
11905
11906 if (nonlocal == 1) {
11907 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
11908 srcaddr, peer->name);
11909 return -1;
11910 } else if (nonlocal == 2) {
11911 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
11912 srcaddr, peer->name);
11913 return -1;
11914 } else {
11915 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
11916 return 0;
11917 }
11918 }
11919
11920 static void peer_destructor(void *obj)
11921 {
11922 struct iax2_peer *peer = obj;
11923 int callno = peer->callno;
11924
11925 ast_free_ha(peer->ha);
11926
11927 if (callno > 0) {
11928 ast_mutex_lock(&iaxsl[callno]);
11929 iax2_destroy(callno);
11930 ast_mutex_unlock(&iaxsl[callno]);
11931 }
11932
11933 register_peer_exten(peer, 0);
11934
11935 if (peer->dnsmgr)
11936 ast_dnsmgr_release(peer->dnsmgr);
11937
11938 if (peer->mwi_event_sub)
11939 ast_event_unsubscribe(peer->mwi_event_sub);
11940
11941 ast_string_field_free_memory(peer);
11942 }
11943
11944
11945 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
11946 {
11947 struct iax2_peer *peer = NULL;
11948 struct ast_ha *oldha = NULL;
11949 int maskfound = 0;
11950 int found = 0;
11951 int firstpass = 1;
11952 struct iax2_peer tmp_peer = {
11953 .name = name,
11954 };
11955
11956 if (!temponly) {
11957 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
11958 if (peer && !ast_test_flag(peer, IAX_DELME))
11959 firstpass = 0;
11960 }
11961
11962 if (peer) {
11963 found++;
11964 if (firstpass) {
11965 oldha = peer->ha;
11966 peer->ha = NULL;
11967 }
11968 unlink_peer(peer);
11969 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
11970 peer->expire = -1;
11971 peer->pokeexpire = -1;
11972 peer->sockfd = defaultsockfd;
11973 if (ast_string_field_init(peer, 32))
11974 peer = peer_unref(peer);
11975 }
11976
11977 if (peer) {
11978 if (firstpass) {
11979 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT);
11980 peer->encmethods = iax2_encryption;
11981 peer->adsi = adsi;
11982 ast_string_field_set(peer,secret,"");
11983 if (!found) {
11984 ast_string_field_set(peer, name, name);
11985 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11986 peer->expiry = min_reg_expire;
11987 }
11988 peer->prefs = prefs;
11989 peer->capability = iax2_capability;
11990 peer->smoothing = 0;
11991 peer->pokefreqok = DEFAULT_FREQ_OK;
11992 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
11993 peer->maxcallno = 0;
11994 peercnt_modify(0, 0, &peer->addr);
11995 peer->calltoken_required = CALLTOKEN_DEFAULT;
11996 ast_string_field_set(peer,context,"");
11997 ast_string_field_set(peer,peercontext,"");
11998 ast_clear_flag(peer, IAX_HASCALLERID);
11999 ast_string_field_set(peer, cid_name, "");
12000 ast_string_field_set(peer, cid_num, "");
12001 ast_string_field_set(peer, mohinterpret, mohinterpret);
12002 ast_string_field_set(peer, mohsuggest, mohsuggest);
12003 }
12004
12005 if (!v) {
12006 v = alt;
12007 alt = NULL;
12008 }
12009 while(v) {
12010 if (!strcasecmp(v->name, "secret")) {
12011 ast_string_field_set(peer, secret, v->value);
12012 } else if (!strcasecmp(v->name, "mailbox")) {
12013 ast_string_field_set(peer, mailbox, v->value);
12014 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12015 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12016 ast_string_field_set(peer, mailbox, name);
12017 }
12018 } else if (!strcasecmp(v->name, "mohinterpret")) {
12019 ast_string_field_set(peer, mohinterpret, v->value);
12020 } else if (!strcasecmp(v->name, "mohsuggest")) {
12021 ast_string_field_set(peer, mohsuggest, v->value);
12022 } else if (!strcasecmp(v->name, "dbsecret")) {
12023 ast_string_field_set(peer, dbsecret, v->value);
12024 } else if (!strcasecmp(v->name, "trunk")) {
12025 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
12026 if (ast_test_flag(peer, IAX_TRUNK) && !timer) {
12027 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12028 ast_clear_flag(peer, IAX_TRUNK);
12029 }
12030 } else if (!strcasecmp(v->name, "auth")) {
12031 peer->authmethods = get_auth_methods(v->value);
12032 } else if (!strcasecmp(v->name, "encryption")) {
12033 peer->encmethods |= get_encrypt_methods(v->value);
12034 if (!peer->encmethods) {
12035 ast_clear_flag(peer, IAX_FORCE_ENCRYPT);
12036 }
12037 } else if (!strcasecmp(v->name, "forceencryption")) {
12038 if (ast_false(v->value)) {
12039 ast_clear_flag(peer, IAX_FORCE_ENCRYPT);
12040 } else {
12041 peer->encmethods |= get_encrypt_methods(v->value);
12042 if (peer->encmethods) {
12043 ast_set_flag(peer, IAX_FORCE_ENCRYPT);
12044 }
12045 }
12046 } else if (!strcasecmp(v->name, "transfer")) {
12047 if (!strcasecmp(v->value, "mediaonly")) {
12048 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12049 } else if (ast_true(v->value)) {
12050 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12051 } else
12052 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12053 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12054 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
12055 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12056 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12057 } else if (!strcasecmp(v->name, "host")) {
12058 if (!strcasecmp(v->value, "dynamic")) {
12059
12060 ast_set_flag(peer, IAX_DYNAMIC);
12061 if (!found) {
12062
12063
12064 memset(&peer->addr.sin_addr, 0, 4);
12065 if (peer->addr.sin_port) {
12066
12067 peer->defaddr.sin_port = peer->addr.sin_port;
12068 peer->addr.sin_port = 0;
12069 }
12070 }
12071 } else {
12072
12073 ast_sched_thread_del(sched, peer->expire);
12074 ast_clear_flag(peer, IAX_DYNAMIC);
12075 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12076 return peer_unref(peer);
12077 if (!peer->addr.sin_port)
12078 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
12079 }
12080 if (!maskfound)
12081 inet_aton("255.255.255.255", &peer->mask);
12082 } else if (!strcasecmp(v->name, "defaultip")) {
12083 if (ast_get_ip(&peer->defaddr, v->value))
12084 return peer_unref(peer);
12085 } else if (!strcasecmp(v->name, "sourceaddress")) {
12086 peer_set_srcaddr(peer, v->value);
12087 } else if (!strcasecmp(v->name, "permit") ||
12088 !strcasecmp(v->name, "deny")) {
12089 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12090 } else if (!strcasecmp(v->name, "mask")) {
12091 maskfound++;
12092 inet_aton(v->value, &peer->mask);
12093 } else if (!strcasecmp(v->name, "context")) {
12094 ast_string_field_set(peer, context, v->value);
12095 } else if (!strcasecmp(v->name, "regexten")) {
12096 ast_string_field_set(peer, regexten, v->value);
12097 } else if (!strcasecmp(v->name, "peercontext")) {
12098 ast_string_field_set(peer, peercontext, v->value);
12099 } else if (!strcasecmp(v->name, "port")) {
12100 if (ast_test_flag(peer, IAX_DYNAMIC))
12101 peer->defaddr.sin_port = htons(atoi(v->value));
12102 else
12103 peer->addr.sin_port = htons(atoi(v->value));
12104 } else if (!strcasecmp(v->name, "username")) {
12105 ast_string_field_set(peer, username, v->value);
12106 } else if (!strcasecmp(v->name, "allow")) {
12107 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12108 } else if (!strcasecmp(v->name, "disallow")) {
12109 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12110 } else if (!strcasecmp(v->name, "callerid")) {
12111 if (!ast_strlen_zero(v->value)) {
12112 char name2[80];
12113 char num2[80];
12114 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12115 ast_string_field_set(peer, cid_name, name2);
12116 ast_string_field_set(peer, cid_num, num2);
12117 } else {
12118 ast_string_field_set(peer, cid_name, "");
12119 ast_string_field_set(peer, cid_num, "");
12120 }
12121 ast_set_flag(peer, IAX_HASCALLERID);
12122 } else if (!strcasecmp(v->name, "fullname")) {
12123 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12124 ast_set_flag(peer, IAX_HASCALLERID);
12125 } else if (!strcasecmp(v->name, "cid_number")) {
12126 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12127 ast_set_flag(peer, IAX_HASCALLERID);
12128 } else if (!strcasecmp(v->name, "sendani")) {
12129 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
12130 } else if (!strcasecmp(v->name, "inkeys")) {
12131 ast_string_field_set(peer, inkeys, v->value);
12132 } else if (!strcasecmp(v->name, "outkey")) {
12133 ast_string_field_set(peer, outkey, v->value);
12134 } else if (!strcasecmp(v->name, "qualify")) {
12135 if (!strcasecmp(v->value, "no")) {
12136 peer->maxms = 0;
12137 } else if (!strcasecmp(v->value, "yes")) {
12138 peer->maxms = DEFAULT_MAXMS;
12139 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12140 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);
12141 peer->maxms = 0;
12142 }
12143 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12144 peer->smoothing = ast_true(v->value);
12145 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12146 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12147 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);
12148 }
12149 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12150 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12151 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);
12152 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12153 } else if (!strcasecmp(v->name, "timezone")) {
12154 ast_string_field_set(peer, zonetag, v->value);
12155 } else if (!strcasecmp(v->name, "adsi")) {
12156 peer->adsi = ast_true(v->value);
12157 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12158 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12159 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12160 } else {
12161 peercnt_modify(1, peer->maxcallno, &peer->addr);
12162 }
12163 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12164
12165 if (ast_false(v->value)) {
12166 peer->calltoken_required = CALLTOKEN_NO;
12167 } else if (!strcasecmp(v->value, "auto")) {
12168 peer->calltoken_required = CALLTOKEN_AUTO;
12169 } else if (ast_true(v->value)) {
12170 peer->calltoken_required = CALLTOKEN_YES;
12171 } else {
12172 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12173 }
12174 }
12175
12176 v = v->next;
12177 if (!v) {
12178 v = alt;
12179 alt = NULL;
12180 }
12181 }
12182 if (!peer->authmethods)
12183 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12184 ast_clear_flag(peer, IAX_DELME);
12185
12186 peer->addr.sin_family = AF_INET;
12187 }
12188
12189 if (oldha)
12190 ast_free_ha(oldha);
12191
12192 if (!ast_strlen_zero(peer->mailbox)) {
12193 char *mailbox, *context;
12194 context = mailbox = ast_strdupa(peer->mailbox);
12195 strsep(&context, "@");
12196 if (ast_strlen_zero(context))
12197 context = "default";
12198 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
12199 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12200 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12201 AST_EVENT_IE_END);
12202 }
12203
12204 return peer;
12205 }
12206
12207 static void user_destructor(void *obj)
12208 {
12209 struct iax2_user *user = obj;
12210
12211 ast_free_ha(user->ha);
12212 free_context(user->contexts);
12213 if(user->vars) {
12214 ast_variables_destroy(user->vars);
12215 user->vars = NULL;
12216 }
12217 ast_string_field_free_memory(user);
12218 }
12219
12220
12221 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12222 {
12223 struct iax2_user *user = NULL;
12224 struct iax2_context *con, *conl = NULL;
12225 struct ast_ha *oldha = NULL;
12226 struct iax2_context *oldcon = NULL;
12227 int format;
12228 int firstpass=1;
12229 int oldcurauthreq = 0;
12230 char *varname = NULL, *varval = NULL;
12231 struct ast_variable *tmpvar = NULL;
12232 struct iax2_user tmp_user = {
12233 .name = name,
12234 };
12235
12236 if (!temponly) {
12237 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12238 if (user && !ast_test_flag(user, IAX_DELME))
12239 firstpass = 0;
12240 }
12241
12242 if (user) {
12243 if (firstpass) {
12244 oldcurauthreq = user->curauthreq;
12245 oldha = user->ha;
12246 oldcon = user->contexts;
12247 user->ha = NULL;
12248 user->contexts = NULL;
12249 }
12250
12251 ao2_unlink(users, user);
12252 } else {
12253 user = ao2_alloc(sizeof(*user), user_destructor);
12254 }
12255
12256 if (user) {
12257 if (firstpass) {
12258 ast_string_field_free_memory(user);
12259 memset(user, 0, sizeof(struct iax2_user));
12260 if (ast_string_field_init(user, 32)) {
12261 user = user_unref(user);
12262 goto cleanup;
12263 }
12264 user->maxauthreq = maxauthreq;
12265 user->curauthreq = oldcurauthreq;
12266 user->prefs = prefs;
12267 user->capability = iax2_capability;
12268 user->encmethods = iax2_encryption;
12269 user->adsi = adsi;
12270 user->calltoken_required = CALLTOKEN_DEFAULT;
12271 ast_string_field_set(user, name, name);
12272 ast_string_field_set(user, language, language);
12273 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
12274 ast_clear_flag(user, IAX_HASCALLERID);
12275 ast_string_field_set(user, cid_name, "");
12276 ast_string_field_set(user, cid_num, "");
12277 ast_string_field_set(user, accountcode, accountcode);
12278 ast_string_field_set(user, mohinterpret, mohinterpret);
12279 ast_string_field_set(user, mohsuggest, mohsuggest);
12280 }
12281 if (!v) {
12282 v = alt;
12283 alt = NULL;
12284 }
12285 while(v) {
12286 if (!strcasecmp(v->name, "context")) {
12287 con = build_context(v->value);
12288 if (con) {
12289 if (conl)
12290 conl->next = con;
12291 else
12292 user->contexts = con;
12293 conl = con;
12294 }
12295 } else if (!strcasecmp(v->name, "permit") ||
12296 !strcasecmp(v->name, "deny")) {
12297 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12298 } else if (!strcasecmp(v->name, "setvar")) {
12299 varname = ast_strdupa(v->value);
12300 if (varname && (varval = strchr(varname,'='))) {
12301 *varval = '\0';
12302 varval++;
12303 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12304 tmpvar->next = user->vars;
12305 user->vars = tmpvar;
12306 }
12307 }
12308 } else if (!strcasecmp(v->name, "allow")) {
12309 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12310 } else if (!strcasecmp(v->name, "disallow")) {
12311 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12312 } else if (!strcasecmp(v->name, "trunk")) {
12313 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
12314 if (ast_test_flag(user, IAX_TRUNK) && !timer) {
12315 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12316 ast_clear_flag(user, IAX_TRUNK);
12317 }
12318 } else if (!strcasecmp(v->name, "auth")) {
12319 user->authmethods = get_auth_methods(v->value);
12320 } else if (!strcasecmp(v->name, "encryption")) {
12321 user->encmethods |= get_encrypt_methods(v->value);
12322 if (!user->encmethods) {
12323 ast_clear_flag(user, IAX_FORCE_ENCRYPT);
12324 }
12325 } else if (!strcasecmp(v->name, "forceencryption")) {
12326 if (ast_false(v->value)) {
12327 ast_clear_flag(user, IAX_FORCE_ENCRYPT);
12328 } else {
12329 user->encmethods |= get_encrypt_methods(v->value);
12330 if (user->encmethods) {
12331 ast_set_flag(user, IAX_FORCE_ENCRYPT);
12332 }
12333 }
12334 } else if (!strcasecmp(v->name, "transfer")) {
12335 if (!strcasecmp(v->value, "mediaonly")) {
12336 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12337 } else if (ast_true(v->value)) {
12338 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12339 } else
12340 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12341 } else if (!strcasecmp(v->name, "codecpriority")) {
12342 if(!strcasecmp(v->value, "caller"))
12343 ast_set_flag(user, IAX_CODEC_USER_FIRST);
12344 else if(!strcasecmp(v->value, "disabled"))
12345 ast_set_flag(user, IAX_CODEC_NOPREFS);
12346 else if(!strcasecmp(v->value, "reqonly")) {
12347 ast_set_flag(user, IAX_CODEC_NOCAP);
12348 ast_set_flag(user, IAX_CODEC_NOPREFS);
12349 }
12350 } else if (!strcasecmp(v->name, "immediate")) {
12351 ast_set2_flag(user, ast_true(v->value), IAX_IMMEDIATE);
12352 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12353 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
12354 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12355 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12356 } else if (!strcasecmp(v->name, "dbsecret")) {
12357 ast_string_field_set(user, dbsecret, v->value);
12358 } else if (!strcasecmp(v->name, "secret")) {
12359 if (!ast_strlen_zero(user->secret)) {
12360 char *old = ast_strdupa(user->secret);
12361
12362 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12363 } else
12364 ast_string_field_set(user, secret, v->value);
12365 } else if (!strcasecmp(v->name, "callerid")) {
12366 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12367 char name2[80];
12368 char num2[80];
12369 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12370 ast_string_field_set(user, cid_name, name2);
12371 ast_string_field_set(user, cid_num, num2);
12372 ast_set_flag(user, IAX_HASCALLERID);
12373 } else {
12374 ast_clear_flag(user, IAX_HASCALLERID);
12375 ast_string_field_set(user, cid_name, "");
12376 ast_string_field_set(user, cid_num, "");
12377 }
12378 } else if (!strcasecmp(v->name, "fullname")) {
12379 if (!ast_strlen_zero(v->value)) {
12380 ast_string_field_set(user, cid_name, v->value);
12381 ast_set_flag(user, IAX_HASCALLERID);
12382 } else {
12383 ast_string_field_set(user, cid_name, "");
12384 if (ast_strlen_zero(user->cid_num))
12385 ast_clear_flag(user, IAX_HASCALLERID);
12386 }
12387 } else if (!strcasecmp(v->name, "cid_number")) {
12388 if (!ast_strlen_zero(v->value)) {
12389 ast_string_field_set(user, cid_num, v->value);
12390 ast_set_flag(user, IAX_HASCALLERID);
12391 } else {
12392 ast_string_field_set(user, cid_num, "");
12393 if (ast_strlen_zero(user->cid_name))
12394 ast_clear_flag(user, IAX_HASCALLERID);
12395 }
12396 } else if (!strcasecmp(v->name, "accountcode")) {
12397 ast_string_field_set(user, accountcode, v->value);
12398 } else if (!strcasecmp(v->name, "mohinterpret")) {
12399 ast_string_field_set(user, mohinterpret, v->value);
12400 } else if (!strcasecmp(v->name, "mohsuggest")) {
12401 ast_string_field_set(user, mohsuggest, v->value);
12402 } else if (!strcasecmp(v->name, "parkinglot")) {
12403 ast_string_field_set(user, parkinglot, v->value);
12404 } else if (!strcasecmp(v->name, "language")) {
12405 ast_string_field_set(user, language, v->value);
12406 } else if (!strcasecmp(v->name, "amaflags")) {
12407 format = ast_cdr_amaflags2int(v->value);
12408 if (format < 0) {
12409 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12410 } else {
12411 user->amaflags = format;
12412 }
12413 } else if (!strcasecmp(v->name, "inkeys")) {
12414 ast_string_field_set(user, inkeys, v->value);
12415 } else if (!strcasecmp(v->name, "maxauthreq")) {
12416 user->maxauthreq = atoi(v->value);
12417 if (user->maxauthreq < 0)
12418 user->maxauthreq = 0;
12419 } else if (!strcasecmp(v->name, "adsi")) {
12420 user->adsi = ast_true(v->value);
12421 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12422
12423 if (ast_false(v->value)) {
12424 user->calltoken_required = CALLTOKEN_NO;
12425 } else if (!strcasecmp(v->value, "auto")) {
12426 user->calltoken_required = CALLTOKEN_AUTO;
12427 } else if (ast_true(v->value)) {
12428 user->calltoken_required = CALLTOKEN_YES;
12429 } else {
12430 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12431 }
12432 }
12433
12434 v = v->next;
12435 if (!v) {
12436 v = alt;
12437 alt = NULL;
12438 }
12439 }
12440 if (!user->authmethods) {
12441 if (!ast_strlen_zero(user->secret)) {
12442 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12443 if (!ast_strlen_zero(user->inkeys))
12444 user->authmethods |= IAX_AUTH_RSA;
12445 } else if (!ast_strlen_zero(user->inkeys)) {
12446 user->authmethods = IAX_AUTH_RSA;
12447 } else {
12448 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12449 }
12450 }
12451 ast_clear_flag(user, IAX_DELME);
12452 }
12453 cleanup:
12454 if (oldha)
12455 ast_free_ha(oldha);
12456 if (oldcon)
12457 free_context(oldcon);
12458 return user;
12459 }
12460
12461 static int peer_delme_cb(void *obj, void *arg, int flags)
12462 {
12463 struct iax2_peer *peer = obj;
12464
12465 ast_set_flag(peer, IAX_DELME);
12466
12467 return 0;
12468 }
12469
12470 static int user_delme_cb(void *obj, void *arg, int flags)
12471 {
12472 struct iax2_user *user = obj;
12473
12474 ast_set_flag(user, IAX_DELME);
12475
12476 return 0;
12477 }
12478
12479 static void delete_users(void)
12480 {
12481 struct iax2_registry *reg;
12482
12483 ao2_callback(users, 0, user_delme_cb, NULL);
12484
12485 AST_LIST_LOCK(®istrations);
12486 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12487 if (sched) {
12488 ast_sched_thread_del(sched, reg->expire);
12489 }
12490 if (reg->callno) {
12491 int callno = reg->callno;
12492 ast_mutex_lock(&iaxsl[callno]);
12493 if (iaxs[callno]) {
12494 iaxs[callno]->reg = NULL;
12495 iax2_destroy(callno);
12496 }
12497 ast_mutex_unlock(&iaxsl[callno]);
12498 }
12499 if (reg->dnsmgr)
12500 ast_dnsmgr_release(reg->dnsmgr);
12501 ast_free(reg);
12502 }
12503 AST_LIST_UNLOCK(®istrations);
12504
12505 ao2_callback(peers, 0, peer_delme_cb, NULL);
12506 }
12507
12508 static void prune_users(void)
12509 {
12510 struct iax2_user *user;
12511 struct ao2_iterator i;
12512
12513 i = ao2_iterator_init(users, 0);
12514 while ((user = ao2_iterator_next(&i))) {
12515 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
12516 ao2_unlink(users, user);
12517 }
12518 user_unref(user);
12519 }
12520 ao2_iterator_destroy(&i);
12521 }
12522
12523
12524 static void prune_peers(void)
12525 {
12526 struct iax2_peer *peer;
12527 struct ao2_iterator i;
12528
12529 i = ao2_iterator_init(peers, 0);
12530 while ((peer = ao2_iterator_next(&i))) {
12531 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
12532 unlink_peer(peer);
12533 }
12534 peer_unref(peer);
12535 }
12536 ao2_iterator_destroy(&i);
12537 }
12538
12539 static void set_config_destroy(void)
12540 {
12541 strcpy(accountcode, "");
12542 strcpy(language, "");
12543 strcpy(mohinterpret, "default");
12544 strcpy(mohsuggest, "");
12545 trunkmaxsize = MAX_TRUNKDATA;
12546 amaflags = 0;
12547 delayreject = 0;
12548 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
12549 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
12550 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
12551 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
12552 delete_users();
12553 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12554 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12555 }
12556
12557
12558 static int set_config(const char *config_file, int reload)
12559 {
12560 struct ast_config *cfg, *ucfg;
12561 int capability=iax2_capability;
12562 struct ast_variable *v;
12563 char *cat;
12564 const char *utype;
12565 const char *tosval;
12566 int format;
12567 int portno = IAX_DEFAULT_PORTNO;
12568 int x;
12569 int mtuv;
12570 struct iax2_user *user;
12571 struct iax2_peer *peer;
12572 struct ast_netsock *ns;
12573 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12574 #if 0
12575 static unsigned short int last_port=0;
12576 #endif
12577
12578 cfg = ast_config_load(config_file, config_flags);
12579
12580 if (!cfg) {
12581 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12582 return -1;
12583 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12584 ucfg = ast_config_load("users.conf", config_flags);
12585 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12586 return 0;
12587
12588 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12589 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
12590 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12591 ast_config_destroy(ucfg);
12592 return 0;
12593 }
12594 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
12595 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12596 return 0;
12597 } else {
12598 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12599 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
12600 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
12601 ast_config_destroy(cfg);
12602 return 0;
12603 }
12604 }
12605
12606 if (reload) {
12607 set_config_destroy();
12608 }
12609
12610
12611 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12612
12613
12614 memset(&globalflags, 0, sizeof(globalflags));
12615 ast_set_flag(&globalflags, IAX_RTUPDATE);
12616 ast_set_flag(&globalflags, IAX_SHRINKCALLERID);
12617
12618 #ifdef SO_NO_CHECK
12619 nochecksums = 0;
12620 #endif
12621
12622 default_parkinglot[0] = '\0';
12623
12624 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12625 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12626 global_max_trunk_mtu = MAX_TRUNK_MTU;
12627 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12628 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12629
12630 maxauthreq = 3;
12631
12632 srvlookup = 0;
12633
12634 v = ast_variable_browse(cfg, "general");
12635
12636
12637 tosval = ast_variable_retrieve(cfg, "general", "tos");
12638 if (tosval) {
12639 if (ast_str2tos(tosval, &qos.tos))
12640 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
12641 }
12642
12643 tosval = ast_variable_retrieve(cfg, "general", "cos");
12644 if (tosval) {
12645 if (ast_str2cos(tosval, &qos.cos))
12646 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
12647 }
12648 while(v) {
12649 if (!strcasecmp(v->name, "bindport")){
12650 if (reload)
12651 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
12652 else
12653 portno = atoi(v->value);
12654 } else if (!strcasecmp(v->name, "pingtime"))
12655 ping_time = atoi(v->value);
12656 else if (!strcasecmp(v->name, "iaxthreadcount")) {
12657 if (reload) {
12658 if (atoi(v->value) != iaxthreadcount)
12659 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
12660 } else {
12661 iaxthreadcount = atoi(v->value);
12662 if (iaxthreadcount < 1) {
12663 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
12664 iaxthreadcount = 1;
12665 } else if (iaxthreadcount > 256) {
12666 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
12667 iaxthreadcount = 256;
12668 }
12669 }
12670 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
12671 if (reload) {
12672 AST_LIST_LOCK(&dynamic_list);
12673 iaxmaxthreadcount = atoi(v->value);
12674 AST_LIST_UNLOCK(&dynamic_list);
12675 } else {
12676 iaxmaxthreadcount = atoi(v->value);
12677 if (iaxmaxthreadcount < 0) {
12678 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
12679 iaxmaxthreadcount = 0;
12680 } else if (iaxmaxthreadcount > 256) {
12681 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
12682 iaxmaxthreadcount = 256;
12683 }
12684 }
12685 } else if (!strcasecmp(v->name, "nochecksums")) {
12686 #ifdef SO_NO_CHECK
12687 if (ast_true(v->value))
12688 nochecksums = 1;
12689 else
12690 nochecksums = 0;
12691 #else
12692 if (ast_true(v->value))
12693 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
12694 #endif
12695 }
12696 else if (!strcasecmp(v->name, "maxjitterbuffer"))
12697 maxjitterbuffer = atoi(v->value);
12698 else if (!strcasecmp(v->name, "resyncthreshold"))
12699 resyncthreshold = atoi(v->value);
12700 else if (!strcasecmp(v->name, "maxjitterinterps"))
12701 maxjitterinterps = atoi(v->value);
12702 else if (!strcasecmp(v->name, "jittertargetextra"))
12703 jittertargetextra = atoi(v->value);
12704 else if (!strcasecmp(v->name, "lagrqtime"))
12705 lagrq_time = atoi(v->value);
12706 else if (!strcasecmp(v->name, "maxregexpire"))
12707 max_reg_expire = atoi(v->value);
12708 else if (!strcasecmp(v->name, "minregexpire"))
12709 min_reg_expire = atoi(v->value);
12710 else if (!strcasecmp(v->name, "bindaddr")) {
12711 if (reload) {
12712 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
12713 } else {
12714 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
12715 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
12716 } else {
12717 if (strchr(v->value, ':'))
12718 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
12719 else
12720 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
12721 if (defaultsockfd < 0)
12722 defaultsockfd = ast_netsock_sockfd(ns);
12723 ast_netsock_unref(ns);
12724 }
12725 }
12726 } else if (!strcasecmp(v->name, "authdebug")) {
12727 authdebug = ast_true(v->value);
12728 } else if (!strcasecmp(v->name, "encryption")) {
12729 iax2_encryption |= get_encrypt_methods(v->value);
12730 if (!iax2_encryption) {
12731 ast_clear_flag((&globalflags), IAX_FORCE_ENCRYPT);
12732 }
12733 } else if (!strcasecmp(v->name, "forceencryption")) {
12734 if (ast_false(v->value)) {
12735 ast_clear_flag((&globalflags), IAX_FORCE_ENCRYPT);
12736 } else {
12737 iax2_encryption |= get_encrypt_methods(v->value);
12738 if (iax2_encryption) {
12739 ast_set_flag((&globalflags), IAX_FORCE_ENCRYPT);
12740 }
12741 }
12742 } else if (!strcasecmp(v->name, "transfer")) {
12743 if (!strcasecmp(v->value, "mediaonly")) {
12744 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12745 } else if (ast_true(v->value)) {
12746 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12747 } else
12748 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12749 } else if (!strcasecmp(v->name, "codecpriority")) {
12750 if(!strcasecmp(v->value, "caller"))
12751 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
12752 else if(!strcasecmp(v->value, "disabled"))
12753 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12754 else if(!strcasecmp(v->value, "reqonly")) {
12755 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
12756 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12757 }
12758 } else if (!strcasecmp(v->name, "jitterbuffer"))
12759 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
12760 else if (!strcasecmp(v->name, "forcejitterbuffer"))
12761 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
12762 else if (!strcasecmp(v->name, "delayreject"))
12763 delayreject = ast_true(v->value);
12764 else if (!strcasecmp(v->name, "allowfwdownload"))
12765 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
12766 else if (!strcasecmp(v->name, "rtcachefriends"))
12767 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
12768 else if (!strcasecmp(v->name, "rtignoreregexpire"))
12769 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
12770 else if (!strcasecmp(v->name, "rtupdate"))
12771 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
12772 else if (!strcasecmp(v->name, "trunktimestamps"))
12773 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
12774 else if (!strcasecmp(v->name, "rtautoclear")) {
12775 int i = atoi(v->value);
12776 if(i > 0)
12777 global_rtautoclear = i;
12778 else
12779 i = 0;
12780 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
12781 } else if (!strcasecmp(v->name, "trunkfreq")) {
12782 trunkfreq = atoi(v->value);
12783 if (trunkfreq < 10)
12784 trunkfreq = 10;
12785 } else if (!strcasecmp(v->name, "trunkmtu")) {
12786 mtuv = atoi(v->value);
12787 if (mtuv == 0 )
12788 global_max_trunk_mtu = 0;
12789 else if (mtuv >= 172 && mtuv < 4000)
12790 global_max_trunk_mtu = mtuv;
12791 else
12792 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
12793 mtuv, v->lineno);
12794 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
12795 trunkmaxsize = atoi(v->value);
12796 if (trunkmaxsize == 0)
12797 trunkmaxsize = MAX_TRUNKDATA;
12798 } else if (!strcasecmp(v->name, "autokill")) {
12799 if (sscanf(v->value, "%30d", &x) == 1) {
12800 if (x >= 0)
12801 autokill = x;
12802 else
12803 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
12804 } else if (ast_true(v->value)) {
12805 autokill = DEFAULT_MAXMS;
12806 } else {
12807 autokill = 0;
12808 }
12809 } else if (!strcasecmp(v->name, "bandwidth")) {
12810 if (!strcasecmp(v->value, "low")) {
12811 capability = IAX_CAPABILITY_LOWBANDWIDTH;
12812 } else if (!strcasecmp(v->value, "medium")) {
12813 capability = IAX_CAPABILITY_MEDBANDWIDTH;
12814 } else if (!strcasecmp(v->value, "high")) {
12815 capability = IAX_CAPABILITY_FULLBANDWIDTH;
12816 } else
12817 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
12818 } else if (!strcasecmp(v->name, "allow")) {
12819 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
12820 } else if (!strcasecmp(v->name, "disallow")) {
12821 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
12822 } else if (!strcasecmp(v->name, "register")) {
12823 iax2_register(v->value, v->lineno);
12824 } else if (!strcasecmp(v->name, "iaxcompat")) {
12825 iaxcompat = ast_true(v->value);
12826 } else if (!strcasecmp(v->name, "regcontext")) {
12827 ast_copy_string(regcontext, v->value, sizeof(regcontext));
12828
12829 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
12830 } else if (!strcasecmp(v->name, "tos")) {
12831 if (ast_str2tos(v->value, &qos.tos))
12832 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
12833 } else if (!strcasecmp(v->name, "cos")) {
12834 if (ast_str2cos(v->value, &qos.cos))
12835 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
12836 } else if (!strcasecmp(v->name, "parkinglot")) {
12837 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
12838 } else if (!strcasecmp(v->name, "accountcode")) {
12839 ast_copy_string(accountcode, v->value, sizeof(accountcode));
12840 } else if (!strcasecmp(v->name, "mohinterpret")) {
12841 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
12842 } else if (!strcasecmp(v->name, "mohsuggest")) {
12843 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
12844 } else if (!strcasecmp(v->name, "amaflags")) {
12845 format = ast_cdr_amaflags2int(v->value);
12846 if (format < 0) {
12847 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12848 } else {
12849 amaflags = format;
12850 }
12851 } else if (!strcasecmp(v->name, "language")) {
12852 ast_copy_string(language, v->value, sizeof(language));
12853 } else if (!strcasecmp(v->name, "maxauthreq")) {
12854 maxauthreq = atoi(v->value);
12855 if (maxauthreq < 0)
12856 maxauthreq = 0;
12857 } else if (!strcasecmp(v->name, "adsi")) {
12858 adsi = ast_true(v->value);
12859 } else if (!strcasecmp(v->name, "srvlookup")) {
12860 srvlookup = ast_true(v->value);
12861 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12862 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
12863 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
12864 }
12865 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
12866 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
12867 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);
12868 }
12869 } else if (!strcasecmp(v->name, "calltokenoptional")) {
12870 if (add_calltoken_ignore(v->value)) {
12871 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
12872 }
12873 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
12874 if (ast_true(v->value)) {
12875 ast_set_flag((&globalflags), IAX_SHRINKCALLERID);
12876 } else if (ast_false(v->value)) {
12877 ast_clear_flag((&globalflags), IAX_SHRINKCALLERID);
12878 } else {
12879 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
12880 }
12881 }
12882
12883 v = v->next;
12884 }
12885
12886 if (defaultsockfd < 0) {
12887 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
12888 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
12889 } else {
12890 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
12891 defaultsockfd = ast_netsock_sockfd(ns);
12892 ast_netsock_unref(ns);
12893 }
12894 }
12895 if (reload) {
12896 ast_netsock_release(outsock);
12897 outsock = ast_netsock_list_alloc();
12898 if (!outsock) {
12899 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12900 return -1;
12901 }
12902 ast_netsock_init(outsock);
12903 }
12904
12905 if (min_reg_expire > max_reg_expire) {
12906 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
12907 min_reg_expire, max_reg_expire, max_reg_expire);
12908 min_reg_expire = max_reg_expire;
12909 }
12910 iax2_capability = capability;
12911
12912 if (ucfg) {
12913 struct ast_variable *gen;
12914 int genhasiax;
12915 int genregisteriax;
12916 const char *hasiax, *registeriax;
12917
12918 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
12919 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
12920 gen = ast_variable_browse(ucfg, "general");
12921 cat = ast_category_browse(ucfg, NULL);
12922 while (cat) {
12923 if (strcasecmp(cat, "general")) {
12924 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
12925 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
12926 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
12927
12928 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
12929 if (user) {
12930 ao2_link(users, user);
12931 user = user_unref(user);
12932 }
12933 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
12934 if (peer) {
12935 if (ast_test_flag(peer, IAX_DYNAMIC))
12936 reg_source_db(peer);
12937 ao2_link(peers, peer);
12938 peer = peer_unref(peer);
12939 }
12940 }
12941 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
12942 char tmp[256];
12943 const char *host = ast_variable_retrieve(ucfg, cat, "host");
12944 const char *username = ast_variable_retrieve(ucfg, cat, "username");
12945 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
12946 if (!host)
12947 host = ast_variable_retrieve(ucfg, "general", "host");
12948 if (!username)
12949 username = ast_variable_retrieve(ucfg, "general", "username");
12950 if (!secret)
12951 secret = ast_variable_retrieve(ucfg, "general", "secret");
12952 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
12953 if (!ast_strlen_zero(secret))
12954 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
12955 else
12956 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
12957 iax2_register(tmp, 0);
12958 }
12959 }
12960 }
12961 cat = ast_category_browse(ucfg, cat);
12962 }
12963 ast_config_destroy(ucfg);
12964 }
12965
12966 cat = ast_category_browse(cfg, NULL);
12967 while(cat) {
12968 if (strcasecmp(cat, "general")) {
12969 utype = ast_variable_retrieve(cfg, cat, "type");
12970 if (!strcasecmp(cat, "callnumberlimits")) {
12971 build_callno_limits(ast_variable_browse(cfg, cat));
12972 } else if (utype) {
12973 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
12974 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
12975 if (user) {
12976 ao2_link(users, user);
12977 user = user_unref(user);
12978 }
12979 }
12980 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
12981 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
12982 if (peer) {
12983 if (ast_test_flag(peer, IAX_DYNAMIC))
12984 reg_source_db(peer);
12985 ao2_link(peers, peer);
12986 peer = peer_unref(peer);
12987 }
12988 } else if (strcasecmp(utype, "user")) {
12989 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
12990 }
12991 } else
12992 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
12993 }
12994 cat = ast_category_browse(cfg, cat);
12995 }
12996 ast_config_destroy(cfg);
12997 return 1;
12998 }
12999
13000 static void poke_all_peers(void)
13001 {
13002 struct ao2_iterator i;
13003 struct iax2_peer *peer;
13004
13005 i = ao2_iterator_init(peers, 0);
13006 while ((peer = ao2_iterator_next(&i))) {
13007 iax2_poke_peer(peer, 0);
13008 peer_unref(peer);
13009 }
13010 ao2_iterator_destroy(&i);
13011 }
13012 static int reload_config(void)
13013 {
13014 static const char config[] = "iax.conf";
13015 struct iax2_registry *reg;
13016
13017 if (set_config(config, 1) > 0) {
13018 prune_peers();
13019 prune_users();
13020 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13021 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13022 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13023 trunk_timed = trunk_untimed = 0;
13024 trunk_nmaxmtu = trunk_maxmtu = 0;
13025 memset(&debugaddr, '\0', sizeof(debugaddr));
13026
13027 AST_LIST_LOCK(®istrations);
13028 AST_LIST_TRAVERSE(®istrations, reg, entry)
13029 iax2_do_register(reg);
13030 AST_LIST_UNLOCK(®istrations);
13031
13032
13033 poke_all_peers();
13034 }
13035
13036 reload_firmware(0);
13037 iax_provision_reload(1);
13038 ast_unload_realtime("iaxpeers");
13039
13040 return 0;
13041 }
13042
13043 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13044 {
13045 switch (cmd) {
13046 case CLI_INIT:
13047 e->command = "iax2 reload";
13048 e->usage =
13049 "Usage: iax2 reload\n"
13050 " Reloads IAX configuration from iax.conf\n";
13051 return NULL;
13052 case CLI_GENERATE:
13053 return NULL;
13054 }
13055
13056 reload_config();
13057
13058 return CLI_SUCCESS;
13059 }
13060
13061 static int reload(void)
13062 {
13063 return reload_config();
13064 }
13065
13066 static int cache_get_callno_locked(const char *data)
13067 {
13068 struct sockaddr_in sin;
13069 int x;
13070 int callno;
13071 struct iax_ie_data ied;
13072 struct create_addr_info cai;
13073 struct parsed_dial_string pds;
13074 char *tmpstr;
13075
13076 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13077
13078
13079 if (!ast_mutex_trylock(&iaxsl[x])) {
13080 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13081 return x;
13082 ast_mutex_unlock(&iaxsl[x]);
13083 }
13084 }
13085
13086
13087
13088 memset(&cai, 0, sizeof(cai));
13089 memset(&ied, 0, sizeof(ied));
13090 memset(&pds, 0, sizeof(pds));
13091
13092 tmpstr = ast_strdupa(data);
13093 parse_dial_string(tmpstr, &pds);
13094
13095 if (ast_strlen_zero(pds.peer)) {
13096 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13097 return -1;
13098 }
13099
13100
13101 if (create_addr(pds.peer, NULL, &sin, &cai))
13102 return -1;
13103
13104 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13105 pds.peer, pds.username, pds.password, pds.context);
13106
13107 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13108 if (callno < 1) {
13109 ast_log(LOG_WARNING, "Unable to create call\n");
13110 return -1;
13111 }
13112
13113 ast_string_field_set(iaxs[callno], dproot, data);
13114 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13115
13116 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13117 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13118
13119
13120
13121 if (pds.exten)
13122 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13123 if (pds.username)
13124 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13125 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13126 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13127
13128 if (pds.password)
13129 ast_string_field_set(iaxs[callno], secret, pds.password);
13130 if (pds.key)
13131 ast_string_field_set(iaxs[callno], outkey, pds.key);
13132
13133 add_empty_calltoken_ie(iaxs[callno], &ied);
13134 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13135
13136 return callno;
13137 }
13138
13139 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13140 {
13141 struct iax2_dpcache *dp = NULL;
13142 struct timeval now = ast_tvnow();
13143 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13144 struct ast_channel *c = NULL;
13145 struct ast_frame *f = NULL;
13146
13147 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13148 if (ast_tvcmp(now, dp->expiry) > 0) {
13149 AST_LIST_REMOVE_CURRENT(cache_list);
13150 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13151 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13152 else
13153 ast_free(dp);
13154 continue;
13155 }
13156 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13157 break;
13158 }
13159 AST_LIST_TRAVERSE_SAFE_END;
13160
13161 if (!dp) {
13162
13163
13164 if ((callno = cache_get_callno_locked(data)) < 0) {
13165 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13166 return NULL;
13167 }
13168 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13169 ast_mutex_unlock(&iaxsl[callno]);
13170 return NULL;
13171 }
13172 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13173 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13174 dp->expiry = ast_tvnow();
13175 dp->orig = dp->expiry;
13176
13177 dp->expiry.tv_sec += iaxdefaultdpcache;
13178 dp->flags = CACHE_FLAG_PENDING;
13179 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13180 dp->waiters[x] = -1;
13181
13182 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13183 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13184
13185 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13186 iax2_dprequest(dp, callno);
13187 ast_mutex_unlock(&iaxsl[callno]);
13188 }
13189
13190
13191 if (dp->flags & CACHE_FLAG_PENDING) {
13192
13193
13194 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13195
13196 if (dp->waiters[x] < 0)
13197 break;
13198 }
13199 if (x >= ARRAY_LEN(dp->waiters)) {
13200 ast_log(LOG_WARNING, "No more waiter positions available\n");
13201 return NULL;
13202 }
13203 if (pipe(com)) {
13204 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13205 return NULL;
13206 }
13207 dp->waiters[x] = com[1];
13208
13209 timeout = iaxdefaulttimeout * 1000;
13210
13211 AST_LIST_UNLOCK(&dpcache);
13212
13213 if (chan)
13214 old = ast_channel_defer_dtmf(chan);
13215 doabort = 0;
13216 while(timeout) {
13217 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13218 if (outfd > -1)
13219 break;
13220 if (!c)
13221 continue;
13222 if (!(f = ast_read(c))) {
13223 doabort = 1;
13224 break;
13225 }
13226 ast_frfree(f);
13227 }
13228 if (!timeout) {
13229 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13230 }
13231 AST_LIST_LOCK(&dpcache);
13232 dp->waiters[x] = -1;
13233 close(com[1]);
13234 close(com[0]);
13235 if (doabort) {
13236
13237
13238 if (!old && chan)
13239 ast_channel_undefer_dtmf(chan);
13240 return NULL;
13241 }
13242 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13243
13244 if (dp->flags & CACHE_FLAG_PENDING) {
13245
13246
13247 dp->flags &= ~CACHE_FLAG_PENDING;
13248 dp->flags |= CACHE_FLAG_TIMEOUT;
13249
13250
13251 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13252 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13253 if (dp->waiters[x] > -1) {
13254 if (write(dp->waiters[x], "asdf", 4) < 0) {
13255 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13256 }
13257 }
13258 }
13259 }
13260 }
13261
13262 if (!old && chan)
13263 ast_channel_undefer_dtmf(chan);
13264 }
13265 return dp;
13266 }
13267
13268
13269 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13270 {
13271 int res = 0;
13272 struct iax2_dpcache *dp = NULL;
13273 #if 0
13274 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13275 #endif
13276 if ((priority != 1) && (priority != 2))
13277 return 0;
13278
13279 AST_LIST_LOCK(&dpcache);
13280 if ((dp = find_cache(chan, data, context, exten, priority))) {
13281 if (dp->flags & CACHE_FLAG_EXISTS)
13282 res = 1;
13283 } else {
13284 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13285 }
13286 AST_LIST_UNLOCK(&dpcache);
13287
13288 return res;
13289 }
13290
13291
13292 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13293 {
13294 int res = 0;
13295 struct iax2_dpcache *dp = NULL;
13296 #if 0
13297 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13298 #endif
13299 if ((priority != 1) && (priority != 2))
13300 return 0;
13301
13302 AST_LIST_LOCK(&dpcache);
13303 if ((dp = find_cache(chan, data, context, exten, priority))) {
13304 if (dp->flags & CACHE_FLAG_CANEXIST)
13305 res = 1;
13306 } else {
13307 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13308 }
13309 AST_LIST_UNLOCK(&dpcache);
13310
13311 return res;
13312 }
13313
13314
13315 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13316 {
13317 int res = 0;
13318 struct iax2_dpcache *dp = NULL;
13319 #if 0
13320 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13321 #endif
13322 if ((priority != 1) && (priority != 2))
13323 return 0;
13324
13325 AST_LIST_LOCK(&dpcache);
13326 if ((dp = find_cache(chan, data, context, exten, priority))) {
13327 if (dp->flags & CACHE_FLAG_MATCHMORE)
13328 res = 1;
13329 } else {
13330 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13331 }
13332 AST_LIST_UNLOCK(&dpcache);
13333
13334 return res;
13335 }
13336
13337
13338 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13339 {
13340 char odata[256];
13341 char req[256];
13342 char *ncontext;
13343 struct iax2_dpcache *dp = NULL;
13344 struct ast_app *dial = NULL;
13345 #if 0
13346 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);
13347 #endif
13348 if (priority == 2) {
13349
13350 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13351 if (dialstatus) {
13352 dial = pbx_findapp(dialstatus);
13353 if (dial)
13354 pbx_exec(chan, dial, "");
13355 }
13356 return -1;
13357 } else if (priority != 1)
13358 return -1;
13359
13360 AST_LIST_LOCK(&dpcache);
13361 if ((dp = find_cache(chan, data, context, exten, priority))) {
13362 if (dp->flags & CACHE_FLAG_EXISTS) {
13363 ast_copy_string(odata, data, sizeof(odata));
13364 ncontext = strchr(odata, '/');
13365 if (ncontext) {
13366 *ncontext = '\0';
13367 ncontext++;
13368 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13369 } else {
13370 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13371 }
13372 ast_verb(3, "Executing Dial('%s')\n", req);
13373 } else {
13374 AST_LIST_UNLOCK(&dpcache);
13375 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13376 return -1;
13377 }
13378 }
13379 AST_LIST_UNLOCK(&dpcache);
13380
13381 if ((dial = pbx_findapp("Dial")))
13382 return pbx_exec(chan, dial, req);
13383 else
13384 ast_log(LOG_WARNING, "No dial application registered\n");
13385
13386 return -1;
13387 }
13388
13389 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13390 {
13391 struct iax2_peer *peer;
13392 char *peername, *colname;
13393
13394 peername = ast_strdupa(data);
13395
13396
13397 if (!strcmp(peername,"CURRENTCHANNEL")) {
13398 unsigned short callno;
13399 if (chan->tech != &iax2_tech)
13400 return -1;
13401 callno = PTR_TO_CALLNO(chan->tech_pvt);
13402 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13403 return 0;
13404 }
13405
13406 if ((colname = strchr(peername, ',')))
13407 *colname++ = '\0';
13408 else
13409 colname = "ip";
13410
13411 if (!(peer = find_peer(peername, 1)))
13412 return -1;
13413
13414 if (!strcasecmp(colname, "ip")) {
13415 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
13416 } else if (!strcasecmp(colname, "status")) {
13417 peer_status(peer, buf, len);
13418 } else if (!strcasecmp(colname, "mailbox")) {
13419 ast_copy_string(buf, peer->mailbox, len);
13420 } else if (!strcasecmp(colname, "context")) {
13421 ast_copy_string(buf, peer->context, len);
13422 } else if (!strcasecmp(colname, "expire")) {
13423 snprintf(buf, len, "%d", peer->expire);
13424 } else if (!strcasecmp(colname, "dynamic")) {
13425 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13426 } else if (!strcasecmp(colname, "callerid_name")) {
13427 ast_copy_string(buf, peer->cid_name, len);
13428 } else if (!strcasecmp(colname, "callerid_num")) {
13429 ast_copy_string(buf, peer->cid_num, len);
13430 } else if (!strcasecmp(colname, "codecs")) {
13431 ast_getformatname_multiple(buf, len -1, peer->capability);
13432 } else if (!strncasecmp(colname, "codec[", 6)) {
13433 char *codecnum, *ptr;
13434 int codec = 0;
13435
13436 codecnum = strchr(colname, '[');
13437 *codecnum = '\0';
13438 codecnum++;
13439 if ((ptr = strchr(codecnum, ']'))) {
13440 *ptr = '\0';
13441 }
13442 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13443 ast_copy_string(buf, ast_getformatname(codec), len);
13444 } else {
13445 buf[0] = '\0';
13446 }
13447 } else {
13448 buf[0] = '\0';
13449 }
13450
13451 peer_unref(peer);
13452
13453 return 0;
13454 }
13455
13456 struct ast_custom_function iaxpeer_function = {
13457 .name = "IAXPEER",
13458 .read = function_iaxpeer,
13459 };
13460
13461 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13462 {
13463 struct chan_iax2_pvt *pvt;
13464 unsigned int callno;
13465 int res = 0;
13466
13467 if (!chan || chan->tech != &iax2_tech) {
13468 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13469 return -1;
13470 }
13471
13472 callno = PTR_TO_CALLNO(chan->tech_pvt);
13473 ast_mutex_lock(&iaxsl[callno]);
13474 if (!(pvt = iaxs[callno])) {
13475 ast_mutex_unlock(&iaxsl[callno]);
13476 return -1;
13477 }
13478
13479 if (!strcasecmp(args, "osptoken")) {
13480 ast_copy_string(buf, pvt->osptoken, buflen);
13481 } else if (!strcasecmp(args, "peerip")) {
13482 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13483 } else if (!strcasecmp(args, "peername")) {
13484 ast_copy_string(buf, pvt->username, buflen);
13485 } else {
13486 res = -1;
13487 }
13488
13489 ast_mutex_unlock(&iaxsl[callno]);
13490
13491 return res;
13492 }
13493
13494
13495 static int iax2_devicestate(void *data)
13496 {
13497 struct parsed_dial_string pds;
13498 char *tmp = ast_strdupa(data);
13499 struct iax2_peer *p;
13500 int res = AST_DEVICE_INVALID;
13501
13502 memset(&pds, 0, sizeof(pds));
13503 parse_dial_string(tmp, &pds);
13504
13505 if (ast_strlen_zero(pds.peer)) {
13506 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13507 return res;
13508 }
13509
13510 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13511
13512
13513 if (!(p = find_peer(pds.peer, 1)))
13514 return res;
13515
13516 res = AST_DEVICE_UNAVAILABLE;
13517 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13518 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13519
13520 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
13521 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13522
13523
13524 if (p->historicms == 0 || p->historicms <= p->maxms)
13525
13526 res = AST_DEVICE_UNKNOWN;
13527 }
13528
13529 peer_unref(p);
13530
13531 return res;
13532 }
13533
13534 static struct ast_switch iax2_switch =
13535 {
13536 name: "IAX2",
13537 description: "IAX Remote Dialplan Switch",
13538 exists: iax2_exists,
13539 canmatch: iax2_canmatch,
13540 exec: iax2_exec,
13541 matchmore: iax2_matchmore,
13542 };
13543
13544
13545
13546
13547
13548
13549
13550
13551
13552
13553
13554
13555
13556
13557
13558
13559
13560
13561
13562
13563
13564
13565
13566
13567
13568
13569
13570
13571
13572
13573
13574
13575
13576
13577
13578
13579
13580
13581
13582
13583
13584
13585
13586
13587
13588
13589
13590
13591
13592
13593
13594
13595
13596
13597
13598
13599
13600
13601
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
13621
13622
13623
13624
13625
13626
13627
13628
13629
13630
13631
13632
13633
13634
13635
13636
13637
13638
13639
13640
13641
13642
13643
13644
13645
13646
13647
13648 static struct ast_cli_entry cli_iax2[] = {
13649 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
13650 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
13651 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
13652 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
13653 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
13654 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
13655 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
13656 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
13657 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
13658 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
13659 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
13660 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
13661 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
13662 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
13663 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
13664 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
13665 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
13666 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
13667 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
13668 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
13669 #ifdef IAXTESTS
13670 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
13671 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
13672 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
13673 #endif
13674 };
13675
13676 static void cleanup_thread_list(void *head)
13677 {
13678 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
13679 struct iax2_thread_list *list_head = head;
13680 struct iax2_thread *thread;
13681
13682 AST_LIST_LOCK(list_head);
13683 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
13684 pthread_t thread_id = thread->threadid;
13685
13686 thread->stop = 1;
13687 signal_condition(&thread->lock, &thread->cond);
13688
13689 AST_LIST_UNLOCK(list_head);
13690 pthread_join(thread_id, NULL);
13691 AST_LIST_LOCK(list_head);
13692 }
13693 AST_LIST_UNLOCK(list_head);
13694 }
13695
13696 static int __unload_module(void)
13697 {
13698 struct ast_context *con;
13699 int x;
13700
13701 ast_manager_unregister("IAXpeers");
13702 ast_manager_unregister("IAXpeerlist");
13703 ast_manager_unregister("IAXnetstats");
13704 ast_manager_unregister("IAXregistry");
13705 ast_unregister_application(papp);
13706 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
13707 ast_unregister_switch(&iax2_switch);
13708 ast_channel_unregister(&iax2_tech);
13709
13710 if (netthreadid != AST_PTHREADT_NULL) {
13711 AST_LIST_LOCK(&frame_queue);
13712 pthread_cancel(netthreadid);
13713 AST_LIST_UNLOCK(&frame_queue);
13714 pthread_join(netthreadid, NULL);
13715 }
13716
13717 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13718 if (iaxs[x]) {
13719 iax2_destroy(x);
13720 }
13721 }
13722
13723
13724 cleanup_thread_list(&idle_list);
13725 cleanup_thread_list(&active_list);
13726 cleanup_thread_list(&dynamic_list);
13727
13728 ast_netsock_release(netsock);
13729 ast_netsock_release(outsock);
13730
13731 delete_users();
13732 iax_provision_unload();
13733 reload_firmware(1);
13734
13735 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13736 ast_mutex_destroy(&iaxsl[x]);
13737 }
13738
13739 ao2_ref(peers, -1);
13740 ao2_ref(users, -1);
13741 ao2_ref(iax_peercallno_pvts, -1);
13742 ao2_ref(iax_transfercallno_pvts, -1);
13743 ao2_ref(peercnts, -1);
13744 ao2_ref(callno_limits, -1);
13745 ao2_ref(calltoken_ignores, -1);
13746 ao2_ref(callno_pool, -1);
13747 ao2_ref(callno_pool_trunk, -1);
13748 if (timer) {
13749 ast_timer_close(timer);
13750 }
13751 sched = ast_sched_thread_destroy(sched);
13752
13753 con = ast_context_find(regcontext);
13754 if (con)
13755 ast_context_destroy(con, "IAX2");
13756 ast_unload_realtime("iaxpeers");
13757 return 0;
13758 }
13759
13760 static int unload_module(void)
13761 {
13762 ast_custom_function_unregister(&iaxpeer_function);
13763 ast_custom_function_unregister(&iaxvar_function);
13764 return __unload_module();
13765 }
13766
13767 static int peer_set_sock_cb(void *obj, void *arg, int flags)
13768 {
13769 struct iax2_peer *peer = obj;
13770
13771 if (peer->sockfd < 0)
13772 peer->sockfd = defaultsockfd;
13773
13774 return 0;
13775 }
13776
13777 static int pvt_hash_cb(const void *obj, const int flags)
13778 {
13779 const struct chan_iax2_pvt *pvt = obj;
13780
13781 return pvt->peercallno;
13782 }
13783
13784 static int pvt_cmp_cb(void *obj, void *arg, int flags)
13785 {
13786 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13787
13788
13789
13790
13791 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
13792 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13793 }
13794
13795 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
13796 {
13797 const struct chan_iax2_pvt *pvt = obj;
13798
13799 return pvt->transfercallno;
13800 }
13801
13802 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
13803 {
13804 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13805
13806
13807
13808
13809 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
13810 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13811 }
13812
13813 static int load_objects(void)
13814 {
13815 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
13816 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
13817
13818 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
13819 goto container_fail;
13820 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
13821 goto container_fail;
13822 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
13823 goto container_fail;
13824 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
13825 goto container_fail;
13826 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
13827 goto container_fail;
13828 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13829 goto container_fail;
13830 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13831 goto container_fail;
13832 } else if (create_callno_pools()) {
13833 goto container_fail;
13834 }
13835
13836 return 0;
13837
13838 container_fail:
13839 if (peers) {
13840 ao2_ref(peers, -1);
13841 }
13842 if (users) {
13843 ao2_ref(users, -1);
13844 }
13845 if (iax_peercallno_pvts) {
13846 ao2_ref(iax_peercallno_pvts, -1);
13847 }
13848 if (iax_transfercallno_pvts) {
13849 ao2_ref(iax_transfercallno_pvts, -1);
13850 }
13851 if (peercnts) {
13852 ao2_ref(peercnts, -1);
13853 }
13854 if (callno_limits) {
13855 ao2_ref(callno_limits, -1);
13856 }
13857 if (calltoken_ignores) {
13858 ao2_ref(calltoken_ignores, -1);
13859 }
13860 if (callno_pool) {
13861 ao2_ref(callno_pool, -1);
13862 }
13863 if (callno_pool_trunk) {
13864 ao2_ref(callno_pool_trunk, -1);
13865 }
13866 return AST_MODULE_LOAD_FAILURE;
13867 }
13868
13869
13870
13871
13872 static int load_module(void)
13873 {
13874 static const char config[] = "iax.conf";
13875 int x = 0;
13876 struct iax2_registry *reg = NULL;
13877
13878 if (load_objects()) {
13879 return AST_MODULE_LOAD_FAILURE;
13880 }
13881
13882 memset(iaxs, 0, sizeof(iaxs));
13883
13884 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13885 ast_mutex_init(&iaxsl[x]);
13886 }
13887
13888 if (!(sched = ast_sched_thread_create())) {
13889 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
13890 return AST_MODULE_LOAD_FAILURE;
13891 }
13892
13893 if (!(io = io_context_create())) {
13894 ast_log(LOG_ERROR, "Failed to create I/O context\n");
13895 sched = ast_sched_thread_destroy(sched);
13896 return AST_MODULE_LOAD_FAILURE;
13897 }
13898
13899 if (!(netsock = ast_netsock_list_alloc())) {
13900 ast_log(LOG_ERROR, "Failed to create netsock list\n");
13901 io_context_destroy(io);
13902 sched = ast_sched_thread_destroy(sched);
13903 return AST_MODULE_LOAD_FAILURE;
13904 }
13905 ast_netsock_init(netsock);
13906
13907 outsock = ast_netsock_list_alloc();
13908 if (!outsock) {
13909 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13910 io_context_destroy(io);
13911 sched = ast_sched_thread_destroy(sched);
13912 return AST_MODULE_LOAD_FAILURE;
13913 }
13914 ast_netsock_init(outsock);
13915
13916 randomcalltokendata = ast_random();
13917
13918 iax_set_output(iax_debug_output);
13919 iax_set_error(iax_error_output);
13920 jb_setoutput(jb_error_output, jb_warning_output, NULL);
13921
13922 if ((timer = ast_timer_open())) {
13923 ast_timer_set_rate(timer, trunkfreq);
13924 }
13925
13926 if (set_config(config, 0) == -1) {
13927 if (timer) {
13928 ast_timer_close(timer);
13929 }
13930 return AST_MODULE_LOAD_DECLINE;
13931 }
13932
13933 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
13934
13935 ast_register_application_xml(papp, iax2_prov_app);
13936
13937 ast_custom_function_register(&iaxpeer_function);
13938 ast_custom_function_register(&iaxvar_function);
13939
13940 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
13941 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
13942 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
13943 ast_manager_register( "IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry, "Show IAX registrations");
13944
13945 if (ast_channel_register(&iax2_tech)) {
13946 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
13947 __unload_module();
13948 return AST_MODULE_LOAD_FAILURE;
13949 }
13950
13951 if (ast_register_switch(&iax2_switch)) {
13952 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
13953 }
13954
13955 if (start_network_thread()) {
13956 ast_log(LOG_ERROR, "Unable to start network thread\n");
13957 __unload_module();
13958 return AST_MODULE_LOAD_FAILURE;
13959 } else {
13960 ast_verb(2, "IAX Ready and Listening\n");
13961 }
13962
13963 AST_LIST_LOCK(®istrations);
13964 AST_LIST_TRAVERSE(®istrations, reg, entry)
13965 iax2_do_register(reg);
13966 AST_LIST_UNLOCK(®istrations);
13967
13968 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
13969 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
13970
13971
13972 reload_firmware(0);
13973 iax_provision_reload(0);
13974
13975 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
13976
13977 return AST_MODULE_LOAD_SUCCESS;
13978 }
13979
13980 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
13981 .load = load_module,
13982 .unload = unload_module,
13983 .reload = reload,
13984 );