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: 273642 $")
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 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01185 {
01186
01187
01188
01189 }
01190
01191
01192
01193 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01194 {
01195 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01196 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01197 pvt->owner ? pvt->owner->name : "",
01198 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01199 }
01200
01201
01202 static struct ast_datastore_info iax2_variable_datastore_info = {
01203 .type = "IAX2_VARIABLE",
01204 .duplicate = iax2_dup_variable_datastore,
01205 .destroy = iax2_free_variable_datastore,
01206 };
01207
01208 static void *iax2_dup_variable_datastore(void *old)
01209 {
01210 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01211 struct ast_var_t *oldvar, *newvar;
01212
01213 newlist = ast_calloc(sizeof(*newlist), 1);
01214 if (!newlist) {
01215 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01216 return NULL;
01217 }
01218
01219 AST_LIST_HEAD_INIT(newlist);
01220 AST_LIST_LOCK(oldlist);
01221 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01222 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01223 if (newvar)
01224 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01225 else
01226 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01227 }
01228 AST_LIST_UNLOCK(oldlist);
01229 return newlist;
01230 }
01231
01232 static void iax2_free_variable_datastore(void *old)
01233 {
01234 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01235 struct ast_var_t *oldvar;
01236
01237 AST_LIST_LOCK(oldlist);
01238 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01239 ast_free(oldvar);
01240 }
01241 AST_LIST_UNLOCK(oldlist);
01242 AST_LIST_HEAD_DESTROY(oldlist);
01243 ast_free(oldlist);
01244 }
01245
01246
01247
01248
01249
01250 static void insert_idle_thread(struct iax2_thread *thread)
01251 {
01252 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01253 AST_LIST_LOCK(&dynamic_list);
01254 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01255 AST_LIST_UNLOCK(&dynamic_list);
01256 } else {
01257 AST_LIST_LOCK(&idle_list);
01258 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01259 AST_LIST_UNLOCK(&idle_list);
01260 }
01261
01262 return;
01263 }
01264
01265 static struct iax2_thread *find_idle_thread(void)
01266 {
01267 struct iax2_thread *thread = NULL;
01268
01269
01270 AST_LIST_LOCK(&idle_list);
01271 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01272 AST_LIST_UNLOCK(&idle_list);
01273
01274
01275 if (thread) {
01276 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01277 return thread;
01278 }
01279
01280
01281 AST_LIST_LOCK(&dynamic_list);
01282 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01283 AST_LIST_UNLOCK(&dynamic_list);
01284
01285
01286 if (thread) {
01287 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01288 return thread;
01289 }
01290
01291
01292 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01293 return NULL;
01294
01295
01296 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01297 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01298 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01299
01300
01301 ast_mutex_init(&thread->lock);
01302 ast_cond_init(&thread->cond, NULL);
01303 ast_mutex_init(&thread->init_lock);
01304 ast_cond_init(&thread->init_cond, NULL);
01305 ast_mutex_lock(&thread->init_lock);
01306
01307
01308 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01309 ast_cond_destroy(&thread->cond);
01310 ast_mutex_destroy(&thread->lock);
01311 ast_free(thread);
01312 return NULL;
01313 }
01314
01315
01316
01317 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01318
01319
01320 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01321
01322
01323 ast_mutex_unlock(&thread->init_lock);
01324
01325 return thread;
01326 }
01327
01328 #ifdef SCHED_MULTITHREADED
01329 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01330 {
01331 struct iax2_thread *thread = NULL;
01332 static time_t lasterror;
01333 static time_t t;
01334
01335 thread = find_idle_thread();
01336
01337 if (thread != NULL) {
01338 thread->schedfunc = func;
01339 thread->scheddata = data;
01340 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01341 #ifdef DEBUG_SCHED_MULTITHREAD
01342 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01343 #endif
01344 signal_condition(&thread->lock, &thread->cond);
01345 return 0;
01346 }
01347 time(&t);
01348 if (t != lasterror)
01349 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01350 lasterror = t;
01351
01352 return -1;
01353 }
01354 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01355 #endif
01356
01357 static int iax2_sched_replace(int id, struct ast_sched_thread *st, int when,
01358 ast_sched_cb callback, const void *data)
01359 {
01360 ast_sched_thread_del(st, id);
01361
01362 return ast_sched_thread_add(st, when, callback, data);
01363 }
01364
01365 static int iax2_sched_add(struct ast_sched_thread *st, int when,
01366 ast_sched_cb callback, const void *data)
01367 {
01368 return ast_sched_thread_add(st, when, callback, data);
01369 }
01370
01371 static int send_ping(const void *data);
01372
01373 static void __send_ping(const void *data)
01374 {
01375 int callno = (long) data;
01376
01377 ast_mutex_lock(&iaxsl[callno]);
01378
01379 if (iaxs[callno]) {
01380 if (iaxs[callno]->peercallno) {
01381 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01382 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01383 } else {
01384
01385 iaxs[callno]->pingid = -1;
01386 }
01387 } else {
01388 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01389 }
01390
01391 ast_mutex_unlock(&iaxsl[callno]);
01392 }
01393
01394 static int send_ping(const void *data)
01395 {
01396 #ifdef SCHED_MULTITHREADED
01397 if (schedule_action(__send_ping, data))
01398 #endif
01399 __send_ping(data);
01400
01401 return 0;
01402 }
01403
01404 static void encmethods_to_str(int e, struct ast_str *buf)
01405 {
01406 ast_str_set(&buf, 0, "(");
01407 if (e & IAX_ENCRYPT_AES128) {
01408 ast_str_append(&buf, 0, "aes128");
01409 }
01410 if (e & IAX_ENCRYPT_KEYROTATE) {
01411 ast_str_append(&buf, 0, ",keyrotate");
01412 }
01413 if (ast_str_strlen(buf) > 1) {
01414 ast_str_append(&buf, 0, ")");
01415 } else {
01416 ast_str_set(&buf, 0, "No");
01417 }
01418 }
01419
01420 static int get_encrypt_methods(const char *s)
01421 {
01422 int e;
01423 if (!strcasecmp(s, "aes128"))
01424 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01425 else if (ast_true(s))
01426 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01427 else
01428 e = 0;
01429 return e;
01430 }
01431
01432 static int send_lagrq(const void *data);
01433
01434 static void __send_lagrq(const void *data)
01435 {
01436 int callno = (long) data;
01437
01438 ast_mutex_lock(&iaxsl[callno]);
01439
01440 if (iaxs[callno]) {
01441 if (iaxs[callno]->peercallno) {
01442 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01443 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01444 } else {
01445
01446 iaxs[callno]->lagid = -1;
01447 }
01448 } else {
01449 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01450 }
01451
01452 ast_mutex_unlock(&iaxsl[callno]);
01453 }
01454
01455 static int send_lagrq(const void *data)
01456 {
01457 #ifdef SCHED_MULTITHREADED
01458 if (schedule_action(__send_lagrq, data))
01459 #endif
01460 __send_lagrq(data);
01461
01462 return 0;
01463 }
01464
01465 static unsigned char compress_subclass(int subclass)
01466 {
01467 int x;
01468 int power=-1;
01469
01470 if (subclass < IAX_FLAG_SC_LOG)
01471 return subclass;
01472
01473 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01474 if (subclass & (1 << x)) {
01475 if (power > -1) {
01476 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01477 return 0;
01478 } else
01479 power = x;
01480 }
01481 }
01482 return power | IAX_FLAG_SC_LOG;
01483 }
01484
01485 static int uncompress_subclass(unsigned char csub)
01486 {
01487
01488 if (csub & IAX_FLAG_SC_LOG) {
01489
01490 if (csub == 0xff)
01491 return -1;
01492 else
01493 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01494 }
01495 else
01496 return csub;
01497 }
01498
01499
01500
01501
01502 static int peer_hash_cb(const void *obj, const int flags)
01503 {
01504 const struct iax2_peer *peer = obj;
01505
01506 return ast_str_hash(peer->name);
01507 }
01508
01509
01510
01511
01512 static int peer_cmp_cb(void *obj, void *arg, int flags)
01513 {
01514 struct iax2_peer *peer = obj, *peer2 = arg;
01515
01516 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01517 }
01518
01519
01520
01521
01522 static int user_hash_cb(const void *obj, const int flags)
01523 {
01524 const struct iax2_user *user = obj;
01525
01526 return ast_str_hash(user->name);
01527 }
01528
01529
01530
01531
01532 static int user_cmp_cb(void *obj, void *arg, int flags)
01533 {
01534 struct iax2_user *user = obj, *user2 = arg;
01535
01536 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01537 }
01538
01539
01540
01541
01542
01543 static struct iax2_peer *find_peer(const char *name, int realtime)
01544 {
01545 struct iax2_peer *peer = NULL;
01546 struct iax2_peer tmp_peer = {
01547 .name = name,
01548 };
01549
01550 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01551
01552
01553 if(!peer && realtime)
01554 peer = realtime_peer(name, NULL);
01555
01556 return peer;
01557 }
01558
01559 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01560 {
01561 ao2_ref(peer, +1);
01562 return peer;
01563 }
01564
01565 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01566 {
01567 ao2_ref(peer, -1);
01568 return NULL;
01569 }
01570
01571 static struct iax2_user *find_user(const char *name)
01572 {
01573 struct iax2_user tmp_user = {
01574 .name = name,
01575 };
01576
01577 return ao2_find(users, &tmp_user, OBJ_POINTER);
01578 }
01579 static inline struct iax2_user *user_ref(struct iax2_user *user)
01580 {
01581 ao2_ref(user, +1);
01582 return user;
01583 }
01584
01585 static inline struct iax2_user *user_unref(struct iax2_user *user)
01586 {
01587 ao2_ref(user, -1);
01588 return NULL;
01589 }
01590
01591 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01592 {
01593 struct iax2_peer *peer = NULL;
01594 int res = 0;
01595 struct ao2_iterator i;
01596
01597 i = ao2_iterator_init(peers, 0);
01598 while ((peer = ao2_iterator_next(&i))) {
01599 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01600 (peer->addr.sin_port == sin.sin_port)) {
01601 ast_copy_string(host, peer->name, len);
01602 peer_unref(peer);
01603 res = 1;
01604 break;
01605 }
01606 peer_unref(peer);
01607 }
01608 ao2_iterator_destroy(&i);
01609
01610 if (!peer) {
01611 peer = realtime_peer(NULL, &sin);
01612 if (peer) {
01613 ast_copy_string(host, peer->name, len);
01614 peer_unref(peer);
01615 res = 1;
01616 }
01617 }
01618
01619 return res;
01620 }
01621
01622
01623
01624 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01625 {
01626
01627 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01628 struct iax2_user *user;
01629 struct iax2_user tmp_user = {
01630 .name = pvt->username,
01631 };
01632
01633 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01634 if (user) {
01635 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01636 user_unref(user);
01637 }
01638
01639 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01640 }
01641
01642 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01643 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01644 ast_sched_thread_del(sched, pvt->autoid);
01645 ast_sched_thread_del(sched, pvt->authid);
01646 ast_sched_thread_del(sched, pvt->initid);
01647 ast_sched_thread_del(sched, pvt->jbid);
01648 ast_sched_thread_del(sched, pvt->keyrotateid);
01649 }
01650
01651 static void iax2_frame_free(struct iax_frame *fr)
01652 {
01653 ast_sched_thread_del(sched, fr->retrans);
01654 iax_frame_free(fr);
01655 }
01656
01657 static int scheduled_destroy(const void *vid)
01658 {
01659 unsigned short callno = PTR_TO_CALLNO(vid);
01660 ast_mutex_lock(&iaxsl[callno]);
01661 if (iaxs[callno]) {
01662 if (option_debug) {
01663 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01664 }
01665 iax2_destroy(callno);
01666 }
01667 ast_mutex_unlock(&iaxsl[callno]);
01668 return 0;
01669 }
01670
01671 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01672 {
01673 ast_free(s->f.data.ptr);
01674 ast_free(s);
01675 }
01676
01677
01678
01679 static void send_signaling(struct chan_iax2_pvt *pvt)
01680 {
01681 struct signaling_queue_entry *s = NULL;
01682
01683 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01684 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01685 free_signaling_queue_entry(s);
01686 }
01687 pvt->hold_signaling = 0;
01688 }
01689
01690
01691
01692 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01693 {
01694 struct signaling_queue_entry *new;
01695
01696 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01697 return 1;
01698 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01699 return -1;
01700 }
01701
01702 memcpy(&new->f, f, sizeof(new->f));
01703
01704 if (new->f.datalen) {
01705 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01706 free_signaling_queue_entry(new);
01707 return -1;
01708 }
01709 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01710 }
01711 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01712
01713 return 0;
01714 }
01715
01716 static void pvt_destructor(void *obj)
01717 {
01718 struct chan_iax2_pvt *pvt = obj;
01719 struct iax_frame *cur = NULL;
01720 struct signaling_queue_entry *s = NULL;
01721
01722 ast_mutex_lock(&iaxsl[pvt->callno]);
01723 iax2_destroy_helper(pvt);
01724 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01725 pvt->callno_entry = NULL;
01726 ast_mutex_unlock(&iaxsl[pvt->callno]);
01727
01728
01729 ast_set_flag(pvt, IAX_ALREADYGONE);
01730
01731 AST_LIST_LOCK(&frame_queue);
01732 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01733
01734 if (cur->callno == pvt->callno) {
01735 cur->retries = -1;
01736 }
01737 }
01738 AST_LIST_UNLOCK(&frame_queue);
01739
01740 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01741 free_signaling_queue_entry(s);
01742 }
01743
01744 if (pvt->reg) {
01745 pvt->reg->callno = 0;
01746 }
01747
01748 if (!pvt->owner) {
01749 jb_frame frame;
01750 if (pvt->vars) {
01751 ast_variables_destroy(pvt->vars);
01752 pvt->vars = NULL;
01753 }
01754
01755 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01756 iax2_frame_free(frame.data);
01757 }
01758
01759 jb_destroy(pvt->jb);
01760 ast_string_field_free_memory(pvt);
01761 }
01762 }
01763
01764 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01765 {
01766 struct chan_iax2_pvt *tmp;
01767 jb_conf jbconf;
01768
01769 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01770 return NULL;
01771 }
01772
01773 if (ast_string_field_init(tmp, 32)) {
01774 ao2_ref(tmp, -1);
01775 tmp = NULL;
01776 return NULL;
01777 }
01778
01779 tmp->prefs = prefs;
01780 tmp->pingid = -1;
01781 tmp->lagid = -1;
01782 tmp->autoid = -1;
01783 tmp->authid = -1;
01784 tmp->initid = -1;
01785 tmp->keyrotateid = -1;
01786
01787 ast_string_field_set(tmp,exten, "s");
01788 ast_string_field_set(tmp,host, host);
01789
01790 tmp->jb = jb_new();
01791 tmp->jbid = -1;
01792 jbconf.max_jitterbuf = maxjitterbuffer;
01793 jbconf.resync_threshold = resyncthreshold;
01794 jbconf.max_contig_interp = maxjitterinterps;
01795 jbconf.target_extra = jittertargetextra;
01796 jb_setconf(tmp->jb,&jbconf);
01797
01798 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01799
01800 tmp->hold_signaling = 1;
01801 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01802
01803 return tmp;
01804 }
01805
01806 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01807 {
01808 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01809 if (new) {
01810 size_t afdatalen = new->afdatalen;
01811 memcpy(new, fr, sizeof(*new));
01812 iax_frame_wrap(new, &fr->af);
01813 new->afdatalen = afdatalen;
01814 new->data = NULL;
01815 new->datalen = 0;
01816 new->direction = DIRECTION_INGRESS;
01817 new->retrans = -1;
01818 }
01819 return new;
01820 }
01821
01822
01823 enum {
01824
01825 NEW_PREVENT = 0,
01826
01827 NEW_ALLOW = 1,
01828
01829 NEW_FORCE = 2,
01830
01831
01832 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01833 };
01834
01835 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01836 {
01837 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01838 (cur->addr.sin_port == sin->sin_port)) {
01839
01840 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01841 (check_dcallno ? dcallno == cur->callno : 1) ) {
01842
01843 return 1;
01844 }
01845 }
01846 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01847 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01848
01849 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01850 return 1;
01851 }
01852 return 0;
01853 }
01854
01855 static void update_max_trunk(void)
01856 {
01857 int max = TRUNK_CALL_START;
01858 int x;
01859
01860
01861 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01862 if (iaxs[x]) {
01863 max = x + 1;
01864 }
01865 }
01866
01867 maxtrunkcall = max;
01868 if (iaxdebug)
01869 ast_debug(1, "New max trunk callno is %d\n", max);
01870 }
01871
01872 static void update_max_nontrunk(void)
01873 {
01874 int max = 1;
01875 int x;
01876
01877 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01878 if (iaxs[x])
01879 max = x + 1;
01880 }
01881 maxnontrunkcall = max;
01882 if (iaxdebug)
01883 ast_debug(1, "New max nontrunk callno is %d\n", max);
01884 }
01885
01886 static int make_trunk(unsigned short callno, int locked)
01887 {
01888 int x;
01889 int res= 0;
01890 struct callno_entry *callno_entry;
01891 if (iaxs[callno]->oseqno) {
01892 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01893 return -1;
01894 }
01895 if (callno & TRUNK_CALL_START) {
01896 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01897 return -1;
01898 }
01899
01900 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
01901 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01902 return -1;
01903 }
01904
01905 x = callno_entry->callno;
01906 ast_mutex_lock(&iaxsl[x]);
01907
01908
01909
01910
01911
01912 ast_sched_thread_del(sched, iaxs[callno]->pingid);
01913 ast_sched_thread_del(sched, iaxs[callno]->lagid);
01914 iaxs[x] = iaxs[callno];
01915 iaxs[x]->callno = x;
01916
01917
01918
01919 if (iaxs[x]->callno_entry) {
01920 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
01921 }
01922 iaxs[x]->callno_entry = callno_entry;
01923
01924 iaxs[callno] = NULL;
01925
01926 iaxs[x]->pingid = iax2_sched_add(sched,
01927 ping_time * 1000, send_ping, (void *)(long)x);
01928 iaxs[x]->lagid = iax2_sched_add(sched,
01929 lagrq_time * 1000, send_lagrq, (void *)(long)x);
01930
01931 if (locked)
01932 ast_mutex_unlock(&iaxsl[callno]);
01933 res = x;
01934 if (!locked)
01935 ast_mutex_unlock(&iaxsl[x]);
01936
01937 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01938
01939 update_max_trunk();
01940 update_max_nontrunk();
01941 return res;
01942 }
01943
01944 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01945 {
01946 if (!pvt->transfercallno) {
01947 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01948 return;
01949 }
01950
01951 ao2_link(iax_transfercallno_pvts, pvt);
01952 }
01953
01954 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01955 {
01956 if (!pvt->transfercallno) {
01957 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01958 return;
01959 }
01960
01961 ao2_unlink(iax_transfercallno_pvts, pvt);
01962 }
01963 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01964 {
01965 if (!pvt->peercallno) {
01966 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01967 return;
01968 }
01969
01970 ao2_link(iax_peercallno_pvts, pvt);
01971 }
01972
01973 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01974 {
01975 if (!pvt->peercallno) {
01976 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01977 return;
01978 }
01979
01980 ao2_unlink(iax_peercallno_pvts, pvt);
01981 }
01982
01983 static int addr_range_delme_cb(void *obj, void *arg, int flags)
01984 {
01985 struct addr_range *lim = obj;
01986 lim->delme = 1;
01987 return 0;
01988 }
01989
01990 static int addr_range_hash_cb(const void *obj, const int flags)
01991 {
01992 const struct addr_range *lim = obj;
01993 return abs((int) lim->ha.netaddr.s_addr);
01994 }
01995
01996 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
01997 {
01998 struct addr_range *lim1 = obj, *lim2 = arg;
01999 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
02000 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
02001 CMP_MATCH | CMP_STOP : 0;
02002 }
02003
02004 static int peercnt_hash_cb(const void *obj, const int flags)
02005 {
02006 const struct peercnt *peercnt = obj;
02007 return abs((int) peercnt->addr);
02008 }
02009
02010 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
02011 {
02012 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02013 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02014 }
02015
02016 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
02017 {
02018 struct addr_range *addr_range = obj;
02019 struct sockaddr_in *sin = arg;
02020
02021 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
02022 return CMP_MATCH | CMP_STOP;
02023 }
02024 return 0;
02025 }
02026
02027
02028
02029
02030
02031
02032 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
02033 {
02034 struct addr_range *addr_range;
02035 struct iax2_peer *peer = NULL;
02036 struct iax2_user *user = NULL;
02037
02038 const char *find = S_OR(name, "guest");
02039 int res = 1;
02040 int optional = 0;
02041 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02042
02043
02044
02045
02046
02047
02048
02049 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02050 ao2_ref(addr_range, -1);
02051 optional = 1;
02052 }
02053
02054
02055 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02056 calltoken_required = user->calltoken_required;
02057 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02058 calltoken_required = user->calltoken_required;
02059 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02060 calltoken_required = peer->calltoken_required;
02061 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02062 calltoken_required = peer->calltoken_required;
02063 }
02064
02065 if (peer) {
02066 peer_unref(peer);
02067 }
02068 if (user) {
02069 user_unref(user);
02070 }
02071
02072 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);
02073 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02074 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02075 res = 0;
02076 }
02077
02078 return res;
02079 }
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091 static void set_peercnt_limit(struct peercnt *peercnt)
02092 {
02093 uint16_t limit = global_maxcallno;
02094 struct addr_range *addr_range;
02095 struct sockaddr_in sin = {
02096 .sin_addr.s_addr = peercnt->addr,
02097 };
02098
02099
02100 if (peercnt->reg && peercnt->limit) {
02101 return;
02102 }
02103
02104 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02105 limit = addr_range->limit;
02106 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02107 ao2_ref(addr_range, -1);
02108 }
02109
02110 peercnt->limit = limit;
02111 }
02112
02113
02114
02115
02116
02117 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02118 {
02119 struct peercnt *peercnt = obj;
02120
02121 set_peercnt_limit(peercnt);
02122 ast_debug(1, "Reset limits for peercnts table\n");
02123
02124 return 0;
02125 }
02126
02127
02128
02129
02130
02131 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02132 {
02133 struct addr_range *addr_range = obj;
02134
02135 return addr_range->delme ? CMP_MATCH : 0;
02136 }
02137
02138
02139
02140
02141
02142 static void peercnt_modify(unsigned char reg, uint16_t limit, struct sockaddr_in *sin)
02143 {
02144
02145 struct peercnt *peercnt;
02146 struct peercnt tmp = {
02147 .addr = sin->sin_addr.s_addr,
02148 };
02149
02150 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02151 peercnt->reg = reg;
02152 if (limit) {
02153 peercnt->limit = limit;
02154 } else {
02155 set_peercnt_limit(peercnt);
02156 }
02157 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg);
02158 ao2_ref(peercnt, -1);
02159 }
02160 }
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170 static int peercnt_add(struct sockaddr_in *sin)
02171 {
02172 struct peercnt *peercnt;
02173 unsigned long addr = sin->sin_addr.s_addr;
02174 int res = 0;
02175 struct peercnt tmp = {
02176 .addr = addr,
02177 };
02178
02179
02180
02181
02182
02183
02184
02185 ao2_lock(peercnts);
02186 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02187 ao2_lock(peercnt);
02188 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02189 ao2_lock(peercnt);
02190
02191 peercnt->addr = addr;
02192 set_peercnt_limit(peercnt);
02193
02194
02195 ao2_link(peercnts, peercnt);
02196 } else {
02197 ao2_unlock(peercnts);
02198 return -1;
02199 }
02200
02201
02202 if (peercnt->limit > peercnt->cur) {
02203 peercnt->cur++;
02204 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02205 } else {
02206 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02207 res = -1;
02208 }
02209
02210
02211 ao2_unlock(peercnt);
02212 ao2_unlock(peercnts);
02213 ao2_ref(peercnt, -1);
02214
02215 return res;
02216 }
02217
02218
02219
02220
02221
02222 static void peercnt_remove(struct peercnt *peercnt)
02223 {
02224 struct sockaddr_in sin = {
02225 .sin_addr.s_addr = peercnt->addr,
02226 };
02227
02228 if (peercnt) {
02229
02230
02231
02232 ao2_lock(peercnts);
02233 peercnt->cur--;
02234 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02235
02236 if (peercnt->cur == 0) {
02237 ao2_unlink(peercnts, peercnt);
02238 }
02239 ao2_unlock(peercnts);
02240 }
02241 }
02242
02243
02244
02245
02246
02247 static int peercnt_remove_cb(const void *obj)
02248 {
02249 struct peercnt *peercnt = (struct peercnt *) obj;
02250
02251 peercnt_remove(peercnt);
02252 ao2_ref(peercnt, -1);
02253
02254 return 0;
02255 }
02256
02257
02258
02259
02260
02261 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02262 {
02263 struct peercnt *peercnt;
02264 struct peercnt tmp = {
02265 .addr = sin->sin_addr.s_addr,
02266 };
02267
02268 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02269 peercnt_remove(peercnt);
02270 ao2_ref(peercnt, -1);
02271 }
02272 return 0;
02273 }
02274
02275
02276
02277
02278
02279 static void build_callno_limits(struct ast_variable *v)
02280 {
02281 struct addr_range *addr_range = NULL;
02282 struct addr_range tmp;
02283 struct ast_ha *ha;
02284 int limit;
02285 int error;
02286 int found;
02287
02288 for (; v; v = v->next) {
02289 limit = -1;
02290 error = 0;
02291 found = 0;
02292 ha = ast_append_ha("permit", v->name, NULL, &error);
02293
02294
02295 if (error) {
02296 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02297 continue;
02298 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02299 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02300 ast_free_ha(ha);
02301 continue;
02302 }
02303
02304 ast_copy_ha(ha, &tmp.ha);
02305
02306 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02307 ao2_lock(addr_range);
02308 found = 1;
02309 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02310 ast_free_ha(ha);
02311 return;
02312 }
02313
02314
02315 ast_copy_ha(ha, &addr_range->ha);
02316 ast_free_ha(ha);
02317 addr_range->limit = limit;
02318 addr_range->delme = 0;
02319
02320
02321 if (found) {
02322 ao2_unlock(addr_range);
02323 } else {
02324 ao2_link(callno_limits, addr_range);
02325 }
02326 ao2_ref(addr_range, -1);
02327 }
02328 }
02329
02330
02331
02332
02333
02334 static int add_calltoken_ignore(const char *addr)
02335 {
02336 struct addr_range tmp;
02337 struct addr_range *addr_range = NULL;
02338 struct ast_ha *ha = NULL;
02339 int error = 0;
02340
02341 if (ast_strlen_zero(addr)) {
02342 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02343 return -1;
02344 }
02345
02346 ha = ast_append_ha("permit", addr, NULL, &error);
02347
02348
02349 if (error) {
02350 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02351 return -1;
02352 }
02353
02354 ast_copy_ha(ha, &tmp.ha);
02355
02356 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02357 ao2_lock(addr_range);
02358 addr_range->delme = 0;
02359 ao2_unlock(addr_range);
02360 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02361
02362 ast_copy_ha(ha, &addr_range->ha);
02363 ao2_link(calltoken_ignores, addr_range);
02364 } else {
02365 ast_free_ha(ha);
02366 return -1;
02367 }
02368
02369 ast_free_ha(ha);
02370 ao2_ref(addr_range, -1);
02371
02372 return 0;
02373 }
02374
02375 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02376 {
02377 struct ao2_iterator i;
02378 struct peercnt *peercnt;
02379 struct sockaddr_in sin;
02380 int found = 0;
02381
02382 switch (cmd) {
02383 case CLI_INIT:
02384 e->command = "iax2 show callnumber usage";
02385 e->usage =
02386 "Usage: iax2 show callnumber usage <ip address (optional)>\n"
02387 " Shows current ip addresses which are consuming iax2 call numbers\n";
02388 return NULL;
02389 case CLI_GENERATE:
02390 return NULL;
02391 case CLI_HANDLER:
02392 if (a->argc < 4 || a->argc > 5)
02393 return CLI_SHOWUSAGE;
02394
02395 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02396 i = ao2_iterator_init(peercnts, 0);
02397 while ((peercnt = ao2_iterator_next(&i))) {
02398 sin.sin_addr.s_addr = peercnt->addr;
02399 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02400 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02401 found = 1;
02402 break;
02403 } else {
02404 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02405 }
02406 ao2_ref(peercnt, -1);
02407 }
02408 ao2_iterator_destroy(&i);
02409
02410 if (a->argc == 4) {
02411 ast_cli(a->fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
02412 } else if (a->argc == 5 && !found) {
02413 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02414 }
02415
02416 return CLI_SUCCESS;
02417 default:
02418 return NULL;
02419 }
02420 }
02421
02422 static struct callno_entry *get_unused_callno(int trunk, int validated)
02423 {
02424 struct callno_entry *callno_entry = NULL;
02425 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02426 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02427
02428 return NULL;
02429 }
02430
02431
02432
02433 ao2_lock(callno_pool);
02434
02435
02436
02437
02438 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02439 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02440 ao2_unlock(callno_pool);
02441 return NULL;
02442 }
02443
02444
02445
02446 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02447
02448 if (callno_entry) {
02449 callno_entry->validated = validated;
02450 if (!validated) {
02451 total_nonval_callno_used++;
02452 }
02453 }
02454
02455 ao2_unlock(callno_pool);
02456 return callno_entry;
02457 }
02458
02459 static int replace_callno(const void *obj)
02460 {
02461 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02462
02463
02464
02465 ao2_lock(callno_pool);
02466
02467 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02468 total_nonval_callno_used--;
02469 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02470 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02471 }
02472
02473 if (callno_entry->callno < TRUNK_CALL_START) {
02474 ao2_link(callno_pool, callno_entry);
02475 } else {
02476 ao2_link(callno_pool_trunk, callno_entry);
02477 }
02478 ao2_ref(callno_entry, -1);
02479
02480 ao2_unlock(callno_pool);
02481 return 0;
02482 }
02483
02484 static int callno_hash(const void *obj, const int flags)
02485 {
02486 return abs(ast_random());
02487 }
02488
02489 static int create_callno_pools(void)
02490 {
02491 uint16_t i;
02492
02493 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02494 return -1;
02495 }
02496
02497 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02498 return -1;
02499 }
02500
02501
02502 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02503 struct callno_entry *callno_entry;
02504
02505 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02506 return -1;
02507 }
02508
02509 callno_entry->callno = i;
02510
02511 if (i < TRUNK_CALL_START) {
02512 ao2_link(callno_pool, callno_entry);
02513 } else {
02514 ao2_link(callno_pool_trunk, callno_entry);
02515 }
02516
02517 ao2_ref(callno_entry, -1);
02518 }
02519
02520 return 0;
02521 }
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02532 {
02533 int i;
02534 struct peercnt *peercnt;
02535 struct peercnt tmp = {
02536 .addr = sin->sin_addr.s_addr,
02537 };
02538
02539 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02540
02541 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02542 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02543 if (i == -1) {
02544 ao2_ref(peercnt, -1);
02545 }
02546 }
02547
02548 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02549 }
02550
02551
02552
02553
02554
02555
02556
02557
02558 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02559 {
02560 if (frametype != AST_FRAME_IAX) {
02561 return 0;
02562 }
02563 switch (subclass) {
02564 case IAX_COMMAND_NEW:
02565 case IAX_COMMAND_REGREQ:
02566 case IAX_COMMAND_FWDOWNL:
02567 case IAX_COMMAND_REGREL:
02568 return 1;
02569 case IAX_COMMAND_POKE:
02570 if (!inbound) {
02571 return 1;
02572 }
02573 break;
02574 }
02575 return 0;
02576 }
02577
02578
02579
02580
02581 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02582 {
02583 int res = 0;
02584 int x;
02585
02586
02587 int validated = (new > NEW_ALLOW) ? 1 : 0;
02588 char host[80];
02589
02590 if (new <= NEW_ALLOW) {
02591 if (callno) {
02592 struct chan_iax2_pvt *pvt;
02593 struct chan_iax2_pvt tmp_pvt = {
02594 .callno = dcallno,
02595 .peercallno = callno,
02596 .transfercallno = callno,
02597
02598 .frames_received = check_dcallno,
02599 };
02600
02601 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02602
02603 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02604 if (return_locked) {
02605 ast_mutex_lock(&iaxsl[pvt->callno]);
02606 }
02607 res = pvt->callno;
02608 ao2_ref(pvt, -1);
02609 pvt = NULL;
02610 return res;
02611 }
02612
02613 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02614 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02615 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02616 if (return_locked) {
02617 ast_mutex_lock(&iaxsl[pvt->callno]);
02618 }
02619 res = pvt->callno;
02620 ao2_ref(pvt, -1);
02621 pvt = NULL;
02622 return res;
02623 }
02624 }
02625
02626
02627 if (dcallno) {
02628 ast_mutex_lock(&iaxsl[dcallno]);
02629 }
02630 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02631 iaxs[dcallno]->peercallno = callno;
02632 res = dcallno;
02633 store_by_peercallno(iaxs[dcallno]);
02634 if (!res || !return_locked) {
02635 ast_mutex_unlock(&iaxsl[dcallno]);
02636 }
02637 return res;
02638 }
02639 if (dcallno) {
02640 ast_mutex_unlock(&iaxsl[dcallno]);
02641 }
02642 #ifdef IAX_OLD_FIND
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654 for (x = 1; !res && x < maxnontrunkcall; x++) {
02655 ast_mutex_lock(&iaxsl[x]);
02656 if (iaxs[x]) {
02657
02658 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02659 res = x;
02660 }
02661 }
02662 if (!res || !return_locked)
02663 ast_mutex_unlock(&iaxsl[x]);
02664 }
02665 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02666 ast_mutex_lock(&iaxsl[x]);
02667 if (iaxs[x]) {
02668
02669 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02670 res = x;
02671 }
02672 }
02673 if (!res || !return_locked)
02674 ast_mutex_unlock(&iaxsl[x]);
02675 }
02676 #endif
02677 }
02678 if (!res && (new >= NEW_ALLOW)) {
02679 struct callno_entry *callno_entry;
02680
02681
02682
02683
02684
02685
02686 if (!iax2_getpeername(*sin, host, sizeof(host)))
02687 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02688
02689 if (peercnt_add(sin)) {
02690
02691
02692 return 0;
02693 }
02694
02695 if (!(callno_entry = get_unused_callno(0, validated))) {
02696
02697
02698 peercnt_remove_by_addr(sin);
02699 ast_log(LOG_WARNING, "No more space\n");
02700 return 0;
02701 }
02702 x = callno_entry->callno;
02703 ast_mutex_lock(&iaxsl[x]);
02704
02705 iaxs[x] = new_iax(sin, host);
02706 update_max_nontrunk();
02707 if (iaxs[x]) {
02708 if (iaxdebug)
02709 ast_debug(1, "Creating new call structure %d\n", x);
02710 iaxs[x]->callno_entry = callno_entry;
02711 iaxs[x]->sockfd = sockfd;
02712 iaxs[x]->addr.sin_port = sin->sin_port;
02713 iaxs[x]->addr.sin_family = sin->sin_family;
02714 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02715 iaxs[x]->peercallno = callno;
02716 iaxs[x]->callno = x;
02717 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02718 iaxs[x]->expiry = min_reg_expire;
02719 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02720 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02721 iaxs[x]->amaflags = amaflags;
02722 ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT);
02723 ast_string_field_set(iaxs[x], accountcode, accountcode);
02724 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02725 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02726 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02727
02728 if (iaxs[x]->peercallno) {
02729 store_by_peercallno(iaxs[x]);
02730 }
02731 } else {
02732 ast_log(LOG_WARNING, "Out of resources\n");
02733 ast_mutex_unlock(&iaxsl[x]);
02734 replace_callno(callno_entry);
02735 return 0;
02736 }
02737 if (!return_locked)
02738 ast_mutex_unlock(&iaxsl[x]);
02739 res = x;
02740 }
02741 return res;
02742 }
02743
02744 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02745
02746 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02747 }
02748
02749 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02750
02751 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02752 }
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764 static int iax2_queue_frame(int callno, struct ast_frame *f)
02765 {
02766 for (;;) {
02767 if (iaxs[callno] && iaxs[callno]->owner) {
02768 if (ast_channel_trylock(iaxs[callno]->owner)) {
02769
02770 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02771 } else {
02772 ast_queue_frame(iaxs[callno]->owner, f);
02773 ast_channel_unlock(iaxs[callno]->owner);
02774 break;
02775 }
02776 } else
02777 break;
02778 }
02779 return 0;
02780 }
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795 static int iax2_queue_hangup(int callno)
02796 {
02797 for (;;) {
02798 if (iaxs[callno] && iaxs[callno]->owner) {
02799 if (ast_channel_trylock(iaxs[callno]->owner)) {
02800
02801 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02802 } else {
02803 ast_queue_hangup(iaxs[callno]->owner);
02804 ast_channel_unlock(iaxs[callno]->owner);
02805 break;
02806 }
02807 } else
02808 break;
02809 }
02810 return 0;
02811 }
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826 static int iax2_queue_control_data(int callno,
02827 enum ast_control_frame_type control, const void *data, size_t datalen)
02828 {
02829 for (;;) {
02830 if (iaxs[callno] && iaxs[callno]->owner) {
02831 if (ast_channel_trylock(iaxs[callno]->owner)) {
02832
02833 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02834 } else {
02835 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02836 ast_channel_unlock(iaxs[callno]->owner);
02837 break;
02838 }
02839 } else
02840 break;
02841 }
02842 return 0;
02843 }
02844 static void destroy_firmware(struct iax_firmware *cur)
02845 {
02846
02847 if (cur->fwh) {
02848 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02849 }
02850 close(cur->fd);
02851 ast_free(cur);
02852 }
02853
02854 static int try_firmware(char *s)
02855 {
02856 struct stat stbuf;
02857 struct iax_firmware *cur = NULL;
02858 int ifd, fd, res, len, chunk;
02859 struct ast_iax2_firmware_header *fwh, fwh2;
02860 struct MD5Context md5;
02861 unsigned char sum[16], buf[1024];
02862 char *s2, *last;
02863
02864 if (!(s2 = alloca(strlen(s) + 100))) {
02865 ast_log(LOG_WARNING, "Alloca failed!\n");
02866 return -1;
02867 }
02868
02869 last = strrchr(s, '/');
02870 if (last)
02871 last++;
02872 else
02873 last = s;
02874
02875 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02876
02877 if ((res = stat(s, &stbuf) < 0)) {
02878 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02879 return -1;
02880 }
02881
02882
02883 if (S_ISDIR(stbuf.st_mode))
02884 return -1;
02885 ifd = open(s, O_RDONLY);
02886 if (ifd < 0) {
02887 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02888 return -1;
02889 }
02890 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02891 if (fd < 0) {
02892 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02893 close(ifd);
02894 return -1;
02895 }
02896
02897 unlink(s2);
02898
02899
02900 len = stbuf.st_size;
02901 while(len) {
02902 chunk = len;
02903 if (chunk > sizeof(buf))
02904 chunk = sizeof(buf);
02905 res = read(ifd, buf, chunk);
02906 if (res != chunk) {
02907 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02908 close(ifd);
02909 close(fd);
02910 return -1;
02911 }
02912 res = write(fd, buf, chunk);
02913 if (res != chunk) {
02914 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02915 close(ifd);
02916 close(fd);
02917 return -1;
02918 }
02919 len -= chunk;
02920 }
02921 close(ifd);
02922
02923 lseek(fd, 0, SEEK_SET);
02924 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02925 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02926 close(fd);
02927 return -1;
02928 }
02929 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02930 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02931 close(fd);
02932 return -1;
02933 }
02934 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02935 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02936 close(fd);
02937 return -1;
02938 }
02939 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02940 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02941 close(fd);
02942 return -1;
02943 }
02944 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
02945 if (fwh == (void *) -1) {
02946 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02947 close(fd);
02948 return -1;
02949 }
02950 MD5Init(&md5);
02951 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02952 MD5Final(sum, &md5);
02953 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02954 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02955 munmap((void*)fwh, stbuf.st_size);
02956 close(fd);
02957 return -1;
02958 }
02959
02960 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02961 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02962
02963 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02964
02965 break;
02966
02967
02968 munmap((void*)fwh, stbuf.st_size);
02969 close(fd);
02970 return 0;
02971 }
02972 }
02973
02974 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02975 cur->fd = -1;
02976 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02977 }
02978
02979 if (cur) {
02980 if (cur->fwh)
02981 munmap((void*)cur->fwh, cur->mmaplen);
02982 if (cur->fd > -1)
02983 close(cur->fd);
02984 cur->fwh = fwh;
02985 cur->fd = fd;
02986 cur->mmaplen = stbuf.st_size;
02987 cur->dead = 0;
02988 }
02989
02990 return 0;
02991 }
02992
02993 static int iax_check_version(char *dev)
02994 {
02995 int res = 0;
02996 struct iax_firmware *cur = NULL;
02997
02998 if (ast_strlen_zero(dev))
02999 return 0;
03000
03001 AST_LIST_LOCK(&firmwares);
03002 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03003 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03004 res = ntohs(cur->fwh->version);
03005 break;
03006 }
03007 }
03008 AST_LIST_UNLOCK(&firmwares);
03009
03010 return res;
03011 }
03012
03013 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03014 {
03015 int res = -1;
03016 unsigned int bs = desc & 0xff;
03017 unsigned int start = (desc >> 8) & 0xffffff;
03018 unsigned int bytes;
03019 struct iax_firmware *cur;
03020
03021 if (ast_strlen_zero((char *)dev) || !bs)
03022 return -1;
03023
03024 start *= bs;
03025
03026 AST_LIST_LOCK(&firmwares);
03027 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03028 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03029 continue;
03030 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03031 if (start < ntohl(cur->fwh->datalen)) {
03032 bytes = ntohl(cur->fwh->datalen) - start;
03033 if (bytes > bs)
03034 bytes = bs;
03035 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03036 } else {
03037 bytes = 0;
03038 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03039 }
03040 if (bytes == bs)
03041 res = 0;
03042 else
03043 res = 1;
03044 break;
03045 }
03046 AST_LIST_UNLOCK(&firmwares);
03047
03048 return res;
03049 }
03050
03051
03052 static void reload_firmware(int unload)
03053 {
03054 struct iax_firmware *cur = NULL;
03055 DIR *fwd;
03056 struct dirent *de;
03057 char dir[256], fn[256];
03058
03059 AST_LIST_LOCK(&firmwares);
03060
03061
03062 AST_LIST_TRAVERSE(&firmwares, cur, list)
03063 cur->dead = 1;
03064
03065
03066 if (!unload) {
03067 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03068 fwd = opendir(dir);
03069 if (fwd) {
03070 while((de = readdir(fwd))) {
03071 if (de->d_name[0] != '.') {
03072 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03073 if (!try_firmware(fn)) {
03074 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03075 }
03076 }
03077 }
03078 closedir(fwd);
03079 } else
03080 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03081 }
03082
03083
03084 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03085 if (!cur->dead)
03086 continue;
03087 AST_LIST_REMOVE_CURRENT(list);
03088 destroy_firmware(cur);
03089 }
03090 AST_LIST_TRAVERSE_SAFE_END;
03091
03092 AST_LIST_UNLOCK(&firmwares);
03093 }
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103 static int __do_deliver(void *data)
03104 {
03105
03106
03107 struct iax_frame *fr = data;
03108 fr->retrans = -1;
03109 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03110 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
03111 iax2_queue_frame(fr->callno, &fr->af);
03112
03113 iax2_frame_free(fr);
03114
03115 return 0;
03116 }
03117
03118 static int handle_error(void)
03119 {
03120
03121
03122
03123 #if 0
03124 struct sockaddr_in *sin;
03125 int res;
03126 struct msghdr m;
03127 struct sock_extended_err e;
03128 m.msg_name = NULL;
03129 m.msg_namelen = 0;
03130 m.msg_iov = NULL;
03131 m.msg_control = &e;
03132 m.msg_controllen = sizeof(e);
03133 m.msg_flags = 0;
03134 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03135 if (res < 0)
03136 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03137 else {
03138 if (m.msg_controllen) {
03139 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03140 if (sin)
03141 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03142 else
03143 ast_log(LOG_WARNING, "No address detected??\n");
03144 } else {
03145 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03146 }
03147 }
03148 #endif
03149 return 0;
03150 }
03151
03152 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03153 {
03154 int res;
03155 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03156 sizeof(*sin));
03157 if (res < 0) {
03158 ast_debug(1, "Received error: %s\n", strerror(errno));
03159 handle_error();
03160 } else
03161 res = 0;
03162 return res;
03163 }
03164
03165 static int send_packet(struct iax_frame *f)
03166 {
03167 int res;
03168 int callno = f->callno;
03169
03170
03171 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03172 return -1;
03173
03174
03175 if (iaxdebug)
03176 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));
03177
03178 if (f->transfer) {
03179 if (iaxdebug)
03180 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03181 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03182 } else {
03183 if (iaxdebug)
03184 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03185 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03186 }
03187 if (res < 0) {
03188 if (iaxdebug)
03189 ast_debug(1, "Received error: %s\n", strerror(errno));
03190 handle_error();
03191 } else
03192 res = 0;
03193
03194 return res;
03195 }
03196
03197
03198
03199
03200
03201 static int iax2_predestroy(int callno)
03202 {
03203 struct ast_channel *c = NULL;
03204 struct chan_iax2_pvt *pvt = iaxs[callno];
03205
03206 if (!pvt)
03207 return -1;
03208
03209 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
03210 iax2_destroy_helper(pvt);
03211 ast_set_flag(pvt, IAX_ALREADYGONE);
03212 }
03213
03214 if ((c = pvt->owner)) {
03215 c->tech_pvt = NULL;
03216 iax2_queue_hangup(callno);
03217 pvt->owner = NULL;
03218 ast_module_unref(ast_module_info->self);
03219 }
03220
03221 return 0;
03222 }
03223
03224 static void iax2_destroy(int callno)
03225 {
03226 struct chan_iax2_pvt *pvt = NULL;
03227 struct ast_channel *owner = NULL;
03228
03229 retry:
03230 if ((pvt = iaxs[callno])) {
03231 #if 0
03232
03233
03234
03235
03236
03237
03238
03239 iax2_destroy_helper(pvt);
03240 #endif
03241 }
03242
03243 owner = pvt ? pvt->owner : NULL;
03244
03245 if (owner) {
03246 if (ast_channel_trylock(owner)) {
03247 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03248 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03249 goto retry;
03250 }
03251 }
03252
03253 if (!owner) {
03254 iaxs[callno] = NULL;
03255 }
03256
03257 if (pvt) {
03258 if (!owner) {
03259 pvt->owner = NULL;
03260 } else {
03261
03262
03263
03264 ast_queue_hangup(owner);
03265 }
03266
03267 if (pvt->peercallno) {
03268 remove_by_peercallno(pvt);
03269 }
03270
03271 if (pvt->transfercallno) {
03272 remove_by_transfercallno(pvt);
03273 }
03274
03275 if (!owner) {
03276 ao2_ref(pvt, -1);
03277 pvt = NULL;
03278 }
03279 }
03280
03281 if (owner) {
03282 ast_channel_unlock(owner);
03283 }
03284
03285 if (callno & 0x4000) {
03286 update_max_trunk();
03287 }
03288 }
03289
03290 static int update_packet(struct iax_frame *f)
03291 {
03292
03293 struct ast_iax2_full_hdr *fh = f->data;
03294 struct ast_frame af;
03295
03296
03297 if (f->encmethods) {
03298 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03299 }
03300
03301 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03302
03303 f->iseqno = iaxs[f->callno]->iseqno;
03304 fh->iseqno = f->iseqno;
03305
03306
03307 if (f->encmethods) {
03308
03309
03310 build_rand_pad(f->semirand, sizeof(f->semirand));
03311 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03312 }
03313 return 0;
03314 }
03315
03316 static int attempt_transmit(const void *data);
03317 static void __attempt_transmit(const void *data)
03318 {
03319
03320
03321 struct iax_frame *f = (struct iax_frame *)data;
03322 int freeme = 0;
03323 int callno = f->callno;
03324
03325 if (callno)
03326 ast_mutex_lock(&iaxsl[callno]);
03327 if (callno && iaxs[callno]) {
03328 if ((f->retries < 0) ||
03329 (f->retries >= max_retries) ) {
03330
03331 if (f->retries >= max_retries) {
03332 if (f->transfer) {
03333
03334 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03335 } else if (f->final) {
03336 iax2_destroy(callno);
03337 } else {
03338 if (iaxs[callno]->owner)
03339 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);
03340 iaxs[callno]->error = ETIMEDOUT;
03341 if (iaxs[callno]->owner) {
03342 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03343
03344 iax2_queue_frame(callno, &fr);
03345
03346 if (iaxs[callno] && iaxs[callno]->owner)
03347 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03348 } else {
03349 if (iaxs[callno]->reg) {
03350 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03351 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03352 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03353 }
03354 iax2_destroy(callno);
03355 }
03356 }
03357
03358 }
03359 freeme = 1;
03360 } else {
03361
03362 update_packet(f);
03363
03364 send_packet(f);
03365 f->retries++;
03366
03367 f->retrytime *= 10;
03368 if (f->retrytime > MAX_RETRY_TIME)
03369 f->retrytime = MAX_RETRY_TIME;
03370
03371 if (f->transfer && (f->retrytime > 1000))
03372 f->retrytime = 1000;
03373 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03374 }
03375 } else {
03376
03377 f->retries = -1;
03378 freeme = 1;
03379 }
03380 if (callno)
03381 ast_mutex_unlock(&iaxsl[callno]);
03382
03383 if (freeme) {
03384
03385 AST_LIST_LOCK(&frame_queue);
03386 AST_LIST_REMOVE(&frame_queue, f, list);
03387 AST_LIST_UNLOCK(&frame_queue);
03388 f->retrans = -1;
03389
03390 iax2_frame_free(f);
03391 }
03392 }
03393
03394 static int attempt_transmit(const void *data)
03395 {
03396 #ifdef SCHED_MULTITHREADED
03397 if (schedule_action(__attempt_transmit, data))
03398 #endif
03399 __attempt_transmit(data);
03400 return 0;
03401 }
03402
03403 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03404 {
03405 struct iax2_peer *peer = NULL;
03406 struct iax2_user *user = NULL;
03407 static char *choices[] = { "all", NULL };
03408 char *cmplt;
03409
03410 switch (cmd) {
03411 case CLI_INIT:
03412 e->command = "iax2 prune realtime";
03413 e->usage =
03414 "Usage: iax2 prune realtime [<peername>|all]\n"
03415 " Prunes object(s) from the cache\n";
03416 return NULL;
03417 case CLI_GENERATE:
03418 if (a->pos == 3) {
03419 cmplt = ast_cli_complete(a->word, choices, a->n);
03420 if (!cmplt)
03421 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03422 return cmplt;
03423 }
03424 return NULL;
03425 }
03426 if (a->argc != 4)
03427 return CLI_SHOWUSAGE;
03428 if (!strcmp(a->argv[3], "all")) {
03429 prune_users();
03430 prune_peers();
03431 ast_cli(a->fd, "Cache flushed successfully.\n");
03432 return CLI_SUCCESS;
03433 }
03434 peer = find_peer(a->argv[3], 0);
03435 user = find_user(a->argv[3]);
03436 if (peer || user) {
03437 if (peer) {
03438 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
03439 ast_set_flag(peer, IAX_RTAUTOCLEAR);
03440 expire_registry(peer_ref(peer));
03441 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03442 } else {
03443 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03444 }
03445 peer_unref(peer);
03446 }
03447 if (user) {
03448 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
03449 ast_set_flag(user, IAX_RTAUTOCLEAR);
03450 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03451 } else {
03452 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03453 }
03454 ao2_unlink(users,user);
03455 user_unref(user);
03456 }
03457 } else {
03458 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03459 }
03460
03461 return CLI_SUCCESS;
03462 }
03463
03464 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03465 {
03466 switch (cmd) {
03467 case CLI_INIT:
03468 e->command = "iax2 test losspct";
03469 e->usage =
03470 "Usage: iax2 test losspct <percentage>\n"
03471 " For testing, throws away <percentage> percent of incoming packets\n";
03472 return NULL;
03473 case CLI_GENERATE:
03474 return NULL;
03475 }
03476 if (a->argc != 4)
03477 return CLI_SHOWUSAGE;
03478
03479 test_losspct = atoi(a->argv[3]);
03480
03481 return CLI_SUCCESS;
03482 }
03483
03484 #ifdef IAXTESTS
03485 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03486 {
03487 switch (cmd) {
03488 case CLI_INIT:
03489 e->command = "iax2 test late";
03490 e->usage =
03491 "Usage: iax2 test late <ms>\n"
03492 " For testing, count the next frame as <ms> ms late\n";
03493 return NULL;
03494 case CLI_GENERATE:
03495 return NULL;
03496 }
03497
03498 if (a->argc != 4)
03499 return CLI_SHOWUSAGE;
03500
03501 test_late = atoi(a->argv[3]);
03502
03503 return CLI_SUCCESS;
03504 }
03505
03506 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03507 {
03508 switch (cmd) {
03509 case CLI_INIT:
03510 e->command = "iax2 test resync";
03511 e->usage =
03512 "Usage: iax2 test resync <ms>\n"
03513 " For testing, adjust all future frames by <ms> ms\n";
03514 return NULL;
03515 case CLI_GENERATE:
03516 return NULL;
03517 }
03518
03519 if (a->argc != 4)
03520 return CLI_SHOWUSAGE;
03521
03522 test_resync = atoi(a->argv[3]);
03523
03524 return CLI_SUCCESS;
03525 }
03526
03527 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03528 {
03529 switch (cmd) {
03530 case CLI_INIT:
03531 e->command = "iax2 test jitter";
03532 e->usage =
03533 "Usage: iax2 test jitter <ms> <pct>\n"
03534 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03535 " percentage of packets. If <pct> is not specified, adds\n"
03536 " jitter to all packets.\n";
03537 return NULL;
03538 case CLI_GENERATE:
03539 return NULL;
03540 }
03541
03542 if (a->argc < 4 || a->argc > 5)
03543 return CLI_SHOWUSAGE;
03544
03545 test_jit = atoi(a->argv[3]);
03546 if (a->argc == 5)
03547 test_jitpct = atoi(a->argv[4]);
03548
03549 return CLI_SUCCESS;
03550 }
03551 #endif
03552
03553
03554
03555 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03556 {
03557 int res = 0;
03558 if (peer->maxms) {
03559 if (peer->lastms < 0) {
03560 ast_copy_string(status, "UNREACHABLE", statuslen);
03561 } else if (peer->lastms > peer->maxms) {
03562 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03563 res = 1;
03564 } else if (peer->lastms) {
03565 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03566 res = 1;
03567 } else {
03568 ast_copy_string(status, "UNKNOWN", statuslen);
03569 }
03570 } else {
03571 ast_copy_string(status, "Unmonitored", statuslen);
03572 res = -1;
03573 }
03574 return res;
03575 }
03576
03577
03578 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03579 {
03580 char status[30];
03581 char cbuf[256];
03582 struct iax2_peer *peer;
03583 char codec_buf[512];
03584 struct ast_str *encmethods = ast_str_alloca(256);
03585 int x = 0, codec = 0, load_realtime = 0;
03586
03587 switch (cmd) {
03588 case CLI_INIT:
03589 e->command = "iax2 show peer";
03590 e->usage =
03591 "Usage: iax2 show peer <name>\n"
03592 " Display details on specific IAX peer\n";
03593 return NULL;
03594 case CLI_GENERATE:
03595 if (a->pos == 3)
03596 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03597 return NULL;
03598 }
03599
03600 if (a->argc < 4)
03601 return CLI_SHOWUSAGE;
03602
03603 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03604
03605 peer = find_peer(a->argv[3], load_realtime);
03606 if (peer) {
03607 encmethods_to_str(peer->encmethods, encmethods);
03608 ast_cli(a->fd, "\n\n");
03609 ast_cli(a->fd, " * Name : %s\n", peer->name);
03610 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03611 ast_cli(a->fd, " Context : %s\n", peer->context);
03612 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03613 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03614 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
03615 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03616 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03617 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
03618 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03619 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03620 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03621 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03622 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));
03623 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03624 ast_cli(a->fd, " Username : %s\n", peer->username);
03625 ast_cli(a->fd, " Codecs : ");
03626 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03627 ast_cli(a->fd, "%s\n", codec_buf);
03628
03629 ast_cli(a->fd, " Codec Order : (");
03630 for(x = 0; x < 32 ; x++) {
03631 codec = ast_codec_pref_index(&peer->prefs,x);
03632 if(!codec)
03633 break;
03634 ast_cli(a->fd, "%s", ast_getformatname(codec));
03635 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03636 ast_cli(a->fd, "|");
03637 }
03638
03639 if (!x)
03640 ast_cli(a->fd, "none");
03641 ast_cli(a->fd, ")\n");
03642
03643 ast_cli(a->fd, " Status : ");
03644 peer_status(peer, status, sizeof(status));
03645 ast_cli(a->fd, "%s\n",status);
03646 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");
03647 ast_cli(a->fd, "\n");
03648 peer_unref(peer);
03649 } else {
03650 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03651 ast_cli(a->fd, "\n");
03652 }
03653
03654 return CLI_SUCCESS;
03655 }
03656
03657 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, int flags)
03658 {
03659 int which = 0;
03660 struct iax2_peer *peer;
03661 char *res = NULL;
03662 int wordlen = strlen(word);
03663 struct ao2_iterator i;
03664
03665 i = ao2_iterator_init(peers, 0);
03666 while ((peer = ao2_iterator_next(&i))) {
03667 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03668 && (!flags || ast_test_flag(peer, flags))) {
03669 res = ast_strdup(peer->name);
03670 peer_unref(peer);
03671 break;
03672 }
03673 peer_unref(peer);
03674 }
03675 ao2_iterator_destroy(&i);
03676
03677 return res;
03678 }
03679
03680 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03681 {
03682 struct iax_frame *cur;
03683 int cnt = 0, dead = 0, final = 0;
03684
03685 switch (cmd) {
03686 case CLI_INIT:
03687 e->command = "iax2 show stats";
03688 e->usage =
03689 "Usage: iax2 show stats\n"
03690 " Display statistics on IAX channel driver.\n";
03691 return NULL;
03692 case CLI_GENERATE:
03693 return NULL;
03694 }
03695
03696 if (a->argc != 3)
03697 return CLI_SHOWUSAGE;
03698
03699 AST_LIST_LOCK(&frame_queue);
03700 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
03701 if (cur->retries < 0)
03702 dead++;
03703 if (cur->final)
03704 final++;
03705 cnt++;
03706 }
03707 AST_LIST_UNLOCK(&frame_queue);
03708
03709 ast_cli(a->fd, " IAX Statistics\n");
03710 ast_cli(a->fd, "---------------------\n");
03711 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03712 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03713 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03714 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03715
03716 trunk_timed = trunk_untimed = 0;
03717 if (trunk_maxmtu > trunk_nmaxmtu)
03718 trunk_nmaxmtu = trunk_maxmtu;
03719
03720 return CLI_SUCCESS;
03721 }
03722
03723
03724 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03725 {
03726 int mtuv;
03727
03728 switch (cmd) {
03729 case CLI_INIT:
03730 e->command = "iax2 set mtu";
03731 e->usage =
03732 "Usage: iax2 set mtu <value>\n"
03733 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03734 " zero to disable. Disabling means that the operating system\n"
03735 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03736 " packet exceeds the UDP payload size. This is substantially\n"
03737 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03738 " greater for G.711 samples.\n";
03739 return NULL;
03740 case CLI_GENERATE:
03741 return NULL;
03742 }
03743
03744 if (a->argc != 4)
03745 return CLI_SHOWUSAGE;
03746 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03747 mtuv = MAX_TRUNK_MTU;
03748 else
03749 mtuv = atoi(a->argv[3]);
03750
03751 if (mtuv == 0) {
03752 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03753 global_max_trunk_mtu = 0;
03754 return CLI_SUCCESS;
03755 }
03756 if (mtuv < 172 || mtuv > 4000) {
03757 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03758 return CLI_SHOWUSAGE;
03759 }
03760 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03761 global_max_trunk_mtu = mtuv;
03762 return CLI_SUCCESS;
03763 }
03764
03765 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03766 {
03767 struct iax2_dpcache *dp = NULL;
03768 char tmp[1024], *pc = NULL;
03769 int s, x, y;
03770 struct timeval now = ast_tvnow();
03771
03772 switch (cmd) {
03773 case CLI_INIT:
03774 e->command = "iax2 show cache";
03775 e->usage =
03776 "Usage: iax2 show cache\n"
03777 " Display currently cached IAX Dialplan results.\n";
03778 return NULL;
03779 case CLI_GENERATE:
03780 return NULL;
03781 }
03782
03783 AST_LIST_LOCK(&dpcache);
03784
03785 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03786
03787 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03788 s = dp->expiry.tv_sec - now.tv_sec;
03789 tmp[0] = '\0';
03790 if (dp->flags & CACHE_FLAG_EXISTS)
03791 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03792 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03793 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03794 if (dp->flags & CACHE_FLAG_CANEXIST)
03795 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03796 if (dp->flags & CACHE_FLAG_PENDING)
03797 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03798 if (dp->flags & CACHE_FLAG_TIMEOUT)
03799 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03800 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03801 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03802 if (dp->flags & CACHE_FLAG_MATCHMORE)
03803 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03804 if (dp->flags & CACHE_FLAG_UNKNOWN)
03805 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03806
03807 if (!ast_strlen_zero(tmp)) {
03808 tmp[strlen(tmp) - 1] = '\0';
03809 } else {
03810 ast_copy_string(tmp, "(none)", sizeof(tmp));
03811 }
03812 y = 0;
03813 pc = strchr(dp->peercontext, '@');
03814 if (!pc) {
03815 pc = dp->peercontext;
03816 } else {
03817 pc++;
03818 }
03819 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03820 if (dp->waiters[x] > -1)
03821 y++;
03822 }
03823 if (s > 0) {
03824 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03825 } else {
03826 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03827 }
03828 }
03829
03830 AST_LIST_UNLOCK(&dpcache);
03831
03832 return CLI_SUCCESS;
03833 }
03834
03835 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03836
03837 static void unwrap_timestamp(struct iax_frame *fr)
03838 {
03839
03840
03841 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03842 const int lower_mask = (1 << ts_shift) - 1;
03843 const int upper_mask = ~lower_mask;
03844 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03845
03846 if ( (fr->ts & upper_mask) == last_upper ) {
03847 const int x = fr->ts - iaxs[fr->callno]->last;
03848 const int threshold = (ts_shift == 15) ? 25000 : 50000;
03849
03850 if (x < -threshold) {
03851
03852
03853
03854
03855 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
03856 if (iaxdebug)
03857 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
03858 } else if (x > threshold) {
03859
03860
03861
03862
03863 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03864 if (iaxdebug)
03865 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
03866 }
03867 }
03868 }
03869
03870 static int get_from_jb(const void *p);
03871
03872 static void update_jbsched(struct chan_iax2_pvt *pvt)
03873 {
03874 int when;
03875
03876 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03877
03878 when = jb_next(pvt->jb) - when;
03879
03880 if (when <= 0) {
03881
03882 when = 1;
03883 }
03884
03885 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
03886 CALLNO_TO_PTR(pvt->callno));
03887 }
03888
03889 static void __get_from_jb(const void *p)
03890 {
03891 int callno = PTR_TO_CALLNO(p);
03892 struct chan_iax2_pvt *pvt = NULL;
03893 struct iax_frame *fr;
03894 jb_frame frame;
03895 int ret;
03896 long ms;
03897 long next;
03898 struct timeval now = ast_tvnow();
03899
03900
03901 ast_mutex_lock(&iaxsl[callno]);
03902 pvt = iaxs[callno];
03903 if (!pvt) {
03904
03905 ast_mutex_unlock(&iaxsl[callno]);
03906 return;
03907 }
03908
03909 pvt->jbid = -1;
03910
03911
03912
03913
03914 now.tv_usec += 1000;
03915
03916 ms = ast_tvdiff_ms(now, pvt->rxcore);
03917
03918 if(ms >= (next = jb_next(pvt->jb))) {
03919 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
03920 switch(ret) {
03921 case JB_OK:
03922 fr = frame.data;
03923 __do_deliver(fr);
03924
03925 pvt = iaxs[callno];
03926 break;
03927 case JB_INTERP:
03928 {
03929 struct ast_frame af = { 0, };
03930
03931
03932 af.frametype = AST_FRAME_VOICE;
03933 af.subclass = pvt->voiceformat;
03934 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03935 af.src = "IAX2 JB interpolation";
03936 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03937 af.offset = AST_FRIENDLY_OFFSET;
03938
03939
03940
03941 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03942 iax2_queue_frame(callno, &af);
03943
03944 pvt = iaxs[callno];
03945 }
03946 }
03947 break;
03948 case JB_DROP:
03949 iax2_frame_free(frame.data);
03950 break;
03951 case JB_NOFRAME:
03952 case JB_EMPTY:
03953
03954 break;
03955 default:
03956
03957 break;
03958 }
03959 }
03960 if (pvt)
03961 update_jbsched(pvt);
03962 ast_mutex_unlock(&iaxsl[callno]);
03963 }
03964
03965 static int get_from_jb(const void *data)
03966 {
03967 #ifdef SCHED_MULTITHREADED
03968 if (schedule_action(__get_from_jb, data))
03969 #endif
03970 __get_from_jb(data);
03971 return 0;
03972 }
03973
03974
03975
03976
03977
03978
03979
03980 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03981 {
03982 int type, len;
03983 int ret;
03984 int needfree = 0;
03985 struct ast_channel *owner = NULL;
03986 struct ast_channel *bridge = NULL;
03987
03988
03989 unwrap_timestamp(fr);
03990
03991
03992 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03993 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03994 else {
03995 #if 0
03996 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03997 #endif
03998 fr->af.delivery = ast_tv(0,0);
03999 }
04000
04001 type = JB_TYPE_CONTROL;
04002 len = 0;
04003
04004 if(fr->af.frametype == AST_FRAME_VOICE) {
04005 type = JB_TYPE_VOICE;
04006 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
04007 } else if(fr->af.frametype == AST_FRAME_CNG) {
04008 type = JB_TYPE_SILENCE;
04009 }
04010
04011 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04012 if (tsout)
04013 *tsout = fr->ts;
04014 __do_deliver(fr);
04015 return -1;
04016 }
04017
04018 if ((owner = iaxs[fr->callno]->owner))
04019 bridge = ast_bridged_channel(owner);
04020
04021
04022
04023 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04024 jb_frame frame;
04025
04026
04027 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04028 __do_deliver(frame.data);
04029
04030 if (!iaxs[fr->callno])
04031 return -1;
04032 }
04033
04034 jb_reset(iaxs[fr->callno]->jb);
04035
04036 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04037
04038
04039 if (tsout)
04040 *tsout = fr->ts;
04041 __do_deliver(fr);
04042 return -1;
04043 }
04044
04045
04046
04047 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04048 calc_rxstamp(iaxs[fr->callno],fr->ts));
04049 if (ret == JB_DROP) {
04050 needfree++;
04051 } else if (ret == JB_SCHED) {
04052 update_jbsched(iaxs[fr->callno]);
04053 }
04054 if (tsout)
04055 *tsout = fr->ts;
04056 if (needfree) {
04057
04058 iax2_frame_free(fr);
04059 return -1;
04060 }
04061 return 0;
04062 }
04063
04064 static int iax2_transmit(struct iax_frame *fr)
04065 {
04066
04067
04068
04069 fr->sentyet = 0;
04070 AST_LIST_LOCK(&frame_queue);
04071 AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
04072 AST_LIST_UNLOCK(&frame_queue);
04073
04074 if (netthreadid != AST_PTHREADT_NULL)
04075 pthread_kill(netthreadid, SIGURG);
04076 ast_sched_thread_poke(sched);
04077 return 0;
04078 }
04079
04080
04081
04082 static int iax2_digit_begin(struct ast_channel *c, char digit)
04083 {
04084 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04085 }
04086
04087 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04088 {
04089 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04090 }
04091
04092 static int iax2_sendtext(struct ast_channel *c, const char *text)
04093 {
04094
04095 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04096 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04097 }
04098
04099 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04100 {
04101 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1);
04102 }
04103
04104 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04105 {
04106 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04107 }
04108
04109 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04110 {
04111 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04112 ast_mutex_lock(&iaxsl[callno]);
04113 if (iaxs[callno])
04114 iaxs[callno]->owner = newchan;
04115 else
04116 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04117 ast_mutex_unlock(&iaxsl[callno]);
04118 return 0;
04119 }
04120
04121
04122
04123
04124
04125 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04126 {
04127 struct ast_variable *var = NULL;
04128 struct ast_variable *tmp;
04129 struct iax2_peer *peer=NULL;
04130 time_t regseconds = 0, nowtime;
04131 int dynamic=0;
04132
04133 if (peername) {
04134 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04135 if (!var && sin)
04136 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04137 } else if (sin) {
04138 char porta[25];
04139 sprintf(porta, "%d", ntohs(sin->sin_port));
04140 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04141 if (var) {
04142
04143 for (tmp = var; tmp; tmp = tmp->next) {
04144 if (!strcasecmp(tmp->name, "name"))
04145 peername = tmp->value;
04146 }
04147 }
04148 }
04149 if (!var && peername) {
04150 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04151
04152
04153
04154
04155
04156
04157 if (var && sin) {
04158 for (tmp = var; tmp; tmp = tmp->next) {
04159 if (!strcasecmp(tmp->name, "host")) {
04160 struct ast_hostent ahp;
04161 struct hostent *hp;
04162 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04163
04164 ast_variables_destroy(var);
04165 var = NULL;
04166 }
04167 break;
04168 }
04169 }
04170 }
04171 }
04172 if (!var)
04173 return NULL;
04174
04175 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04176
04177 if (!peer) {
04178 ast_variables_destroy(var);
04179 return NULL;
04180 }
04181
04182 for (tmp = var; tmp; tmp = tmp->next) {
04183
04184 if (!strcasecmp(tmp->name, "type")) {
04185 if (strcasecmp(tmp->value, "friend") &&
04186 strcasecmp(tmp->value, "peer")) {
04187
04188 peer = peer_unref(peer);
04189 break;
04190 }
04191 } else if (!strcasecmp(tmp->name, "regseconds")) {
04192 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04193 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04194 inet_aton(tmp->value, &(peer->addr.sin_addr));
04195 } else if (!strcasecmp(tmp->name, "port")) {
04196 peer->addr.sin_port = htons(atoi(tmp->value));
04197 } else if (!strcasecmp(tmp->name, "host")) {
04198 if (!strcasecmp(tmp->value, "dynamic"))
04199 dynamic = 1;
04200 }
04201 }
04202
04203 ast_variables_destroy(var);
04204
04205 if (!peer)
04206 return NULL;
04207
04208 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04209 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04210 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
04211 if (peer->expire > -1) {
04212 if (!ast_sched_thread_del(sched, peer->expire)) {
04213 peer->expire = -1;
04214 peer_unref(peer);
04215 }
04216 }
04217 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04218 if (peer->expire == -1)
04219 peer_unref(peer);
04220 }
04221 ao2_link(peers, peer);
04222 if (ast_test_flag(peer, IAX_DYNAMIC))
04223 reg_source_db(peer);
04224 } else {
04225 ast_set_flag(peer, IAX_TEMPONLY);
04226 }
04227
04228 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04229 time(&nowtime);
04230 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04231 memset(&peer->addr, 0, sizeof(peer->addr));
04232 realtime_update_peer(peer->name, &peer->addr, 0);
04233 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04234 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04235 }
04236 else {
04237 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04238 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04239 }
04240 }
04241
04242 return peer;
04243 }
04244
04245 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04246 {
04247 struct ast_variable *var;
04248 struct ast_variable *tmp;
04249 struct iax2_user *user=NULL;
04250
04251 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04252 if (!var)
04253 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04254 if (!var && sin) {
04255 char porta[6];
04256 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04257 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04258 if (!var)
04259 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04260 }
04261 if (!var) {
04262 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04263
04264
04265
04266
04267
04268
04269 if (var) {
04270 for (tmp = var; tmp; tmp = tmp->next) {
04271 if (!strcasecmp(tmp->name, "host")) {
04272 struct ast_hostent ahp;
04273 struct hostent *hp;
04274 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04275
04276 ast_variables_destroy(var);
04277 var = NULL;
04278 }
04279 break;
04280 }
04281 }
04282 }
04283 }
04284 if (!var)
04285 return NULL;
04286
04287 tmp = var;
04288 while(tmp) {
04289
04290 if (!strcasecmp(tmp->name, "type")) {
04291 if (strcasecmp(tmp->value, "friend") &&
04292 strcasecmp(tmp->value, "user")) {
04293 return NULL;
04294 }
04295 }
04296 tmp = tmp->next;
04297 }
04298
04299 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
04300
04301 ast_variables_destroy(var);
04302
04303 if (!user)
04304 return NULL;
04305
04306 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04307 ast_set_flag(user, IAX_RTCACHEFRIENDS);
04308 ao2_link(users, user);
04309 } else {
04310 ast_set_flag(user, IAX_TEMPONLY);
04311 }
04312
04313 return user;
04314 }
04315
04316 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
04317 {
04318 char port[10];
04319 char regseconds[20];
04320
04321 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04322 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
04323 ast_update_realtime("iaxpeers", "name", peername,
04324 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
04325 "regseconds", regseconds, SENTINEL);
04326 }
04327
04328 struct create_addr_info {
04329 int capability;
04330 unsigned int flags;
04331 int maxtime;
04332 int encmethods;
04333 int found;
04334 int sockfd;
04335 int adsi;
04336 char username[80];
04337 char secret[80];
04338 char outkey[80];
04339 char timezone[80];
04340 char prefs[32];
04341 char context[AST_MAX_CONTEXT];
04342 char peercontext[AST_MAX_CONTEXT];
04343 char mohinterpret[MAX_MUSICCLASS];
04344 char mohsuggest[MAX_MUSICCLASS];
04345 };
04346
04347 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04348 {
04349 struct iax2_peer *peer;
04350 int res = -1;
04351 struct ast_codec_pref ourprefs;
04352
04353 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
04354 cai->sockfd = defaultsockfd;
04355 cai->maxtime = 0;
04356 sin->sin_family = AF_INET;
04357
04358 if (!(peer = find_peer(peername, 1))) {
04359 cai->found = 0;
04360 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
04361 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04362 return -1;
04363 }
04364 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04365
04366
04367 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04368 if (c)
04369 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04370 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04371 return 0;
04372 }
04373
04374 cai->found = 1;
04375
04376
04377 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
04378 goto return_unref;
04379
04380
04381 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04382 goto return_unref;
04383
04384 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT);
04385 cai->maxtime = peer->maxms;
04386 cai->capability = peer->capability;
04387 cai->encmethods = peer->encmethods;
04388 cai->sockfd = peer->sockfd;
04389 cai->adsi = peer->adsi;
04390 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04391
04392 if (c) {
04393 ast_debug(1, "prepending %x to prefs\n", c->nativeformats);
04394 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04395 }
04396 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04397 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04398 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04399 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04400 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04401 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04402 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04403 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04404 if (ast_strlen_zero(peer->dbsecret)) {
04405 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04406 } else {
04407 char *family;
04408 char *key = NULL;
04409
04410 family = ast_strdupa(peer->dbsecret);
04411 key = strchr(family, '/');
04412 if (key)
04413 *key++ = '\0';
04414 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04415 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04416 goto return_unref;
04417 }
04418 }
04419
04420 if (peer->addr.sin_addr.s_addr) {
04421 sin->sin_addr = peer->addr.sin_addr;
04422 sin->sin_port = peer->addr.sin_port;
04423 } else {
04424 sin->sin_addr = peer->defaddr.sin_addr;
04425 sin->sin_port = peer->defaddr.sin_port;
04426 }
04427
04428 res = 0;
04429
04430 return_unref:
04431 peer_unref(peer);
04432
04433 return res;
04434 }
04435
04436 static void __auto_congest(const void *nothing)
04437 {
04438 int callno = PTR_TO_CALLNO(nothing);
04439 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
04440 ast_mutex_lock(&iaxsl[callno]);
04441 if (iaxs[callno]) {
04442 iaxs[callno]->initid = -1;
04443 iax2_queue_frame(callno, &f);
04444 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04445 }
04446 ast_mutex_unlock(&iaxsl[callno]);
04447 }
04448
04449 static int auto_congest(const void *data)
04450 {
04451 #ifdef SCHED_MULTITHREADED
04452 if (schedule_action(__auto_congest, data))
04453 #endif
04454 __auto_congest(data);
04455 return 0;
04456 }
04457
04458 static unsigned int iax2_datetime(const char *tz)
04459 {
04460 struct timeval t = ast_tvnow();
04461 struct ast_tm tm;
04462 unsigned int tmp;
04463 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04464 tmp = (tm.tm_sec >> 1) & 0x1f;
04465 tmp |= (tm.tm_min & 0x3f) << 5;
04466 tmp |= (tm.tm_hour & 0x1f) << 11;
04467 tmp |= (tm.tm_mday & 0x1f) << 16;
04468 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04469 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04470 return tmp;
04471 }
04472
04473 struct parsed_dial_string {
04474 char *username;
04475 char *password;
04476 char *key;
04477 char *peer;
04478 char *port;
04479 char *exten;
04480 char *context;
04481 char *options;
04482 };
04483
04484 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04485 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04486 int sockfd, struct iax_ie_data *ied)
04487 {
04488 struct {
04489 struct ast_iax2_full_hdr f;
04490 struct iax_ie_data ied;
04491 } data;
04492 size_t size = sizeof(struct ast_iax2_full_hdr);
04493
04494 if (ied) {
04495 size += ied->pos;
04496 memcpy(&data.ied, ied->buf, ied->pos);
04497 }
04498
04499 data.f.scallno = htons(0x8000 | callno);
04500 data.f.dcallno = htons(dcallno);
04501 data.f.ts = htonl(ts);
04502 data.f.iseqno = seqno;
04503 data.f.oseqno = 0;
04504 data.f.type = AST_FRAME_IAX;
04505 data.f.csub = compress_subclass(command);
04506
04507 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04508 }
04509
04510 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04511 {
04512
04513 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04514 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04515 ied->buf[ied->pos++] = 0;
04516 pvt->calltoken_ie_len = 2;
04517 }
04518 }
04519
04520 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04521 {
04522 struct chan_iax2_pvt *pvt = iaxs[callno];
04523 int frametype = f->af.frametype;
04524 int subclass = f->af.subclass;
04525 struct {
04526 struct ast_iax2_full_hdr fh;
04527 struct iax_ie_data ied;
04528 } data = {
04529 .ied.buf = { 0 },
04530 .ied.pos = 0,
04531 };
04532
04533 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04534
04535 if (!pvt) {
04536 return;
04537 }
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04551 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04552 (f->datalen > sizeof(data))) {
04553
04554 return;
04555 }
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571 memcpy(&data, f->data, f->datalen);
04572 data.ied.pos = ie_data_pos;
04573
04574
04575
04576 data.ied.pos -= pvt->calltoken_ie_len;
04577 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04578
04579
04580 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04581
04582
04583 AST_LIST_LOCK(&frame_queue);
04584 AST_LIST_REMOVE(&frame_queue, f, list);
04585 AST_LIST_UNLOCK(&frame_queue);
04586
04587
04588 iax2_frame_free(f);
04589
04590
04591 pvt->oseqno = 0;
04592 pvt->rseqno = 0;
04593 pvt->iseqno = 0;
04594 pvt->aseqno = 0;
04595 if (pvt->peercallno) {
04596 remove_by_peercallno(pvt);
04597 pvt->peercallno = 0;
04598 }
04599
04600
04601 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04602 }
04603
04604 static void requirecalltoken_mark_auto(const char *name, int subclass)
04605 {
04606 struct iax2_user *user = NULL;
04607 struct iax2_peer *peer = NULL;
04608
04609 if (ast_strlen_zero(name)) {
04610 return;
04611 }
04612
04613 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04614 user->calltoken_required = CALLTOKEN_YES;
04615 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04616 peer->calltoken_required = CALLTOKEN_YES;
04617 }
04618
04619 if (peer) {
04620 peer_unref(peer);
04621 }
04622 if (user) {
04623 user_unref(user);
04624 }
04625 }
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639
04640
04641
04642
04643
04644 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04645 struct sockaddr_in *sin, int fd)
04646 {
04647 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04648 #define CALLTOKEN_IE_FORMAT "%u?%s"
04649 struct ast_str *buf = ast_str_alloca(256);
04650 time_t t = time(NULL);
04651 char hash[41];
04652 int subclass = uncompress_subclass(fh->csub);
04653
04654
04655 if (ies->calltoken && !ies->calltokendata) {
04656 struct iax_ie_data ied = {
04657 .buf = { 0 },
04658 .pos = 0,
04659 };
04660
04661
04662 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04663 ast_sha1_hash(hash, ast_str_buffer(buf));
04664
04665 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04666 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04667 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04668
04669 return 1;
04670
04671
04672 } else if (ies->calltoken && ies->calltokendata) {
04673 char *rec_hash = NULL;
04674 char *rec_ts = NULL;
04675 unsigned int rec_time;
04676
04677
04678 rec_hash = strchr((char *) ies->calltokendata, '?');
04679 if (rec_hash) {
04680 *rec_hash++ = '\0';
04681 rec_ts = (char *) ies->calltokendata;
04682 }
04683
04684
04685 if (!rec_hash || !rec_ts) {
04686 goto reject;
04687 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04688 goto reject;
04689 }
04690
04691
04692 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04693 ast_sha1_hash(hash, ast_str_buffer(buf));
04694
04695
04696 if (strcmp(hash, rec_hash)) {
04697 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04698 goto reject;
04699 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04700 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04701 goto reject;
04702 }
04703
04704
04705
04706 requirecalltoken_mark_auto(ies->username, subclass);
04707 return 0;
04708
04709
04710 } else {
04711 if (calltoken_required(sin, ies->username, subclass)) {
04712 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"));
04713 goto reject;
04714 }
04715 return 0;
04716 }
04717
04718 reject:
04719
04720 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04721 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04722 } else {
04723 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04724 }
04725
04726 return 1;
04727 }
04728
04729
04730
04731
04732
04733
04734
04735
04736
04737
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04748 {
04749 if (ast_strlen_zero(data))
04750 return;
04751
04752 pds->peer = strsep(&data, "/");
04753 pds->exten = strsep(&data, "/");
04754 pds->options = data;
04755
04756 if (pds->exten) {
04757 data = pds->exten;
04758 pds->exten = strsep(&data, "@");
04759 pds->context = data;
04760 }
04761
04762 if (strchr(pds->peer, '@')) {
04763 data = pds->peer;
04764 pds->username = strsep(&data, "@");
04765 pds->peer = data;
04766 }
04767
04768 if (pds->username) {
04769 data = pds->username;
04770 pds->username = strsep(&data, ":");
04771 pds->password = data;
04772 }
04773
04774 data = pds->peer;
04775 pds->peer = strsep(&data, ":");
04776 pds->port = data;
04777
04778
04779
04780
04781 if (pds->password && (pds->password[0] == '[')) {
04782 pds->key = ast_strip_quoted(pds->password, "[", "]");
04783 pds->password = NULL;
04784 }
04785 }
04786
04787 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04788 {
04789 struct sockaddr_in sin;
04790 char *l=NULL, *n=NULL, *tmpstr;
04791 struct iax_ie_data ied;
04792 char *defaultrdest = "s";
04793 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04794 struct parsed_dial_string pds;
04795 struct create_addr_info cai;
04796 struct ast_var_t *var;
04797 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04798 const char* osp_token_ptr;
04799 unsigned int osp_token_length;
04800 unsigned char osp_block_index;
04801 unsigned int osp_block_length;
04802 unsigned char osp_buffer[256];
04803
04804 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
04805 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
04806 return -1;
04807 }
04808
04809 memset(&cai, 0, sizeof(cai));
04810 cai.encmethods = iax2_encryption;
04811
04812 memset(&pds, 0, sizeof(pds));
04813 tmpstr = ast_strdupa(dest);
04814 parse_dial_string(tmpstr, &pds);
04815
04816 if (ast_strlen_zero(pds.peer)) {
04817 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
04818 return -1;
04819 }
04820 if (!pds.exten) {
04821 pds.exten = defaultrdest;
04822 }
04823 if (create_addr(pds.peer, c, &sin, &cai)) {
04824 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
04825 return -1;
04826 }
04827 if (ast_strlen_zero(cai.secret) && ast_test_flag(iaxs[callno], IAX_FORCE_ENCRYPT)) {
04828 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
04829 return -1;
04830 }
04831 if (!pds.username && !ast_strlen_zero(cai.username))
04832 pds.username = cai.username;
04833 if (!pds.password && !ast_strlen_zero(cai.secret))
04834 pds.password = cai.secret;
04835 if (!pds.key && !ast_strlen_zero(cai.outkey))
04836 pds.key = cai.outkey;
04837 if (!pds.context && !ast_strlen_zero(cai.peercontext))
04838 pds.context = cai.peercontext;
04839
04840
04841 ast_copy_string(c->context, cai.context, sizeof(c->context));
04842
04843 if (pds.port)
04844 sin.sin_port = htons(atoi(pds.port));
04845
04846 l = c->cid.cid_num;
04847 n = c->cid.cid_name;
04848
04849
04850 memset(&ied, 0, sizeof(ied));
04851
04852
04853 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
04854 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
04855 if (pds.options && strchr(pds.options, 'a')) {
04856
04857 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
04858 }
04859
04860 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
04861
04862 if (l) {
04863 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
04864 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04865 } else {
04866 if (n)
04867 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04868 else
04869 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
04870 }
04871
04872 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
04873 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
04874
04875 if (n)
04876 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
04877 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
04878 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
04879
04880 if (!ast_strlen_zero(c->language))
04881 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
04882 if (!ast_strlen_zero(c->cid.cid_dnid))
04883 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
04884 if (!ast_strlen_zero(c->cid.cid_rdnis))
04885 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
04886
04887 if (pds.context)
04888 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
04889
04890 if (pds.username)
04891 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
04892
04893 if (cai.encmethods)
04894 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
04895
04896 ast_mutex_lock(&iaxsl[callno]);
04897
04898 if (!ast_strlen_zero(c->context))
04899 ast_string_field_set(iaxs[callno], context, c->context);
04900
04901 if (pds.username)
04902 ast_string_field_set(iaxs[callno], username, pds.username);
04903
04904 iaxs[callno]->encmethods = cai.encmethods;
04905
04906 iaxs[callno]->adsi = cai.adsi;
04907
04908 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
04909 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
04910
04911 if (pds.key)
04912 ast_string_field_set(iaxs[callno], outkey, pds.key);
04913 if (pds.password)
04914 ast_string_field_set(iaxs[callno], secret, pds.password);
04915
04916 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
04917 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
04918 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
04919 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
04920
04921 if (iaxs[callno]->maxtime) {
04922
04923 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
04924 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
04925 } else if (autokill) {
04926 iaxs[callno]->pingtime = autokill / 2;
04927 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
04928 }
04929
04930
04931 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
04932 if (!ast_strlen_zero(osp_token_ptr)) {
04933 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
04934 osp_block_index = 0;
04935 while (osp_token_length > 0) {
04936 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
04937 osp_buffer[0] = osp_block_index;
04938 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
04939 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
04940 osp_block_index++;
04941 osp_token_ptr += osp_block_length;
04942 osp_token_length -= osp_block_length;
04943 }
04944 } else
04945 ast_log(LOG_WARNING, "OSP token is too long\n");
04946 } else if (iaxdebug)
04947 ast_debug(1, "OSP token is undefined\n");
04948
04949
04950 iaxs[callno]->sockfd = cai.sockfd;
04951
04952
04953 if (variablestore) {
04954 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
04955 ast_debug(1, "Found an IAX variable store on this channel\n");
04956 AST_LIST_LOCK(variablelist);
04957 AST_LIST_TRAVERSE(variablelist, var, entries) {
04958 char tmp[256];
04959 int i;
04960 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
04961
04962 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
04963 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
04964 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
04965 }
04966 }
04967 AST_LIST_UNLOCK(variablelist);
04968 }
04969
04970
04971 add_empty_calltoken_ie(iaxs[callno], &ied);
04972 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
04973
04974 ast_mutex_unlock(&iaxsl[callno]);
04975 ast_setstate(c, AST_STATE_RINGING);
04976
04977 return 0;
04978 }
04979
04980 static int iax2_hangup(struct ast_channel *c)
04981 {
04982 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04983 struct iax_ie_data ied;
04984 int alreadygone;
04985 memset(&ied, 0, sizeof(ied));
04986 ast_mutex_lock(&iaxsl[callno]);
04987 if (callno && iaxs[callno]) {
04988 ast_debug(1, "We're hanging up %s now...\n", c->name);
04989 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
04990
04991 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
04992 if (!iaxs[callno]->error && !alreadygone) {
04993 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
04994 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
04995 }
04996 if (!iaxs[callno]) {
04997 ast_mutex_unlock(&iaxsl[callno]);
04998 return 0;
04999 }
05000 }
05001
05002 iax2_predestroy(callno);
05003
05004 if (iaxs[callno] && alreadygone) {
05005 ast_debug(1, "Really destroying %s now...\n", c->name);
05006 iax2_destroy(callno);
05007 } else if (iaxs[callno]) {
05008 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05009 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05010 iax2_destroy(callno);
05011 }
05012 }
05013 } else if (c->tech_pvt) {
05014
05015
05016
05017
05018 c->tech_pvt = NULL;
05019 }
05020 ast_mutex_unlock(&iaxsl[callno]);
05021 ast_verb(3, "Hungup '%s'\n", c->name);
05022 return 0;
05023 }
05024
05025
05026
05027
05028 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05029 {
05030 unsigned short callno = pvt->callno;
05031
05032 if (!pvt->peercallno) {
05033
05034 int count = 10;
05035 while (count-- && pvt && !pvt->peercallno) {
05036 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05037 pvt = iaxs[callno];
05038 }
05039 if (!pvt->peercallno) {
05040 return -1;
05041 }
05042 }
05043
05044 return 0;
05045 }
05046
05047 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05048 {
05049 struct ast_option_header *h;
05050 int res;
05051
05052 switch (option) {
05053 case AST_OPTION_TXGAIN:
05054 case AST_OPTION_RXGAIN:
05055
05056 errno = ENOSYS;
05057 return -1;
05058 case AST_OPTION_OPRMODE:
05059 errno = EINVAL;
05060 return -1;
05061 default:
05062 {
05063 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05064 struct chan_iax2_pvt *pvt;
05065
05066 ast_mutex_lock(&iaxsl[callno]);
05067 pvt = iaxs[callno];
05068
05069 if (wait_for_peercallno(pvt)) {
05070 ast_mutex_unlock(&iaxsl[callno]);
05071 return -1;
05072 }
05073
05074 ast_mutex_unlock(&iaxsl[callno]);
05075
05076 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05077 return -1;
05078 }
05079
05080 h->flag = AST_OPTION_FLAG_REQUEST;
05081 h->option = htons(option);
05082 memcpy(h->data, data, datalen);
05083 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05084 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05085 datalen + sizeof(*h), -1);
05086 ast_free(h);
05087 return res;
05088 }
05089 }
05090 }
05091
05092 static struct ast_frame *iax2_read(struct ast_channel *c)
05093 {
05094 ast_log(LOG_NOTICE, "I should never be called!\n");
05095 return &ast_null_frame;
05096 }
05097
05098 static int iax2_key_rotate(const void *vpvt)
05099 {
05100 int res = 0;
05101 struct chan_iax2_pvt *pvt = (void *) vpvt;
05102 struct MD5Context md5;
05103 char key[17] = "";
05104 struct iax_ie_data ied = {
05105 .pos = 0,
05106 };
05107
05108 ast_mutex_lock(&iaxsl[pvt->callno]);
05109 pvt->keyrotateid =
05110 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05111
05112 snprintf(key, sizeof(key), "%lX", ast_random());
05113
05114 MD5Init(&md5);
05115 MD5Update(&md5, (unsigned char *) key, strlen(key));
05116 MD5Final((unsigned char *) key, &md5);
05117
05118 IAX_DEBUGDIGEST("Sending", key);
05119
05120 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05121
05122 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05123
05124 build_ecx_key((unsigned char *) key, pvt);
05125
05126 ast_mutex_unlock(&iaxsl[pvt->callno]);
05127
05128 return res;
05129 }
05130
05131 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05132 {
05133 int res;
05134 struct iax_ie_data ied0;
05135 struct iax_ie_data ied1;
05136 unsigned int transferid = (unsigned int)ast_random();
05137
05138 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05139 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05140 ast_set_flag(iaxs[callno0], IAX_NOTRANSFER);
05141 ast_set_flag(iaxs[callno1], IAX_NOTRANSFER);
05142 return 0;
05143 }
05144
05145 memset(&ied0, 0, sizeof(ied0));
05146 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05147 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05148 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05149
05150 memset(&ied1, 0, sizeof(ied1));
05151 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05152 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05153 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05154
05155 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05156 if (res)
05157 return -1;
05158 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05159 if (res)
05160 return -1;
05161 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05162 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05163 return 0;
05164 }
05165
05166 static void lock_both(unsigned short callno0, unsigned short callno1)
05167 {
05168 ast_mutex_lock(&iaxsl[callno0]);
05169 while (ast_mutex_trylock(&iaxsl[callno1])) {
05170 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05171 }
05172 }
05173
05174 static void unlock_both(unsigned short callno0, unsigned short callno1)
05175 {
05176 ast_mutex_unlock(&iaxsl[callno1]);
05177 ast_mutex_unlock(&iaxsl[callno0]);
05178 }
05179
05180 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)
05181 {
05182 struct ast_channel *cs[3];
05183 struct ast_channel *who, *other;
05184 int to = -1;
05185 int res = -1;
05186 int transferstarted=0;
05187 struct ast_frame *f;
05188 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05189 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05190 struct timeval waittimer = {0, 0};
05191
05192
05193 if (timeoutms > 0) {
05194 return AST_BRIDGE_FAILED;
05195 }
05196
05197 timeoutms = -1;
05198
05199 lock_both(callno0, callno1);
05200 if (!iaxs[callno0] || !iaxs[callno1]) {
05201 unlock_both(callno0, callno1);
05202 return AST_BRIDGE_FAILED;
05203 }
05204
05205 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05206 iaxs[callno0]->bridgecallno = callno1;
05207 iaxs[callno1]->bridgecallno = callno0;
05208 }
05209 unlock_both(callno0, callno1);
05210
05211
05212 cs[0] = c0;
05213 cs[1] = c1;
05214 for (;;) {
05215
05216 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05217 ast_verb(3, "Can't masquerade, we're different...\n");
05218
05219 if (c0->tech == &iax2_tech) {
05220 ast_mutex_lock(&iaxsl[callno0]);
05221 iaxs[callno0]->bridgecallno = 0;
05222 ast_mutex_unlock(&iaxsl[callno0]);
05223 }
05224 if (c1->tech == &iax2_tech) {
05225 ast_mutex_lock(&iaxsl[callno1]);
05226 iaxs[callno1]->bridgecallno = 0;
05227 ast_mutex_unlock(&iaxsl[callno1]);
05228 }
05229 return AST_BRIDGE_FAILED_NOWARN;
05230 }
05231 if (c0->nativeformats != c1->nativeformats) {
05232 char buf0[255];
05233 char buf1[255];
05234 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
05235 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
05236 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
05237
05238 lock_both(callno0, callno1);
05239 if (iaxs[callno0])
05240 iaxs[callno0]->bridgecallno = 0;
05241 if (iaxs[callno1])
05242 iaxs[callno1]->bridgecallno = 0;
05243 unlock_both(callno0, callno1);
05244 return AST_BRIDGE_FAILED_NOWARN;
05245 }
05246
05247 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
05248
05249 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05250 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
05251 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05252 transferstarted = 1;
05253 }
05254 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05255
05256 struct timeval now = ast_tvnow();
05257 if (ast_tvzero(waittimer)) {
05258 waittimer = now;
05259 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05260 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05261 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05262 *fo = NULL;
05263 *rc = c0;
05264 res = AST_BRIDGE_COMPLETE;
05265 break;
05266 }
05267 }
05268 to = 1000;
05269 who = ast_waitfor_n(cs, 2, &to);
05270 if (timeoutms > -1) {
05271 timeoutms -= (1000 - to);
05272 if (timeoutms < 0)
05273 timeoutms = 0;
05274 }
05275 if (!who) {
05276 if (!timeoutms) {
05277 res = AST_BRIDGE_RETRY;
05278 break;
05279 }
05280 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05281 res = AST_BRIDGE_FAILED;
05282 break;
05283 }
05284 continue;
05285 }
05286 f = ast_read(who);
05287 if (!f) {
05288 *fo = NULL;
05289 *rc = who;
05290 res = AST_BRIDGE_COMPLETE;
05291 break;
05292 }
05293 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
05294 *fo = f;
05295 *rc = who;
05296 res = AST_BRIDGE_COMPLETE;
05297 break;
05298 }
05299 other = (who == c0) ? c1 : c0;
05300 if ((f->frametype == AST_FRAME_VOICE) ||
05301 (f->frametype == AST_FRAME_TEXT) ||
05302 (f->frametype == AST_FRAME_VIDEO) ||
05303 (f->frametype == AST_FRAME_IMAGE) ||
05304 (f->frametype == AST_FRAME_DTMF) ||
05305 (f->frametype == AST_FRAME_CONTROL)) {
05306
05307
05308
05309 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05310 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05311 *rc = who;
05312 *fo = f;
05313 res = AST_BRIDGE_COMPLETE;
05314
05315 break;
05316 }
05317
05318 ast_write(other, f);
05319 }
05320 ast_frfree(f);
05321
05322 cs[2] = cs[0];
05323 cs[0] = cs[1];
05324 cs[1] = cs[2];
05325 }
05326 lock_both(callno0, callno1);
05327 if(iaxs[callno0])
05328 iaxs[callno0]->bridgecallno = 0;
05329 if(iaxs[callno1])
05330 iaxs[callno1]->bridgecallno = 0;
05331 unlock_both(callno0, callno1);
05332 return res;
05333 }
05334
05335 static int iax2_answer(struct ast_channel *c)
05336 {
05337 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05338 ast_debug(1, "Answering IAX2 call\n");
05339 ast_mutex_lock(&iaxsl[callno]);
05340 if (iaxs[callno])
05341 iax2_ami_channelupdate(iaxs[callno]);
05342 ast_mutex_unlock(&iaxsl[callno]);
05343 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05344 }
05345
05346 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05347 {
05348 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05349 struct chan_iax2_pvt *pvt;
05350 int res = 0;
05351
05352 if (iaxdebug)
05353 ast_debug(1, "Indicating condition %d\n", condition);
05354
05355 ast_mutex_lock(&iaxsl[callno]);
05356 pvt = iaxs[callno];
05357
05358 if (wait_for_peercallno(pvt)) {
05359 res = -1;
05360 goto done;
05361 }
05362
05363 switch (condition) {
05364 case AST_CONTROL_HOLD:
05365 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05366 ast_moh_start(c, data, pvt->mohinterpret);
05367 goto done;
05368 }
05369 break;
05370 case AST_CONTROL_UNHOLD:
05371 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05372 ast_moh_stop(c);
05373 goto done;
05374 }
05375 }
05376
05377 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05378
05379 done:
05380 ast_mutex_unlock(&iaxsl[callno]);
05381
05382 return res;
05383 }
05384
05385 static int iax2_transfer(struct ast_channel *c, const char *dest)
05386 {
05387 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05388 struct iax_ie_data ied = { "", };
05389 char tmp[256], *context;
05390 ast_copy_string(tmp, dest, sizeof(tmp));
05391 context = strchr(tmp, '@');
05392 if (context) {
05393 *context = '\0';
05394 context++;
05395 }
05396 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05397 if (context)
05398 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05399 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05400 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05401 }
05402
05403 static int iax2_getpeertrunk(struct sockaddr_in sin)
05404 {
05405 struct iax2_peer *peer;
05406 int res = 0;
05407 struct ao2_iterator i;
05408
05409 i = ao2_iterator_init(peers, 0);
05410 while ((peer = ao2_iterator_next(&i))) {
05411 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05412 (peer->addr.sin_port == sin.sin_port)) {
05413 res = ast_test_flag(peer, IAX_TRUNK);
05414 peer_unref(peer);
05415 break;
05416 }
05417 peer_unref(peer);
05418 }
05419 ao2_iterator_destroy(&i);
05420
05421 return res;
05422 }
05423
05424
05425 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
05426 {
05427 struct ast_channel *tmp;
05428 struct chan_iax2_pvt *i;
05429 struct ast_variable *v = NULL;
05430
05431 if (!(i = iaxs[callno])) {
05432 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05433 return NULL;
05434 }
05435
05436
05437 ast_mutex_unlock(&iaxsl[callno]);
05438 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);
05439 ast_mutex_lock(&iaxsl[callno]);
05440 if (i != iaxs[callno]) {
05441 if (tmp) {
05442
05443 ast_mutex_unlock(&iaxsl[callno]);
05444 ast_channel_free(tmp);
05445 ast_mutex_lock(&iaxsl[callno]);
05446 }
05447 return NULL;
05448 }
05449 iax2_ami_channelupdate(i);
05450 if (!tmp)
05451 return NULL;
05452 tmp->tech = &iax2_tech;
05453
05454 tmp->nativeformats = capability;
05455 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05456 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05457 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05458
05459 if (!ast_strlen_zero(i->parkinglot))
05460 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05461
05462
05463 if (!ast_strlen_zero(i->ani))
05464 tmp->cid.cid_ani = ast_strdup(i->ani);
05465 else
05466 tmp->cid.cid_ani = ast_strdup(i->cid_num);
05467 tmp->cid.cid_dnid = ast_strdup(i->dnid);
05468 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05469 tmp->cid.cid_pres = i->calling_pres;
05470 tmp->cid.cid_ton = i->calling_ton;
05471 tmp->cid.cid_tns = i->calling_tns;
05472 if (!ast_strlen_zero(i->language))
05473 ast_string_field_set(tmp, language, i->language);
05474 if (!ast_strlen_zero(i->accountcode))
05475 ast_string_field_set(tmp, accountcode, i->accountcode);
05476 if (i->amaflags)
05477 tmp->amaflags = i->amaflags;
05478 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05479 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05480 if (i->adsi)
05481 tmp->adsicpe = i->peeradsicpe;
05482 else
05483 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05484 i->owner = tmp;
05485 i->capability = capability;
05486
05487
05488 if (i->vars) {
05489 for (v = i->vars ; v ; v = v->next)
05490 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05491 }
05492 if (i->iaxvars) {
05493 struct ast_datastore *variablestore;
05494 struct ast_variable *var, *prev = NULL;
05495 AST_LIST_HEAD(, ast_var_t) *varlist;
05496 ast_debug(1, "Loading up the channel with IAXVARs\n");
05497 varlist = ast_calloc(1, sizeof(*varlist));
05498 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05499 if (variablestore && varlist) {
05500 variablestore->data = varlist;
05501 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05502 AST_LIST_HEAD_INIT(varlist);
05503 for (var = i->iaxvars; var; var = var->next) {
05504 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05505 if (prev)
05506 ast_free(prev);
05507 prev = var;
05508 if (!newvar) {
05509
05510 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05511 } else {
05512 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05513 }
05514 }
05515 if (prev)
05516 ast_free(prev);
05517 i->iaxvars = NULL;
05518 ast_channel_datastore_add(i->owner, variablestore);
05519 } else {
05520 if (variablestore) {
05521 ast_datastore_free(variablestore);
05522 }
05523 if (varlist) {
05524 ast_free(varlist);
05525 }
05526 }
05527 }
05528
05529 if (state != AST_STATE_DOWN) {
05530 if (ast_pbx_start(tmp)) {
05531 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05532 ast_hangup(tmp);
05533 i->owner = NULL;
05534 return NULL;
05535 }
05536 }
05537
05538 ast_module_ref(ast_module_info->self);
05539 return tmp;
05540 }
05541
05542 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05543 {
05544 unsigned long int mssincetx;
05545 long int ms, pred;
05546
05547 tpeer->trunkact = *now;
05548 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05549 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05550
05551 tpeer->txtrunktime = *now;
05552 tpeer->lastsent = 999999;
05553 }
05554
05555 tpeer->lasttxtime = *now;
05556
05557
05558 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05559
05560 pred = tpeer->lastsent + sampms;
05561 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05562 ms = pred;
05563
05564
05565 if (ms == tpeer->lastsent)
05566 ms = tpeer->lastsent + 1;
05567 tpeer->lastsent = ms;
05568 return ms;
05569 }
05570
05571 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05572 {
05573 long ms;
05574 if (ast_tvzero(iaxs[callno]->rxcore)) {
05575
05576 iaxs[callno]->rxcore = ast_tvnow();
05577
05578 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05579 }
05580
05581 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05582
05583 return ms + ts;
05584 }
05585
05586 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05587 {
05588 int ms;
05589 int voice = 0;
05590 int genuine = 0;
05591 int adjust;
05592 int rate = ast_format_rate(f->subclass) / 1000;
05593 struct timeval *delivery = NULL;
05594
05595
05596
05597
05598
05599
05600
05601
05602 if (f) {
05603 if (f->frametype == AST_FRAME_VOICE) {
05604 voice = 1;
05605 delivery = &f->delivery;
05606 } else if (f->frametype == AST_FRAME_IAX) {
05607 genuine = 1;
05608 } else if (f->frametype == AST_FRAME_CNG) {
05609 p->notsilenttx = 0;
05610 }
05611 }
05612 if (ast_tvzero(p->offset)) {
05613 p->offset = ast_tvnow();
05614
05615 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05616 }
05617
05618 if (ts)
05619 return ts;
05620
05621 if (delivery && !ast_tvzero(*delivery)) {
05622 ms = ast_tvdiff_ms(*delivery, p->offset);
05623 if (ms < 0) {
05624 ms = 0;
05625 }
05626 if (iaxdebug)
05627 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05628 } else {
05629 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05630 if (ms < 0)
05631 ms = 0;
05632 if (voice) {
05633
05634 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05635
05636
05637
05638
05639
05640
05641
05642
05643
05644
05645
05646
05647
05648
05649
05650
05651
05652
05653 adjust = (ms - p->nextpred);
05654 if (adjust < 0)
05655 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05656 else if (adjust > 0)
05657 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05658
05659 if (!p->nextpred) {
05660 p->nextpred = ms;
05661 if (p->nextpred <= p->lastsent)
05662 p->nextpred = p->lastsent + 3;
05663 }
05664 ms = p->nextpred;
05665 } else {
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05676 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05677 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05678
05679 if (f->samples >= rate)
05680 {
05681 int diff = ms % (f->samples / rate);
05682 if (diff)
05683 ms += f->samples/rate - diff;
05684 }
05685
05686 p->nextpred = ms;
05687 p->notsilenttx = 1;
05688 }
05689 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05690
05691
05692
05693
05694
05695
05696
05697
05698 if ( (unsigned int)ms < p->lastsent )
05699 ms = p->lastsent;
05700 } else {
05701
05702
05703 if (genuine) {
05704
05705 if (ms <= p->lastsent)
05706 ms = p->lastsent + 3;
05707 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05708
05709 ms = p->lastsent + 3;
05710 }
05711 }
05712 }
05713 p->lastsent = ms;
05714 if (voice)
05715 p->nextpred = p->nextpred + f->samples / rate;
05716 return ms;
05717 }
05718
05719 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05720 {
05721
05722
05723 int ms;
05724 #ifdef IAXTESTS
05725 int jit;
05726 #endif
05727
05728 if (ast_tvzero(p->rxcore)) {
05729 p->rxcore = ast_tvnow();
05730 if (iaxdebug)
05731 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05732 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05733 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05734 #if 1
05735 if (iaxdebug)
05736 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05737 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05738 #endif
05739 }
05740
05741 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05742 #ifdef IAXTESTS
05743 if (test_jit) {
05744 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05745 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05746 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05747 jit = -jit;
05748 ms += jit;
05749 }
05750 }
05751 if (test_late) {
05752 ms += test_late;
05753 test_late = 0;
05754 }
05755 #endif
05756 return ms;
05757 }
05758
05759 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
05760 {
05761 struct iax2_trunk_peer *tpeer = NULL;
05762
05763
05764 AST_LIST_LOCK(&tpeers);
05765
05766 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
05767 if (!inaddrcmp(&tpeer->addr, sin)) {
05768 ast_mutex_lock(&tpeer->lock);
05769 break;
05770 }
05771 }
05772
05773 if (!tpeer) {
05774 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
05775 ast_mutex_init(&tpeer->lock);
05776 tpeer->lastsent = 9999;
05777 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
05778 tpeer->trunkact = ast_tvnow();
05779 ast_mutex_lock(&tpeer->lock);
05780 tpeer->sockfd = fd;
05781 #ifdef SO_NO_CHECK
05782 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
05783 #endif
05784 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05785 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
05786 }
05787 }
05788
05789 AST_LIST_UNLOCK(&tpeers);
05790
05791 return tpeer;
05792 }
05793
05794 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
05795 {
05796 struct ast_frame *f;
05797 struct iax2_trunk_peer *tpeer;
05798 void *tmp, *ptr;
05799 struct timeval now;
05800 int res;
05801 struct ast_iax2_meta_trunk_entry *met;
05802 struct ast_iax2_meta_trunk_mini *mtm;
05803
05804 f = &fr->af;
05805 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
05806 if (tpeer) {
05807 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
05808
05809 if (tpeer->trunkdataalloc < trunkmaxsize) {
05810 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
05811 ast_mutex_unlock(&tpeer->lock);
05812 return -1;
05813 }
05814
05815 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
05816 tpeer->trunkdata = tmp;
05817 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);
05818 } else {
05819 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));
05820 ast_mutex_unlock(&tpeer->lock);
05821 return -1;
05822 }
05823 }
05824
05825
05826 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
05827 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
05828 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
05829 mtm->len = htons(f->datalen);
05830 mtm->mini.callno = htons(pvt->callno);
05831 mtm->mini.ts = htons(0xffff & fr->ts);
05832 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
05833 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
05834 } else {
05835 met = (struct ast_iax2_meta_trunk_entry *)ptr;
05836
05837 met->callno = htons(pvt->callno);
05838 met->len = htons(f->datalen);
05839
05840 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
05841 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
05842 }
05843
05844 memcpy(ptr, f->data.ptr, f->datalen);
05845 tpeer->trunkdatalen += f->datalen;
05846
05847 tpeer->calls++;
05848
05849
05850 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
05851 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
05852
05853
05854 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
05855 now = ast_tvnow();
05856 res = send_trunk(tpeer, &now);
05857 trunk_untimed ++;
05858 }
05859
05860 ast_mutex_unlock(&tpeer->lock);
05861 }
05862 return 0;
05863 }
05864
05865
05866
05867 static void build_rand_pad(unsigned char *buf, ssize_t len)
05868 {
05869 long tmp;
05870 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05871 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05872 buf += sizeof(tmp);
05873 len -= sizeof(tmp);
05874 }
05875 }
05876
05877 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05878 {
05879 build_ecx_key(digest, pvt);
05880 ast_aes_decrypt_key(digest, &pvt->dcx);
05881 }
05882
05883 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05884 {
05885
05886
05887
05888 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05889 ast_aes_encrypt_key(digest, &pvt->ecx);
05890 ast_aes_decrypt_key(digest, &pvt->mydcx);
05891 }
05892
05893 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
05894 {
05895 #if 0
05896
05897 int x;
05898 if (len % 16)
05899 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05900 for (x=0;x<len;x++)
05901 dst[x] = src[x] ^ 0xff;
05902 #else
05903 unsigned char lastblock[16] = { 0 };
05904 int x;
05905 while(len > 0) {
05906 ast_aes_decrypt(src, dst, dcx);
05907 for (x=0;x<16;x++)
05908 dst[x] ^= lastblock[x];
05909 memcpy(lastblock, src, sizeof(lastblock));
05910 dst += 16;
05911 src += 16;
05912 len -= 16;
05913 }
05914 #endif
05915 }
05916
05917 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
05918 {
05919 #if 0
05920
05921 int x;
05922 if (len % 16)
05923 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05924 for (x=0;x<len;x++)
05925 dst[x] = src[x] ^ 0xff;
05926 #else
05927 unsigned char curblock[16] = { 0 };
05928 int x;
05929 while(len > 0) {
05930 for (x=0;x<16;x++)
05931 curblock[x] ^= src[x];
05932 ast_aes_encrypt(curblock, dst, ecx);
05933 memcpy(curblock, dst, sizeof(curblock));
05934 dst += 16;
05935 src += 16;
05936 len -= 16;
05937 }
05938 #endif
05939 }
05940
05941 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05942 {
05943 int padding;
05944 unsigned char *workspace;
05945
05946 workspace = alloca(*datalen);
05947 memset(f, 0, sizeof(*f));
05948 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05949 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05950 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
05951 return -1;
05952
05953 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
05954
05955 padding = 16 + (workspace[15] & 0x0f);
05956 if (iaxdebug)
05957 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
05958 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
05959 return -1;
05960
05961 *datalen -= padding;
05962 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05963 f->frametype = fh->type;
05964 if (f->frametype == AST_FRAME_VIDEO) {
05965 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
05966 } else {
05967 f->subclass = uncompress_subclass(fh->csub);
05968 }
05969 } else {
05970 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05971 if (iaxdebug)
05972 ast_debug(1, "Decoding mini with length %d\n", *datalen);
05973 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
05974 return -1;
05975
05976 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
05977 padding = 16 + (workspace[15] & 0x0f);
05978 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
05979 return -1;
05980 *datalen -= padding;
05981 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05982 }
05983 return 0;
05984 }
05985
05986 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
05987 {
05988 int padding;
05989 unsigned char *workspace;
05990 workspace = alloca(*datalen + 32);
05991 if (!workspace)
05992 return -1;
05993 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05994 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05995 if (iaxdebug)
05996 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
05997 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
05998 padding = 16 + (padding & 0xf);
05999 memcpy(workspace, poo, padding);
06000 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06001 workspace[15] &= 0xf0;
06002 workspace[15] |= (padding & 0xf);
06003 if (iaxdebug)
06004 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06005 *datalen += padding;
06006 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06007 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06008 memcpy(poo, workspace + *datalen - 32, 32);
06009 } else {
06010 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06011 if (iaxdebug)
06012 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06013 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06014 padding = 16 + (padding & 0xf);
06015 memcpy(workspace, poo, padding);
06016 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06017 workspace[15] &= 0xf0;
06018 workspace[15] |= (padding & 0x0f);
06019 *datalen += padding;
06020 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06021 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06022 memcpy(poo, workspace + *datalen - 32, 32);
06023 }
06024 return 0;
06025 }
06026
06027 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06028 {
06029 int res=-1;
06030 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
06031
06032 struct MD5Context md5;
06033 unsigned char digest[16];
06034 char *tmppw, *stringp;
06035
06036 tmppw = ast_strdupa(iaxs[callno]->secret);
06037 stringp = tmppw;
06038 while ((tmppw = strsep(&stringp, ";"))) {
06039 MD5Init(&md5);
06040 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06041 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06042 MD5Final(digest, &md5);
06043 build_encryption_keys(digest, iaxs[callno]);
06044 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06045 if (!res) {
06046 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
06047 break;
06048 }
06049 }
06050 } else
06051 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06052 return res;
06053 }
06054
06055 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06056 {
06057
06058
06059
06060 struct ast_iax2_full_hdr *fh;
06061 struct ast_iax2_mini_hdr *mh;
06062 struct ast_iax2_video_hdr *vh;
06063 struct {
06064 struct iax_frame fr2;
06065 unsigned char buffer[4096];
06066 } frb;
06067 struct iax_frame *fr;
06068 int res;
06069 int sendmini=0;
06070 unsigned int lastsent;
06071 unsigned int fts;
06072
06073 frb.fr2.afdatalen = sizeof(frb.buffer);
06074
06075 if (!pvt) {
06076 ast_log(LOG_WARNING, "No private structure for packet?\n");
06077 return -1;
06078 }
06079
06080 lastsent = pvt->lastsent;
06081
06082
06083 fts = calc_timestamp(pvt, ts, f);
06084
06085
06086
06087
06088 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06089 return 0;
06090 #if 0
06091 ast_log(LOG_NOTICE,
06092 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06093 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06094 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06095 pvt->keyrotateid != -1 ? "" : "no "
06096 );
06097 #endif
06098 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06099 iax2_key_rotate(pvt);
06100 }
06101
06102 if ((ast_test_flag(pvt, IAX_TRUNK) ||
06103 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06104 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06105 &&
06106 (f->frametype == AST_FRAME_VOICE)
06107 &&
06108 (f->subclass == pvt->svoiceformat)
06109 ) {
06110
06111 now = 1;
06112
06113 sendmini = 1;
06114 }
06115 if ( f->frametype == AST_FRAME_VIDEO ) {
06116
06117
06118
06119
06120
06121 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06122 ((f->subclass & ~0x1) == pvt->svideoformat)
06123 ) {
06124 now = 1;
06125 sendmini = 1;
06126 } else {
06127 now = 0;
06128 sendmini = 0;
06129 }
06130 pvt->lastvsent = fts;
06131 }
06132 if (f->frametype == AST_FRAME_IAX) {
06133
06134 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
06135 if (!pvt->first_iax_message) {
06136 pvt->first_iax_message = pvt->last_iax_message;
06137 }
06138 }
06139
06140 if (now) {
06141 fr = &frb.fr2;
06142 } else
06143 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));
06144 if (!fr) {
06145 ast_log(LOG_WARNING, "Out of memory\n");
06146 return -1;
06147 }
06148
06149 iax_frame_wrap(fr, f);
06150
06151 fr->ts = fts;
06152 fr->callno = pvt->callno;
06153 fr->transfer = transfer;
06154 fr->final = final;
06155 fr->encmethods = 0;
06156 if (!sendmini) {
06157
06158 if (seqno > -1)
06159 fr->oseqno = seqno;
06160 else
06161 fr->oseqno = pvt->oseqno++;
06162 fr->iseqno = pvt->iseqno;
06163 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06164 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06165 fh->ts = htonl(fr->ts);
06166 fh->oseqno = fr->oseqno;
06167 if (transfer) {
06168 fh->iseqno = 0;
06169 } else
06170 fh->iseqno = fr->iseqno;
06171
06172 if (!transfer)
06173 pvt->aseqno = fr->iseqno;
06174 fh->type = fr->af.frametype & 0xFF;
06175 if (fr->af.frametype == AST_FRAME_VIDEO)
06176 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
06177 else
06178 fh->csub = compress_subclass(fr->af.subclass);
06179 if (transfer) {
06180 fr->dcallno = pvt->transfercallno;
06181 } else
06182 fr->dcallno = pvt->peercallno;
06183 fh->dcallno = htons(fr->dcallno);
06184 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06185 fr->data = fh;
06186 fr->retries = 0;
06187
06188 fr->retrytime = pvt->pingtime * 2;
06189 if (fr->retrytime < MIN_RETRY_TIME)
06190 fr->retrytime = MIN_RETRY_TIME;
06191 if (fr->retrytime > MAX_RETRY_TIME)
06192 fr->retrytime = MAX_RETRY_TIME;
06193
06194 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
06195 fr->retries = -1;
06196 else if (f->frametype == AST_FRAME_VOICE)
06197 pvt->svoiceformat = f->subclass;
06198 else if (f->frametype == AST_FRAME_VIDEO)
06199 pvt->svideoformat = f->subclass & ~0x1;
06200 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06201 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06202 if (fr->transfer)
06203 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06204 else
06205 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06206 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06207 fr->encmethods = pvt->encmethods;
06208 fr->ecx = pvt->ecx;
06209 fr->mydcx = pvt->mydcx;
06210 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06211 } else
06212 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06213 }
06214
06215 if (now) {
06216 res = send_packet(fr);
06217 } else
06218 res = iax2_transmit(fr);
06219 } else {
06220 if (ast_test_flag(pvt, IAX_TRUNK)) {
06221 iax2_trunk_queue(pvt, fr);
06222 res = 0;
06223 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06224
06225 fr->oseqno = -1;
06226 fr->iseqno = -1;
06227 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06228 vh->zeros = 0;
06229 vh->callno = htons(0x8000 | fr->callno);
06230 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
06231 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06232 fr->data = vh;
06233 fr->retries = -1;
06234 res = send_packet(fr);
06235 } else {
06236
06237 fr->oseqno = -1;
06238 fr->iseqno = -1;
06239
06240 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06241 mh->callno = htons(fr->callno);
06242 mh->ts = htons(fr->ts & 0xFFFF);
06243 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06244 fr->data = mh;
06245 fr->retries = -1;
06246 if (pvt->transferring == TRANSFER_MEDIAPASS)
06247 fr->transfer = 1;
06248 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06249 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06250 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06251 } else
06252 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06253 }
06254 res = send_packet(fr);
06255 }
06256 }
06257 return res;
06258 }
06259
06260 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06261 {
06262 regex_t regexbuf;
06263 int havepattern = 0;
06264
06265 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06266 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06267
06268 struct iax2_user *user = NULL;
06269 char auth[90];
06270 char *pstr = "";
06271 struct ao2_iterator i;
06272
06273 switch (cmd) {
06274 case CLI_INIT:
06275 e->command = "iax2 show users [like]";
06276 e->usage =
06277 "Usage: iax2 show users [like <pattern>]\n"
06278 " Lists all known IAX2 users.\n"
06279 " Optional regular expression pattern is used to filter the user list.\n";
06280 return NULL;
06281 case CLI_GENERATE:
06282 return NULL;
06283 }
06284
06285 switch (a->argc) {
06286 case 5:
06287 if (!strcasecmp(a->argv[3], "like")) {
06288 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06289 return CLI_SHOWUSAGE;
06290 havepattern = 1;
06291 } else
06292 return CLI_SHOWUSAGE;
06293 case 3:
06294 break;
06295 default:
06296 return CLI_SHOWUSAGE;
06297 }
06298
06299 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06300 i = ao2_iterator_init(users, 0);
06301 for (user = ao2_iterator_next(&i); user;
06302 user_unref(user), user = ao2_iterator_next(&i)) {
06303 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06304 continue;
06305
06306 if (!ast_strlen_zero(user->secret)) {
06307 ast_copy_string(auth,user->secret, sizeof(auth));
06308 } else if (!ast_strlen_zero(user->inkeys)) {
06309 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06310 } else
06311 ast_copy_string(auth, "-no secret-", sizeof(auth));
06312
06313 if(ast_test_flag(user,IAX_CODEC_NOCAP))
06314 pstr = "REQ Only";
06315 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
06316 pstr = "Disabled";
06317 else
06318 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06319
06320 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06321 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06322 user->ha ? "Yes" : "No", pstr);
06323 }
06324 ao2_iterator_destroy(&i);
06325
06326 if (havepattern)
06327 regfree(®exbuf);
06328
06329 return CLI_SUCCESS;
06330 #undef FORMAT
06331 #undef FORMAT2
06332 }
06333
06334 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
06335 {
06336 regex_t regexbuf;
06337 int havepattern = 0;
06338 int total_peers = 0;
06339 int online_peers = 0;
06340 int offline_peers = 0;
06341 int unmonitored_peers = 0;
06342 struct ao2_iterator i;
06343
06344 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
06345 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
06346
06347 struct iax2_peer *peer = NULL;
06348 char name[256];
06349 struct ast_str *encmethods = ast_str_alloca(256);
06350 int registeredonly=0;
06351 char *term = manager ? "\r\n" : "\n";
06352 char idtext[256] = "";
06353 switch (argc) {
06354 case 6:
06355 if (!strcasecmp(argv[3], "registered"))
06356 registeredonly = 1;
06357 else
06358 return RESULT_SHOWUSAGE;
06359 if (!strcasecmp(argv[4], "like")) {
06360 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06361 return RESULT_SHOWUSAGE;
06362 havepattern = 1;
06363 } else
06364 return RESULT_SHOWUSAGE;
06365 break;
06366 case 5:
06367 if (!strcasecmp(argv[3], "like")) {
06368 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06369 return RESULT_SHOWUSAGE;
06370 havepattern = 1;
06371 } else
06372 return RESULT_SHOWUSAGE;
06373 break;
06374 case 4:
06375 if (!strcasecmp(argv[3], "registered"))
06376 registeredonly = 1;
06377 else
06378 return RESULT_SHOWUSAGE;
06379 break;
06380 case 3:
06381 break;
06382 default:
06383 return RESULT_SHOWUSAGE;
06384 }
06385
06386
06387 if (!s)
06388 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
06389
06390 i = ao2_iterator_init(peers, 0);
06391 for (peer = ao2_iterator_next(&i); peer;
06392 peer_unref(peer), peer = ao2_iterator_next(&i)) {
06393 char nm[20];
06394 char status[20];
06395 int retstatus;
06396
06397 if (registeredonly && !peer->addr.sin_addr.s_addr)
06398 continue;
06399 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
06400 continue;
06401
06402 if (!ast_strlen_zero(peer->username))
06403 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06404 else
06405 ast_copy_string(name, peer->name, sizeof(name));
06406
06407 encmethods_to_str(peer->encmethods, encmethods);
06408 retstatus = peer_status(peer, status, sizeof(status));
06409 if (retstatus > 0)
06410 online_peers++;
06411 else if (!retstatus)
06412 offline_peers++;
06413 else
06414 unmonitored_peers++;
06415
06416 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06417
06418 if (s) {
06419 astman_append(s,
06420 "Event: PeerEntry\r\n%s"
06421 "Channeltype: IAX2\r\n"
06422 "ChanObjectType: peer\r\n"
06423 "ObjectName: %s\r\n"
06424 "IPaddress: %s\r\n"
06425 "IPport: %d\r\n"
06426 "Dynamic: %s\r\n"
06427 "Trunk: %s\r\n"
06428 "Encryption: %s\r\n"
06429 "Status: %s\r\n\r\n",
06430 idtext,
06431 name,
06432 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
06433 ntohs(peer->addr.sin_port),
06434 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
06435 ast_test_flag(peer, IAX_TRUNK) ? "yes" : "no",
06436 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06437 status);
06438 } else {
06439 ast_cli(fd, FORMAT, name,
06440 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06441 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06442 nm,
06443 ntohs(peer->addr.sin_port),
06444 ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
06445 peer->encmethods ? "(E)" : " ",
06446 status,
06447 term);
06448 }
06449 total_peers++;
06450 }
06451 ao2_iterator_destroy(&i);
06452
06453 if (!s)
06454 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
06455
06456 if (havepattern)
06457 regfree(®exbuf);
06458
06459 return RESULT_SUCCESS;
06460 #undef FORMAT
06461 #undef FORMAT2
06462 }
06463
06464 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06465 {
06466 struct iax2_thread *thread = NULL;
06467 time_t t;
06468 int threadcount = 0, dynamiccount = 0;
06469 char type;
06470
06471 switch (cmd) {
06472 case CLI_INIT:
06473 e->command = "iax2 show threads";
06474 e->usage =
06475 "Usage: iax2 show threads\n"
06476 " Lists status of IAX helper threads\n";
06477 return NULL;
06478 case CLI_GENERATE:
06479 return NULL;
06480 }
06481 if (a->argc != 3)
06482 return CLI_SHOWUSAGE;
06483
06484 ast_cli(a->fd, "IAX2 Thread Information\n");
06485 time(&t);
06486 ast_cli(a->fd, "Idle Threads:\n");
06487 AST_LIST_LOCK(&idle_list);
06488 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06489 #ifdef DEBUG_SCHED_MULTITHREAD
06490 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06491 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06492 #else
06493 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06494 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06495 #endif
06496 threadcount++;
06497 }
06498 AST_LIST_UNLOCK(&idle_list);
06499 ast_cli(a->fd, "Active Threads:\n");
06500 AST_LIST_LOCK(&active_list);
06501 AST_LIST_TRAVERSE(&active_list, thread, list) {
06502 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06503 type = 'D';
06504 else
06505 type = 'P';
06506 #ifdef DEBUG_SCHED_MULTITHREAD
06507 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06508 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06509 #else
06510 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06511 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06512 #endif
06513 threadcount++;
06514 }
06515 AST_LIST_UNLOCK(&active_list);
06516 ast_cli(a->fd, "Dynamic Threads:\n");
06517 AST_LIST_LOCK(&dynamic_list);
06518 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06519 #ifdef DEBUG_SCHED_MULTITHREAD
06520 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06521 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06522 #else
06523 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06524 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06525 #endif
06526 dynamiccount++;
06527 }
06528 AST_LIST_UNLOCK(&dynamic_list);
06529 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06530 return CLI_SUCCESS;
06531 }
06532
06533 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06534 {
06535 struct iax2_peer *p;
06536
06537 switch (cmd) {
06538 case CLI_INIT:
06539 e->command = "iax2 unregister";
06540 e->usage =
06541 "Usage: iax2 unregister <peername>\n"
06542 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06543 return NULL;
06544 case CLI_GENERATE:
06545 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06546 }
06547
06548 if (a->argc != 3)
06549 return CLI_SHOWUSAGE;
06550
06551 p = find_peer(a->argv[2], 1);
06552 if (p) {
06553 if (p->expire > 0) {
06554 struct iax2_peer tmp_peer = {
06555 .name = a->argv[2],
06556 };
06557 struct iax2_peer *peer;
06558
06559 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06560 if (peer) {
06561 expire_registry(peer_ref(peer));
06562 peer_unref(peer);
06563 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06564 } else {
06565 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06566 }
06567 } else {
06568 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06569 }
06570 } else {
06571 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06572 }
06573 return CLI_SUCCESS;
06574 }
06575
06576 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06577 {
06578 int which = 0;
06579 struct iax2_peer *p = NULL;
06580 char *res = NULL;
06581 int wordlen = strlen(word);
06582
06583
06584 if (pos == 2) {
06585 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06586 while ((p = ao2_iterator_next(&i))) {
06587 if (!strncasecmp(p->name, word, wordlen) &&
06588 ++which > state && p->expire > 0) {
06589 res = ast_strdup(p->name);
06590 peer_unref(p);
06591 break;
06592 }
06593 peer_unref(p);
06594 }
06595 ao2_iterator_destroy(&i);
06596 }
06597
06598 return res;
06599 }
06600
06601 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06602 {
06603 switch (cmd) {
06604 case CLI_INIT:
06605 e->command = "iax2 show peers";
06606 e->usage =
06607 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06608 " Lists all known IAX2 peers.\n"
06609 " Optional 'registered' argument lists only peers with known addresses.\n"
06610 " Optional regular expression pattern is used to filter the peer list.\n";
06611 return NULL;
06612 case CLI_GENERATE:
06613 return NULL;
06614 }
06615
06616 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
06617 case RESULT_SHOWUSAGE:
06618 return CLI_SHOWUSAGE;
06619 case RESULT_FAILURE:
06620 return CLI_FAILURE;
06621 default:
06622 return CLI_SUCCESS;
06623 }
06624 }
06625
06626 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06627 {
06628 ast_cli_netstats(s, -1, 0);
06629 astman_append(s, "\r\n");
06630 return RESULT_SUCCESS;
06631 }
06632
06633 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06634 {
06635 struct iax_firmware *cur = NULL;
06636
06637 switch (cmd) {
06638 case CLI_INIT:
06639 e->command = "iax2 show firmware";
06640 e->usage =
06641 "Usage: iax2 show firmware\n"
06642 " Lists all known IAX firmware images.\n";
06643 return NULL;
06644 case CLI_GENERATE:
06645 return NULL;
06646 }
06647
06648 if (a->argc != 3 && a->argc != 4)
06649 return CLI_SHOWUSAGE;
06650
06651 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06652 AST_LIST_LOCK(&firmwares);
06653 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06654 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06655 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06656 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06657 }
06658 }
06659 AST_LIST_UNLOCK(&firmwares);
06660
06661 return CLI_SUCCESS;
06662 }
06663
06664
06665 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06666 {
06667 char *a[] = { "iax2", "show", "users" };
06668 const char *id = astman_get_header(m,"ActionID");
06669 char idtext[256] = "";
06670
06671 if (!ast_strlen_zero(id))
06672 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06673 astman_send_ack(s, m, "Peer status list will follow");
06674 return __iax2_show_peers(1, -1, s, 3, a );
06675 }
06676
06677
06678 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06679 {
06680 struct iax2_peer *peer = NULL;
06681 int peer_count = 0;
06682 char nm[20];
06683 char status[20];
06684 const char *id = astman_get_header(m,"ActionID");
06685 char idtext[256] = "";
06686 struct ast_str *encmethods = ast_str_alloca(256);
06687 struct ao2_iterator i;
06688
06689 if (!ast_strlen_zero(id))
06690 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06691
06692 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06693
06694
06695 i = ao2_iterator_init(peers, 0);
06696 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06697 encmethods_to_str(peer->encmethods, encmethods);
06698 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06699 if (!ast_strlen_zero(peer->username)) {
06700 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06701 } else {
06702 astman_append(s, "ObjectName: %s\r\n", peer->name);
06703 }
06704 astman_append(s, "ChanObjectType: peer\r\n");
06705 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
06706 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06707 astman_append(s, "Mask: %s\r\n", nm);
06708 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
06709 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
06710 astman_append(s, "Trunk: %s\r\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
06711 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
06712 peer_status(peer, status, sizeof(status));
06713 astman_append(s, "Status: %s\r\n\r\n", status);
06714 peer_count++;
06715 }
06716 ao2_iterator_destroy(&i);
06717
06718 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
06719 return RESULT_SUCCESS;
06720 }
06721
06722
06723 static char *regstate2str(int regstate)
06724 {
06725 switch(regstate) {
06726 case REG_STATE_UNREGISTERED:
06727 return "Unregistered";
06728 case REG_STATE_REGSENT:
06729 return "Request Sent";
06730 case REG_STATE_AUTHSENT:
06731 return "Auth. Sent";
06732 case REG_STATE_REGISTERED:
06733 return "Registered";
06734 case REG_STATE_REJECTED:
06735 return "Rejected";
06736 case REG_STATE_TIMEOUT:
06737 return "Timeout";
06738 case REG_STATE_NOAUTH:
06739 return "No Authentication";
06740 default:
06741 return "Unknown";
06742 }
06743 }
06744
06745 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06746 {
06747 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
06748 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
06749 struct iax2_registry *reg = NULL;
06750 char host[80];
06751 char perceived[80];
06752 int counter = 0;
06753
06754 switch (cmd) {
06755 case CLI_INIT:
06756 e->command = "iax2 show registry";
06757 e->usage =
06758 "Usage: iax2 show registry\n"
06759 " Lists all registration requests and status.\n";
06760 return NULL;
06761 case CLI_GENERATE:
06762 return NULL;
06763 }
06764 if (a->argc != 3)
06765 return CLI_SHOWUSAGE;
06766 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
06767 AST_LIST_LOCK(®istrations);
06768 AST_LIST_TRAVERSE(®istrations, reg, entry) {
06769 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06770 if (reg->us.sin_addr.s_addr)
06771 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06772 else
06773 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06774 ast_cli(a->fd, FORMAT, host,
06775 (reg->dnsmgr) ? "Y" : "N",
06776 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
06777 counter++;
06778 }
06779 AST_LIST_UNLOCK(®istrations);
06780 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
06781 return CLI_SUCCESS;
06782 #undef FORMAT
06783 #undef FORMAT2
06784 }
06785
06786 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
06787 {
06788 const char *id = astman_get_header(m, "ActionID");
06789 struct iax2_registry *reg = NULL;
06790 char idtext[256] = "";
06791 char host[80] = "";
06792 char perceived[80] = "";
06793 int total = 0;
06794
06795 if (!ast_strlen_zero(id))
06796 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06797
06798 astman_send_listack(s, m, "Registrations will follow", "start");
06799
06800 AST_LIST_LOCK(®istrations);
06801 AST_LIST_TRAVERSE(®istrations, reg, entry) {
06802 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06803
06804 if (reg->us.sin_addr.s_addr) {
06805 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06806 } else {
06807 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06808 }
06809
06810 astman_append(s,
06811 "Event: RegistryEntry\r\n"
06812 "Host: %s\r\n"
06813 "DNSmanager: %s\r\n"
06814 "Username: %s\r\n"
06815 "Perceived: %s\r\n"
06816 "Refresh: %d\r\n"
06817 "State: %s\r\n"
06818 "\r\n", host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
06819 reg->refresh, regstate2str(reg->regstate));
06820
06821 total++;
06822 }
06823 AST_LIST_UNLOCK(®istrations);
06824
06825 astman_append(s,
06826 "Event: RegistrationsComplete\r\n"
06827 "EventList: Complete\r\n"
06828 "ListItems: %d\r\n"
06829 "%s"
06830 "\r\n", total, idtext);
06831
06832 return 0;
06833 }
06834
06835 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06836 {
06837 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
06838 #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"
06839 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
06840 int x;
06841 int numchans = 0;
06842 char first_message[10] = { 0, };
06843 char last_message[10] = { 0, };
06844
06845 switch (cmd) {
06846 case CLI_INIT:
06847 e->command = "iax2 show channels";
06848 e->usage =
06849 "Usage: iax2 show channels\n"
06850 " Lists all currently active IAX channels.\n";
06851 return NULL;
06852 case CLI_GENERATE:
06853 return NULL;
06854 }
06855
06856 if (a->argc != 3)
06857 return CLI_SHOWUSAGE;
06858 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
06859 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06860 ast_mutex_lock(&iaxsl[x]);
06861 if (iaxs[x]) {
06862 int lag, jitter, localdelay;
06863 jb_info jbinfo;
06864 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06865 jb_getinfo(iaxs[x]->jb, &jbinfo);
06866 jitter = jbinfo.jitter;
06867 localdelay = jbinfo.current - jbinfo.min;
06868 } else {
06869 jitter = -1;
06870 localdelay = 0;
06871 }
06872
06873 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06874 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06875 lag = iaxs[x]->remote_rr.delay;
06876 ast_cli(a->fd, FORMAT,
06877 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06878 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
06879 S_OR(iaxs[x]->username, "(None)"),
06880 iaxs[x]->callno, iaxs[x]->peercallno,
06881 iaxs[x]->oseqno, iaxs[x]->iseqno,
06882 lag,
06883 jitter,
06884 localdelay,
06885 ast_getformatname(iaxs[x]->voiceformat),
06886 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06887 first_message,
06888 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06889 last_message);
06890 numchans++;
06891 }
06892 ast_mutex_unlock(&iaxsl[x]);
06893 }
06894 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06895 return CLI_SUCCESS;
06896 #undef FORMAT
06897 #undef FORMAT2
06898 #undef FORMATB
06899 }
06900
06901 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
06902 {
06903 int x;
06904 int numchans = 0;
06905 char first_message[10] = { 0, };
06906 char last_message[10] = { 0, };
06907 #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"
06908 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
06909 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06910 ast_mutex_lock(&iaxsl[x]);
06911 if (iaxs[x]) {
06912 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06913 jb_info jbinfo;
06914 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06915 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06916
06917 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06918 jb_getinfo(iaxs[x]->jb, &jbinfo);
06919 localjitter = jbinfo.jitter;
06920 localdelay = jbinfo.current - jbinfo.min;
06921 locallost = jbinfo.frames_lost;
06922 locallosspct = jbinfo.losspct/1000;
06923 localdropped = jbinfo.frames_dropped;
06924 localooo = jbinfo.frames_ooo;
06925 } else {
06926 localjitter = -1;
06927 localdelay = 0;
06928 locallost = -1;
06929 locallosspct = -1;
06930 localdropped = 0;
06931 localooo = -1;
06932 }
06933 if (s)
06934 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06935 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06936 iaxs[x]->pingtime,
06937 localjitter,
06938 localdelay,
06939 locallost,
06940 locallosspct,
06941 localdropped,
06942 localooo,
06943 iaxs[x]->frames_received/1000,
06944 iaxs[x]->remote_rr.jitter,
06945 iaxs[x]->remote_rr.delay,
06946 iaxs[x]->remote_rr.losscnt,
06947 iaxs[x]->remote_rr.losspct,
06948 iaxs[x]->remote_rr.dropped,
06949 iaxs[x]->remote_rr.ooo,
06950 iaxs[x]->remote_rr.packets/1000,
06951 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06952 first_message,
06953 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06954 last_message);
06955 else
06956 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06957 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06958 iaxs[x]->pingtime,
06959 localjitter,
06960 localdelay,
06961 locallost,
06962 locallosspct,
06963 localdropped,
06964 localooo,
06965 iaxs[x]->frames_received/1000,
06966 iaxs[x]->remote_rr.jitter,
06967 iaxs[x]->remote_rr.delay,
06968 iaxs[x]->remote_rr.losscnt,
06969 iaxs[x]->remote_rr.losspct,
06970 iaxs[x]->remote_rr.dropped,
06971 iaxs[x]->remote_rr.ooo,
06972 iaxs[x]->remote_rr.packets/1000,
06973 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06974 first_message,
06975 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06976 last_message);
06977 numchans++;
06978 }
06979 ast_mutex_unlock(&iaxsl[x]);
06980 }
06981
06982 return numchans;
06983 }
06984
06985 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06986 {
06987 int numchans = 0;
06988
06989 switch (cmd) {
06990 case CLI_INIT:
06991 e->command = "iax2 show netstats";
06992 e->usage =
06993 "Usage: iax2 show netstats\n"
06994 " Lists network status for all currently active IAX channels.\n";
06995 return NULL;
06996 case CLI_GENERATE:
06997 return NULL;
06998 }
06999 if (a->argc != 3)
07000 return CLI_SHOWUSAGE;
07001 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07002 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07003 numchans = ast_cli_netstats(NULL, a->fd, 1);
07004 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07005 return CLI_SUCCESS;
07006 }
07007
07008 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07009 {
07010 switch (cmd) {
07011 case CLI_INIT:
07012 e->command = "iax2 set debug {on|off|peer}";
07013 e->usage =
07014 "Usage: iax2 set debug {on|off|peer peername}\n"
07015 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07016 return NULL;
07017 case CLI_GENERATE:
07018 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07019 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07020 return NULL;
07021 }
07022
07023 if (a->argc < e->args || a->argc > e->args + 1)
07024 return CLI_SHOWUSAGE;
07025
07026 if (!strcasecmp(a->argv[3], "peer")) {
07027 struct iax2_peer *peer;
07028
07029 if (a->argc != e->args + 1)
07030 return CLI_SHOWUSAGE;
07031
07032 peer = find_peer(a->argv[4], 1);
07033
07034 if (!peer) {
07035 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07036 return CLI_FAILURE;
07037 }
07038
07039 debugaddr.sin_addr = peer->addr.sin_addr;
07040 debugaddr.sin_port = peer->addr.sin_port;
07041
07042 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07043 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07044
07045 ao2_ref(peer, -1);
07046 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07047 iaxdebug = 1;
07048 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07049 } else {
07050 iaxdebug = 0;
07051 memset(&debugaddr, 0, sizeof(debugaddr));
07052 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07053 }
07054 return CLI_SUCCESS;
07055 }
07056
07057 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07058 {
07059 switch (cmd) {
07060 case CLI_INIT:
07061 e->command = "iax2 set debug trunk {on|off}";
07062 e->usage =
07063 "Usage: iax2 set debug trunk {on|off}\n"
07064 " Enables/Disables debugging of IAX trunking\n";
07065 return NULL;
07066 case CLI_GENERATE:
07067 return NULL;
07068 }
07069
07070 if (a->argc != e->args)
07071 return CLI_SHOWUSAGE;
07072
07073 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07074 iaxtrunkdebug = 1;
07075 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07076 } else {
07077 iaxtrunkdebug = 0;
07078 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07079 }
07080 return CLI_SUCCESS;
07081 }
07082
07083 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07084 {
07085 switch (cmd) {
07086 case CLI_INIT:
07087 e->command = "iax2 set debug jb {on|off}";
07088 e->usage =
07089 "Usage: iax2 set debug jb {on|off}\n"
07090 " Enables/Disables jitterbuffer debugging information\n";
07091 return NULL;
07092 case CLI_GENERATE:
07093 return NULL;
07094 }
07095
07096 if (a->argc != e->args)
07097 return CLI_SHOWUSAGE;
07098
07099 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07100 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07101 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07102 } else {
07103 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07104 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07105 }
07106 return CLI_SUCCESS;
07107 }
07108
07109 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07110 {
07111 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07112 int res = -1;
07113 ast_mutex_lock(&iaxsl[callno]);
07114 if (iaxs[callno]) {
07115
07116 if (!iaxs[callno]->error) {
07117 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
07118 res = 0;
07119
07120 else if (f->frametype == AST_FRAME_NULL)
07121 res = 0;
07122 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
07123 res = 0;
07124 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07125 res = 0;
07126 else
07127
07128 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07129 } else {
07130 ast_debug(1, "Write error: %s\n", strerror(errno));
07131 }
07132 }
07133
07134 ast_mutex_unlock(&iaxsl[callno]);
07135 return res;
07136 }
07137
07138 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07139 int now, int transfer, int final)
07140 {
07141 struct ast_frame f = { 0, };
07142 int res = 0;
07143
07144 f.frametype = type;
07145 f.subclass = command;
07146 f.datalen = datalen;
07147 f.src = __FUNCTION__;
07148 f.data.ptr = (void *) data;
07149
07150 if ((res = queue_signalling(i, &f)) <= 0) {
07151 return res;
07152 }
07153
07154 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07155 }
07156
07157 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07158 {
07159 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07160 }
07161
07162 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07163 {
07164 int res;
07165 ast_mutex_lock(&iaxsl[callno]);
07166 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07167 ast_mutex_unlock(&iaxsl[callno]);
07168 return res;
07169 }
07170
07171
07172
07173
07174
07175
07176 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)
07177 {
07178 int call_num = i->callno;
07179
07180 iax2_predestroy(i->callno);
07181 if (!iaxs[call_num])
07182 return -1;
07183 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07184 }
07185
07186 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)
07187 {
07188 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07189 }
07190
07191 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07192 {
07193 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07194 }
07195
07196 static int apply_context(struct iax2_context *con, const char *context)
07197 {
07198 while(con) {
07199 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07200 return -1;
07201 con = con->next;
07202 }
07203 return 0;
07204 }
07205
07206
07207 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07208 {
07209
07210 int res = -1;
07211 int version = 2;
07212 struct iax2_user *user = NULL, *best = NULL;
07213 int bestscore = 0;
07214 int gotcapability = 0;
07215 struct ast_variable *v = NULL, *tmpvar = NULL;
07216 struct ao2_iterator i;
07217
07218 if (!iaxs[callno])
07219 return res;
07220 if (ies->called_number)
07221 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07222 if (ies->calling_number) {
07223 if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) {
07224 ast_shrink_phone_number(ies->calling_number);
07225 }
07226 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07227 }
07228 if (ies->calling_name)
07229 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07230 if (ies->calling_ani)
07231 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07232 if (ies->dnid)
07233 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07234 if (ies->rdnis)
07235 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07236 if (ies->called_context)
07237 ast_string_field_set(iaxs[callno], context, ies->called_context);
07238 if (ies->language)
07239 ast_string_field_set(iaxs[callno], language, ies->language);
07240 if (ies->username)
07241 ast_string_field_set(iaxs[callno], username, ies->username);
07242 if (ies->calling_ton > -1)
07243 iaxs[callno]->calling_ton = ies->calling_ton;
07244 if (ies->calling_tns > -1)
07245 iaxs[callno]->calling_tns = ies->calling_tns;
07246 if (ies->calling_pres > -1)
07247 iaxs[callno]->calling_pres = ies->calling_pres;
07248 if (ies->format)
07249 iaxs[callno]->peerformat = ies->format;
07250 if (ies->adsicpe)
07251 iaxs[callno]->peeradsicpe = ies->adsicpe;
07252 if (ies->capability) {
07253 gotcapability = 1;
07254 iaxs[callno]->peercapability = ies->capability;
07255 }
07256 if (ies->version)
07257 version = ies->version;
07258
07259
07260 if(ies->codec_prefs) {
07261 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07262 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07263 }
07264
07265 if (!gotcapability)
07266 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07267 if (version > IAX_PROTO_VERSION) {
07268 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07269 ast_inet_ntoa(sin->sin_addr), version);
07270 return res;
07271 }
07272
07273 i = ao2_iterator_init(users, 0);
07274 while ((user = ao2_iterator_next(&i))) {
07275 if ((ast_strlen_zero(iaxs[callno]->username) ||
07276 !strcmp(iaxs[callno]->username, user->name))
07277 && ast_apply_ha(user->ha, sin)
07278 && (ast_strlen_zero(iaxs[callno]->context) ||
07279 apply_context(user->contexts, iaxs[callno]->context))) {
07280 if (!ast_strlen_zero(iaxs[callno]->username)) {
07281
07282 if (best)
07283 user_unref(best);
07284 best = user;
07285 break;
07286 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07287
07288 if (user->ha) {
07289
07290 if (bestscore < 4) {
07291 bestscore = 4;
07292 if (best)
07293 user_unref(best);
07294 best = user;
07295 continue;
07296 }
07297 } else {
07298
07299 if (bestscore < 3) {
07300 bestscore = 3;
07301 if (best)
07302 user_unref(best);
07303 best = user;
07304 continue;
07305 }
07306 }
07307 } else {
07308 if (user->ha) {
07309
07310 if (bestscore < 2) {
07311 bestscore = 2;
07312 if (best)
07313 user_unref(best);
07314 best = user;
07315 continue;
07316 }
07317 } else {
07318
07319 if (bestscore < 1) {
07320 bestscore = 1;
07321 if (best)
07322 user_unref(best);
07323 best = user;
07324 continue;
07325 }
07326 }
07327 }
07328 }
07329 user_unref(user);
07330 }
07331 ao2_iterator_destroy(&i);
07332 user = best;
07333 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07334 user = realtime_user(iaxs[callno]->username, sin);
07335 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07336 !apply_context(user->contexts, iaxs[callno]->context)) {
07337 user = user_unref(user);
07338 }
07339 }
07340 if (user) {
07341
07342
07343 for (v = user->vars ; v ; v = v->next) {
07344 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07345 tmpvar->next = iaxs[callno]->vars;
07346 iaxs[callno]->vars = tmpvar;
07347 }
07348 }
07349
07350 if (user->maxauthreq > 0)
07351 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
07352 iaxs[callno]->prefs = user->prefs;
07353 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07354 iaxs[callno]->encmethods = user->encmethods;
07355
07356 if (ast_strlen_zero(iaxs[callno]->username))
07357 ast_string_field_set(iaxs[callno], username, user->name);
07358
07359 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
07360 iaxs[callno]->capability = user->capability;
07361
07362 if (ast_strlen_zero(iaxs[callno]->context)) {
07363 if (user->contexts)
07364 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07365 else
07366 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07367 }
07368
07369 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07370
07371 iaxs[callno]->authmethods = user->authmethods;
07372 iaxs[callno]->adsi = user->adsi;
07373
07374 if (ast_test_flag(user, IAX_HASCALLERID)) {
07375 iaxs[callno]->calling_tns = 0;
07376 iaxs[callno]->calling_ton = 0;
07377 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07378 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07379 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07380 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07381 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07382 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07383 }
07384 if (!ast_strlen_zero(user->accountcode))
07385 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07386 if (!ast_strlen_zero(user->mohinterpret))
07387 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07388 if (!ast_strlen_zero(user->mohsuggest))
07389 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07390 if (!ast_strlen_zero(user->parkinglot))
07391 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07392 if (user->amaflags)
07393 iaxs[callno]->amaflags = user->amaflags;
07394 if (!ast_strlen_zero(user->language))
07395 ast_string_field_set(iaxs[callno], language, user->language);
07396 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07397
07398 if (!ast_strlen_zero(user->dbsecret)) {
07399 char *family, *key=NULL;
07400 char buf[80];
07401 family = ast_strdupa(user->dbsecret);
07402 key = strchr(family, '/');
07403 if (key) {
07404 *key = '\0';
07405 key++;
07406 }
07407 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07408 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07409 else
07410 ast_string_field_set(iaxs[callno], secret, buf);
07411 } else
07412 ast_string_field_set(iaxs[callno], secret, user->secret);
07413 res = 0;
07414 user = user_unref(user);
07415 } else {
07416
07417
07418
07419
07420 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07421 ast_string_field_set(iaxs[callno], secret, "badsecret");
07422 iaxs[callno]->authrej = 1;
07423 if (!ast_strlen_zero(iaxs[callno]->username)) {
07424
07425 res = 0;
07426 }
07427 }
07428 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07429 return res;
07430 }
07431
07432 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07433 {
07434 struct ast_iax2_full_hdr fh;
07435 fh.scallno = htons(src | IAX_FLAG_FULL);
07436 fh.dcallno = htons(dst);
07437 fh.ts = 0;
07438 fh.oseqno = 0;
07439 fh.iseqno = 0;
07440 fh.type = AST_FRAME_IAX;
07441 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07442 iax_outputframe(NULL, &fh, 0, sin, 0);
07443 #if 0
07444 if (option_debug)
07445 #endif
07446 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07447 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07448 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07449 }
07450
07451 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07452 {
07453
07454 p->encmethods &= enc;
07455 if (p->encmethods) {
07456 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07457 p->keyrotateid = -2;
07458 }
07459 if (p->encmethods & IAX_ENCRYPT_AES128)
07460 p->encmethods = IAX_ENCRYPT_AES128;
07461 else
07462 p->encmethods = 0;
07463 }
07464 }
07465
07466
07467
07468
07469
07470
07471
07472 static int authenticate_request(int call_num)
07473 {
07474 struct iax_ie_data ied;
07475 int res = -1, authreq_restrict = 0;
07476 char challenge[10];
07477 struct chan_iax2_pvt *p = iaxs[call_num];
07478
07479 memset(&ied, 0, sizeof(ied));
07480
07481
07482 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07483 struct iax2_user *user, tmp_user = {
07484 .name = p->username,
07485 };
07486
07487 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07488 if (user) {
07489 if (user->curauthreq == user->maxauthreq)
07490 authreq_restrict = 1;
07491 else
07492 user->curauthreq++;
07493 user = user_unref(user);
07494 }
07495 }
07496
07497
07498 if (authreq_restrict) {
07499 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07500 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07501 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07502 return 0;
07503 }
07504
07505 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07506 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07507 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07508 ast_string_field_set(p, challenge, challenge);
07509
07510 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07511 }
07512 if (p->encmethods)
07513 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07514
07515 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07516
07517 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07518
07519 if (p->encmethods)
07520 ast_set_flag(p, IAX_ENCRYPTED);
07521
07522 return res;
07523 }
07524
07525 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07526 {
07527 char requeststr[256];
07528 char md5secret[256] = "";
07529 char secret[256] = "";
07530 char rsasecret[256] = "";
07531 int res = -1;
07532 int x;
07533 struct iax2_user *user, tmp_user = {
07534 .name = p->username,
07535 };
07536
07537 if (p->authrej) {
07538 return res;
07539 }
07540 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07541 if (user) {
07542 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07543 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07544 ast_clear_flag(p, IAX_MAXAUTHREQ);
07545 }
07546 ast_string_field_set(p, host, user->name);
07547 user = user_unref(user);
07548 }
07549 if (ast_test_flag(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07550 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07551 return res;
07552 }
07553 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07554 return res;
07555 if (ies->password)
07556 ast_copy_string(secret, ies->password, sizeof(secret));
07557 if (ies->md5_result)
07558 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07559 if (ies->rsa_result)
07560 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07561 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07562 struct ast_key *key;
07563 char *keyn;
07564 char tmpkey[256];
07565 char *stringp=NULL;
07566 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07567 stringp=tmpkey;
07568 keyn = strsep(&stringp, ":");
07569 while(keyn) {
07570 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07571 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07572 res = 0;
07573 break;
07574 } else if (!key)
07575 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07576 keyn = strsep(&stringp, ":");
07577 }
07578 } else if (p->authmethods & IAX_AUTH_MD5) {
07579 struct MD5Context md5;
07580 unsigned char digest[16];
07581 char *tmppw, *stringp;
07582
07583 tmppw = ast_strdupa(p->secret);
07584 stringp = tmppw;
07585 while((tmppw = strsep(&stringp, ";"))) {
07586 MD5Init(&md5);
07587 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07588 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07589 MD5Final(digest, &md5);
07590
07591 for (x=0;x<16;x++)
07592 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07593 if (!strcasecmp(requeststr, md5secret)) {
07594 res = 0;
07595 break;
07596 }
07597 }
07598 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07599 if (!strcmp(secret, p->secret))
07600 res = 0;
07601 }
07602 return res;
07603 }
07604
07605
07606 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07607 {
07608 char requeststr[256] = "";
07609 char peer[256] = "";
07610 char md5secret[256] = "";
07611 char rsasecret[256] = "";
07612 char secret[256] = "";
07613 struct iax2_peer *p = NULL;
07614 struct ast_key *key;
07615 char *keyn;
07616 int x;
07617 int expire = 0;
07618 int res = -1;
07619
07620 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07621
07622 if (ies->username)
07623 ast_copy_string(peer, ies->username, sizeof(peer));
07624 if (ies->password)
07625 ast_copy_string(secret, ies->password, sizeof(secret));
07626 if (ies->md5_result)
07627 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07628 if (ies->rsa_result)
07629 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07630 if (ies->refresh)
07631 expire = ies->refresh;
07632
07633 if (ast_strlen_zero(peer)) {
07634 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07635 return -1;
07636 }
07637
07638
07639 ast_mutex_unlock(&iaxsl[callno]);
07640 p = find_peer(peer, 1);
07641 ast_mutex_lock(&iaxsl[callno]);
07642 if (!p || !iaxs[callno]) {
07643 if (iaxs[callno]) {
07644 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07645
07646 ast_string_field_set(iaxs[callno], secret, "badsecret");
07647
07648
07649
07650
07651
07652
07653
07654
07655
07656 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07657 !(!ast_strlen_zero(secret) && plaintext)) {
07658
07659 res = 0;
07660 }
07661 }
07662 if (authdebug && !p)
07663 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07664 goto return_unref;
07665 }
07666
07667 if (!ast_test_flag(p, IAX_DYNAMIC)) {
07668 if (authdebug)
07669 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07670 goto return_unref;
07671 }
07672
07673 if (!ast_apply_ha(p->ha, sin)) {
07674 if (authdebug)
07675 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07676 goto return_unref;
07677 }
07678 ast_string_field_set(iaxs[callno], secret, p->secret);
07679 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07680
07681 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07682 if (!ast_strlen_zero(p->inkeys)) {
07683 char tmpkeys[256];
07684 char *stringp=NULL;
07685 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07686 stringp=tmpkeys;
07687 keyn = strsep(&stringp, ":");
07688 while(keyn) {
07689 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07690 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07691 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07692 break;
07693 } else if (!key)
07694 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
07695 keyn = strsep(&stringp, ":");
07696 }
07697 if (!keyn) {
07698 if (authdebug)
07699 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
07700 goto return_unref;
07701 }
07702 } else {
07703 if (authdebug)
07704 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
07705 goto return_unref;
07706 }
07707 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07708 struct MD5Context md5;
07709 unsigned char digest[16];
07710 char *tmppw, *stringp;
07711
07712 tmppw = ast_strdupa(p->secret);
07713 stringp = tmppw;
07714 while((tmppw = strsep(&stringp, ";"))) {
07715 MD5Init(&md5);
07716 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
07717 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07718 MD5Final(digest, &md5);
07719 for (x=0;x<16;x++)
07720 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07721 if (!strcasecmp(requeststr, md5secret))
07722 break;
07723 }
07724 if (tmppw) {
07725 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07726 } else {
07727 if (authdebug)
07728 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
07729 goto return_unref;
07730 }
07731 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
07732
07733 if (strcmp(secret, p->secret)) {
07734 if (authdebug)
07735 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07736 goto return_unref;
07737 } else
07738 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07739 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
07740
07741 goto return_unref;
07742 }
07743 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
07744
07745
07746 res = 0;
07747
07748 return_unref:
07749 if (iaxs[callno]) {
07750 ast_string_field_set(iaxs[callno], peer, peer);
07751
07752
07753 if (expire && (expire < iaxs[callno]->expiry)) {
07754 iaxs[callno]->expiry = expire;
07755 }
07756 }
07757
07758 if (p) {
07759 peer_unref(p);
07760 }
07761 return res;
07762 }
07763
07764 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)
07765 {
07766 int res = -1;
07767 int x;
07768 if (!ast_strlen_zero(keyn)) {
07769 if (!(authmethods & IAX_AUTH_RSA)) {
07770 if (ast_strlen_zero(secret))
07771 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));
07772 } else if (ast_strlen_zero(challenge)) {
07773 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
07774 } else {
07775 char sig[256];
07776 struct ast_key *key;
07777 key = ast_key_get(keyn, AST_KEY_PRIVATE);
07778 if (!key) {
07779 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
07780 } else {
07781 if (ast_sign(key, (char*)challenge, sig)) {
07782 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
07783 res = -1;
07784 } else {
07785 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
07786 res = 0;
07787 }
07788 }
07789 }
07790 }
07791
07792 if (res && !ast_strlen_zero(secret)) {
07793 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
07794 struct MD5Context md5;
07795 unsigned char digest[16];
07796 char digres[128];
07797 MD5Init(&md5);
07798 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
07799 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
07800 MD5Final(digest, &md5);
07801
07802 for (x=0;x<16;x++)
07803 sprintf(digres + (x << 1), "%2.2x", digest[x]);
07804 if (pvt) {
07805 build_encryption_keys(digest, pvt);
07806 }
07807 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
07808 res = 0;
07809 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
07810 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
07811 res = 0;
07812 } else
07813 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
07814 }
07815 return res;
07816 }
07817
07818
07819
07820
07821
07822 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
07823 {
07824 struct iax2_peer *peer = NULL;
07825
07826 int res = -1;
07827 int authmethods = 0;
07828 struct iax_ie_data ied;
07829 uint16_t callno = p->callno;
07830
07831 memset(&ied, 0, sizeof(ied));
07832
07833 if (ies->username)
07834 ast_string_field_set(p, username, ies->username);
07835 if (ies->challenge)
07836 ast_string_field_set(p, challenge, ies->challenge);
07837 if (ies->authmethods)
07838 authmethods = ies->authmethods;
07839 if (authmethods & IAX_AUTH_MD5)
07840 merge_encryption(p, ies->encmethods);
07841 else
07842 p->encmethods = 0;
07843
07844
07845 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
07846
07847 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
07848 } else {
07849 struct ao2_iterator i = ao2_iterator_init(peers, 0);
07850 while ((peer = ao2_iterator_next(&i))) {
07851 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
07852
07853 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
07854
07855 && (!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)))
07856
07857 ) {
07858 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
07859 if (!res) {
07860 peer_unref(peer);
07861 break;
07862 }
07863 }
07864 peer_unref(peer);
07865 }
07866 ao2_iterator_destroy(&i);
07867 if (!peer) {
07868
07869
07870 const char *peer_name = ast_strdupa(p->peer);
07871 ast_mutex_unlock(&iaxsl[callno]);
07872 if ((peer = realtime_peer(peer_name, NULL))) {
07873 ast_mutex_lock(&iaxsl[callno]);
07874 if (!(p = iaxs[callno])) {
07875 peer_unref(peer);
07876 return -1;
07877 }
07878 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
07879 peer_unref(peer);
07880 }
07881 if (!peer) {
07882 ast_mutex_lock(&iaxsl[callno]);
07883 if (!(p = iaxs[callno]))
07884 return -1;
07885 }
07886 }
07887 }
07888
07889 if (ies->encmethods) {
07890 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
07891 } else if (ast_test_flag(iaxs[callno], IAX_FORCE_ENCRYPT)) {
07892 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
07893 return -1;
07894 }
07895 if (!res) {
07896 struct ast_datastore *variablestore;
07897 struct ast_variable *var, *prev = NULL;
07898 AST_LIST_HEAD(, ast_var_t) *varlist;
07899 varlist = ast_calloc(1, sizeof(*varlist));
07900 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
07901 if (variablestore && varlist && p->owner) {
07902 variablestore->data = varlist;
07903 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
07904 AST_LIST_HEAD_INIT(varlist);
07905 for (var = ies->vars; var; var = var->next) {
07906 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
07907 if (prev)
07908 ast_free(prev);
07909 prev = var;
07910 if (!newvar) {
07911
07912 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07913 } else {
07914 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
07915 }
07916 }
07917 if (prev)
07918 ast_free(prev);
07919 ies->vars = NULL;
07920 ast_channel_datastore_add(p->owner, variablestore);
07921 } else {
07922 if (p->owner)
07923 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07924 if (variablestore)
07925 ast_datastore_free(variablestore);
07926 if (varlist)
07927 ast_free(varlist);
07928 }
07929 }
07930
07931 if (!res)
07932 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
07933 return res;
07934 }
07935
07936 static int iax2_do_register(struct iax2_registry *reg);
07937
07938 static void __iax2_do_register_s(const void *data)
07939 {
07940 struct iax2_registry *reg = (struct iax2_registry *)data;
07941 reg->expire = -1;
07942 iax2_do_register(reg);
07943 }
07944
07945 static int iax2_do_register_s(const void *data)
07946 {
07947 #ifdef SCHED_MULTITHREADED
07948 if (schedule_action(__iax2_do_register_s, data))
07949 #endif
07950 __iax2_do_register_s(data);
07951 return 0;
07952 }
07953
07954 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07955 {
07956 int newcall = 0;
07957 char newip[256];
07958 struct iax_ie_data ied;
07959 struct sockaddr_in new;
07960
07961
07962 memset(&ied, 0, sizeof(ied));
07963 if (ies->apparent_addr)
07964 memmove(&new, ies->apparent_addr, sizeof(new));
07965 if (ies->callno)
07966 newcall = ies->callno;
07967 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
07968 ast_log(LOG_WARNING, "Invalid transfer request\n");
07969 return -1;
07970 }
07971 pvt->transfercallno = newcall;
07972 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
07973 inet_aton(newip, &pvt->transfer.sin_addr);
07974 pvt->transfer.sin_family = AF_INET;
07975 pvt->transferid = ies->transferid;
07976
07977
07978 if (pvt->transferring == TRANSFER_NONE) {
07979 store_by_transfercallno(pvt);
07980 }
07981 pvt->transferring = TRANSFER_BEGIN;
07982
07983 if (ies->transferid)
07984 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
07985 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
07986 return 0;
07987 }
07988
07989 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07990 {
07991 char exten[256] = "";
07992 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
07993 struct iax2_dpcache *dp = NULL;
07994
07995 if (ies->called_number)
07996 ast_copy_string(exten, ies->called_number, sizeof(exten));
07997
07998 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
07999 status = CACHE_FLAG_EXISTS;
08000 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08001 status = CACHE_FLAG_CANEXIST;
08002 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08003 status = CACHE_FLAG_NONEXISTENT;
08004
08005 if (ies->refresh)
08006 expiry = ies->refresh;
08007 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08008 matchmore = CACHE_FLAG_MATCHMORE;
08009
08010 AST_LIST_LOCK(&dpcache);
08011 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08012 if (strcmp(dp->exten, exten))
08013 continue;
08014 AST_LIST_REMOVE_CURRENT(peer_list);
08015 dp->callno = 0;
08016 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08017 if (dp->flags & CACHE_FLAG_PENDING) {
08018 dp->flags &= ~CACHE_FLAG_PENDING;
08019 dp->flags |= status;
08020 dp->flags |= matchmore;
08021 }
08022
08023 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08024 if (dp->waiters[x] > -1) {
08025 if (write(dp->waiters[x], "asdf", 4) < 0) {
08026 }
08027 }
08028 }
08029 }
08030 AST_LIST_TRAVERSE_SAFE_END;
08031 AST_LIST_UNLOCK(&dpcache);
08032
08033 return 0;
08034 }
08035
08036 static int complete_transfer(int callno, struct iax_ies *ies)
08037 {
08038 int peercallno = 0;
08039 struct chan_iax2_pvt *pvt = iaxs[callno];
08040 struct iax_frame *cur;
08041 jb_frame frame;
08042
08043 if (ies->callno)
08044 peercallno = ies->callno;
08045
08046 if (peercallno < 1) {
08047 ast_log(LOG_WARNING, "Invalid transfer request\n");
08048 return -1;
08049 }
08050 remove_by_transfercallno(pvt);
08051
08052
08053
08054 peercnt_remove_by_addr(&pvt->addr);
08055 peercnt_add(&pvt->transfer);
08056
08057 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08058 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08059
08060 pvt->oseqno = 0;
08061 pvt->rseqno = 0;
08062 pvt->iseqno = 0;
08063 pvt->aseqno = 0;
08064
08065 if (pvt->peercallno) {
08066 remove_by_peercallno(pvt);
08067 }
08068 pvt->peercallno = peercallno;
08069
08070 store_by_peercallno(pvt);
08071 pvt->transferring = TRANSFER_NONE;
08072 pvt->svoiceformat = -1;
08073 pvt->voiceformat = 0;
08074 pvt->svideoformat = -1;
08075 pvt->videoformat = 0;
08076 pvt->transfercallno = 0;
08077 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08078 memset(&pvt->offset, 0, sizeof(pvt->offset));
08079
08080 while(jb_getall(pvt->jb,&frame) == JB_OK)
08081 iax2_frame_free(frame.data);
08082 jb_reset(pvt->jb);
08083 pvt->lag = 0;
08084 pvt->last = 0;
08085 pvt->lastsent = 0;
08086 pvt->nextpred = 0;
08087 pvt->pingtime = DEFAULT_RETRY_TIME;
08088 AST_LIST_LOCK(&frame_queue);
08089 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08090
08091
08092
08093 if (callno == cur->callno)
08094 cur->retries = -1;
08095 }
08096 AST_LIST_UNLOCK(&frame_queue);
08097 return 0;
08098 }
08099
08100
08101 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08102 {
08103 struct iax2_registry *reg;
08104
08105 char peer[256] = "";
08106 char msgstatus[60];
08107 int refresh = 60;
08108 char ourip[256] = "<Unspecified>";
08109 struct sockaddr_in oldus;
08110 struct sockaddr_in us;
08111 int oldmsgs;
08112
08113 memset(&us, 0, sizeof(us));
08114 if (ies->apparent_addr)
08115 memmove(&us, ies->apparent_addr, sizeof(us));
08116 if (ies->username)
08117 ast_copy_string(peer, ies->username, sizeof(peer));
08118 if (ies->refresh)
08119 refresh = ies->refresh;
08120 if (ies->calling_number) {
08121
08122 }
08123 reg = iaxs[callno]->reg;
08124 if (!reg) {
08125 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08126 return -1;
08127 }
08128 memcpy(&oldus, ®->us, sizeof(oldus));
08129 oldmsgs = reg->messages;
08130 if (inaddrcmp(®->addr, sin)) {
08131 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08132 return -1;
08133 }
08134 memcpy(®->us, &us, sizeof(reg->us));
08135 if (ies->msgcount >= 0)
08136 reg->messages = ies->msgcount & 0xffff;
08137
08138
08139
08140 reg->refresh = refresh;
08141 reg->expire = iax2_sched_replace(reg->expire, sched,
08142 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08143 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08144 if (reg->messages > 255)
08145 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08146 else if (reg->messages > 1)
08147 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
08148 else if (reg->messages > 0)
08149 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
08150 else
08151 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
08152 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08153 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08154 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08155 }
08156 reg->regstate = REG_STATE_REGISTERED;
08157 return 0;
08158 }
08159
08160 static int iax2_append_register(const char *hostname, const char *username,
08161 const char *secret, const char *porta)
08162 {
08163 struct iax2_registry *reg;
08164
08165 if (!(reg = ast_calloc(1, sizeof(*reg))))
08166 return -1;
08167
08168 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08169 ast_free(reg);
08170 return -1;
08171 }
08172
08173 ast_copy_string(reg->username, username, sizeof(reg->username));
08174
08175 if (secret)
08176 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08177
08178 reg->expire = -1;
08179 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08180 reg->addr.sin_family = AF_INET;
08181 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
08182
08183 AST_LIST_LOCK(®istrations);
08184 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08185 AST_LIST_UNLOCK(®istrations);
08186
08187 return 0;
08188 }
08189
08190 static int iax2_register(const char *value, int lineno)
08191 {
08192 char copy[256];
08193 char *username, *hostname, *secret;
08194 char *porta;
08195 char *stringp=NULL;
08196
08197 if (!value)
08198 return -1;
08199
08200 ast_copy_string(copy, value, sizeof(copy));
08201 stringp = copy;
08202 username = strsep(&stringp, "@");
08203 hostname = strsep(&stringp, "@");
08204
08205 if (!hostname) {
08206 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08207 return -1;
08208 }
08209
08210 stringp = username;
08211 username = strsep(&stringp, ":");
08212 secret = strsep(&stringp, ":");
08213 stringp = hostname;
08214 hostname = strsep(&stringp, ":");
08215 porta = strsep(&stringp, ":");
08216
08217 if (porta && !atoi(porta)) {
08218 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08219 return -1;
08220 }
08221
08222 return iax2_append_register(hostname, username, secret, porta);
08223 }
08224
08225
08226 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08227 {
08228 char multi[256];
08229 char *stringp, *ext;
08230 if (!ast_strlen_zero(regcontext)) {
08231 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08232 stringp = multi;
08233 while((ext = strsep(&stringp, "&"))) {
08234 if (onoff) {
08235 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08236 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08237 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08238 } else
08239 ast_context_remove_extension(regcontext, ext, 1, NULL);
08240 }
08241 }
08242 }
08243 static void prune_peers(void);
08244
08245 static void unlink_peer(struct iax2_peer *peer)
08246 {
08247 if (peer->expire > -1) {
08248 if (!ast_sched_thread_del(sched, peer->expire)) {
08249 peer->expire = -1;
08250 peer_unref(peer);
08251 }
08252 }
08253
08254 if (peer->pokeexpire > -1) {
08255 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08256 peer->pokeexpire = -1;
08257 peer_unref(peer);
08258 }
08259 }
08260
08261 ao2_unlink(peers, peer);
08262 }
08263
08264 static void __expire_registry(const void *data)
08265 {
08266 struct iax2_peer *peer = (struct iax2_peer *) data;
08267
08268 if (!peer)
08269 return;
08270
08271 peer->expire = -1;
08272
08273 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08274 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08275 realtime_update_peer(peer->name, &peer->addr, 0);
08276 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08277
08278 peercnt_modify(0, 0, &peer->addr);
08279
08280 memset(&peer->addr, 0, sizeof(peer->addr));
08281
08282 peer->expiry = min_reg_expire;
08283 if (!ast_test_flag(peer, IAX_TEMPONLY))
08284 ast_db_del("IAX/Registry", peer->name);
08285 register_peer_exten(peer, 0);
08286 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08287 if (iax2_regfunk)
08288 iax2_regfunk(peer->name, 0);
08289
08290 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
08291 unlink_peer(peer);
08292
08293 peer_unref(peer);
08294 }
08295
08296 static int expire_registry(const void *data)
08297 {
08298 #ifdef SCHED_MULTITHREADED
08299 if (schedule_action(__expire_registry, data))
08300 #endif
08301 __expire_registry(data);
08302 return 0;
08303 }
08304
08305 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08306
08307 static void reg_source_db(struct iax2_peer *p)
08308 {
08309 char data[80];
08310 struct in_addr in;
08311 char *c, *d;
08312 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
08313 c = strchr(data, ':');
08314 if (c) {
08315 *c = '\0';
08316 c++;
08317 if (inet_aton(data, &in)) {
08318 d = strchr(c, ':');
08319 if (d) {
08320 *d = '\0';
08321 d++;
08322 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
08323 ast_inet_ntoa(in), atoi(c), atoi(d));
08324 iax2_poke_peer(p, 0);
08325 p->expiry = atoi(d);
08326 memset(&p->addr, 0, sizeof(p->addr));
08327 p->addr.sin_family = AF_INET;
08328 p->addr.sin_addr = in;
08329 p->addr.sin_port = htons(atoi(c));
08330 if (p->expire > -1) {
08331 if (!ast_sched_thread_del(sched, p->expire)) {
08332 p->expire = -1;
08333 peer_unref(p);
08334 }
08335 }
08336 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08337 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08338 if (p->expire == -1)
08339 peer_unref(p);
08340 if (iax2_regfunk)
08341 iax2_regfunk(p->name, 1);
08342 register_peer_exten(p, 1);
08343 }
08344
08345 }
08346 }
08347 }
08348 }
08349
08350
08351
08352
08353
08354
08355
08356 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08357 {
08358
08359 struct iax_ie_data ied;
08360 struct iax2_peer *p;
08361 int msgcount;
08362 char data[80];
08363 int version;
08364 const char *peer_name;
08365 int res = -1;
08366
08367 memset(&ied, 0, sizeof(ied));
08368
08369 peer_name = ast_strdupa(iaxs[callno]->peer);
08370
08371
08372 ast_mutex_unlock(&iaxsl[callno]);
08373 if (!(p = find_peer(peer_name, 1))) {
08374 ast_mutex_lock(&iaxsl[callno]);
08375 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08376 return -1;
08377 }
08378 ast_mutex_lock(&iaxsl[callno]);
08379 if (!iaxs[callno])
08380 goto return_unref;
08381
08382 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08383 if (sin->sin_addr.s_addr) {
08384 time_t nowtime;
08385 time(&nowtime);
08386 realtime_update_peer(peer_name, sin, nowtime);
08387 } else {
08388 realtime_update_peer(peer_name, sin, 0);
08389 }
08390 }
08391 if (inaddrcmp(&p->addr, sin)) {
08392 if (iax2_regfunk)
08393 iax2_regfunk(p->name, 1);
08394
08395
08396 peercnt_modify(0, 0, &p->addr);
08397
08398
08399 memcpy(&p->addr, sin, sizeof(p->addr));
08400
08401 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08402 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08403 ast_db_put("IAX/Registry", p->name, data);
08404 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08405 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08406 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08407 register_peer_exten(p, 1);
08408 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08409 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
08410 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08411 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08412 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08413 register_peer_exten(p, 0);
08414 ast_db_del("IAX/Registry", p->name);
08415 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08416 }
08417
08418
08419 iax2_poke_peer(p, callno);
08420 }
08421
08422
08423 if (p->maxcallno) {
08424 peercnt_modify(1, p->maxcallno, &p->addr);
08425 }
08426
08427
08428 if (!iaxs[callno]) {
08429 res = -1;
08430 goto return_unref;
08431 }
08432
08433
08434 p->sockfd = fd;
08435
08436 if (p->expire > -1) {
08437 if (!ast_sched_thread_del(sched, p->expire)) {
08438 p->expire = -1;
08439 peer_unref(p);
08440 }
08441 }
08442
08443 if (!refresh)
08444 refresh = min_reg_expire;
08445 if (refresh > max_reg_expire) {
08446 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08447 p->name, max_reg_expire, refresh);
08448 p->expiry = max_reg_expire;
08449 } else if (refresh < min_reg_expire) {
08450 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08451 p->name, min_reg_expire, refresh);
08452 p->expiry = min_reg_expire;
08453 } else {
08454 p->expiry = refresh;
08455 }
08456 if (p->expiry && sin->sin_addr.s_addr) {
08457 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08458 if (p->expire == -1)
08459 peer_unref(p);
08460 }
08461 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08462 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08463 if (sin->sin_addr.s_addr) {
08464 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08465 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
08466 if (!ast_strlen_zero(p->mailbox)) {
08467 struct ast_event *event;
08468 int new, old;
08469 char *mailbox, *context;
08470
08471 context = mailbox = ast_strdupa(p->mailbox);
08472 strsep(&context, "@");
08473 if (ast_strlen_zero(context))
08474 context = "default";
08475
08476 event = ast_event_get_cached(AST_EVENT_MWI,
08477 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08478 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08479 AST_EVENT_IE_END);
08480 if (event) {
08481 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08482 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08483 ast_event_destroy(event);
08484 } else {
08485 ast_app_inboxcount(p->mailbox, &new, &old);
08486 }
08487
08488 if (new > 255) {
08489 new = 255;
08490 }
08491 if (old > 255) {
08492 old = 255;
08493 }
08494 msgcount = (old << 8) | new;
08495
08496 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08497 }
08498 if (ast_test_flag(p, IAX_HASCALLERID)) {
08499 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08500 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08501 }
08502 }
08503 version = iax_check_version(devtype);
08504 if (version)
08505 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08506
08507 res = 0;
08508
08509 return_unref:
08510 peer_unref(p);
08511
08512 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08513 }
08514
08515 static int registry_authrequest(int callno)
08516 {
08517 struct iax_ie_data ied;
08518 struct iax2_peer *p;
08519 char challenge[10];
08520 const char *peer_name;
08521 int sentauthmethod;
08522
08523 peer_name = ast_strdupa(iaxs[callno]->peer);
08524
08525
08526 ast_mutex_unlock(&iaxsl[callno]);
08527 if ((p = find_peer(peer_name, 1))) {
08528 last_authmethod = p->authmethods;
08529 }
08530
08531 ast_mutex_lock(&iaxsl[callno]);
08532 if (!iaxs[callno])
08533 goto return_unref;
08534
08535 memset(&ied, 0, sizeof(ied));
08536
08537
08538
08539
08540
08541
08542 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08543 if (!p) {
08544 iaxs[callno]->authmethods = sentauthmethod;
08545 }
08546 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08547 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08548
08549 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08550 ast_string_field_set(iaxs[callno], challenge, challenge);
08551 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08552 }
08553 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08554
08555 return_unref:
08556 if (p) {
08557 peer_unref(p);
08558 }
08559
08560 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08561 }
08562
08563 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08564 {
08565 struct iax2_registry *reg;
08566
08567 struct iax_ie_data ied;
08568 char peer[256] = "";
08569 char challenge[256] = "";
08570 int res;
08571 int authmethods = 0;
08572 if (ies->authmethods)
08573 authmethods = ies->authmethods;
08574 if (ies->username)
08575 ast_copy_string(peer, ies->username, sizeof(peer));
08576 if (ies->challenge)
08577 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08578 memset(&ied, 0, sizeof(ied));
08579 reg = iaxs[callno]->reg;
08580 if (reg) {
08581 if (inaddrcmp(®->addr, sin)) {
08582 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08583 return -1;
08584 }
08585 if (ast_strlen_zero(reg->secret)) {
08586 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08587 reg->regstate = REG_STATE_NOAUTH;
08588 return -1;
08589 }
08590 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08591 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08592 if (reg->secret[0] == '[') {
08593 char tmpkey[256];
08594 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08595 tmpkey[strlen(tmpkey) - 1] = '\0';
08596 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08597 } else
08598 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08599 if (!res) {
08600 reg->regstate = REG_STATE_AUTHSENT;
08601 add_empty_calltoken_ie(iaxs[callno], &ied);
08602 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08603 } else
08604 return -1;
08605 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08606 } else
08607 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08608 return -1;
08609 }
08610
08611 static void stop_stuff(int callno)
08612 {
08613 iax2_destroy_helper(iaxs[callno]);
08614 }
08615
08616 static void __auth_reject(const void *nothing)
08617 {
08618
08619 int callno = (int)(long)(nothing);
08620 struct iax_ie_data ied;
08621 ast_mutex_lock(&iaxsl[callno]);
08622 if (iaxs[callno]) {
08623 memset(&ied, 0, sizeof(ied));
08624 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08625 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08626 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08627 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08628 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08629 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08630 }
08631 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08632 }
08633 ast_mutex_unlock(&iaxsl[callno]);
08634 }
08635
08636 static int auth_reject(const void *data)
08637 {
08638 int callno = (int)(long)(data);
08639 ast_mutex_lock(&iaxsl[callno]);
08640 if (iaxs[callno])
08641 iaxs[callno]->authid = -1;
08642 ast_mutex_unlock(&iaxsl[callno]);
08643 #ifdef SCHED_MULTITHREADED
08644 if (schedule_action(__auth_reject, data))
08645 #endif
08646 __auth_reject(data);
08647 return 0;
08648 }
08649
08650 static int auth_fail(int callno, int failcode)
08651 {
08652
08653
08654 if (iaxs[callno]) {
08655 iaxs[callno]->authfail = failcode;
08656 if (delayreject) {
08657 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08658 sched, 1000, auth_reject, (void *)(long)callno);
08659 } else
08660 auth_reject((void *)(long)callno);
08661 }
08662 return 0;
08663 }
08664
08665 static void __auto_hangup(const void *nothing)
08666 {
08667
08668 int callno = (int)(long)(nothing);
08669 struct iax_ie_data ied;
08670 ast_mutex_lock(&iaxsl[callno]);
08671 if (iaxs[callno]) {
08672 memset(&ied, 0, sizeof(ied));
08673 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08674 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
08675 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
08676 }
08677 ast_mutex_unlock(&iaxsl[callno]);
08678 }
08679
08680 static int auto_hangup(const void *data)
08681 {
08682 int callno = (int)(long)(data);
08683 ast_mutex_lock(&iaxsl[callno]);
08684 if (iaxs[callno]) {
08685 iaxs[callno]->autoid = -1;
08686 }
08687 ast_mutex_unlock(&iaxsl[callno]);
08688 #ifdef SCHED_MULTITHREADED
08689 if (schedule_action(__auto_hangup, data))
08690 #endif
08691 __auto_hangup(data);
08692 return 0;
08693 }
08694
08695 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
08696 {
08697 struct iax_ie_data ied;
08698
08699 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
08700 sched, 30000, auto_hangup, (void *)(long)callno);
08701 memset(&ied, 0, sizeof(ied));
08702 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
08703 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
08704 dp->flags |= CACHE_FLAG_TRANSMITTED;
08705 }
08706
08707 static int iax2_vnak(int callno)
08708 {
08709 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
08710 }
08711
08712 static void vnak_retransmit(int callno, int last)
08713 {
08714 struct iax_frame *f;
08715
08716 AST_LIST_LOCK(&frame_queue);
08717 AST_LIST_TRAVERSE(&frame_queue, f, list) {
08718
08719 if ((f->callno == callno) && iaxs[f->callno] &&
08720 ((unsigned char ) (f->oseqno - last) < 128) &&
08721 (f->retries >= 0)) {
08722 send_packet(f);
08723 }
08724 }
08725 AST_LIST_UNLOCK(&frame_queue);
08726 }
08727
08728 static void __iax2_poke_peer_s(const void *data)
08729 {
08730 struct iax2_peer *peer = (struct iax2_peer *)data;
08731 iax2_poke_peer(peer, 0);
08732 peer_unref(peer);
08733 }
08734
08735 static int iax2_poke_peer_s(const void *data)
08736 {
08737 struct iax2_peer *peer = (struct iax2_peer *)data;
08738 peer->pokeexpire = -1;
08739 #ifdef SCHED_MULTITHREADED
08740 if (schedule_action(__iax2_poke_peer_s, data))
08741 #endif
08742 __iax2_poke_peer_s(data);
08743 return 0;
08744 }
08745
08746 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
08747 {
08748 int res = 0;
08749 struct iax_frame *fr;
08750 struct ast_iax2_meta_hdr *meta;
08751 struct ast_iax2_meta_trunk_hdr *mth;
08752 int calls = 0;
08753
08754
08755 fr = (struct iax_frame *)tpeer->trunkdata;
08756
08757 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
08758 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
08759 if (tpeer->trunkdatalen) {
08760
08761 meta->zeros = 0;
08762 meta->metacmd = IAX_META_TRUNK;
08763 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
08764 meta->cmddata = IAX_META_TRUNK_MINI;
08765 else
08766 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
08767 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
08768
08769 fr->direction = DIRECTION_OUTGRESS;
08770 fr->retrans = -1;
08771 fr->transfer = 0;
08772
08773 fr->data = fr->afdata;
08774 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
08775 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
08776 calls = tpeer->calls;
08777 #if 0
08778 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));
08779 #endif
08780
08781 tpeer->trunkdatalen = 0;
08782 tpeer->calls = 0;
08783 }
08784 if (res < 0)
08785 return res;
08786 return calls;
08787 }
08788
08789 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
08790 {
08791
08792 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
08793 return 1;
08794 return 0;
08795 }
08796
08797 static int timing_read(int *id, int fd, short events, void *cbdata)
08798 {
08799 int res, processed = 0, totalcalls = 0;
08800 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
08801 struct timeval now = ast_tvnow();
08802
08803 if (iaxtrunkdebug)
08804 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
08805
08806 if (timer) {
08807 ast_timer_ack(timer, 1);
08808 }
08809
08810
08811 AST_LIST_LOCK(&tpeers);
08812 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
08813 processed++;
08814 res = 0;
08815 ast_mutex_lock(&tpeer->lock);
08816
08817
08818 if (!drop && iax2_trunk_expired(tpeer, &now)) {
08819
08820
08821 AST_LIST_REMOVE_CURRENT(list);
08822 drop = tpeer;
08823 } else {
08824 res = send_trunk(tpeer, &now);
08825 trunk_timed++;
08826 if (iaxtrunkdebug)
08827 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);
08828 }
08829 totalcalls += res;
08830 res = 0;
08831 ast_mutex_unlock(&tpeer->lock);
08832 }
08833 AST_LIST_TRAVERSE_SAFE_END;
08834 AST_LIST_UNLOCK(&tpeers);
08835
08836 if (drop) {
08837 ast_mutex_lock(&drop->lock);
08838
08839
08840 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
08841 if (drop->trunkdata) {
08842 ast_free(drop->trunkdata);
08843 drop->trunkdata = NULL;
08844 }
08845 ast_mutex_unlock(&drop->lock);
08846 ast_mutex_destroy(&drop->lock);
08847 ast_free(drop);
08848
08849 }
08850
08851 if (iaxtrunkdebug)
08852 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
08853 iaxtrunkdebug = 0;
08854
08855 return 1;
08856 }
08857
08858 struct dpreq_data {
08859 int callno;
08860 char context[AST_MAX_EXTENSION];
08861 char callednum[AST_MAX_EXTENSION];
08862 char *callerid;
08863 };
08864
08865 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
08866 {
08867 unsigned short dpstatus = 0;
08868 struct iax_ie_data ied1;
08869 int mm;
08870
08871 memset(&ied1, 0, sizeof(ied1));
08872 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
08873
08874 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
08875 dpstatus = IAX_DPSTATUS_EXISTS;
08876 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
08877 dpstatus = IAX_DPSTATUS_CANEXIST;
08878 } else {
08879 dpstatus = IAX_DPSTATUS_NONEXISTENT;
08880 }
08881 if (ast_ignore_pattern(context, callednum))
08882 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
08883 if (mm)
08884 dpstatus |= IAX_DPSTATUS_MATCHMORE;
08885 if (!skiplock)
08886 ast_mutex_lock(&iaxsl[callno]);
08887 if (iaxs[callno]) {
08888 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
08889 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
08890 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
08891 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
08892 }
08893 if (!skiplock)
08894 ast_mutex_unlock(&iaxsl[callno]);
08895 }
08896
08897 static void *dp_lookup_thread(void *data)
08898 {
08899
08900 struct dpreq_data *dpr = data;
08901 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
08902 if (dpr->callerid)
08903 ast_free(dpr->callerid);
08904 ast_free(dpr);
08905 return NULL;
08906 }
08907
08908 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
08909 {
08910 pthread_t newthread;
08911 struct dpreq_data *dpr;
08912
08913 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
08914 return;
08915
08916 dpr->callno = callno;
08917 ast_copy_string(dpr->context, context, sizeof(dpr->context));
08918 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
08919 if (callerid)
08920 dpr->callerid = ast_strdup(callerid);
08921 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
08922 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
08923 }
08924 }
08925
08926 struct iax_dual {
08927 struct ast_channel *chan1;
08928 struct ast_channel *chan2;
08929 };
08930
08931 static void *iax_park_thread(void *stuff)
08932 {
08933 struct ast_channel *chan1, *chan2;
08934 struct iax_dual *d;
08935 struct ast_frame *f;
08936 int ext;
08937 int res;
08938 d = stuff;
08939 chan1 = d->chan1;
08940 chan2 = d->chan2;
08941 ast_free(d);
08942 f = ast_read(chan1);
08943 if (f)
08944 ast_frfree(f);
08945 res = ast_park_call(chan1, chan2, 0, &ext);
08946 ast_hangup(chan2);
08947 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
08948 return NULL;
08949 }
08950
08951 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
08952 {
08953 struct iax_dual *d;
08954 struct ast_channel *chan1m, *chan2m;
08955 pthread_t th;
08956 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
08957 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
08958 if (chan2m && chan1m) {
08959
08960 chan1m->readformat = chan1->readformat;
08961 chan1m->writeformat = chan1->writeformat;
08962 ast_channel_masquerade(chan1m, chan1);
08963
08964 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
08965 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
08966 chan1m->priority = chan1->priority;
08967
08968
08969
08970
08971 chan2m->readformat = chan2->readformat;
08972 chan2m->writeformat = chan2->writeformat;
08973 ast_channel_masquerade(chan2m, chan2);
08974
08975 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
08976 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
08977 chan2m->priority = chan2->priority;
08978 if (ast_do_masquerade(chan2m)) {
08979 ast_log(LOG_WARNING, "Masquerade failed :(\n");
08980 ast_hangup(chan2m);
08981 return -1;
08982 }
08983 } else {
08984 if (chan1m)
08985 ast_hangup(chan1m);
08986 if (chan2m)
08987 ast_hangup(chan2m);
08988 return -1;
08989 }
08990 if ((d = ast_calloc(1, sizeof(*d)))) {
08991 d->chan1 = chan1m;
08992 d->chan2 = chan2m;
08993 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
08994 return 0;
08995 }
08996 ast_free(d);
08997 }
08998 return -1;
08999 }
09000
09001
09002 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
09003
09004 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09005 {
09006 unsigned int ourver;
09007 char rsi[80];
09008 snprintf(rsi, sizeof(rsi), "si-%s", si);
09009 if (iax_provision_version(&ourver, rsi, 1))
09010 return 0;
09011 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09012 if (ourver != ver)
09013 iax2_provision(sin, sockfd, NULL, rsi, 1);
09014 return 0;
09015 }
09016
09017 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09018 {
09019 jb_info stats;
09020 jb_getinfo(pvt->jb, &stats);
09021
09022 memset(iep, 0, sizeof(*iep));
09023
09024 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09025 if(stats.frames_in == 0) stats.frames_in = 1;
09026 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09027 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09028 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09029 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09030 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09031 }
09032
09033 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09034 {
09035 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09036 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09037 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09038 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09039 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09040 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09041 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09042 }
09043
09044 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09045 {
09046 int i;
09047 unsigned int length, offset = 0;
09048 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09049
09050 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09051 length = ies->ospblocklength[i];
09052 if (length != 0) {
09053 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09054
09055 offset = 0;
09056 break;
09057 } else {
09058 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09059 offset += length;
09060 }
09061 } else {
09062 break;
09063 }
09064 }
09065 *(full_osptoken + offset) = '\0';
09066 if (strlen(full_osptoken) != offset) {
09067
09068 *full_osptoken = '\0';
09069 }
09070
09071 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09072 }
09073
09074 static void log_jitterstats(unsigned short callno)
09075 {
09076 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09077 jb_info jbinfo;
09078
09079 ast_mutex_lock(&iaxsl[callno]);
09080 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09081 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
09082 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09083 localjitter = jbinfo.jitter;
09084 localdelay = jbinfo.current - jbinfo.min;
09085 locallost = jbinfo.frames_lost;
09086 locallosspct = jbinfo.losspct/1000;
09087 localdropped = jbinfo.frames_dropped;
09088 localooo = jbinfo.frames_ooo;
09089 localpackets = jbinfo.frames_in;
09090 }
09091 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",
09092 iaxs[callno]->owner->name,
09093 iaxs[callno]->pingtime,
09094 localjitter,
09095 localdelay,
09096 locallost,
09097 locallosspct,
09098 localdropped,
09099 localooo,
09100 localpackets,
09101 iaxs[callno]->remote_rr.jitter,
09102 iaxs[callno]->remote_rr.delay,
09103 iaxs[callno]->remote_rr.losscnt,
09104 iaxs[callno]->remote_rr.losspct/1000,
09105 iaxs[callno]->remote_rr.dropped,
09106 iaxs[callno]->remote_rr.ooo,
09107 iaxs[callno]->remote_rr.packets);
09108 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",
09109 iaxs[callno]->owner->name,
09110 iaxs[callno]->pingtime,
09111 localjitter,
09112 localdelay,
09113 locallost,
09114 locallosspct,
09115 localdropped,
09116 localooo,
09117 localpackets,
09118 iaxs[callno]->remote_rr.jitter,
09119 iaxs[callno]->remote_rr.delay,
09120 iaxs[callno]->remote_rr.losscnt,
09121 iaxs[callno]->remote_rr.losspct/1000,
09122 iaxs[callno]->remote_rr.dropped,
09123 iaxs[callno]->remote_rr.ooo,
09124 iaxs[callno]->remote_rr.packets);
09125 }
09126 ast_mutex_unlock(&iaxsl[callno]);
09127 }
09128
09129 static int socket_process(struct iax2_thread *thread);
09130
09131
09132
09133
09134 static void handle_deferred_full_frames(struct iax2_thread *thread)
09135 {
09136 struct iax2_pkt_buf *pkt_buf;
09137
09138 ast_mutex_lock(&thread->lock);
09139
09140 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09141 ast_mutex_unlock(&thread->lock);
09142
09143 thread->buf = pkt_buf->buf;
09144 thread->buf_len = pkt_buf->len;
09145 thread->buf_size = pkt_buf->len + 1;
09146
09147 socket_process(thread);
09148
09149 thread->buf = NULL;
09150 ast_free(pkt_buf);
09151
09152 ast_mutex_lock(&thread->lock);
09153 }
09154
09155 ast_mutex_unlock(&thread->lock);
09156 }
09157
09158
09159
09160
09161
09162
09163
09164 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09165 {
09166 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09167 struct ast_iax2_full_hdr *fh, *cur_fh;
09168
09169 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09170 return;
09171
09172 pkt_buf->len = from_here->buf_len;
09173 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09174
09175 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09176 ast_mutex_lock(&to_here->lock);
09177 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09178 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09179 if (fh->oseqno < cur_fh->oseqno) {
09180 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09181 break;
09182 }
09183 }
09184 AST_LIST_TRAVERSE_SAFE_END
09185
09186 if (!cur_pkt_buf)
09187 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09188
09189 ast_mutex_unlock(&to_here->lock);
09190 }
09191
09192 static int socket_read(int *id, int fd, short events, void *cbdata)
09193 {
09194 struct iax2_thread *thread;
09195 socklen_t len;
09196 time_t t;
09197 static time_t last_errtime = 0;
09198 struct ast_iax2_full_hdr *fh;
09199
09200 if (!(thread = find_idle_thread())) {
09201 time(&t);
09202 if (t != last_errtime)
09203 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09204 last_errtime = t;
09205 usleep(1);
09206 return 1;
09207 }
09208
09209 len = sizeof(thread->iosin);
09210 thread->iofd = fd;
09211 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09212 thread->buf_size = sizeof(thread->readbuf);
09213 thread->buf = thread->readbuf;
09214 if (thread->buf_len < 0) {
09215 if (errno != ECONNREFUSED && errno != EAGAIN)
09216 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09217 handle_error();
09218 thread->iostate = IAX_IOSTATE_IDLE;
09219 signal_condition(&thread->lock, &thread->cond);
09220 return 1;
09221 }
09222 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09223 thread->iostate = IAX_IOSTATE_IDLE;
09224 signal_condition(&thread->lock, &thread->cond);
09225 return 1;
09226 }
09227
09228
09229
09230
09231 fh = (struct ast_iax2_full_hdr *) thread->buf;
09232 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09233 struct iax2_thread *cur = NULL;
09234 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09235
09236 AST_LIST_LOCK(&active_list);
09237 AST_LIST_TRAVERSE(&active_list, cur, list) {
09238 if ((cur->ffinfo.callno == callno) &&
09239 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09240 break;
09241 }
09242 if (cur) {
09243
09244
09245 defer_full_frame(thread, cur);
09246 AST_LIST_UNLOCK(&active_list);
09247 thread->iostate = IAX_IOSTATE_IDLE;
09248 signal_condition(&thread->lock, &thread->cond);
09249 return 1;
09250 } else {
09251
09252 thread->ffinfo.callno = callno;
09253 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09254 thread->ffinfo.type = fh->type;
09255 thread->ffinfo.csub = fh->csub;
09256 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09257 }
09258 AST_LIST_UNLOCK(&active_list);
09259 }
09260
09261
09262 thread->iostate = IAX_IOSTATE_READY;
09263 #ifdef DEBUG_SCHED_MULTITHREAD
09264 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09265 #endif
09266 signal_condition(&thread->lock, &thread->cond);
09267
09268 return 1;
09269 }
09270
09271 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09272 struct iax_frame *fr)
09273 {
09274 unsigned char metatype;
09275 struct ast_iax2_meta_trunk_mini *mtm;
09276 struct ast_iax2_meta_trunk_hdr *mth;
09277 struct ast_iax2_meta_trunk_entry *mte;
09278 struct iax2_trunk_peer *tpeer;
09279 unsigned int ts;
09280 void *ptr;
09281 struct timeval rxtrunktime;
09282 struct ast_frame f = { 0, };
09283
09284 if (packet_len < sizeof(*meta)) {
09285 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09286 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09287 return 1;
09288 }
09289
09290 if (meta->metacmd != IAX_META_TRUNK)
09291 return 1;
09292
09293 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09294 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09295 (int) (sizeof(*meta) + sizeof(*mth)));
09296 return 1;
09297 }
09298 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09299 ts = ntohl(mth->ts);
09300 metatype = meta->cmddata;
09301 packet_len -= (sizeof(*meta) + sizeof(*mth));
09302 ptr = mth->data;
09303 tpeer = find_tpeer(sin, sockfd);
09304 if (!tpeer) {
09305 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09306 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09307 return 1;
09308 }
09309 tpeer->trunkact = ast_tvnow();
09310 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09311 tpeer->rxtrunktime = tpeer->trunkact;
09312 rxtrunktime = tpeer->rxtrunktime;
09313 ast_mutex_unlock(&tpeer->lock);
09314 while (packet_len >= sizeof(*mte)) {
09315
09316 unsigned short callno, trunked_ts, len;
09317
09318 if (metatype == IAX_META_TRUNK_MINI) {
09319 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09320 ptr += sizeof(*mtm);
09321 packet_len -= sizeof(*mtm);
09322 len = ntohs(mtm->len);
09323 callno = ntohs(mtm->mini.callno);
09324 trunked_ts = ntohs(mtm->mini.ts);
09325 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09326 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09327 ptr += sizeof(*mte);
09328 packet_len -= sizeof(*mte);
09329 len = ntohs(mte->len);
09330 callno = ntohs(mte->callno);
09331 trunked_ts = 0;
09332 } else {
09333 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09334 break;
09335 }
09336
09337 if (len > packet_len)
09338 break;
09339 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09340 if (!fr->callno)
09341 continue;
09342
09343
09344
09345
09346 memset(&f, 0, sizeof(f));
09347 f.frametype = AST_FRAME_VOICE;
09348 if (!iaxs[fr->callno]) {
09349
09350 } else if (iaxs[fr->callno]->voiceformat == 0) {
09351 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09352 iax2_vnak(fr->callno);
09353 } else {
09354 f.subclass = iaxs[fr->callno]->voiceformat;
09355 f.datalen = len;
09356 if (f.datalen >= 0) {
09357 if (f.datalen)
09358 f.data.ptr = ptr;
09359 else
09360 f.data.ptr = NULL;
09361 if (trunked_ts)
09362 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09363 else
09364 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09365
09366 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09367 struct iax_frame *duped_fr;
09368
09369
09370 f.src = "IAX2";
09371 f.mallocd = 0;
09372 f.offset = 0;
09373 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09374 f.samples = ast_codec_get_samples(&f);
09375 else
09376 f.samples = 0;
09377 fr->outoforder = 0;
09378 iax_frame_wrap(fr, &f);
09379 duped_fr = iaxfrdup2(fr);
09380 if (duped_fr)
09381 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09382 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09383 iaxs[fr->callno]->last = fr->ts;
09384 }
09385 } else {
09386 ast_log(LOG_WARNING, "Datalen < 0?\n");
09387 }
09388 }
09389 ast_mutex_unlock(&iaxsl[fr->callno]);
09390 ptr += len;
09391 packet_len -= len;
09392 }
09393
09394 return 1;
09395 }
09396
09397 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09398 {
09399 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09400 AST_LIST_HEAD(, ast_var_t) *varlist;
09401 struct ast_var_t *var;
09402
09403 if (!variablestore) {
09404 *buf = '\0';
09405 return 0;
09406 }
09407 varlist = variablestore->data;
09408
09409 AST_LIST_LOCK(varlist);
09410 AST_LIST_TRAVERSE(varlist, var, entries) {
09411 if (strcmp(var->name, data) == 0) {
09412 ast_copy_string(buf, var->value, len);
09413 break;
09414 }
09415 }
09416 AST_LIST_UNLOCK(varlist);
09417 return 0;
09418 }
09419
09420 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09421 {
09422 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09423 AST_LIST_HEAD(, ast_var_t) *varlist;
09424 struct ast_var_t *var;
09425
09426 if (!variablestore) {
09427 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09428 if (!variablestore) {
09429 ast_log(LOG_ERROR, "Memory allocation error\n");
09430 return -1;
09431 }
09432 varlist = ast_calloc(1, sizeof(*varlist));
09433 if (!varlist) {
09434 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09435 return -1;
09436 }
09437
09438 AST_LIST_HEAD_INIT(varlist);
09439 variablestore->data = varlist;
09440 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09441 ast_channel_datastore_add(chan, variablestore);
09442 } else
09443 varlist = variablestore->data;
09444
09445 AST_LIST_LOCK(varlist);
09446 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09447 if (strcmp(var->name, data) == 0) {
09448 AST_LIST_REMOVE_CURRENT(entries);
09449 ast_var_delete(var);
09450 break;
09451 }
09452 }
09453 AST_LIST_TRAVERSE_SAFE_END;
09454 var = ast_var_assign(data, value);
09455 if (var)
09456 AST_LIST_INSERT_TAIL(varlist, var, entries);
09457 else
09458 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09459 AST_LIST_UNLOCK(varlist);
09460 return 0;
09461 }
09462
09463 static struct ast_custom_function iaxvar_function = {
09464 .name = "IAXVAR",
09465 .read = acf_iaxvar_read,
09466 .write = acf_iaxvar_write,
09467 };
09468
09469 static int socket_process(struct iax2_thread *thread)
09470 {
09471 struct sockaddr_in sin;
09472 int res;
09473 int updatehistory=1;
09474 int new = NEW_PREVENT;
09475 int dcallno = 0;
09476 char decrypted = 0;
09477 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09478 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09479 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09480 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09481 struct iax_frame *fr;
09482 struct iax_frame *cur;
09483 struct ast_frame f = { 0, };
09484 struct ast_channel *c = NULL;
09485 struct iax2_dpcache *dp;
09486 struct iax2_peer *peer;
09487 struct iax_ies ies;
09488 struct iax_ie_data ied0, ied1;
09489 int format;
09490 int fd;
09491 int exists;
09492 int minivid = 0;
09493 char empty[32]="";
09494 struct iax_frame *duped_fr;
09495 char host_pref_buf[128];
09496 char caller_pref_buf[128];
09497 struct ast_codec_pref pref;
09498 char *using_prefs = "mine";
09499
09500
09501 fr = alloca(sizeof(*fr) + 4096);
09502 memset(fr, 0, sizeof(*fr));
09503 fr->afdatalen = 4096;
09504
09505
09506 res = thread->buf_len;
09507 fd = thread->iofd;
09508 memcpy(&sin, &thread->iosin, sizeof(sin));
09509
09510 if (res < sizeof(*mh)) {
09511 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09512 return 1;
09513 }
09514 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09515 if (res < sizeof(*vh)) {
09516 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));
09517 return 1;
09518 }
09519
09520
09521 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09522 minivid = 1;
09523 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09524 return socket_process_meta(res, meta, &sin, fd, fr);
09525
09526 #ifdef DEBUG_SUPPORT
09527 if (res >= sizeof(*fh))
09528 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09529 #endif
09530 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09531 if (res < sizeof(*fh)) {
09532 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));
09533 return 1;
09534 }
09535
09536
09537 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09538
09539
09540
09541
09542
09543
09544 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09545 ast_mutex_lock(&iaxsl[fr->callno]);
09546 if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
09547 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09548 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09549 ast_mutex_unlock(&iaxsl[fr->callno]);
09550 return 1;
09551 }
09552 decrypted = 1;
09553 }
09554 ast_mutex_unlock(&iaxsl[fr->callno]);
09555 }
09556
09557
09558 f.frametype = fh->type;
09559 if (f.frametype == AST_FRAME_VIDEO) {
09560 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09561 } else {
09562 f.subclass = uncompress_subclass(fh->csub);
09563 }
09564
09565
09566 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
09567
09568 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09569 return 1;
09570 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
09571
09572 return 1;
09573 }
09574
09575 f.datalen = res - sizeof(*fh);
09576 if (f.datalen) {
09577 if (f.frametype == AST_FRAME_IAX) {
09578 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09579 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09580 return 1;
09581 }
09582 f.data.ptr = NULL;
09583 f.datalen = 0;
09584 } else {
09585 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09586 memset(&ies, 0, sizeof(ies));
09587 }
09588 } else {
09589 if (f.frametype == AST_FRAME_IAX)
09590 f.data.ptr = NULL;
09591 else
09592 f.data.ptr = empty;
09593 memset(&ies, 0, sizeof(ies));
09594 }
09595
09596 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) {
09597
09598 if (handle_call_token(fh, &ies, &sin, fd)) {
09599 return 1;
09600 }
09601
09602 if (ies.calltoken && ies.calltokendata) {
09603
09604
09605
09606
09607 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09608 } else {
09609 new = NEW_ALLOW;
09610 }
09611 }
09612 } else {
09613
09614 f.frametype = AST_FRAME_NULL;
09615 f.subclass = 0;
09616 }
09617
09618 if (!fr->callno) {
09619 int check_dcallno = 0;
09620
09621
09622
09623
09624
09625
09626
09627
09628
09629 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) {
09630 check_dcallno = 1;
09631 }
09632
09633 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09634 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) {
09635 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09636 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) {
09637 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09638 }
09639 return 1;
09640 }
09641 }
09642
09643 if (fr->callno > 0)
09644 ast_mutex_lock(&iaxsl[fr->callno]);
09645
09646 if (!fr->callno || !iaxs[fr->callno]) {
09647
09648
09649 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09650
09651 if (((f.subclass != IAX_COMMAND_INVAL) &&
09652 (f.subclass != IAX_COMMAND_TXCNT) &&
09653 (f.subclass != IAX_COMMAND_TXACC) &&
09654 (f.subclass != IAX_COMMAND_FWDOWNL))||
09655 (f.frametype != AST_FRAME_IAX))
09656 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09657 fd);
09658 }
09659 if (fr->callno > 0)
09660 ast_mutex_unlock(&iaxsl[fr->callno]);
09661 return 1;
09662 }
09663 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
09664 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09665 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09666 ast_mutex_unlock(&iaxsl[fr->callno]);
09667 return 1;
09668 }
09669 decrypted = 1;
09670 }
09671 #ifdef DEBUG_SUPPORT
09672 if (decrypted) {
09673 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
09674 }
09675 #endif
09676
09677
09678 iaxs[fr->callno]->frames_received++;
09679
09680 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
09681 f.subclass != IAX_COMMAND_TXCNT &&
09682 f.subclass != IAX_COMMAND_TXACC) {
09683 unsigned short new_peercallno;
09684
09685 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
09686 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
09687 if (iaxs[fr->callno]->peercallno) {
09688 remove_by_peercallno(iaxs[fr->callno]);
09689 }
09690 iaxs[fr->callno]->peercallno = new_peercallno;
09691 store_by_peercallno(iaxs[fr->callno]);
09692 }
09693 }
09694 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09695 if (iaxdebug)
09696 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
09697
09698 fr->oseqno = fh->oseqno;
09699 fr->iseqno = fh->iseqno;
09700 fr->ts = ntohl(fh->ts);
09701 #ifdef IAXTESTS
09702 if (test_resync) {
09703 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
09704 fr->ts += test_resync;
09705 }
09706 #endif
09707 #if 0
09708 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
09709 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
09710 (f.subclass == IAX_COMMAND_NEW ||
09711 f.subclass == IAX_COMMAND_AUTHREQ ||
09712 f.subclass == IAX_COMMAND_ACCEPT ||
09713 f.subclass == IAX_COMMAND_REJECT)) ) )
09714 #endif
09715 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
09716 updatehistory = 0;
09717 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
09718 (iaxs[fr->callno]->iseqno ||
09719 ((f.subclass != IAX_COMMAND_TXCNT) &&
09720 (f.subclass != IAX_COMMAND_TXREADY) &&
09721 (f.subclass != IAX_COMMAND_TXREL) &&
09722 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09723 (f.subclass != IAX_COMMAND_TXACC)) ||
09724 (f.frametype != AST_FRAME_IAX))) {
09725 if (
09726 ((f.subclass != IAX_COMMAND_ACK) &&
09727 (f.subclass != IAX_COMMAND_INVAL) &&
09728 (f.subclass != IAX_COMMAND_TXCNT) &&
09729 (f.subclass != IAX_COMMAND_TXREADY) &&
09730 (f.subclass != IAX_COMMAND_TXREL) &&
09731 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09732 (f.subclass != IAX_COMMAND_TXACC) &&
09733 (f.subclass != IAX_COMMAND_VNAK)) ||
09734 (f.frametype != AST_FRAME_IAX)) {
09735
09736 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
09737 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
09738
09739
09740 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
09741
09742 if ((f.frametype != AST_FRAME_IAX) ||
09743 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
09744 ast_debug(1, "Acking anyway\n");
09745
09746
09747 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09748 }
09749 } else {
09750
09751 iax2_vnak(fr->callno);
09752 }
09753 ast_mutex_unlock(&iaxsl[fr->callno]);
09754 return 1;
09755 }
09756 } else {
09757
09758 if (((f.subclass != IAX_COMMAND_ACK) &&
09759 (f.subclass != IAX_COMMAND_INVAL) &&
09760 (f.subclass != IAX_COMMAND_TXCNT) &&
09761 (f.subclass != IAX_COMMAND_TXACC) &&
09762 (f.subclass != IAX_COMMAND_VNAK)) ||
09763 (f.frametype != AST_FRAME_IAX))
09764 iaxs[fr->callno]->iseqno++;
09765 }
09766
09767 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
09768 if (res < thread->buf_size)
09769 thread->buf[res++] = '\0';
09770 else
09771 thread->buf[res - 1] = '\0';
09772 }
09773
09774
09775
09776 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09777 ((f.subclass != IAX_COMMAND_INVAL) ||
09778 (f.frametype != AST_FRAME_IAX))) {
09779 unsigned char x;
09780 int call_to_destroy;
09781
09782 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
09783 x = fr->iseqno;
09784 else
09785 x = iaxs[fr->callno]->oseqno;
09786 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
09787
09788
09789 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
09790
09791 if (iaxdebug)
09792 ast_debug(1, "Cancelling transmission of packet %d\n", x);
09793 call_to_destroy = 0;
09794 AST_LIST_LOCK(&frame_queue);
09795 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09796
09797 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
09798 cur->retries = -1;
09799
09800 if (cur->final)
09801 call_to_destroy = fr->callno;
09802 }
09803 }
09804 AST_LIST_UNLOCK(&frame_queue);
09805 if (call_to_destroy) {
09806 if (iaxdebug)
09807 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
09808 ast_mutex_lock(&iaxsl[call_to_destroy]);
09809 iax2_destroy(call_to_destroy);
09810 ast_mutex_unlock(&iaxsl[call_to_destroy]);
09811 }
09812 }
09813
09814 if (iaxs[fr->callno])
09815 iaxs[fr->callno]->rseqno = fr->iseqno;
09816 else {
09817
09818 ast_mutex_unlock(&iaxsl[fr->callno]);
09819 return 1;
09820 }
09821 } else {
09822 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
09823 }
09824 }
09825 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09826 ((f.frametype != AST_FRAME_IAX) ||
09827 ((f.subclass != IAX_COMMAND_TXACC) &&
09828 (f.subclass != IAX_COMMAND_TXCNT)))) {
09829
09830 ast_mutex_unlock(&iaxsl[fr->callno]);
09831 return 1;
09832 }
09833
09834
09835
09836
09837 if ((f.frametype == AST_FRAME_VOICE) ||
09838 (f.frametype == AST_FRAME_VIDEO) ||
09839 (f.frametype == AST_FRAME_IAX)) {
09840 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
09841 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
09842 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
09843 ast_mutex_unlock(&iaxsl[fr->callno]);
09844 return 1;
09845 }
09846 }
09847
09848 if (ies.vars) {
09849 struct ast_datastore *variablestore = NULL;
09850 struct ast_variable *var, *prev = NULL;
09851 AST_LIST_HEAD(, ast_var_t) *varlist;
09852 if ((c = iaxs[fr->callno]->owner)) {
09853 varlist = ast_calloc(1, sizeof(*varlist));
09854 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09855
09856 if (variablestore && varlist) {
09857 variablestore->data = varlist;
09858 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09859 AST_LIST_HEAD_INIT(varlist);
09860 ast_debug(1, "I can haz IAX vars?\n");
09861 for (var = ies.vars; var; var = var->next) {
09862 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09863 if (prev) {
09864 ast_free(prev);
09865 }
09866 prev = var;
09867 if (!newvar) {
09868
09869 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09870 } else {
09871 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09872 }
09873 }
09874 if (prev) {
09875 ast_free(prev);
09876 }
09877 ies.vars = NULL;
09878 ast_channel_datastore_add(c, variablestore);
09879 } else {
09880 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09881 if (variablestore) {
09882 ast_datastore_free(variablestore);
09883 }
09884 if (varlist) {
09885 ast_free(varlist);
09886 }
09887 }
09888 } else {
09889
09890
09891 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
09892 for (var = ies.vars; var && var->next; var = var->next);
09893 if (var) {
09894 var->next = iaxs[fr->callno]->iaxvars;
09895 iaxs[fr->callno]->iaxvars = ies.vars;
09896 ies.vars = NULL;
09897 }
09898 }
09899 }
09900
09901 if (ies.vars) {
09902 ast_debug(1, "I have IAX variables, but they were not processed\n");
09903 }
09904 }
09905
09906
09907
09908 if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
09909 send_signaling(iaxs[fr->callno]);
09910 }
09911
09912 if (f.frametype == AST_FRAME_VOICE) {
09913 if (f.subclass != iaxs[fr->callno]->voiceformat) {
09914 iaxs[fr->callno]->voiceformat = f.subclass;
09915 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
09916 if (iaxs[fr->callno]->owner) {
09917 int orignative;
09918 retryowner:
09919 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
09920 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09921 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
09922 }
09923 if (iaxs[fr->callno]) {
09924 if (iaxs[fr->callno]->owner) {
09925 orignative = iaxs[fr->callno]->owner->nativeformats;
09926 iaxs[fr->callno]->owner->nativeformats = f.subclass;
09927 if (iaxs[fr->callno]->owner->readformat)
09928 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
09929 iaxs[fr->callno]->owner->nativeformats = orignative;
09930 ast_channel_unlock(iaxs[fr->callno]->owner);
09931 }
09932 } else {
09933 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
09934
09935 if (ies.vars) {
09936 ast_variables_destroy(ies.vars);
09937 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
09938 ies.vars = NULL;
09939 }
09940 ast_mutex_unlock(&iaxsl[fr->callno]);
09941 return 1;
09942 }
09943 }
09944 }
09945 }
09946 if (f.frametype == AST_FRAME_VIDEO) {
09947 if (f.subclass != iaxs[fr->callno]->videoformat) {
09948 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
09949 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
09950 }
09951 }
09952 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
09953 if (f.subclass == AST_CONTROL_BUSY) {
09954 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
09955 } else if (f.subclass == AST_CONTROL_CONGESTION) {
09956 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
09957 }
09958 }
09959 if (f.frametype == AST_FRAME_IAX) {
09960 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
09961
09962 if (iaxdebug)
09963 ast_debug(1, "IAX subclass %d received\n", f.subclass);
09964
09965
09966 if (iaxs[fr->callno]->last < fr->ts &&
09967 f.subclass != IAX_COMMAND_ACK &&
09968 f.subclass != IAX_COMMAND_PONG &&
09969 f.subclass != IAX_COMMAND_LAGRP) {
09970 iaxs[fr->callno]->last = fr->ts;
09971 if (iaxdebug)
09972 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09973 }
09974 iaxs[fr->callno]->last_iax_message = f.subclass;
09975 if (!iaxs[fr->callno]->first_iax_message) {
09976 iaxs[fr->callno]->first_iax_message = f.subclass;
09977 }
09978 switch(f.subclass) {
09979 case IAX_COMMAND_ACK:
09980
09981 break;
09982 case IAX_COMMAND_QUELCH:
09983 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09984
09985 if (iaxs[fr->callno]->owner) {
09986 manager_event(EVENT_FLAG_CALL, "Hold",
09987 "Status: On\r\n"
09988 "Channel: %s\r\n"
09989 "Uniqueid: %s\r\n",
09990 iaxs[fr->callno]->owner->name,
09991 iaxs[fr->callno]->owner->uniqueid);
09992 }
09993
09994 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
09995 if (ies.musiconhold) {
09996 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
09997 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
09998 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
09999 S_OR(moh_suggest, NULL),
10000 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10001 if (!iaxs[fr->callno]) {
10002 ast_mutex_unlock(&iaxsl[fr->callno]);
10003 return 1;
10004 }
10005 }
10006 }
10007 }
10008 break;
10009 case IAX_COMMAND_UNQUELCH:
10010 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10011
10012 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
10013 manager_event(EVENT_FLAG_CALL, "Hold",
10014 "Status: Off\r\n"
10015 "Channel: %s\r\n"
10016 "Uniqueid: %s\r\n",
10017 iaxs[fr->callno]->owner->name,
10018 iaxs[fr->callno]->owner->uniqueid);
10019 }
10020
10021 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
10022 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
10023 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10024 if (!iaxs[fr->callno]) {
10025 ast_mutex_unlock(&iaxsl[fr->callno]);
10026 return 1;
10027 }
10028 }
10029 }
10030 break;
10031 case IAX_COMMAND_TXACC:
10032 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10033
10034 AST_LIST_LOCK(&frame_queue);
10035 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10036
10037 if ((fr->callno == cur->callno) && (cur->transfer))
10038 cur->retries = -1;
10039 }
10040 AST_LIST_UNLOCK(&frame_queue);
10041 memset(&ied1, 0, sizeof(ied1));
10042 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10043 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10044 iaxs[fr->callno]->transferring = TRANSFER_READY;
10045 }
10046 break;
10047 case IAX_COMMAND_NEW:
10048
10049 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10050 break;
10051 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10052 ast_mutex_unlock(&iaxsl[fr->callno]);
10053 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10054 ast_mutex_lock(&iaxsl[fr->callno]);
10055 if (!iaxs[fr->callno]) {
10056 ast_mutex_unlock(&iaxsl[fr->callno]);
10057 return 1;
10058 }
10059 }
10060
10061 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
10062 int new_callno;
10063 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10064 fr->callno = new_callno;
10065 }
10066
10067 if (delayreject)
10068 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10069 if (check_access(fr->callno, &sin, &ies)) {
10070
10071 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10072 if (authdebug)
10073 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);
10074 break;
10075 }
10076 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10077 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10078 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10079 break;
10080 }
10081 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10082 const char *context, *exten, *cid_num;
10083
10084 context = ast_strdupa(iaxs[fr->callno]->context);
10085 exten = ast_strdupa(iaxs[fr->callno]->exten);
10086 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10087
10088
10089 ast_mutex_unlock(&iaxsl[fr->callno]);
10090 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10091 ast_mutex_lock(&iaxsl[fr->callno]);
10092
10093 if (!iaxs[fr->callno]) {
10094 ast_mutex_unlock(&iaxsl[fr->callno]);
10095 return 1;
10096 }
10097 } else
10098 exists = 0;
10099
10100 save_osptoken(fr, &ies);
10101 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10102 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10103 memset(&ied0, 0, sizeof(ied0));
10104 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10105 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10106 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10107 if (!iaxs[fr->callno]) {
10108 ast_mutex_unlock(&iaxsl[fr->callno]);
10109 return 1;
10110 }
10111 if (authdebug)
10112 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);
10113 } else {
10114
10115
10116 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10117 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10118 using_prefs = "reqonly";
10119 } else {
10120 using_prefs = "disabled";
10121 }
10122 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10123 memset(&pref, 0, sizeof(pref));
10124 strcpy(caller_pref_buf, "disabled");
10125 strcpy(host_pref_buf, "disabled");
10126 } else {
10127 using_prefs = "mine";
10128
10129 if (ies.codec_prefs)
10130 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10131 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10132
10133 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10134 pref = iaxs[fr->callno]->rprefs;
10135 using_prefs = "caller";
10136 } else {
10137 pref = iaxs[fr->callno]->prefs;
10138 }
10139 } else
10140 pref = iaxs[fr->callno]->prefs;
10141
10142 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10143 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10144 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10145 }
10146 if (!format) {
10147 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10148 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10149 if (!format) {
10150 memset(&ied0, 0, sizeof(ied0));
10151 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10152 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10153 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10154 if (!iaxs[fr->callno]) {
10155 ast_mutex_unlock(&iaxsl[fr->callno]);
10156 return 1;
10157 }
10158 if (authdebug) {
10159 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10160 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);
10161 else
10162 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);
10163 }
10164 } else {
10165
10166 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10167 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10168 format = 0;
10169 } else {
10170 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10171 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10172 memset(&pref, 0, sizeof(pref));
10173 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10174 strcpy(caller_pref_buf,"disabled");
10175 strcpy(host_pref_buf,"disabled");
10176 } else {
10177 using_prefs = "mine";
10178 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10179
10180 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10181 pref = iaxs[fr->callno]->prefs;
10182 } else {
10183 pref = iaxs[fr->callno]->rprefs;
10184 using_prefs = "caller";
10185 }
10186 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10187
10188 } else
10189 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10190 }
10191 }
10192
10193 if (!format) {
10194 memset(&ied0, 0, sizeof(ied0));
10195 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10196 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10197 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10198 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10199 if (!iaxs[fr->callno]) {
10200 ast_mutex_unlock(&iaxsl[fr->callno]);
10201 return 1;
10202 }
10203 if (authdebug)
10204 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);
10205 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10206 break;
10207 }
10208 }
10209 }
10210 if (format) {
10211
10212 memset(&ied1, 0, sizeof(ied1));
10213 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10214 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10215 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10216 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10217 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10218 "%srequested format = %s,\n"
10219 "%srequested prefs = %s,\n"
10220 "%sactual format = %s,\n"
10221 "%shost prefs = %s,\n"
10222 "%spriority = %s\n",
10223 ast_inet_ntoa(sin.sin_addr),
10224 VERBOSE_PREFIX_4,
10225 ast_getformatname(iaxs[fr->callno]->peerformat),
10226 VERBOSE_PREFIX_4,
10227 caller_pref_buf,
10228 VERBOSE_PREFIX_4,
10229 ast_getformatname(format),
10230 VERBOSE_PREFIX_4,
10231 host_pref_buf,
10232 VERBOSE_PREFIX_4,
10233 using_prefs);
10234
10235 iaxs[fr->callno]->chosenformat = format;
10236 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
10237 } else {
10238 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10239
10240 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10241 }
10242 }
10243 }
10244 break;
10245 }
10246 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10247 merge_encryption(iaxs[fr->callno],ies.encmethods);
10248 else
10249 iaxs[fr->callno]->encmethods = 0;
10250 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10251 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10252 if (!iaxs[fr->callno]) {
10253 ast_mutex_unlock(&iaxsl[fr->callno]);
10254 return 1;
10255 }
10256 break;
10257 case IAX_COMMAND_DPREQ:
10258
10259 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10260 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10261 if (iaxcompat) {
10262
10263 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10264 } else {
10265
10266 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10267 }
10268 }
10269 break;
10270 case IAX_COMMAND_HANGUP:
10271 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10272 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10273
10274 if (ies.causecode && iaxs[fr->callno]->owner)
10275 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10276
10277 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10278 iax2_destroy(fr->callno);
10279 break;
10280 case IAX_COMMAND_REJECT:
10281
10282 if (ies.causecode && iaxs[fr->callno]->owner)
10283 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10284
10285 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10286 if (iaxs[fr->callno]->owner && authdebug)
10287 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10288 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10289 ies.cause ? ies.cause : "<Unknown>");
10290 ast_debug(1, "Immediately destroying %d, having received reject\n",
10291 fr->callno);
10292 }
10293
10294 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10295 fr->ts, NULL, 0, fr->iseqno);
10296 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
10297 iaxs[fr->callno]->error = EPERM;
10298 iax2_destroy(fr->callno);
10299 break;
10300 case IAX_COMMAND_TRANSFER:
10301 {
10302 struct ast_channel *bridged_chan;
10303
10304 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
10305
10306
10307 ast_mutex_unlock(&iaxsl[fr->callno]);
10308 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
10309 ast_mutex_lock(&iaxsl[fr->callno]);
10310 if (!iaxs[fr->callno]) {
10311 ast_mutex_unlock(&iaxsl[fr->callno]);
10312 return 1;
10313 }
10314
10315 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
10316 if (!strcmp(ies.called_number, ast_parking_ext())) {
10317 struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
10318 ast_mutex_unlock(&iaxsl[fr->callno]);
10319 if (iax_park(bridged_chan, saved_channel)) {
10320 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
10321 } else {
10322 ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
10323 }
10324 ast_mutex_lock(&iaxsl[fr->callno]);
10325 } else {
10326 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
10327 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
10328 ies.called_number, iaxs[fr->callno]->context);
10329 else {
10330 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
10331 ies.called_number, iaxs[fr->callno]->context);
10332 }
10333 }
10334 } else {
10335 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10336 }
10337
10338 break;
10339 }
10340 case IAX_COMMAND_ACCEPT:
10341
10342 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10343 break;
10344 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10345
10346 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10347 iax2_destroy(fr->callno);
10348 break;
10349 }
10350 if (ies.format) {
10351 iaxs[fr->callno]->peerformat = ies.format;
10352 } else {
10353 if (iaxs[fr->callno]->owner)
10354 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10355 else
10356 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10357 }
10358 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));
10359 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10360 memset(&ied0, 0, sizeof(ied0));
10361 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10362 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10363 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10364 if (!iaxs[fr->callno]) {
10365 ast_mutex_unlock(&iaxsl[fr->callno]);
10366 return 1;
10367 }
10368 if (authdebug)
10369 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);
10370 } else {
10371 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10372 if (iaxs[fr->callno]->owner) {
10373
10374 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10375 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10376 retryowner2:
10377 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
10378 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
10379 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
10380 }
10381
10382 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10383
10384 if (iaxs[fr->callno]->owner->writeformat)
10385 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10386 if (iaxs[fr->callno]->owner->readformat)
10387 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10388 ast_channel_unlock(iaxs[fr->callno]->owner);
10389 }
10390 }
10391 }
10392 if (iaxs[fr->callno]) {
10393 AST_LIST_LOCK(&dpcache);
10394 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10395 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10396 iax2_dprequest(dp, fr->callno);
10397 AST_LIST_UNLOCK(&dpcache);
10398 }
10399 break;
10400 case IAX_COMMAND_POKE:
10401
10402 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10403 if (!iaxs[fr->callno]) {
10404 ast_mutex_unlock(&iaxsl[fr->callno]);
10405 return 1;
10406 }
10407 break;
10408 case IAX_COMMAND_PING:
10409 {
10410 struct iax_ie_data pingied;
10411 construct_rr(iaxs[fr->callno], &pingied);
10412
10413 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10414 }
10415 break;
10416 case IAX_COMMAND_PONG:
10417
10418 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10419
10420 save_rr(fr, &ies);
10421
10422
10423 log_jitterstats(fr->callno);
10424
10425 if (iaxs[fr->callno]->peerpoke) {
10426 peer = iaxs[fr->callno]->peerpoke;
10427 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10428 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10429 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10430 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);
10431 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10432 }
10433 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10434 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10435 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10436 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);
10437 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10438 }
10439 }
10440 peer->lastms = iaxs[fr->callno]->pingtime;
10441 if (peer->smoothing && (peer->lastms > -1))
10442 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10443 else if (peer->smoothing && peer->lastms < 0)
10444 peer->historicms = (0 + peer->historicms) / 2;
10445 else
10446 peer->historicms = iaxs[fr->callno]->pingtime;
10447
10448
10449 if (peer->pokeexpire > -1) {
10450 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10451 peer_unref(peer);
10452 peer->pokeexpire = -1;
10453 }
10454 }
10455
10456 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10457 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10458 else
10459 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10460 if (peer->pokeexpire == -1)
10461 peer_unref(peer);
10462
10463 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10464
10465 iax2_destroy(fr->callno);
10466 peer->callno = 0;
10467 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10468 }
10469 break;
10470 case IAX_COMMAND_LAGRQ:
10471 case IAX_COMMAND_LAGRP:
10472 f.src = "LAGRQ";
10473 f.mallocd = 0;
10474 f.offset = 0;
10475 f.samples = 0;
10476 iax_frame_wrap(fr, &f);
10477 if(f.subclass == IAX_COMMAND_LAGRQ) {
10478
10479 fr->af.subclass = IAX_COMMAND_LAGRP;
10480 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10481 } else {
10482
10483 unsigned int ts;
10484
10485 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10486 iaxs[fr->callno]->lag = ts - fr->ts;
10487 if (iaxdebug)
10488 ast_debug(1, "Peer %s lag measured as %dms\n",
10489 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10490 }
10491 break;
10492 case IAX_COMMAND_AUTHREQ:
10493 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10494 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>");
10495 break;
10496 }
10497 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10498 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10499 .subclass = AST_CONTROL_HANGUP,
10500 };
10501 ast_log(LOG_WARNING,
10502 "I don't know how to authenticate %s to %s\n",
10503 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10504 iax2_queue_frame(fr->callno, &hangup_fr);
10505 }
10506 if (!iaxs[fr->callno]) {
10507 ast_mutex_unlock(&iaxsl[fr->callno]);
10508 return 1;
10509 }
10510 break;
10511 case IAX_COMMAND_AUTHREP:
10512
10513 if (delayreject)
10514 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10515
10516 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10517 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>");
10518 break;
10519 }
10520 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10521 if (authdebug)
10522 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);
10523 memset(&ied0, 0, sizeof(ied0));
10524 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10525 break;
10526 }
10527 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10528
10529 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10530 } else
10531 exists = 0;
10532 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10533 if (authdebug)
10534 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);
10535 memset(&ied0, 0, sizeof(ied0));
10536 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10537 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10538 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10539 if (!iaxs[fr->callno]) {
10540 ast_mutex_unlock(&iaxsl[fr->callno]);
10541 return 1;
10542 }
10543 } else {
10544
10545 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10546 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10547 using_prefs = "reqonly";
10548 } else {
10549 using_prefs = "disabled";
10550 }
10551 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10552 memset(&pref, 0, sizeof(pref));
10553 strcpy(caller_pref_buf, "disabled");
10554 strcpy(host_pref_buf, "disabled");
10555 } else {
10556 using_prefs = "mine";
10557 if (ies.codec_prefs)
10558 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10559 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10560 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10561 pref = iaxs[fr->callno]->rprefs;
10562 using_prefs = "caller";
10563 } else {
10564 pref = iaxs[fr->callno]->prefs;
10565 }
10566 } else
10567 pref = iaxs[fr->callno]->prefs;
10568
10569 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10570 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10571 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10572 }
10573 if (!format) {
10574 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10575 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);
10576 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10577 }
10578 if (!format) {
10579 if (authdebug) {
10580 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10581 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);
10582 else
10583 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);
10584 }
10585 memset(&ied0, 0, sizeof(ied0));
10586 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10587 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10588 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10589 if (!iaxs[fr->callno]) {
10590 ast_mutex_unlock(&iaxsl[fr->callno]);
10591 return 1;
10592 }
10593 } else {
10594
10595 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10596 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10597 format = 0;
10598 } else {
10599 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10600 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10601 memset(&pref, 0, sizeof(pref));
10602 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10603 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10604 strcpy(caller_pref_buf,"disabled");
10605 strcpy(host_pref_buf,"disabled");
10606 } else {
10607 using_prefs = "mine";
10608 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10609
10610 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10611 pref = iaxs[fr->callno]->prefs;
10612 } else {
10613 pref = iaxs[fr->callno]->rprefs;
10614 using_prefs = "caller";
10615 }
10616 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10617 } else
10618 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10619 }
10620 }
10621 if (!format) {
10622 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10623 if (authdebug) {
10624 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10625 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);
10626 else
10627 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);
10628 }
10629 memset(&ied0, 0, sizeof(ied0));
10630 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10631 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10632 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10633 if (!iaxs[fr->callno]) {
10634 ast_mutex_unlock(&iaxsl[fr->callno]);
10635 return 1;
10636 }
10637 }
10638 }
10639 }
10640 if (format) {
10641
10642 memset(&ied1, 0, sizeof(ied1));
10643 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10644 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10645 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10646 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10647 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
10648 "%srequested format = %s,\n"
10649 "%srequested prefs = %s,\n"
10650 "%sactual format = %s,\n"
10651 "%shost prefs = %s,\n"
10652 "%spriority = %s\n",
10653 ast_inet_ntoa(sin.sin_addr),
10654 VERBOSE_PREFIX_4,
10655 ast_getformatname(iaxs[fr->callno]->peerformat),
10656 VERBOSE_PREFIX_4,
10657 caller_pref_buf,
10658 VERBOSE_PREFIX_4,
10659 ast_getformatname(format),
10660 VERBOSE_PREFIX_4,
10661 host_pref_buf,
10662 VERBOSE_PREFIX_4,
10663 using_prefs);
10664
10665 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10666 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
10667 iax2_destroy(fr->callno);
10668 else if (ies.vars) {
10669 struct ast_datastore *variablestore;
10670 struct ast_variable *var, *prev = NULL;
10671 AST_LIST_HEAD(, ast_var_t) *varlist;
10672 varlist = ast_calloc(1, sizeof(*varlist));
10673 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10674 if (variablestore && varlist) {
10675 variablestore->data = varlist;
10676 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10677 AST_LIST_HEAD_INIT(varlist);
10678 ast_debug(1, "I can haz IAX vars? w00t\n");
10679 for (var = ies.vars; var; var = var->next) {
10680 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10681 if (prev)
10682 ast_free(prev);
10683 prev = var;
10684 if (!newvar) {
10685
10686 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10687 } else {
10688 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10689 }
10690 }
10691 if (prev)
10692 ast_free(prev);
10693 ies.vars = NULL;
10694 ast_channel_datastore_add(c, variablestore);
10695 } else {
10696 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10697 if (variablestore)
10698 ast_datastore_free(variablestore);
10699 if (varlist)
10700 ast_free(varlist);
10701 }
10702 }
10703 } else {
10704 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10705
10706 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10707 if (ast_test_flag(iaxs[fr->callno], IAX_IMMEDIATE)) {
10708 goto immediatedial;
10709 }
10710 }
10711 }
10712 }
10713 break;
10714 case IAX_COMMAND_DIAL:
10715 immediatedial:
10716 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
10717 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10718 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
10719 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
10720 if (authdebug)
10721 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);
10722 memset(&ied0, 0, sizeof(ied0));
10723 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10724 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10725 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10726 if (!iaxs[fr->callno]) {
10727 ast_mutex_unlock(&iaxsl[fr->callno]);
10728 return 1;
10729 }
10730 } else {
10731 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10732 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
10733 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10734 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
10735 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
10736 iax2_destroy(fr->callno);
10737 else if (ies.vars) {
10738 struct ast_datastore *variablestore;
10739 struct ast_variable *var, *prev = NULL;
10740 AST_LIST_HEAD(, ast_var_t) *varlist;
10741 varlist = ast_calloc(1, sizeof(*varlist));
10742 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10743 ast_debug(1, "I can haz IAX vars? w00t\n");
10744 if (variablestore && varlist) {
10745 variablestore->data = varlist;
10746 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10747 AST_LIST_HEAD_INIT(varlist);
10748 for (var = ies.vars; var; var = var->next) {
10749 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10750 if (prev)
10751 ast_free(prev);
10752 prev = var;
10753 if (!newvar) {
10754
10755 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10756 } else {
10757 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10758 }
10759 }
10760 if (prev)
10761 ast_free(prev);
10762 ies.vars = NULL;
10763 ast_channel_datastore_add(c, variablestore);
10764 } else {
10765 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10766 if (variablestore)
10767 ast_datastore_free(variablestore);
10768 if (varlist)
10769 ast_free(varlist);
10770 }
10771 }
10772 }
10773 }
10774 break;
10775 case IAX_COMMAND_INVAL:
10776 iaxs[fr->callno]->error = ENOTCONN;
10777 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
10778 iax2_destroy(fr->callno);
10779 ast_debug(1, "Destroying call %d\n", fr->callno);
10780 break;
10781 case IAX_COMMAND_VNAK:
10782 ast_debug(1, "Received VNAK: resending outstanding frames\n");
10783
10784 vnak_retransmit(fr->callno, fr->iseqno);
10785 break;
10786 case IAX_COMMAND_REGREQ:
10787 case IAX_COMMAND_REGREL:
10788
10789 if (delayreject)
10790 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10791 if (register_verify(fr->callno, &sin, &ies)) {
10792 if (!iaxs[fr->callno]) {
10793 ast_mutex_unlock(&iaxsl[fr->callno]);
10794 return 1;
10795 }
10796
10797 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
10798 break;
10799 }
10800 if (!iaxs[fr->callno]) {
10801 ast_mutex_unlock(&iaxsl[fr->callno]);
10802 return 1;
10803 }
10804 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
10805 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
10806
10807 if (f.subclass == IAX_COMMAND_REGREL)
10808 memset(&sin, 0, sizeof(sin));
10809 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
10810 ast_log(LOG_WARNING, "Registry error\n");
10811 if (!iaxs[fr->callno]) {
10812 ast_mutex_unlock(&iaxsl[fr->callno]);
10813 return 1;
10814 }
10815 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10816 ast_mutex_unlock(&iaxsl[fr->callno]);
10817 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10818 ast_mutex_lock(&iaxsl[fr->callno]);
10819 if (!iaxs[fr->callno]) {
10820 ast_mutex_unlock(&iaxsl[fr->callno]);
10821 return 1;
10822 }
10823 }
10824 break;
10825 }
10826 registry_authrequest(fr->callno);
10827 if (!iaxs[fr->callno]) {
10828 ast_mutex_unlock(&iaxsl[fr->callno]);
10829 return 1;
10830 }
10831 break;
10832 case IAX_COMMAND_REGACK:
10833 if (iax2_ack_registry(&ies, &sin, fr->callno))
10834 ast_log(LOG_WARNING, "Registration failure\n");
10835
10836 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10837 iax2_destroy(fr->callno);
10838 break;
10839 case IAX_COMMAND_REGREJ:
10840 if (iaxs[fr->callno]->reg) {
10841 if (authdebug) {
10842 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));
10843 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>");
10844 }
10845 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
10846 }
10847
10848 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10849 iax2_destroy(fr->callno);
10850 break;
10851 case IAX_COMMAND_REGAUTH:
10852
10853 if (registry_rerequest(&ies, fr->callno, &sin)) {
10854 memset(&ied0, 0, sizeof(ied0));
10855 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
10856 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
10857 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10858 if (!iaxs[fr->callno]) {
10859 ast_mutex_unlock(&iaxsl[fr->callno]);
10860 return 1;
10861 }
10862 }
10863 break;
10864 case IAX_COMMAND_TXREJ:
10865 iaxs[fr->callno]->transferring = 0;
10866 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10867 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
10868 if (iaxs[fr->callno]->bridgecallno) {
10869 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
10870 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
10871 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
10872 }
10873 }
10874 break;
10875 case IAX_COMMAND_TXREADY:
10876 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
10877 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
10878 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
10879 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
10880 else
10881 iaxs[fr->callno]->transferring = TRANSFER_READY;
10882 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10883 if (iaxs[fr->callno]->bridgecallno) {
10884 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
10885 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
10886
10887 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
10888 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10889 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10890
10891 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
10892 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
10893
10894 memset(&ied0, 0, sizeof(ied0));
10895 memset(&ied1, 0, sizeof(ied1));
10896 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10897 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10898 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
10899 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
10900 } else {
10901 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10902 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10903
10904 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
10905 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
10906 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
10907 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10908
10909
10910 stop_stuff(fr->callno);
10911 stop_stuff(iaxs[fr->callno]->bridgecallno);
10912
10913 memset(&ied0, 0, sizeof(ied0));
10914 memset(&ied1, 0, sizeof(ied1));
10915 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10916 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10917 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
10918 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
10919 }
10920
10921 }
10922 }
10923 }
10924 break;
10925 case IAX_COMMAND_TXREQ:
10926 try_transfer(iaxs[fr->callno], &ies);
10927 break;
10928 case IAX_COMMAND_TXCNT:
10929 if (iaxs[fr->callno]->transferring)
10930 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
10931 break;
10932 case IAX_COMMAND_TXREL:
10933
10934 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10935 complete_transfer(fr->callno, &ies);
10936 stop_stuff(fr->callno);
10937 break;
10938 case IAX_COMMAND_TXMEDIA:
10939 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
10940 AST_LIST_LOCK(&frame_queue);
10941 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10942
10943 if ((fr->callno == cur->callno) && (cur->transfer))
10944 cur->retries = -1;
10945 }
10946 AST_LIST_UNLOCK(&frame_queue);
10947
10948 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
10949 }
10950 break;
10951 case IAX_COMMAND_RTKEY:
10952 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
10953 ast_log(LOG_WARNING,
10954 "we've been told to rotate our encryption key, "
10955 "but this isn't an encrypted call. bad things will happen.\n"
10956 );
10957 break;
10958 }
10959
10960 IAX_DEBUGDIGEST("Receiving", ies.challenge);
10961
10962 ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
10963 break;
10964 case IAX_COMMAND_DPREP:
10965 complete_dpreply(iaxs[fr->callno], &ies);
10966 break;
10967 case IAX_COMMAND_UNSUPPORT:
10968 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
10969 break;
10970 case IAX_COMMAND_FWDOWNL:
10971
10972 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
10973 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
10974 break;
10975 }
10976 memset(&ied0, 0, sizeof(ied0));
10977 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
10978 if (res < 0)
10979 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10980 else if (res > 0)
10981 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
10982 else
10983 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
10984 if (!iaxs[fr->callno]) {
10985 ast_mutex_unlock(&iaxsl[fr->callno]);
10986 return 1;
10987 }
10988 break;
10989 case IAX_COMMAND_CALLTOKEN:
10990 {
10991 struct iax_frame *cur;
10992 int found = 0;
10993 AST_LIST_LOCK(&frame_queue);
10994 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10995
10996
10997
10998 if (cur->callno == fr->callno) {
10999 found = 1;
11000 break;
11001 }
11002 }
11003 AST_LIST_UNLOCK(&frame_queue);
11004
11005
11006 if (cur && found && ies.calltoken && ies.calltokendata) {
11007 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11008 }
11009 break;
11010 }
11011 default:
11012 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
11013 memset(&ied0, 0, sizeof(ied0));
11014 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
11015 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11016 }
11017
11018 if (ies.vars) {
11019 ast_variables_destroy(ies.vars);
11020 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11021 ies.vars = NULL;
11022 }
11023
11024
11025 if ((f.subclass != IAX_COMMAND_ACK) &&
11026 (f.subclass != IAX_COMMAND_TXCNT) &&
11027 (f.subclass != IAX_COMMAND_TXACC) &&
11028 (f.subclass != IAX_COMMAND_INVAL) &&
11029 (f.subclass != IAX_COMMAND_VNAK)) {
11030 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11031 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11032 }
11033 ast_mutex_unlock(&iaxsl[fr->callno]);
11034 return 1;
11035 }
11036
11037 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11038 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11039 } else if (minivid) {
11040 f.frametype = AST_FRAME_VIDEO;
11041 if (iaxs[fr->callno]->videoformat > 0)
11042 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
11043 else {
11044 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11045 iax2_vnak(fr->callno);
11046 ast_mutex_unlock(&iaxsl[fr->callno]);
11047 return 1;
11048 }
11049 f.datalen = res - sizeof(*vh);
11050 if (f.datalen)
11051 f.data.ptr = thread->buf + sizeof(*vh);
11052 else
11053 f.data.ptr = NULL;
11054 #ifdef IAXTESTS
11055 if (test_resync) {
11056 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11057 } else
11058 #endif
11059 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11060 } else {
11061
11062 f.frametype = AST_FRAME_VOICE;
11063 if (iaxs[fr->callno]->voiceformat > 0)
11064 f.subclass = iaxs[fr->callno]->voiceformat;
11065 else {
11066 ast_debug(1, "Received mini frame before first full voice frame\n");
11067 iax2_vnak(fr->callno);
11068 ast_mutex_unlock(&iaxsl[fr->callno]);
11069 return 1;
11070 }
11071 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11072 if (f.datalen < 0) {
11073 ast_log(LOG_WARNING, "Datalen < 0?\n");
11074 ast_mutex_unlock(&iaxsl[fr->callno]);
11075 return 1;
11076 }
11077 if (f.datalen)
11078 f.data.ptr = thread->buf + sizeof(*mh);
11079 else
11080 f.data.ptr = NULL;
11081 #ifdef IAXTESTS
11082 if (test_resync) {
11083 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11084 } else
11085 #endif
11086 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11087
11088 }
11089
11090 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11091 ast_mutex_unlock(&iaxsl[fr->callno]);
11092 return 1;
11093 }
11094
11095 f.src = "IAX2";
11096 f.mallocd = 0;
11097 f.offset = 0;
11098 f.len = 0;
11099 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11100 f.samples = ast_codec_get_samples(&f);
11101
11102 if (f.subclass == AST_FORMAT_SLINEAR)
11103 ast_frame_byteswap_be(&f);
11104 } else
11105 f.samples = 0;
11106 iax_frame_wrap(fr, &f);
11107
11108
11109 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11110
11111 fr->outoforder = 0;
11112 } else {
11113 if (iaxdebug && iaxs[fr->callno])
11114 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);
11115 fr->outoforder = -1;
11116 }
11117 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11118 duped_fr = iaxfrdup2(fr);
11119 if (duped_fr) {
11120 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11121 }
11122 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11123 iaxs[fr->callno]->last = fr->ts;
11124 #if 1
11125 if (iaxdebug)
11126 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11127 #endif
11128 }
11129
11130
11131 ast_mutex_unlock(&iaxsl[fr->callno]);
11132 return 1;
11133 }
11134
11135
11136 static void iax2_process_thread_cleanup(void *data)
11137 {
11138 struct iax2_thread *thread = data;
11139 ast_mutex_destroy(&thread->lock);
11140 ast_cond_destroy(&thread->cond);
11141 ast_mutex_destroy(&thread->init_lock);
11142 ast_cond_destroy(&thread->init_cond);
11143 ast_free(thread);
11144 ast_atomic_dec_and_test(&iaxactivethreadcount);
11145 }
11146
11147 static void *iax2_process_thread(void *data)
11148 {
11149 struct iax2_thread *thread = data;
11150 struct timeval wait;
11151 struct timespec ts;
11152 int put_into_idle = 0;
11153 int first_time = 1;
11154 int old_state;
11155
11156 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11157
11158 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11159 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11160
11161 for (;;) {
11162
11163 ast_mutex_lock(&thread->lock);
11164
11165 if (thread->stop) {
11166 ast_mutex_unlock(&thread->lock);
11167 break;
11168 }
11169
11170
11171 if (first_time) {
11172 signal_condition(&thread->init_lock, &thread->init_cond);
11173 first_time = 0;
11174 }
11175
11176
11177 if (put_into_idle) {
11178 insert_idle_thread(thread);
11179 }
11180
11181 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11182 struct iax2_thread *t = NULL;
11183
11184 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11185 ts.tv_sec = wait.tv_sec;
11186 ts.tv_nsec = wait.tv_usec * 1000;
11187 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11188
11189
11190 if (!put_into_idle || thread->stop) {
11191 ast_mutex_unlock(&thread->lock);
11192 break;
11193 }
11194 AST_LIST_LOCK(&dynamic_list);
11195
11196 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11197 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11198 AST_LIST_UNLOCK(&dynamic_list);
11199 if (t) {
11200
11201
11202
11203 ast_mutex_unlock(&thread->lock);
11204 break;
11205 }
11206
11207
11208
11209 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11210 ts.tv_sec = wait.tv_sec;
11211 ts.tv_nsec = wait.tv_usec * 1000;
11212 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11213 ast_mutex_unlock(&thread->lock);
11214 break;
11215 }
11216 }
11217 } else {
11218 ast_cond_wait(&thread->cond, &thread->lock);
11219 }
11220
11221
11222 put_into_idle = 1;
11223
11224 ast_mutex_unlock(&thread->lock);
11225
11226 if (thread->stop) {
11227 break;
11228 }
11229
11230 if (thread->iostate == IAX_IOSTATE_IDLE)
11231 continue;
11232
11233
11234 switch (thread->iostate) {
11235 case IAX_IOSTATE_READY:
11236 thread->actions++;
11237 thread->iostate = IAX_IOSTATE_PROCESSING;
11238 socket_process(thread);
11239 handle_deferred_full_frames(thread);
11240 break;
11241 case IAX_IOSTATE_SCHEDREADY:
11242 thread->actions++;
11243 thread->iostate = IAX_IOSTATE_PROCESSING;
11244 #ifdef SCHED_MULTITHREADED
11245 thread->schedfunc(thread->scheddata);
11246 #endif
11247 default:
11248 break;
11249 }
11250 time(&thread->checktime);
11251 thread->iostate = IAX_IOSTATE_IDLE;
11252 #ifdef DEBUG_SCHED_MULTITHREAD
11253 thread->curfunc[0]='\0';
11254 #endif
11255
11256
11257
11258
11259 AST_LIST_LOCK(&active_list);
11260 AST_LIST_REMOVE(&active_list, thread, list);
11261 AST_LIST_UNLOCK(&active_list);
11262
11263
11264 handle_deferred_full_frames(thread);
11265 }
11266
11267
11268
11269
11270
11271 AST_LIST_LOCK(&idle_list);
11272 AST_LIST_REMOVE(&idle_list, thread, list);
11273 AST_LIST_UNLOCK(&idle_list);
11274
11275 AST_LIST_LOCK(&dynamic_list);
11276 AST_LIST_REMOVE(&dynamic_list, thread, list);
11277 AST_LIST_UNLOCK(&dynamic_list);
11278
11279
11280
11281
11282 pthread_cleanup_pop(1);
11283 return NULL;
11284 }
11285
11286 static int iax2_do_register(struct iax2_registry *reg)
11287 {
11288 struct iax_ie_data ied;
11289 if (iaxdebug)
11290 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11291
11292 if (reg->dnsmgr &&
11293 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
11294
11295 ast_dnsmgr_refresh(reg->dnsmgr);
11296 }
11297
11298
11299
11300
11301
11302 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11303 int callno = reg->callno;
11304 ast_mutex_lock(&iaxsl[callno]);
11305 iax2_destroy(callno);
11306 ast_mutex_unlock(&iaxsl[callno]);
11307 reg->callno = 0;
11308 }
11309 if (!reg->addr.sin_addr.s_addr) {
11310 if (iaxdebug)
11311 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11312
11313 reg->expire = iax2_sched_replace(reg->expire, sched,
11314 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11315 return -1;
11316 }
11317
11318 if (!reg->callno) {
11319 ast_debug(3, "Allocate call number\n");
11320 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
11321 if (reg->callno < 1) {
11322 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11323 return -1;
11324 } else
11325 ast_debug(3, "Registration created on call %d\n", reg->callno);
11326 iaxs[reg->callno]->reg = reg;
11327 ast_mutex_unlock(&iaxsl[reg->callno]);
11328 }
11329
11330 reg->expire = iax2_sched_replace(reg->expire, sched,
11331 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11332
11333 memset(&ied, 0, sizeof(ied));
11334 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11335 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11336 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11337 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11338 reg->regstate = REG_STATE_REGSENT;
11339 return 0;
11340 }
11341
11342 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
11343 {
11344
11345
11346 struct iax_ie_data provdata;
11347 struct iax_ie_data ied;
11348 unsigned int sig;
11349 struct sockaddr_in sin;
11350 int callno;
11351 struct create_addr_info cai;
11352
11353 memset(&cai, 0, sizeof(cai));
11354
11355 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11356
11357 if (iax_provision_build(&provdata, &sig, template, force)) {
11358 ast_debug(1, "No provisioning found for template '%s'\n", template);
11359 return 0;
11360 }
11361
11362 if (end) {
11363 memcpy(&sin, end, sizeof(sin));
11364 cai.sockfd = sockfd;
11365 } else if (create_addr(dest, NULL, &sin, &cai))
11366 return -1;
11367
11368
11369 memset(&ied, 0, sizeof(ied));
11370 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11371
11372 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11373 if (!callno)
11374 return -1;
11375
11376 if (iaxs[callno]) {
11377
11378 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11379 sched, 15000, auto_hangup, (void *)(long)callno);
11380 ast_set_flag(iaxs[callno], IAX_PROVISION);
11381
11382 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11383 }
11384 ast_mutex_unlock(&iaxsl[callno]);
11385
11386 return 1;
11387 }
11388
11389 static char *papp = "IAX2Provision";
11390
11391
11392
11393
11394 static int iax2_prov_app(struct ast_channel *chan, void *data)
11395 {
11396 int res;
11397 char *sdata;
11398 char *opts;
11399 int force =0;
11400 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11401 if (ast_strlen_zero(data))
11402 data = "default";
11403 sdata = ast_strdupa(data);
11404 opts = strchr(sdata, '|');
11405 if (opts)
11406 *opts='\0';
11407
11408 if (chan->tech != &iax2_tech) {
11409 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11410 return -1;
11411 }
11412 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11413 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11414 return -1;
11415 }
11416 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11417 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11418 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11419 sdata, res);
11420 return res;
11421 }
11422
11423 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11424 {
11425 int force = 0;
11426 int res;
11427
11428 switch (cmd) {
11429 case CLI_INIT:
11430 e->command = "iax2 provision";
11431 e->usage =
11432 "Usage: iax2 provision <host> <template> [forced]\n"
11433 " Provisions the given peer or IP address using a template\n"
11434 " matching either 'template' or '*' if the template is not\n"
11435 " found. If 'forced' is specified, even empty provisioning\n"
11436 " fields will be provisioned as empty fields.\n";
11437 return NULL;
11438 case CLI_GENERATE:
11439 if (a->pos == 3)
11440 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11441 return NULL;
11442 }
11443
11444 if (a->argc < 4)
11445 return CLI_SHOWUSAGE;
11446 if (a->argc > 4) {
11447 if (!strcasecmp(a->argv[4], "forced"))
11448 force = 1;
11449 else
11450 return CLI_SHOWUSAGE;
11451 }
11452 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11453 if (res < 0)
11454 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11455 else if (res < 1)
11456 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11457 else
11458 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11459 return CLI_SUCCESS;
11460 }
11461
11462 static void __iax2_poke_noanswer(const void *data)
11463 {
11464 struct iax2_peer *peer = (struct iax2_peer *)data;
11465 int callno;
11466
11467 if (peer->lastms > -1) {
11468 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11469 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11470 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11471 }
11472 if ((callno = peer->callno) > 0) {
11473 ast_mutex_lock(&iaxsl[callno]);
11474 iax2_destroy(callno);
11475 ast_mutex_unlock(&iaxsl[callno]);
11476 }
11477 peer->callno = 0;
11478 peer->lastms = -1;
11479
11480 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11481 if (peer->pokeexpire == -1)
11482 peer_unref(peer);
11483 }
11484
11485 static int iax2_poke_noanswer(const void *data)
11486 {
11487 struct iax2_peer *peer = (struct iax2_peer *)data;
11488 peer->pokeexpire = -1;
11489 #ifdef SCHED_MULTITHREADED
11490 if (schedule_action(__iax2_poke_noanswer, data))
11491 #endif
11492 __iax2_poke_noanswer(data);
11493 peer_unref(peer);
11494 return 0;
11495 }
11496
11497 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11498 {
11499 struct iax2_peer *peer = obj;
11500
11501 iax2_poke_peer(peer, 0);
11502
11503 return 0;
11504 }
11505
11506 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11507 {
11508 int callno;
11509 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
11510
11511
11512 peer->lastms = 0;
11513 peer->historicms = 0;
11514 peer->pokeexpire = -1;
11515 peer->callno = 0;
11516 return 0;
11517 }
11518
11519
11520 if ((callno = peer->callno) > 0) {
11521 ast_log(LOG_NOTICE, "Still have a callno...\n");
11522 ast_mutex_lock(&iaxsl[callno]);
11523 iax2_destroy(callno);
11524 ast_mutex_unlock(&iaxsl[callno]);
11525 }
11526 if (heldcall)
11527 ast_mutex_unlock(&iaxsl[heldcall]);
11528 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
11529 if (heldcall)
11530 ast_mutex_lock(&iaxsl[heldcall]);
11531 if (peer->callno < 1) {
11532 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11533 return -1;
11534 }
11535
11536
11537 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11538 iaxs[peer->callno]->peerpoke = peer;
11539
11540 if (peer->pokeexpire > -1) {
11541 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
11542 peer->pokeexpire = -1;
11543 peer_unref(peer);
11544 }
11545 }
11546
11547
11548
11549 if (peer->lastms < 0)
11550 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11551 else
11552 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11553
11554 if (peer->pokeexpire == -1)
11555 peer_unref(peer);
11556
11557
11558 ast_mutex_lock(&iaxsl[callno]);
11559 if (iaxs[callno]) {
11560 struct iax_ie_data ied = {
11561 .buf = { 0 },
11562 .pos = 0,
11563 };
11564 add_empty_calltoken_ie(iaxs[callno], &ied);
11565 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11566 }
11567 ast_mutex_unlock(&iaxsl[callno]);
11568
11569 return 0;
11570 }
11571
11572 static void free_context(struct iax2_context *con)
11573 {
11574 struct iax2_context *conl;
11575 while(con) {
11576 conl = con;
11577 con = con->next;
11578 ast_free(conl);
11579 }
11580 }
11581
11582 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
11583 {
11584 int callno;
11585 int res;
11586 int fmt, native;
11587 struct sockaddr_in sin;
11588 struct ast_channel *c;
11589 struct parsed_dial_string pds;
11590 struct create_addr_info cai;
11591 char *tmpstr;
11592
11593 memset(&pds, 0, sizeof(pds));
11594 tmpstr = ast_strdupa(data);
11595 parse_dial_string(tmpstr, &pds);
11596
11597 if (ast_strlen_zero(pds.peer)) {
11598 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
11599 return NULL;
11600 }
11601
11602 memset(&cai, 0, sizeof(cai));
11603 cai.capability = iax2_capability;
11604
11605 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11606
11607
11608 if (create_addr(pds.peer, NULL, &sin, &cai)) {
11609 *cause = AST_CAUSE_UNREGISTERED;
11610 return NULL;
11611 }
11612
11613 if (pds.port)
11614 sin.sin_port = htons(atoi(pds.port));
11615
11616 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11617 if (callno < 1) {
11618 ast_log(LOG_WARNING, "Unable to create call\n");
11619 *cause = AST_CAUSE_CONGESTION;
11620 return NULL;
11621 }
11622
11623
11624 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11625 if (ast_test_flag(&cai, IAX_TRUNK)) {
11626 int new_callno;
11627 if ((new_callno = make_trunk(callno, 1)) != -1)
11628 callno = new_callno;
11629 }
11630 iaxs[callno]->maxtime = cai.maxtime;
11631 if (cai.found)
11632 ast_string_field_set(iaxs[callno], host, pds.peer);
11633
11634 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
11635
11636 ast_mutex_unlock(&iaxsl[callno]);
11637
11638 if (c) {
11639
11640 if (c->nativeformats & format)
11641 c->nativeformats &= format;
11642 else {
11643 native = c->nativeformats;
11644 fmt = format;
11645 res = ast_translator_best_choice(&fmt, &native);
11646 if (res < 0) {
11647 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
11648 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
11649 ast_hangup(c);
11650 return NULL;
11651 }
11652 c->nativeformats = native;
11653 }
11654 c->readformat = ast_best_codec(c->nativeformats);
11655 c->writeformat = c->readformat;
11656 }
11657
11658 return c;
11659 }
11660
11661 static void *network_thread(void *ignore)
11662 {
11663
11664
11665 int res, count, wakeup;
11666 struct iax_frame *f;
11667
11668 if (timer)
11669 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
11670
11671 for(;;) {
11672 pthread_testcancel();
11673
11674
11675
11676 AST_LIST_LOCK(&frame_queue);
11677 count = 0;
11678 wakeup = -1;
11679 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
11680 if (f->sentyet)
11681 continue;
11682
11683
11684 if (ast_mutex_trylock(&iaxsl[f->callno])) {
11685 wakeup = 1;
11686 continue;
11687 }
11688
11689 f->sentyet = 1;
11690
11691 if (iaxs[f->callno]) {
11692 send_packet(f);
11693 count++;
11694 }
11695
11696 ast_mutex_unlock(&iaxsl[f->callno]);
11697
11698 if (f->retries < 0) {
11699
11700 AST_LIST_REMOVE_CURRENT(list);
11701
11702 iax_frame_free(f);
11703 } else {
11704
11705 f->retries++;
11706 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
11707 }
11708 }
11709 AST_LIST_TRAVERSE_SAFE_END;
11710 AST_LIST_UNLOCK(&frame_queue);
11711
11712 pthread_testcancel();
11713 if (count >= 20)
11714 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
11715
11716
11717 res = ast_io_wait(io, wakeup);
11718 if (res >= 0) {
11719 if (res >= 20)
11720 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
11721 }
11722 }
11723 return NULL;
11724 }
11725
11726 static int start_network_thread(void)
11727 {
11728 struct iax2_thread *thread;
11729 int threadcount = 0;
11730 int x;
11731 for (x = 0; x < iaxthreadcount; x++) {
11732 thread = ast_calloc(1, sizeof(*thread));
11733 if (thread) {
11734 thread->type = IAX_THREAD_TYPE_POOL;
11735 thread->threadnum = ++threadcount;
11736 ast_mutex_init(&thread->lock);
11737 ast_cond_init(&thread->cond, NULL);
11738 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
11739 ast_log(LOG_WARNING, "Failed to create new thread!\n");
11740 ast_free(thread);
11741 thread = NULL;
11742 }
11743 AST_LIST_LOCK(&idle_list);
11744 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
11745 AST_LIST_UNLOCK(&idle_list);
11746 }
11747 }
11748 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
11749 ast_verb(2, "%d helper threads started\n", threadcount);
11750 return 0;
11751 }
11752
11753 static struct iax2_context *build_context(const char *context)
11754 {
11755 struct iax2_context *con;
11756
11757 if ((con = ast_calloc(1, sizeof(*con))))
11758 ast_copy_string(con->context, context, sizeof(con->context));
11759
11760 return con;
11761 }
11762
11763 static int get_auth_methods(const char *value)
11764 {
11765 int methods = 0;
11766 if (strstr(value, "rsa"))
11767 methods |= IAX_AUTH_RSA;
11768 if (strstr(value, "md5"))
11769 methods |= IAX_AUTH_MD5;
11770 if (strstr(value, "plaintext"))
11771 methods |= IAX_AUTH_PLAINTEXT;
11772 return methods;
11773 }
11774
11775
11776
11777
11778
11779 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
11780 {
11781 int sd;
11782 int res;
11783
11784 sd = socket(AF_INET, SOCK_DGRAM, 0);
11785 if (sd < 0) {
11786 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
11787 return -1;
11788 }
11789
11790 res = bind(sd, sa, salen);
11791 if (res < 0) {
11792 ast_debug(1, "Can't bind: %s\n", strerror(errno));
11793 close(sd);
11794 return 1;
11795 }
11796
11797 close(sd);
11798 return 0;
11799 }
11800
11801
11802
11803
11804 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
11805 {
11806 struct sockaddr_in sin;
11807 int nonlocal = 1;
11808 int port = IAX_DEFAULT_PORTNO;
11809 int sockfd = defaultsockfd;
11810 char *tmp;
11811 char *addr;
11812 char *portstr;
11813
11814 if (!(tmp = ast_strdupa(srcaddr)))
11815 return -1;
11816
11817 addr = strsep(&tmp, ":");
11818 portstr = tmp;
11819
11820 if (portstr) {
11821 port = atoi(portstr);
11822 if (port < 1)
11823 port = IAX_DEFAULT_PORTNO;
11824 }
11825
11826 if (!ast_get_ip(&sin, addr)) {
11827 struct ast_netsock *sock;
11828 int res;
11829
11830 sin.sin_port = 0;
11831 sin.sin_family = AF_INET;
11832 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
11833 if (res == 0) {
11834
11835 sin.sin_port = htons(port);
11836 if (!(sock = ast_netsock_find(netsock, &sin)))
11837 sock = ast_netsock_find(outsock, &sin);
11838 if (sock) {
11839 sockfd = ast_netsock_sockfd(sock);
11840 nonlocal = 0;
11841 } else {
11842 unsigned int orig_saddr = sin.sin_addr.s_addr;
11843
11844 sin.sin_addr.s_addr = INADDR_ANY;
11845 if (ast_netsock_find(netsock, &sin)) {
11846 sin.sin_addr.s_addr = orig_saddr;
11847 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
11848 if (sock) {
11849 sockfd = ast_netsock_sockfd(sock);
11850 ast_netsock_unref(sock);
11851 nonlocal = 0;
11852 } else {
11853 nonlocal = 2;
11854 }
11855 }
11856 }
11857 }
11858 }
11859
11860 peer->sockfd = sockfd;
11861
11862 if (nonlocal == 1) {
11863 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
11864 srcaddr, peer->name);
11865 return -1;
11866 } else if (nonlocal == 2) {
11867 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
11868 srcaddr, peer->name);
11869 return -1;
11870 } else {
11871 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
11872 return 0;
11873 }
11874 }
11875
11876 static void peer_destructor(void *obj)
11877 {
11878 struct iax2_peer *peer = obj;
11879 int callno = peer->callno;
11880
11881 ast_free_ha(peer->ha);
11882
11883 if (callno > 0) {
11884 ast_mutex_lock(&iaxsl[callno]);
11885 iax2_destroy(callno);
11886 ast_mutex_unlock(&iaxsl[callno]);
11887 }
11888
11889 register_peer_exten(peer, 0);
11890
11891 if (peer->dnsmgr)
11892 ast_dnsmgr_release(peer->dnsmgr);
11893
11894 if (peer->mwi_event_sub)
11895 ast_event_unsubscribe(peer->mwi_event_sub);
11896
11897 ast_string_field_free_memory(peer);
11898 }
11899
11900
11901 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
11902 {
11903 struct iax2_peer *peer = NULL;
11904 struct ast_ha *oldha = NULL;
11905 int maskfound = 0;
11906 int found = 0;
11907 int firstpass = 1;
11908 struct iax2_peer tmp_peer = {
11909 .name = name,
11910 };
11911
11912 if (!temponly) {
11913 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
11914 if (peer && !ast_test_flag(peer, IAX_DELME))
11915 firstpass = 0;
11916 }
11917
11918 if (peer) {
11919 found++;
11920 if (firstpass) {
11921 oldha = peer->ha;
11922 peer->ha = NULL;
11923 }
11924 unlink_peer(peer);
11925 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
11926 peer->expire = -1;
11927 peer->pokeexpire = -1;
11928 peer->sockfd = defaultsockfd;
11929 if (ast_string_field_init(peer, 32))
11930 peer = peer_unref(peer);
11931 }
11932
11933 if (peer) {
11934 if (firstpass) {
11935 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT);
11936 peer->encmethods = iax2_encryption;
11937 peer->adsi = adsi;
11938 ast_string_field_set(peer,secret,"");
11939 if (!found) {
11940 ast_string_field_set(peer, name, name);
11941 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11942 peer->expiry = min_reg_expire;
11943 }
11944 peer->prefs = prefs;
11945 peer->capability = iax2_capability;
11946 peer->smoothing = 0;
11947 peer->pokefreqok = DEFAULT_FREQ_OK;
11948 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
11949 peer->maxcallno = 0;
11950 peercnt_modify(0, 0, &peer->addr);
11951 peer->calltoken_required = CALLTOKEN_DEFAULT;
11952 ast_string_field_set(peer,context,"");
11953 ast_string_field_set(peer,peercontext,"");
11954 ast_clear_flag(peer, IAX_HASCALLERID);
11955 ast_string_field_set(peer, cid_name, "");
11956 ast_string_field_set(peer, cid_num, "");
11957 ast_string_field_set(peer, mohinterpret, mohinterpret);
11958 ast_string_field_set(peer, mohsuggest, mohsuggest);
11959 }
11960
11961 if (!v) {
11962 v = alt;
11963 alt = NULL;
11964 }
11965 while(v) {
11966 if (!strcasecmp(v->name, "secret")) {
11967 ast_string_field_set(peer, secret, v->value);
11968 } else if (!strcasecmp(v->name, "mailbox")) {
11969 ast_string_field_set(peer, mailbox, v->value);
11970 } else if (!strcasecmp(v->name, "hasvoicemail")) {
11971 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
11972 ast_string_field_set(peer, mailbox, name);
11973 }
11974 } else if (!strcasecmp(v->name, "mohinterpret")) {
11975 ast_string_field_set(peer, mohinterpret, v->value);
11976 } else if (!strcasecmp(v->name, "mohsuggest")) {
11977 ast_string_field_set(peer, mohsuggest, v->value);
11978 } else if (!strcasecmp(v->name, "dbsecret")) {
11979 ast_string_field_set(peer, dbsecret, v->value);
11980 } else if (!strcasecmp(v->name, "trunk")) {
11981 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
11982 if (ast_test_flag(peer, IAX_TRUNK) && !timer) {
11983 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
11984 ast_clear_flag(peer, IAX_TRUNK);
11985 }
11986 } else if (!strcasecmp(v->name, "auth")) {
11987 peer->authmethods = get_auth_methods(v->value);
11988 } else if (!strcasecmp(v->name, "encryption")) {
11989 peer->encmethods |= get_encrypt_methods(v->value);
11990 if (!peer->encmethods) {
11991 ast_clear_flag(peer, IAX_FORCE_ENCRYPT);
11992 }
11993 } else if (!strcasecmp(v->name, "forceencryption")) {
11994 if (ast_false(v->value)) {
11995 ast_clear_flag(peer, IAX_FORCE_ENCRYPT);
11996 } else {
11997 peer->encmethods |= get_encrypt_methods(v->value);
11998 if (peer->encmethods) {
11999 ast_set_flag(peer, IAX_FORCE_ENCRYPT);
12000 }
12001 }
12002 } else if (!strcasecmp(v->name, "transfer")) {
12003 if (!strcasecmp(v->value, "mediaonly")) {
12004 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12005 } else if (ast_true(v->value)) {
12006 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12007 } else
12008 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12009 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12010 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
12011 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12012 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12013 } else if (!strcasecmp(v->name, "host")) {
12014 if (!strcasecmp(v->value, "dynamic")) {
12015
12016 ast_set_flag(peer, IAX_DYNAMIC);
12017 if (!found) {
12018
12019
12020 memset(&peer->addr.sin_addr, 0, 4);
12021 if (peer->addr.sin_port) {
12022
12023 peer->defaddr.sin_port = peer->addr.sin_port;
12024 peer->addr.sin_port = 0;
12025 }
12026 }
12027 } else {
12028
12029 ast_sched_thread_del(sched, peer->expire);
12030 ast_clear_flag(peer, IAX_DYNAMIC);
12031 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12032 return peer_unref(peer);
12033 if (!peer->addr.sin_port)
12034 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
12035 }
12036 if (!maskfound)
12037 inet_aton("255.255.255.255", &peer->mask);
12038 } else if (!strcasecmp(v->name, "defaultip")) {
12039 if (ast_get_ip(&peer->defaddr, v->value))
12040 return peer_unref(peer);
12041 } else if (!strcasecmp(v->name, "sourceaddress")) {
12042 peer_set_srcaddr(peer, v->value);
12043 } else if (!strcasecmp(v->name, "permit") ||
12044 !strcasecmp(v->name, "deny")) {
12045 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12046 } else if (!strcasecmp(v->name, "mask")) {
12047 maskfound++;
12048 inet_aton(v->value, &peer->mask);
12049 } else if (!strcasecmp(v->name, "context")) {
12050 ast_string_field_set(peer, context, v->value);
12051 } else if (!strcasecmp(v->name, "regexten")) {
12052 ast_string_field_set(peer, regexten, v->value);
12053 } else if (!strcasecmp(v->name, "peercontext")) {
12054 ast_string_field_set(peer, peercontext, v->value);
12055 } else if (!strcasecmp(v->name, "port")) {
12056 if (ast_test_flag(peer, IAX_DYNAMIC))
12057 peer->defaddr.sin_port = htons(atoi(v->value));
12058 else
12059 peer->addr.sin_port = htons(atoi(v->value));
12060 } else if (!strcasecmp(v->name, "username")) {
12061 ast_string_field_set(peer, username, v->value);
12062 } else if (!strcasecmp(v->name, "allow")) {
12063 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12064 } else if (!strcasecmp(v->name, "disallow")) {
12065 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12066 } else if (!strcasecmp(v->name, "callerid")) {
12067 if (!ast_strlen_zero(v->value)) {
12068 char name2[80];
12069 char num2[80];
12070 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12071 ast_string_field_set(peer, cid_name, name2);
12072 ast_string_field_set(peer, cid_num, num2);
12073 } else {
12074 ast_string_field_set(peer, cid_name, "");
12075 ast_string_field_set(peer, cid_num, "");
12076 }
12077 ast_set_flag(peer, IAX_HASCALLERID);
12078 } else if (!strcasecmp(v->name, "fullname")) {
12079 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12080 ast_set_flag(peer, IAX_HASCALLERID);
12081 } else if (!strcasecmp(v->name, "cid_number")) {
12082 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12083 ast_set_flag(peer, IAX_HASCALLERID);
12084 } else if (!strcasecmp(v->name, "sendani")) {
12085 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
12086 } else if (!strcasecmp(v->name, "inkeys")) {
12087 ast_string_field_set(peer, inkeys, v->value);
12088 } else if (!strcasecmp(v->name, "outkey")) {
12089 ast_string_field_set(peer, outkey, v->value);
12090 } else if (!strcasecmp(v->name, "qualify")) {
12091 if (!strcasecmp(v->value, "no")) {
12092 peer->maxms = 0;
12093 } else if (!strcasecmp(v->value, "yes")) {
12094 peer->maxms = DEFAULT_MAXMS;
12095 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12096 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);
12097 peer->maxms = 0;
12098 }
12099 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12100 peer->smoothing = ast_true(v->value);
12101 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12102 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12103 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);
12104 }
12105 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12106 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12107 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);
12108 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12109 } else if (!strcasecmp(v->name, "timezone")) {
12110 ast_string_field_set(peer, zonetag, v->value);
12111 } else if (!strcasecmp(v->name, "adsi")) {
12112 peer->adsi = ast_true(v->value);
12113 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12114 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12115 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12116 } else {
12117 peercnt_modify(1, peer->maxcallno, &peer->addr);
12118 }
12119 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12120
12121 if (ast_false(v->value)) {
12122 peer->calltoken_required = CALLTOKEN_NO;
12123 } else if (!strcasecmp(v->value, "auto")) {
12124 peer->calltoken_required = CALLTOKEN_AUTO;
12125 } else if (ast_true(v->value)) {
12126 peer->calltoken_required = CALLTOKEN_YES;
12127 } else {
12128 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12129 }
12130 }
12131
12132 v = v->next;
12133 if (!v) {
12134 v = alt;
12135 alt = NULL;
12136 }
12137 }
12138 if (!peer->authmethods)
12139 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12140 ast_clear_flag(peer, IAX_DELME);
12141
12142 peer->addr.sin_family = AF_INET;
12143 }
12144
12145 if (oldha)
12146 ast_free_ha(oldha);
12147
12148 if (!ast_strlen_zero(peer->mailbox)) {
12149 char *mailbox, *context;
12150 context = mailbox = ast_strdupa(peer->mailbox);
12151 strsep(&context, "@");
12152 if (ast_strlen_zero(context))
12153 context = "default";
12154 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
12155 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12156 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12157 AST_EVENT_IE_END);
12158 }
12159
12160 return peer;
12161 }
12162
12163 static void user_destructor(void *obj)
12164 {
12165 struct iax2_user *user = obj;
12166
12167 ast_free_ha(user->ha);
12168 free_context(user->contexts);
12169 if(user->vars) {
12170 ast_variables_destroy(user->vars);
12171 user->vars = NULL;
12172 }
12173 ast_string_field_free_memory(user);
12174 }
12175
12176
12177 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12178 {
12179 struct iax2_user *user = NULL;
12180 struct iax2_context *con, *conl = NULL;
12181 struct ast_ha *oldha = NULL;
12182 struct iax2_context *oldcon = NULL;
12183 int format;
12184 int firstpass=1;
12185 int oldcurauthreq = 0;
12186 char *varname = NULL, *varval = NULL;
12187 struct ast_variable *tmpvar = NULL;
12188 struct iax2_user tmp_user = {
12189 .name = name,
12190 };
12191
12192 if (!temponly) {
12193 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12194 if (user && !ast_test_flag(user, IAX_DELME))
12195 firstpass = 0;
12196 }
12197
12198 if (user) {
12199 if (firstpass) {
12200 oldcurauthreq = user->curauthreq;
12201 oldha = user->ha;
12202 oldcon = user->contexts;
12203 user->ha = NULL;
12204 user->contexts = NULL;
12205 }
12206
12207 ao2_unlink(users, user);
12208 } else {
12209 user = ao2_alloc(sizeof(*user), user_destructor);
12210 }
12211
12212 if (user) {
12213 if (firstpass) {
12214 ast_string_field_free_memory(user);
12215 memset(user, 0, sizeof(struct iax2_user));
12216 if (ast_string_field_init(user, 32)) {
12217 user = user_unref(user);
12218 goto cleanup;
12219 }
12220 user->maxauthreq = maxauthreq;
12221 user->curauthreq = oldcurauthreq;
12222 user->prefs = prefs;
12223 user->capability = iax2_capability;
12224 user->encmethods = iax2_encryption;
12225 user->adsi = adsi;
12226 user->calltoken_required = CALLTOKEN_DEFAULT;
12227 ast_string_field_set(user, name, name);
12228 ast_string_field_set(user, language, language);
12229 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
12230 ast_clear_flag(user, IAX_HASCALLERID);
12231 ast_string_field_set(user, cid_name, "");
12232 ast_string_field_set(user, cid_num, "");
12233 ast_string_field_set(user, accountcode, accountcode);
12234 ast_string_field_set(user, mohinterpret, mohinterpret);
12235 ast_string_field_set(user, mohsuggest, mohsuggest);
12236 }
12237 if (!v) {
12238 v = alt;
12239 alt = NULL;
12240 }
12241 while(v) {
12242 if (!strcasecmp(v->name, "context")) {
12243 con = build_context(v->value);
12244 if (con) {
12245 if (conl)
12246 conl->next = con;
12247 else
12248 user->contexts = con;
12249 conl = con;
12250 }
12251 } else if (!strcasecmp(v->name, "permit") ||
12252 !strcasecmp(v->name, "deny")) {
12253 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12254 } else if (!strcasecmp(v->name, "setvar")) {
12255 varname = ast_strdupa(v->value);
12256 if (varname && (varval = strchr(varname,'='))) {
12257 *varval = '\0';
12258 varval++;
12259 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12260 tmpvar->next = user->vars;
12261 user->vars = tmpvar;
12262 }
12263 }
12264 } else if (!strcasecmp(v->name, "allow")) {
12265 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12266 } else if (!strcasecmp(v->name, "disallow")) {
12267 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12268 } else if (!strcasecmp(v->name, "trunk")) {
12269 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
12270 if (ast_test_flag(user, IAX_TRUNK) && !timer) {
12271 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12272 ast_clear_flag(user, IAX_TRUNK);
12273 }
12274 } else if (!strcasecmp(v->name, "auth")) {
12275 user->authmethods = get_auth_methods(v->value);
12276 } else if (!strcasecmp(v->name, "encryption")) {
12277 user->encmethods |= get_encrypt_methods(v->value);
12278 if (!user->encmethods) {
12279 ast_clear_flag(user, IAX_FORCE_ENCRYPT);
12280 }
12281 } else if (!strcasecmp(v->name, "forceencryption")) {
12282 if (ast_false(v->value)) {
12283 ast_clear_flag(user, IAX_FORCE_ENCRYPT);
12284 } else {
12285 user->encmethods |= get_encrypt_methods(v->value);
12286 if (user->encmethods) {
12287 ast_set_flag(user, IAX_FORCE_ENCRYPT);
12288 }
12289 }
12290 } else if (!strcasecmp(v->name, "transfer")) {
12291 if (!strcasecmp(v->value, "mediaonly")) {
12292 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12293 } else if (ast_true(v->value)) {
12294 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12295 } else
12296 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12297 } else if (!strcasecmp(v->name, "codecpriority")) {
12298 if(!strcasecmp(v->value, "caller"))
12299 ast_set_flag(user, IAX_CODEC_USER_FIRST);
12300 else if(!strcasecmp(v->value, "disabled"))
12301 ast_set_flag(user, IAX_CODEC_NOPREFS);
12302 else if(!strcasecmp(v->value, "reqonly")) {
12303 ast_set_flag(user, IAX_CODEC_NOCAP);
12304 ast_set_flag(user, IAX_CODEC_NOPREFS);
12305 }
12306 } else if (!strcasecmp(v->name, "immediate")) {
12307 ast_set2_flag(user, ast_true(v->value), IAX_IMMEDIATE);
12308 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12309 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
12310 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12311 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12312 } else if (!strcasecmp(v->name, "dbsecret")) {
12313 ast_string_field_set(user, dbsecret, v->value);
12314 } else if (!strcasecmp(v->name, "secret")) {
12315 if (!ast_strlen_zero(user->secret)) {
12316 char *old = ast_strdupa(user->secret);
12317
12318 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12319 } else
12320 ast_string_field_set(user, secret, v->value);
12321 } else if (!strcasecmp(v->name, "callerid")) {
12322 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12323 char name2[80];
12324 char num2[80];
12325 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12326 ast_string_field_set(user, cid_name, name2);
12327 ast_string_field_set(user, cid_num, num2);
12328 ast_set_flag(user, IAX_HASCALLERID);
12329 } else {
12330 ast_clear_flag(user, IAX_HASCALLERID);
12331 ast_string_field_set(user, cid_name, "");
12332 ast_string_field_set(user, cid_num, "");
12333 }
12334 } else if (!strcasecmp(v->name, "fullname")) {
12335 if (!ast_strlen_zero(v->value)) {
12336 ast_string_field_set(user, cid_name, v->value);
12337 ast_set_flag(user, IAX_HASCALLERID);
12338 } else {
12339 ast_string_field_set(user, cid_name, "");
12340 if (ast_strlen_zero(user->cid_num))
12341 ast_clear_flag(user, IAX_HASCALLERID);
12342 }
12343 } else if (!strcasecmp(v->name, "cid_number")) {
12344 if (!ast_strlen_zero(v->value)) {
12345 ast_string_field_set(user, cid_num, v->value);
12346 ast_set_flag(user, IAX_HASCALLERID);
12347 } else {
12348 ast_string_field_set(user, cid_num, "");
12349 if (ast_strlen_zero(user->cid_name))
12350 ast_clear_flag(user, IAX_HASCALLERID);
12351 }
12352 } else if (!strcasecmp(v->name, "accountcode")) {
12353 ast_string_field_set(user, accountcode, v->value);
12354 } else if (!strcasecmp(v->name, "mohinterpret")) {
12355 ast_string_field_set(user, mohinterpret, v->value);
12356 } else if (!strcasecmp(v->name, "mohsuggest")) {
12357 ast_string_field_set(user, mohsuggest, v->value);
12358 } else if (!strcasecmp(v->name, "parkinglot")) {
12359 ast_string_field_set(user, parkinglot, v->value);
12360 } else if (!strcasecmp(v->name, "language")) {
12361 ast_string_field_set(user, language, v->value);
12362 } else if (!strcasecmp(v->name, "amaflags")) {
12363 format = ast_cdr_amaflags2int(v->value);
12364 if (format < 0) {
12365 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12366 } else {
12367 user->amaflags = format;
12368 }
12369 } else if (!strcasecmp(v->name, "inkeys")) {
12370 ast_string_field_set(user, inkeys, v->value);
12371 } else if (!strcasecmp(v->name, "maxauthreq")) {
12372 user->maxauthreq = atoi(v->value);
12373 if (user->maxauthreq < 0)
12374 user->maxauthreq = 0;
12375 } else if (!strcasecmp(v->name, "adsi")) {
12376 user->adsi = ast_true(v->value);
12377 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12378
12379 if (ast_false(v->value)) {
12380 user->calltoken_required = CALLTOKEN_NO;
12381 } else if (!strcasecmp(v->value, "auto")) {
12382 user->calltoken_required = CALLTOKEN_AUTO;
12383 } else if (ast_true(v->value)) {
12384 user->calltoken_required = CALLTOKEN_YES;
12385 } else {
12386 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12387 }
12388 }
12389
12390 v = v->next;
12391 if (!v) {
12392 v = alt;
12393 alt = NULL;
12394 }
12395 }
12396 if (!user->authmethods) {
12397 if (!ast_strlen_zero(user->secret)) {
12398 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12399 if (!ast_strlen_zero(user->inkeys))
12400 user->authmethods |= IAX_AUTH_RSA;
12401 } else if (!ast_strlen_zero(user->inkeys)) {
12402 user->authmethods = IAX_AUTH_RSA;
12403 } else {
12404 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12405 }
12406 }
12407 ast_clear_flag(user, IAX_DELME);
12408 }
12409 cleanup:
12410 if (oldha)
12411 ast_free_ha(oldha);
12412 if (oldcon)
12413 free_context(oldcon);
12414 return user;
12415 }
12416
12417 static int peer_delme_cb(void *obj, void *arg, int flags)
12418 {
12419 struct iax2_peer *peer = obj;
12420
12421 ast_set_flag(peer, IAX_DELME);
12422
12423 return 0;
12424 }
12425
12426 static int user_delme_cb(void *obj, void *arg, int flags)
12427 {
12428 struct iax2_user *user = obj;
12429
12430 ast_set_flag(user, IAX_DELME);
12431
12432 return 0;
12433 }
12434
12435 static void delete_users(void)
12436 {
12437 struct iax2_registry *reg;
12438
12439 ao2_callback(users, 0, user_delme_cb, NULL);
12440
12441 AST_LIST_LOCK(®istrations);
12442 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12443 if (sched) {
12444 ast_sched_thread_del(sched, reg->expire);
12445 }
12446 if (reg->callno) {
12447 int callno = reg->callno;
12448 ast_mutex_lock(&iaxsl[callno]);
12449 if (iaxs[callno]) {
12450 iaxs[callno]->reg = NULL;
12451 iax2_destroy(callno);
12452 }
12453 ast_mutex_unlock(&iaxsl[callno]);
12454 }
12455 if (reg->dnsmgr)
12456 ast_dnsmgr_release(reg->dnsmgr);
12457 ast_free(reg);
12458 }
12459 AST_LIST_UNLOCK(®istrations);
12460
12461 ao2_callback(peers, 0, peer_delme_cb, NULL);
12462 }
12463
12464 static void prune_users(void)
12465 {
12466 struct iax2_user *user;
12467 struct ao2_iterator i;
12468
12469 i = ao2_iterator_init(users, 0);
12470 while ((user = ao2_iterator_next(&i))) {
12471 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
12472 ao2_unlink(users, user);
12473 }
12474 user_unref(user);
12475 }
12476 ao2_iterator_destroy(&i);
12477 }
12478
12479
12480 static void prune_peers(void)
12481 {
12482 struct iax2_peer *peer;
12483 struct ao2_iterator i;
12484
12485 i = ao2_iterator_init(peers, 0);
12486 while ((peer = ao2_iterator_next(&i))) {
12487 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
12488 unlink_peer(peer);
12489 }
12490 peer_unref(peer);
12491 }
12492 ao2_iterator_destroy(&i);
12493 }
12494
12495 static void set_config_destroy(void)
12496 {
12497 strcpy(accountcode, "");
12498 strcpy(language, "");
12499 strcpy(mohinterpret, "default");
12500 strcpy(mohsuggest, "");
12501 trunkmaxsize = MAX_TRUNKDATA;
12502 amaflags = 0;
12503 delayreject = 0;
12504 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
12505 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
12506 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
12507 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
12508 delete_users();
12509 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12510 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12511 }
12512
12513
12514 static int set_config(const char *config_file, int reload)
12515 {
12516 struct ast_config *cfg, *ucfg;
12517 int capability=iax2_capability;
12518 struct ast_variable *v;
12519 char *cat;
12520 const char *utype;
12521 const char *tosval;
12522 int format;
12523 int portno = IAX_DEFAULT_PORTNO;
12524 int x;
12525 int mtuv;
12526 struct iax2_user *user;
12527 struct iax2_peer *peer;
12528 struct ast_netsock *ns;
12529 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12530 #if 0
12531 static unsigned short int last_port=0;
12532 #endif
12533
12534 cfg = ast_config_load(config_file, config_flags);
12535
12536 if (!cfg) {
12537 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12538 return -1;
12539 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12540 ucfg = ast_config_load("users.conf", config_flags);
12541 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12542 return 0;
12543
12544 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12545 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
12546 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12547 ast_config_destroy(ucfg);
12548 return 0;
12549 }
12550 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
12551 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12552 return 0;
12553 } else {
12554 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12555 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
12556 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
12557 ast_config_destroy(cfg);
12558 return 0;
12559 }
12560 }
12561
12562 if (reload) {
12563 set_config_destroy();
12564 }
12565
12566
12567 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12568
12569
12570 memset(&globalflags, 0, sizeof(globalflags));
12571 ast_set_flag(&globalflags, IAX_RTUPDATE);
12572 ast_set_flag(&globalflags, IAX_SHRINKCALLERID);
12573
12574 #ifdef SO_NO_CHECK
12575 nochecksums = 0;
12576 #endif
12577
12578 default_parkinglot[0] = '\0';
12579
12580 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12581 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12582 global_max_trunk_mtu = MAX_TRUNK_MTU;
12583 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12584 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12585
12586 maxauthreq = 3;
12587
12588 srvlookup = 0;
12589
12590 v = ast_variable_browse(cfg, "general");
12591
12592
12593 tosval = ast_variable_retrieve(cfg, "general", "tos");
12594 if (tosval) {
12595 if (ast_str2tos(tosval, &qos.tos))
12596 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
12597 }
12598
12599 tosval = ast_variable_retrieve(cfg, "general", "cos");
12600 if (tosval) {
12601 if (ast_str2cos(tosval, &qos.cos))
12602 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
12603 }
12604 while(v) {
12605 if (!strcasecmp(v->name, "bindport")){
12606 if (reload)
12607 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
12608 else
12609 portno = atoi(v->value);
12610 } else if (!strcasecmp(v->name, "pingtime"))
12611 ping_time = atoi(v->value);
12612 else if (!strcasecmp(v->name, "iaxthreadcount")) {
12613 if (reload) {
12614 if (atoi(v->value) != iaxthreadcount)
12615 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
12616 } else {
12617 iaxthreadcount = atoi(v->value);
12618 if (iaxthreadcount < 1) {
12619 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
12620 iaxthreadcount = 1;
12621 } else if (iaxthreadcount > 256) {
12622 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
12623 iaxthreadcount = 256;
12624 }
12625 }
12626 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
12627 if (reload) {
12628 AST_LIST_LOCK(&dynamic_list);
12629 iaxmaxthreadcount = atoi(v->value);
12630 AST_LIST_UNLOCK(&dynamic_list);
12631 } else {
12632 iaxmaxthreadcount = atoi(v->value);
12633 if (iaxmaxthreadcount < 0) {
12634 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
12635 iaxmaxthreadcount = 0;
12636 } else if (iaxmaxthreadcount > 256) {
12637 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
12638 iaxmaxthreadcount = 256;
12639 }
12640 }
12641 } else if (!strcasecmp(v->name, "nochecksums")) {
12642 #ifdef SO_NO_CHECK
12643 if (ast_true(v->value))
12644 nochecksums = 1;
12645 else
12646 nochecksums = 0;
12647 #else
12648 if (ast_true(v->value))
12649 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
12650 #endif
12651 }
12652 else if (!strcasecmp(v->name, "maxjitterbuffer"))
12653 maxjitterbuffer = atoi(v->value);
12654 else if (!strcasecmp(v->name, "resyncthreshold"))
12655 resyncthreshold = atoi(v->value);
12656 else if (!strcasecmp(v->name, "maxjitterinterps"))
12657 maxjitterinterps = atoi(v->value);
12658 else if (!strcasecmp(v->name, "jittertargetextra"))
12659 jittertargetextra = atoi(v->value);
12660 else if (!strcasecmp(v->name, "lagrqtime"))
12661 lagrq_time = atoi(v->value);
12662 else if (!strcasecmp(v->name, "maxregexpire"))
12663 max_reg_expire = atoi(v->value);
12664 else if (!strcasecmp(v->name, "minregexpire"))
12665 min_reg_expire = atoi(v->value);
12666 else if (!strcasecmp(v->name, "bindaddr")) {
12667 if (reload) {
12668 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
12669 } else {
12670 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
12671 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
12672 } else {
12673 if (strchr(v->value, ':'))
12674 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
12675 else
12676 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
12677 if (defaultsockfd < 0)
12678 defaultsockfd = ast_netsock_sockfd(ns);
12679 ast_netsock_unref(ns);
12680 }
12681 }
12682 } else if (!strcasecmp(v->name, "authdebug")) {
12683 authdebug = ast_true(v->value);
12684 } else if (!strcasecmp(v->name, "encryption")) {
12685 iax2_encryption |= get_encrypt_methods(v->value);
12686 if (!iax2_encryption) {
12687 ast_clear_flag((&globalflags), IAX_FORCE_ENCRYPT);
12688 }
12689 } else if (!strcasecmp(v->name, "forceencryption")) {
12690 if (ast_false(v->value)) {
12691 ast_clear_flag((&globalflags), IAX_FORCE_ENCRYPT);
12692 } else {
12693 iax2_encryption |= get_encrypt_methods(v->value);
12694 if (iax2_encryption) {
12695 ast_set_flag((&globalflags), IAX_FORCE_ENCRYPT);
12696 }
12697 }
12698 } else if (!strcasecmp(v->name, "transfer")) {
12699 if (!strcasecmp(v->value, "mediaonly")) {
12700 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12701 } else if (ast_true(v->value)) {
12702 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12703 } else
12704 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12705 } else if (!strcasecmp(v->name, "codecpriority")) {
12706 if(!strcasecmp(v->value, "caller"))
12707 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
12708 else if(!strcasecmp(v->value, "disabled"))
12709 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12710 else if(!strcasecmp(v->value, "reqonly")) {
12711 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
12712 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12713 }
12714 } else if (!strcasecmp(v->name, "jitterbuffer"))
12715 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
12716 else if (!strcasecmp(v->name, "forcejitterbuffer"))
12717 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
12718 else if (!strcasecmp(v->name, "delayreject"))
12719 delayreject = ast_true(v->value);
12720 else if (!strcasecmp(v->name, "allowfwdownload"))
12721 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
12722 else if (!strcasecmp(v->name, "rtcachefriends"))
12723 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
12724 else if (!strcasecmp(v->name, "rtignoreregexpire"))
12725 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
12726 else if (!strcasecmp(v->name, "rtupdate"))
12727 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
12728 else if (!strcasecmp(v->name, "trunktimestamps"))
12729 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
12730 else if (!strcasecmp(v->name, "rtautoclear")) {
12731 int i = atoi(v->value);
12732 if(i > 0)
12733 global_rtautoclear = i;
12734 else
12735 i = 0;
12736 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
12737 } else if (!strcasecmp(v->name, "trunkfreq")) {
12738 trunkfreq = atoi(v->value);
12739 if (trunkfreq < 10)
12740 trunkfreq = 10;
12741 } else if (!strcasecmp(v->name, "trunkmtu")) {
12742 mtuv = atoi(v->value);
12743 if (mtuv == 0 )
12744 global_max_trunk_mtu = 0;
12745 else if (mtuv >= 172 && mtuv < 4000)
12746 global_max_trunk_mtu = mtuv;
12747 else
12748 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
12749 mtuv, v->lineno);
12750 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
12751 trunkmaxsize = atoi(v->value);
12752 if (trunkmaxsize == 0)
12753 trunkmaxsize = MAX_TRUNKDATA;
12754 } else if (!strcasecmp(v->name, "autokill")) {
12755 if (sscanf(v->value, "%30d", &x) == 1) {
12756 if (x >= 0)
12757 autokill = x;
12758 else
12759 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
12760 } else if (ast_true(v->value)) {
12761 autokill = DEFAULT_MAXMS;
12762 } else {
12763 autokill = 0;
12764 }
12765 } else if (!strcasecmp(v->name, "bandwidth")) {
12766 if (!strcasecmp(v->value, "low")) {
12767 capability = IAX_CAPABILITY_LOWBANDWIDTH;
12768 } else if (!strcasecmp(v->value, "medium")) {
12769 capability = IAX_CAPABILITY_MEDBANDWIDTH;
12770 } else if (!strcasecmp(v->value, "high")) {
12771 capability = IAX_CAPABILITY_FULLBANDWIDTH;
12772 } else
12773 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
12774 } else if (!strcasecmp(v->name, "allow")) {
12775 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
12776 } else if (!strcasecmp(v->name, "disallow")) {
12777 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
12778 } else if (!strcasecmp(v->name, "register")) {
12779 iax2_register(v->value, v->lineno);
12780 } else if (!strcasecmp(v->name, "iaxcompat")) {
12781 iaxcompat = ast_true(v->value);
12782 } else if (!strcasecmp(v->name, "regcontext")) {
12783 ast_copy_string(regcontext, v->value, sizeof(regcontext));
12784
12785 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
12786 } else if (!strcasecmp(v->name, "tos")) {
12787 if (ast_str2tos(v->value, &qos.tos))
12788 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
12789 } else if (!strcasecmp(v->name, "cos")) {
12790 if (ast_str2cos(v->value, &qos.cos))
12791 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
12792 } else if (!strcasecmp(v->name, "parkinglot")) {
12793 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
12794 } else if (!strcasecmp(v->name, "accountcode")) {
12795 ast_copy_string(accountcode, v->value, sizeof(accountcode));
12796 } else if (!strcasecmp(v->name, "mohinterpret")) {
12797 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
12798 } else if (!strcasecmp(v->name, "mohsuggest")) {
12799 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
12800 } else if (!strcasecmp(v->name, "amaflags")) {
12801 format = ast_cdr_amaflags2int(v->value);
12802 if (format < 0) {
12803 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12804 } else {
12805 amaflags = format;
12806 }
12807 } else if (!strcasecmp(v->name, "language")) {
12808 ast_copy_string(language, v->value, sizeof(language));
12809 } else if (!strcasecmp(v->name, "maxauthreq")) {
12810 maxauthreq = atoi(v->value);
12811 if (maxauthreq < 0)
12812 maxauthreq = 0;
12813 } else if (!strcasecmp(v->name, "adsi")) {
12814 adsi = ast_true(v->value);
12815 } else if (!strcasecmp(v->name, "srvlookup")) {
12816 srvlookup = ast_true(v->value);
12817 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12818 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
12819 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
12820 }
12821 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
12822 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
12823 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);
12824 }
12825 } else if (!strcasecmp(v->name, "calltokenoptional")) {
12826 if (add_calltoken_ignore(v->value)) {
12827 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
12828 }
12829 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
12830 if (ast_true(v->value)) {
12831 ast_set_flag((&globalflags), IAX_SHRINKCALLERID);
12832 } else if (ast_false(v->value)) {
12833 ast_clear_flag((&globalflags), IAX_SHRINKCALLERID);
12834 } else {
12835 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
12836 }
12837 }
12838
12839 v = v->next;
12840 }
12841
12842 if (defaultsockfd < 0) {
12843 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
12844 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
12845 } else {
12846 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
12847 defaultsockfd = ast_netsock_sockfd(ns);
12848 ast_netsock_unref(ns);
12849 }
12850 }
12851 if (reload) {
12852 ast_netsock_release(outsock);
12853 outsock = ast_netsock_list_alloc();
12854 if (!outsock) {
12855 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12856 return -1;
12857 }
12858 ast_netsock_init(outsock);
12859 }
12860
12861 if (min_reg_expire > max_reg_expire) {
12862 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
12863 min_reg_expire, max_reg_expire, max_reg_expire);
12864 min_reg_expire = max_reg_expire;
12865 }
12866 iax2_capability = capability;
12867
12868 if (ucfg) {
12869 struct ast_variable *gen;
12870 int genhasiax;
12871 int genregisteriax;
12872 const char *hasiax, *registeriax;
12873
12874 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
12875 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
12876 gen = ast_variable_browse(ucfg, "general");
12877 cat = ast_category_browse(ucfg, NULL);
12878 while (cat) {
12879 if (strcasecmp(cat, "general")) {
12880 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
12881 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
12882 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
12883
12884 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
12885 if (user) {
12886 ao2_link(users, user);
12887 user = user_unref(user);
12888 }
12889 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
12890 if (peer) {
12891 if (ast_test_flag(peer, IAX_DYNAMIC))
12892 reg_source_db(peer);
12893 ao2_link(peers, peer);
12894 peer = peer_unref(peer);
12895 }
12896 }
12897 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
12898 char tmp[256];
12899 const char *host = ast_variable_retrieve(ucfg, cat, "host");
12900 const char *username = ast_variable_retrieve(ucfg, cat, "username");
12901 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
12902 if (!host)
12903 host = ast_variable_retrieve(ucfg, "general", "host");
12904 if (!username)
12905 username = ast_variable_retrieve(ucfg, "general", "username");
12906 if (!secret)
12907 secret = ast_variable_retrieve(ucfg, "general", "secret");
12908 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
12909 if (!ast_strlen_zero(secret))
12910 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
12911 else
12912 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
12913 iax2_register(tmp, 0);
12914 }
12915 }
12916 }
12917 cat = ast_category_browse(ucfg, cat);
12918 }
12919 ast_config_destroy(ucfg);
12920 }
12921
12922 cat = ast_category_browse(cfg, NULL);
12923 while(cat) {
12924 if (strcasecmp(cat, "general")) {
12925 utype = ast_variable_retrieve(cfg, cat, "type");
12926 if (!strcasecmp(cat, "callnumberlimits")) {
12927 build_callno_limits(ast_variable_browse(cfg, cat));
12928 } else if (utype) {
12929 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
12930 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
12931 if (user) {
12932 ao2_link(users, user);
12933 user = user_unref(user);
12934 }
12935 }
12936 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
12937 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
12938 if (peer) {
12939 if (ast_test_flag(peer, IAX_DYNAMIC))
12940 reg_source_db(peer);
12941 ao2_link(peers, peer);
12942 peer = peer_unref(peer);
12943 }
12944 } else if (strcasecmp(utype, "user")) {
12945 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
12946 }
12947 } else
12948 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
12949 }
12950 cat = ast_category_browse(cfg, cat);
12951 }
12952 ast_config_destroy(cfg);
12953 return 1;
12954 }
12955
12956 static void poke_all_peers(void)
12957 {
12958 struct ao2_iterator i;
12959 struct iax2_peer *peer;
12960
12961 i = ao2_iterator_init(peers, 0);
12962 while ((peer = ao2_iterator_next(&i))) {
12963 iax2_poke_peer(peer, 0);
12964 peer_unref(peer);
12965 }
12966 ao2_iterator_destroy(&i);
12967 }
12968 static int reload_config(void)
12969 {
12970 static const char config[] = "iax.conf";
12971 struct iax2_registry *reg;
12972
12973 if (set_config(config, 1) > 0) {
12974 prune_peers();
12975 prune_users();
12976 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
12977 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
12978 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
12979 trunk_timed = trunk_untimed = 0;
12980 trunk_nmaxmtu = trunk_maxmtu = 0;
12981 memset(&debugaddr, '\0', sizeof(debugaddr));
12982
12983 AST_LIST_LOCK(®istrations);
12984 AST_LIST_TRAVERSE(®istrations, reg, entry)
12985 iax2_do_register(reg);
12986 AST_LIST_UNLOCK(®istrations);
12987
12988
12989 poke_all_peers();
12990 }
12991
12992 reload_firmware(0);
12993 iax_provision_reload(1);
12994 ast_unload_realtime("iaxpeers");
12995
12996 return 0;
12997 }
12998
12999 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13000 {
13001 switch (cmd) {
13002 case CLI_INIT:
13003 e->command = "iax2 reload";
13004 e->usage =
13005 "Usage: iax2 reload\n"
13006 " Reloads IAX configuration from iax.conf\n";
13007 return NULL;
13008 case CLI_GENERATE:
13009 return NULL;
13010 }
13011
13012 reload_config();
13013
13014 return CLI_SUCCESS;
13015 }
13016
13017 static int reload(void)
13018 {
13019 return reload_config();
13020 }
13021
13022 static int cache_get_callno_locked(const char *data)
13023 {
13024 struct sockaddr_in sin;
13025 int x;
13026 int callno;
13027 struct iax_ie_data ied;
13028 struct create_addr_info cai;
13029 struct parsed_dial_string pds;
13030 char *tmpstr;
13031
13032 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13033
13034
13035 if (!ast_mutex_trylock(&iaxsl[x])) {
13036 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13037 return x;
13038 ast_mutex_unlock(&iaxsl[x]);
13039 }
13040 }
13041
13042
13043
13044 memset(&cai, 0, sizeof(cai));
13045 memset(&ied, 0, sizeof(ied));
13046 memset(&pds, 0, sizeof(pds));
13047
13048 tmpstr = ast_strdupa(data);
13049 parse_dial_string(tmpstr, &pds);
13050
13051 if (ast_strlen_zero(pds.peer)) {
13052 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13053 return -1;
13054 }
13055
13056
13057 if (create_addr(pds.peer, NULL, &sin, &cai))
13058 return -1;
13059
13060 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13061 pds.peer, pds.username, pds.password, pds.context);
13062
13063 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13064 if (callno < 1) {
13065 ast_log(LOG_WARNING, "Unable to create call\n");
13066 return -1;
13067 }
13068
13069 ast_string_field_set(iaxs[callno], dproot, data);
13070 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13071
13072 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13073 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13074
13075
13076
13077 if (pds.exten)
13078 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13079 if (pds.username)
13080 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13081 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13082 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13083
13084 if (pds.password)
13085 ast_string_field_set(iaxs[callno], secret, pds.password);
13086 if (pds.key)
13087 ast_string_field_set(iaxs[callno], outkey, pds.key);
13088
13089 add_empty_calltoken_ie(iaxs[callno], &ied);
13090 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13091
13092 return callno;
13093 }
13094
13095 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13096 {
13097 struct iax2_dpcache *dp = NULL;
13098 struct timeval now = ast_tvnow();
13099 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13100 struct ast_channel *c = NULL;
13101 struct ast_frame *f = NULL;
13102
13103 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13104 if (ast_tvcmp(now, dp->expiry) > 0) {
13105 AST_LIST_REMOVE_CURRENT(cache_list);
13106 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13107 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13108 else
13109 ast_free(dp);
13110 continue;
13111 }
13112 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13113 break;
13114 }
13115 AST_LIST_TRAVERSE_SAFE_END;
13116
13117 if (!dp) {
13118
13119
13120 if ((callno = cache_get_callno_locked(data)) < 0) {
13121 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13122 return NULL;
13123 }
13124 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13125 ast_mutex_unlock(&iaxsl[callno]);
13126 return NULL;
13127 }
13128 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13129 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13130 dp->expiry = ast_tvnow();
13131 dp->orig = dp->expiry;
13132
13133 dp->expiry.tv_sec += iaxdefaultdpcache;
13134 dp->flags = CACHE_FLAG_PENDING;
13135 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13136 dp->waiters[x] = -1;
13137
13138 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13139 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13140
13141 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13142 iax2_dprequest(dp, callno);
13143 ast_mutex_unlock(&iaxsl[callno]);
13144 }
13145
13146
13147 if (dp->flags & CACHE_FLAG_PENDING) {
13148
13149
13150 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13151
13152 if (dp->waiters[x] < 0)
13153 break;
13154 }
13155 if (x >= ARRAY_LEN(dp->waiters)) {
13156 ast_log(LOG_WARNING, "No more waiter positions available\n");
13157 return NULL;
13158 }
13159 if (pipe(com)) {
13160 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13161 return NULL;
13162 }
13163 dp->waiters[x] = com[1];
13164
13165 timeout = iaxdefaulttimeout * 1000;
13166
13167 AST_LIST_UNLOCK(&dpcache);
13168
13169 if (chan)
13170 old = ast_channel_defer_dtmf(chan);
13171 doabort = 0;
13172 while(timeout) {
13173 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13174 if (outfd > -1)
13175 break;
13176 if (!c)
13177 continue;
13178 if (!(f = ast_read(c))) {
13179 doabort = 1;
13180 break;
13181 }
13182 ast_frfree(f);
13183 }
13184 if (!timeout) {
13185 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13186 }
13187 AST_LIST_LOCK(&dpcache);
13188 dp->waiters[x] = -1;
13189 close(com[1]);
13190 close(com[0]);
13191 if (doabort) {
13192
13193
13194 if (!old && chan)
13195 ast_channel_undefer_dtmf(chan);
13196 return NULL;
13197 }
13198 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13199
13200 if (dp->flags & CACHE_FLAG_PENDING) {
13201
13202
13203 dp->flags &= ~CACHE_FLAG_PENDING;
13204 dp->flags |= CACHE_FLAG_TIMEOUT;
13205
13206
13207 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13208 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13209 if (dp->waiters[x] > -1) {
13210 if (write(dp->waiters[x], "asdf", 4) < 0) {
13211 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13212 }
13213 }
13214 }
13215 }
13216 }
13217
13218 if (!old && chan)
13219 ast_channel_undefer_dtmf(chan);
13220 }
13221 return dp;
13222 }
13223
13224
13225 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13226 {
13227 int res = 0;
13228 struct iax2_dpcache *dp = NULL;
13229 #if 0
13230 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13231 #endif
13232 if ((priority != 1) && (priority != 2))
13233 return 0;
13234
13235 AST_LIST_LOCK(&dpcache);
13236 if ((dp = find_cache(chan, data, context, exten, priority))) {
13237 if (dp->flags & CACHE_FLAG_EXISTS)
13238 res = 1;
13239 } else {
13240 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13241 }
13242 AST_LIST_UNLOCK(&dpcache);
13243
13244 return res;
13245 }
13246
13247
13248 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13249 {
13250 int res = 0;
13251 struct iax2_dpcache *dp = NULL;
13252 #if 0
13253 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13254 #endif
13255 if ((priority != 1) && (priority != 2))
13256 return 0;
13257
13258 AST_LIST_LOCK(&dpcache);
13259 if ((dp = find_cache(chan, data, context, exten, priority))) {
13260 if (dp->flags & CACHE_FLAG_CANEXIST)
13261 res = 1;
13262 } else {
13263 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13264 }
13265 AST_LIST_UNLOCK(&dpcache);
13266
13267 return res;
13268 }
13269
13270
13271 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13272 {
13273 int res = 0;
13274 struct iax2_dpcache *dp = NULL;
13275 #if 0
13276 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13277 #endif
13278 if ((priority != 1) && (priority != 2))
13279 return 0;
13280
13281 AST_LIST_LOCK(&dpcache);
13282 if ((dp = find_cache(chan, data, context, exten, priority))) {
13283 if (dp->flags & CACHE_FLAG_MATCHMORE)
13284 res = 1;
13285 } else {
13286 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13287 }
13288 AST_LIST_UNLOCK(&dpcache);
13289
13290 return res;
13291 }
13292
13293
13294 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13295 {
13296 char odata[256];
13297 char req[256];
13298 char *ncontext;
13299 struct iax2_dpcache *dp = NULL;
13300 struct ast_app *dial = NULL;
13301 #if 0
13302 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);
13303 #endif
13304 if (priority == 2) {
13305
13306 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13307 if (dialstatus) {
13308 dial = pbx_findapp(dialstatus);
13309 if (dial)
13310 pbx_exec(chan, dial, "");
13311 }
13312 return -1;
13313 } else if (priority != 1)
13314 return -1;
13315
13316 AST_LIST_LOCK(&dpcache);
13317 if ((dp = find_cache(chan, data, context, exten, priority))) {
13318 if (dp->flags & CACHE_FLAG_EXISTS) {
13319 ast_copy_string(odata, data, sizeof(odata));
13320 ncontext = strchr(odata, '/');
13321 if (ncontext) {
13322 *ncontext = '\0';
13323 ncontext++;
13324 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13325 } else {
13326 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13327 }
13328 ast_verb(3, "Executing Dial('%s')\n", req);
13329 } else {
13330 AST_LIST_UNLOCK(&dpcache);
13331 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13332 return -1;
13333 }
13334 }
13335 AST_LIST_UNLOCK(&dpcache);
13336
13337 if ((dial = pbx_findapp("Dial")))
13338 return pbx_exec(chan, dial, req);
13339 else
13340 ast_log(LOG_WARNING, "No dial application registered\n");
13341
13342 return -1;
13343 }
13344
13345 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13346 {
13347 struct iax2_peer *peer;
13348 char *peername, *colname;
13349
13350 peername = ast_strdupa(data);
13351
13352
13353 if (!strcmp(peername,"CURRENTCHANNEL")) {
13354 unsigned short callno;
13355 if (chan->tech != &iax2_tech)
13356 return -1;
13357 callno = PTR_TO_CALLNO(chan->tech_pvt);
13358 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13359 return 0;
13360 }
13361
13362 if ((colname = strchr(peername, ',')))
13363 *colname++ = '\0';
13364 else
13365 colname = "ip";
13366
13367 if (!(peer = find_peer(peername, 1)))
13368 return -1;
13369
13370 if (!strcasecmp(colname, "ip")) {
13371 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
13372 } else if (!strcasecmp(colname, "status")) {
13373 peer_status(peer, buf, len);
13374 } else if (!strcasecmp(colname, "mailbox")) {
13375 ast_copy_string(buf, peer->mailbox, len);
13376 } else if (!strcasecmp(colname, "context")) {
13377 ast_copy_string(buf, peer->context, len);
13378 } else if (!strcasecmp(colname, "expire")) {
13379 snprintf(buf, len, "%d", peer->expire);
13380 } else if (!strcasecmp(colname, "dynamic")) {
13381 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13382 } else if (!strcasecmp(colname, "callerid_name")) {
13383 ast_copy_string(buf, peer->cid_name, len);
13384 } else if (!strcasecmp(colname, "callerid_num")) {
13385 ast_copy_string(buf, peer->cid_num, len);
13386 } else if (!strcasecmp(colname, "codecs")) {
13387 ast_getformatname_multiple(buf, len -1, peer->capability);
13388 } else if (!strncasecmp(colname, "codec[", 6)) {
13389 char *codecnum, *ptr;
13390 int codec = 0;
13391
13392 codecnum = strchr(colname, '[');
13393 *codecnum = '\0';
13394 codecnum++;
13395 if ((ptr = strchr(codecnum, ']'))) {
13396 *ptr = '\0';
13397 }
13398 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13399 ast_copy_string(buf, ast_getformatname(codec), len);
13400 } else {
13401 buf[0] = '\0';
13402 }
13403 } else {
13404 buf[0] = '\0';
13405 }
13406
13407 peer_unref(peer);
13408
13409 return 0;
13410 }
13411
13412 struct ast_custom_function iaxpeer_function = {
13413 .name = "IAXPEER",
13414 .read = function_iaxpeer,
13415 };
13416
13417 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13418 {
13419 struct chan_iax2_pvt *pvt;
13420 unsigned int callno;
13421 int res = 0;
13422
13423 if (!chan || chan->tech != &iax2_tech) {
13424 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13425 return -1;
13426 }
13427
13428 callno = PTR_TO_CALLNO(chan->tech_pvt);
13429 ast_mutex_lock(&iaxsl[callno]);
13430 if (!(pvt = iaxs[callno])) {
13431 ast_mutex_unlock(&iaxsl[callno]);
13432 return -1;
13433 }
13434
13435 if (!strcasecmp(args, "osptoken")) {
13436 ast_copy_string(buf, pvt->osptoken, buflen);
13437 } else if (!strcasecmp(args, "peerip")) {
13438 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13439 } else if (!strcasecmp(args, "peername")) {
13440 ast_copy_string(buf, pvt->username, buflen);
13441 } else {
13442 res = -1;
13443 }
13444
13445 ast_mutex_unlock(&iaxsl[callno]);
13446
13447 return res;
13448 }
13449
13450
13451 static int iax2_devicestate(void *data)
13452 {
13453 struct parsed_dial_string pds;
13454 char *tmp = ast_strdupa(data);
13455 struct iax2_peer *p;
13456 int res = AST_DEVICE_INVALID;
13457
13458 memset(&pds, 0, sizeof(pds));
13459 parse_dial_string(tmp, &pds);
13460
13461 if (ast_strlen_zero(pds.peer)) {
13462 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13463 return res;
13464 }
13465
13466 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13467
13468
13469 if (!(p = find_peer(pds.peer, 1)))
13470 return res;
13471
13472 res = AST_DEVICE_UNAVAILABLE;
13473 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13474 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13475
13476 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
13477 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13478
13479
13480 if (p->historicms == 0 || p->historicms <= p->maxms)
13481
13482 res = AST_DEVICE_UNKNOWN;
13483 }
13484
13485 peer_unref(p);
13486
13487 return res;
13488 }
13489
13490 static struct ast_switch iax2_switch =
13491 {
13492 name: "IAX2",
13493 description: "IAX Remote Dialplan Switch",
13494 exists: iax2_exists,
13495 canmatch: iax2_canmatch,
13496 exec: iax2_exec,
13497 matchmore: iax2_matchmore,
13498 };
13499
13500
13501
13502
13503
13504
13505
13506
13507
13508
13509
13510
13511
13512
13513
13514
13515
13516
13517
13518
13519
13520
13521
13522
13523
13524
13525
13526
13527
13528
13529
13530
13531
13532
13533
13534
13535
13536
13537
13538
13539
13540
13541
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 static struct ast_cli_entry cli_iax2[] = {
13605 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
13606 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
13607 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
13608 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
13609 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
13610 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
13611 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
13612 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
13613 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
13614 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
13615 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
13616 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
13617 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
13618 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
13619 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
13620 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
13621 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
13622 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
13623 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
13624 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
13625 #ifdef IAXTESTS
13626 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
13627 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
13628 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
13629 #endif
13630 };
13631
13632 static void cleanup_thread_list(void *head)
13633 {
13634 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
13635 struct iax2_thread_list *list_head = head;
13636 struct iax2_thread *thread;
13637
13638 AST_LIST_LOCK(list_head);
13639 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
13640 pthread_t thread_id = thread->threadid;
13641
13642 thread->stop = 1;
13643 signal_condition(&thread->lock, &thread->cond);
13644
13645 AST_LIST_UNLOCK(list_head);
13646 pthread_join(thread_id, NULL);
13647 AST_LIST_LOCK(list_head);
13648 }
13649 AST_LIST_UNLOCK(list_head);
13650 }
13651
13652 static int __unload_module(void)
13653 {
13654 struct ast_context *con;
13655 int x;
13656
13657 ast_manager_unregister("IAXpeers");
13658 ast_manager_unregister("IAXpeerlist");
13659 ast_manager_unregister("IAXnetstats");
13660 ast_manager_unregister("IAXregistry");
13661 ast_unregister_application(papp);
13662 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
13663 ast_unregister_switch(&iax2_switch);
13664 ast_channel_unregister(&iax2_tech);
13665
13666 if (netthreadid != AST_PTHREADT_NULL) {
13667 AST_LIST_LOCK(&frame_queue);
13668 pthread_cancel(netthreadid);
13669 AST_LIST_UNLOCK(&frame_queue);
13670 pthread_join(netthreadid, NULL);
13671 }
13672
13673 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13674 if (iaxs[x]) {
13675 iax2_destroy(x);
13676 }
13677 }
13678
13679
13680 cleanup_thread_list(&idle_list);
13681 cleanup_thread_list(&active_list);
13682 cleanup_thread_list(&dynamic_list);
13683
13684 sched = ast_sched_thread_destroy(sched);
13685
13686 ast_netsock_release(netsock);
13687 ast_netsock_release(outsock);
13688
13689 delete_users();
13690 iax_provision_unload();
13691 reload_firmware(1);
13692
13693 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13694 ast_mutex_destroy(&iaxsl[x]);
13695 }
13696
13697 ao2_ref(peers, -1);
13698 ao2_ref(users, -1);
13699 ao2_ref(iax_peercallno_pvts, -1);
13700 ao2_ref(iax_transfercallno_pvts, -1);
13701 ao2_ref(peercnts, -1);
13702 ao2_ref(callno_limits, -1);
13703 ao2_ref(calltoken_ignores, -1);
13704 ao2_ref(callno_pool, -1);
13705 ao2_ref(callno_pool_trunk, -1);
13706 if (timer) {
13707 ast_timer_close(timer);
13708 }
13709
13710 con = ast_context_find(regcontext);
13711 if (con)
13712 ast_context_destroy(con, "IAX2");
13713 ast_unload_realtime("iaxpeers");
13714 return 0;
13715 }
13716
13717 static int unload_module(void)
13718 {
13719 ast_custom_function_unregister(&iaxpeer_function);
13720 ast_custom_function_unregister(&iaxvar_function);
13721 return __unload_module();
13722 }
13723
13724 static int peer_set_sock_cb(void *obj, void *arg, int flags)
13725 {
13726 struct iax2_peer *peer = obj;
13727
13728 if (peer->sockfd < 0)
13729 peer->sockfd = defaultsockfd;
13730
13731 return 0;
13732 }
13733
13734 static int pvt_hash_cb(const void *obj, const int flags)
13735 {
13736 const struct chan_iax2_pvt *pvt = obj;
13737
13738 return pvt->peercallno;
13739 }
13740
13741 static int pvt_cmp_cb(void *obj, void *arg, int flags)
13742 {
13743 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13744
13745
13746
13747
13748 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
13749 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13750 }
13751
13752 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
13753 {
13754 const struct chan_iax2_pvt *pvt = obj;
13755
13756 return pvt->transfercallno;
13757 }
13758
13759 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
13760 {
13761 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13762
13763
13764
13765
13766 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
13767 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13768 }
13769
13770 static int load_objects(void)
13771 {
13772 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
13773 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
13774
13775 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
13776 goto container_fail;
13777 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
13778 goto container_fail;
13779 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
13780 goto container_fail;
13781 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
13782 goto container_fail;
13783 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
13784 goto container_fail;
13785 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13786 goto container_fail;
13787 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13788 goto container_fail;
13789 } else if (create_callno_pools()) {
13790 goto container_fail;
13791 }
13792
13793 return 0;
13794
13795 container_fail:
13796 if (peers) {
13797 ao2_ref(peers, -1);
13798 }
13799 if (users) {
13800 ao2_ref(users, -1);
13801 }
13802 if (iax_peercallno_pvts) {
13803 ao2_ref(iax_peercallno_pvts, -1);
13804 }
13805 if (iax_transfercallno_pvts) {
13806 ao2_ref(iax_transfercallno_pvts, -1);
13807 }
13808 if (peercnts) {
13809 ao2_ref(peercnts, -1);
13810 }
13811 if (callno_limits) {
13812 ao2_ref(callno_limits, -1);
13813 }
13814 if (calltoken_ignores) {
13815 ao2_ref(calltoken_ignores, -1);
13816 }
13817 if (callno_pool) {
13818 ao2_ref(callno_pool, -1);
13819 }
13820 if (callno_pool_trunk) {
13821 ao2_ref(callno_pool_trunk, -1);
13822 }
13823 return AST_MODULE_LOAD_FAILURE;
13824 }
13825
13826
13827
13828
13829 static int load_module(void)
13830 {
13831
13832 static const char config[] = "iax.conf";
13833 int x = 0;
13834 struct iax2_registry *reg = NULL;
13835
13836 if (load_objects()) {
13837 return AST_MODULE_LOAD_FAILURE;
13838 }
13839
13840 randomcalltokendata = ast_random();
13841 ast_custom_function_register(&iaxpeer_function);
13842 ast_custom_function_register(&iaxvar_function);
13843
13844 iax_set_output(iax_debug_output);
13845 iax_set_error(iax_error_output);
13846 jb_setoutput(jb_error_output, jb_warning_output, NULL);
13847
13848 memset(iaxs, 0, sizeof(iaxs));
13849
13850 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13851 ast_mutex_init(&iaxsl[x]);
13852 }
13853
13854 if (!(sched = ast_sched_thread_create())) {
13855 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
13856 return AST_MODULE_LOAD_FAILURE;
13857 }
13858
13859 if (!(io = io_context_create())) {
13860 ast_log(LOG_ERROR, "Failed to create I/O context\n");
13861 sched = ast_sched_thread_destroy(sched);
13862 return AST_MODULE_LOAD_FAILURE;
13863 }
13864
13865 if (!(netsock = ast_netsock_list_alloc())) {
13866 ast_log(LOG_ERROR, "Failed to create netsock list\n");
13867 io_context_destroy(io);
13868 sched = ast_sched_thread_destroy(sched);
13869 return AST_MODULE_LOAD_FAILURE;
13870 }
13871 ast_netsock_init(netsock);
13872
13873 outsock = ast_netsock_list_alloc();
13874 if (!outsock) {
13875 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13876 io_context_destroy(io);
13877 sched = ast_sched_thread_destroy(sched);
13878 return AST_MODULE_LOAD_FAILURE;
13879 }
13880 ast_netsock_init(outsock);
13881
13882 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
13883
13884 ast_register_application_xml(papp, iax2_prov_app);
13885
13886 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
13887 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
13888 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
13889 ast_manager_register( "IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry, "Show IAX registrations");
13890
13891 if ((timer = ast_timer_open())) {
13892 ast_timer_set_rate(timer, trunkfreq);
13893 }
13894
13895 if (set_config(config, 0) == -1) {
13896 if (timer) {
13897 ast_timer_close(timer);
13898 }
13899 return AST_MODULE_LOAD_DECLINE;
13900 }
13901
13902 if (ast_channel_register(&iax2_tech)) {
13903 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
13904 __unload_module();
13905 return AST_MODULE_LOAD_FAILURE;
13906 }
13907
13908 if (ast_register_switch(&iax2_switch))
13909 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
13910
13911 if (start_network_thread()) {
13912 ast_log(LOG_ERROR, "Unable to start network thread\n");
13913 __unload_module();
13914 return AST_MODULE_LOAD_FAILURE;
13915 } else
13916 ast_verb(2, "IAX Ready and Listening\n");
13917
13918 AST_LIST_LOCK(®istrations);
13919 AST_LIST_TRAVERSE(®istrations, reg, entry)
13920 iax2_do_register(reg);
13921 AST_LIST_UNLOCK(®istrations);
13922
13923 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
13924 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
13925
13926
13927 reload_firmware(0);
13928 iax_provision_reload(0);
13929
13930 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
13931
13932 return AST_MODULE_LOAD_SUCCESS;
13933 }
13934
13935 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
13936 .load = load_module,
13937 .unload = unload_module,
13938 .reload = reload,
13939 );