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: 300520 $")
00041
00042 #include <sys/mman.h>
00043 #include <dirent.h>
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 #include <arpa/inet.h>
00047 #include <netinet/in_systm.h>
00048 #include <netinet/ip.h>
00049 #include <sys/time.h>
00050 #include <sys/signal.h>
00051 #include <signal.h>
00052 #include <strings.h>
00053 #include <netdb.h>
00054 #include <fcntl.h>
00055 #include <sys/stat.h>
00056 #include <regex.h>
00057
00058 #include "asterisk/paths.h"
00059
00060 #include "asterisk/lock.h"
00061 #include "asterisk/frame.h"
00062 #include "asterisk/channel.h"
00063 #include "asterisk/module.h"
00064 #include "asterisk/pbx.h"
00065 #include "asterisk/sched.h"
00066 #include "asterisk/io.h"
00067 #include "asterisk/config.h"
00068 #include "asterisk/cli.h"
00069 #include "asterisk/translate.h"
00070 #include "asterisk/md5.h"
00071 #include "asterisk/cdr.h"
00072 #include "asterisk/crypto.h"
00073 #include "asterisk/acl.h"
00074 #include "asterisk/manager.h"
00075 #include "asterisk/callerid.h"
00076 #include "asterisk/app.h"
00077 #include "asterisk/astdb.h"
00078 #include "asterisk/musiconhold.h"
00079 #include "asterisk/features.h"
00080 #include "asterisk/utils.h"
00081 #include "asterisk/causes.h"
00082 #include "asterisk/localtime.h"
00083 #include "asterisk/aes.h"
00084 #include "asterisk/dnsmgr.h"
00085 #include "asterisk/devicestate.h"
00086 #include "asterisk/netsock.h"
00087 #include "asterisk/stringfields.h"
00088 #include "asterisk/linkedlists.h"
00089 #include "asterisk/event.h"
00090 #include "asterisk/astobj2.h"
00091 #include "asterisk/timing.h"
00092
00093 #include "iax2.h"
00094 #include "iax2-parser.h"
00095 #include "iax2-provision.h"
00096 #include "jitterbuf.h"
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 #define SCHED_MULTITHREADED
00183
00184
00185
00186 #define DEBUG_SCHED_MULTITHREAD
00187
00188
00189 #ifdef SO_NO_CHECK
00190 static int nochecksums = 0;
00191 #endif
00192
00193 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00194 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00195
00196 #define DEFAULT_THREAD_COUNT 10
00197 #define DEFAULT_MAX_THREAD_COUNT 100
00198 #define DEFAULT_RETRY_TIME 1000
00199 #define MEMORY_SIZE 100
00200 #define DEFAULT_DROP 3
00201
00202 #define DEBUG_SUPPORT
00203
00204 #define MIN_REUSE_TIME 60
00205
00206
00207 #define GAMMA (0.01)
00208
00209 static struct ast_codec_pref prefs;
00210
00211 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00212
00213
00214
00215
00216 #define MAX_TRUNK_MTU 1240
00217
00218 static int global_max_trunk_mtu;
00219 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00220
00221 #define DEFAULT_CONTEXT "default"
00222
00223 static char default_parkinglot[AST_MAX_CONTEXT];
00224
00225 static char language[MAX_LANGUAGE] = "";
00226 static char regcontext[AST_MAX_CONTEXT] = "";
00227
00228 static int maxauthreq = 3;
00229 static int max_retries = 4;
00230 static int ping_time = 21;
00231 static int lagrq_time = 10;
00232 static int maxjitterbuffer=1000;
00233 static int resyncthreshold=1000;
00234 static int maxjitterinterps=10;
00235 static int jittertargetextra = 40;
00236
00237 #define MAX_TRUNKDATA 640 * 200
00238
00239 static int trunkfreq = 20;
00240 static int trunkmaxsize = MAX_TRUNKDATA;
00241
00242 static int authdebug = 1;
00243 static int autokill = 0;
00244 static int iaxcompat = 0;
00245 static int last_authmethod = 0;
00246
00247 static int iaxdefaultdpcache=10 * 60;
00248
00249 static int iaxdefaulttimeout = 5;
00250
00251 static struct {
00252 unsigned int tos;
00253 unsigned int cos;
00254 } qos = { 0, 0 };
00255
00256 static int min_reg_expire;
00257 static int max_reg_expire;
00258
00259 static int srvlookup = 0;
00260
00261 static struct ast_timer *timer;
00262
00263 static struct ast_netsock_list *netsock;
00264 static struct ast_netsock_list *outsock;
00265 static int defaultsockfd = -1;
00266
00267 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00268
00269
00270 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00271
00272 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00273 ~AST_FORMAT_SLINEAR & \
00274 ~AST_FORMAT_SLINEAR16 & \
00275 ~AST_FORMAT_SIREN7 & \
00276 ~AST_FORMAT_SIREN14 & \
00277 ~AST_FORMAT_ULAW & \
00278 ~AST_FORMAT_ALAW & \
00279 ~AST_FORMAT_G722)
00280
00281 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00282 ~AST_FORMAT_G726 & \
00283 ~AST_FORMAT_G726_AAL2 & \
00284 ~AST_FORMAT_ADPCM)
00285
00286 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00287 ~AST_FORMAT_G723_1)
00288
00289
00290 #define DEFAULT_MAXMS 2000
00291 #define DEFAULT_FREQ_OK 60 * 1000
00292 #define DEFAULT_FREQ_NOTOK 10 * 1000
00293
00294
00295 #define IAX_CALLENCRYPTED(pvt) \
00296 (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED))
00297
00298 #define IAX_DEBUGDIGEST(msg, key) do { \
00299 int idx; \
00300 char digest[33] = ""; \
00301 \
00302 if (!iaxdebug) \
00303 break; \
00304 \
00305 for (idx = 0; idx < 16; idx++) \
00306 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00307 \
00308 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00309 } while(0)
00310
00311 static struct io_context *io;
00312 static struct ast_sched_thread *sched;
00313
00314 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00315
00316 static int iaxdebug = 0;
00317
00318 static int iaxtrunkdebug = 0;
00319
00320 static int test_losspct = 0;
00321 #ifdef IAXTESTS
00322 static int test_late = 0;
00323 static int test_resync = 0;
00324 static int test_jit = 0;
00325 static int test_jitpct = 0;
00326 #endif
00327
00328 static char accountcode[AST_MAX_ACCOUNT_CODE];
00329 static char mohinterpret[MAX_MUSICCLASS];
00330 static char mohsuggest[MAX_MUSICCLASS];
00331 static int amaflags = 0;
00332 static int adsi = 0;
00333 static int delayreject = 0;
00334 static int iax2_encryption = 0;
00335
00336 static struct ast_flags globalflags = { 0 };
00337
00338 static pthread_t netthreadid = AST_PTHREADT_NULL;
00339
00340 enum iax2_state {
00341 IAX_STATE_STARTED = (1 << 0),
00342 IAX_STATE_AUTHENTICATED = (1 << 1),
00343 IAX_STATE_TBD = (1 << 2),
00344 };
00345
00346 struct iax2_context {
00347 char context[AST_MAX_CONTEXT];
00348 struct iax2_context *next;
00349 };
00350
00351 enum iax2_flags {
00352 IAX_HASCALLERID = (1 << 0),
00353 IAX_DELME = (1 << 1),
00354 IAX_TEMPONLY = (1 << 2),
00355 IAX_TRUNK = (1 << 3),
00356 IAX_NOTRANSFER = (1 << 4),
00357 IAX_USEJITTERBUF = (1 << 5),
00358 IAX_DYNAMIC = (1 << 6),
00359 IAX_SENDANI = (1 << 7),
00360
00361 IAX_ALREADYGONE = (1 << 9),
00362 IAX_PROVISION = (1 << 10),
00363 IAX_QUELCH = (1 << 11),
00364 IAX_ENCRYPTED = (1 << 12),
00365 IAX_KEYPOPULATED = (1 << 13),
00366 IAX_CODEC_USER_FIRST = (1 << 14),
00367 IAX_CODEC_NOPREFS = (1 << 15),
00368 IAX_CODEC_NOCAP = (1 << 16),
00369 IAX_RTCACHEFRIENDS = (1 << 17),
00370 IAX_RTUPDATE = (1 << 18),
00371 IAX_RTAUTOCLEAR = (1 << 19),
00372 IAX_FORCEJITTERBUF = (1 << 20),
00373 IAX_RTIGNOREREGEXPIRE = (1 << 21),
00374 IAX_TRUNKTIMESTAMPS = (1 << 22),
00375 IAX_TRANSFERMEDIA = (1 << 23),
00376 IAX_MAXAUTHREQ = (1 << 24),
00377 IAX_DELAYPBXSTART = (1 << 25),
00378
00379
00380 IAX_ALLOWFWDOWNLOAD = (1 << 26),
00381 IAX_IMMEDIATE = (1 << 27),
00382 IAX_FORCE_ENCRYPT = (1 << 28),
00383 IAX_SHRINKCALLERID = (1 << 29),
00384 };
00385
00386 static int global_rtautoclear = 120;
00387
00388 static int reload_config(void);
00389
00390
00391
00392
00393 enum calltoken_peer_enum {
00394
00395 CALLTOKEN_DEFAULT = 0,
00396
00397 CALLTOKEN_YES = 1,
00398
00399
00400 CALLTOKEN_AUTO = 2,
00401
00402 CALLTOKEN_NO = 3,
00403 };
00404
00405 struct iax2_user {
00406 AST_DECLARE_STRING_FIELDS(
00407 AST_STRING_FIELD(name);
00408 AST_STRING_FIELD(secret);
00409 AST_STRING_FIELD(dbsecret);
00410 AST_STRING_FIELD(accountcode);
00411 AST_STRING_FIELD(mohinterpret);
00412 AST_STRING_FIELD(mohsuggest);
00413 AST_STRING_FIELD(inkeys);
00414 AST_STRING_FIELD(language);
00415 AST_STRING_FIELD(cid_num);
00416 AST_STRING_FIELD(cid_name);
00417 AST_STRING_FIELD(parkinglot);
00418 );
00419
00420 int authmethods;
00421 int encmethods;
00422 int amaflags;
00423 int adsi;
00424 unsigned int flags;
00425 int capability;
00426 int maxauthreq;
00427 int curauthreq;
00428 struct ast_codec_pref prefs;
00429 struct ast_ha *ha;
00430 struct iax2_context *contexts;
00431 struct ast_variable *vars;
00432 enum calltoken_peer_enum calltoken_required;
00433 };
00434
00435 struct iax2_peer {
00436 AST_DECLARE_STRING_FIELDS(
00437 AST_STRING_FIELD(name);
00438 AST_STRING_FIELD(username);
00439 AST_STRING_FIELD(secret);
00440 AST_STRING_FIELD(dbsecret);
00441 AST_STRING_FIELD(outkey);
00442
00443 AST_STRING_FIELD(regexten);
00444 AST_STRING_FIELD(context);
00445 AST_STRING_FIELD(peercontext);
00446 AST_STRING_FIELD(mailbox);
00447 AST_STRING_FIELD(mohinterpret);
00448 AST_STRING_FIELD(mohsuggest);
00449 AST_STRING_FIELD(inkeys);
00450
00451 AST_STRING_FIELD(cid_num);
00452 AST_STRING_FIELD(cid_name);
00453 AST_STRING_FIELD(zonetag);
00454 AST_STRING_FIELD(parkinglot);
00455 );
00456 struct ast_codec_pref prefs;
00457 struct ast_dnsmgr_entry *dnsmgr;
00458 struct sockaddr_in addr;
00459 int formats;
00460 int sockfd;
00461 struct in_addr mask;
00462 int adsi;
00463 unsigned int flags;
00464
00465
00466 struct sockaddr_in defaddr;
00467 int authmethods;
00468 int encmethods;
00469
00470 int expire;
00471 int expiry;
00472 int capability;
00473
00474
00475 int callno;
00476 int pokeexpire;
00477 int lastms;
00478 int maxms;
00479
00480 int pokefreqok;
00481 int pokefreqnotok;
00482 int historicms;
00483 int smoothing;
00484 uint16_t maxcallno;
00485
00486 struct ast_event_sub *mwi_event_sub;
00487
00488 struct ast_ha *ha;
00489 enum calltoken_peer_enum calltoken_required;
00490 };
00491
00492 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00493
00494 struct iax2_trunk_peer {
00495 ast_mutex_t lock;
00496 int sockfd;
00497 struct sockaddr_in addr;
00498 struct timeval txtrunktime;
00499 struct timeval rxtrunktime;
00500 struct timeval lasttxtime;
00501 struct timeval trunkact;
00502 unsigned int lastsent;
00503
00504 unsigned char *trunkdata;
00505 unsigned int trunkdatalen;
00506 unsigned int trunkdataalloc;
00507 int trunkmaxmtu;
00508 int trunkerror;
00509 int calls;
00510 AST_LIST_ENTRY(iax2_trunk_peer) list;
00511 };
00512
00513 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00514
00515 struct iax_firmware {
00516 AST_LIST_ENTRY(iax_firmware) list;
00517 int fd;
00518 int mmaplen;
00519 int dead;
00520 struct ast_iax2_firmware_header *fwh;
00521 unsigned char *buf;
00522 };
00523
00524 enum iax_reg_state {
00525 REG_STATE_UNREGISTERED = 0,
00526 REG_STATE_REGSENT,
00527 REG_STATE_AUTHSENT,
00528 REG_STATE_REGISTERED,
00529 REG_STATE_REJECTED,
00530 REG_STATE_TIMEOUT,
00531 REG_STATE_NOAUTH
00532 };
00533
00534 enum iax_transfer_state {
00535 TRANSFER_NONE = 0,
00536 TRANSFER_BEGIN,
00537 TRANSFER_READY,
00538 TRANSFER_RELEASED,
00539 TRANSFER_PASSTHROUGH,
00540 TRANSFER_MBEGIN,
00541 TRANSFER_MREADY,
00542 TRANSFER_MRELEASED,
00543 TRANSFER_MPASSTHROUGH,
00544 TRANSFER_MEDIA,
00545 TRANSFER_MEDIAPASS
00546 };
00547
00548 struct iax2_registry {
00549 struct sockaddr_in addr;
00550 char username[80];
00551 char secret[80];
00552 int expire;
00553 int refresh;
00554 enum iax_reg_state regstate;
00555 int messages;
00556 int callno;
00557 struct sockaddr_in us;
00558 struct ast_dnsmgr_entry *dnsmgr;
00559 AST_LIST_ENTRY(iax2_registry) entry;
00560 };
00561
00562 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00563
00564
00565 #define MIN_RETRY_TIME 100
00566 #define MAX_RETRY_TIME 10000
00567
00568 #define MAX_JITTER_BUFFER 50
00569 #define MIN_JITTER_BUFFER 10
00570
00571 #define DEFAULT_TRUNKDATA 640 * 10
00572
00573 #define MAX_TIMESTAMP_SKEW 160
00574
00575
00576 #define TS_GAP_FOR_JB_RESYNC 5000
00577
00578
00579 #define MARK_IAX_SUBCLASS_TX 0x8000
00580
00581 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00582 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00583 static int iaxdynamicthreadcount = 0;
00584 static int iaxdynamicthreadnum = 0;
00585 static int iaxactivethreadcount = 0;
00586
00587 struct iax_rr {
00588 int jitter;
00589 int losspct;
00590 int losscnt;
00591 int packets;
00592 int delay;
00593 int dropped;
00594 int ooo;
00595 };
00596
00597 struct iax2_pvt_ref;
00598
00599 struct chan_iax2_pvt {
00600
00601 int sockfd;
00602
00603 int voiceformat;
00604
00605 int videoformat;
00606
00607 int svoiceformat;
00608
00609 int svideoformat;
00610
00611 int capability;
00612
00613 unsigned int last;
00614
00615 unsigned int lastsent;
00616
00617 unsigned int lastvsent;
00618
00619 unsigned int nextpred;
00620
00621 int first_iax_message;
00622
00623 int last_iax_message;
00624
00625 unsigned int notsilenttx:1;
00626
00627 unsigned int pingtime;
00628
00629 int maxtime;
00630
00631 struct sockaddr_in addr;
00632
00633 struct ast_codec_pref prefs;
00634
00635 struct ast_codec_pref rprefs;
00636
00637 unsigned short callno;
00638
00639 struct callno_entry *callno_entry;
00640
00641 unsigned short peercallno;
00642
00643
00644
00645 int chosenformat;
00646
00647 int peerformat;
00648
00649 int peercapability;
00650
00651 struct timeval offset;
00652
00653 struct timeval rxcore;
00654
00655 jitterbuf *jb;
00656
00657 int jbid;
00658
00659 int lag;
00660
00661 int error;
00662
00663 struct ast_channel *owner;
00664
00665 struct ast_flags state;
00666
00667 int expiry;
00668
00669 unsigned char oseqno;
00670
00671 unsigned char rseqno;
00672
00673 unsigned char iseqno;
00674
00675 unsigned char aseqno;
00676
00677 AST_DECLARE_STRING_FIELDS(
00678
00679 AST_STRING_FIELD(peer);
00680
00681 AST_STRING_FIELD(context);
00682
00683 AST_STRING_FIELD(cid_num);
00684 AST_STRING_FIELD(cid_name);
00685
00686 AST_STRING_FIELD(ani);
00687
00688 AST_STRING_FIELD(dnid);
00689
00690 AST_STRING_FIELD(rdnis);
00691
00692 AST_STRING_FIELD(exten);
00693
00694 AST_STRING_FIELD(username);
00695
00696 AST_STRING_FIELD(secret);
00697
00698 AST_STRING_FIELD(challenge);
00699
00700 AST_STRING_FIELD(inkeys);
00701
00702 AST_STRING_FIELD(outkey);
00703
00704 AST_STRING_FIELD(language);
00705
00706 AST_STRING_FIELD(host);
00707
00708 AST_STRING_FIELD(dproot);
00709 AST_STRING_FIELD(accountcode);
00710 AST_STRING_FIELD(mohinterpret);
00711 AST_STRING_FIELD(mohsuggest);
00712
00713 AST_STRING_FIELD(osptoken);
00714
00715 AST_STRING_FIELD(parkinglot);
00716 );
00717
00718 int authrej;
00719
00720 int authmethods;
00721
00722 int encmethods;
00723
00724 ast_aes_encrypt_key ecx;
00725
00726 ast_aes_decrypt_key mydcx;
00727
00728 ast_aes_decrypt_key dcx;
00729
00730
00731 int keyrotateid;
00732
00733 unsigned char semirand[32];
00734
00735 struct iax2_registry *reg;
00736
00737 struct iax2_peer *peerpoke;
00738
00739 unsigned int flags;
00740 int adsi;
00741
00742
00743 enum iax_transfer_state transferring;
00744
00745 int transferid;
00746
00747 struct sockaddr_in transfer;
00748
00749 unsigned short transfercallno;
00750
00751 ast_aes_encrypt_key tdcx;
00752
00753
00754 int peeradsicpe;
00755
00756
00757 unsigned short bridgecallno;
00758
00759 int pingid;
00760 int lagid;
00761 int autoid;
00762 int authid;
00763 int authfail;
00764 int initid;
00765 int calling_ton;
00766 int calling_tns;
00767 int calling_pres;
00768 int amaflags;
00769 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00770
00771 struct ast_variable *vars;
00772
00773 struct ast_variable *iaxvars;
00774
00775 struct iax_rr remote_rr;
00776
00777 int min;
00778
00779 int frames_dropped;
00780
00781 int frames_received;
00782
00783 unsigned char calltoken_ie_len;
00784
00785 char hold_signaling;
00786
00787 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00788 };
00789
00790 struct signaling_queue_entry {
00791 struct ast_frame f;
00792 AST_LIST_ENTRY(signaling_queue_entry) next;
00793 };
00794
00795
00796 static struct ao2_container *callno_pool;
00797
00798
00799 static struct ao2_container *callno_pool_trunk;
00800
00801 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00802
00803
00804
00805
00806
00807
00808
00809
00810 static AST_LIST_HEAD_STATIC(frame_queue, iax_frame);
00811
00812 static int randomcalltokendata;
00813
00814 static const time_t MAX_CALLTOKEN_DELAY = 10;
00815
00816
00817
00818
00819
00820
00821
00822
00823 #ifdef LOW_MEMORY
00824 #define MAX_PEER_BUCKETS 17
00825 #else
00826 #define MAX_PEER_BUCKETS 563
00827 #endif
00828 static struct ao2_container *peers;
00829
00830 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00831 static struct ao2_container *users;
00832
00833
00834 static struct ao2_container *peercnts;
00835
00836
00837 static struct ao2_container *callno_limits;
00838
00839
00840 static struct ao2_container *calltoken_ignores;
00841
00842 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00843
00844 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00845
00846 static uint16_t global_maxcallno;
00847
00848
00849 static uint16_t global_maxcallno_nonval;
00850
00851 static uint16_t total_nonval_callno_used = 0;
00852
00853
00854
00855 struct peercnt {
00856
00857 unsigned long addr;
00858
00859 uint16_t cur;
00860
00861 uint16_t limit;
00862
00863
00864 unsigned char reg;
00865 };
00866
00867
00868 struct addr_range {
00869
00870 struct ast_ha ha;
00871
00872 uint16_t limit;
00873
00874 unsigned char delme;
00875 };
00876
00877 struct callno_entry {
00878
00879 uint16_t callno;
00880
00881 unsigned char validated;
00882 };
00883
00884 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00885
00886 enum {
00887
00888 CACHE_FLAG_EXISTS = (1 << 0),
00889
00890 CACHE_FLAG_NONEXISTENT = (1 << 1),
00891
00892 CACHE_FLAG_CANEXIST = (1 << 2),
00893
00894 CACHE_FLAG_PENDING = (1 << 3),
00895
00896 CACHE_FLAG_TIMEOUT = (1 << 4),
00897
00898 CACHE_FLAG_TRANSMITTED = (1 << 5),
00899
00900 CACHE_FLAG_UNKNOWN = (1 << 6),
00901
00902 CACHE_FLAG_MATCHMORE = (1 << 7),
00903 };
00904
00905 struct iax2_dpcache {
00906 char peercontext[AST_MAX_CONTEXT];
00907 char exten[AST_MAX_EXTENSION];
00908 struct timeval orig;
00909 struct timeval expiry;
00910 int flags;
00911 unsigned short callno;
00912 int waiters[256];
00913 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00914 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00915 };
00916
00917 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00918
00919 static void reg_source_db(struct iax2_peer *p);
00920 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00921 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00922
00923 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00924 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, int flags);
00925 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00926
00927 enum iax2_thread_iostate {
00928 IAX_IOSTATE_IDLE,
00929 IAX_IOSTATE_READY,
00930 IAX_IOSTATE_PROCESSING,
00931 IAX_IOSTATE_SCHEDREADY,
00932 };
00933
00934 enum iax2_thread_type {
00935 IAX_THREAD_TYPE_POOL,
00936 IAX_THREAD_TYPE_DYNAMIC,
00937 };
00938
00939 struct iax2_pkt_buf {
00940 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00941 size_t len;
00942 unsigned char buf[1];
00943 };
00944
00945 struct iax2_thread {
00946 AST_LIST_ENTRY(iax2_thread) list;
00947 enum iax2_thread_type type;
00948 enum iax2_thread_iostate iostate;
00949 #ifdef SCHED_MULTITHREADED
00950 void (*schedfunc)(const void *);
00951 const void *scheddata;
00952 #endif
00953 #ifdef DEBUG_SCHED_MULTITHREAD
00954 char curfunc[80];
00955 #endif
00956 int actions;
00957 pthread_t threadid;
00958 int threadnum;
00959 struct sockaddr_in iosin;
00960 unsigned char readbuf[4096];
00961 unsigned char *buf;
00962 ssize_t buf_len;
00963 size_t buf_size;
00964 int iofd;
00965 time_t checktime;
00966 ast_mutex_t lock;
00967 ast_cond_t cond;
00968 ast_mutex_t init_lock;
00969 ast_cond_t init_cond;
00970
00971
00972
00973
00974 struct {
00975 unsigned short callno;
00976 struct sockaddr_in sin;
00977 unsigned char type;
00978 unsigned char csub;
00979 } ffinfo;
00980
00981
00982
00983 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00984 unsigned char stop;
00985 };
00986
00987
00988 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00989 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00990 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00991
00992 static void *iax2_process_thread(void *data);
00993 static void iax2_destroy(int callno);
00994
00995 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00996 {
00997 ast_mutex_lock(lock);
00998 ast_cond_signal(cond);
00999 ast_mutex_unlock(lock);
01000 }
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS + 1];
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021 static struct ao2_container *iax_peercallno_pvts;
01022
01023
01024
01025
01026
01027
01028
01029
01030 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
01031
01032
01033
01034
01035
01036
01037 static struct ao2_container *iax_transfercallno_pvts;
01038
01039
01040
01041 #define TRUNK_CALL_START IAX_MAX_CALLS / 2
01042
01043
01044 static struct sockaddr_in debugaddr;
01045
01046 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
01047 {
01048 if (iaxdebug ||
01049 (sin && debugaddr.sin_addr.s_addr &&
01050 (!ntohs(debugaddr.sin_port) ||
01051 debugaddr.sin_port == sin->sin_port) &&
01052 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01053 if (iaxdebug) {
01054 iax_showframe(f, fhi, rx, sin, datalen);
01055 } else {
01056 iaxdebug = 1;
01057 iax_showframe(f, fhi, rx, sin, datalen);
01058 iaxdebug = 0;
01059 }
01060 }
01061 }
01062
01063 static void iax_debug_output(const char *data)
01064 {
01065 if (iaxdebug)
01066 ast_verbose("%s", data);
01067 }
01068
01069 static void iax_error_output(const char *data)
01070 {
01071 ast_log(LOG_WARNING, "%s", data);
01072 }
01073
01074 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
01075 {
01076 va_list args;
01077 char buf[1024];
01078
01079 va_start(args, fmt);
01080 vsnprintf(buf, sizeof(buf), fmt, args);
01081 va_end(args);
01082
01083 ast_log(LOG_ERROR, "%s", buf);
01084 }
01085
01086 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01087 {
01088 va_list args;
01089 char buf[1024];
01090
01091 va_start(args, fmt);
01092 vsnprintf(buf, sizeof(buf), fmt, args);
01093 va_end(args);
01094
01095 ast_log(LOG_WARNING, "%s", buf);
01096 }
01097
01098 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01099 {
01100 va_list args;
01101 char buf[1024];
01102
01103 va_start(args, fmt);
01104 vsnprintf(buf, sizeof(buf), fmt, args);
01105 va_end(args);
01106
01107 ast_verbose("%s", buf);
01108 }
01109
01110 static int maxtrunkcall = TRUNK_CALL_START;
01111 static int maxnontrunkcall = 1;
01112
01113 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
01114 static int expire_registry(const void *data);
01115 static int iax2_answer(struct ast_channel *c);
01116 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01117 static int iax2_devicestate(void *data);
01118 static int iax2_digit_begin(struct ast_channel *c, char digit);
01119 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01120 static int iax2_do_register(struct iax2_registry *reg);
01121 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01122 static int iax2_hangup(struct ast_channel *c);
01123 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01124 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01125 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
01126 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01127 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01128 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01129 static int iax2_sendtext(struct ast_channel *c, const char *text);
01130 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01131 static int iax2_transfer(struct ast_channel *c, const char *dest);
01132 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01133 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01134 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01135 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01136 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01137 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01138 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01139 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
01140 static struct ast_frame *iax2_read(struct ast_channel *c);
01141 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01142 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01143 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
01144 static void *iax2_dup_variable_datastore(void *);
01145 static void prune_peers(void);
01146 static void prune_users(void);
01147 static void iax2_free_variable_datastore(void *);
01148
01149 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01150 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01151 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01152 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01153 static void build_rand_pad(unsigned char *buf, ssize_t len);
01154 static struct callno_entry *get_unused_callno(int trunk, int validated);
01155 static int replace_callno(const void *obj);
01156 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01157
01158 static const struct ast_channel_tech iax2_tech = {
01159 .type = "IAX2",
01160 .description = tdesc,
01161 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01162 .properties = AST_CHAN_TP_WANTSJITTER,
01163 .requester = iax2_request,
01164 .devicestate = iax2_devicestate,
01165 .send_digit_begin = iax2_digit_begin,
01166 .send_digit_end = iax2_digit_end,
01167 .send_text = iax2_sendtext,
01168 .send_image = iax2_sendimage,
01169 .send_html = iax2_sendhtml,
01170 .call = iax2_call,
01171 .hangup = iax2_hangup,
01172 .answer = iax2_answer,
01173 .read = iax2_read,
01174 .write = iax2_write,
01175 .write_video = iax2_write,
01176 .indicate = iax2_indicate,
01177 .setoption = iax2_setoption,
01178 .bridge = iax2_bridge,
01179 .transfer = iax2_transfer,
01180 .fixup = iax2_fixup,
01181 .func_channel_read = acf_channel_read,
01182 };
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201 static void iax2_lock_owner(int callno)
01202 {
01203 for (;;) {
01204 if (!iaxs[callno] || !iaxs[callno]->owner) {
01205
01206 break;
01207 }
01208 if (!ast_channel_trylock(iaxs[callno]->owner)) {
01209
01210 break;
01211 }
01212
01213 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01214 }
01215 }
01216
01217 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01218 {
01219
01220
01221
01222 }
01223
01224
01225
01226 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01227 {
01228 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01229 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01230 pvt->owner ? pvt->owner->name : "",
01231 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01232 }
01233
01234
01235 static struct ast_datastore_info iax2_variable_datastore_info = {
01236 .type = "IAX2_VARIABLE",
01237 .duplicate = iax2_dup_variable_datastore,
01238 .destroy = iax2_free_variable_datastore,
01239 };
01240
01241 static void *iax2_dup_variable_datastore(void *old)
01242 {
01243 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01244 struct ast_var_t *oldvar, *newvar;
01245
01246 newlist = ast_calloc(sizeof(*newlist), 1);
01247 if (!newlist) {
01248 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01249 return NULL;
01250 }
01251
01252 AST_LIST_HEAD_INIT(newlist);
01253 AST_LIST_LOCK(oldlist);
01254 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01255 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01256 if (newvar)
01257 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01258 else
01259 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01260 }
01261 AST_LIST_UNLOCK(oldlist);
01262 return newlist;
01263 }
01264
01265 static void iax2_free_variable_datastore(void *old)
01266 {
01267 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01268 struct ast_var_t *oldvar;
01269
01270 AST_LIST_LOCK(oldlist);
01271 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01272 ast_free(oldvar);
01273 }
01274 AST_LIST_UNLOCK(oldlist);
01275 AST_LIST_HEAD_DESTROY(oldlist);
01276 ast_free(oldlist);
01277 }
01278
01279
01280
01281
01282
01283 static void insert_idle_thread(struct iax2_thread *thread)
01284 {
01285 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01286 AST_LIST_LOCK(&dynamic_list);
01287 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01288 AST_LIST_UNLOCK(&dynamic_list);
01289 } else {
01290 AST_LIST_LOCK(&idle_list);
01291 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01292 AST_LIST_UNLOCK(&idle_list);
01293 }
01294
01295 return;
01296 }
01297
01298 static struct iax2_thread *find_idle_thread(void)
01299 {
01300 struct iax2_thread *thread = NULL;
01301
01302
01303 AST_LIST_LOCK(&idle_list);
01304 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01305 AST_LIST_UNLOCK(&idle_list);
01306
01307
01308 if (thread) {
01309 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01310 return thread;
01311 }
01312
01313
01314 AST_LIST_LOCK(&dynamic_list);
01315 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01316 AST_LIST_UNLOCK(&dynamic_list);
01317
01318
01319 if (thread) {
01320 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01321 return thread;
01322 }
01323
01324
01325 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01326 return NULL;
01327
01328
01329 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01330 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01331 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01332
01333
01334 ast_mutex_init(&thread->lock);
01335 ast_cond_init(&thread->cond, NULL);
01336 ast_mutex_init(&thread->init_lock);
01337 ast_cond_init(&thread->init_cond, NULL);
01338 ast_mutex_lock(&thread->init_lock);
01339
01340
01341 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01342 ast_cond_destroy(&thread->cond);
01343 ast_mutex_destroy(&thread->lock);
01344 ast_mutex_unlock(&thread->init_lock);
01345 ast_cond_destroy(&thread->init_cond);
01346 ast_mutex_destroy(&thread->init_lock);
01347 ast_free(thread);
01348 return NULL;
01349 }
01350
01351
01352
01353 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01354
01355
01356 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01357
01358
01359 ast_mutex_unlock(&thread->init_lock);
01360
01361 return thread;
01362 }
01363
01364 #ifdef SCHED_MULTITHREADED
01365 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01366 {
01367 struct iax2_thread *thread = NULL;
01368 static time_t lasterror;
01369 static time_t t;
01370
01371 thread = find_idle_thread();
01372
01373 if (thread != NULL) {
01374 thread->schedfunc = func;
01375 thread->scheddata = data;
01376 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01377 #ifdef DEBUG_SCHED_MULTITHREAD
01378 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01379 #endif
01380 signal_condition(&thread->lock, &thread->cond);
01381 return 0;
01382 }
01383 time(&t);
01384 if (t != lasterror)
01385 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01386 lasterror = t;
01387
01388 return -1;
01389 }
01390 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01391 #endif
01392
01393 static int iax2_sched_replace(int id, struct ast_sched_thread *st, int when,
01394 ast_sched_cb callback, const void *data)
01395 {
01396 ast_sched_thread_del(st, id);
01397
01398 return ast_sched_thread_add(st, when, callback, data);
01399 }
01400
01401 static int iax2_sched_add(struct ast_sched_thread *st, int when,
01402 ast_sched_cb callback, const void *data)
01403 {
01404 return ast_sched_thread_add(st, when, callback, data);
01405 }
01406
01407 static int send_ping(const void *data);
01408
01409 static void __send_ping(const void *data)
01410 {
01411 int callno = (long) data;
01412
01413 ast_mutex_lock(&iaxsl[callno]);
01414
01415 if (iaxs[callno]) {
01416 if (iaxs[callno]->peercallno) {
01417 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01418 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01419 } else {
01420
01421 iaxs[callno]->pingid = -1;
01422 }
01423 } else {
01424 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01425 }
01426
01427 ast_mutex_unlock(&iaxsl[callno]);
01428 }
01429
01430 static int send_ping(const void *data)
01431 {
01432 #ifdef SCHED_MULTITHREADED
01433 if (schedule_action(__send_ping, data))
01434 #endif
01435 __send_ping(data);
01436
01437 return 0;
01438 }
01439
01440 static void encmethods_to_str(int e, struct ast_str *buf)
01441 {
01442 ast_str_set(&buf, 0, "(");
01443 if (e & IAX_ENCRYPT_AES128) {
01444 ast_str_append(&buf, 0, "aes128");
01445 }
01446 if (e & IAX_ENCRYPT_KEYROTATE) {
01447 ast_str_append(&buf, 0, ",keyrotate");
01448 }
01449 if (ast_str_strlen(buf) > 1) {
01450 ast_str_append(&buf, 0, ")");
01451 } else {
01452 ast_str_set(&buf, 0, "No");
01453 }
01454 }
01455
01456 static int get_encrypt_methods(const char *s)
01457 {
01458 int e;
01459 if (!strcasecmp(s, "aes128"))
01460 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01461 else if (ast_true(s))
01462 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01463 else
01464 e = 0;
01465 return e;
01466 }
01467
01468 static int send_lagrq(const void *data);
01469
01470 static void __send_lagrq(const void *data)
01471 {
01472 int callno = (long) data;
01473
01474 ast_mutex_lock(&iaxsl[callno]);
01475
01476 if (iaxs[callno]) {
01477 if (iaxs[callno]->peercallno) {
01478 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01479 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01480 } else {
01481
01482 iaxs[callno]->lagid = -1;
01483 }
01484 } else {
01485 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01486 }
01487
01488 ast_mutex_unlock(&iaxsl[callno]);
01489 }
01490
01491 static int send_lagrq(const void *data)
01492 {
01493 #ifdef SCHED_MULTITHREADED
01494 if (schedule_action(__send_lagrq, data))
01495 #endif
01496 __send_lagrq(data);
01497
01498 return 0;
01499 }
01500
01501 static unsigned char compress_subclass(int subclass)
01502 {
01503 int x;
01504 int power=-1;
01505
01506 if (subclass < IAX_FLAG_SC_LOG)
01507 return subclass;
01508
01509 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01510 if (subclass & (1 << x)) {
01511 if (power > -1) {
01512 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01513 return 0;
01514 } else
01515 power = x;
01516 }
01517 }
01518 return power | IAX_FLAG_SC_LOG;
01519 }
01520
01521 static int uncompress_subclass(unsigned char csub)
01522 {
01523
01524 if (csub & IAX_FLAG_SC_LOG) {
01525
01526 if (csub == 0xff)
01527 return -1;
01528 else
01529 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01530 }
01531 else
01532 return csub;
01533 }
01534
01535
01536
01537
01538 static int peer_hash_cb(const void *obj, const int flags)
01539 {
01540 const struct iax2_peer *peer = obj;
01541
01542 return ast_str_hash(peer->name);
01543 }
01544
01545
01546
01547
01548 static int peer_cmp_cb(void *obj, void *arg, int flags)
01549 {
01550 struct iax2_peer *peer = obj, *peer2 = arg;
01551
01552 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01553 }
01554
01555
01556
01557
01558 static int user_hash_cb(const void *obj, const int flags)
01559 {
01560 const struct iax2_user *user = obj;
01561
01562 return ast_str_hash(user->name);
01563 }
01564
01565
01566
01567
01568 static int user_cmp_cb(void *obj, void *arg, int flags)
01569 {
01570 struct iax2_user *user = obj, *user2 = arg;
01571
01572 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01573 }
01574
01575
01576
01577
01578
01579 static struct iax2_peer *find_peer(const char *name, int realtime)
01580 {
01581 struct iax2_peer *peer = NULL;
01582 struct iax2_peer tmp_peer = {
01583 .name = name,
01584 };
01585
01586 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01587
01588
01589 if(!peer && realtime)
01590 peer = realtime_peer(name, NULL);
01591
01592 return peer;
01593 }
01594
01595 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01596 {
01597 ao2_ref(peer, +1);
01598 return peer;
01599 }
01600
01601 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01602 {
01603 ao2_ref(peer, -1);
01604 return NULL;
01605 }
01606
01607 static struct iax2_user *find_user(const char *name)
01608 {
01609 struct iax2_user tmp_user = {
01610 .name = name,
01611 };
01612
01613 return ao2_find(users, &tmp_user, OBJ_POINTER);
01614 }
01615 static inline struct iax2_user *user_ref(struct iax2_user *user)
01616 {
01617 ao2_ref(user, +1);
01618 return user;
01619 }
01620
01621 static inline struct iax2_user *user_unref(struct iax2_user *user)
01622 {
01623 ao2_ref(user, -1);
01624 return NULL;
01625 }
01626
01627 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01628 {
01629 struct iax2_peer *peer = NULL;
01630 int res = 0;
01631 struct ao2_iterator i;
01632
01633 i = ao2_iterator_init(peers, 0);
01634 while ((peer = ao2_iterator_next(&i))) {
01635 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01636 (peer->addr.sin_port == sin.sin_port)) {
01637 ast_copy_string(host, peer->name, len);
01638 peer_unref(peer);
01639 res = 1;
01640 break;
01641 }
01642 peer_unref(peer);
01643 }
01644 ao2_iterator_destroy(&i);
01645
01646 if (!peer) {
01647 peer = realtime_peer(NULL, &sin);
01648 if (peer) {
01649 ast_copy_string(host, peer->name, len);
01650 peer_unref(peer);
01651 res = 1;
01652 }
01653 }
01654
01655 return res;
01656 }
01657
01658
01659
01660 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01661 {
01662
01663 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01664 struct iax2_user *user;
01665 struct iax2_user tmp_user = {
01666 .name = pvt->username,
01667 };
01668
01669 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01670 if (user) {
01671 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01672 user_unref(user);
01673 }
01674
01675 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01676 }
01677
01678 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01679 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01680 ast_sched_thread_del(sched, pvt->autoid);
01681 ast_sched_thread_del(sched, pvt->authid);
01682 ast_sched_thread_del(sched, pvt->initid);
01683 ast_sched_thread_del(sched, pvt->jbid);
01684 ast_sched_thread_del(sched, pvt->keyrotateid);
01685 }
01686
01687 static void iax2_frame_free(struct iax_frame *fr)
01688 {
01689 ast_sched_thread_del(sched, fr->retrans);
01690 iax_frame_free(fr);
01691 }
01692
01693 static int scheduled_destroy(const void *vid)
01694 {
01695 unsigned short callno = PTR_TO_CALLNO(vid);
01696 ast_mutex_lock(&iaxsl[callno]);
01697 if (iaxs[callno]) {
01698 if (option_debug) {
01699 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01700 }
01701 iax2_destroy(callno);
01702 }
01703 ast_mutex_unlock(&iaxsl[callno]);
01704 return 0;
01705 }
01706
01707 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01708 {
01709 ast_free(s->f.data.ptr);
01710 ast_free(s);
01711 }
01712
01713
01714
01715 static void send_signaling(struct chan_iax2_pvt *pvt)
01716 {
01717 struct signaling_queue_entry *s = NULL;
01718
01719 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01720 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01721 free_signaling_queue_entry(s);
01722 }
01723 pvt->hold_signaling = 0;
01724 }
01725
01726
01727
01728 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01729 {
01730 struct signaling_queue_entry *new;
01731
01732 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01733 return 1;
01734 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01735 return -1;
01736 }
01737
01738 memcpy(&new->f, f, sizeof(new->f));
01739
01740 if (new->f.datalen) {
01741 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01742 free_signaling_queue_entry(new);
01743 return -1;
01744 }
01745 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01746 }
01747 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01748
01749 return 0;
01750 }
01751
01752 static void pvt_destructor(void *obj)
01753 {
01754 struct chan_iax2_pvt *pvt = obj;
01755 struct iax_frame *cur = NULL;
01756 struct signaling_queue_entry *s = NULL;
01757
01758 ast_mutex_lock(&iaxsl[pvt->callno]);
01759 iax2_destroy_helper(pvt);
01760 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01761 pvt->callno_entry = NULL;
01762 ast_mutex_unlock(&iaxsl[pvt->callno]);
01763
01764
01765 ast_set_flag(pvt, IAX_ALREADYGONE);
01766
01767 AST_LIST_LOCK(&frame_queue);
01768 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01769
01770 if (cur->callno == pvt->callno) {
01771 cur->retries = -1;
01772 }
01773 }
01774 AST_LIST_UNLOCK(&frame_queue);
01775
01776 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01777 free_signaling_queue_entry(s);
01778 }
01779
01780 if (pvt->reg) {
01781 pvt->reg->callno = 0;
01782 }
01783
01784 if (!pvt->owner) {
01785 jb_frame frame;
01786 if (pvt->vars) {
01787 ast_variables_destroy(pvt->vars);
01788 pvt->vars = NULL;
01789 }
01790
01791 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01792 iax2_frame_free(frame.data);
01793 }
01794
01795 jb_destroy(pvt->jb);
01796 ast_string_field_free_memory(pvt);
01797 }
01798 }
01799
01800 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01801 {
01802 struct chan_iax2_pvt *tmp;
01803 jb_conf jbconf;
01804
01805 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01806 return NULL;
01807 }
01808
01809 if (ast_string_field_init(tmp, 32)) {
01810 ao2_ref(tmp, -1);
01811 tmp = NULL;
01812 return NULL;
01813 }
01814
01815 tmp->prefs = prefs;
01816 tmp->pingid = -1;
01817 tmp->lagid = -1;
01818 tmp->autoid = -1;
01819 tmp->authid = -1;
01820 tmp->initid = -1;
01821 tmp->keyrotateid = -1;
01822
01823 ast_string_field_set(tmp,exten, "s");
01824 ast_string_field_set(tmp,host, host);
01825
01826 tmp->jb = jb_new();
01827 tmp->jbid = -1;
01828 jbconf.max_jitterbuf = maxjitterbuffer;
01829 jbconf.resync_threshold = resyncthreshold;
01830 jbconf.max_contig_interp = maxjitterinterps;
01831 jbconf.target_extra = jittertargetextra;
01832 jb_setconf(tmp->jb,&jbconf);
01833
01834 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01835
01836 tmp->hold_signaling = 1;
01837 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01838
01839 return tmp;
01840 }
01841
01842 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01843 {
01844 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01845 if (new) {
01846 size_t afdatalen = new->afdatalen;
01847 memcpy(new, fr, sizeof(*new));
01848 iax_frame_wrap(new, &fr->af);
01849 new->afdatalen = afdatalen;
01850 new->data = NULL;
01851 new->datalen = 0;
01852 new->direction = DIRECTION_INGRESS;
01853 new->retrans = -1;
01854 }
01855 return new;
01856 }
01857
01858
01859 enum {
01860
01861 NEW_PREVENT = 0,
01862
01863 NEW_ALLOW = 1,
01864
01865 NEW_FORCE = 2,
01866
01867
01868 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01869 };
01870
01871 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01872 {
01873 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01874 (cur->addr.sin_port == sin->sin_port)) {
01875
01876 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01877 (check_dcallno ? dcallno == cur->callno : 1) ) {
01878
01879 return 1;
01880 }
01881 }
01882 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01883 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01884
01885 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01886 return 1;
01887 }
01888 return 0;
01889 }
01890
01891 static void update_max_trunk(void)
01892 {
01893 int max = TRUNK_CALL_START;
01894 int x;
01895
01896
01897 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01898 if (iaxs[x]) {
01899 max = x + 1;
01900 }
01901 }
01902
01903 maxtrunkcall = max;
01904 if (iaxdebug)
01905 ast_debug(1, "New max trunk callno is %d\n", max);
01906 }
01907
01908 static void update_max_nontrunk(void)
01909 {
01910 int max = 1;
01911 int x;
01912
01913 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01914 if (iaxs[x])
01915 max = x + 1;
01916 }
01917 maxnontrunkcall = max;
01918 if (iaxdebug)
01919 ast_debug(1, "New max nontrunk callno is %d\n", max);
01920 }
01921
01922 static int make_trunk(unsigned short callno, int locked)
01923 {
01924 int x;
01925 int res= 0;
01926 struct callno_entry *callno_entry;
01927 if (iaxs[callno]->oseqno) {
01928 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01929 return -1;
01930 }
01931 if (callno & TRUNK_CALL_START) {
01932 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01933 return -1;
01934 }
01935
01936 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
01937 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01938 return -1;
01939 }
01940
01941 x = callno_entry->callno;
01942 ast_mutex_lock(&iaxsl[x]);
01943
01944
01945
01946
01947
01948 ast_sched_thread_del(sched, iaxs[callno]->pingid);
01949 ast_sched_thread_del(sched, iaxs[callno]->lagid);
01950 iaxs[x] = iaxs[callno];
01951 iaxs[x]->callno = x;
01952
01953
01954
01955 if (iaxs[x]->callno_entry) {
01956 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
01957 }
01958 iaxs[x]->callno_entry = callno_entry;
01959
01960 iaxs[callno] = NULL;
01961
01962 iaxs[x]->pingid = iax2_sched_add(sched,
01963 ping_time * 1000, send_ping, (void *)(long)x);
01964 iaxs[x]->lagid = iax2_sched_add(sched,
01965 lagrq_time * 1000, send_lagrq, (void *)(long)x);
01966
01967 if (locked)
01968 ast_mutex_unlock(&iaxsl[callno]);
01969 res = x;
01970 if (!locked)
01971 ast_mutex_unlock(&iaxsl[x]);
01972
01973 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01974
01975 update_max_trunk();
01976 update_max_nontrunk();
01977 return res;
01978 }
01979
01980 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01981 {
01982 if (!pvt->transfercallno) {
01983 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01984 return;
01985 }
01986
01987 ao2_link(iax_transfercallno_pvts, pvt);
01988 }
01989
01990 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01991 {
01992 if (!pvt->transfercallno) {
01993 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01994 return;
01995 }
01996
01997 ao2_unlink(iax_transfercallno_pvts, pvt);
01998 }
01999 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
02000 {
02001 if (!pvt->peercallno) {
02002 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02003 return;
02004 }
02005
02006 ao2_link(iax_peercallno_pvts, pvt);
02007 }
02008
02009 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
02010 {
02011 if (!pvt->peercallno) {
02012 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02013 return;
02014 }
02015
02016 ao2_unlink(iax_peercallno_pvts, pvt);
02017 }
02018
02019 static int addr_range_delme_cb(void *obj, void *arg, int flags)
02020 {
02021 struct addr_range *lim = obj;
02022 lim->delme = 1;
02023 return 0;
02024 }
02025
02026 static int addr_range_hash_cb(const void *obj, const int flags)
02027 {
02028 const struct addr_range *lim = obj;
02029 return abs((int) lim->ha.netaddr.s_addr);
02030 }
02031
02032 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
02033 {
02034 struct addr_range *lim1 = obj, *lim2 = arg;
02035 return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
02036 (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
02037 CMP_MATCH | CMP_STOP : 0;
02038 }
02039
02040 static int peercnt_hash_cb(const void *obj, const int flags)
02041 {
02042 const struct peercnt *peercnt = obj;
02043 return abs((int) peercnt->addr);
02044 }
02045
02046 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
02047 {
02048 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02049 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02050 }
02051
02052 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
02053 {
02054 struct addr_range *addr_range = obj;
02055 struct sockaddr_in *sin = arg;
02056
02057 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
02058 return CMP_MATCH | CMP_STOP;
02059 }
02060 return 0;
02061 }
02062
02063
02064
02065
02066
02067
02068 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
02069 {
02070 struct addr_range *addr_range;
02071 struct iax2_peer *peer = NULL;
02072 struct iax2_user *user = NULL;
02073
02074 const char *find = S_OR(name, "guest");
02075 int res = 1;
02076 int optional = 0;
02077 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02078
02079
02080
02081
02082
02083
02084
02085 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02086 ao2_ref(addr_range, -1);
02087 optional = 1;
02088 }
02089
02090
02091 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02092 calltoken_required = user->calltoken_required;
02093 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02094 calltoken_required = user->calltoken_required;
02095 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02096 calltoken_required = peer->calltoken_required;
02097 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02098 calltoken_required = peer->calltoken_required;
02099 }
02100
02101 if (peer) {
02102 peer_unref(peer);
02103 }
02104 if (user) {
02105 user_unref(user);
02106 }
02107
02108 ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required);
02109 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02110 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02111 res = 0;
02112 }
02113
02114 return res;
02115 }
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127 static void set_peercnt_limit(struct peercnt *peercnt)
02128 {
02129 uint16_t limit = global_maxcallno;
02130 struct addr_range *addr_range;
02131 struct sockaddr_in sin = {
02132 .sin_addr.s_addr = peercnt->addr,
02133 };
02134
02135
02136 if (peercnt->reg && peercnt->limit) {
02137 return;
02138 }
02139
02140 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02141 limit = addr_range->limit;
02142 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02143 ao2_ref(addr_range, -1);
02144 }
02145
02146 peercnt->limit = limit;
02147 }
02148
02149
02150
02151
02152
02153 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02154 {
02155 struct peercnt *peercnt = obj;
02156
02157 set_peercnt_limit(peercnt);
02158 ast_debug(1, "Reset limits for peercnts table\n");
02159
02160 return 0;
02161 }
02162
02163
02164
02165
02166
02167 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02168 {
02169 struct addr_range *addr_range = obj;
02170
02171 return addr_range->delme ? CMP_MATCH : 0;
02172 }
02173
02174
02175
02176
02177
02178 static void peercnt_modify(unsigned char reg, uint16_t limit, struct sockaddr_in *sin)
02179 {
02180
02181 struct peercnt *peercnt;
02182 struct peercnt tmp = {
02183 .addr = sin->sin_addr.s_addr,
02184 };
02185
02186 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02187 peercnt->reg = reg;
02188 if (limit) {
02189 peercnt->limit = limit;
02190 } else {
02191 set_peercnt_limit(peercnt);
02192 }
02193 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg);
02194 ao2_ref(peercnt, -1);
02195 }
02196 }
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206 static int peercnt_add(struct sockaddr_in *sin)
02207 {
02208 struct peercnt *peercnt;
02209 unsigned long addr = sin->sin_addr.s_addr;
02210 int res = 0;
02211 struct peercnt tmp = {
02212 .addr = addr,
02213 };
02214
02215
02216
02217
02218
02219
02220
02221 ao2_lock(peercnts);
02222 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02223 ao2_lock(peercnt);
02224 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02225 ao2_lock(peercnt);
02226
02227 peercnt->addr = addr;
02228 set_peercnt_limit(peercnt);
02229
02230
02231 ao2_link(peercnts, peercnt);
02232 } else {
02233 ao2_unlock(peercnts);
02234 return -1;
02235 }
02236
02237
02238 if (peercnt->limit > peercnt->cur) {
02239 peercnt->cur++;
02240 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02241 } else {
02242 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02243 res = -1;
02244 }
02245
02246
02247 ao2_unlock(peercnt);
02248 ao2_unlock(peercnts);
02249 ao2_ref(peercnt, -1);
02250
02251 return res;
02252 }
02253
02254
02255
02256
02257
02258 static void peercnt_remove(struct peercnt *peercnt)
02259 {
02260 struct sockaddr_in sin = {
02261 .sin_addr.s_addr = peercnt->addr,
02262 };
02263
02264 if (peercnt) {
02265
02266
02267
02268 ao2_lock(peercnts);
02269 peercnt->cur--;
02270 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02271
02272 if (peercnt->cur == 0) {
02273 ao2_unlink(peercnts, peercnt);
02274 }
02275 ao2_unlock(peercnts);
02276 }
02277 }
02278
02279
02280
02281
02282
02283 static int peercnt_remove_cb(const void *obj)
02284 {
02285 struct peercnt *peercnt = (struct peercnt *) obj;
02286
02287 peercnt_remove(peercnt);
02288 ao2_ref(peercnt, -1);
02289
02290 return 0;
02291 }
02292
02293
02294
02295
02296
02297 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02298 {
02299 struct peercnt *peercnt;
02300 struct peercnt tmp = {
02301 .addr = sin->sin_addr.s_addr,
02302 };
02303
02304 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02305 peercnt_remove(peercnt);
02306 ao2_ref(peercnt, -1);
02307 }
02308 return 0;
02309 }
02310
02311
02312
02313
02314
02315 static void build_callno_limits(struct ast_variable *v)
02316 {
02317 struct addr_range *addr_range = NULL;
02318 struct addr_range tmp;
02319 struct ast_ha *ha;
02320 int limit;
02321 int error;
02322 int found;
02323
02324 for (; v; v = v->next) {
02325 limit = -1;
02326 error = 0;
02327 found = 0;
02328 ha = ast_append_ha("permit", v->name, NULL, &error);
02329
02330
02331 if (error) {
02332 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02333 continue;
02334 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02335 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02336 ast_free_ha(ha);
02337 continue;
02338 }
02339
02340 ast_copy_ha(ha, &tmp.ha);
02341
02342 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02343 ao2_lock(addr_range);
02344 found = 1;
02345 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02346 ast_free_ha(ha);
02347 return;
02348 }
02349
02350
02351 ast_copy_ha(ha, &addr_range->ha);
02352 ast_free_ha(ha);
02353 addr_range->limit = limit;
02354 addr_range->delme = 0;
02355
02356
02357 if (found) {
02358 ao2_unlock(addr_range);
02359 } else {
02360 ao2_link(callno_limits, addr_range);
02361 }
02362 ao2_ref(addr_range, -1);
02363 }
02364 }
02365
02366
02367
02368
02369
02370 static int add_calltoken_ignore(const char *addr)
02371 {
02372 struct addr_range tmp;
02373 struct addr_range *addr_range = NULL;
02374 struct ast_ha *ha = NULL;
02375 int error = 0;
02376
02377 if (ast_strlen_zero(addr)) {
02378 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02379 return -1;
02380 }
02381
02382 ha = ast_append_ha("permit", addr, NULL, &error);
02383
02384
02385 if (error) {
02386 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02387 return -1;
02388 }
02389
02390 ast_copy_ha(ha, &tmp.ha);
02391
02392 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02393 ao2_lock(addr_range);
02394 addr_range->delme = 0;
02395 ao2_unlock(addr_range);
02396 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02397
02398 ast_copy_ha(ha, &addr_range->ha);
02399 ao2_link(calltoken_ignores, addr_range);
02400 } else {
02401 ast_free_ha(ha);
02402 return -1;
02403 }
02404
02405 ast_free_ha(ha);
02406 ao2_ref(addr_range, -1);
02407
02408 return 0;
02409 }
02410
02411 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02412 {
02413 struct ao2_iterator i;
02414 struct peercnt *peercnt;
02415 struct sockaddr_in sin;
02416 int found = 0;
02417
02418 switch (cmd) {
02419 case CLI_INIT:
02420 e->command = "iax2 show callnumber usage";
02421 e->usage =
02422 "Usage: iax2 show callnumber usage <ip address (optional)>\n"
02423 " Shows current ip addresses which are consuming iax2 call numbers\n";
02424 return NULL;
02425 case CLI_GENERATE:
02426 return NULL;
02427 case CLI_HANDLER:
02428 if (a->argc < 4 || a->argc > 5)
02429 return CLI_SHOWUSAGE;
02430
02431 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02432 i = ao2_iterator_init(peercnts, 0);
02433 while ((peercnt = ao2_iterator_next(&i))) {
02434 sin.sin_addr.s_addr = peercnt->addr;
02435 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02436 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02437 found = 1;
02438 break;
02439 } else {
02440 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02441 }
02442 ao2_ref(peercnt, -1);
02443 }
02444 ao2_iterator_destroy(&i);
02445
02446 if (a->argc == 4) {
02447 ast_cli(a->fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
02448 } else if (a->argc == 5 && !found) {
02449 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02450 }
02451
02452 return CLI_SUCCESS;
02453 default:
02454 return NULL;
02455 }
02456 }
02457
02458 static struct callno_entry *get_unused_callno(int trunk, int validated)
02459 {
02460 struct callno_entry *callno_entry = NULL;
02461 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02462 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02463
02464 return NULL;
02465 }
02466
02467
02468
02469 ao2_lock(callno_pool);
02470
02471
02472
02473
02474 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02475 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02476 ao2_unlock(callno_pool);
02477 return NULL;
02478 }
02479
02480
02481
02482 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02483
02484 if (callno_entry) {
02485 callno_entry->validated = validated;
02486 if (!validated) {
02487 total_nonval_callno_used++;
02488 }
02489 }
02490
02491 ao2_unlock(callno_pool);
02492 return callno_entry;
02493 }
02494
02495 static int replace_callno(const void *obj)
02496 {
02497 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02498
02499
02500
02501 ao2_lock(callno_pool);
02502
02503 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02504 total_nonval_callno_used--;
02505 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02506 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02507 }
02508
02509 if (callno_entry->callno < TRUNK_CALL_START) {
02510 ao2_link(callno_pool, callno_entry);
02511 } else {
02512 ao2_link(callno_pool_trunk, callno_entry);
02513 }
02514 ao2_ref(callno_entry, -1);
02515
02516 ao2_unlock(callno_pool);
02517 return 0;
02518 }
02519
02520 static int callno_hash(const void *obj, const int flags)
02521 {
02522 return abs(ast_random());
02523 }
02524
02525 static int create_callno_pools(void)
02526 {
02527 uint16_t i;
02528
02529 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02530 return -1;
02531 }
02532
02533 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02534 return -1;
02535 }
02536
02537
02538 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02539 struct callno_entry *callno_entry;
02540
02541 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02542 return -1;
02543 }
02544
02545 callno_entry->callno = i;
02546
02547 if (i < TRUNK_CALL_START) {
02548 ao2_link(callno_pool, callno_entry);
02549 } else {
02550 ao2_link(callno_pool_trunk, callno_entry);
02551 }
02552
02553 ao2_ref(callno_entry, -1);
02554 }
02555
02556 return 0;
02557 }
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02568 {
02569 int i;
02570 struct peercnt *peercnt;
02571 struct peercnt tmp = {
02572 .addr = sin->sin_addr.s_addr,
02573 };
02574
02575 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02576
02577 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02578 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02579 if (i == -1) {
02580 ao2_ref(peercnt, -1);
02581 }
02582 }
02583
02584 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02585 }
02586
02587
02588
02589
02590
02591
02592
02593
02594 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02595 {
02596 if (frametype != AST_FRAME_IAX) {
02597 return 0;
02598 }
02599 switch (subclass) {
02600 case IAX_COMMAND_NEW:
02601 case IAX_COMMAND_REGREQ:
02602 case IAX_COMMAND_FWDOWNL:
02603 case IAX_COMMAND_REGREL:
02604 return 1;
02605 case IAX_COMMAND_POKE:
02606 if (!inbound) {
02607 return 1;
02608 }
02609 break;
02610 }
02611 return 0;
02612 }
02613
02614
02615
02616
02617 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02618 {
02619 int res = 0;
02620 int x;
02621
02622
02623 int validated = (new > NEW_ALLOW) ? 1 : 0;
02624 char host[80];
02625
02626 if (new <= NEW_ALLOW) {
02627 if (callno) {
02628 struct chan_iax2_pvt *pvt;
02629 struct chan_iax2_pvt tmp_pvt = {
02630 .callno = dcallno,
02631 .peercallno = callno,
02632 .transfercallno = callno,
02633
02634 .frames_received = check_dcallno,
02635 };
02636
02637 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02638
02639 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02640 if (return_locked) {
02641 ast_mutex_lock(&iaxsl[pvt->callno]);
02642 }
02643 res = pvt->callno;
02644 ao2_ref(pvt, -1);
02645 pvt = NULL;
02646 return res;
02647 }
02648
02649 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02650 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02651 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02652 if (return_locked) {
02653 ast_mutex_lock(&iaxsl[pvt->callno]);
02654 }
02655 res = pvt->callno;
02656 ao2_ref(pvt, -1);
02657 pvt = NULL;
02658 return res;
02659 }
02660 }
02661
02662
02663 if (dcallno) {
02664 ast_mutex_lock(&iaxsl[dcallno]);
02665 }
02666 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02667 iaxs[dcallno]->peercallno = callno;
02668 res = dcallno;
02669 store_by_peercallno(iaxs[dcallno]);
02670 if (!res || !return_locked) {
02671 ast_mutex_unlock(&iaxsl[dcallno]);
02672 }
02673 return res;
02674 }
02675 if (dcallno) {
02676 ast_mutex_unlock(&iaxsl[dcallno]);
02677 }
02678 #ifdef IAX_OLD_FIND
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690 for (x = 1; !res && x < maxnontrunkcall; x++) {
02691 ast_mutex_lock(&iaxsl[x]);
02692 if (iaxs[x]) {
02693
02694 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02695 res = x;
02696 }
02697 }
02698 if (!res || !return_locked)
02699 ast_mutex_unlock(&iaxsl[x]);
02700 }
02701 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02702 ast_mutex_lock(&iaxsl[x]);
02703 if (iaxs[x]) {
02704
02705 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02706 res = x;
02707 }
02708 }
02709 if (!res || !return_locked)
02710 ast_mutex_unlock(&iaxsl[x]);
02711 }
02712 #endif
02713 }
02714 if (!res && (new >= NEW_ALLOW)) {
02715 struct callno_entry *callno_entry;
02716
02717
02718
02719
02720
02721
02722 if (!iax2_getpeername(*sin, host, sizeof(host)))
02723 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02724
02725 if (peercnt_add(sin)) {
02726
02727
02728 return 0;
02729 }
02730
02731 if (!(callno_entry = get_unused_callno(0, validated))) {
02732
02733
02734 peercnt_remove_by_addr(sin);
02735 ast_log(LOG_WARNING, "No more space\n");
02736 return 0;
02737 }
02738 x = callno_entry->callno;
02739 ast_mutex_lock(&iaxsl[x]);
02740
02741 iaxs[x] = new_iax(sin, host);
02742 update_max_nontrunk();
02743 if (iaxs[x]) {
02744 if (iaxdebug)
02745 ast_debug(1, "Creating new call structure %d\n", x);
02746 iaxs[x]->callno_entry = callno_entry;
02747 iaxs[x]->sockfd = sockfd;
02748 iaxs[x]->addr.sin_port = sin->sin_port;
02749 iaxs[x]->addr.sin_family = sin->sin_family;
02750 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02751 iaxs[x]->peercallno = callno;
02752 iaxs[x]->callno = x;
02753 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02754 iaxs[x]->expiry = min_reg_expire;
02755 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02756 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02757 iaxs[x]->amaflags = amaflags;
02758 ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT);
02759 ast_string_field_set(iaxs[x], accountcode, accountcode);
02760 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02761 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02762 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02763
02764 if (iaxs[x]->peercallno) {
02765 store_by_peercallno(iaxs[x]);
02766 }
02767 } else {
02768 ast_log(LOG_WARNING, "Out of resources\n");
02769 ast_mutex_unlock(&iaxsl[x]);
02770 replace_callno(callno_entry);
02771 return 0;
02772 }
02773 if (!return_locked)
02774 ast_mutex_unlock(&iaxsl[x]);
02775 res = x;
02776 }
02777 return res;
02778 }
02779
02780 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02781
02782 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02783 }
02784
02785 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02786
02787 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02788 }
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800 static int iax2_queue_frame(int callno, struct ast_frame *f)
02801 {
02802 iax2_lock_owner(callno);
02803 if (iaxs[callno] && iaxs[callno]->owner) {
02804 ast_queue_frame(iaxs[callno]->owner, f);
02805 ast_channel_unlock(iaxs[callno]->owner);
02806 }
02807 return 0;
02808 }
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823 static int iax2_queue_hangup(int callno)
02824 {
02825 iax2_lock_owner(callno);
02826 if (iaxs[callno] && iaxs[callno]->owner) {
02827 ast_queue_hangup(iaxs[callno]->owner);
02828 ast_channel_unlock(iaxs[callno]->owner);
02829 }
02830 return 0;
02831 }
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846 static int iax2_queue_control_data(int callno,
02847 enum ast_control_frame_type control, const void *data, size_t datalen)
02848 {
02849 iax2_lock_owner(callno);
02850 if (iaxs[callno] && iaxs[callno]->owner) {
02851 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02852 ast_channel_unlock(iaxs[callno]->owner);
02853 }
02854 return 0;
02855 }
02856 static void destroy_firmware(struct iax_firmware *cur)
02857 {
02858
02859 if (cur->fwh) {
02860 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02861 }
02862 close(cur->fd);
02863 ast_free(cur);
02864 }
02865
02866 static int try_firmware(char *s)
02867 {
02868 struct stat stbuf;
02869 struct iax_firmware *cur = NULL;
02870 int ifd, fd, res, len, chunk;
02871 struct ast_iax2_firmware_header *fwh, fwh2;
02872 struct MD5Context md5;
02873 unsigned char sum[16], buf[1024];
02874 char *s2, *last;
02875
02876 if (!(s2 = alloca(strlen(s) + 100))) {
02877 ast_log(LOG_WARNING, "Alloca failed!\n");
02878 return -1;
02879 }
02880
02881 last = strrchr(s, '/');
02882 if (last)
02883 last++;
02884 else
02885 last = s;
02886
02887 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02888
02889 if ((res = stat(s, &stbuf) < 0)) {
02890 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02891 return -1;
02892 }
02893
02894
02895 if (S_ISDIR(stbuf.st_mode))
02896 return -1;
02897 ifd = open(s, O_RDONLY);
02898 if (ifd < 0) {
02899 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02900 return -1;
02901 }
02902 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02903 if (fd < 0) {
02904 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02905 close(ifd);
02906 return -1;
02907 }
02908
02909 unlink(s2);
02910
02911
02912 len = stbuf.st_size;
02913 while(len) {
02914 chunk = len;
02915 if (chunk > sizeof(buf))
02916 chunk = sizeof(buf);
02917 res = read(ifd, buf, chunk);
02918 if (res != chunk) {
02919 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02920 close(ifd);
02921 close(fd);
02922 return -1;
02923 }
02924 res = write(fd, buf, chunk);
02925 if (res != chunk) {
02926 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02927 close(ifd);
02928 close(fd);
02929 return -1;
02930 }
02931 len -= chunk;
02932 }
02933 close(ifd);
02934
02935 lseek(fd, 0, SEEK_SET);
02936 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02937 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02938 close(fd);
02939 return -1;
02940 }
02941 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02942 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02943 close(fd);
02944 return -1;
02945 }
02946 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02947 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02948 close(fd);
02949 return -1;
02950 }
02951 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02952 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02953 close(fd);
02954 return -1;
02955 }
02956 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
02957 if (fwh == (void *) -1) {
02958 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02959 close(fd);
02960 return -1;
02961 }
02962 MD5Init(&md5);
02963 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02964 MD5Final(sum, &md5);
02965 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02966 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02967 munmap((void*)fwh, stbuf.st_size);
02968 close(fd);
02969 return -1;
02970 }
02971
02972 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02973 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02974
02975 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02976
02977 break;
02978
02979
02980 munmap((void*)fwh, stbuf.st_size);
02981 close(fd);
02982 return 0;
02983 }
02984 }
02985
02986 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02987 cur->fd = -1;
02988 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02989 }
02990
02991 if (cur) {
02992 if (cur->fwh)
02993 munmap((void*)cur->fwh, cur->mmaplen);
02994 if (cur->fd > -1)
02995 close(cur->fd);
02996 cur->fwh = fwh;
02997 cur->fd = fd;
02998 cur->mmaplen = stbuf.st_size;
02999 cur->dead = 0;
03000 }
03001
03002 return 0;
03003 }
03004
03005 static int iax_check_version(char *dev)
03006 {
03007 int res = 0;
03008 struct iax_firmware *cur = NULL;
03009
03010 if (ast_strlen_zero(dev))
03011 return 0;
03012
03013 AST_LIST_LOCK(&firmwares);
03014 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03015 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03016 res = ntohs(cur->fwh->version);
03017 break;
03018 }
03019 }
03020 AST_LIST_UNLOCK(&firmwares);
03021
03022 return res;
03023 }
03024
03025 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03026 {
03027 int res = -1;
03028 unsigned int bs = desc & 0xff;
03029 unsigned int start = (desc >> 8) & 0xffffff;
03030 unsigned int bytes;
03031 struct iax_firmware *cur;
03032
03033 if (ast_strlen_zero((char *)dev) || !bs)
03034 return -1;
03035
03036 start *= bs;
03037
03038 AST_LIST_LOCK(&firmwares);
03039 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03040 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03041 continue;
03042 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03043 if (start < ntohl(cur->fwh->datalen)) {
03044 bytes = ntohl(cur->fwh->datalen) - start;
03045 if (bytes > bs)
03046 bytes = bs;
03047 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03048 } else {
03049 bytes = 0;
03050 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03051 }
03052 if (bytes == bs)
03053 res = 0;
03054 else
03055 res = 1;
03056 break;
03057 }
03058 AST_LIST_UNLOCK(&firmwares);
03059
03060 return res;
03061 }
03062
03063
03064 static void reload_firmware(int unload)
03065 {
03066 struct iax_firmware *cur = NULL;
03067 DIR *fwd;
03068 struct dirent *de;
03069 char dir[256], fn[256];
03070
03071 AST_LIST_LOCK(&firmwares);
03072
03073
03074 AST_LIST_TRAVERSE(&firmwares, cur, list)
03075 cur->dead = 1;
03076
03077
03078 if (!unload) {
03079 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03080 fwd = opendir(dir);
03081 if (fwd) {
03082 while((de = readdir(fwd))) {
03083 if (de->d_name[0] != '.') {
03084 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03085 if (!try_firmware(fn)) {
03086 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03087 }
03088 }
03089 }
03090 closedir(fwd);
03091 } else
03092 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03093 }
03094
03095
03096 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03097 if (!cur->dead)
03098 continue;
03099 AST_LIST_REMOVE_CURRENT(list);
03100 destroy_firmware(cur);
03101 }
03102 AST_LIST_TRAVERSE_SAFE_END;
03103
03104 AST_LIST_UNLOCK(&firmwares);
03105 }
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115 static int __do_deliver(void *data)
03116 {
03117
03118
03119 struct iax_frame *fr = data;
03120 fr->retrans = -1;
03121 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03122 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
03123 iax2_queue_frame(fr->callno, &fr->af);
03124
03125 iax2_frame_free(fr);
03126
03127 return 0;
03128 }
03129
03130 static int handle_error(void)
03131 {
03132
03133
03134
03135 #if 0
03136 struct sockaddr_in *sin;
03137 int res;
03138 struct msghdr m;
03139 struct sock_extended_err e;
03140 m.msg_name = NULL;
03141 m.msg_namelen = 0;
03142 m.msg_iov = NULL;
03143 m.msg_control = &e;
03144 m.msg_controllen = sizeof(e);
03145 m.msg_flags = 0;
03146 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03147 if (res < 0)
03148 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03149 else {
03150 if (m.msg_controllen) {
03151 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03152 if (sin)
03153 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03154 else
03155 ast_log(LOG_WARNING, "No address detected??\n");
03156 } else {
03157 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03158 }
03159 }
03160 #endif
03161 return 0;
03162 }
03163
03164 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03165 {
03166 int res;
03167 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03168 sizeof(*sin));
03169 if (res < 0) {
03170 ast_debug(1, "Received error: %s\n", strerror(errno));
03171 handle_error();
03172 } else
03173 res = 0;
03174 return res;
03175 }
03176
03177 static int send_packet(struct iax_frame *f)
03178 {
03179 int res;
03180 int callno = f->callno;
03181
03182
03183 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03184 return -1;
03185
03186
03187 if (iaxdebug)
03188 ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
03189
03190 if (f->transfer) {
03191 if (iaxdebug)
03192 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03193 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03194 } else {
03195 if (iaxdebug)
03196 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03197 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03198 }
03199 if (res < 0) {
03200 if (iaxdebug)
03201 ast_debug(1, "Received error: %s\n", strerror(errno));
03202 handle_error();
03203 } else
03204 res = 0;
03205
03206 return res;
03207 }
03208
03209
03210
03211
03212
03213 static int iax2_predestroy(int callno)
03214 {
03215 struct ast_channel *c = NULL;
03216 struct chan_iax2_pvt *pvt = iaxs[callno];
03217
03218 if (!pvt)
03219 return -1;
03220
03221 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
03222 iax2_destroy_helper(pvt);
03223 ast_set_flag(pvt, IAX_ALREADYGONE);
03224 }
03225
03226 if ((c = pvt->owner)) {
03227 c->tech_pvt = NULL;
03228 iax2_queue_hangup(callno);
03229 pvt->owner = NULL;
03230 ast_module_unref(ast_module_info->self);
03231 }
03232
03233 return 0;
03234 }
03235
03236 static void iax2_destroy(int callno)
03237 {
03238 struct chan_iax2_pvt *pvt = NULL;
03239 struct ast_channel *owner = NULL;
03240
03241 retry:
03242 if ((pvt = iaxs[callno])) {
03243 #if 0
03244
03245
03246
03247
03248
03249
03250
03251 iax2_destroy_helper(pvt);
03252 #endif
03253 }
03254
03255 owner = pvt ? pvt->owner : NULL;
03256
03257 if (owner) {
03258 if (ast_channel_trylock(owner)) {
03259 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03260 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03261 goto retry;
03262 }
03263 }
03264
03265 if (!owner) {
03266 iaxs[callno] = NULL;
03267 }
03268
03269 if (pvt) {
03270 if (!owner) {
03271 pvt->owner = NULL;
03272 } else {
03273
03274
03275
03276 ast_queue_hangup(owner);
03277 }
03278
03279 if (pvt->peercallno) {
03280 remove_by_peercallno(pvt);
03281 }
03282
03283 if (pvt->transfercallno) {
03284 remove_by_transfercallno(pvt);
03285 }
03286
03287 if (!owner) {
03288 ao2_ref(pvt, -1);
03289 pvt = NULL;
03290 }
03291 }
03292
03293 if (owner) {
03294 ast_channel_unlock(owner);
03295 }
03296
03297 if (callno & 0x4000) {
03298 update_max_trunk();
03299 }
03300 }
03301
03302 static int update_packet(struct iax_frame *f)
03303 {
03304
03305 struct ast_iax2_full_hdr *fh = f->data;
03306 struct ast_frame af;
03307
03308
03309 if (f->encmethods) {
03310 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03311 }
03312
03313 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03314
03315 f->iseqno = iaxs[f->callno]->iseqno;
03316 fh->iseqno = f->iseqno;
03317
03318
03319 if (f->encmethods) {
03320
03321
03322 build_rand_pad(f->semirand, sizeof(f->semirand));
03323 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03324 }
03325 return 0;
03326 }
03327
03328 static int attempt_transmit(const void *data);
03329 static void __attempt_transmit(const void *data)
03330 {
03331
03332
03333 struct iax_frame *f = (struct iax_frame *)data;
03334 int freeme = 0;
03335 int callno = f->callno;
03336
03337 if (callno)
03338 ast_mutex_lock(&iaxsl[callno]);
03339 if (callno && iaxs[callno]) {
03340 if ((f->retries < 0) ||
03341 (f->retries >= max_retries) ) {
03342
03343 if (f->retries >= max_retries) {
03344 if (f->transfer) {
03345
03346 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03347 } else if (f->final) {
03348 iax2_destroy(callno);
03349 } else {
03350 if (iaxs[callno]->owner)
03351 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
03352 iaxs[callno]->error = ETIMEDOUT;
03353 if (iaxs[callno]->owner) {
03354 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03355
03356 iax2_queue_frame(callno, &fr);
03357
03358 if (iaxs[callno] && iaxs[callno]->owner)
03359 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03360 } else {
03361 if (iaxs[callno]->reg) {
03362 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03363 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03364 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03365 }
03366 iax2_destroy(callno);
03367 }
03368 }
03369
03370 }
03371 freeme = 1;
03372 } else {
03373
03374 update_packet(f);
03375
03376 send_packet(f);
03377 f->retries++;
03378
03379 f->retrytime *= 10;
03380 if (f->retrytime > MAX_RETRY_TIME)
03381 f->retrytime = MAX_RETRY_TIME;
03382
03383 if (f->transfer && (f->retrytime > 1000))
03384 f->retrytime = 1000;
03385 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03386 }
03387 } else {
03388
03389 f->retries = -1;
03390 freeme = 1;
03391 }
03392 if (callno)
03393 ast_mutex_unlock(&iaxsl[callno]);
03394
03395 if (freeme) {
03396
03397 AST_LIST_LOCK(&frame_queue);
03398 AST_LIST_REMOVE(&frame_queue, f, list);
03399 AST_LIST_UNLOCK(&frame_queue);
03400 f->retrans = -1;
03401
03402 iax2_frame_free(f);
03403 }
03404 }
03405
03406 static int attempt_transmit(const void *data)
03407 {
03408 #ifdef SCHED_MULTITHREADED
03409 if (schedule_action(__attempt_transmit, data))
03410 #endif
03411 __attempt_transmit(data);
03412 return 0;
03413 }
03414
03415 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03416 {
03417 struct iax2_peer *peer = NULL;
03418 struct iax2_user *user = NULL;
03419 static char *choices[] = { "all", NULL };
03420 char *cmplt;
03421
03422 switch (cmd) {
03423 case CLI_INIT:
03424 e->command = "iax2 prune realtime";
03425 e->usage =
03426 "Usage: iax2 prune realtime [<peername>|all]\n"
03427 " Prunes object(s) from the cache\n";
03428 return NULL;
03429 case CLI_GENERATE:
03430 if (a->pos == 3) {
03431 cmplt = ast_cli_complete(a->word, choices, a->n);
03432 if (!cmplt)
03433 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03434 return cmplt;
03435 }
03436 return NULL;
03437 }
03438 if (a->argc != 4)
03439 return CLI_SHOWUSAGE;
03440 if (!strcmp(a->argv[3], "all")) {
03441 prune_users();
03442 prune_peers();
03443 ast_cli(a->fd, "Cache flushed successfully.\n");
03444 return CLI_SUCCESS;
03445 }
03446 peer = find_peer(a->argv[3], 0);
03447 user = find_user(a->argv[3]);
03448 if (peer || user) {
03449 if (peer) {
03450 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
03451 ast_set_flag(peer, IAX_RTAUTOCLEAR);
03452 expire_registry(peer_ref(peer));
03453 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03454 } else {
03455 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03456 }
03457 peer_unref(peer);
03458 }
03459 if (user) {
03460 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
03461 ast_set_flag(user, IAX_RTAUTOCLEAR);
03462 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03463 } else {
03464 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03465 }
03466 ao2_unlink(users,user);
03467 user_unref(user);
03468 }
03469 } else {
03470 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03471 }
03472
03473 return CLI_SUCCESS;
03474 }
03475
03476 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03477 {
03478 switch (cmd) {
03479 case CLI_INIT:
03480 e->command = "iax2 test losspct";
03481 e->usage =
03482 "Usage: iax2 test losspct <percentage>\n"
03483 " For testing, throws away <percentage> percent of incoming packets\n";
03484 return NULL;
03485 case CLI_GENERATE:
03486 return NULL;
03487 }
03488 if (a->argc != 4)
03489 return CLI_SHOWUSAGE;
03490
03491 test_losspct = atoi(a->argv[3]);
03492
03493 return CLI_SUCCESS;
03494 }
03495
03496 #ifdef IAXTESTS
03497 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03498 {
03499 switch (cmd) {
03500 case CLI_INIT:
03501 e->command = "iax2 test late";
03502 e->usage =
03503 "Usage: iax2 test late <ms>\n"
03504 " For testing, count the next frame as <ms> ms late\n";
03505 return NULL;
03506 case CLI_GENERATE:
03507 return NULL;
03508 }
03509
03510 if (a->argc != 4)
03511 return CLI_SHOWUSAGE;
03512
03513 test_late = atoi(a->argv[3]);
03514
03515 return CLI_SUCCESS;
03516 }
03517
03518 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03519 {
03520 switch (cmd) {
03521 case CLI_INIT:
03522 e->command = "iax2 test resync";
03523 e->usage =
03524 "Usage: iax2 test resync <ms>\n"
03525 " For testing, adjust all future frames by <ms> ms\n";
03526 return NULL;
03527 case CLI_GENERATE:
03528 return NULL;
03529 }
03530
03531 if (a->argc != 4)
03532 return CLI_SHOWUSAGE;
03533
03534 test_resync = atoi(a->argv[3]);
03535
03536 return CLI_SUCCESS;
03537 }
03538
03539 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03540 {
03541 switch (cmd) {
03542 case CLI_INIT:
03543 e->command = "iax2 test jitter";
03544 e->usage =
03545 "Usage: iax2 test jitter <ms> <pct>\n"
03546 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03547 " percentage of packets. If <pct> is not specified, adds\n"
03548 " jitter to all packets.\n";
03549 return NULL;
03550 case CLI_GENERATE:
03551 return NULL;
03552 }
03553
03554 if (a->argc < 4 || a->argc > 5)
03555 return CLI_SHOWUSAGE;
03556
03557 test_jit = atoi(a->argv[3]);
03558 if (a->argc == 5)
03559 test_jitpct = atoi(a->argv[4]);
03560
03561 return CLI_SUCCESS;
03562 }
03563 #endif
03564
03565
03566
03567 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03568 {
03569 int res = 0;
03570 if (peer->maxms) {
03571 if (peer->lastms < 0) {
03572 ast_copy_string(status, "UNREACHABLE", statuslen);
03573 } else if (peer->lastms > peer->maxms) {
03574 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03575 res = 1;
03576 } else if (peer->lastms) {
03577 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03578 res = 1;
03579 } else {
03580 ast_copy_string(status, "UNKNOWN", statuslen);
03581 }
03582 } else {
03583 ast_copy_string(status, "Unmonitored", statuslen);
03584 res = -1;
03585 }
03586 return res;
03587 }
03588
03589
03590 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03591 {
03592 char status[30];
03593 char cbuf[256];
03594 struct iax2_peer *peer;
03595 char codec_buf[512];
03596 struct ast_str *encmethods = ast_str_alloca(256);
03597 int x = 0, codec = 0, load_realtime = 0;
03598
03599 switch (cmd) {
03600 case CLI_INIT:
03601 e->command = "iax2 show peer";
03602 e->usage =
03603 "Usage: iax2 show peer <name>\n"
03604 " Display details on specific IAX peer\n";
03605 return NULL;
03606 case CLI_GENERATE:
03607 if (a->pos == 3)
03608 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03609 return NULL;
03610 }
03611
03612 if (a->argc < 4)
03613 return CLI_SHOWUSAGE;
03614
03615 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03616
03617 peer = find_peer(a->argv[3], load_realtime);
03618 if (peer) {
03619 encmethods_to_str(peer->encmethods, encmethods);
03620 ast_cli(a->fd, "\n\n");
03621 ast_cli(a->fd, " * Name : %s\n", peer->name);
03622 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03623 ast_cli(a->fd, " Context : %s\n", peer->context);
03624 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03625 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03626 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
03627 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03628 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03629 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
03630 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03631 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03632 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03633 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03634 ast_cli(a->fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
03635 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03636 ast_cli(a->fd, " Username : %s\n", peer->username);
03637 ast_cli(a->fd, " Codecs : ");
03638 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03639 ast_cli(a->fd, "%s\n", codec_buf);
03640
03641 ast_cli(a->fd, " Codec Order : (");
03642 for(x = 0; x < 32 ; x++) {
03643 codec = ast_codec_pref_index(&peer->prefs,x);
03644 if(!codec)
03645 break;
03646 ast_cli(a->fd, "%s", ast_getformatname(codec));
03647 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03648 ast_cli(a->fd, "|");
03649 }
03650
03651 if (!x)
03652 ast_cli(a->fd, "none");
03653 ast_cli(a->fd, ")\n");
03654
03655 ast_cli(a->fd, " Status : ");
03656 peer_status(peer, status, sizeof(status));
03657 ast_cli(a->fd, "%s\n",status);
03658 ast_cli(a->fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
03659 ast_cli(a->fd, "\n");
03660 peer_unref(peer);
03661 } else {
03662 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03663 ast_cli(a->fd, "\n");
03664 }
03665
03666 return CLI_SUCCESS;
03667 }
03668
03669 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, int flags)
03670 {
03671 int which = 0;
03672 struct iax2_peer *peer;
03673 char *res = NULL;
03674 int wordlen = strlen(word);
03675 struct ao2_iterator i;
03676
03677 i = ao2_iterator_init(peers, 0);
03678 while ((peer = ao2_iterator_next(&i))) {
03679 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03680 && (!flags || ast_test_flag(peer, flags))) {
03681 res = ast_strdup(peer->name);
03682 peer_unref(peer);
03683 break;
03684 }
03685 peer_unref(peer);
03686 }
03687 ao2_iterator_destroy(&i);
03688
03689 return res;
03690 }
03691
03692 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03693 {
03694 struct iax_frame *cur;
03695 int cnt = 0, dead = 0, final = 0;
03696
03697 switch (cmd) {
03698 case CLI_INIT:
03699 e->command = "iax2 show stats";
03700 e->usage =
03701 "Usage: iax2 show stats\n"
03702 " Display statistics on IAX channel driver.\n";
03703 return NULL;
03704 case CLI_GENERATE:
03705 return NULL;
03706 }
03707
03708 if (a->argc != 3)
03709 return CLI_SHOWUSAGE;
03710
03711 AST_LIST_LOCK(&frame_queue);
03712 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
03713 if (cur->retries < 0)
03714 dead++;
03715 if (cur->final)
03716 final++;
03717 cnt++;
03718 }
03719 AST_LIST_UNLOCK(&frame_queue);
03720
03721 ast_cli(a->fd, " IAX Statistics\n");
03722 ast_cli(a->fd, "---------------------\n");
03723 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03724 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03725 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03726 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03727
03728 trunk_timed = trunk_untimed = 0;
03729 if (trunk_maxmtu > trunk_nmaxmtu)
03730 trunk_nmaxmtu = trunk_maxmtu;
03731
03732 return CLI_SUCCESS;
03733 }
03734
03735
03736 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03737 {
03738 int mtuv;
03739
03740 switch (cmd) {
03741 case CLI_INIT:
03742 e->command = "iax2 set mtu";
03743 e->usage =
03744 "Usage: iax2 set mtu <value>\n"
03745 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03746 " zero to disable. Disabling means that the operating system\n"
03747 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03748 " packet exceeds the UDP payload size. This is substantially\n"
03749 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03750 " greater for G.711 samples.\n";
03751 return NULL;
03752 case CLI_GENERATE:
03753 return NULL;
03754 }
03755
03756 if (a->argc != 4)
03757 return CLI_SHOWUSAGE;
03758 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03759 mtuv = MAX_TRUNK_MTU;
03760 else
03761 mtuv = atoi(a->argv[3]);
03762
03763 if (mtuv == 0) {
03764 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03765 global_max_trunk_mtu = 0;
03766 return CLI_SUCCESS;
03767 }
03768 if (mtuv < 172 || mtuv > 4000) {
03769 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03770 return CLI_SHOWUSAGE;
03771 }
03772 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03773 global_max_trunk_mtu = mtuv;
03774 return CLI_SUCCESS;
03775 }
03776
03777 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03778 {
03779 struct iax2_dpcache *dp = NULL;
03780 char tmp[1024], *pc = NULL;
03781 int s, x, y;
03782 struct timeval now = ast_tvnow();
03783
03784 switch (cmd) {
03785 case CLI_INIT:
03786 e->command = "iax2 show cache";
03787 e->usage =
03788 "Usage: iax2 show cache\n"
03789 " Display currently cached IAX Dialplan results.\n";
03790 return NULL;
03791 case CLI_GENERATE:
03792 return NULL;
03793 }
03794
03795 AST_LIST_LOCK(&dpcache);
03796
03797 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03798
03799 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03800 s = dp->expiry.tv_sec - now.tv_sec;
03801 tmp[0] = '\0';
03802 if (dp->flags & CACHE_FLAG_EXISTS)
03803 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03804 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03805 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03806 if (dp->flags & CACHE_FLAG_CANEXIST)
03807 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03808 if (dp->flags & CACHE_FLAG_PENDING)
03809 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03810 if (dp->flags & CACHE_FLAG_TIMEOUT)
03811 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03812 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03813 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03814 if (dp->flags & CACHE_FLAG_MATCHMORE)
03815 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03816 if (dp->flags & CACHE_FLAG_UNKNOWN)
03817 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03818
03819 if (!ast_strlen_zero(tmp)) {
03820 tmp[strlen(tmp) - 1] = '\0';
03821 } else {
03822 ast_copy_string(tmp, "(none)", sizeof(tmp));
03823 }
03824 y = 0;
03825 pc = strchr(dp->peercontext, '@');
03826 if (!pc) {
03827 pc = dp->peercontext;
03828 } else {
03829 pc++;
03830 }
03831 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03832 if (dp->waiters[x] > -1)
03833 y++;
03834 }
03835 if (s > 0) {
03836 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03837 } else {
03838 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03839 }
03840 }
03841
03842 AST_LIST_UNLOCK(&dpcache);
03843
03844 return CLI_SUCCESS;
03845 }
03846
03847 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03848
03849 static void unwrap_timestamp(struct iax_frame *fr)
03850 {
03851
03852
03853 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03854 const int lower_mask = (1 << ts_shift) - 1;
03855 const int upper_mask = ~lower_mask;
03856 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03857
03858 if ( (fr->ts & upper_mask) == last_upper ) {
03859 const int x = fr->ts - iaxs[fr->callno]->last;
03860 const int threshold = (ts_shift == 15) ? 25000 : 50000;
03861
03862 if (x < -threshold) {
03863
03864
03865
03866
03867 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
03868 if (iaxdebug)
03869 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
03870 } else if (x > threshold) {
03871
03872
03873
03874
03875 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03876 if (iaxdebug)
03877 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
03878 }
03879 }
03880 }
03881
03882 static int get_from_jb(const void *p);
03883
03884 static void update_jbsched(struct chan_iax2_pvt *pvt)
03885 {
03886 int when;
03887
03888 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03889
03890 when = jb_next(pvt->jb) - when;
03891
03892 if (when <= 0) {
03893
03894 when = 1;
03895 }
03896
03897 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
03898 CALLNO_TO_PTR(pvt->callno));
03899 }
03900
03901 static void __get_from_jb(const void *p)
03902 {
03903 int callno = PTR_TO_CALLNO(p);
03904 struct chan_iax2_pvt *pvt = NULL;
03905 struct iax_frame *fr;
03906 jb_frame frame;
03907 int ret;
03908 long ms;
03909 long next;
03910 struct timeval now = ast_tvnow();
03911
03912
03913 ast_mutex_lock(&iaxsl[callno]);
03914 pvt = iaxs[callno];
03915 if (!pvt) {
03916
03917 ast_mutex_unlock(&iaxsl[callno]);
03918 return;
03919 }
03920
03921 pvt->jbid = -1;
03922
03923
03924
03925
03926 now.tv_usec += 1000;
03927
03928 ms = ast_tvdiff_ms(now, pvt->rxcore);
03929
03930 if(ms >= (next = jb_next(pvt->jb))) {
03931 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
03932 switch(ret) {
03933 case JB_OK:
03934 fr = frame.data;
03935 __do_deliver(fr);
03936
03937 pvt = iaxs[callno];
03938 break;
03939 case JB_INTERP:
03940 {
03941 struct ast_frame af = { 0, };
03942
03943
03944 af.frametype = AST_FRAME_VOICE;
03945 af.subclass = pvt->voiceformat;
03946 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03947 af.src = "IAX2 JB interpolation";
03948 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03949 af.offset = AST_FRIENDLY_OFFSET;
03950
03951
03952
03953 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03954 iax2_queue_frame(callno, &af);
03955
03956 pvt = iaxs[callno];
03957 }
03958 }
03959 break;
03960 case JB_DROP:
03961 iax2_frame_free(frame.data);
03962 break;
03963 case JB_NOFRAME:
03964 case JB_EMPTY:
03965
03966 break;
03967 default:
03968
03969 break;
03970 }
03971 }
03972 if (pvt)
03973 update_jbsched(pvt);
03974 ast_mutex_unlock(&iaxsl[callno]);
03975 }
03976
03977 static int get_from_jb(const void *data)
03978 {
03979 #ifdef SCHED_MULTITHREADED
03980 if (schedule_action(__get_from_jb, data))
03981 #endif
03982 __get_from_jb(data);
03983 return 0;
03984 }
03985
03986
03987
03988
03989
03990
03991
03992 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03993 {
03994 int type, len;
03995 int ret;
03996 int needfree = 0;
03997 struct ast_channel *owner = NULL;
03998 struct ast_channel *bridge = NULL;
03999
04000
04001 unwrap_timestamp(fr);
04002
04003
04004 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04005 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04006 else {
04007 #if 0
04008 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04009 #endif
04010 fr->af.delivery = ast_tv(0,0);
04011 }
04012
04013 type = JB_TYPE_CONTROL;
04014 len = 0;
04015
04016 if(fr->af.frametype == AST_FRAME_VOICE) {
04017 type = JB_TYPE_VOICE;
04018 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
04019 } else if(fr->af.frametype == AST_FRAME_CNG) {
04020 type = JB_TYPE_SILENCE;
04021 }
04022
04023 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04024 if (tsout)
04025 *tsout = fr->ts;
04026 __do_deliver(fr);
04027 return -1;
04028 }
04029
04030 iax2_lock_owner(fr->callno);
04031 if (!iaxs[fr->callno]) {
04032
04033 iax2_frame_free(fr);
04034 return -1;
04035 }
04036 if ((owner = iaxs[fr->callno]->owner))
04037 bridge = ast_bridged_channel(owner);
04038
04039
04040
04041 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04042 jb_frame frame;
04043
04044 ast_channel_unlock(owner);
04045
04046
04047 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04048 __do_deliver(frame.data);
04049
04050 if (!iaxs[fr->callno])
04051 return -1;
04052 }
04053
04054 jb_reset(iaxs[fr->callno]->jb);
04055
04056 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04057
04058
04059 if (tsout)
04060 *tsout = fr->ts;
04061 __do_deliver(fr);
04062 return -1;
04063 }
04064 if (owner) {
04065 ast_channel_unlock(owner);
04066 }
04067
04068
04069
04070 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04071 calc_rxstamp(iaxs[fr->callno],fr->ts));
04072 if (ret == JB_DROP) {
04073 needfree++;
04074 } else if (ret == JB_SCHED) {
04075 update_jbsched(iaxs[fr->callno]);
04076 }
04077 if (tsout)
04078 *tsout = fr->ts;
04079 if (needfree) {
04080
04081 iax2_frame_free(fr);
04082 return -1;
04083 }
04084 return 0;
04085 }
04086
04087 static int iax2_transmit(struct iax_frame *fr)
04088 {
04089
04090
04091
04092 fr->sentyet = 0;
04093 AST_LIST_LOCK(&frame_queue);
04094 AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
04095 AST_LIST_UNLOCK(&frame_queue);
04096
04097 if (netthreadid != AST_PTHREADT_NULL)
04098 pthread_kill(netthreadid, SIGURG);
04099 ast_sched_thread_poke(sched);
04100 return 0;
04101 }
04102
04103
04104
04105 static int iax2_digit_begin(struct ast_channel *c, char digit)
04106 {
04107 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04108 }
04109
04110 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04111 {
04112 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04113 }
04114
04115 static int iax2_sendtext(struct ast_channel *c, const char *text)
04116 {
04117
04118 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04119 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04120 }
04121
04122 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04123 {
04124 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1);
04125 }
04126
04127 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04128 {
04129 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04130 }
04131
04132 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04133 {
04134 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04135 ast_mutex_lock(&iaxsl[callno]);
04136 if (iaxs[callno])
04137 iaxs[callno]->owner = newchan;
04138 else
04139 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04140 ast_mutex_unlock(&iaxsl[callno]);
04141 return 0;
04142 }
04143
04144
04145
04146
04147
04148 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04149 {
04150 struct ast_variable *var = NULL;
04151 struct ast_variable *tmp;
04152 struct iax2_peer *peer=NULL;
04153 time_t regseconds = 0, nowtime;
04154 int dynamic=0;
04155
04156 if (peername) {
04157 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04158 if (!var && sin)
04159 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04160 } else if (sin) {
04161 char porta[25];
04162 sprintf(porta, "%d", ntohs(sin->sin_port));
04163 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04164 if (var) {
04165
04166 for (tmp = var; tmp; tmp = tmp->next) {
04167 if (!strcasecmp(tmp->name, "name"))
04168 peername = tmp->value;
04169 }
04170 }
04171 }
04172 if (!var && peername) {
04173 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04174
04175
04176
04177
04178
04179
04180 if (var && sin) {
04181 for (tmp = var; tmp; tmp = tmp->next) {
04182 if (!strcasecmp(tmp->name, "host")) {
04183 struct ast_hostent ahp;
04184 struct hostent *hp;
04185 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04186
04187 ast_variables_destroy(var);
04188 var = NULL;
04189 }
04190 break;
04191 }
04192 }
04193 }
04194 }
04195 if (!var)
04196 return NULL;
04197
04198 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04199
04200 if (!peer) {
04201 ast_variables_destroy(var);
04202 return NULL;
04203 }
04204
04205 for (tmp = var; tmp; tmp = tmp->next) {
04206
04207 if (!strcasecmp(tmp->name, "type")) {
04208 if (strcasecmp(tmp->value, "friend") &&
04209 strcasecmp(tmp->value, "peer")) {
04210
04211 peer = peer_unref(peer);
04212 break;
04213 }
04214 } else if (!strcasecmp(tmp->name, "regseconds")) {
04215 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04216 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04217 inet_aton(tmp->value, &(peer->addr.sin_addr));
04218 } else if (!strcasecmp(tmp->name, "port")) {
04219 peer->addr.sin_port = htons(atoi(tmp->value));
04220 } else if (!strcasecmp(tmp->name, "host")) {
04221 if (!strcasecmp(tmp->value, "dynamic"))
04222 dynamic = 1;
04223 }
04224 }
04225
04226 ast_variables_destroy(var);
04227
04228 if (!peer)
04229 return NULL;
04230
04231 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04232 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04233 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
04234 if (peer->expire > -1) {
04235 if (!ast_sched_thread_del(sched, peer->expire)) {
04236 peer->expire = -1;
04237 peer_unref(peer);
04238 }
04239 }
04240 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04241 if (peer->expire == -1)
04242 peer_unref(peer);
04243 }
04244 ao2_link(peers, peer);
04245 if (ast_test_flag(peer, IAX_DYNAMIC))
04246 reg_source_db(peer);
04247 } else {
04248 ast_set_flag(peer, IAX_TEMPONLY);
04249 }
04250
04251 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04252 time(&nowtime);
04253 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04254 memset(&peer->addr, 0, sizeof(peer->addr));
04255 realtime_update_peer(peer->name, &peer->addr, 0);
04256 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04257 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04258 }
04259 else {
04260 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04261 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04262 }
04263 }
04264
04265 return peer;
04266 }
04267
04268 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04269 {
04270 struct ast_variable *var;
04271 struct ast_variable *tmp;
04272 struct iax2_user *user=NULL;
04273
04274 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04275 if (!var)
04276 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04277 if (!var && sin) {
04278 char porta[6];
04279 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04280 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04281 if (!var)
04282 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04283 }
04284 if (!var) {
04285 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04286
04287
04288
04289
04290
04291
04292 if (var) {
04293 for (tmp = var; tmp; tmp = tmp->next) {
04294 if (!strcasecmp(tmp->name, "host")) {
04295 struct ast_hostent ahp;
04296 struct hostent *hp;
04297 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04298
04299 ast_variables_destroy(var);
04300 var = NULL;
04301 }
04302 break;
04303 }
04304 }
04305 }
04306 }
04307 if (!var)
04308 return NULL;
04309
04310 tmp = var;
04311 while(tmp) {
04312
04313 if (!strcasecmp(tmp->name, "type")) {
04314 if (strcasecmp(tmp->value, "friend") &&
04315 strcasecmp(tmp->value, "user")) {
04316 return NULL;
04317 }
04318 }
04319 tmp = tmp->next;
04320 }
04321
04322 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
04323
04324 ast_variables_destroy(var);
04325
04326 if (!user)
04327 return NULL;
04328
04329 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
04330 ast_set_flag(user, IAX_RTCACHEFRIENDS);
04331 ao2_link(users, user);
04332 } else {
04333 ast_set_flag(user, IAX_TEMPONLY);
04334 }
04335
04336 return user;
04337 }
04338
04339 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
04340 {
04341 char port[10];
04342 char regseconds[20];
04343
04344 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04345 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
04346 ast_update_realtime("iaxpeers", "name", peername,
04347 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
04348 "regseconds", regseconds, SENTINEL);
04349 }
04350
04351 struct create_addr_info {
04352 int capability;
04353 unsigned int flags;
04354 int maxtime;
04355 int encmethods;
04356 int found;
04357 int sockfd;
04358 int adsi;
04359 char username[80];
04360 char secret[80];
04361 char outkey[80];
04362 char timezone[80];
04363 char prefs[32];
04364 char context[AST_MAX_CONTEXT];
04365 char peercontext[AST_MAX_CONTEXT];
04366 char mohinterpret[MAX_MUSICCLASS];
04367 char mohsuggest[MAX_MUSICCLASS];
04368 };
04369
04370 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04371 {
04372 struct iax2_peer *peer;
04373 int res = -1;
04374 struct ast_codec_pref ourprefs;
04375
04376 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
04377 cai->sockfd = defaultsockfd;
04378 cai->maxtime = 0;
04379 sin->sin_family = AF_INET;
04380
04381 if (!(peer = find_peer(peername, 1))) {
04382 cai->found = 0;
04383 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
04384 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04385 return -1;
04386 }
04387 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04388
04389
04390 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04391 if (c)
04392 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04393 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04394 return 0;
04395 }
04396
04397 cai->found = 1;
04398
04399
04400 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
04401 goto return_unref;
04402
04403
04404 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04405 goto return_unref;
04406
04407 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT);
04408 cai->maxtime = peer->maxms;
04409 cai->capability = peer->capability;
04410 cai->encmethods = peer->encmethods;
04411 cai->sockfd = peer->sockfd;
04412 cai->adsi = peer->adsi;
04413 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04414
04415 if (c) {
04416 ast_debug(1, "prepending %x to prefs\n", c->nativeformats);
04417 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04418 }
04419 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04420 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04421 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04422 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04423 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04424 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04425 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04426 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04427 if (ast_strlen_zero(peer->dbsecret)) {
04428 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04429 } else {
04430 char *family;
04431 char *key = NULL;
04432
04433 family = ast_strdupa(peer->dbsecret);
04434 key = strchr(family, '/');
04435 if (key)
04436 *key++ = '\0';
04437 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04438 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04439 goto return_unref;
04440 }
04441 }
04442
04443 if (peer->addr.sin_addr.s_addr) {
04444 sin->sin_addr = peer->addr.sin_addr;
04445 sin->sin_port = peer->addr.sin_port;
04446 } else {
04447 sin->sin_addr = peer->defaddr.sin_addr;
04448 sin->sin_port = peer->defaddr.sin_port;
04449 }
04450
04451 res = 0;
04452
04453 return_unref:
04454 peer_unref(peer);
04455
04456 return res;
04457 }
04458
04459 static void __auto_congest(const void *nothing)
04460 {
04461 int callno = PTR_TO_CALLNO(nothing);
04462 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
04463 ast_mutex_lock(&iaxsl[callno]);
04464 if (iaxs[callno]) {
04465 iaxs[callno]->initid = -1;
04466 iax2_queue_frame(callno, &f);
04467 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04468 }
04469 ast_mutex_unlock(&iaxsl[callno]);
04470 }
04471
04472 static int auto_congest(const void *data)
04473 {
04474 #ifdef SCHED_MULTITHREADED
04475 if (schedule_action(__auto_congest, data))
04476 #endif
04477 __auto_congest(data);
04478 return 0;
04479 }
04480
04481 static unsigned int iax2_datetime(const char *tz)
04482 {
04483 struct timeval t = ast_tvnow();
04484 struct ast_tm tm;
04485 unsigned int tmp;
04486 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04487 tmp = (tm.tm_sec >> 1) & 0x1f;
04488 tmp |= (tm.tm_min & 0x3f) << 5;
04489 tmp |= (tm.tm_hour & 0x1f) << 11;
04490 tmp |= (tm.tm_mday & 0x1f) << 16;
04491 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04492 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04493 return tmp;
04494 }
04495
04496 struct parsed_dial_string {
04497 char *username;
04498 char *password;
04499 char *key;
04500 char *peer;
04501 char *port;
04502 char *exten;
04503 char *context;
04504 char *options;
04505 };
04506
04507 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04508 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04509 int sockfd, struct iax_ie_data *ied)
04510 {
04511 struct {
04512 struct ast_iax2_full_hdr f;
04513 struct iax_ie_data ied;
04514 } data;
04515 size_t size = sizeof(struct ast_iax2_full_hdr);
04516
04517 if (ied) {
04518 size += ied->pos;
04519 memcpy(&data.ied, ied->buf, ied->pos);
04520 }
04521
04522 data.f.scallno = htons(0x8000 | callno);
04523 data.f.dcallno = htons(dcallno);
04524 data.f.ts = htonl(ts);
04525 data.f.iseqno = seqno;
04526 data.f.oseqno = 0;
04527 data.f.type = AST_FRAME_IAX;
04528 data.f.csub = compress_subclass(command);
04529
04530 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04531 }
04532
04533 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04534 {
04535
04536 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04537 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04538 ied->buf[ied->pos++] = 0;
04539 pvt->calltoken_ie_len = 2;
04540 }
04541 }
04542
04543 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04544 {
04545 struct chan_iax2_pvt *pvt = iaxs[callno];
04546 int frametype = f->af.frametype;
04547 int subclass = f->af.subclass;
04548 struct {
04549 struct ast_iax2_full_hdr fh;
04550 struct iax_ie_data ied;
04551 } data = {
04552 .ied.buf = { 0 },
04553 .ied.pos = 0,
04554 };
04555
04556 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04557
04558 if (!pvt) {
04559 return;
04560 }
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04574 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04575 (f->datalen > sizeof(data))) {
04576
04577 return;
04578 }
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594 memcpy(&data, f->data, f->datalen);
04595 data.ied.pos = ie_data_pos;
04596
04597
04598
04599 data.ied.pos -= pvt->calltoken_ie_len;
04600 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04601
04602
04603 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04604
04605
04606 AST_LIST_LOCK(&frame_queue);
04607 AST_LIST_REMOVE(&frame_queue, f, list);
04608 AST_LIST_UNLOCK(&frame_queue);
04609
04610
04611 iax2_frame_free(f);
04612
04613
04614 pvt->oseqno = 0;
04615 pvt->rseqno = 0;
04616 pvt->iseqno = 0;
04617 pvt->aseqno = 0;
04618 if (pvt->peercallno) {
04619 remove_by_peercallno(pvt);
04620 pvt->peercallno = 0;
04621 }
04622
04623
04624 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04625 }
04626
04627 static void requirecalltoken_mark_auto(const char *name, int subclass)
04628 {
04629 struct iax2_user *user = NULL;
04630 struct iax2_peer *peer = NULL;
04631
04632 if (ast_strlen_zero(name)) {
04633 return;
04634 }
04635
04636 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04637 user->calltoken_required = CALLTOKEN_YES;
04638 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04639 peer->calltoken_required = CALLTOKEN_YES;
04640 }
04641
04642 if (peer) {
04643 peer_unref(peer);
04644 }
04645 if (user) {
04646 user_unref(user);
04647 }
04648 }
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664
04665
04666
04667 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04668 struct sockaddr_in *sin, int fd)
04669 {
04670 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04671 #define CALLTOKEN_IE_FORMAT "%u?%s"
04672 struct ast_str *buf = ast_str_alloca(256);
04673 time_t t = time(NULL);
04674 char hash[41];
04675 int subclass = uncompress_subclass(fh->csub);
04676
04677
04678 if (ies->calltoken && !ies->calltokendata) {
04679 struct iax_ie_data ied = {
04680 .buf = { 0 },
04681 .pos = 0,
04682 };
04683
04684
04685 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04686 ast_sha1_hash(hash, ast_str_buffer(buf));
04687
04688 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04689 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04690 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04691
04692 return 1;
04693
04694
04695 } else if (ies->calltoken && ies->calltokendata) {
04696 char *rec_hash = NULL;
04697 char *rec_ts = NULL;
04698 unsigned int rec_time;
04699
04700
04701 rec_hash = strchr((char *) ies->calltokendata, '?');
04702 if (rec_hash) {
04703 *rec_hash++ = '\0';
04704 rec_ts = (char *) ies->calltokendata;
04705 }
04706
04707
04708 if (!rec_hash || !rec_ts) {
04709 goto reject;
04710 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04711 goto reject;
04712 }
04713
04714
04715 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04716 ast_sha1_hash(hash, ast_str_buffer(buf));
04717
04718
04719 if (strcmp(hash, rec_hash)) {
04720 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04721 goto reject;
04722 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04723 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04724 goto reject;
04725 }
04726
04727
04728
04729 requirecalltoken_mark_auto(ies->username, subclass);
04730 return 0;
04731
04732
04733 } else {
04734 if (calltoken_required(sin, ies->username, subclass)) {
04735 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest"));
04736 goto reject;
04737 }
04738 return 0;
04739 }
04740
04741 reject:
04742
04743 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04744 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04745 } else {
04746 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04747 }
04748
04749 return 1;
04750 }
04751
04752
04753
04754
04755
04756
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04771 {
04772 if (ast_strlen_zero(data))
04773 return;
04774
04775 pds->peer = strsep(&data, "/");
04776 pds->exten = strsep(&data, "/");
04777 pds->options = data;
04778
04779 if (pds->exten) {
04780 data = pds->exten;
04781 pds->exten = strsep(&data, "@");
04782 pds->context = data;
04783 }
04784
04785 if (strchr(pds->peer, '@')) {
04786 data = pds->peer;
04787 pds->username = strsep(&data, "@");
04788 pds->peer = data;
04789 }
04790
04791 if (pds->username) {
04792 data = pds->username;
04793 pds->username = strsep(&data, ":");
04794 pds->password = data;
04795 }
04796
04797 data = pds->peer;
04798 pds->peer = strsep(&data, ":");
04799 pds->port = data;
04800
04801
04802
04803
04804 if (pds->password && (pds->password[0] == '[')) {
04805 pds->key = ast_strip_quoted(pds->password, "[", "]");
04806 pds->password = NULL;
04807 }
04808 }
04809
04810 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04811 {
04812 struct sockaddr_in sin;
04813 char *l=NULL, *n=NULL, *tmpstr;
04814 struct iax_ie_data ied;
04815 char *defaultrdest = "s";
04816 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04817 struct parsed_dial_string pds;
04818 struct create_addr_info cai;
04819 struct ast_var_t *var;
04820 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04821 const char* osp_token_ptr;
04822 unsigned int osp_token_length;
04823 unsigned char osp_block_index;
04824 unsigned int osp_block_length;
04825 unsigned char osp_buffer[256];
04826
04827 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
04828 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
04829 return -1;
04830 }
04831
04832 memset(&cai, 0, sizeof(cai));
04833 cai.encmethods = iax2_encryption;
04834
04835 memset(&pds, 0, sizeof(pds));
04836 tmpstr = ast_strdupa(dest);
04837 parse_dial_string(tmpstr, &pds);
04838
04839 if (ast_strlen_zero(pds.peer)) {
04840 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
04841 return -1;
04842 }
04843 if (!pds.exten) {
04844 pds.exten = defaultrdest;
04845 }
04846 if (create_addr(pds.peer, c, &sin, &cai)) {
04847 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
04848 return -1;
04849 }
04850 if (ast_strlen_zero(cai.secret) && ast_test_flag(iaxs[callno], IAX_FORCE_ENCRYPT)) {
04851 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
04852 return -1;
04853 }
04854 if (!pds.username && !ast_strlen_zero(cai.username))
04855 pds.username = cai.username;
04856 if (!pds.password && !ast_strlen_zero(cai.secret))
04857 pds.password = cai.secret;
04858 if (!pds.key && !ast_strlen_zero(cai.outkey))
04859 pds.key = cai.outkey;
04860 if (!pds.context && !ast_strlen_zero(cai.peercontext))
04861 pds.context = cai.peercontext;
04862
04863
04864 ast_copy_string(c->context, cai.context, sizeof(c->context));
04865
04866 if (pds.port)
04867 sin.sin_port = htons(atoi(pds.port));
04868
04869 l = c->cid.cid_num;
04870 n = c->cid.cid_name;
04871
04872
04873 memset(&ied, 0, sizeof(ied));
04874
04875
04876 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
04877 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
04878 if (pds.options && strchr(pds.options, 'a')) {
04879
04880 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
04881 }
04882
04883 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
04884
04885 if (l) {
04886 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
04887 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04888 } else {
04889 if (n)
04890 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04891 else
04892 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
04893 }
04894
04895 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
04896 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
04897
04898 if (n)
04899 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
04900 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
04901 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
04902
04903 if (!ast_strlen_zero(c->language))
04904 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
04905 if (!ast_strlen_zero(c->cid.cid_dnid))
04906 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
04907 if (!ast_strlen_zero(c->cid.cid_rdnis))
04908 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
04909
04910 if (pds.context)
04911 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
04912
04913 if (pds.username)
04914 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
04915
04916 if (cai.encmethods)
04917 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
04918
04919 ast_mutex_lock(&iaxsl[callno]);
04920
04921 if (!ast_strlen_zero(c->context))
04922 ast_string_field_set(iaxs[callno], context, c->context);
04923
04924 if (pds.username)
04925 ast_string_field_set(iaxs[callno], username, pds.username);
04926
04927 iaxs[callno]->encmethods = cai.encmethods;
04928
04929 iaxs[callno]->adsi = cai.adsi;
04930
04931 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
04932 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
04933
04934 if (pds.key)
04935 ast_string_field_set(iaxs[callno], outkey, pds.key);
04936 if (pds.password)
04937 ast_string_field_set(iaxs[callno], secret, pds.password);
04938
04939 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
04940 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
04941 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
04942 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
04943
04944 if (iaxs[callno]->maxtime) {
04945
04946 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
04947 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
04948 } else if (autokill) {
04949 iaxs[callno]->pingtime = autokill / 2;
04950 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
04951 }
04952
04953
04954 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
04955 if (!ast_strlen_zero(osp_token_ptr)) {
04956 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
04957 osp_block_index = 0;
04958 while (osp_token_length > 0) {
04959 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
04960 osp_buffer[0] = osp_block_index;
04961 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
04962 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
04963 osp_block_index++;
04964 osp_token_ptr += osp_block_length;
04965 osp_token_length -= osp_block_length;
04966 }
04967 } else
04968 ast_log(LOG_WARNING, "OSP token is too long\n");
04969 } else if (iaxdebug)
04970 ast_debug(1, "OSP token is undefined\n");
04971
04972
04973 iaxs[callno]->sockfd = cai.sockfd;
04974
04975
04976 if (variablestore) {
04977 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
04978 ast_debug(1, "Found an IAX variable store on this channel\n");
04979 AST_LIST_LOCK(variablelist);
04980 AST_LIST_TRAVERSE(variablelist, var, entries) {
04981 char tmp[256];
04982 int i;
04983 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
04984
04985 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
04986 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
04987 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
04988 }
04989 }
04990 AST_LIST_UNLOCK(variablelist);
04991 }
04992
04993
04994 add_empty_calltoken_ie(iaxs[callno], &ied);
04995 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
04996
04997 ast_mutex_unlock(&iaxsl[callno]);
04998 ast_setstate(c, AST_STATE_RINGING);
04999
05000 return 0;
05001 }
05002
05003 static int iax2_hangup(struct ast_channel *c)
05004 {
05005 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05006 struct iax_ie_data ied;
05007 int alreadygone;
05008 memset(&ied, 0, sizeof(ied));
05009 ast_mutex_lock(&iaxsl[callno]);
05010 if (callno && iaxs[callno]) {
05011 ast_debug(1, "We're hanging up %s now...\n", c->name);
05012 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
05013
05014 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05015 if (!iaxs[callno]->error && !alreadygone) {
05016 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05017 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05018 }
05019 if (!iaxs[callno]) {
05020 ast_mutex_unlock(&iaxsl[callno]);
05021 return 0;
05022 }
05023 }
05024
05025 iax2_predestroy(callno);
05026
05027 if (iaxs[callno] && alreadygone) {
05028 ast_debug(1, "Really destroying %s now...\n", c->name);
05029 iax2_destroy(callno);
05030 } else if (iaxs[callno]) {
05031 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05032 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05033 iax2_destroy(callno);
05034 }
05035 }
05036 } else if (c->tech_pvt) {
05037
05038
05039
05040
05041 c->tech_pvt = NULL;
05042 }
05043 ast_mutex_unlock(&iaxsl[callno]);
05044 ast_verb(3, "Hungup '%s'\n", c->name);
05045 return 0;
05046 }
05047
05048
05049
05050
05051 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05052 {
05053 unsigned short callno = pvt->callno;
05054
05055 if (!pvt->peercallno) {
05056
05057 int count = 10;
05058 while (count-- && pvt && !pvt->peercallno) {
05059 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05060 pvt = iaxs[callno];
05061 }
05062 if (!pvt->peercallno) {
05063 return -1;
05064 }
05065 }
05066
05067 return 0;
05068 }
05069
05070 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05071 {
05072 struct ast_option_header *h;
05073 int res;
05074
05075 switch (option) {
05076 case AST_OPTION_TXGAIN:
05077 case AST_OPTION_RXGAIN:
05078
05079 errno = ENOSYS;
05080 return -1;
05081 case AST_OPTION_OPRMODE:
05082 errno = EINVAL;
05083 return -1;
05084 default:
05085 {
05086 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05087 struct chan_iax2_pvt *pvt;
05088
05089 ast_mutex_lock(&iaxsl[callno]);
05090 pvt = iaxs[callno];
05091
05092 if (wait_for_peercallno(pvt)) {
05093 ast_mutex_unlock(&iaxsl[callno]);
05094 return -1;
05095 }
05096
05097 ast_mutex_unlock(&iaxsl[callno]);
05098
05099 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05100 return -1;
05101 }
05102
05103 h->flag = AST_OPTION_FLAG_REQUEST;
05104 h->option = htons(option);
05105 memcpy(h->data, data, datalen);
05106 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05107 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05108 datalen + sizeof(*h), -1);
05109 ast_free(h);
05110 return res;
05111 }
05112 }
05113 }
05114
05115 static struct ast_frame *iax2_read(struct ast_channel *c)
05116 {
05117 ast_log(LOG_NOTICE, "I should never be called!\n");
05118 return &ast_null_frame;
05119 }
05120
05121 static int iax2_key_rotate(const void *vpvt)
05122 {
05123 int res = 0;
05124 struct chan_iax2_pvt *pvt = (void *) vpvt;
05125 struct MD5Context md5;
05126 char key[17] = "";
05127 struct iax_ie_data ied = {
05128 .pos = 0,
05129 };
05130
05131 ast_mutex_lock(&iaxsl[pvt->callno]);
05132 pvt->keyrotateid =
05133 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05134
05135 snprintf(key, sizeof(key), "%lX", ast_random());
05136
05137 MD5Init(&md5);
05138 MD5Update(&md5, (unsigned char *) key, strlen(key));
05139 MD5Final((unsigned char *) key, &md5);
05140
05141 IAX_DEBUGDIGEST("Sending", key);
05142
05143 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05144
05145 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05146
05147 build_ecx_key((unsigned char *) key, pvt);
05148
05149 ast_mutex_unlock(&iaxsl[pvt->callno]);
05150
05151 return res;
05152 }
05153
05154 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05155 {
05156 int res;
05157 struct iax_ie_data ied0;
05158 struct iax_ie_data ied1;
05159 unsigned int transferid = (unsigned int)ast_random();
05160
05161 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05162 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05163 ast_set_flag(iaxs[callno0], IAX_NOTRANSFER);
05164 ast_set_flag(iaxs[callno1], IAX_NOTRANSFER);
05165 return 0;
05166 }
05167
05168 memset(&ied0, 0, sizeof(ied0));
05169 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05170 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05171 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05172
05173 memset(&ied1, 0, sizeof(ied1));
05174 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05175 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05176 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05177
05178 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05179 if (res)
05180 return -1;
05181 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05182 if (res)
05183 return -1;
05184 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05185 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05186 return 0;
05187 }
05188
05189 static void lock_both(unsigned short callno0, unsigned short callno1)
05190 {
05191 ast_mutex_lock(&iaxsl[callno0]);
05192 while (ast_mutex_trylock(&iaxsl[callno1])) {
05193 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05194 }
05195 }
05196
05197 static void unlock_both(unsigned short callno0, unsigned short callno1)
05198 {
05199 ast_mutex_unlock(&iaxsl[callno1]);
05200 ast_mutex_unlock(&iaxsl[callno0]);
05201 }
05202
05203 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)
05204 {
05205 struct ast_channel *cs[3];
05206 struct ast_channel *who, *other;
05207 int to = -1;
05208 int res = -1;
05209 int transferstarted=0;
05210 struct ast_frame *f;
05211 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05212 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05213 struct timeval waittimer = {0, 0};
05214
05215
05216 if (timeoutms > 0) {
05217 return AST_BRIDGE_FAILED;
05218 }
05219
05220 timeoutms = -1;
05221
05222 lock_both(callno0, callno1);
05223 if (!iaxs[callno0] || !iaxs[callno1]) {
05224 unlock_both(callno0, callno1);
05225 return AST_BRIDGE_FAILED;
05226 }
05227
05228 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05229 iaxs[callno0]->bridgecallno = callno1;
05230 iaxs[callno1]->bridgecallno = callno0;
05231 }
05232 unlock_both(callno0, callno1);
05233
05234
05235 cs[0] = c0;
05236 cs[1] = c1;
05237 for (;;) {
05238
05239 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05240 ast_verb(3, "Can't masquerade, we're different...\n");
05241
05242 if (c0->tech == &iax2_tech) {
05243 ast_mutex_lock(&iaxsl[callno0]);
05244 iaxs[callno0]->bridgecallno = 0;
05245 ast_mutex_unlock(&iaxsl[callno0]);
05246 }
05247 if (c1->tech == &iax2_tech) {
05248 ast_mutex_lock(&iaxsl[callno1]);
05249 iaxs[callno1]->bridgecallno = 0;
05250 ast_mutex_unlock(&iaxsl[callno1]);
05251 }
05252 return AST_BRIDGE_FAILED_NOWARN;
05253 }
05254 if (c0->nativeformats != c1->nativeformats) {
05255 char buf0[255];
05256 char buf1[255];
05257 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
05258 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
05259 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
05260
05261 lock_both(callno0, callno1);
05262 if (iaxs[callno0])
05263 iaxs[callno0]->bridgecallno = 0;
05264 if (iaxs[callno1])
05265 iaxs[callno1]->bridgecallno = 0;
05266 unlock_both(callno0, callno1);
05267 return AST_BRIDGE_FAILED_NOWARN;
05268 }
05269
05270 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
05271
05272 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05273 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
05274 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05275 transferstarted = 1;
05276 }
05277 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05278
05279 struct timeval now = ast_tvnow();
05280 if (ast_tvzero(waittimer)) {
05281 waittimer = now;
05282 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05283 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05284 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05285 *fo = NULL;
05286 *rc = c0;
05287 res = AST_BRIDGE_COMPLETE;
05288 break;
05289 }
05290 }
05291 to = 1000;
05292 who = ast_waitfor_n(cs, 2, &to);
05293 if (timeoutms > -1) {
05294 timeoutms -= (1000 - to);
05295 if (timeoutms < 0)
05296 timeoutms = 0;
05297 }
05298 if (!who) {
05299 if (!timeoutms) {
05300 res = AST_BRIDGE_RETRY;
05301 break;
05302 }
05303 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05304 res = AST_BRIDGE_FAILED;
05305 break;
05306 }
05307 continue;
05308 }
05309 f = ast_read(who);
05310 if (!f) {
05311 *fo = NULL;
05312 *rc = who;
05313 res = AST_BRIDGE_COMPLETE;
05314 break;
05315 }
05316 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
05317 *fo = f;
05318 *rc = who;
05319 res = AST_BRIDGE_COMPLETE;
05320 break;
05321 }
05322 other = (who == c0) ? c1 : c0;
05323 if ((f->frametype == AST_FRAME_VOICE) ||
05324 (f->frametype == AST_FRAME_TEXT) ||
05325 (f->frametype == AST_FRAME_VIDEO) ||
05326 (f->frametype == AST_FRAME_IMAGE) ||
05327 (f->frametype == AST_FRAME_DTMF) ||
05328 (f->frametype == AST_FRAME_CONTROL)) {
05329
05330
05331
05332 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05333 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05334 *rc = who;
05335 *fo = f;
05336 res = AST_BRIDGE_COMPLETE;
05337
05338 break;
05339 }
05340
05341 ast_write(other, f);
05342 }
05343 ast_frfree(f);
05344
05345 cs[2] = cs[0];
05346 cs[0] = cs[1];
05347 cs[1] = cs[2];
05348 }
05349 lock_both(callno0, callno1);
05350 if(iaxs[callno0])
05351 iaxs[callno0]->bridgecallno = 0;
05352 if(iaxs[callno1])
05353 iaxs[callno1]->bridgecallno = 0;
05354 unlock_both(callno0, callno1);
05355 return res;
05356 }
05357
05358 static int iax2_answer(struct ast_channel *c)
05359 {
05360 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05361 ast_debug(1, "Answering IAX2 call\n");
05362 ast_mutex_lock(&iaxsl[callno]);
05363 if (iaxs[callno])
05364 iax2_ami_channelupdate(iaxs[callno]);
05365 ast_mutex_unlock(&iaxsl[callno]);
05366 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05367 }
05368
05369 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05370 {
05371 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05372 struct chan_iax2_pvt *pvt;
05373 int res = 0;
05374
05375 if (iaxdebug)
05376 ast_debug(1, "Indicating condition %d\n", condition);
05377
05378 ast_mutex_lock(&iaxsl[callno]);
05379 pvt = iaxs[callno];
05380
05381 if (wait_for_peercallno(pvt)) {
05382 res = -1;
05383 goto done;
05384 }
05385
05386 switch (condition) {
05387 case AST_CONTROL_HOLD:
05388 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05389 ast_moh_start(c, data, pvt->mohinterpret);
05390 goto done;
05391 }
05392 break;
05393 case AST_CONTROL_UNHOLD:
05394 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05395 ast_moh_stop(c);
05396 goto done;
05397 }
05398 }
05399
05400 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05401
05402 done:
05403 ast_mutex_unlock(&iaxsl[callno]);
05404
05405 return res;
05406 }
05407
05408 static int iax2_transfer(struct ast_channel *c, const char *dest)
05409 {
05410 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05411 struct iax_ie_data ied = { "", };
05412 char tmp[256], *context;
05413 ast_copy_string(tmp, dest, sizeof(tmp));
05414 context = strchr(tmp, '@');
05415 if (context) {
05416 *context = '\0';
05417 context++;
05418 }
05419 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05420 if (context)
05421 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05422 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05423 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05424 }
05425
05426 static int iax2_getpeertrunk(struct sockaddr_in sin)
05427 {
05428 struct iax2_peer *peer;
05429 int res = 0;
05430 struct ao2_iterator i;
05431
05432 i = ao2_iterator_init(peers, 0);
05433 while ((peer = ao2_iterator_next(&i))) {
05434 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05435 (peer->addr.sin_port == sin.sin_port)) {
05436 res = ast_test_flag(peer, IAX_TRUNK);
05437 peer_unref(peer);
05438 break;
05439 }
05440 peer_unref(peer);
05441 }
05442 ao2_iterator_destroy(&i);
05443
05444 return res;
05445 }
05446
05447
05448 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
05449 {
05450 struct ast_channel *tmp;
05451 struct chan_iax2_pvt *i;
05452 struct ast_variable *v = NULL;
05453
05454 if (!(i = iaxs[callno])) {
05455 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05456 return NULL;
05457 }
05458
05459
05460 ast_mutex_unlock(&iaxsl[callno]);
05461 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);
05462 ast_mutex_lock(&iaxsl[callno]);
05463 if (i != iaxs[callno]) {
05464 if (tmp) {
05465
05466 ast_mutex_unlock(&iaxsl[callno]);
05467 ast_channel_free(tmp);
05468 ast_mutex_lock(&iaxsl[callno]);
05469 }
05470 return NULL;
05471 }
05472 iax2_ami_channelupdate(i);
05473 if (!tmp)
05474 return NULL;
05475 tmp->tech = &iax2_tech;
05476
05477 tmp->nativeformats = capability;
05478 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05479 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05480 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05481
05482 if (!ast_strlen_zero(i->parkinglot))
05483 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05484
05485
05486 if (!ast_strlen_zero(i->ani))
05487 tmp->cid.cid_ani = ast_strdup(i->ani);
05488 else
05489 tmp->cid.cid_ani = ast_strdup(i->cid_num);
05490 tmp->cid.cid_dnid = ast_strdup(i->dnid);
05491 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
05492 tmp->cid.cid_pres = i->calling_pres;
05493 tmp->cid.cid_ton = i->calling_ton;
05494 tmp->cid.cid_tns = i->calling_tns;
05495 if (!ast_strlen_zero(i->language))
05496 ast_string_field_set(tmp, language, i->language);
05497 if (!ast_strlen_zero(i->accountcode))
05498 ast_string_field_set(tmp, accountcode, i->accountcode);
05499 if (i->amaflags)
05500 tmp->amaflags = i->amaflags;
05501 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05502 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05503 if (i->adsi)
05504 tmp->adsicpe = i->peeradsicpe;
05505 else
05506 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05507 i->owner = tmp;
05508 i->capability = capability;
05509
05510
05511 if (i->vars) {
05512 for (v = i->vars ; v ; v = v->next)
05513 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05514 }
05515 if (i->iaxvars) {
05516 struct ast_datastore *variablestore;
05517 struct ast_variable *var, *prev = NULL;
05518 AST_LIST_HEAD(, ast_var_t) *varlist;
05519 ast_debug(1, "Loading up the channel with IAXVARs\n");
05520 varlist = ast_calloc(1, sizeof(*varlist));
05521 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05522 if (variablestore && varlist) {
05523 variablestore->data = varlist;
05524 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05525 AST_LIST_HEAD_INIT(varlist);
05526 for (var = i->iaxvars; var; var = var->next) {
05527 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05528 if (prev)
05529 ast_free(prev);
05530 prev = var;
05531 if (!newvar) {
05532
05533 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05534 } else {
05535 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05536 }
05537 }
05538 if (prev)
05539 ast_free(prev);
05540 i->iaxvars = NULL;
05541 ast_channel_datastore_add(i->owner, variablestore);
05542 } else {
05543 if (variablestore) {
05544 ast_datastore_free(variablestore);
05545 }
05546 if (varlist) {
05547 ast_free(varlist);
05548 }
05549 }
05550 }
05551
05552 if (state != AST_STATE_DOWN) {
05553 if (ast_pbx_start(tmp)) {
05554 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05555 ast_hangup(tmp);
05556 i->owner = NULL;
05557 return NULL;
05558 }
05559 }
05560
05561 ast_module_ref(ast_module_info->self);
05562 return tmp;
05563 }
05564
05565 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05566 {
05567 unsigned long int mssincetx;
05568 long int ms, pred;
05569
05570 tpeer->trunkact = *now;
05571 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05572 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05573
05574 tpeer->txtrunktime = *now;
05575 tpeer->lastsent = 999999;
05576 }
05577
05578 tpeer->lasttxtime = *now;
05579
05580
05581 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05582
05583 pred = tpeer->lastsent + sampms;
05584 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05585 ms = pred;
05586
05587
05588 if (ms == tpeer->lastsent)
05589 ms = tpeer->lastsent + 1;
05590 tpeer->lastsent = ms;
05591 return ms;
05592 }
05593
05594 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05595 {
05596 long ms;
05597 if (ast_tvzero(iaxs[callno]->rxcore)) {
05598
05599 iaxs[callno]->rxcore = ast_tvnow();
05600
05601 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05602 }
05603
05604 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05605
05606 return ms + ts;
05607 }
05608
05609 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05610 {
05611 int ms;
05612 int voice = 0;
05613 int genuine = 0;
05614 int adjust;
05615 int rate = ast_format_rate(f->subclass) / 1000;
05616 struct timeval *delivery = NULL;
05617
05618
05619
05620
05621
05622
05623
05624
05625 if (f) {
05626 if (f->frametype == AST_FRAME_VOICE) {
05627 voice = 1;
05628 delivery = &f->delivery;
05629 } else if (f->frametype == AST_FRAME_IAX) {
05630 genuine = 1;
05631 } else if (f->frametype == AST_FRAME_CNG) {
05632 p->notsilenttx = 0;
05633 }
05634 }
05635 if (ast_tvzero(p->offset)) {
05636 p->offset = ast_tvnow();
05637
05638 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05639 }
05640
05641 if (ts)
05642 return ts;
05643
05644 if (delivery && !ast_tvzero(*delivery)) {
05645 ms = ast_tvdiff_ms(*delivery, p->offset);
05646 if (ms < 0) {
05647 ms = 0;
05648 }
05649 if (iaxdebug)
05650 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05651 } else {
05652 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05653 if (ms < 0)
05654 ms = 0;
05655 if (voice) {
05656
05657 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05658
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675
05676 adjust = (ms - p->nextpred);
05677 if (adjust < 0)
05678 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05679 else if (adjust > 0)
05680 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05681
05682 if (!p->nextpred) {
05683 p->nextpred = ms;
05684 if (p->nextpred <= p->lastsent)
05685 p->nextpred = p->lastsent + 3;
05686 }
05687 ms = p->nextpred;
05688 } else {
05689
05690
05691
05692
05693
05694
05695
05696
05697
05698 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05699 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05700 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05701
05702 if (f->samples >= rate)
05703 {
05704 int diff = ms % (f->samples / rate);
05705 if (diff)
05706 ms += f->samples/rate - diff;
05707 }
05708
05709 p->nextpred = ms;
05710 p->notsilenttx = 1;
05711 }
05712 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05713
05714
05715
05716
05717
05718
05719
05720
05721 if ( (unsigned int)ms < p->lastsent )
05722 ms = p->lastsent;
05723 } else {
05724
05725
05726 if (genuine) {
05727
05728 if (ms <= p->lastsent)
05729 ms = p->lastsent + 3;
05730 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05731
05732 ms = p->lastsent + 3;
05733 }
05734 }
05735 }
05736 p->lastsent = ms;
05737 if (voice)
05738 p->nextpred = p->nextpred + f->samples / rate;
05739 return ms;
05740 }
05741
05742 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05743 {
05744
05745
05746 int ms;
05747 #ifdef IAXTESTS
05748 int jit;
05749 #endif
05750
05751 if (ast_tvzero(p->rxcore)) {
05752 p->rxcore = ast_tvnow();
05753 if (iaxdebug)
05754 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05755 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05756 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05757 #if 1
05758 if (iaxdebug)
05759 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05760 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05761 #endif
05762 }
05763
05764 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05765 #ifdef IAXTESTS
05766 if (test_jit) {
05767 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05768 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05769 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05770 jit = -jit;
05771 ms += jit;
05772 }
05773 }
05774 if (test_late) {
05775 ms += test_late;
05776 test_late = 0;
05777 }
05778 #endif
05779 return ms;
05780 }
05781
05782 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
05783 {
05784 struct iax2_trunk_peer *tpeer = NULL;
05785
05786
05787 AST_LIST_LOCK(&tpeers);
05788
05789 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
05790 if (!inaddrcmp(&tpeer->addr, sin)) {
05791 ast_mutex_lock(&tpeer->lock);
05792 break;
05793 }
05794 }
05795
05796 if (!tpeer) {
05797 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
05798 ast_mutex_init(&tpeer->lock);
05799 tpeer->lastsent = 9999;
05800 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
05801 tpeer->trunkact = ast_tvnow();
05802 ast_mutex_lock(&tpeer->lock);
05803 tpeer->sockfd = fd;
05804 #ifdef SO_NO_CHECK
05805 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
05806 #endif
05807 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05808 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
05809 }
05810 }
05811
05812 AST_LIST_UNLOCK(&tpeers);
05813
05814 return tpeer;
05815 }
05816
05817 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
05818 {
05819 struct ast_frame *f;
05820 struct iax2_trunk_peer *tpeer;
05821 void *tmp, *ptr;
05822 struct timeval now;
05823 int res;
05824 struct ast_iax2_meta_trunk_entry *met;
05825 struct ast_iax2_meta_trunk_mini *mtm;
05826
05827 f = &fr->af;
05828 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
05829 if (tpeer) {
05830 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
05831
05832 if (tpeer->trunkdataalloc < trunkmaxsize) {
05833 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
05834 ast_mutex_unlock(&tpeer->lock);
05835 return -1;
05836 }
05837
05838 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
05839 tpeer->trunkdata = tmp;
05840 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);
05841 } else {
05842 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));
05843 ast_mutex_unlock(&tpeer->lock);
05844 return -1;
05845 }
05846 }
05847
05848
05849 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
05850 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
05851 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
05852 mtm->len = htons(f->datalen);
05853 mtm->mini.callno = htons(pvt->callno);
05854 mtm->mini.ts = htons(0xffff & fr->ts);
05855 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
05856 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
05857 } else {
05858 met = (struct ast_iax2_meta_trunk_entry *)ptr;
05859
05860 met->callno = htons(pvt->callno);
05861 met->len = htons(f->datalen);
05862
05863 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
05864 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
05865 }
05866
05867 memcpy(ptr, f->data.ptr, f->datalen);
05868 tpeer->trunkdatalen += f->datalen;
05869
05870 tpeer->calls++;
05871
05872
05873 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
05874 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
05875
05876
05877 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
05878 now = ast_tvnow();
05879 res = send_trunk(tpeer, &now);
05880 trunk_untimed ++;
05881 }
05882
05883 ast_mutex_unlock(&tpeer->lock);
05884 }
05885 return 0;
05886 }
05887
05888
05889
05890 static void build_rand_pad(unsigned char *buf, ssize_t len)
05891 {
05892 long tmp;
05893 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05894 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05895 buf += sizeof(tmp);
05896 len -= sizeof(tmp);
05897 }
05898 }
05899
05900 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05901 {
05902 build_ecx_key(digest, pvt);
05903 ast_aes_decrypt_key(digest, &pvt->dcx);
05904 }
05905
05906 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
05907 {
05908
05909
05910
05911 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05912 ast_aes_encrypt_key(digest, &pvt->ecx);
05913 ast_aes_decrypt_key(digest, &pvt->mydcx);
05914 }
05915
05916 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
05917 {
05918 #if 0
05919
05920 int x;
05921 if (len % 16)
05922 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05923 for (x=0;x<len;x++)
05924 dst[x] = src[x] ^ 0xff;
05925 #else
05926 unsigned char lastblock[16] = { 0 };
05927 int x;
05928 while(len > 0) {
05929 ast_aes_decrypt(src, dst, dcx);
05930 for (x=0;x<16;x++)
05931 dst[x] ^= lastblock[x];
05932 memcpy(lastblock, src, sizeof(lastblock));
05933 dst += 16;
05934 src += 16;
05935 len -= 16;
05936 }
05937 #endif
05938 }
05939
05940 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
05941 {
05942 #if 0
05943
05944 int x;
05945 if (len % 16)
05946 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05947 for (x=0;x<len;x++)
05948 dst[x] = src[x] ^ 0xff;
05949 #else
05950 unsigned char curblock[16] = { 0 };
05951 int x;
05952 while(len > 0) {
05953 for (x=0;x<16;x++)
05954 curblock[x] ^= src[x];
05955 ast_aes_encrypt(curblock, dst, ecx);
05956 memcpy(curblock, dst, sizeof(curblock));
05957 dst += 16;
05958 src += 16;
05959 len -= 16;
05960 }
05961 #endif
05962 }
05963
05964 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
05965 {
05966 int padding;
05967 unsigned char *workspace;
05968
05969 workspace = alloca(*datalen);
05970 memset(f, 0, sizeof(*f));
05971 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05972 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05973 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
05974 return -1;
05975
05976 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
05977
05978 padding = 16 + (workspace[15] & 0x0f);
05979 if (iaxdebug)
05980 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
05981 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
05982 return -1;
05983
05984 *datalen -= padding;
05985 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05986 f->frametype = fh->type;
05987 if (f->frametype == AST_FRAME_VIDEO) {
05988 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
05989 } else {
05990 f->subclass = uncompress_subclass(fh->csub);
05991 }
05992 } else {
05993 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05994 if (iaxdebug)
05995 ast_debug(1, "Decoding mini with length %d\n", *datalen);
05996 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
05997 return -1;
05998
05999 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06000 padding = 16 + (workspace[15] & 0x0f);
06001 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06002 return -1;
06003 *datalen -= padding;
06004 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06005 }
06006 return 0;
06007 }
06008
06009 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06010 {
06011 int padding;
06012 unsigned char *workspace;
06013 workspace = alloca(*datalen + 32);
06014 if (!workspace)
06015 return -1;
06016 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06017 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06018 if (iaxdebug)
06019 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06020 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06021 padding = 16 + (padding & 0xf);
06022 memcpy(workspace, poo, padding);
06023 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06024 workspace[15] &= 0xf0;
06025 workspace[15] |= (padding & 0xf);
06026 if (iaxdebug)
06027 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06028 *datalen += padding;
06029 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06030 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06031 memcpy(poo, workspace + *datalen - 32, 32);
06032 } else {
06033 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06034 if (iaxdebug)
06035 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06036 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06037 padding = 16 + (padding & 0xf);
06038 memcpy(workspace, poo, padding);
06039 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06040 workspace[15] &= 0xf0;
06041 workspace[15] |= (padding & 0x0f);
06042 *datalen += padding;
06043 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06044 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06045 memcpy(poo, workspace + *datalen - 32, 32);
06046 }
06047 return 0;
06048 }
06049
06050 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06051 {
06052 int res=-1;
06053 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
06054
06055 struct MD5Context md5;
06056 unsigned char digest[16];
06057 char *tmppw, *stringp;
06058
06059 tmppw = ast_strdupa(iaxs[callno]->secret);
06060 stringp = tmppw;
06061 while ((tmppw = strsep(&stringp, ";"))) {
06062 MD5Init(&md5);
06063 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06064 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06065 MD5Final(digest, &md5);
06066 build_encryption_keys(digest, iaxs[callno]);
06067 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06068 if (!res) {
06069 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
06070 break;
06071 }
06072 }
06073 } else
06074 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06075 return res;
06076 }
06077
06078 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06079 {
06080
06081
06082
06083 struct ast_iax2_full_hdr *fh;
06084 struct ast_iax2_mini_hdr *mh;
06085 struct ast_iax2_video_hdr *vh;
06086 struct {
06087 struct iax_frame fr2;
06088 unsigned char buffer[4096];
06089 } frb;
06090 struct iax_frame *fr;
06091 int res;
06092 int sendmini=0;
06093 unsigned int lastsent;
06094 unsigned int fts;
06095
06096 frb.fr2.afdatalen = sizeof(frb.buffer);
06097
06098 if (!pvt) {
06099 ast_log(LOG_WARNING, "No private structure for packet?\n");
06100 return -1;
06101 }
06102
06103 lastsent = pvt->lastsent;
06104
06105
06106 fts = calc_timestamp(pvt, ts, f);
06107
06108
06109
06110
06111 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06112 return 0;
06113 #if 0
06114 ast_log(LOG_NOTICE,
06115 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06116 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06117 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06118 pvt->keyrotateid != -1 ? "" : "no "
06119 );
06120 #endif
06121 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06122 iax2_key_rotate(pvt);
06123 }
06124
06125 if ((ast_test_flag(pvt, IAX_TRUNK) ||
06126 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06127 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06128 &&
06129 (f->frametype == AST_FRAME_VOICE)
06130 &&
06131 (f->subclass == pvt->svoiceformat)
06132 ) {
06133
06134 now = 1;
06135
06136 sendmini = 1;
06137 }
06138 if ( f->frametype == AST_FRAME_VIDEO ) {
06139
06140
06141
06142
06143
06144 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06145 ((f->subclass & ~0x1) == pvt->svideoformat)
06146 ) {
06147 now = 1;
06148 sendmini = 1;
06149 } else {
06150 now = 0;
06151 sendmini = 0;
06152 }
06153 pvt->lastvsent = fts;
06154 }
06155 if (f->frametype == AST_FRAME_IAX) {
06156
06157 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
06158 if (!pvt->first_iax_message) {
06159 pvt->first_iax_message = pvt->last_iax_message;
06160 }
06161 }
06162
06163 if (now) {
06164 fr = &frb.fr2;
06165 } else
06166 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));
06167 if (!fr) {
06168 ast_log(LOG_WARNING, "Out of memory\n");
06169 return -1;
06170 }
06171
06172 iax_frame_wrap(fr, f);
06173
06174 fr->ts = fts;
06175 fr->callno = pvt->callno;
06176 fr->transfer = transfer;
06177 fr->final = final;
06178 fr->encmethods = 0;
06179 if (!sendmini) {
06180
06181 if (seqno > -1)
06182 fr->oseqno = seqno;
06183 else
06184 fr->oseqno = pvt->oseqno++;
06185 fr->iseqno = pvt->iseqno;
06186 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06187 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06188 fh->ts = htonl(fr->ts);
06189 fh->oseqno = fr->oseqno;
06190 if (transfer) {
06191 fh->iseqno = 0;
06192 } else
06193 fh->iseqno = fr->iseqno;
06194
06195 if (!transfer)
06196 pvt->aseqno = fr->iseqno;
06197 fh->type = fr->af.frametype & 0xFF;
06198 if (fr->af.frametype == AST_FRAME_VIDEO)
06199 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
06200 else
06201 fh->csub = compress_subclass(fr->af.subclass);
06202 if (transfer) {
06203 fr->dcallno = pvt->transfercallno;
06204 } else
06205 fr->dcallno = pvt->peercallno;
06206 fh->dcallno = htons(fr->dcallno);
06207 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06208 fr->data = fh;
06209 fr->retries = 0;
06210
06211 fr->retrytime = pvt->pingtime * 2;
06212 if (fr->retrytime < MIN_RETRY_TIME)
06213 fr->retrytime = MIN_RETRY_TIME;
06214 if (fr->retrytime > MAX_RETRY_TIME)
06215 fr->retrytime = MAX_RETRY_TIME;
06216
06217 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
06218 fr->retries = -1;
06219 else if (f->frametype == AST_FRAME_VOICE)
06220 pvt->svoiceformat = f->subclass;
06221 else if (f->frametype == AST_FRAME_VIDEO)
06222 pvt->svideoformat = f->subclass & ~0x1;
06223 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06224 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06225 if (fr->transfer)
06226 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06227 else
06228 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06229 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06230 fr->encmethods = pvt->encmethods;
06231 fr->ecx = pvt->ecx;
06232 fr->mydcx = pvt->mydcx;
06233 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06234 } else
06235 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06236 }
06237
06238 if (now) {
06239 res = send_packet(fr);
06240 } else
06241 res = iax2_transmit(fr);
06242 } else {
06243 if (ast_test_flag(pvt, IAX_TRUNK)) {
06244 iax2_trunk_queue(pvt, fr);
06245 res = 0;
06246 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06247
06248 fr->oseqno = -1;
06249 fr->iseqno = -1;
06250 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06251 vh->zeros = 0;
06252 vh->callno = htons(0x8000 | fr->callno);
06253 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
06254 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06255 fr->data = vh;
06256 fr->retries = -1;
06257 res = send_packet(fr);
06258 } else {
06259
06260 fr->oseqno = -1;
06261 fr->iseqno = -1;
06262
06263 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06264 mh->callno = htons(fr->callno);
06265 mh->ts = htons(fr->ts & 0xFFFF);
06266 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06267 fr->data = mh;
06268 fr->retries = -1;
06269 if (pvt->transferring == TRANSFER_MEDIAPASS)
06270 fr->transfer = 1;
06271 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
06272 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
06273 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06274 } else
06275 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06276 }
06277 res = send_packet(fr);
06278 }
06279 }
06280 return res;
06281 }
06282
06283 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06284 {
06285 regex_t regexbuf;
06286 int havepattern = 0;
06287
06288 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06289 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06290
06291 struct iax2_user *user = NULL;
06292 char auth[90];
06293 char *pstr = "";
06294 struct ao2_iterator i;
06295
06296 switch (cmd) {
06297 case CLI_INIT:
06298 e->command = "iax2 show users [like]";
06299 e->usage =
06300 "Usage: iax2 show users [like <pattern>]\n"
06301 " Lists all known IAX2 users.\n"
06302 " Optional regular expression pattern is used to filter the user list.\n";
06303 return NULL;
06304 case CLI_GENERATE:
06305 return NULL;
06306 }
06307
06308 switch (a->argc) {
06309 case 5:
06310 if (!strcasecmp(a->argv[3], "like")) {
06311 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06312 return CLI_SHOWUSAGE;
06313 havepattern = 1;
06314 } else
06315 return CLI_SHOWUSAGE;
06316 case 3:
06317 break;
06318 default:
06319 return CLI_SHOWUSAGE;
06320 }
06321
06322 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06323 i = ao2_iterator_init(users, 0);
06324 for (user = ao2_iterator_next(&i); user;
06325 user_unref(user), user = ao2_iterator_next(&i)) {
06326 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06327 continue;
06328
06329 if (!ast_strlen_zero(user->secret)) {
06330 ast_copy_string(auth,user->secret, sizeof(auth));
06331 } else if (!ast_strlen_zero(user->inkeys)) {
06332 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06333 } else
06334 ast_copy_string(auth, "-no secret-", sizeof(auth));
06335
06336 if(ast_test_flag(user,IAX_CODEC_NOCAP))
06337 pstr = "REQ Only";
06338 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
06339 pstr = "Disabled";
06340 else
06341 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06342
06343 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06344 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06345 user->ha ? "Yes" : "No", pstr);
06346 }
06347 ao2_iterator_destroy(&i);
06348
06349 if (havepattern)
06350 regfree(®exbuf);
06351
06352 return CLI_SUCCESS;
06353 #undef FORMAT
06354 #undef FORMAT2
06355 }
06356
06357 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
06358 {
06359 regex_t regexbuf;
06360 int havepattern = 0;
06361 int total_peers = 0;
06362 int online_peers = 0;
06363 int offline_peers = 0;
06364 int unmonitored_peers = 0;
06365 struct ao2_iterator i;
06366
06367 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
06368 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
06369
06370 struct iax2_peer *peer = NULL;
06371 char name[256];
06372 struct ast_str *encmethods = ast_str_alloca(256);
06373 int registeredonly=0;
06374 char *term = manager ? "\r\n" : "\n";
06375 char idtext[256] = "";
06376 switch (argc) {
06377 case 6:
06378 if (!strcasecmp(argv[3], "registered"))
06379 registeredonly = 1;
06380 else
06381 return RESULT_SHOWUSAGE;
06382 if (!strcasecmp(argv[4], "like")) {
06383 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06384 return RESULT_SHOWUSAGE;
06385 havepattern = 1;
06386 } else
06387 return RESULT_SHOWUSAGE;
06388 break;
06389 case 5:
06390 if (!strcasecmp(argv[3], "like")) {
06391 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06392 return RESULT_SHOWUSAGE;
06393 havepattern = 1;
06394 } else
06395 return RESULT_SHOWUSAGE;
06396 break;
06397 case 4:
06398 if (!strcasecmp(argv[3], "registered"))
06399 registeredonly = 1;
06400 else
06401 return RESULT_SHOWUSAGE;
06402 break;
06403 case 3:
06404 break;
06405 default:
06406 return RESULT_SHOWUSAGE;
06407 }
06408
06409
06410 if (!s)
06411 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
06412
06413 i = ao2_iterator_init(peers, 0);
06414 for (peer = ao2_iterator_next(&i); peer;
06415 peer_unref(peer), peer = ao2_iterator_next(&i)) {
06416 char nm[20];
06417 char status[20];
06418 int retstatus;
06419
06420 if (registeredonly && !peer->addr.sin_addr.s_addr)
06421 continue;
06422 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
06423 continue;
06424
06425 if (!ast_strlen_zero(peer->username))
06426 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06427 else
06428 ast_copy_string(name, peer->name, sizeof(name));
06429
06430 encmethods_to_str(peer->encmethods, encmethods);
06431 retstatus = peer_status(peer, status, sizeof(status));
06432 if (retstatus > 0)
06433 online_peers++;
06434 else if (!retstatus)
06435 offline_peers++;
06436 else
06437 unmonitored_peers++;
06438
06439 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06440
06441 if (s) {
06442 astman_append(s,
06443 "Event: PeerEntry\r\n%s"
06444 "Channeltype: IAX2\r\n"
06445 "ChanObjectType: peer\r\n"
06446 "ObjectName: %s\r\n"
06447 "IPaddress: %s\r\n"
06448 "IPport: %d\r\n"
06449 "Dynamic: %s\r\n"
06450 "Trunk: %s\r\n"
06451 "Encryption: %s\r\n"
06452 "Status: %s\r\n\r\n",
06453 idtext,
06454 name,
06455 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
06456 ntohs(peer->addr.sin_port),
06457 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
06458 ast_test_flag(peer, IAX_TRUNK) ? "yes" : "no",
06459 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06460 status);
06461 } else {
06462 ast_cli(fd, FORMAT, name,
06463 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
06464 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06465 nm,
06466 ntohs(peer->addr.sin_port),
06467 ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
06468 peer->encmethods ? "(E)" : " ",
06469 status,
06470 term);
06471 }
06472 total_peers++;
06473 }
06474 ao2_iterator_destroy(&i);
06475
06476 if (!s)
06477 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
06478
06479 if (havepattern)
06480 regfree(®exbuf);
06481
06482 return RESULT_SUCCESS;
06483 #undef FORMAT
06484 #undef FORMAT2
06485 }
06486
06487 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06488 {
06489 struct iax2_thread *thread = NULL;
06490 time_t t;
06491 int threadcount = 0, dynamiccount = 0;
06492 char type;
06493
06494 switch (cmd) {
06495 case CLI_INIT:
06496 e->command = "iax2 show threads";
06497 e->usage =
06498 "Usage: iax2 show threads\n"
06499 " Lists status of IAX helper threads\n";
06500 return NULL;
06501 case CLI_GENERATE:
06502 return NULL;
06503 }
06504 if (a->argc != 3)
06505 return CLI_SHOWUSAGE;
06506
06507 ast_cli(a->fd, "IAX2 Thread Information\n");
06508 time(&t);
06509 ast_cli(a->fd, "Idle Threads:\n");
06510 AST_LIST_LOCK(&idle_list);
06511 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06512 #ifdef DEBUG_SCHED_MULTITHREAD
06513 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06514 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06515 #else
06516 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06517 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06518 #endif
06519 threadcount++;
06520 }
06521 AST_LIST_UNLOCK(&idle_list);
06522 ast_cli(a->fd, "Active Threads:\n");
06523 AST_LIST_LOCK(&active_list);
06524 AST_LIST_TRAVERSE(&active_list, thread, list) {
06525 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06526 type = 'D';
06527 else
06528 type = 'P';
06529 #ifdef DEBUG_SCHED_MULTITHREAD
06530 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06531 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06532 #else
06533 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06534 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06535 #endif
06536 threadcount++;
06537 }
06538 AST_LIST_UNLOCK(&active_list);
06539 ast_cli(a->fd, "Dynamic Threads:\n");
06540 AST_LIST_LOCK(&dynamic_list);
06541 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06542 #ifdef DEBUG_SCHED_MULTITHREAD
06543 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06544 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06545 #else
06546 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06547 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06548 #endif
06549 dynamiccount++;
06550 }
06551 AST_LIST_UNLOCK(&dynamic_list);
06552 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06553 return CLI_SUCCESS;
06554 }
06555
06556 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06557 {
06558 struct iax2_peer *p;
06559
06560 switch (cmd) {
06561 case CLI_INIT:
06562 e->command = "iax2 unregister";
06563 e->usage =
06564 "Usage: iax2 unregister <peername>\n"
06565 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06566 return NULL;
06567 case CLI_GENERATE:
06568 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06569 }
06570
06571 if (a->argc != 3)
06572 return CLI_SHOWUSAGE;
06573
06574 p = find_peer(a->argv[2], 1);
06575 if (p) {
06576 if (p->expire > 0) {
06577 struct iax2_peer tmp_peer = {
06578 .name = a->argv[2],
06579 };
06580 struct iax2_peer *peer;
06581
06582 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06583 if (peer) {
06584 expire_registry(peer_ref(peer));
06585 peer_unref(peer);
06586 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06587 } else {
06588 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06589 }
06590 } else {
06591 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06592 }
06593 } else {
06594 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06595 }
06596 return CLI_SUCCESS;
06597 }
06598
06599 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06600 {
06601 int which = 0;
06602 struct iax2_peer *p = NULL;
06603 char *res = NULL;
06604 int wordlen = strlen(word);
06605
06606
06607 if (pos == 2) {
06608 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06609 while ((p = ao2_iterator_next(&i))) {
06610 if (!strncasecmp(p->name, word, wordlen) &&
06611 ++which > state && p->expire > 0) {
06612 res = ast_strdup(p->name);
06613 peer_unref(p);
06614 break;
06615 }
06616 peer_unref(p);
06617 }
06618 ao2_iterator_destroy(&i);
06619 }
06620
06621 return res;
06622 }
06623
06624 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06625 {
06626 switch (cmd) {
06627 case CLI_INIT:
06628 e->command = "iax2 show peers";
06629 e->usage =
06630 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06631 " Lists all known IAX2 peers.\n"
06632 " Optional 'registered' argument lists only peers with known addresses.\n"
06633 " Optional regular expression pattern is used to filter the peer list.\n";
06634 return NULL;
06635 case CLI_GENERATE:
06636 return NULL;
06637 }
06638
06639 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
06640 case RESULT_SHOWUSAGE:
06641 return CLI_SHOWUSAGE;
06642 case RESULT_FAILURE:
06643 return CLI_FAILURE;
06644 default:
06645 return CLI_SUCCESS;
06646 }
06647 }
06648
06649 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06650 {
06651 ast_cli_netstats(s, -1, 0);
06652 astman_append(s, "\r\n");
06653 return RESULT_SUCCESS;
06654 }
06655
06656 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06657 {
06658 struct iax_firmware *cur = NULL;
06659
06660 switch (cmd) {
06661 case CLI_INIT:
06662 e->command = "iax2 show firmware";
06663 e->usage =
06664 "Usage: iax2 show firmware\n"
06665 " Lists all known IAX firmware images.\n";
06666 return NULL;
06667 case CLI_GENERATE:
06668 return NULL;
06669 }
06670
06671 if (a->argc != 3 && a->argc != 4)
06672 return CLI_SHOWUSAGE;
06673
06674 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06675 AST_LIST_LOCK(&firmwares);
06676 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06677 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06678 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06679 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06680 }
06681 }
06682 AST_LIST_UNLOCK(&firmwares);
06683
06684 return CLI_SUCCESS;
06685 }
06686
06687
06688 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06689 {
06690 char *a[] = { "iax2", "show", "users" };
06691 const char *id = astman_get_header(m,"ActionID");
06692 char idtext[256] = "";
06693
06694 if (!ast_strlen_zero(id))
06695 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06696 astman_send_ack(s, m, "Peer status list will follow");
06697 return __iax2_show_peers(1, -1, s, 3, a );
06698 }
06699
06700
06701 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06702 {
06703 struct iax2_peer *peer = NULL;
06704 int peer_count = 0;
06705 char nm[20];
06706 char status[20];
06707 const char *id = astman_get_header(m,"ActionID");
06708 char idtext[256] = "";
06709 struct ast_str *encmethods = ast_str_alloca(256);
06710 struct ao2_iterator i;
06711
06712 if (!ast_strlen_zero(id))
06713 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06714
06715 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06716
06717
06718 i = ao2_iterator_init(peers, 0);
06719 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06720 encmethods_to_str(peer->encmethods, encmethods);
06721 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06722 if (!ast_strlen_zero(peer->username)) {
06723 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06724 } else {
06725 astman_append(s, "ObjectName: %s\r\n", peer->name);
06726 }
06727 astman_append(s, "ChanObjectType: peer\r\n");
06728 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
06729 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06730 astman_append(s, "Mask: %s\r\n", nm);
06731 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
06732 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
06733 astman_append(s, "Trunk: %s\r\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
06734 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
06735 peer_status(peer, status, sizeof(status));
06736 astman_append(s, "Status: %s\r\n\r\n", status);
06737 peer_count++;
06738 }
06739 ao2_iterator_destroy(&i);
06740
06741 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
06742 return RESULT_SUCCESS;
06743 }
06744
06745
06746 static char *regstate2str(int regstate)
06747 {
06748 switch(regstate) {
06749 case REG_STATE_UNREGISTERED:
06750 return "Unregistered";
06751 case REG_STATE_REGSENT:
06752 return "Request Sent";
06753 case REG_STATE_AUTHSENT:
06754 return "Auth. Sent";
06755 case REG_STATE_REGISTERED:
06756 return "Registered";
06757 case REG_STATE_REJECTED:
06758 return "Rejected";
06759 case REG_STATE_TIMEOUT:
06760 return "Timeout";
06761 case REG_STATE_NOAUTH:
06762 return "No Authentication";
06763 default:
06764 return "Unknown";
06765 }
06766 }
06767
06768 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06769 {
06770 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
06771 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
06772 struct iax2_registry *reg = NULL;
06773 char host[80];
06774 char perceived[80];
06775 int counter = 0;
06776
06777 switch (cmd) {
06778 case CLI_INIT:
06779 e->command = "iax2 show registry";
06780 e->usage =
06781 "Usage: iax2 show registry\n"
06782 " Lists all registration requests and status.\n";
06783 return NULL;
06784 case CLI_GENERATE:
06785 return NULL;
06786 }
06787 if (a->argc != 3)
06788 return CLI_SHOWUSAGE;
06789 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
06790 AST_LIST_LOCK(®istrations);
06791 AST_LIST_TRAVERSE(®istrations, reg, entry) {
06792 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06793 if (reg->us.sin_addr.s_addr)
06794 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06795 else
06796 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06797 ast_cli(a->fd, FORMAT, host,
06798 (reg->dnsmgr) ? "Y" : "N",
06799 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
06800 counter++;
06801 }
06802 AST_LIST_UNLOCK(®istrations);
06803 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
06804 return CLI_SUCCESS;
06805 #undef FORMAT
06806 #undef FORMAT2
06807 }
06808
06809 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
06810 {
06811 const char *id = astman_get_header(m, "ActionID");
06812 struct iax2_registry *reg = NULL;
06813 char idtext[256] = "";
06814 char host[80] = "";
06815 char perceived[80] = "";
06816 int total = 0;
06817
06818 if (!ast_strlen_zero(id))
06819 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06820
06821 astman_send_listack(s, m, "Registrations will follow", "start");
06822
06823 AST_LIST_LOCK(®istrations);
06824 AST_LIST_TRAVERSE(®istrations, reg, entry) {
06825 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06826
06827 if (reg->us.sin_addr.s_addr) {
06828 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06829 } else {
06830 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06831 }
06832
06833 astman_append(s,
06834 "Event: RegistryEntry\r\n"
06835 "%s"
06836 "Host: %s\r\n"
06837 "DNSmanager: %s\r\n"
06838 "Username: %s\r\n"
06839 "Perceived: %s\r\n"
06840 "Refresh: %d\r\n"
06841 "State: %s\r\n"
06842 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
06843 reg->refresh, regstate2str(reg->regstate));
06844
06845 total++;
06846 }
06847 AST_LIST_UNLOCK(®istrations);
06848
06849 astman_append(s,
06850 "Event: RegistrationsComplete\r\n"
06851 "EventList: Complete\r\n"
06852 "ListItems: %d\r\n"
06853 "%s"
06854 "\r\n", total, idtext);
06855
06856 return 0;
06857 }
06858
06859 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06860 {
06861 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
06862 #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"
06863 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
06864 int x;
06865 int numchans = 0;
06866 char first_message[10] = { 0, };
06867 char last_message[10] = { 0, };
06868
06869 switch (cmd) {
06870 case CLI_INIT:
06871 e->command = "iax2 show channels";
06872 e->usage =
06873 "Usage: iax2 show channels\n"
06874 " Lists all currently active IAX channels.\n";
06875 return NULL;
06876 case CLI_GENERATE:
06877 return NULL;
06878 }
06879
06880 if (a->argc != 3)
06881 return CLI_SHOWUSAGE;
06882 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
06883 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06884 ast_mutex_lock(&iaxsl[x]);
06885 if (iaxs[x]) {
06886 int lag, jitter, localdelay;
06887 jb_info jbinfo;
06888 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06889 jb_getinfo(iaxs[x]->jb, &jbinfo);
06890 jitter = jbinfo.jitter;
06891 localdelay = jbinfo.current - jbinfo.min;
06892 } else {
06893 jitter = -1;
06894 localdelay = 0;
06895 }
06896
06897 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06898 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06899 lag = iaxs[x]->remote_rr.delay;
06900 ast_cli(a->fd, FORMAT,
06901 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06902 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
06903 S_OR(iaxs[x]->username, "(None)"),
06904 iaxs[x]->callno, iaxs[x]->peercallno,
06905 iaxs[x]->oseqno, iaxs[x]->iseqno,
06906 lag,
06907 jitter,
06908 localdelay,
06909 ast_getformatname(iaxs[x]->voiceformat),
06910 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06911 first_message,
06912 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06913 last_message);
06914 numchans++;
06915 }
06916 ast_mutex_unlock(&iaxsl[x]);
06917 }
06918 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06919 return CLI_SUCCESS;
06920 #undef FORMAT
06921 #undef FORMAT2
06922 #undef FORMATB
06923 }
06924
06925 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
06926 {
06927 int x;
06928 int numchans = 0;
06929 char first_message[10] = { 0, };
06930 char last_message[10] = { 0, };
06931 #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"
06932 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
06933 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06934 ast_mutex_lock(&iaxsl[x]);
06935 if (iaxs[x]) {
06936 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06937 jb_info jbinfo;
06938 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06939 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06940
06941 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06942 jb_getinfo(iaxs[x]->jb, &jbinfo);
06943 localjitter = jbinfo.jitter;
06944 localdelay = jbinfo.current - jbinfo.min;
06945 locallost = jbinfo.frames_lost;
06946 locallosspct = jbinfo.losspct/1000;
06947 localdropped = jbinfo.frames_dropped;
06948 localooo = jbinfo.frames_ooo;
06949 } else {
06950 localjitter = -1;
06951 localdelay = 0;
06952 locallost = -1;
06953 locallosspct = -1;
06954 localdropped = 0;
06955 localooo = -1;
06956 }
06957 if (s)
06958 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06959 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06960 iaxs[x]->pingtime,
06961 localjitter,
06962 localdelay,
06963 locallost,
06964 locallosspct,
06965 localdropped,
06966 localooo,
06967 iaxs[x]->frames_received/1000,
06968 iaxs[x]->remote_rr.jitter,
06969 iaxs[x]->remote_rr.delay,
06970 iaxs[x]->remote_rr.losscnt,
06971 iaxs[x]->remote_rr.losspct,
06972 iaxs[x]->remote_rr.dropped,
06973 iaxs[x]->remote_rr.ooo,
06974 iaxs[x]->remote_rr.packets/1000,
06975 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06976 first_message,
06977 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06978 last_message);
06979 else
06980 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
06981 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06982 iaxs[x]->pingtime,
06983 localjitter,
06984 localdelay,
06985 locallost,
06986 locallosspct,
06987 localdropped,
06988 localooo,
06989 iaxs[x]->frames_received/1000,
06990 iaxs[x]->remote_rr.jitter,
06991 iaxs[x]->remote_rr.delay,
06992 iaxs[x]->remote_rr.losscnt,
06993 iaxs[x]->remote_rr.losspct,
06994 iaxs[x]->remote_rr.dropped,
06995 iaxs[x]->remote_rr.ooo,
06996 iaxs[x]->remote_rr.packets/1000,
06997 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06998 first_message,
06999 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07000 last_message);
07001 numchans++;
07002 }
07003 ast_mutex_unlock(&iaxsl[x]);
07004 }
07005
07006 return numchans;
07007 }
07008
07009 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07010 {
07011 int numchans = 0;
07012
07013 switch (cmd) {
07014 case CLI_INIT:
07015 e->command = "iax2 show netstats";
07016 e->usage =
07017 "Usage: iax2 show netstats\n"
07018 " Lists network status for all currently active IAX channels.\n";
07019 return NULL;
07020 case CLI_GENERATE:
07021 return NULL;
07022 }
07023 if (a->argc != 3)
07024 return CLI_SHOWUSAGE;
07025 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07026 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07027 numchans = ast_cli_netstats(NULL, a->fd, 1);
07028 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07029 return CLI_SUCCESS;
07030 }
07031
07032 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07033 {
07034 switch (cmd) {
07035 case CLI_INIT:
07036 e->command = "iax2 set debug {on|off|peer}";
07037 e->usage =
07038 "Usage: iax2 set debug {on|off|peer peername}\n"
07039 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07040 return NULL;
07041 case CLI_GENERATE:
07042 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07043 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07044 return NULL;
07045 }
07046
07047 if (a->argc < e->args || a->argc > e->args + 1)
07048 return CLI_SHOWUSAGE;
07049
07050 if (!strcasecmp(a->argv[3], "peer")) {
07051 struct iax2_peer *peer;
07052
07053 if (a->argc != e->args + 1)
07054 return CLI_SHOWUSAGE;
07055
07056 peer = find_peer(a->argv[4], 1);
07057
07058 if (!peer) {
07059 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07060 return CLI_FAILURE;
07061 }
07062
07063 debugaddr.sin_addr = peer->addr.sin_addr;
07064 debugaddr.sin_port = peer->addr.sin_port;
07065
07066 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07067 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07068
07069 ao2_ref(peer, -1);
07070 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07071 iaxdebug = 1;
07072 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07073 } else {
07074 iaxdebug = 0;
07075 memset(&debugaddr, 0, sizeof(debugaddr));
07076 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07077 }
07078 return CLI_SUCCESS;
07079 }
07080
07081 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07082 {
07083 switch (cmd) {
07084 case CLI_INIT:
07085 e->command = "iax2 set debug trunk {on|off}";
07086 e->usage =
07087 "Usage: iax2 set debug trunk {on|off}\n"
07088 " Enables/Disables debugging of IAX trunking\n";
07089 return NULL;
07090 case CLI_GENERATE:
07091 return NULL;
07092 }
07093
07094 if (a->argc != e->args)
07095 return CLI_SHOWUSAGE;
07096
07097 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07098 iaxtrunkdebug = 1;
07099 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07100 } else {
07101 iaxtrunkdebug = 0;
07102 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07103 }
07104 return CLI_SUCCESS;
07105 }
07106
07107 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07108 {
07109 switch (cmd) {
07110 case CLI_INIT:
07111 e->command = "iax2 set debug jb {on|off}";
07112 e->usage =
07113 "Usage: iax2 set debug jb {on|off}\n"
07114 " Enables/Disables jitterbuffer debugging information\n";
07115 return NULL;
07116 case CLI_GENERATE:
07117 return NULL;
07118 }
07119
07120 if (a->argc != e->args)
07121 return CLI_SHOWUSAGE;
07122
07123 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07124 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07125 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07126 } else {
07127 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07128 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07129 }
07130 return CLI_SUCCESS;
07131 }
07132
07133 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07134 {
07135 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07136 int res = -1;
07137 ast_mutex_lock(&iaxsl[callno]);
07138 if (iaxs[callno]) {
07139
07140 if (!iaxs[callno]->error) {
07141 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
07142 res = 0;
07143
07144 else if (f->frametype == AST_FRAME_NULL)
07145 res = 0;
07146 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
07147 res = 0;
07148 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07149 res = 0;
07150 else
07151
07152 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07153 } else {
07154 ast_debug(1, "Write error: %s\n", strerror(errno));
07155 }
07156 }
07157
07158 ast_mutex_unlock(&iaxsl[callno]);
07159 return res;
07160 }
07161
07162 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07163 int now, int transfer, int final)
07164 {
07165 struct ast_frame f = { 0, };
07166 int res = 0;
07167
07168 f.frametype = type;
07169 f.subclass = command;
07170 f.datalen = datalen;
07171 f.src = __FUNCTION__;
07172 f.data.ptr = (void *) data;
07173
07174 if ((res = queue_signalling(i, &f)) <= 0) {
07175 return res;
07176 }
07177
07178 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07179 }
07180
07181 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07182 {
07183 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07184 }
07185
07186 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07187 {
07188 int res;
07189 ast_mutex_lock(&iaxsl[callno]);
07190 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07191 ast_mutex_unlock(&iaxsl[callno]);
07192 return res;
07193 }
07194
07195
07196
07197
07198
07199
07200 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)
07201 {
07202 int call_num = i->callno;
07203
07204 iax2_predestroy(i->callno);
07205 if (!iaxs[call_num])
07206 return -1;
07207 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07208 }
07209
07210 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)
07211 {
07212 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07213 }
07214
07215 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07216 {
07217 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07218 }
07219
07220 static int apply_context(struct iax2_context *con, const char *context)
07221 {
07222 while(con) {
07223 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07224 return -1;
07225 con = con->next;
07226 }
07227 return 0;
07228 }
07229
07230
07231 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07232 {
07233
07234 int res = -1;
07235 int version = 2;
07236 struct iax2_user *user = NULL, *best = NULL;
07237 int bestscore = 0;
07238 int gotcapability = 0;
07239 struct ast_variable *v = NULL, *tmpvar = NULL;
07240 struct ao2_iterator i;
07241
07242 if (!iaxs[callno])
07243 return res;
07244 if (ies->called_number)
07245 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07246 if (ies->calling_number) {
07247 if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) {
07248 ast_shrink_phone_number(ies->calling_number);
07249 }
07250 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07251 }
07252 if (ies->calling_name)
07253 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07254 if (ies->calling_ani)
07255 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07256 if (ies->dnid)
07257 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07258 if (ies->rdnis)
07259 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07260 if (ies->called_context)
07261 ast_string_field_set(iaxs[callno], context, ies->called_context);
07262 if (ies->language)
07263 ast_string_field_set(iaxs[callno], language, ies->language);
07264 if (ies->username)
07265 ast_string_field_set(iaxs[callno], username, ies->username);
07266 if (ies->calling_ton > -1)
07267 iaxs[callno]->calling_ton = ies->calling_ton;
07268 if (ies->calling_tns > -1)
07269 iaxs[callno]->calling_tns = ies->calling_tns;
07270 if (ies->calling_pres > -1)
07271 iaxs[callno]->calling_pres = ies->calling_pres;
07272 if (ies->format)
07273 iaxs[callno]->peerformat = ies->format;
07274 if (ies->adsicpe)
07275 iaxs[callno]->peeradsicpe = ies->adsicpe;
07276 if (ies->capability) {
07277 gotcapability = 1;
07278 iaxs[callno]->peercapability = ies->capability;
07279 }
07280 if (ies->version)
07281 version = ies->version;
07282
07283
07284 if(ies->codec_prefs) {
07285 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07286 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07287 }
07288
07289 if (!gotcapability)
07290 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07291 if (version > IAX_PROTO_VERSION) {
07292 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07293 ast_inet_ntoa(sin->sin_addr), version);
07294 return res;
07295 }
07296
07297 i = ao2_iterator_init(users, 0);
07298 while ((user = ao2_iterator_next(&i))) {
07299 if ((ast_strlen_zero(iaxs[callno]->username) ||
07300 !strcmp(iaxs[callno]->username, user->name))
07301 && ast_apply_ha(user->ha, sin)
07302 && (ast_strlen_zero(iaxs[callno]->context) ||
07303 apply_context(user->contexts, iaxs[callno]->context))) {
07304 if (!ast_strlen_zero(iaxs[callno]->username)) {
07305
07306 if (best)
07307 user_unref(best);
07308 best = user;
07309 break;
07310 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07311
07312 if (user->ha) {
07313
07314 if (bestscore < 4) {
07315 bestscore = 4;
07316 if (best)
07317 user_unref(best);
07318 best = user;
07319 continue;
07320 }
07321 } else {
07322
07323 if (bestscore < 3) {
07324 bestscore = 3;
07325 if (best)
07326 user_unref(best);
07327 best = user;
07328 continue;
07329 }
07330 }
07331 } else {
07332 if (user->ha) {
07333
07334 if (bestscore < 2) {
07335 bestscore = 2;
07336 if (best)
07337 user_unref(best);
07338 best = user;
07339 continue;
07340 }
07341 } else {
07342
07343 if (bestscore < 1) {
07344 bestscore = 1;
07345 if (best)
07346 user_unref(best);
07347 best = user;
07348 continue;
07349 }
07350 }
07351 }
07352 }
07353 user_unref(user);
07354 }
07355 ao2_iterator_destroy(&i);
07356 user = best;
07357 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07358 user = realtime_user(iaxs[callno]->username, sin);
07359 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07360 !apply_context(user->contexts, iaxs[callno]->context)) {
07361 user = user_unref(user);
07362 }
07363 }
07364 if (user) {
07365
07366
07367 for (v = user->vars ; v ; v = v->next) {
07368 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07369 tmpvar->next = iaxs[callno]->vars;
07370 iaxs[callno]->vars = tmpvar;
07371 }
07372 }
07373
07374 if (user->maxauthreq > 0)
07375 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
07376 iaxs[callno]->prefs = user->prefs;
07377 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07378 iaxs[callno]->encmethods = user->encmethods;
07379
07380 if (ast_strlen_zero(iaxs[callno]->username))
07381 ast_string_field_set(iaxs[callno], username, user->name);
07382
07383 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
07384 iaxs[callno]->capability = user->capability;
07385
07386 if (ast_strlen_zero(iaxs[callno]->context)) {
07387 if (user->contexts)
07388 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07389 else
07390 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07391 }
07392
07393 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07394
07395 iaxs[callno]->authmethods = user->authmethods;
07396 iaxs[callno]->adsi = user->adsi;
07397
07398 if (ast_test_flag(user, IAX_HASCALLERID)) {
07399 iaxs[callno]->calling_tns = 0;
07400 iaxs[callno]->calling_ton = 0;
07401 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07402 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07403 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07404 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07405 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07406 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07407 }
07408 if (!ast_strlen_zero(user->accountcode))
07409 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07410 if (!ast_strlen_zero(user->mohinterpret))
07411 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07412 if (!ast_strlen_zero(user->mohsuggest))
07413 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07414 if (!ast_strlen_zero(user->parkinglot))
07415 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07416 if (user->amaflags)
07417 iaxs[callno]->amaflags = user->amaflags;
07418 if (!ast_strlen_zero(user->language))
07419 ast_string_field_set(iaxs[callno], language, user->language);
07420 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07421
07422 if (!ast_strlen_zero(user->dbsecret)) {
07423 char *family, *key=NULL;
07424 char buf[80];
07425 family = ast_strdupa(user->dbsecret);
07426 key = strchr(family, '/');
07427 if (key) {
07428 *key = '\0';
07429 key++;
07430 }
07431 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07432 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07433 else
07434 ast_string_field_set(iaxs[callno], secret, buf);
07435 } else
07436 ast_string_field_set(iaxs[callno], secret, user->secret);
07437 res = 0;
07438 user = user_unref(user);
07439 } else {
07440
07441
07442
07443
07444 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07445 ast_string_field_set(iaxs[callno], secret, "badsecret");
07446 iaxs[callno]->authrej = 1;
07447 if (!ast_strlen_zero(iaxs[callno]->username)) {
07448
07449 res = 0;
07450 }
07451 }
07452 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07453 return res;
07454 }
07455
07456 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07457 {
07458 struct ast_iax2_full_hdr fh;
07459 fh.scallno = htons(src | IAX_FLAG_FULL);
07460 fh.dcallno = htons(dst);
07461 fh.ts = 0;
07462 fh.oseqno = 0;
07463 fh.iseqno = 0;
07464 fh.type = AST_FRAME_IAX;
07465 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07466 iax_outputframe(NULL, &fh, 0, sin, 0);
07467 #if 0
07468 if (option_debug)
07469 #endif
07470 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07471 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07472 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07473 }
07474
07475 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07476 {
07477
07478 p->encmethods &= enc;
07479 if (p->encmethods) {
07480 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07481 p->keyrotateid = -2;
07482 }
07483 if (p->encmethods & IAX_ENCRYPT_AES128)
07484 p->encmethods = IAX_ENCRYPT_AES128;
07485 else
07486 p->encmethods = 0;
07487 }
07488 }
07489
07490
07491
07492
07493
07494
07495
07496 static int authenticate_request(int call_num)
07497 {
07498 struct iax_ie_data ied;
07499 int res = -1, authreq_restrict = 0;
07500 char challenge[10];
07501 struct chan_iax2_pvt *p = iaxs[call_num];
07502
07503 memset(&ied, 0, sizeof(ied));
07504
07505
07506 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07507 struct iax2_user *user, tmp_user = {
07508 .name = p->username,
07509 };
07510
07511 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07512 if (user) {
07513 if (user->curauthreq == user->maxauthreq)
07514 authreq_restrict = 1;
07515 else
07516 user->curauthreq++;
07517 user = user_unref(user);
07518 }
07519 }
07520
07521
07522 if (authreq_restrict) {
07523 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07524 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07525 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07526 return 0;
07527 }
07528
07529 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07530 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07531 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07532 ast_string_field_set(p, challenge, challenge);
07533
07534 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07535 }
07536 if (p->encmethods)
07537 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07538
07539 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07540
07541 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07542
07543 if (p->encmethods)
07544 ast_set_flag(p, IAX_ENCRYPTED);
07545
07546 return res;
07547 }
07548
07549 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07550 {
07551 char requeststr[256];
07552 char md5secret[256] = "";
07553 char secret[256] = "";
07554 char rsasecret[256] = "";
07555 int res = -1;
07556 int x;
07557 struct iax2_user *user, tmp_user = {
07558 .name = p->username,
07559 };
07560
07561 if (p->authrej) {
07562 return res;
07563 }
07564 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07565 if (user) {
07566 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
07567 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07568 ast_clear_flag(p, IAX_MAXAUTHREQ);
07569 }
07570 ast_string_field_set(p, host, user->name);
07571 user = user_unref(user);
07572 }
07573 if (ast_test_flag(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07574 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07575 return res;
07576 }
07577 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07578 return res;
07579 if (ies->password)
07580 ast_copy_string(secret, ies->password, sizeof(secret));
07581 if (ies->md5_result)
07582 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07583 if (ies->rsa_result)
07584 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07585 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07586 struct ast_key *key;
07587 char *keyn;
07588 char tmpkey[256];
07589 char *stringp=NULL;
07590 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07591 stringp=tmpkey;
07592 keyn = strsep(&stringp, ":");
07593 while(keyn) {
07594 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07595 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07596 res = 0;
07597 break;
07598 } else if (!key)
07599 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07600 keyn = strsep(&stringp, ":");
07601 }
07602 } else if (p->authmethods & IAX_AUTH_MD5) {
07603 struct MD5Context md5;
07604 unsigned char digest[16];
07605 char *tmppw, *stringp;
07606
07607 tmppw = ast_strdupa(p->secret);
07608 stringp = tmppw;
07609 while((tmppw = strsep(&stringp, ";"))) {
07610 MD5Init(&md5);
07611 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07612 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07613 MD5Final(digest, &md5);
07614
07615 for (x=0;x<16;x++)
07616 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07617 if (!strcasecmp(requeststr, md5secret)) {
07618 res = 0;
07619 break;
07620 }
07621 }
07622 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07623 if (!strcmp(secret, p->secret))
07624 res = 0;
07625 }
07626 return res;
07627 }
07628
07629
07630 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07631 {
07632 char requeststr[256] = "";
07633 char peer[256] = "";
07634 char md5secret[256] = "";
07635 char rsasecret[256] = "";
07636 char secret[256] = "";
07637 struct iax2_peer *p = NULL;
07638 struct ast_key *key;
07639 char *keyn;
07640 int x;
07641 int expire = 0;
07642 int res = -1;
07643
07644 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07645
07646 if (ies->username)
07647 ast_copy_string(peer, ies->username, sizeof(peer));
07648 if (ies->password)
07649 ast_copy_string(secret, ies->password, sizeof(secret));
07650 if (ies->md5_result)
07651 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07652 if (ies->rsa_result)
07653 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07654 if (ies->refresh)
07655 expire = ies->refresh;
07656
07657 if (ast_strlen_zero(peer)) {
07658 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07659 return -1;
07660 }
07661
07662
07663 ast_mutex_unlock(&iaxsl[callno]);
07664 p = find_peer(peer, 1);
07665 ast_mutex_lock(&iaxsl[callno]);
07666 if (!p || !iaxs[callno]) {
07667 if (iaxs[callno]) {
07668 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07669
07670 ast_string_field_set(iaxs[callno], secret, "badsecret");
07671
07672
07673
07674
07675
07676
07677
07678
07679
07680 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07681 !(!ast_strlen_zero(secret) && plaintext)) {
07682
07683 res = 0;
07684 }
07685 }
07686 if (authdebug && !p)
07687 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07688 goto return_unref;
07689 }
07690
07691 if (!ast_test_flag(p, IAX_DYNAMIC)) {
07692 if (authdebug)
07693 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07694 goto return_unref;
07695 }
07696
07697 if (!ast_apply_ha(p->ha, sin)) {
07698 if (authdebug)
07699 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07700 goto return_unref;
07701 }
07702 ast_string_field_set(iaxs[callno], secret, p->secret);
07703 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07704
07705 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07706 if (!ast_strlen_zero(p->inkeys)) {
07707 char tmpkeys[256];
07708 char *stringp=NULL;
07709 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07710 stringp=tmpkeys;
07711 keyn = strsep(&stringp, ":");
07712 while(keyn) {
07713 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07714 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07715 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07716 break;
07717 } else if (!key)
07718 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
07719 keyn = strsep(&stringp, ":");
07720 }
07721 if (!keyn) {
07722 if (authdebug)
07723 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
07724 goto return_unref;
07725 }
07726 } else {
07727 if (authdebug)
07728 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
07729 goto return_unref;
07730 }
07731 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07732 struct MD5Context md5;
07733 unsigned char digest[16];
07734 char *tmppw, *stringp;
07735
07736 tmppw = ast_strdupa(p->secret);
07737 stringp = tmppw;
07738 while((tmppw = strsep(&stringp, ";"))) {
07739 MD5Init(&md5);
07740 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
07741 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07742 MD5Final(digest, &md5);
07743 for (x=0;x<16;x++)
07744 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07745 if (!strcasecmp(requeststr, md5secret))
07746 break;
07747 }
07748 if (tmppw) {
07749 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07750 } else {
07751 if (authdebug)
07752 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
07753 goto return_unref;
07754 }
07755 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
07756
07757 if (strcmp(secret, p->secret)) {
07758 if (authdebug)
07759 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07760 goto return_unref;
07761 } else
07762 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07763 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
07764
07765 goto return_unref;
07766 }
07767 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
07768
07769
07770 res = 0;
07771
07772 return_unref:
07773 if (iaxs[callno]) {
07774 ast_string_field_set(iaxs[callno], peer, peer);
07775
07776
07777 if (expire && (expire < iaxs[callno]->expiry)) {
07778 iaxs[callno]->expiry = expire;
07779 }
07780 }
07781
07782 if (p) {
07783 peer_unref(p);
07784 }
07785 return res;
07786 }
07787
07788 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)
07789 {
07790 int res = -1;
07791 int x;
07792 if (!ast_strlen_zero(keyn)) {
07793 if (!(authmethods & IAX_AUTH_RSA)) {
07794 if (ast_strlen_zero(secret))
07795 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));
07796 } else if (ast_strlen_zero(challenge)) {
07797 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
07798 } else {
07799 char sig[256];
07800 struct ast_key *key;
07801 key = ast_key_get(keyn, AST_KEY_PRIVATE);
07802 if (!key) {
07803 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
07804 } else {
07805 if (ast_sign(key, (char*)challenge, sig)) {
07806 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
07807 res = -1;
07808 } else {
07809 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
07810 res = 0;
07811 }
07812 }
07813 }
07814 }
07815
07816 if (res && !ast_strlen_zero(secret)) {
07817 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
07818 struct MD5Context md5;
07819 unsigned char digest[16];
07820 char digres[128];
07821 MD5Init(&md5);
07822 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
07823 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
07824 MD5Final(digest, &md5);
07825
07826 for (x=0;x<16;x++)
07827 sprintf(digres + (x << 1), "%2.2x", digest[x]);
07828 if (pvt) {
07829 build_encryption_keys(digest, pvt);
07830 }
07831 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
07832 res = 0;
07833 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
07834 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
07835 res = 0;
07836 } else
07837 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
07838 }
07839 return res;
07840 }
07841
07842
07843
07844
07845
07846 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
07847 {
07848 struct iax2_peer *peer = NULL;
07849
07850 int res = -1;
07851 int authmethods = 0;
07852 struct iax_ie_data ied;
07853 uint16_t callno = p->callno;
07854
07855 memset(&ied, 0, sizeof(ied));
07856
07857 if (ies->username)
07858 ast_string_field_set(p, username, ies->username);
07859 if (ies->challenge)
07860 ast_string_field_set(p, challenge, ies->challenge);
07861 if (ies->authmethods)
07862 authmethods = ies->authmethods;
07863 if (authmethods & IAX_AUTH_MD5)
07864 merge_encryption(p, ies->encmethods);
07865 else
07866 p->encmethods = 0;
07867
07868
07869 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
07870
07871 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
07872 } else {
07873 struct ao2_iterator i = ao2_iterator_init(peers, 0);
07874 while ((peer = ao2_iterator_next(&i))) {
07875 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
07876
07877 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
07878
07879 && (!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)))
07880
07881 ) {
07882 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
07883 if (!res) {
07884 peer_unref(peer);
07885 break;
07886 }
07887 }
07888 peer_unref(peer);
07889 }
07890 ao2_iterator_destroy(&i);
07891 if (!peer) {
07892
07893
07894 const char *peer_name = ast_strdupa(p->peer);
07895 ast_mutex_unlock(&iaxsl[callno]);
07896 if ((peer = realtime_peer(peer_name, NULL))) {
07897 ast_mutex_lock(&iaxsl[callno]);
07898 if (!(p = iaxs[callno])) {
07899 peer_unref(peer);
07900 return -1;
07901 }
07902 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
07903 peer_unref(peer);
07904 }
07905 if (!peer) {
07906 ast_mutex_lock(&iaxsl[callno]);
07907 if (!(p = iaxs[callno]))
07908 return -1;
07909 }
07910 }
07911 }
07912
07913 if (ies->encmethods) {
07914 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
07915 } else if (ast_test_flag(iaxs[callno], IAX_FORCE_ENCRYPT)) {
07916 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
07917 return -1;
07918 }
07919 if (!res) {
07920 struct ast_datastore *variablestore;
07921 struct ast_variable *var, *prev = NULL;
07922 AST_LIST_HEAD(, ast_var_t) *varlist;
07923 varlist = ast_calloc(1, sizeof(*varlist));
07924 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
07925 if (variablestore && varlist && p->owner) {
07926 variablestore->data = varlist;
07927 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
07928 AST_LIST_HEAD_INIT(varlist);
07929 for (var = ies->vars; var; var = var->next) {
07930 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
07931 if (prev)
07932 ast_free(prev);
07933 prev = var;
07934 if (!newvar) {
07935
07936 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07937 } else {
07938 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
07939 }
07940 }
07941 if (prev)
07942 ast_free(prev);
07943 ies->vars = NULL;
07944 ast_channel_datastore_add(p->owner, variablestore);
07945 } else {
07946 if (p->owner)
07947 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
07948 if (variablestore)
07949 ast_datastore_free(variablestore);
07950 if (varlist)
07951 ast_free(varlist);
07952 }
07953 }
07954
07955 if (!res)
07956 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
07957 return res;
07958 }
07959
07960 static int iax2_do_register(struct iax2_registry *reg);
07961
07962 static void __iax2_do_register_s(const void *data)
07963 {
07964 struct iax2_registry *reg = (struct iax2_registry *)data;
07965 reg->expire = -1;
07966 iax2_do_register(reg);
07967 }
07968
07969 static int iax2_do_register_s(const void *data)
07970 {
07971 #ifdef SCHED_MULTITHREADED
07972 if (schedule_action(__iax2_do_register_s, data))
07973 #endif
07974 __iax2_do_register_s(data);
07975 return 0;
07976 }
07977
07978 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
07979 {
07980 int newcall = 0;
07981 char newip[256];
07982 struct iax_ie_data ied;
07983 struct sockaddr_in new;
07984
07985
07986 memset(&ied, 0, sizeof(ied));
07987 if (ies->apparent_addr)
07988 memmove(&new, ies->apparent_addr, sizeof(new));
07989 if (ies->callno)
07990 newcall = ies->callno;
07991 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
07992 ast_log(LOG_WARNING, "Invalid transfer request\n");
07993 return -1;
07994 }
07995 pvt->transfercallno = newcall;
07996 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
07997 inet_aton(newip, &pvt->transfer.sin_addr);
07998 pvt->transfer.sin_family = AF_INET;
07999 pvt->transferid = ies->transferid;
08000
08001
08002 if (pvt->transferring == TRANSFER_NONE) {
08003 store_by_transfercallno(pvt);
08004 }
08005 pvt->transferring = TRANSFER_BEGIN;
08006
08007 if (ies->transferid)
08008 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08009 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08010 return 0;
08011 }
08012
08013 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08014 {
08015 char exten[256] = "";
08016 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08017 struct iax2_dpcache *dp = NULL;
08018
08019 if (ies->called_number)
08020 ast_copy_string(exten, ies->called_number, sizeof(exten));
08021
08022 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08023 status = CACHE_FLAG_EXISTS;
08024 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08025 status = CACHE_FLAG_CANEXIST;
08026 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08027 status = CACHE_FLAG_NONEXISTENT;
08028
08029 if (ies->refresh)
08030 expiry = ies->refresh;
08031 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08032 matchmore = CACHE_FLAG_MATCHMORE;
08033
08034 AST_LIST_LOCK(&dpcache);
08035 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08036 if (strcmp(dp->exten, exten))
08037 continue;
08038 AST_LIST_REMOVE_CURRENT(peer_list);
08039 dp->callno = 0;
08040 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08041 if (dp->flags & CACHE_FLAG_PENDING) {
08042 dp->flags &= ~CACHE_FLAG_PENDING;
08043 dp->flags |= status;
08044 dp->flags |= matchmore;
08045 }
08046
08047 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08048 if (dp->waiters[x] > -1) {
08049 if (write(dp->waiters[x], "asdf", 4) < 0) {
08050 }
08051 }
08052 }
08053 }
08054 AST_LIST_TRAVERSE_SAFE_END;
08055 AST_LIST_UNLOCK(&dpcache);
08056
08057 return 0;
08058 }
08059
08060 static int complete_transfer(int callno, struct iax_ies *ies)
08061 {
08062 int peercallno = 0;
08063 struct chan_iax2_pvt *pvt = iaxs[callno];
08064 struct iax_frame *cur;
08065 jb_frame frame;
08066
08067 if (ies->callno)
08068 peercallno = ies->callno;
08069
08070 if (peercallno < 1) {
08071 ast_log(LOG_WARNING, "Invalid transfer request\n");
08072 return -1;
08073 }
08074 remove_by_transfercallno(pvt);
08075
08076
08077
08078 peercnt_remove_by_addr(&pvt->addr);
08079 peercnt_add(&pvt->transfer);
08080
08081 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08082 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08083
08084 pvt->oseqno = 0;
08085 pvt->rseqno = 0;
08086 pvt->iseqno = 0;
08087 pvt->aseqno = 0;
08088
08089 if (pvt->peercallno) {
08090 remove_by_peercallno(pvt);
08091 }
08092 pvt->peercallno = peercallno;
08093
08094 store_by_peercallno(pvt);
08095 pvt->transferring = TRANSFER_NONE;
08096 pvt->svoiceformat = -1;
08097 pvt->voiceformat = 0;
08098 pvt->svideoformat = -1;
08099 pvt->videoformat = 0;
08100 pvt->transfercallno = 0;
08101 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08102 memset(&pvt->offset, 0, sizeof(pvt->offset));
08103
08104 while(jb_getall(pvt->jb,&frame) == JB_OK)
08105 iax2_frame_free(frame.data);
08106 jb_reset(pvt->jb);
08107 pvt->lag = 0;
08108 pvt->last = 0;
08109 pvt->lastsent = 0;
08110 pvt->nextpred = 0;
08111 pvt->pingtime = DEFAULT_RETRY_TIME;
08112 AST_LIST_LOCK(&frame_queue);
08113 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08114
08115
08116
08117 if (callno == cur->callno)
08118 cur->retries = -1;
08119 }
08120 AST_LIST_UNLOCK(&frame_queue);
08121 return 0;
08122 }
08123
08124
08125 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08126 {
08127 struct iax2_registry *reg;
08128
08129 char peer[256] = "";
08130 char msgstatus[60];
08131 int refresh = 60;
08132 char ourip[256] = "<Unspecified>";
08133 struct sockaddr_in oldus;
08134 struct sockaddr_in us;
08135 int oldmsgs;
08136
08137 memset(&us, 0, sizeof(us));
08138 if (ies->apparent_addr)
08139 memmove(&us, ies->apparent_addr, sizeof(us));
08140 if (ies->username)
08141 ast_copy_string(peer, ies->username, sizeof(peer));
08142 if (ies->refresh)
08143 refresh = ies->refresh;
08144 if (ies->calling_number) {
08145
08146 }
08147 reg = iaxs[callno]->reg;
08148 if (!reg) {
08149 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08150 return -1;
08151 }
08152 memcpy(&oldus, ®->us, sizeof(oldus));
08153 oldmsgs = reg->messages;
08154 if (inaddrcmp(®->addr, sin)) {
08155 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08156 return -1;
08157 }
08158 memcpy(®->us, &us, sizeof(reg->us));
08159 if (ies->msgcount >= 0)
08160 reg->messages = ies->msgcount & 0xffff;
08161
08162
08163
08164 reg->refresh = refresh;
08165 reg->expire = iax2_sched_replace(reg->expire, sched,
08166 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08167 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08168 if (reg->messages > 255)
08169 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08170 else if (reg->messages > 1)
08171 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
08172 else if (reg->messages > 0)
08173 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
08174 else
08175 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
08176 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08177 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08178 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08179 }
08180 reg->regstate = REG_STATE_REGISTERED;
08181 return 0;
08182 }
08183
08184 static int iax2_append_register(const char *hostname, const char *username,
08185 const char *secret, const char *porta)
08186 {
08187 struct iax2_registry *reg;
08188
08189 if (!(reg = ast_calloc(1, sizeof(*reg))))
08190 return -1;
08191
08192 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08193 ast_free(reg);
08194 return -1;
08195 }
08196
08197 ast_copy_string(reg->username, username, sizeof(reg->username));
08198
08199 if (secret)
08200 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08201
08202 reg->expire = -1;
08203 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08204 reg->addr.sin_family = AF_INET;
08205 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
08206
08207 AST_LIST_LOCK(®istrations);
08208 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08209 AST_LIST_UNLOCK(®istrations);
08210
08211 return 0;
08212 }
08213
08214 static int iax2_register(const char *value, int lineno)
08215 {
08216 char copy[256];
08217 char *username, *hostname, *secret;
08218 char *porta;
08219 char *stringp=NULL;
08220
08221 if (!value)
08222 return -1;
08223
08224 ast_copy_string(copy, value, sizeof(copy));
08225 stringp = copy;
08226 username = strsep(&stringp, "@");
08227 hostname = strsep(&stringp, "@");
08228
08229 if (!hostname) {
08230 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08231 return -1;
08232 }
08233
08234 stringp = username;
08235 username = strsep(&stringp, ":");
08236 secret = strsep(&stringp, ":");
08237 stringp = hostname;
08238 hostname = strsep(&stringp, ":");
08239 porta = strsep(&stringp, ":");
08240
08241 if (porta && !atoi(porta)) {
08242 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08243 return -1;
08244 }
08245
08246 return iax2_append_register(hostname, username, secret, porta);
08247 }
08248
08249
08250 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08251 {
08252 char multi[256];
08253 char *stringp, *ext;
08254 if (!ast_strlen_zero(regcontext)) {
08255 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08256 stringp = multi;
08257 while((ext = strsep(&stringp, "&"))) {
08258 if (onoff) {
08259 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08260 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08261 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08262 } else
08263 ast_context_remove_extension(regcontext, ext, 1, NULL);
08264 }
08265 }
08266 }
08267 static void prune_peers(void);
08268
08269 static void unlink_peer(struct iax2_peer *peer)
08270 {
08271 if (peer->expire > -1) {
08272 if (!ast_sched_thread_del(sched, peer->expire)) {
08273 peer->expire = -1;
08274 peer_unref(peer);
08275 }
08276 }
08277
08278 if (peer->pokeexpire > -1) {
08279 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08280 peer->pokeexpire = -1;
08281 peer_unref(peer);
08282 }
08283 }
08284
08285 ao2_unlink(peers, peer);
08286 }
08287
08288 static void __expire_registry(const void *data)
08289 {
08290 struct iax2_peer *peer = (struct iax2_peer *) data;
08291
08292 if (!peer)
08293 return;
08294
08295 peer->expire = -1;
08296
08297 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08298 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08299 realtime_update_peer(peer->name, &peer->addr, 0);
08300 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08301
08302 peercnt_modify(0, 0, &peer->addr);
08303
08304 memset(&peer->addr, 0, sizeof(peer->addr));
08305
08306 peer->expiry = min_reg_expire;
08307 if (!ast_test_flag(peer, IAX_TEMPONLY))
08308 ast_db_del("IAX/Registry", peer->name);
08309 register_peer_exten(peer, 0);
08310 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08311 if (iax2_regfunk)
08312 iax2_regfunk(peer->name, 0);
08313
08314 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
08315 unlink_peer(peer);
08316
08317 peer_unref(peer);
08318 }
08319
08320 static int expire_registry(const void *data)
08321 {
08322 #ifdef SCHED_MULTITHREADED
08323 if (schedule_action(__expire_registry, data))
08324 #endif
08325 __expire_registry(data);
08326 return 0;
08327 }
08328
08329 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08330
08331 static void reg_source_db(struct iax2_peer *p)
08332 {
08333 char data[80];
08334 struct in_addr in;
08335 char *c, *d;
08336 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
08337 c = strchr(data, ':');
08338 if (c) {
08339 *c = '\0';
08340 c++;
08341 if (inet_aton(data, &in)) {
08342 d = strchr(c, ':');
08343 if (d) {
08344 *d = '\0';
08345 d++;
08346 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
08347 ast_inet_ntoa(in), atoi(c), atoi(d));
08348 iax2_poke_peer(p, 0);
08349 p->expiry = atoi(d);
08350 memset(&p->addr, 0, sizeof(p->addr));
08351 p->addr.sin_family = AF_INET;
08352 p->addr.sin_addr = in;
08353 p->addr.sin_port = htons(atoi(c));
08354 if (p->expire > -1) {
08355 if (!ast_sched_thread_del(sched, p->expire)) {
08356 p->expire = -1;
08357 peer_unref(p);
08358 }
08359 }
08360 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08361 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08362 if (p->expire == -1)
08363 peer_unref(p);
08364 if (iax2_regfunk)
08365 iax2_regfunk(p->name, 1);
08366 register_peer_exten(p, 1);
08367 }
08368
08369 }
08370 }
08371 }
08372 }
08373
08374
08375
08376
08377
08378
08379
08380 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08381 {
08382
08383 struct iax_ie_data ied;
08384 struct iax2_peer *p;
08385 int msgcount;
08386 char data[80];
08387 int version;
08388 const char *peer_name;
08389 int res = -1;
08390
08391 memset(&ied, 0, sizeof(ied));
08392
08393 peer_name = ast_strdupa(iaxs[callno]->peer);
08394
08395
08396 ast_mutex_unlock(&iaxsl[callno]);
08397 if (!(p = find_peer(peer_name, 1))) {
08398 ast_mutex_lock(&iaxsl[callno]);
08399 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08400 return -1;
08401 }
08402 ast_mutex_lock(&iaxsl[callno]);
08403 if (!iaxs[callno])
08404 goto return_unref;
08405
08406 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08407 if (sin->sin_addr.s_addr) {
08408 time_t nowtime;
08409 time(&nowtime);
08410 realtime_update_peer(peer_name, sin, nowtime);
08411 } else {
08412 realtime_update_peer(peer_name, sin, 0);
08413 }
08414 }
08415 if (inaddrcmp(&p->addr, sin)) {
08416 if (iax2_regfunk)
08417 iax2_regfunk(p->name, 1);
08418
08419
08420 peercnt_modify(0, 0, &p->addr);
08421
08422
08423 memcpy(&p->addr, sin, sizeof(p->addr));
08424
08425 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08426 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08427 ast_db_put("IAX/Registry", p->name, data);
08428 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08429 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08430 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08431 register_peer_exten(p, 1);
08432 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08433 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
08434 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08435 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08436 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08437 register_peer_exten(p, 0);
08438 ast_db_del("IAX/Registry", p->name);
08439 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08440 }
08441
08442
08443 iax2_poke_peer(p, callno);
08444 }
08445
08446
08447 if (p->maxcallno) {
08448 peercnt_modify(1, p->maxcallno, &p->addr);
08449 }
08450
08451
08452 if (!iaxs[callno]) {
08453 res = -1;
08454 goto return_unref;
08455 }
08456
08457
08458 p->sockfd = fd;
08459
08460 if (p->expire > -1) {
08461 if (!ast_sched_thread_del(sched, p->expire)) {
08462 p->expire = -1;
08463 peer_unref(p);
08464 }
08465 }
08466
08467 if (!refresh)
08468 refresh = min_reg_expire;
08469 if (refresh > max_reg_expire) {
08470 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08471 p->name, max_reg_expire, refresh);
08472 p->expiry = max_reg_expire;
08473 } else if (refresh < min_reg_expire) {
08474 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08475 p->name, min_reg_expire, refresh);
08476 p->expiry = min_reg_expire;
08477 } else {
08478 p->expiry = refresh;
08479 }
08480 if (p->expiry && sin->sin_addr.s_addr) {
08481 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08482 if (p->expire == -1)
08483 peer_unref(p);
08484 }
08485 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08486 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08487 if (sin->sin_addr.s_addr) {
08488 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08489 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
08490 if (!ast_strlen_zero(p->mailbox)) {
08491 struct ast_event *event;
08492 int new, old;
08493 char *mailbox, *context;
08494
08495 context = mailbox = ast_strdupa(p->mailbox);
08496 strsep(&context, "@");
08497 if (ast_strlen_zero(context))
08498 context = "default";
08499
08500 event = ast_event_get_cached(AST_EVENT_MWI,
08501 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08502 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08503 AST_EVENT_IE_END);
08504 if (event) {
08505 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08506 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08507 ast_event_destroy(event);
08508 } else {
08509 ast_app_inboxcount(p->mailbox, &new, &old);
08510 }
08511
08512 if (new > 255) {
08513 new = 255;
08514 }
08515 if (old > 255) {
08516 old = 255;
08517 }
08518 msgcount = (old << 8) | new;
08519
08520 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08521 }
08522 if (ast_test_flag(p, IAX_HASCALLERID)) {
08523 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08524 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08525 }
08526 }
08527 version = iax_check_version(devtype);
08528 if (version)
08529 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08530
08531 res = 0;
08532
08533 return_unref:
08534 peer_unref(p);
08535
08536 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08537 }
08538
08539 static int registry_authrequest(int callno)
08540 {
08541 struct iax_ie_data ied;
08542 struct iax2_peer *p;
08543 char challenge[10];
08544 const char *peer_name;
08545 int sentauthmethod;
08546
08547 peer_name = ast_strdupa(iaxs[callno]->peer);
08548
08549
08550 ast_mutex_unlock(&iaxsl[callno]);
08551 if ((p = find_peer(peer_name, 1))) {
08552 last_authmethod = p->authmethods;
08553 }
08554
08555 ast_mutex_lock(&iaxsl[callno]);
08556 if (!iaxs[callno])
08557 goto return_unref;
08558
08559 memset(&ied, 0, sizeof(ied));
08560
08561
08562
08563
08564
08565
08566 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08567 if (!p) {
08568 iaxs[callno]->authmethods = sentauthmethod;
08569 }
08570 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08571 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08572
08573 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08574 ast_string_field_set(iaxs[callno], challenge, challenge);
08575 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08576 }
08577 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08578
08579 return_unref:
08580 if (p) {
08581 peer_unref(p);
08582 }
08583
08584 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08585 }
08586
08587 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08588 {
08589 struct iax2_registry *reg;
08590
08591 struct iax_ie_data ied;
08592 char peer[256] = "";
08593 char challenge[256] = "";
08594 int res;
08595 int authmethods = 0;
08596 if (ies->authmethods)
08597 authmethods = ies->authmethods;
08598 if (ies->username)
08599 ast_copy_string(peer, ies->username, sizeof(peer));
08600 if (ies->challenge)
08601 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08602 memset(&ied, 0, sizeof(ied));
08603 reg = iaxs[callno]->reg;
08604 if (reg) {
08605 if (inaddrcmp(®->addr, sin)) {
08606 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08607 return -1;
08608 }
08609 if (ast_strlen_zero(reg->secret)) {
08610 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08611 reg->regstate = REG_STATE_NOAUTH;
08612 return -1;
08613 }
08614 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08615 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08616 if (reg->secret[0] == '[') {
08617 char tmpkey[256];
08618 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08619 tmpkey[strlen(tmpkey) - 1] = '\0';
08620 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08621 } else
08622 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08623 if (!res) {
08624 reg->regstate = REG_STATE_AUTHSENT;
08625 add_empty_calltoken_ie(iaxs[callno], &ied);
08626 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08627 } else
08628 return -1;
08629 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08630 } else
08631 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08632 return -1;
08633 }
08634
08635 static void stop_stuff(int callno)
08636 {
08637 iax2_destroy_helper(iaxs[callno]);
08638 }
08639
08640 static void __auth_reject(const void *nothing)
08641 {
08642
08643 int callno = (int)(long)(nothing);
08644 struct iax_ie_data ied;
08645 ast_mutex_lock(&iaxsl[callno]);
08646 if (iaxs[callno]) {
08647 memset(&ied, 0, sizeof(ied));
08648 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08649 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08650 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08651 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08652 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08653 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08654 }
08655 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08656 }
08657 ast_mutex_unlock(&iaxsl[callno]);
08658 }
08659
08660 static int auth_reject(const void *data)
08661 {
08662 int callno = (int)(long)(data);
08663 ast_mutex_lock(&iaxsl[callno]);
08664 if (iaxs[callno])
08665 iaxs[callno]->authid = -1;
08666 ast_mutex_unlock(&iaxsl[callno]);
08667 #ifdef SCHED_MULTITHREADED
08668 if (schedule_action(__auth_reject, data))
08669 #endif
08670 __auth_reject(data);
08671 return 0;
08672 }
08673
08674 static int auth_fail(int callno, int failcode)
08675 {
08676
08677
08678 if (iaxs[callno]) {
08679 iaxs[callno]->authfail = failcode;
08680 if (delayreject) {
08681 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08682 sched, 1000, auth_reject, (void *)(long)callno);
08683 } else
08684 auth_reject((void *)(long)callno);
08685 }
08686 return 0;
08687 }
08688
08689 static void __auto_hangup(const void *nothing)
08690 {
08691
08692 int callno = (int)(long)(nothing);
08693 struct iax_ie_data ied;
08694 ast_mutex_lock(&iaxsl[callno]);
08695 if (iaxs[callno]) {
08696 memset(&ied, 0, sizeof(ied));
08697 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08698 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
08699 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
08700 }
08701 ast_mutex_unlock(&iaxsl[callno]);
08702 }
08703
08704 static int auto_hangup(const void *data)
08705 {
08706 int callno = (int)(long)(data);
08707 ast_mutex_lock(&iaxsl[callno]);
08708 if (iaxs[callno]) {
08709 iaxs[callno]->autoid = -1;
08710 }
08711 ast_mutex_unlock(&iaxsl[callno]);
08712 #ifdef SCHED_MULTITHREADED
08713 if (schedule_action(__auto_hangup, data))
08714 #endif
08715 __auto_hangup(data);
08716 return 0;
08717 }
08718
08719 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
08720 {
08721 struct iax_ie_data ied;
08722
08723 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
08724 sched, 30000, auto_hangup, (void *)(long)callno);
08725 memset(&ied, 0, sizeof(ied));
08726 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
08727 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
08728 dp->flags |= CACHE_FLAG_TRANSMITTED;
08729 }
08730
08731 static int iax2_vnak(int callno)
08732 {
08733 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
08734 }
08735
08736 static void vnak_retransmit(int callno, int last)
08737 {
08738 struct iax_frame *f;
08739
08740 AST_LIST_LOCK(&frame_queue);
08741 AST_LIST_TRAVERSE(&frame_queue, f, list) {
08742
08743 if ((f->callno == callno) && iaxs[f->callno] &&
08744 ((unsigned char ) (f->oseqno - last) < 128) &&
08745 (f->retries >= 0)) {
08746 send_packet(f);
08747 }
08748 }
08749 AST_LIST_UNLOCK(&frame_queue);
08750 }
08751
08752 static void __iax2_poke_peer_s(const void *data)
08753 {
08754 struct iax2_peer *peer = (struct iax2_peer *)data;
08755 iax2_poke_peer(peer, 0);
08756 peer_unref(peer);
08757 }
08758
08759 static int iax2_poke_peer_s(const void *data)
08760 {
08761 struct iax2_peer *peer = (struct iax2_peer *)data;
08762 peer->pokeexpire = -1;
08763 #ifdef SCHED_MULTITHREADED
08764 if (schedule_action(__iax2_poke_peer_s, data))
08765 #endif
08766 __iax2_poke_peer_s(data);
08767 return 0;
08768 }
08769
08770 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
08771 {
08772 int res = 0;
08773 struct iax_frame *fr;
08774 struct ast_iax2_meta_hdr *meta;
08775 struct ast_iax2_meta_trunk_hdr *mth;
08776 int calls = 0;
08777
08778
08779 fr = (struct iax_frame *)tpeer->trunkdata;
08780
08781 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
08782 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
08783 if (tpeer->trunkdatalen) {
08784
08785 meta->zeros = 0;
08786 meta->metacmd = IAX_META_TRUNK;
08787 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
08788 meta->cmddata = IAX_META_TRUNK_MINI;
08789 else
08790 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
08791 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
08792
08793 fr->direction = DIRECTION_OUTGRESS;
08794 fr->retrans = -1;
08795 fr->transfer = 0;
08796
08797 fr->data = fr->afdata;
08798 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
08799 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
08800 calls = tpeer->calls;
08801 #if 0
08802 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));
08803 #endif
08804
08805 tpeer->trunkdatalen = 0;
08806 tpeer->calls = 0;
08807 }
08808 if (res < 0)
08809 return res;
08810 return calls;
08811 }
08812
08813 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
08814 {
08815
08816 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
08817 return 1;
08818 return 0;
08819 }
08820
08821 static int timing_read(int *id, int fd, short events, void *cbdata)
08822 {
08823 int res, processed = 0, totalcalls = 0;
08824 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
08825 struct timeval now = ast_tvnow();
08826
08827 if (iaxtrunkdebug)
08828 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
08829
08830 if (timer) {
08831 ast_timer_ack(timer, 1);
08832 }
08833
08834
08835 AST_LIST_LOCK(&tpeers);
08836 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
08837 processed++;
08838 res = 0;
08839 ast_mutex_lock(&tpeer->lock);
08840
08841
08842 if (!drop && iax2_trunk_expired(tpeer, &now)) {
08843
08844
08845 AST_LIST_REMOVE_CURRENT(list);
08846 drop = tpeer;
08847 } else {
08848 res = send_trunk(tpeer, &now);
08849 trunk_timed++;
08850 if (iaxtrunkdebug)
08851 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);
08852 }
08853 totalcalls += res;
08854 res = 0;
08855 ast_mutex_unlock(&tpeer->lock);
08856 }
08857 AST_LIST_TRAVERSE_SAFE_END;
08858 AST_LIST_UNLOCK(&tpeers);
08859
08860 if (drop) {
08861 ast_mutex_lock(&drop->lock);
08862
08863
08864 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
08865 if (drop->trunkdata) {
08866 ast_free(drop->trunkdata);
08867 drop->trunkdata = NULL;
08868 }
08869 ast_mutex_unlock(&drop->lock);
08870 ast_mutex_destroy(&drop->lock);
08871 ast_free(drop);
08872
08873 }
08874
08875 if (iaxtrunkdebug)
08876 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
08877 iaxtrunkdebug = 0;
08878
08879 return 1;
08880 }
08881
08882 struct dpreq_data {
08883 int callno;
08884 char context[AST_MAX_EXTENSION];
08885 char callednum[AST_MAX_EXTENSION];
08886 char *callerid;
08887 };
08888
08889 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
08890 {
08891 unsigned short dpstatus = 0;
08892 struct iax_ie_data ied1;
08893 int mm;
08894
08895 memset(&ied1, 0, sizeof(ied1));
08896 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
08897
08898 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
08899 dpstatus = IAX_DPSTATUS_EXISTS;
08900 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
08901 dpstatus = IAX_DPSTATUS_CANEXIST;
08902 } else {
08903 dpstatus = IAX_DPSTATUS_NONEXISTENT;
08904 }
08905 if (ast_ignore_pattern(context, callednum))
08906 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
08907 if (mm)
08908 dpstatus |= IAX_DPSTATUS_MATCHMORE;
08909 if (!skiplock)
08910 ast_mutex_lock(&iaxsl[callno]);
08911 if (iaxs[callno]) {
08912 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
08913 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
08914 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
08915 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
08916 }
08917 if (!skiplock)
08918 ast_mutex_unlock(&iaxsl[callno]);
08919 }
08920
08921 static void *dp_lookup_thread(void *data)
08922 {
08923
08924 struct dpreq_data *dpr = data;
08925 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
08926 if (dpr->callerid)
08927 ast_free(dpr->callerid);
08928 ast_free(dpr);
08929 return NULL;
08930 }
08931
08932 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
08933 {
08934 pthread_t newthread;
08935 struct dpreq_data *dpr;
08936
08937 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
08938 return;
08939
08940 dpr->callno = callno;
08941 ast_copy_string(dpr->context, context, sizeof(dpr->context));
08942 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
08943 if (callerid)
08944 dpr->callerid = ast_strdup(callerid);
08945 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
08946 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
08947 }
08948 }
08949
08950 struct iax_dual {
08951 struct ast_channel *chan1;
08952 struct ast_channel *chan2;
08953 };
08954
08955 static void *iax_park_thread(void *stuff)
08956 {
08957 struct ast_channel *chan1, *chan2;
08958 struct iax_dual *d;
08959 struct ast_frame *f;
08960 int ext;
08961 int res;
08962 d = stuff;
08963 chan1 = d->chan1;
08964 chan2 = d->chan2;
08965 ast_free(d);
08966 f = ast_read(chan1);
08967 if (f)
08968 ast_frfree(f);
08969 res = ast_park_call(chan1, chan2, 0, &ext);
08970 ast_hangup(chan2);
08971 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
08972 return NULL;
08973 }
08974
08975 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
08976 {
08977 struct iax_dual *d;
08978 struct ast_channel *chan1m, *chan2m;
08979 pthread_t th;
08980 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
08981 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
08982 if (chan2m && chan1m) {
08983
08984 chan1m->readformat = chan1->readformat;
08985 chan1m->writeformat = chan1->writeformat;
08986 ast_channel_masquerade(chan1m, chan1);
08987
08988 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
08989 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
08990 chan1m->priority = chan1->priority;
08991
08992
08993
08994
08995 chan2m->readformat = chan2->readformat;
08996 chan2m->writeformat = chan2->writeformat;
08997 ast_channel_masquerade(chan2m, chan2);
08998
08999 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09000 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09001 chan2m->priority = chan2->priority;
09002 if (ast_do_masquerade(chan2m)) {
09003 ast_log(LOG_WARNING, "Masquerade failed :(\n");
09004 ast_hangup(chan2m);
09005 return -1;
09006 }
09007 } else {
09008 if (chan1m)
09009 ast_hangup(chan1m);
09010 if (chan2m)
09011 ast_hangup(chan2m);
09012 return -1;
09013 }
09014 if ((d = ast_calloc(1, sizeof(*d)))) {
09015 d->chan1 = chan1m;
09016 d->chan2 = chan2m;
09017 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
09018 return 0;
09019 }
09020 ast_free(d);
09021 }
09022 return -1;
09023 }
09024
09025
09026 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
09027
09028 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09029 {
09030 unsigned int ourver;
09031 char rsi[80];
09032 snprintf(rsi, sizeof(rsi), "si-%s", si);
09033 if (iax_provision_version(&ourver, rsi, 1))
09034 return 0;
09035 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09036 if (ourver != ver)
09037 iax2_provision(sin, sockfd, NULL, rsi, 1);
09038 return 0;
09039 }
09040
09041 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09042 {
09043 jb_info stats;
09044 jb_getinfo(pvt->jb, &stats);
09045
09046 memset(iep, 0, sizeof(*iep));
09047
09048 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09049 if(stats.frames_in == 0) stats.frames_in = 1;
09050 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09051 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09052 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09053 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09054 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09055 }
09056
09057 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09058 {
09059 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09060 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09061 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09062 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09063 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09064 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09065 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09066 }
09067
09068 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09069 {
09070 int i;
09071 unsigned int length, offset = 0;
09072 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09073
09074 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09075 length = ies->ospblocklength[i];
09076 if (length != 0) {
09077 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09078
09079 offset = 0;
09080 break;
09081 } else {
09082 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09083 offset += length;
09084 }
09085 } else {
09086 break;
09087 }
09088 }
09089 *(full_osptoken + offset) = '\0';
09090 if (strlen(full_osptoken) != offset) {
09091
09092 *full_osptoken = '\0';
09093 }
09094
09095 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09096 }
09097
09098 static void log_jitterstats(unsigned short callno)
09099 {
09100 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09101 jb_info jbinfo;
09102
09103 ast_mutex_lock(&iaxsl[callno]);
09104 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09105 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
09106 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09107 localjitter = jbinfo.jitter;
09108 localdelay = jbinfo.current - jbinfo.min;
09109 locallost = jbinfo.frames_lost;
09110 locallosspct = jbinfo.losspct/1000;
09111 localdropped = jbinfo.frames_dropped;
09112 localooo = jbinfo.frames_ooo;
09113 localpackets = jbinfo.frames_in;
09114 }
09115 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",
09116 iaxs[callno]->owner->name,
09117 iaxs[callno]->pingtime,
09118 localjitter,
09119 localdelay,
09120 locallost,
09121 locallosspct,
09122 localdropped,
09123 localooo,
09124 localpackets,
09125 iaxs[callno]->remote_rr.jitter,
09126 iaxs[callno]->remote_rr.delay,
09127 iaxs[callno]->remote_rr.losscnt,
09128 iaxs[callno]->remote_rr.losspct/1000,
09129 iaxs[callno]->remote_rr.dropped,
09130 iaxs[callno]->remote_rr.ooo,
09131 iaxs[callno]->remote_rr.packets);
09132 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",
09133 iaxs[callno]->owner->name,
09134 iaxs[callno]->pingtime,
09135 localjitter,
09136 localdelay,
09137 locallost,
09138 locallosspct,
09139 localdropped,
09140 localooo,
09141 localpackets,
09142 iaxs[callno]->remote_rr.jitter,
09143 iaxs[callno]->remote_rr.delay,
09144 iaxs[callno]->remote_rr.losscnt,
09145 iaxs[callno]->remote_rr.losspct/1000,
09146 iaxs[callno]->remote_rr.dropped,
09147 iaxs[callno]->remote_rr.ooo,
09148 iaxs[callno]->remote_rr.packets);
09149 }
09150 ast_mutex_unlock(&iaxsl[callno]);
09151 }
09152
09153 static int socket_process(struct iax2_thread *thread);
09154
09155
09156
09157
09158 static void handle_deferred_full_frames(struct iax2_thread *thread)
09159 {
09160 struct iax2_pkt_buf *pkt_buf;
09161
09162 ast_mutex_lock(&thread->lock);
09163
09164 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09165 ast_mutex_unlock(&thread->lock);
09166
09167 thread->buf = pkt_buf->buf;
09168 thread->buf_len = pkt_buf->len;
09169 thread->buf_size = pkt_buf->len + 1;
09170
09171 socket_process(thread);
09172
09173 thread->buf = NULL;
09174 ast_free(pkt_buf);
09175
09176 ast_mutex_lock(&thread->lock);
09177 }
09178
09179 ast_mutex_unlock(&thread->lock);
09180 }
09181
09182
09183
09184
09185
09186
09187
09188 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09189 {
09190 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09191 struct ast_iax2_full_hdr *fh, *cur_fh;
09192
09193 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09194 return;
09195
09196 pkt_buf->len = from_here->buf_len;
09197 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09198
09199 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09200 ast_mutex_lock(&to_here->lock);
09201 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09202 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09203 if (fh->oseqno < cur_fh->oseqno) {
09204 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09205 break;
09206 }
09207 }
09208 AST_LIST_TRAVERSE_SAFE_END
09209
09210 if (!cur_pkt_buf)
09211 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09212
09213 ast_mutex_unlock(&to_here->lock);
09214 }
09215
09216 static int socket_read(int *id, int fd, short events, void *cbdata)
09217 {
09218 struct iax2_thread *thread;
09219 socklen_t len;
09220 time_t t;
09221 static time_t last_errtime = 0;
09222 struct ast_iax2_full_hdr *fh;
09223
09224 if (!(thread = find_idle_thread())) {
09225 time(&t);
09226 if (t != last_errtime)
09227 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09228 last_errtime = t;
09229 usleep(1);
09230 return 1;
09231 }
09232
09233 len = sizeof(thread->iosin);
09234 thread->iofd = fd;
09235 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09236 thread->buf_size = sizeof(thread->readbuf);
09237 thread->buf = thread->readbuf;
09238 if (thread->buf_len < 0) {
09239 if (errno != ECONNREFUSED && errno != EAGAIN)
09240 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09241 handle_error();
09242 thread->iostate = IAX_IOSTATE_IDLE;
09243 signal_condition(&thread->lock, &thread->cond);
09244 return 1;
09245 }
09246 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09247 thread->iostate = IAX_IOSTATE_IDLE;
09248 signal_condition(&thread->lock, &thread->cond);
09249 return 1;
09250 }
09251
09252
09253
09254
09255 fh = (struct ast_iax2_full_hdr *) thread->buf;
09256 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09257 struct iax2_thread *cur = NULL;
09258 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09259
09260 AST_LIST_LOCK(&active_list);
09261 AST_LIST_TRAVERSE(&active_list, cur, list) {
09262 if ((cur->ffinfo.callno == callno) &&
09263 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09264 break;
09265 }
09266 if (cur) {
09267
09268
09269 defer_full_frame(thread, cur);
09270 AST_LIST_UNLOCK(&active_list);
09271 thread->iostate = IAX_IOSTATE_IDLE;
09272 signal_condition(&thread->lock, &thread->cond);
09273 return 1;
09274 } else {
09275
09276 thread->ffinfo.callno = callno;
09277 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09278 thread->ffinfo.type = fh->type;
09279 thread->ffinfo.csub = fh->csub;
09280 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09281 }
09282 AST_LIST_UNLOCK(&active_list);
09283 }
09284
09285
09286 thread->iostate = IAX_IOSTATE_READY;
09287 #ifdef DEBUG_SCHED_MULTITHREAD
09288 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09289 #endif
09290 signal_condition(&thread->lock, &thread->cond);
09291
09292 return 1;
09293 }
09294
09295 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09296 struct iax_frame *fr)
09297 {
09298 unsigned char metatype;
09299 struct ast_iax2_meta_trunk_mini *mtm;
09300 struct ast_iax2_meta_trunk_hdr *mth;
09301 struct ast_iax2_meta_trunk_entry *mte;
09302 struct iax2_trunk_peer *tpeer;
09303 unsigned int ts;
09304 void *ptr;
09305 struct timeval rxtrunktime;
09306 struct ast_frame f = { 0, };
09307
09308 if (packet_len < sizeof(*meta)) {
09309 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09310 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09311 return 1;
09312 }
09313
09314 if (meta->metacmd != IAX_META_TRUNK)
09315 return 1;
09316
09317 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09318 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09319 (int) (sizeof(*meta) + sizeof(*mth)));
09320 return 1;
09321 }
09322 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09323 ts = ntohl(mth->ts);
09324 metatype = meta->cmddata;
09325 packet_len -= (sizeof(*meta) + sizeof(*mth));
09326 ptr = mth->data;
09327 tpeer = find_tpeer(sin, sockfd);
09328 if (!tpeer) {
09329 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09330 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09331 return 1;
09332 }
09333 tpeer->trunkact = ast_tvnow();
09334 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09335 tpeer->rxtrunktime = tpeer->trunkact;
09336 rxtrunktime = tpeer->rxtrunktime;
09337 ast_mutex_unlock(&tpeer->lock);
09338 while (packet_len >= sizeof(*mte)) {
09339
09340 unsigned short callno, trunked_ts, len;
09341
09342 if (metatype == IAX_META_TRUNK_MINI) {
09343 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09344 ptr += sizeof(*mtm);
09345 packet_len -= sizeof(*mtm);
09346 len = ntohs(mtm->len);
09347 callno = ntohs(mtm->mini.callno);
09348 trunked_ts = ntohs(mtm->mini.ts);
09349 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09350 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09351 ptr += sizeof(*mte);
09352 packet_len -= sizeof(*mte);
09353 len = ntohs(mte->len);
09354 callno = ntohs(mte->callno);
09355 trunked_ts = 0;
09356 } else {
09357 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09358 break;
09359 }
09360
09361 if (len > packet_len)
09362 break;
09363 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09364 if (!fr->callno)
09365 continue;
09366
09367
09368
09369
09370 memset(&f, 0, sizeof(f));
09371 f.frametype = AST_FRAME_VOICE;
09372 if (!iaxs[fr->callno]) {
09373
09374 } else if (iaxs[fr->callno]->voiceformat == 0) {
09375 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09376 iax2_vnak(fr->callno);
09377 } else {
09378 f.subclass = iaxs[fr->callno]->voiceformat;
09379 f.datalen = len;
09380 if (f.datalen >= 0) {
09381 if (f.datalen)
09382 f.data.ptr = ptr;
09383 else
09384 f.data.ptr = NULL;
09385 if (trunked_ts)
09386 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09387 else
09388 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09389
09390 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09391 struct iax_frame *duped_fr;
09392
09393
09394 f.src = "IAX2";
09395 f.mallocd = 0;
09396 f.offset = 0;
09397 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09398 f.samples = ast_codec_get_samples(&f);
09399 else
09400 f.samples = 0;
09401 fr->outoforder = 0;
09402 iax_frame_wrap(fr, &f);
09403 duped_fr = iaxfrdup2(fr);
09404 if (duped_fr)
09405 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09406 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09407 iaxs[fr->callno]->last = fr->ts;
09408 }
09409 } else {
09410 ast_log(LOG_WARNING, "Datalen < 0?\n");
09411 }
09412 }
09413 ast_mutex_unlock(&iaxsl[fr->callno]);
09414 ptr += len;
09415 packet_len -= len;
09416 }
09417
09418 return 1;
09419 }
09420
09421 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09422 {
09423 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09424 AST_LIST_HEAD(, ast_var_t) *varlist;
09425 struct ast_var_t *var;
09426
09427 if (!variablestore) {
09428 *buf = '\0';
09429 return 0;
09430 }
09431 varlist = variablestore->data;
09432
09433 AST_LIST_LOCK(varlist);
09434 AST_LIST_TRAVERSE(varlist, var, entries) {
09435 if (strcmp(var->name, data) == 0) {
09436 ast_copy_string(buf, var->value, len);
09437 break;
09438 }
09439 }
09440 AST_LIST_UNLOCK(varlist);
09441 return 0;
09442 }
09443
09444 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09445 {
09446 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09447 AST_LIST_HEAD(, ast_var_t) *varlist;
09448 struct ast_var_t *var;
09449
09450 if (!variablestore) {
09451 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09452 if (!variablestore) {
09453 ast_log(LOG_ERROR, "Memory allocation error\n");
09454 return -1;
09455 }
09456 varlist = ast_calloc(1, sizeof(*varlist));
09457 if (!varlist) {
09458 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09459 return -1;
09460 }
09461
09462 AST_LIST_HEAD_INIT(varlist);
09463 variablestore->data = varlist;
09464 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09465 ast_channel_datastore_add(chan, variablestore);
09466 } else
09467 varlist = variablestore->data;
09468
09469 AST_LIST_LOCK(varlist);
09470 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09471 if (strcmp(var->name, data) == 0) {
09472 AST_LIST_REMOVE_CURRENT(entries);
09473 ast_var_delete(var);
09474 break;
09475 }
09476 }
09477 AST_LIST_TRAVERSE_SAFE_END;
09478 var = ast_var_assign(data, value);
09479 if (var)
09480 AST_LIST_INSERT_TAIL(varlist, var, entries);
09481 else
09482 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09483 AST_LIST_UNLOCK(varlist);
09484 return 0;
09485 }
09486
09487 static struct ast_custom_function iaxvar_function = {
09488 .name = "IAXVAR",
09489 .read = acf_iaxvar_read,
09490 .write = acf_iaxvar_write,
09491 };
09492
09493 static int socket_process(struct iax2_thread *thread)
09494 {
09495 struct sockaddr_in sin;
09496 int res;
09497 int updatehistory=1;
09498 int new = NEW_PREVENT;
09499 int dcallno = 0;
09500 char decrypted = 0;
09501 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09502 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09503 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09504 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09505 struct iax_frame *fr;
09506 struct iax_frame *cur;
09507 struct ast_frame f = { 0, };
09508 struct ast_channel *c = NULL;
09509 struct iax2_dpcache *dp;
09510 struct iax2_peer *peer;
09511 struct iax_ies ies;
09512 struct iax_ie_data ied0, ied1;
09513 int format;
09514 int fd;
09515 int exists;
09516 int minivid = 0;
09517 char empty[32]="";
09518 struct iax_frame *duped_fr;
09519 char host_pref_buf[128];
09520 char caller_pref_buf[128];
09521 struct ast_codec_pref pref;
09522 char *using_prefs = "mine";
09523
09524
09525 fr = alloca(sizeof(*fr) + 4096);
09526 memset(fr, 0, sizeof(*fr));
09527 fr->afdatalen = 4096;
09528
09529
09530 res = thread->buf_len;
09531 fd = thread->iofd;
09532 memcpy(&sin, &thread->iosin, sizeof(sin));
09533
09534 if (res < sizeof(*mh)) {
09535 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09536 return 1;
09537 }
09538 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09539 if (res < sizeof(*vh)) {
09540 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));
09541 return 1;
09542 }
09543
09544
09545 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09546 minivid = 1;
09547 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09548 return socket_process_meta(res, meta, &sin, fd, fr);
09549
09550 #ifdef DEBUG_SUPPORT
09551 if (res >= sizeof(*fh))
09552 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09553 #endif
09554 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09555 if (res < sizeof(*fh)) {
09556 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));
09557 return 1;
09558 }
09559
09560
09561 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09562
09563
09564
09565
09566
09567
09568 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09569 ast_mutex_lock(&iaxsl[fr->callno]);
09570 if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
09571 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09572 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09573 ast_mutex_unlock(&iaxsl[fr->callno]);
09574 return 1;
09575 }
09576 decrypted = 1;
09577 }
09578 ast_mutex_unlock(&iaxsl[fr->callno]);
09579 }
09580
09581
09582 f.frametype = fh->type;
09583 if (f.frametype == AST_FRAME_VIDEO) {
09584 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09585 } else {
09586 f.subclass = uncompress_subclass(fh->csub);
09587 }
09588
09589
09590 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
09591
09592 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09593 return 1;
09594 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
09595
09596 return 1;
09597 }
09598
09599 f.datalen = res - sizeof(*fh);
09600 if (f.datalen) {
09601 if (f.frametype == AST_FRAME_IAX) {
09602 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09603 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09604 ast_variables_destroy(ies.vars);
09605 return 1;
09606 }
09607 f.data.ptr = NULL;
09608 f.datalen = 0;
09609 } else {
09610 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09611 memset(&ies, 0, sizeof(ies));
09612 }
09613 } else {
09614 if (f.frametype == AST_FRAME_IAX)
09615 f.data.ptr = NULL;
09616 else
09617 f.data.ptr = empty;
09618 memset(&ies, 0, sizeof(ies));
09619 }
09620
09621 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) {
09622
09623 if (handle_call_token(fh, &ies, &sin, fd)) {
09624 ast_variables_destroy(ies.vars);
09625 return 1;
09626 }
09627
09628 if (ies.calltoken && ies.calltokendata) {
09629
09630
09631
09632
09633 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09634 } else {
09635 new = NEW_ALLOW;
09636 }
09637 }
09638 } else {
09639
09640 f.frametype = AST_FRAME_NULL;
09641 f.subclass = 0;
09642 memset(&ies, 0, sizeof(ies));
09643 }
09644
09645 if (!fr->callno) {
09646 int check_dcallno = 0;
09647
09648
09649
09650
09651
09652
09653
09654
09655
09656 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) {
09657 check_dcallno = 1;
09658 }
09659
09660 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09661 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) {
09662 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09663 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) {
09664 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09665 }
09666 ast_variables_destroy(ies.vars);
09667 return 1;
09668 }
09669 }
09670
09671 if (fr->callno > 0)
09672 ast_mutex_lock(&iaxsl[fr->callno]);
09673
09674 if (!fr->callno || !iaxs[fr->callno]) {
09675
09676
09677 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09678
09679 if (((f.subclass != IAX_COMMAND_INVAL) &&
09680 (f.subclass != IAX_COMMAND_TXCNT) &&
09681 (f.subclass != IAX_COMMAND_TXACC) &&
09682 (f.subclass != IAX_COMMAND_FWDOWNL))||
09683 (f.frametype != AST_FRAME_IAX))
09684 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09685 fd);
09686 }
09687 if (fr->callno > 0)
09688 ast_mutex_unlock(&iaxsl[fr->callno]);
09689 ast_variables_destroy(ies.vars);
09690 return 1;
09691 }
09692 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
09693 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09694 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09695 ast_variables_destroy(ies.vars);
09696 ast_mutex_unlock(&iaxsl[fr->callno]);
09697 return 1;
09698 }
09699 decrypted = 1;
09700 }
09701 #ifdef DEBUG_SUPPORT
09702 if (decrypted) {
09703 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
09704 }
09705 #endif
09706
09707
09708 iaxs[fr->callno]->frames_received++;
09709
09710 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
09711 f.subclass != IAX_COMMAND_TXCNT &&
09712 f.subclass != IAX_COMMAND_TXACC) {
09713 unsigned short new_peercallno;
09714
09715 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
09716 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
09717 if (iaxs[fr->callno]->peercallno) {
09718 remove_by_peercallno(iaxs[fr->callno]);
09719 }
09720 iaxs[fr->callno]->peercallno = new_peercallno;
09721 store_by_peercallno(iaxs[fr->callno]);
09722 }
09723 }
09724 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09725 if (iaxdebug)
09726 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
09727
09728 fr->oseqno = fh->oseqno;
09729 fr->iseqno = fh->iseqno;
09730 fr->ts = ntohl(fh->ts);
09731 #ifdef IAXTESTS
09732 if (test_resync) {
09733 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
09734 fr->ts += test_resync;
09735 }
09736 #endif
09737 #if 0
09738 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
09739 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
09740 (f.subclass == IAX_COMMAND_NEW ||
09741 f.subclass == IAX_COMMAND_AUTHREQ ||
09742 f.subclass == IAX_COMMAND_ACCEPT ||
09743 f.subclass == IAX_COMMAND_REJECT)) ) )
09744 #endif
09745 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
09746 updatehistory = 0;
09747 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
09748 (iaxs[fr->callno]->iseqno ||
09749 ((f.subclass != IAX_COMMAND_TXCNT) &&
09750 (f.subclass != IAX_COMMAND_TXREADY) &&
09751 (f.subclass != IAX_COMMAND_TXREL) &&
09752 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09753 (f.subclass != IAX_COMMAND_TXACC)) ||
09754 (f.frametype != AST_FRAME_IAX))) {
09755 if (
09756 ((f.subclass != IAX_COMMAND_ACK) &&
09757 (f.subclass != IAX_COMMAND_INVAL) &&
09758 (f.subclass != IAX_COMMAND_TXCNT) &&
09759 (f.subclass != IAX_COMMAND_TXREADY) &&
09760 (f.subclass != IAX_COMMAND_TXREL) &&
09761 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
09762 (f.subclass != IAX_COMMAND_TXACC) &&
09763 (f.subclass != IAX_COMMAND_VNAK)) ||
09764 (f.frametype != AST_FRAME_IAX)) {
09765
09766 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
09767 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
09768
09769
09770 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
09771
09772 if ((f.frametype != AST_FRAME_IAX) ||
09773 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
09774 ast_debug(1, "Acking anyway\n");
09775
09776
09777 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09778 }
09779 } else {
09780
09781 iax2_vnak(fr->callno);
09782 }
09783 ast_variables_destroy(ies.vars);
09784 ast_mutex_unlock(&iaxsl[fr->callno]);
09785 return 1;
09786 }
09787 } else {
09788
09789 if (((f.subclass != IAX_COMMAND_ACK) &&
09790 (f.subclass != IAX_COMMAND_INVAL) &&
09791 (f.subclass != IAX_COMMAND_TXCNT) &&
09792 (f.subclass != IAX_COMMAND_TXACC) &&
09793 (f.subclass != IAX_COMMAND_VNAK)) ||
09794 (f.frametype != AST_FRAME_IAX))
09795 iaxs[fr->callno]->iseqno++;
09796 }
09797
09798 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
09799 if (res < thread->buf_size)
09800 thread->buf[res++] = '\0';
09801 else
09802 thread->buf[res - 1] = '\0';
09803 }
09804
09805
09806
09807 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09808 ((f.subclass != IAX_COMMAND_INVAL) ||
09809 (f.frametype != AST_FRAME_IAX))) {
09810 unsigned char x;
09811 int call_to_destroy;
09812
09813 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
09814 x = fr->iseqno;
09815 else
09816 x = iaxs[fr->callno]->oseqno;
09817 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
09818
09819
09820 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
09821
09822 if (iaxdebug)
09823 ast_debug(1, "Cancelling transmission of packet %d\n", x);
09824 call_to_destroy = 0;
09825 AST_LIST_LOCK(&frame_queue);
09826 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09827
09828 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
09829 cur->retries = -1;
09830
09831 if (cur->final)
09832 call_to_destroy = fr->callno;
09833 }
09834 }
09835 AST_LIST_UNLOCK(&frame_queue);
09836 if (call_to_destroy) {
09837 if (iaxdebug)
09838 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
09839 ast_mutex_lock(&iaxsl[call_to_destroy]);
09840 iax2_destroy(call_to_destroy);
09841 ast_mutex_unlock(&iaxsl[call_to_destroy]);
09842 }
09843 }
09844
09845 if (iaxs[fr->callno])
09846 iaxs[fr->callno]->rseqno = fr->iseqno;
09847 else {
09848
09849 ast_variables_destroy(ies.vars);
09850 ast_mutex_unlock(&iaxsl[fr->callno]);
09851 return 1;
09852 }
09853 } else {
09854 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
09855 }
09856 }
09857 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
09858 ((f.frametype != AST_FRAME_IAX) ||
09859 ((f.subclass != IAX_COMMAND_TXACC) &&
09860 (f.subclass != IAX_COMMAND_TXCNT)))) {
09861
09862 ast_variables_destroy(ies.vars);
09863 ast_mutex_unlock(&iaxsl[fr->callno]);
09864 return 1;
09865 }
09866
09867
09868
09869
09870 if ((f.frametype == AST_FRAME_VOICE) ||
09871 (f.frametype == AST_FRAME_VIDEO) ||
09872 (f.frametype == AST_FRAME_IAX)) {
09873 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
09874 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
09875 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
09876 ast_variables_destroy(ies.vars);
09877 ast_mutex_unlock(&iaxsl[fr->callno]);
09878 return 1;
09879 }
09880 }
09881
09882 if (ies.vars) {
09883 struct ast_datastore *variablestore = NULL;
09884 struct ast_variable *var, *prev = NULL;
09885 AST_LIST_HEAD(, ast_var_t) *varlist;
09886
09887 iax2_lock_owner(fr->callno);
09888 if (!iaxs[fr->callno]) {
09889 ast_variables_destroy(ies.vars);
09890 ast_mutex_unlock(&iaxsl[fr->callno]);
09891 return 1;
09892 }
09893 if ((c = iaxs[fr->callno]->owner)) {
09894 varlist = ast_calloc(1, sizeof(*varlist));
09895 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09896
09897 if (variablestore && varlist) {
09898 variablestore->data = varlist;
09899 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09900 AST_LIST_HEAD_INIT(varlist);
09901 ast_debug(1, "I can haz IAX vars?\n");
09902 for (var = ies.vars; var; var = var->next) {
09903 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09904 if (prev) {
09905 ast_free(prev);
09906 }
09907 prev = var;
09908 if (!newvar) {
09909
09910 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09911 } else {
09912 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09913 }
09914 }
09915 if (prev) {
09916 ast_free(prev);
09917 }
09918 ies.vars = NULL;
09919 ast_channel_datastore_add(c, variablestore);
09920 } else {
09921 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09922 if (variablestore) {
09923 ast_datastore_free(variablestore);
09924 }
09925 if (varlist) {
09926 ast_free(varlist);
09927 }
09928 }
09929 ast_channel_unlock(c);
09930 } else {
09931
09932
09933 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
09934 for (var = ies.vars; var && var->next; var = var->next);
09935 if (var) {
09936 var->next = iaxs[fr->callno]->iaxvars;
09937 iaxs[fr->callno]->iaxvars = ies.vars;
09938 ies.vars = NULL;
09939 }
09940 }
09941 }
09942
09943 if (ies.vars) {
09944 ast_debug(1, "I have IAX variables, but they were not processed\n");
09945 }
09946 }
09947
09948
09949
09950 if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
09951 send_signaling(iaxs[fr->callno]);
09952 }
09953
09954 if (f.frametype == AST_FRAME_VOICE) {
09955 if (f.subclass != iaxs[fr->callno]->voiceformat) {
09956 iaxs[fr->callno]->voiceformat = f.subclass;
09957 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
09958 if (iaxs[fr->callno]->owner) {
09959 iax2_lock_owner(fr->callno);
09960 if (iaxs[fr->callno]) {
09961 if (iaxs[fr->callno]->owner) {
09962 int orignative;
09963
09964 orignative = iaxs[fr->callno]->owner->nativeformats;
09965 iaxs[fr->callno]->owner->nativeformats = f.subclass;
09966 if (iaxs[fr->callno]->owner->readformat)
09967 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
09968 iaxs[fr->callno]->owner->nativeformats = orignative;
09969 ast_channel_unlock(iaxs[fr->callno]->owner);
09970 }
09971 } else {
09972 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
09973
09974 if (ies.vars) {
09975 ast_variables_destroy(ies.vars);
09976 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
09977 ies.vars = NULL;
09978 }
09979 ast_mutex_unlock(&iaxsl[fr->callno]);
09980 return 1;
09981 }
09982 }
09983 }
09984 }
09985 if (f.frametype == AST_FRAME_VIDEO) {
09986 if (f.subclass != iaxs[fr->callno]->videoformat) {
09987 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
09988 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
09989 }
09990 }
09991 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
09992 if (f.subclass == AST_CONTROL_BUSY) {
09993 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
09994 } else if (f.subclass == AST_CONTROL_CONGESTION) {
09995 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
09996 }
09997 }
09998 if (f.frametype == AST_FRAME_IAX) {
09999 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10000
10001 if (iaxdebug)
10002 ast_debug(1, "IAX subclass %d received\n", f.subclass);
10003
10004
10005 if (iaxs[fr->callno]->last < fr->ts &&
10006 f.subclass != IAX_COMMAND_ACK &&
10007 f.subclass != IAX_COMMAND_PONG &&
10008 f.subclass != IAX_COMMAND_LAGRP) {
10009 iaxs[fr->callno]->last = fr->ts;
10010 if (iaxdebug)
10011 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10012 }
10013 iaxs[fr->callno]->last_iax_message = f.subclass;
10014 if (!iaxs[fr->callno]->first_iax_message) {
10015 iaxs[fr->callno]->first_iax_message = f.subclass;
10016 }
10017 switch(f.subclass) {
10018 case IAX_COMMAND_ACK:
10019
10020 break;
10021 case IAX_COMMAND_QUELCH:
10022 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10023
10024 if (iaxs[fr->callno]->owner) {
10025 manager_event(EVENT_FLAG_CALL, "Hold",
10026 "Status: On\r\n"
10027 "Channel: %s\r\n"
10028 "Uniqueid: %s\r\n",
10029 iaxs[fr->callno]->owner->name,
10030 iaxs[fr->callno]->owner->uniqueid);
10031 }
10032
10033 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
10034 if (ies.musiconhold) {
10035 iax2_lock_owner(fr->callno);
10036 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10037 break;
10038 }
10039 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10040 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10041
10042
10043
10044
10045
10046 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10047 S_OR(moh_suggest, NULL),
10048 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10049 }
10050 ast_channel_unlock(iaxs[fr->callno]->owner);
10051 }
10052 }
10053 break;
10054 case IAX_COMMAND_UNQUELCH:
10055 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10056 iax2_lock_owner(fr->callno);
10057 if (!iaxs[fr->callno]) {
10058 break;
10059 }
10060
10061 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
10062 manager_event(EVENT_FLAG_CALL, "Hold",
10063 "Status: Off\r\n"
10064 "Channel: %s\r\n"
10065 "Uniqueid: %s\r\n",
10066 iaxs[fr->callno]->owner->name,
10067 iaxs[fr->callno]->owner->uniqueid);
10068 }
10069
10070 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
10071 if (!iaxs[fr->callno]->owner) {
10072 break;
10073 }
10074 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10075
10076
10077
10078
10079 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10080 }
10081 ast_channel_unlock(iaxs[fr->callno]->owner);
10082 }
10083 break;
10084 case IAX_COMMAND_TXACC:
10085 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10086
10087 AST_LIST_LOCK(&frame_queue);
10088 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10089
10090 if ((fr->callno == cur->callno) && (cur->transfer))
10091 cur->retries = -1;
10092 }
10093 AST_LIST_UNLOCK(&frame_queue);
10094 memset(&ied1, 0, sizeof(ied1));
10095 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10096 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10097 iaxs[fr->callno]->transferring = TRANSFER_READY;
10098 }
10099 break;
10100 case IAX_COMMAND_NEW:
10101
10102 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10103 break;
10104 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10105 ast_mutex_unlock(&iaxsl[fr->callno]);
10106 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10107 ast_mutex_lock(&iaxsl[fr->callno]);
10108 if (!iaxs[fr->callno]) {
10109 break;
10110 }
10111 }
10112
10113 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
10114 int new_callno;
10115 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10116 fr->callno = new_callno;
10117 }
10118
10119 if (delayreject)
10120 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10121 if (check_access(fr->callno, &sin, &ies)) {
10122
10123 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10124 if (authdebug)
10125 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);
10126 break;
10127 }
10128 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10129 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10130 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10131 break;
10132 }
10133 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10134 const char *context, *exten, *cid_num;
10135
10136 context = ast_strdupa(iaxs[fr->callno]->context);
10137 exten = ast_strdupa(iaxs[fr->callno]->exten);
10138 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10139
10140
10141 ast_mutex_unlock(&iaxsl[fr->callno]);
10142 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10143 ast_mutex_lock(&iaxsl[fr->callno]);
10144
10145 if (!iaxs[fr->callno]) {
10146 break;
10147 }
10148 } else
10149 exists = 0;
10150
10151 save_osptoken(fr, &ies);
10152 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10153 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10154 memset(&ied0, 0, sizeof(ied0));
10155 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10156 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10157 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10158 if (!iaxs[fr->callno]) {
10159 break;
10160 }
10161 if (authdebug)
10162 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);
10163 } else {
10164
10165
10166 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10167 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10168 using_prefs = "reqonly";
10169 } else {
10170 using_prefs = "disabled";
10171 }
10172 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10173 memset(&pref, 0, sizeof(pref));
10174 strcpy(caller_pref_buf, "disabled");
10175 strcpy(host_pref_buf, "disabled");
10176 } else {
10177 using_prefs = "mine";
10178
10179 if (ies.codec_prefs)
10180 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10181 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10182
10183 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10184 pref = iaxs[fr->callno]->rprefs;
10185 using_prefs = "caller";
10186 } else {
10187 pref = iaxs[fr->callno]->prefs;
10188 }
10189 } else
10190 pref = iaxs[fr->callno]->prefs;
10191
10192 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10193 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10194 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10195 }
10196 if (!format) {
10197 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10198 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10199 if (!format) {
10200 memset(&ied0, 0, sizeof(ied0));
10201 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10202 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10203 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10204 if (!iaxs[fr->callno]) {
10205 break;
10206 }
10207 if (authdebug) {
10208 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10209 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);
10210 else
10211 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);
10212 }
10213 } else {
10214
10215 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10216 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10217 format = 0;
10218 } else {
10219 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10220 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10221 memset(&pref, 0, sizeof(pref));
10222 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10223 strcpy(caller_pref_buf,"disabled");
10224 strcpy(host_pref_buf,"disabled");
10225 } else {
10226 using_prefs = "mine";
10227 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10228
10229 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10230 pref = iaxs[fr->callno]->prefs;
10231 } else {
10232 pref = iaxs[fr->callno]->rprefs;
10233 using_prefs = "caller";
10234 }
10235 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10236
10237 } else
10238 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10239 }
10240 }
10241
10242 if (!format) {
10243 memset(&ied0, 0, sizeof(ied0));
10244 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10245 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10246 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10247 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10248 if (!iaxs[fr->callno]) {
10249 break;
10250 }
10251 if (authdebug)
10252 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);
10253 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10254 break;
10255 }
10256 }
10257 }
10258 if (format) {
10259
10260 memset(&ied1, 0, sizeof(ied1));
10261 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10262 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10263 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10264 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10265 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10266 "%srequested format = %s,\n"
10267 "%srequested prefs = %s,\n"
10268 "%sactual format = %s,\n"
10269 "%shost prefs = %s,\n"
10270 "%spriority = %s\n",
10271 ast_inet_ntoa(sin.sin_addr),
10272 VERBOSE_PREFIX_4,
10273 ast_getformatname(iaxs[fr->callno]->peerformat),
10274 VERBOSE_PREFIX_4,
10275 caller_pref_buf,
10276 VERBOSE_PREFIX_4,
10277 ast_getformatname(format),
10278 VERBOSE_PREFIX_4,
10279 host_pref_buf,
10280 VERBOSE_PREFIX_4,
10281 using_prefs);
10282
10283 iaxs[fr->callno]->chosenformat = format;
10284 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
10285 } else {
10286 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10287
10288 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10289 }
10290 }
10291 }
10292 break;
10293 }
10294 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10295 merge_encryption(iaxs[fr->callno],ies.encmethods);
10296 else
10297 iaxs[fr->callno]->encmethods = 0;
10298 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10299 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10300 break;
10301 case IAX_COMMAND_DPREQ:
10302
10303 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10304 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10305 if (iaxcompat) {
10306
10307 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10308 } else {
10309
10310 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10311 }
10312 }
10313 break;
10314 case IAX_COMMAND_HANGUP:
10315 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10316 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10317
10318 if (ies.causecode && iaxs[fr->callno]->owner)
10319 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10320
10321 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10322 iax2_destroy(fr->callno);
10323 break;
10324 case IAX_COMMAND_REJECT:
10325
10326 if (ies.causecode && iaxs[fr->callno]->owner)
10327 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
10328
10329 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10330 if (iaxs[fr->callno]->owner && authdebug)
10331 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10332 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10333 ies.cause ? ies.cause : "<Unknown>");
10334 ast_debug(1, "Immediately destroying %d, having received reject\n",
10335 fr->callno);
10336 }
10337
10338 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10339 fr->ts, NULL, 0, fr->iseqno);
10340 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
10341 iaxs[fr->callno]->error = EPERM;
10342 iax2_destroy(fr->callno);
10343 break;
10344 case IAX_COMMAND_TRANSFER:
10345 {
10346 struct ast_channel *bridged_chan;
10347 struct ast_channel *owner;
10348
10349 iax2_lock_owner(fr->callno);
10350 if (!iaxs[fr->callno]) {
10351
10352 break;
10353 }
10354 owner = iaxs[fr->callno]->owner;
10355 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10356 if (bridged_chan && ies.called_number) {
10357 ast_mutex_unlock(&iaxsl[fr->callno]);
10358
10359
10360 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10361 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10362
10363 if (!strcmp(ies.called_number, ast_parking_ext())) {
10364 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10365 if (iax_park(bridged_chan, owner)) {
10366 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10367 bridged_chan->name);
10368 }
10369 ast_mutex_lock(&iaxsl[fr->callno]);
10370 } else {
10371 ast_mutex_lock(&iaxsl[fr->callno]);
10372
10373 if (iaxs[fr->callno]) {
10374 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context,
10375 ies.called_number, 1)) {
10376 ast_log(LOG_WARNING,
10377 "Async goto of '%s' to '%s@%s' failed\n",
10378 bridged_chan->name, ies.called_number,
10379 iaxs[fr->callno]->context);
10380 } else {
10381 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10382 bridged_chan->name, ies.called_number,
10383 iaxs[fr->callno]->context);
10384 }
10385 } else {
10386
10387 }
10388 }
10389 } else {
10390 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10391 }
10392 if (owner) {
10393 ast_channel_unlock(owner);
10394 }
10395
10396 break;
10397 }
10398 case IAX_COMMAND_ACCEPT:
10399
10400 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10401 break;
10402 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
10403
10404 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10405 iax2_destroy(fr->callno);
10406 break;
10407 }
10408 if (ies.format) {
10409 iaxs[fr->callno]->peerformat = ies.format;
10410 } else {
10411 if (iaxs[fr->callno]->owner)
10412 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10413 else
10414 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10415 }
10416 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));
10417 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10418 memset(&ied0, 0, sizeof(ied0));
10419 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10420 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10421 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10422 if (!iaxs[fr->callno]) {
10423 break;
10424 }
10425 if (authdebug)
10426 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);
10427 } else {
10428 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10429 iax2_lock_owner(fr->callno);
10430 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10431
10432 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10433 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10434
10435
10436 if (iaxs[fr->callno]->owner->writeformat)
10437 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10438 if (iaxs[fr->callno]->owner->readformat)
10439 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10440 ast_channel_unlock(iaxs[fr->callno]->owner);
10441 }
10442 }
10443 if (iaxs[fr->callno]) {
10444 AST_LIST_LOCK(&dpcache);
10445 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10446 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10447 iax2_dprequest(dp, fr->callno);
10448 AST_LIST_UNLOCK(&dpcache);
10449 }
10450 break;
10451 case IAX_COMMAND_POKE:
10452
10453 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10454 break;
10455 case IAX_COMMAND_PING:
10456 {
10457 struct iax_ie_data pingied;
10458 construct_rr(iaxs[fr->callno], &pingied);
10459
10460 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10461 }
10462 break;
10463 case IAX_COMMAND_PONG:
10464
10465 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10466
10467 save_rr(fr, &ies);
10468
10469
10470 log_jitterstats(fr->callno);
10471
10472 if (iaxs[fr->callno]->peerpoke) {
10473 peer = iaxs[fr->callno]->peerpoke;
10474 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10475 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10476 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10477 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);
10478 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10479 }
10480 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10481 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10482 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10483 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);
10484 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10485 }
10486 }
10487 peer->lastms = iaxs[fr->callno]->pingtime;
10488 if (peer->smoothing && (peer->lastms > -1))
10489 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10490 else if (peer->smoothing && peer->lastms < 0)
10491 peer->historicms = (0 + peer->historicms) / 2;
10492 else
10493 peer->historicms = iaxs[fr->callno]->pingtime;
10494
10495
10496 if (peer->pokeexpire > -1) {
10497 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10498 peer_unref(peer);
10499 peer->pokeexpire = -1;
10500 }
10501 }
10502
10503 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10504 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10505 else
10506 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10507 if (peer->pokeexpire == -1)
10508 peer_unref(peer);
10509
10510 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10511
10512 iax2_destroy(fr->callno);
10513 peer->callno = 0;
10514 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10515 }
10516 break;
10517 case IAX_COMMAND_LAGRQ:
10518 case IAX_COMMAND_LAGRP:
10519 f.src = "LAGRQ";
10520 f.mallocd = 0;
10521 f.offset = 0;
10522 f.samples = 0;
10523 iax_frame_wrap(fr, &f);
10524 if(f.subclass == IAX_COMMAND_LAGRQ) {
10525
10526 fr->af.subclass = IAX_COMMAND_LAGRP;
10527 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10528 } else {
10529
10530 unsigned int ts;
10531
10532 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10533 iaxs[fr->callno]->lag = ts - fr->ts;
10534 if (iaxdebug)
10535 ast_debug(1, "Peer %s lag measured as %dms\n",
10536 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10537 }
10538 break;
10539 case IAX_COMMAND_AUTHREQ:
10540 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10541 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>");
10542 break;
10543 }
10544 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10545 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10546 .subclass = AST_CONTROL_HANGUP,
10547 };
10548 ast_log(LOG_WARNING,
10549 "I don't know how to authenticate %s to %s\n",
10550 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10551 iax2_queue_frame(fr->callno, &hangup_fr);
10552 }
10553 break;
10554 case IAX_COMMAND_AUTHREP:
10555
10556 if (delayreject)
10557 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10558
10559 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10560 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>");
10561 break;
10562 }
10563 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10564 if (authdebug)
10565 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);
10566 memset(&ied0, 0, sizeof(ied0));
10567 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10568 break;
10569 }
10570 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10571
10572 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10573 } else
10574 exists = 0;
10575 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10576 if (authdebug)
10577 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);
10578 memset(&ied0, 0, sizeof(ied0));
10579 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10580 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10581 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10582 if (!iaxs[fr->callno]) {
10583 break;
10584 }
10585 } else {
10586
10587 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10588 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10589 using_prefs = "reqonly";
10590 } else {
10591 using_prefs = "disabled";
10592 }
10593 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10594 memset(&pref, 0, sizeof(pref));
10595 strcpy(caller_pref_buf, "disabled");
10596 strcpy(host_pref_buf, "disabled");
10597 } else {
10598 using_prefs = "mine";
10599 if (ies.codec_prefs)
10600 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10601 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10602 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10603 pref = iaxs[fr->callno]->rprefs;
10604 using_prefs = "caller";
10605 } else {
10606 pref = iaxs[fr->callno]->prefs;
10607 }
10608 } else
10609 pref = iaxs[fr->callno]->prefs;
10610
10611 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10612 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10613 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10614 }
10615 if (!format) {
10616 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10617 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);
10618 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10619 }
10620 if (!format) {
10621 if (authdebug) {
10622 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10623 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);
10624 else
10625 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);
10626 }
10627 memset(&ied0, 0, sizeof(ied0));
10628 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10629 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10630 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10631 if (!iaxs[fr->callno]) {
10632 break;
10633 }
10634 } else {
10635
10636 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10637 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10638 format = 0;
10639 } else {
10640 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10641 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10642 memset(&pref, 0, sizeof(pref));
10643 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10644 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10645 strcpy(caller_pref_buf,"disabled");
10646 strcpy(host_pref_buf,"disabled");
10647 } else {
10648 using_prefs = "mine";
10649 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10650
10651 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10652 pref = iaxs[fr->callno]->prefs;
10653 } else {
10654 pref = iaxs[fr->callno]->rprefs;
10655 using_prefs = "caller";
10656 }
10657 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10658 } else
10659 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10660 }
10661 }
10662 if (!format) {
10663 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10664 if (authdebug) {
10665 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
10666 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);
10667 else
10668 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);
10669 }
10670 memset(&ied0, 0, sizeof(ied0));
10671 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10672 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10673 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10674 if (!iaxs[fr->callno]) {
10675 break;
10676 }
10677 }
10678 }
10679 }
10680 if (format) {
10681
10682 memset(&ied1, 0, sizeof(ied1));
10683 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10684 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10685 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10686 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10687 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
10688 "%srequested format = %s,\n"
10689 "%srequested prefs = %s,\n"
10690 "%sactual format = %s,\n"
10691 "%shost prefs = %s,\n"
10692 "%spriority = %s\n",
10693 ast_inet_ntoa(sin.sin_addr),
10694 VERBOSE_PREFIX_4,
10695 ast_getformatname(iaxs[fr->callno]->peerformat),
10696 VERBOSE_PREFIX_4,
10697 caller_pref_buf,
10698 VERBOSE_PREFIX_4,
10699 ast_getformatname(format),
10700 VERBOSE_PREFIX_4,
10701 host_pref_buf,
10702 VERBOSE_PREFIX_4,
10703 using_prefs);
10704
10705 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10706 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
10707 iax2_destroy(fr->callno);
10708 else if (ies.vars) {
10709 struct ast_datastore *variablestore;
10710 struct ast_variable *var, *prev = NULL;
10711 AST_LIST_HEAD(, ast_var_t) *varlist;
10712 varlist = ast_calloc(1, sizeof(*varlist));
10713 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10714 if (variablestore && varlist) {
10715 variablestore->data = varlist;
10716 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10717 AST_LIST_HEAD_INIT(varlist);
10718 ast_debug(1, "I can haz IAX vars? w00t\n");
10719 for (var = ies.vars; var; var = var->next) {
10720 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10721 if (prev)
10722 ast_free(prev);
10723 prev = var;
10724 if (!newvar) {
10725
10726 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10727 } else {
10728 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10729 }
10730 }
10731 if (prev)
10732 ast_free(prev);
10733 ies.vars = NULL;
10734 ast_channel_datastore_add(c, variablestore);
10735 } else {
10736 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10737 if (variablestore)
10738 ast_datastore_free(variablestore);
10739 if (varlist)
10740 ast_free(varlist);
10741 }
10742 }
10743 } else {
10744 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10745
10746 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10747 if (ast_test_flag(iaxs[fr->callno], IAX_IMMEDIATE)) {
10748 goto immediatedial;
10749 }
10750 }
10751 }
10752 }
10753 break;
10754 case IAX_COMMAND_DIAL:
10755 immediatedial:
10756 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
10757 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10758 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
10759 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
10760 if (authdebug)
10761 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);
10762 memset(&ied0, 0, sizeof(ied0));
10763 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10764 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10765 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10766 if (!iaxs[fr->callno]) {
10767 break;
10768 }
10769 } else {
10770 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10771 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
10772 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10773 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
10774 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
10775 iax2_destroy(fr->callno);
10776 else if (ies.vars) {
10777 struct ast_datastore *variablestore;
10778 struct ast_variable *var, *prev = NULL;
10779 AST_LIST_HEAD(, ast_var_t) *varlist;
10780 varlist = ast_calloc(1, sizeof(*varlist));
10781 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10782 ast_debug(1, "I can haz IAX vars? w00t\n");
10783 if (variablestore && varlist) {
10784 variablestore->data = varlist;
10785 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10786 AST_LIST_HEAD_INIT(varlist);
10787 for (var = ies.vars; var; var = var->next) {
10788 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10789 if (prev)
10790 ast_free(prev);
10791 prev = var;
10792 if (!newvar) {
10793
10794 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10795 } else {
10796 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10797 }
10798 }
10799 if (prev)
10800 ast_free(prev);
10801 ies.vars = NULL;
10802 ast_channel_datastore_add(c, variablestore);
10803 } else {
10804 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10805 if (variablestore)
10806 ast_datastore_free(variablestore);
10807 if (varlist)
10808 ast_free(varlist);
10809 }
10810 }
10811 }
10812 }
10813 break;
10814 case IAX_COMMAND_INVAL:
10815 iaxs[fr->callno]->error = ENOTCONN;
10816 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
10817 iax2_destroy(fr->callno);
10818 ast_debug(1, "Destroying call %d\n", fr->callno);
10819 break;
10820 case IAX_COMMAND_VNAK:
10821 ast_debug(1, "Received VNAK: resending outstanding frames\n");
10822
10823 vnak_retransmit(fr->callno, fr->iseqno);
10824 break;
10825 case IAX_COMMAND_REGREQ:
10826 case IAX_COMMAND_REGREL:
10827
10828 if (delayreject)
10829 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10830 if (register_verify(fr->callno, &sin, &ies)) {
10831 if (!iaxs[fr->callno]) {
10832 break;
10833 }
10834
10835 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
10836 break;
10837 }
10838 if (!iaxs[fr->callno]) {
10839 break;
10840 }
10841 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
10842 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
10843
10844 if (f.subclass == IAX_COMMAND_REGREL)
10845 memset(&sin, 0, sizeof(sin));
10846 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
10847 ast_log(LOG_WARNING, "Registry error\n");
10848 if (!iaxs[fr->callno]) {
10849 break;
10850 }
10851 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10852 ast_mutex_unlock(&iaxsl[fr->callno]);
10853 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10854 ast_mutex_lock(&iaxsl[fr->callno]);
10855 }
10856 break;
10857 }
10858 registry_authrequest(fr->callno);
10859 break;
10860 case IAX_COMMAND_REGACK:
10861 if (iax2_ack_registry(&ies, &sin, fr->callno))
10862 ast_log(LOG_WARNING, "Registration failure\n");
10863
10864 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10865 iax2_destroy(fr->callno);
10866 break;
10867 case IAX_COMMAND_REGREJ:
10868 if (iaxs[fr->callno]->reg) {
10869 if (authdebug) {
10870 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));
10871 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>");
10872 }
10873 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
10874 }
10875
10876 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10877 iax2_destroy(fr->callno);
10878 break;
10879 case IAX_COMMAND_REGAUTH:
10880
10881 if (registry_rerequest(&ies, fr->callno, &sin)) {
10882 memset(&ied0, 0, sizeof(ied0));
10883 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
10884 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
10885 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10886 }
10887 break;
10888 case IAX_COMMAND_TXREJ:
10889 iaxs[fr->callno]->transferring = 0;
10890 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10891 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
10892 if (iaxs[fr->callno]->bridgecallno) {
10893 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
10894 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
10895 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
10896 }
10897 }
10898 break;
10899 case IAX_COMMAND_TXREADY:
10900 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
10901 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
10902 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
10903 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
10904 else
10905 iaxs[fr->callno]->transferring = TRANSFER_READY;
10906 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
10907 if (iaxs[fr->callno]->bridgecallno) {
10908 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
10909 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
10910
10911 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
10912 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10913 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10914
10915 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
10916 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
10917
10918 memset(&ied0, 0, sizeof(ied0));
10919 memset(&ied1, 0, sizeof(ied1));
10920 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10921 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10922 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
10923 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
10924 } else {
10925 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
10926 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
10927
10928 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
10929 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
10930 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
10931 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
10932
10933
10934 stop_stuff(fr->callno);
10935 stop_stuff(iaxs[fr->callno]->bridgecallno);
10936
10937 memset(&ied0, 0, sizeof(ied0));
10938 memset(&ied1, 0, sizeof(ied1));
10939 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
10940 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
10941 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
10942 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
10943 }
10944
10945 }
10946 }
10947 }
10948 break;
10949 case IAX_COMMAND_TXREQ:
10950 try_transfer(iaxs[fr->callno], &ies);
10951 break;
10952 case IAX_COMMAND_TXCNT:
10953 if (iaxs[fr->callno]->transferring)
10954 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
10955 break;
10956 case IAX_COMMAND_TXREL:
10957
10958 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10959 complete_transfer(fr->callno, &ies);
10960 stop_stuff(fr->callno);
10961 break;
10962 case IAX_COMMAND_TXMEDIA:
10963 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
10964 AST_LIST_LOCK(&frame_queue);
10965 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
10966
10967 if ((fr->callno == cur->callno) && (cur->transfer))
10968 cur->retries = -1;
10969 }
10970 AST_LIST_UNLOCK(&frame_queue);
10971
10972 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
10973 }
10974 break;
10975 case IAX_COMMAND_RTKEY:
10976 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
10977 ast_log(LOG_WARNING,
10978 "we've been told to rotate our encryption key, "
10979 "but this isn't an encrypted call. bad things will happen.\n"
10980 );
10981 break;
10982 }
10983
10984 IAX_DEBUGDIGEST("Receiving", ies.challenge);
10985
10986 ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
10987 break;
10988 case IAX_COMMAND_DPREP:
10989 complete_dpreply(iaxs[fr->callno], &ies);
10990 break;
10991 case IAX_COMMAND_UNSUPPORT:
10992 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
10993 break;
10994 case IAX_COMMAND_FWDOWNL:
10995
10996 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
10997 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
10998 break;
10999 }
11000 memset(&ied0, 0, sizeof(ied0));
11001 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11002 if (res < 0)
11003 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11004 else if (res > 0)
11005 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11006 else
11007 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11008 break;
11009 case IAX_COMMAND_CALLTOKEN:
11010 {
11011 struct iax_frame *cur;
11012 int found = 0;
11013 AST_LIST_LOCK(&frame_queue);
11014 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
11015
11016
11017
11018 if (cur->callno == fr->callno) {
11019 found = 1;
11020 break;
11021 }
11022 }
11023 AST_LIST_UNLOCK(&frame_queue);
11024
11025
11026 if (cur && found && ies.calltoken && ies.calltokendata) {
11027 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11028 }
11029 break;
11030 }
11031 default:
11032 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
11033 memset(&ied0, 0, sizeof(ied0));
11034 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
11035 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11036 }
11037
11038 if (ies.vars) {
11039 ast_variables_destroy(ies.vars);
11040 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11041 ies.vars = NULL;
11042 }
11043
11044
11045 if ((f.subclass != IAX_COMMAND_ACK) &&
11046 (f.subclass != IAX_COMMAND_TXCNT) &&
11047 (f.subclass != IAX_COMMAND_TXACC) &&
11048 (f.subclass != IAX_COMMAND_INVAL) &&
11049 (f.subclass != IAX_COMMAND_VNAK)) {
11050 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11051 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11052 }
11053 ast_mutex_unlock(&iaxsl[fr->callno]);
11054 return 1;
11055 }
11056
11057 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11058 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11059 } else if (minivid) {
11060 f.frametype = AST_FRAME_VIDEO;
11061 if (iaxs[fr->callno]->videoformat > 0)
11062 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
11063 else {
11064 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11065 iax2_vnak(fr->callno);
11066 ast_variables_destroy(ies.vars);
11067 ast_mutex_unlock(&iaxsl[fr->callno]);
11068 return 1;
11069 }
11070 f.datalen = res - sizeof(*vh);
11071 if (f.datalen)
11072 f.data.ptr = thread->buf + sizeof(*vh);
11073 else
11074 f.data.ptr = NULL;
11075 #ifdef IAXTESTS
11076 if (test_resync) {
11077 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11078 } else
11079 #endif
11080 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11081 } else {
11082
11083 f.frametype = AST_FRAME_VOICE;
11084 if (iaxs[fr->callno]->voiceformat > 0)
11085 f.subclass = iaxs[fr->callno]->voiceformat;
11086 else {
11087 ast_debug(1, "Received mini frame before first full voice frame\n");
11088 iax2_vnak(fr->callno);
11089 ast_variables_destroy(ies.vars);
11090 ast_mutex_unlock(&iaxsl[fr->callno]);
11091 return 1;
11092 }
11093 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11094 if (f.datalen < 0) {
11095 ast_log(LOG_WARNING, "Datalen < 0?\n");
11096 ast_variables_destroy(ies.vars);
11097 ast_mutex_unlock(&iaxsl[fr->callno]);
11098 return 1;
11099 }
11100 if (f.datalen)
11101 f.data.ptr = thread->buf + sizeof(*mh);
11102 else
11103 f.data.ptr = NULL;
11104 #ifdef IAXTESTS
11105 if (test_resync) {
11106 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11107 } else
11108 #endif
11109 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11110
11111 }
11112
11113 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11114 ast_variables_destroy(ies.vars);
11115 ast_mutex_unlock(&iaxsl[fr->callno]);
11116 return 1;
11117 }
11118
11119 f.src = "IAX2";
11120 f.mallocd = 0;
11121 f.offset = 0;
11122 f.len = 0;
11123 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11124 f.samples = ast_codec_get_samples(&f);
11125
11126 if (f.subclass == AST_FORMAT_SLINEAR)
11127 ast_frame_byteswap_be(&f);
11128 } else
11129 f.samples = 0;
11130 iax_frame_wrap(fr, &f);
11131
11132
11133 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11134
11135 fr->outoforder = 0;
11136 } else {
11137 if (iaxdebug && iaxs[fr->callno])
11138 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);
11139 fr->outoforder = -1;
11140 }
11141 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11142 duped_fr = iaxfrdup2(fr);
11143 if (duped_fr) {
11144 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11145 }
11146 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11147 iaxs[fr->callno]->last = fr->ts;
11148 #if 1
11149 if (iaxdebug)
11150 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11151 #endif
11152 }
11153
11154
11155 ast_variables_destroy(ies.vars);
11156 ast_mutex_unlock(&iaxsl[fr->callno]);
11157 return 1;
11158 }
11159
11160
11161 static void iax2_process_thread_cleanup(void *data)
11162 {
11163 struct iax2_thread *thread = data;
11164 ast_mutex_destroy(&thread->lock);
11165 ast_cond_destroy(&thread->cond);
11166 ast_mutex_destroy(&thread->init_lock);
11167 ast_cond_destroy(&thread->init_cond);
11168 ast_free(thread);
11169 ast_atomic_dec_and_test(&iaxactivethreadcount);
11170 }
11171
11172 static void *iax2_process_thread(void *data)
11173 {
11174 struct iax2_thread *thread = data;
11175 struct timeval wait;
11176 struct timespec ts;
11177 int put_into_idle = 0;
11178 int first_time = 1;
11179 int old_state;
11180
11181 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11182
11183 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11184 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11185
11186 for (;;) {
11187
11188 ast_mutex_lock(&thread->lock);
11189
11190 if (thread->stop) {
11191 ast_mutex_unlock(&thread->lock);
11192 break;
11193 }
11194
11195
11196 if (first_time) {
11197 signal_condition(&thread->init_lock, &thread->init_cond);
11198 first_time = 0;
11199 }
11200
11201
11202 if (put_into_idle) {
11203 insert_idle_thread(thread);
11204 }
11205
11206 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11207 struct iax2_thread *t = NULL;
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
11214
11215 if (!put_into_idle || thread->stop) {
11216 ast_mutex_unlock(&thread->lock);
11217 break;
11218 }
11219 AST_LIST_LOCK(&dynamic_list);
11220
11221 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11222 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11223 AST_LIST_UNLOCK(&dynamic_list);
11224 if (t) {
11225
11226
11227
11228 ast_mutex_unlock(&thread->lock);
11229 break;
11230 }
11231
11232
11233
11234 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11235 ts.tv_sec = wait.tv_sec;
11236 ts.tv_nsec = wait.tv_usec * 1000;
11237 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11238 ast_mutex_unlock(&thread->lock);
11239 break;
11240 }
11241 }
11242 } else {
11243 ast_cond_wait(&thread->cond, &thread->lock);
11244 }
11245
11246
11247 put_into_idle = 1;
11248
11249 ast_mutex_unlock(&thread->lock);
11250
11251 if (thread->stop) {
11252 break;
11253 }
11254
11255 if (thread->iostate == IAX_IOSTATE_IDLE)
11256 continue;
11257
11258
11259 switch (thread->iostate) {
11260 case IAX_IOSTATE_READY:
11261 thread->actions++;
11262 thread->iostate = IAX_IOSTATE_PROCESSING;
11263 socket_process(thread);
11264 handle_deferred_full_frames(thread);
11265 break;
11266 case IAX_IOSTATE_SCHEDREADY:
11267 thread->actions++;
11268 thread->iostate = IAX_IOSTATE_PROCESSING;
11269 #ifdef SCHED_MULTITHREADED
11270 thread->schedfunc(thread->scheddata);
11271 #endif
11272 default:
11273 break;
11274 }
11275 time(&thread->checktime);
11276 thread->iostate = IAX_IOSTATE_IDLE;
11277 #ifdef DEBUG_SCHED_MULTITHREAD
11278 thread->curfunc[0]='\0';
11279 #endif
11280
11281
11282
11283
11284 AST_LIST_LOCK(&active_list);
11285 AST_LIST_REMOVE(&active_list, thread, list);
11286 AST_LIST_UNLOCK(&active_list);
11287
11288
11289 handle_deferred_full_frames(thread);
11290 }
11291
11292
11293
11294
11295
11296 AST_LIST_LOCK(&idle_list);
11297 AST_LIST_REMOVE(&idle_list, thread, list);
11298 AST_LIST_UNLOCK(&idle_list);
11299
11300 AST_LIST_LOCK(&dynamic_list);
11301 AST_LIST_REMOVE(&dynamic_list, thread, list);
11302 AST_LIST_UNLOCK(&dynamic_list);
11303
11304
11305
11306
11307 pthread_cleanup_pop(1);
11308 return NULL;
11309 }
11310
11311 static int iax2_do_register(struct iax2_registry *reg)
11312 {
11313 struct iax_ie_data ied;
11314 if (iaxdebug)
11315 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11316
11317 if (reg->dnsmgr &&
11318 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
11319
11320 ast_dnsmgr_refresh(reg->dnsmgr);
11321 }
11322
11323
11324
11325
11326
11327 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11328 int callno = reg->callno;
11329 ast_mutex_lock(&iaxsl[callno]);
11330 iax2_destroy(callno);
11331 ast_mutex_unlock(&iaxsl[callno]);
11332 reg->callno = 0;
11333 }
11334 if (!reg->addr.sin_addr.s_addr) {
11335 if (iaxdebug)
11336 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11337
11338 reg->expire = iax2_sched_replace(reg->expire, sched,
11339 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11340 return -1;
11341 }
11342
11343 if (!reg->callno) {
11344 ast_debug(3, "Allocate call number\n");
11345 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
11346 if (reg->callno < 1) {
11347 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11348 return -1;
11349 } else
11350 ast_debug(3, "Registration created on call %d\n", reg->callno);
11351 iaxs[reg->callno]->reg = reg;
11352 ast_mutex_unlock(&iaxsl[reg->callno]);
11353 }
11354
11355 reg->expire = iax2_sched_replace(reg->expire, sched,
11356 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11357
11358 memset(&ied, 0, sizeof(ied));
11359 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11360 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11361 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11362 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11363 reg->regstate = REG_STATE_REGSENT;
11364 return 0;
11365 }
11366
11367 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
11368 {
11369
11370
11371 struct iax_ie_data provdata;
11372 struct iax_ie_data ied;
11373 unsigned int sig;
11374 struct sockaddr_in sin;
11375 int callno;
11376 struct create_addr_info cai;
11377
11378 memset(&cai, 0, sizeof(cai));
11379
11380 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11381
11382 if (iax_provision_build(&provdata, &sig, template, force)) {
11383 ast_debug(1, "No provisioning found for template '%s'\n", template);
11384 return 0;
11385 }
11386
11387 if (end) {
11388 memcpy(&sin, end, sizeof(sin));
11389 cai.sockfd = sockfd;
11390 } else if (create_addr(dest, NULL, &sin, &cai))
11391 return -1;
11392
11393
11394 memset(&ied, 0, sizeof(ied));
11395 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11396
11397 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11398 if (!callno)
11399 return -1;
11400
11401 if (iaxs[callno]) {
11402
11403 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11404 sched, 15000, auto_hangup, (void *)(long)callno);
11405 ast_set_flag(iaxs[callno], IAX_PROVISION);
11406
11407 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11408 }
11409 ast_mutex_unlock(&iaxsl[callno]);
11410
11411 return 1;
11412 }
11413
11414 static char *papp = "IAX2Provision";
11415
11416
11417
11418
11419 static int iax2_prov_app(struct ast_channel *chan, void *data)
11420 {
11421 int res;
11422 char *sdata;
11423 char *opts;
11424 int force =0;
11425 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11426 if (ast_strlen_zero(data))
11427 data = "default";
11428 sdata = ast_strdupa(data);
11429 opts = strchr(sdata, '|');
11430 if (opts)
11431 *opts='\0';
11432
11433 if (chan->tech != &iax2_tech) {
11434 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11435 return -1;
11436 }
11437 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11438 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11439 return -1;
11440 }
11441 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11442 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11443 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11444 sdata, res);
11445 return res;
11446 }
11447
11448 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11449 {
11450 int force = 0;
11451 int res;
11452
11453 switch (cmd) {
11454 case CLI_INIT:
11455 e->command = "iax2 provision";
11456 e->usage =
11457 "Usage: iax2 provision <host> <template> [forced]\n"
11458 " Provisions the given peer or IP address using a template\n"
11459 " matching either 'template' or '*' if the template is not\n"
11460 " found. If 'forced' is specified, even empty provisioning\n"
11461 " fields will be provisioned as empty fields.\n";
11462 return NULL;
11463 case CLI_GENERATE:
11464 if (a->pos == 3)
11465 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11466 return NULL;
11467 }
11468
11469 if (a->argc < 4)
11470 return CLI_SHOWUSAGE;
11471 if (a->argc > 4) {
11472 if (!strcasecmp(a->argv[4], "forced"))
11473 force = 1;
11474 else
11475 return CLI_SHOWUSAGE;
11476 }
11477 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11478 if (res < 0)
11479 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11480 else if (res < 1)
11481 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11482 else
11483 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11484 return CLI_SUCCESS;
11485 }
11486
11487 static void __iax2_poke_noanswer(const void *data)
11488 {
11489 struct iax2_peer *peer = (struct iax2_peer *)data;
11490 int callno;
11491
11492 if (peer->lastms > -1) {
11493 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11494 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11495 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11496 }
11497 if ((callno = peer->callno) > 0) {
11498 ast_mutex_lock(&iaxsl[callno]);
11499 iax2_destroy(callno);
11500 ast_mutex_unlock(&iaxsl[callno]);
11501 }
11502 peer->callno = 0;
11503 peer->lastms = -1;
11504
11505 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11506 if (peer->pokeexpire == -1)
11507 peer_unref(peer);
11508 }
11509
11510 static int iax2_poke_noanswer(const void *data)
11511 {
11512 struct iax2_peer *peer = (struct iax2_peer *)data;
11513 peer->pokeexpire = -1;
11514 #ifdef SCHED_MULTITHREADED
11515 if (schedule_action(__iax2_poke_noanswer, data))
11516 #endif
11517 __iax2_poke_noanswer(data);
11518 peer_unref(peer);
11519 return 0;
11520 }
11521
11522 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11523 {
11524 struct iax2_peer *peer = obj;
11525
11526 iax2_poke_peer(peer, 0);
11527
11528 return 0;
11529 }
11530
11531 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11532 {
11533 int callno;
11534 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
11535
11536
11537 peer->lastms = 0;
11538 peer->historicms = 0;
11539 peer->pokeexpire = -1;
11540 peer->callno = 0;
11541 return 0;
11542 }
11543
11544
11545 if ((callno = peer->callno) > 0) {
11546 ast_log(LOG_NOTICE, "Still have a callno...\n");
11547 ast_mutex_lock(&iaxsl[callno]);
11548 iax2_destroy(callno);
11549 ast_mutex_unlock(&iaxsl[callno]);
11550 }
11551 if (heldcall)
11552 ast_mutex_unlock(&iaxsl[heldcall]);
11553 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
11554 if (heldcall)
11555 ast_mutex_lock(&iaxsl[heldcall]);
11556 if (peer->callno < 1) {
11557 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11558 return -1;
11559 }
11560
11561
11562 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11563 iaxs[peer->callno]->peerpoke = peer;
11564
11565 if (peer->pokeexpire > -1) {
11566 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
11567 peer->pokeexpire = -1;
11568 peer_unref(peer);
11569 }
11570 }
11571
11572
11573
11574 if (peer->lastms < 0)
11575 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11576 else
11577 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11578
11579 if (peer->pokeexpire == -1)
11580 peer_unref(peer);
11581
11582
11583 ast_mutex_lock(&iaxsl[callno]);
11584 if (iaxs[callno]) {
11585 struct iax_ie_data ied = {
11586 .buf = { 0 },
11587 .pos = 0,
11588 };
11589 add_empty_calltoken_ie(iaxs[callno], &ied);
11590 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11591 }
11592 ast_mutex_unlock(&iaxsl[callno]);
11593
11594 return 0;
11595 }
11596
11597 static void free_context(struct iax2_context *con)
11598 {
11599 struct iax2_context *conl;
11600 while(con) {
11601 conl = con;
11602 con = con->next;
11603 ast_free(conl);
11604 }
11605 }
11606
11607 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
11608 {
11609 int callno;
11610 int res;
11611 int fmt, native;
11612 struct sockaddr_in sin;
11613 struct ast_channel *c;
11614 struct parsed_dial_string pds;
11615 struct create_addr_info cai;
11616 char *tmpstr;
11617
11618 memset(&pds, 0, sizeof(pds));
11619 tmpstr = ast_strdupa(data);
11620 parse_dial_string(tmpstr, &pds);
11621
11622 if (ast_strlen_zero(pds.peer)) {
11623 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
11624 return NULL;
11625 }
11626
11627 memset(&cai, 0, sizeof(cai));
11628 cai.capability = iax2_capability;
11629
11630 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11631
11632
11633 if (create_addr(pds.peer, NULL, &sin, &cai)) {
11634 *cause = AST_CAUSE_UNREGISTERED;
11635 return NULL;
11636 }
11637
11638 if (pds.port)
11639 sin.sin_port = htons(atoi(pds.port));
11640
11641 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11642 if (callno < 1) {
11643 ast_log(LOG_WARNING, "Unable to create call\n");
11644 *cause = AST_CAUSE_CONGESTION;
11645 return NULL;
11646 }
11647
11648
11649 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
11650 if (ast_test_flag(&cai, IAX_TRUNK)) {
11651 int new_callno;
11652 if ((new_callno = make_trunk(callno, 1)) != -1)
11653 callno = new_callno;
11654 }
11655 iaxs[callno]->maxtime = cai.maxtime;
11656 if (cai.found)
11657 ast_string_field_set(iaxs[callno], host, pds.peer);
11658
11659 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
11660
11661 ast_mutex_unlock(&iaxsl[callno]);
11662
11663 if (c) {
11664
11665 if (c->nativeformats & format)
11666 c->nativeformats &= format;
11667 else {
11668 native = c->nativeformats;
11669 fmt = format;
11670 res = ast_translator_best_choice(&fmt, &native);
11671 if (res < 0) {
11672 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
11673 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
11674 ast_hangup(c);
11675 return NULL;
11676 }
11677 c->nativeformats = native;
11678 }
11679 c->readformat = ast_best_codec(c->nativeformats);
11680 c->writeformat = c->readformat;
11681 }
11682
11683 return c;
11684 }
11685
11686 static void *network_thread(void *ignore)
11687 {
11688
11689
11690 int res, count, wakeup;
11691 struct iax_frame *f;
11692
11693 if (timer)
11694 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
11695
11696 for(;;) {
11697 pthread_testcancel();
11698
11699
11700
11701 AST_LIST_LOCK(&frame_queue);
11702 count = 0;
11703 wakeup = -1;
11704 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
11705 if (f->sentyet)
11706 continue;
11707
11708
11709 if (ast_mutex_trylock(&iaxsl[f->callno])) {
11710 wakeup = 1;
11711 continue;
11712 }
11713
11714 f->sentyet = 1;
11715
11716 if (iaxs[f->callno]) {
11717 send_packet(f);
11718 count++;
11719 }
11720
11721 ast_mutex_unlock(&iaxsl[f->callno]);
11722
11723 if (f->retries < 0) {
11724
11725 AST_LIST_REMOVE_CURRENT(list);
11726
11727 iax_frame_free(f);
11728 } else {
11729
11730 f->retries++;
11731 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
11732 }
11733 }
11734 AST_LIST_TRAVERSE_SAFE_END;
11735 AST_LIST_UNLOCK(&frame_queue);
11736
11737 pthread_testcancel();
11738 if (count >= 20)
11739 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
11740
11741
11742 res = ast_io_wait(io, wakeup);
11743 if (res >= 0) {
11744 if (res >= 20)
11745 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
11746 }
11747 }
11748 return NULL;
11749 }
11750
11751 static int start_network_thread(void)
11752 {
11753 struct iax2_thread *thread;
11754 int threadcount = 0;
11755 int x;
11756 for (x = 0; x < iaxthreadcount; x++) {
11757 thread = ast_calloc(1, sizeof(*thread));
11758 if (thread) {
11759 thread->type = IAX_THREAD_TYPE_POOL;
11760 thread->threadnum = ++threadcount;
11761 ast_mutex_init(&thread->lock);
11762 ast_cond_init(&thread->cond, NULL);
11763 ast_mutex_init(&thread->init_lock);
11764 ast_cond_init(&thread->init_cond, NULL);
11765 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
11766 ast_log(LOG_WARNING, "Failed to create new thread!\n");
11767 ast_mutex_destroy(&thread->lock);
11768 ast_cond_destroy(&thread->cond);
11769 ast_mutex_destroy(&thread->init_lock);
11770 ast_cond_destroy(&thread->init_cond);
11771 ast_free(thread);
11772 thread = NULL;
11773 continue;
11774 }
11775 AST_LIST_LOCK(&idle_list);
11776 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
11777 AST_LIST_UNLOCK(&idle_list);
11778 }
11779 }
11780 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
11781 ast_verb(2, "%d helper threads started\n", threadcount);
11782 return 0;
11783 }
11784
11785 static struct iax2_context *build_context(const char *context)
11786 {
11787 struct iax2_context *con;
11788
11789 if ((con = ast_calloc(1, sizeof(*con))))
11790 ast_copy_string(con->context, context, sizeof(con->context));
11791
11792 return con;
11793 }
11794
11795 static int get_auth_methods(const char *value)
11796 {
11797 int methods = 0;
11798 if (strstr(value, "rsa"))
11799 methods |= IAX_AUTH_RSA;
11800 if (strstr(value, "md5"))
11801 methods |= IAX_AUTH_MD5;
11802 if (strstr(value, "plaintext"))
11803 methods |= IAX_AUTH_PLAINTEXT;
11804 return methods;
11805 }
11806
11807
11808
11809
11810
11811 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
11812 {
11813 int sd;
11814 int res;
11815
11816 sd = socket(AF_INET, SOCK_DGRAM, 0);
11817 if (sd < 0) {
11818 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
11819 return -1;
11820 }
11821
11822 res = bind(sd, sa, salen);
11823 if (res < 0) {
11824 ast_debug(1, "Can't bind: %s\n", strerror(errno));
11825 close(sd);
11826 return 1;
11827 }
11828
11829 close(sd);
11830 return 0;
11831 }
11832
11833
11834
11835
11836 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
11837 {
11838 struct sockaddr_in sin;
11839 int nonlocal = 1;
11840 int port = IAX_DEFAULT_PORTNO;
11841 int sockfd = defaultsockfd;
11842 char *tmp;
11843 char *addr;
11844 char *portstr;
11845
11846 if (!(tmp = ast_strdupa(srcaddr)))
11847 return -1;
11848
11849 addr = strsep(&tmp, ":");
11850 portstr = tmp;
11851
11852 if (portstr) {
11853 port = atoi(portstr);
11854 if (port < 1)
11855 port = IAX_DEFAULT_PORTNO;
11856 }
11857
11858 if (!ast_get_ip(&sin, addr)) {
11859 struct ast_netsock *sock;
11860 int res;
11861
11862 sin.sin_port = 0;
11863 sin.sin_family = AF_INET;
11864 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
11865 if (res == 0) {
11866
11867 sin.sin_port = htons(port);
11868 if (!(sock = ast_netsock_find(netsock, &sin)))
11869 sock = ast_netsock_find(outsock, &sin);
11870 if (sock) {
11871 sockfd = ast_netsock_sockfd(sock);
11872 nonlocal = 0;
11873 } else {
11874 unsigned int orig_saddr = sin.sin_addr.s_addr;
11875
11876 sin.sin_addr.s_addr = INADDR_ANY;
11877 if (ast_netsock_find(netsock, &sin)) {
11878 sin.sin_addr.s_addr = orig_saddr;
11879 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
11880 if (sock) {
11881 sockfd = ast_netsock_sockfd(sock);
11882 ast_netsock_unref(sock);
11883 nonlocal = 0;
11884 } else {
11885 nonlocal = 2;
11886 }
11887 }
11888 }
11889 }
11890 }
11891
11892 peer->sockfd = sockfd;
11893
11894 if (nonlocal == 1) {
11895 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
11896 srcaddr, peer->name);
11897 return -1;
11898 } else if (nonlocal == 2) {
11899 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
11900 srcaddr, peer->name);
11901 return -1;
11902 } else {
11903 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
11904 return 0;
11905 }
11906 }
11907
11908 static void peer_destructor(void *obj)
11909 {
11910 struct iax2_peer *peer = obj;
11911 int callno = peer->callno;
11912
11913 ast_free_ha(peer->ha);
11914
11915 if (callno > 0) {
11916 ast_mutex_lock(&iaxsl[callno]);
11917 iax2_destroy(callno);
11918 ast_mutex_unlock(&iaxsl[callno]);
11919 }
11920
11921 register_peer_exten(peer, 0);
11922
11923 if (peer->dnsmgr)
11924 ast_dnsmgr_release(peer->dnsmgr);
11925
11926 if (peer->mwi_event_sub)
11927 ast_event_unsubscribe(peer->mwi_event_sub);
11928
11929 ast_string_field_free_memory(peer);
11930 }
11931
11932
11933 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
11934 {
11935 struct iax2_peer *peer = NULL;
11936 struct ast_ha *oldha = NULL;
11937 int maskfound = 0;
11938 int found = 0;
11939 int firstpass = 1;
11940 struct iax2_peer tmp_peer = {
11941 .name = name,
11942 };
11943
11944 if (!temponly) {
11945 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
11946 if (peer && !ast_test_flag(peer, IAX_DELME))
11947 firstpass = 0;
11948 }
11949
11950 if (peer) {
11951 found++;
11952 if (firstpass) {
11953 oldha = peer->ha;
11954 peer->ha = NULL;
11955 }
11956 unlink_peer(peer);
11957 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
11958 peer->expire = -1;
11959 peer->pokeexpire = -1;
11960 peer->sockfd = defaultsockfd;
11961 if (ast_string_field_init(peer, 32))
11962 peer = peer_unref(peer);
11963 }
11964
11965 if (peer) {
11966 if (firstpass) {
11967 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT);
11968 peer->encmethods = iax2_encryption;
11969 peer->adsi = adsi;
11970 ast_string_field_set(peer,secret,"");
11971 if (!found) {
11972 ast_string_field_set(peer, name, name);
11973 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
11974 peer->expiry = min_reg_expire;
11975 }
11976 peer->prefs = prefs;
11977 peer->capability = iax2_capability;
11978 peer->smoothing = 0;
11979 peer->pokefreqok = DEFAULT_FREQ_OK;
11980 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
11981 peer->maxcallno = 0;
11982 peercnt_modify(0, 0, &peer->addr);
11983 peer->calltoken_required = CALLTOKEN_DEFAULT;
11984 ast_string_field_set(peer,context,"");
11985 ast_string_field_set(peer,peercontext,"");
11986 ast_clear_flag(peer, IAX_HASCALLERID);
11987 ast_string_field_set(peer, cid_name, "");
11988 ast_string_field_set(peer, cid_num, "");
11989 ast_string_field_set(peer, mohinterpret, mohinterpret);
11990 ast_string_field_set(peer, mohsuggest, mohsuggest);
11991 }
11992
11993 if (!v) {
11994 v = alt;
11995 alt = NULL;
11996 }
11997 while(v) {
11998 if (!strcasecmp(v->name, "secret")) {
11999 ast_string_field_set(peer, secret, v->value);
12000 } else if (!strcasecmp(v->name, "mailbox")) {
12001 ast_string_field_set(peer, mailbox, v->value);
12002 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12003 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12004 ast_string_field_set(peer, mailbox, name);
12005 }
12006 } else if (!strcasecmp(v->name, "mohinterpret")) {
12007 ast_string_field_set(peer, mohinterpret, v->value);
12008 } else if (!strcasecmp(v->name, "mohsuggest")) {
12009 ast_string_field_set(peer, mohsuggest, v->value);
12010 } else if (!strcasecmp(v->name, "dbsecret")) {
12011 ast_string_field_set(peer, dbsecret, v->value);
12012 } else if (!strcasecmp(v->name, "trunk")) {
12013 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
12014 if (ast_test_flag(peer, IAX_TRUNK) && !timer) {
12015 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12016 ast_clear_flag(peer, IAX_TRUNK);
12017 }
12018 } else if (!strcasecmp(v->name, "auth")) {
12019 peer->authmethods = get_auth_methods(v->value);
12020 } else if (!strcasecmp(v->name, "encryption")) {
12021 peer->encmethods |= get_encrypt_methods(v->value);
12022 if (!peer->encmethods) {
12023 ast_clear_flag(peer, IAX_FORCE_ENCRYPT);
12024 }
12025 } else if (!strcasecmp(v->name, "forceencryption")) {
12026 if (ast_false(v->value)) {
12027 ast_clear_flag(peer, IAX_FORCE_ENCRYPT);
12028 } else {
12029 peer->encmethods |= get_encrypt_methods(v->value);
12030 if (peer->encmethods) {
12031 ast_set_flag(peer, IAX_FORCE_ENCRYPT);
12032 }
12033 }
12034 } else if (!strcasecmp(v->name, "transfer")) {
12035 if (!strcasecmp(v->value, "mediaonly")) {
12036 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12037 } else if (ast_true(v->value)) {
12038 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12039 } else
12040 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12041 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12042 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
12043 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12044 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12045 } else if (!strcasecmp(v->name, "host")) {
12046 if (!strcasecmp(v->value, "dynamic")) {
12047
12048 ast_set_flag(peer, IAX_DYNAMIC);
12049 if (!found) {
12050
12051
12052 memset(&peer->addr.sin_addr, 0, 4);
12053 if (peer->addr.sin_port) {
12054
12055 peer->defaddr.sin_port = peer->addr.sin_port;
12056 peer->addr.sin_port = 0;
12057 }
12058 }
12059 } else {
12060
12061 ast_sched_thread_del(sched, peer->expire);
12062 ast_clear_flag(peer, IAX_DYNAMIC);
12063 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12064 return peer_unref(peer);
12065 if (!peer->addr.sin_port)
12066 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
12067 }
12068 if (!maskfound)
12069 inet_aton("255.255.255.255", &peer->mask);
12070 } else if (!strcasecmp(v->name, "defaultip")) {
12071 if (ast_get_ip(&peer->defaddr, v->value))
12072 return peer_unref(peer);
12073 } else if (!strcasecmp(v->name, "sourceaddress")) {
12074 peer_set_srcaddr(peer, v->value);
12075 } else if (!strcasecmp(v->name, "permit") ||
12076 !strcasecmp(v->name, "deny")) {
12077 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12078 } else if (!strcasecmp(v->name, "mask")) {
12079 maskfound++;
12080 inet_aton(v->value, &peer->mask);
12081 } else if (!strcasecmp(v->name, "context")) {
12082 ast_string_field_set(peer, context, v->value);
12083 } else if (!strcasecmp(v->name, "regexten")) {
12084 ast_string_field_set(peer, regexten, v->value);
12085 } else if (!strcasecmp(v->name, "peercontext")) {
12086 ast_string_field_set(peer, peercontext, v->value);
12087 } else if (!strcasecmp(v->name, "port")) {
12088 if (ast_test_flag(peer, IAX_DYNAMIC))
12089 peer->defaddr.sin_port = htons(atoi(v->value));
12090 else
12091 peer->addr.sin_port = htons(atoi(v->value));
12092 } else if (!strcasecmp(v->name, "username")) {
12093 ast_string_field_set(peer, username, v->value);
12094 } else if (!strcasecmp(v->name, "allow")) {
12095 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12096 } else if (!strcasecmp(v->name, "disallow")) {
12097 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12098 } else if (!strcasecmp(v->name, "callerid")) {
12099 if (!ast_strlen_zero(v->value)) {
12100 char name2[80];
12101 char num2[80];
12102 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12103 ast_string_field_set(peer, cid_name, name2);
12104 ast_string_field_set(peer, cid_num, num2);
12105 } else {
12106 ast_string_field_set(peer, cid_name, "");
12107 ast_string_field_set(peer, cid_num, "");
12108 }
12109 ast_set_flag(peer, IAX_HASCALLERID);
12110 } else if (!strcasecmp(v->name, "fullname")) {
12111 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12112 ast_set_flag(peer, IAX_HASCALLERID);
12113 } else if (!strcasecmp(v->name, "cid_number")) {
12114 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12115 ast_set_flag(peer, IAX_HASCALLERID);
12116 } else if (!strcasecmp(v->name, "sendani")) {
12117 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
12118 } else if (!strcasecmp(v->name, "inkeys")) {
12119 ast_string_field_set(peer, inkeys, v->value);
12120 } else if (!strcasecmp(v->name, "outkey")) {
12121 ast_string_field_set(peer, outkey, v->value);
12122 } else if (!strcasecmp(v->name, "qualify")) {
12123 if (!strcasecmp(v->value, "no")) {
12124 peer->maxms = 0;
12125 } else if (!strcasecmp(v->value, "yes")) {
12126 peer->maxms = DEFAULT_MAXMS;
12127 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12128 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);
12129 peer->maxms = 0;
12130 }
12131 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12132 peer->smoothing = ast_true(v->value);
12133 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12134 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12135 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);
12136 }
12137 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12138 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12139 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);
12140 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12141 } else if (!strcasecmp(v->name, "timezone")) {
12142 ast_string_field_set(peer, zonetag, v->value);
12143 } else if (!strcasecmp(v->name, "adsi")) {
12144 peer->adsi = ast_true(v->value);
12145 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12146 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12147 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12148 } else {
12149 peercnt_modify(1, peer->maxcallno, &peer->addr);
12150 }
12151 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12152
12153 if (ast_false(v->value)) {
12154 peer->calltoken_required = CALLTOKEN_NO;
12155 } else if (!strcasecmp(v->value, "auto")) {
12156 peer->calltoken_required = CALLTOKEN_AUTO;
12157 } else if (ast_true(v->value)) {
12158 peer->calltoken_required = CALLTOKEN_YES;
12159 } else {
12160 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12161 }
12162 }
12163
12164 v = v->next;
12165 if (!v) {
12166 v = alt;
12167 alt = NULL;
12168 }
12169 }
12170 if (!peer->authmethods)
12171 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12172 ast_clear_flag(peer, IAX_DELME);
12173
12174 peer->addr.sin_family = AF_INET;
12175 }
12176
12177 if (oldha)
12178 ast_free_ha(oldha);
12179
12180 if (!ast_strlen_zero(peer->mailbox)) {
12181 char *mailbox, *context;
12182 context = mailbox = ast_strdupa(peer->mailbox);
12183 strsep(&context, "@");
12184 if (ast_strlen_zero(context))
12185 context = "default";
12186 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
12187 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12188 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12189 AST_EVENT_IE_END);
12190 }
12191
12192 return peer;
12193 }
12194
12195 static void user_destructor(void *obj)
12196 {
12197 struct iax2_user *user = obj;
12198
12199 ast_free_ha(user->ha);
12200 free_context(user->contexts);
12201 if(user->vars) {
12202 ast_variables_destroy(user->vars);
12203 user->vars = NULL;
12204 }
12205 ast_string_field_free_memory(user);
12206 }
12207
12208
12209 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12210 {
12211 struct iax2_user *user = NULL;
12212 struct iax2_context *con, *conl = NULL;
12213 struct ast_ha *oldha = NULL;
12214 struct iax2_context *oldcon = NULL;
12215 int format;
12216 int firstpass=1;
12217 int oldcurauthreq = 0;
12218 char *varname = NULL, *varval = NULL;
12219 struct ast_variable *tmpvar = NULL;
12220 struct iax2_user tmp_user = {
12221 .name = name,
12222 };
12223
12224 if (!temponly) {
12225 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12226 if (user && !ast_test_flag(user, IAX_DELME))
12227 firstpass = 0;
12228 }
12229
12230 if (user) {
12231 if (firstpass) {
12232 oldcurauthreq = user->curauthreq;
12233 oldha = user->ha;
12234 oldcon = user->contexts;
12235 user->ha = NULL;
12236 user->contexts = NULL;
12237 }
12238
12239 ao2_unlink(users, user);
12240 } else {
12241 user = ao2_alloc(sizeof(*user), user_destructor);
12242 }
12243
12244 if (user) {
12245 if (firstpass) {
12246 ast_string_field_free_memory(user);
12247 memset(user, 0, sizeof(struct iax2_user));
12248 if (ast_string_field_init(user, 32)) {
12249 user = user_unref(user);
12250 goto cleanup;
12251 }
12252 user->maxauthreq = maxauthreq;
12253 user->curauthreq = oldcurauthreq;
12254 user->prefs = prefs;
12255 user->capability = iax2_capability;
12256 user->encmethods = iax2_encryption;
12257 user->adsi = adsi;
12258 user->calltoken_required = CALLTOKEN_DEFAULT;
12259 ast_string_field_set(user, name, name);
12260 ast_string_field_set(user, language, language);
12261 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
12262 ast_clear_flag(user, IAX_HASCALLERID);
12263 ast_string_field_set(user, cid_name, "");
12264 ast_string_field_set(user, cid_num, "");
12265 ast_string_field_set(user, accountcode, accountcode);
12266 ast_string_field_set(user, mohinterpret, mohinterpret);
12267 ast_string_field_set(user, mohsuggest, mohsuggest);
12268 }
12269 if (!v) {
12270 v = alt;
12271 alt = NULL;
12272 }
12273 while(v) {
12274 if (!strcasecmp(v->name, "context")) {
12275 con = build_context(v->value);
12276 if (con) {
12277 if (conl)
12278 conl->next = con;
12279 else
12280 user->contexts = con;
12281 conl = con;
12282 }
12283 } else if (!strcasecmp(v->name, "permit") ||
12284 !strcasecmp(v->name, "deny")) {
12285 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12286 } else if (!strcasecmp(v->name, "setvar")) {
12287 varname = ast_strdupa(v->value);
12288 if (varname && (varval = strchr(varname,'='))) {
12289 *varval = '\0';
12290 varval++;
12291 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12292 tmpvar->next = user->vars;
12293 user->vars = tmpvar;
12294 }
12295 }
12296 } else if (!strcasecmp(v->name, "allow")) {
12297 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12298 } else if (!strcasecmp(v->name, "disallow")) {
12299 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12300 } else if (!strcasecmp(v->name, "trunk")) {
12301 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
12302 if (ast_test_flag(user, IAX_TRUNK) && !timer) {
12303 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12304 ast_clear_flag(user, IAX_TRUNK);
12305 }
12306 } else if (!strcasecmp(v->name, "auth")) {
12307 user->authmethods = get_auth_methods(v->value);
12308 } else if (!strcasecmp(v->name, "encryption")) {
12309 user->encmethods |= get_encrypt_methods(v->value);
12310 if (!user->encmethods) {
12311 ast_clear_flag(user, IAX_FORCE_ENCRYPT);
12312 }
12313 } else if (!strcasecmp(v->name, "forceencryption")) {
12314 if (ast_false(v->value)) {
12315 ast_clear_flag(user, IAX_FORCE_ENCRYPT);
12316 } else {
12317 user->encmethods |= get_encrypt_methods(v->value);
12318 if (user->encmethods) {
12319 ast_set_flag(user, IAX_FORCE_ENCRYPT);
12320 }
12321 }
12322 } else if (!strcasecmp(v->name, "transfer")) {
12323 if (!strcasecmp(v->value, "mediaonly")) {
12324 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12325 } else if (ast_true(v->value)) {
12326 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12327 } else
12328 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12329 } else if (!strcasecmp(v->name, "codecpriority")) {
12330 if(!strcasecmp(v->value, "caller"))
12331 ast_set_flag(user, IAX_CODEC_USER_FIRST);
12332 else if(!strcasecmp(v->value, "disabled"))
12333 ast_set_flag(user, IAX_CODEC_NOPREFS);
12334 else if(!strcasecmp(v->value, "reqonly")) {
12335 ast_set_flag(user, IAX_CODEC_NOCAP);
12336 ast_set_flag(user, IAX_CODEC_NOPREFS);
12337 }
12338 } else if (!strcasecmp(v->name, "immediate")) {
12339 ast_set2_flag(user, ast_true(v->value), IAX_IMMEDIATE);
12340 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12341 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
12342 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12343 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12344 } else if (!strcasecmp(v->name, "dbsecret")) {
12345 ast_string_field_set(user, dbsecret, v->value);
12346 } else if (!strcasecmp(v->name, "secret")) {
12347 if (!ast_strlen_zero(user->secret)) {
12348 char *old = ast_strdupa(user->secret);
12349
12350 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12351 } else
12352 ast_string_field_set(user, secret, v->value);
12353 } else if (!strcasecmp(v->name, "callerid")) {
12354 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12355 char name2[80];
12356 char num2[80];
12357 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12358 ast_string_field_set(user, cid_name, name2);
12359 ast_string_field_set(user, cid_num, num2);
12360 ast_set_flag(user, IAX_HASCALLERID);
12361 } else {
12362 ast_clear_flag(user, IAX_HASCALLERID);
12363 ast_string_field_set(user, cid_name, "");
12364 ast_string_field_set(user, cid_num, "");
12365 }
12366 } else if (!strcasecmp(v->name, "fullname")) {
12367 if (!ast_strlen_zero(v->value)) {
12368 ast_string_field_set(user, cid_name, v->value);
12369 ast_set_flag(user, IAX_HASCALLERID);
12370 } else {
12371 ast_string_field_set(user, cid_name, "");
12372 if (ast_strlen_zero(user->cid_num))
12373 ast_clear_flag(user, IAX_HASCALLERID);
12374 }
12375 } else if (!strcasecmp(v->name, "cid_number")) {
12376 if (!ast_strlen_zero(v->value)) {
12377 ast_string_field_set(user, cid_num, v->value);
12378 ast_set_flag(user, IAX_HASCALLERID);
12379 } else {
12380 ast_string_field_set(user, cid_num, "");
12381 if (ast_strlen_zero(user->cid_name))
12382 ast_clear_flag(user, IAX_HASCALLERID);
12383 }
12384 } else if (!strcasecmp(v->name, "accountcode")) {
12385 ast_string_field_set(user, accountcode, v->value);
12386 } else if (!strcasecmp(v->name, "mohinterpret")) {
12387 ast_string_field_set(user, mohinterpret, v->value);
12388 } else if (!strcasecmp(v->name, "mohsuggest")) {
12389 ast_string_field_set(user, mohsuggest, v->value);
12390 } else if (!strcasecmp(v->name, "parkinglot")) {
12391 ast_string_field_set(user, parkinglot, v->value);
12392 } else if (!strcasecmp(v->name, "language")) {
12393 ast_string_field_set(user, language, v->value);
12394 } else if (!strcasecmp(v->name, "amaflags")) {
12395 format = ast_cdr_amaflags2int(v->value);
12396 if (format < 0) {
12397 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12398 } else {
12399 user->amaflags = format;
12400 }
12401 } else if (!strcasecmp(v->name, "inkeys")) {
12402 ast_string_field_set(user, inkeys, v->value);
12403 } else if (!strcasecmp(v->name, "maxauthreq")) {
12404 user->maxauthreq = atoi(v->value);
12405 if (user->maxauthreq < 0)
12406 user->maxauthreq = 0;
12407 } else if (!strcasecmp(v->name, "adsi")) {
12408 user->adsi = ast_true(v->value);
12409 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12410
12411 if (ast_false(v->value)) {
12412 user->calltoken_required = CALLTOKEN_NO;
12413 } else if (!strcasecmp(v->value, "auto")) {
12414 user->calltoken_required = CALLTOKEN_AUTO;
12415 } else if (ast_true(v->value)) {
12416 user->calltoken_required = CALLTOKEN_YES;
12417 } else {
12418 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12419 }
12420 }
12421
12422 v = v->next;
12423 if (!v) {
12424 v = alt;
12425 alt = NULL;
12426 }
12427 }
12428 if (!user->authmethods) {
12429 if (!ast_strlen_zero(user->secret)) {
12430 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12431 if (!ast_strlen_zero(user->inkeys))
12432 user->authmethods |= IAX_AUTH_RSA;
12433 } else if (!ast_strlen_zero(user->inkeys)) {
12434 user->authmethods = IAX_AUTH_RSA;
12435 } else {
12436 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12437 }
12438 }
12439 ast_clear_flag(user, IAX_DELME);
12440 }
12441 cleanup:
12442 if (oldha)
12443 ast_free_ha(oldha);
12444 if (oldcon)
12445 free_context(oldcon);
12446 return user;
12447 }
12448
12449 static int peer_delme_cb(void *obj, void *arg, int flags)
12450 {
12451 struct iax2_peer *peer = obj;
12452
12453 ast_set_flag(peer, IAX_DELME);
12454
12455 return 0;
12456 }
12457
12458 static int user_delme_cb(void *obj, void *arg, int flags)
12459 {
12460 struct iax2_user *user = obj;
12461
12462 ast_set_flag(user, IAX_DELME);
12463
12464 return 0;
12465 }
12466
12467 static void delete_users(void)
12468 {
12469 struct iax2_registry *reg;
12470
12471 ao2_callback(users, 0, user_delme_cb, NULL);
12472
12473 AST_LIST_LOCK(®istrations);
12474 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12475 if (sched) {
12476 ast_sched_thread_del(sched, reg->expire);
12477 }
12478 if (reg->callno) {
12479 int callno = reg->callno;
12480 ast_mutex_lock(&iaxsl[callno]);
12481 if (iaxs[callno]) {
12482 iaxs[callno]->reg = NULL;
12483 iax2_destroy(callno);
12484 }
12485 ast_mutex_unlock(&iaxsl[callno]);
12486 }
12487 if (reg->dnsmgr)
12488 ast_dnsmgr_release(reg->dnsmgr);
12489 ast_free(reg);
12490 }
12491 AST_LIST_UNLOCK(®istrations);
12492
12493 ao2_callback(peers, 0, peer_delme_cb, NULL);
12494 }
12495
12496 static void prune_users(void)
12497 {
12498 struct iax2_user *user;
12499 struct ao2_iterator i;
12500
12501 i = ao2_iterator_init(users, 0);
12502 while ((user = ao2_iterator_next(&i))) {
12503 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
12504 ao2_unlink(users, user);
12505 }
12506 user_unref(user);
12507 }
12508 ao2_iterator_destroy(&i);
12509 }
12510
12511
12512 static void prune_peers(void)
12513 {
12514 struct iax2_peer *peer;
12515 struct ao2_iterator i;
12516
12517 i = ao2_iterator_init(peers, 0);
12518 while ((peer = ao2_iterator_next(&i))) {
12519 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
12520 unlink_peer(peer);
12521 }
12522 peer_unref(peer);
12523 }
12524 ao2_iterator_destroy(&i);
12525 }
12526
12527 static void set_config_destroy(void)
12528 {
12529 strcpy(accountcode, "");
12530 strcpy(language, "");
12531 strcpy(mohinterpret, "default");
12532 strcpy(mohsuggest, "");
12533 trunkmaxsize = MAX_TRUNKDATA;
12534 amaflags = 0;
12535 delayreject = 0;
12536 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
12537 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
12538 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
12539 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
12540 delete_users();
12541 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12542 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12543 }
12544
12545
12546 static int set_config(const char *config_file, int reload)
12547 {
12548 struct ast_config *cfg, *ucfg;
12549 int capability=iax2_capability;
12550 struct ast_variable *v;
12551 char *cat;
12552 const char *utype;
12553 const char *tosval;
12554 int format;
12555 int portno = IAX_DEFAULT_PORTNO;
12556 int x;
12557 int mtuv;
12558 struct iax2_user *user;
12559 struct iax2_peer *peer;
12560 struct ast_netsock *ns;
12561 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12562 #if 0
12563 static unsigned short int last_port=0;
12564 #endif
12565
12566 cfg = ast_config_load(config_file, config_flags);
12567
12568 if (!cfg) {
12569 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12570 return -1;
12571 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12572 ucfg = ast_config_load("users.conf", config_flags);
12573 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12574 return 0;
12575
12576 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12577 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
12578 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12579 ast_config_destroy(ucfg);
12580 return 0;
12581 }
12582 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
12583 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12584 return 0;
12585 } else {
12586 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12587 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
12588 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
12589 ast_config_destroy(cfg);
12590 return 0;
12591 }
12592 }
12593
12594 if (reload) {
12595 set_config_destroy();
12596 }
12597
12598
12599 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12600
12601
12602 memset(&globalflags, 0, sizeof(globalflags));
12603 ast_set_flag(&globalflags, IAX_RTUPDATE);
12604 ast_set_flag(&globalflags, IAX_SHRINKCALLERID);
12605
12606 #ifdef SO_NO_CHECK
12607 nochecksums = 0;
12608 #endif
12609
12610 default_parkinglot[0] = '\0';
12611
12612 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12613 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12614 global_max_trunk_mtu = MAX_TRUNK_MTU;
12615 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12616 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12617
12618 maxauthreq = 3;
12619
12620 srvlookup = 0;
12621
12622 v = ast_variable_browse(cfg, "general");
12623
12624
12625 tosval = ast_variable_retrieve(cfg, "general", "tos");
12626 if (tosval) {
12627 if (ast_str2tos(tosval, &qos.tos))
12628 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
12629 }
12630
12631 tosval = ast_variable_retrieve(cfg, "general", "cos");
12632 if (tosval) {
12633 if (ast_str2cos(tosval, &qos.cos))
12634 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
12635 }
12636 while(v) {
12637 if (!strcasecmp(v->name, "bindport")){
12638 if (reload)
12639 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
12640 else
12641 portno = atoi(v->value);
12642 } else if (!strcasecmp(v->name, "pingtime"))
12643 ping_time = atoi(v->value);
12644 else if (!strcasecmp(v->name, "iaxthreadcount")) {
12645 if (reload) {
12646 if (atoi(v->value) != iaxthreadcount)
12647 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
12648 } else {
12649 iaxthreadcount = atoi(v->value);
12650 if (iaxthreadcount < 1) {
12651 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
12652 iaxthreadcount = 1;
12653 } else if (iaxthreadcount > 256) {
12654 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
12655 iaxthreadcount = 256;
12656 }
12657 }
12658 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
12659 if (reload) {
12660 AST_LIST_LOCK(&dynamic_list);
12661 iaxmaxthreadcount = atoi(v->value);
12662 AST_LIST_UNLOCK(&dynamic_list);
12663 } else {
12664 iaxmaxthreadcount = atoi(v->value);
12665 if (iaxmaxthreadcount < 0) {
12666 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
12667 iaxmaxthreadcount = 0;
12668 } else if (iaxmaxthreadcount > 256) {
12669 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
12670 iaxmaxthreadcount = 256;
12671 }
12672 }
12673 } else if (!strcasecmp(v->name, "nochecksums")) {
12674 #ifdef SO_NO_CHECK
12675 if (ast_true(v->value))
12676 nochecksums = 1;
12677 else
12678 nochecksums = 0;
12679 #else
12680 if (ast_true(v->value))
12681 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
12682 #endif
12683 }
12684 else if (!strcasecmp(v->name, "maxjitterbuffer"))
12685 maxjitterbuffer = atoi(v->value);
12686 else if (!strcasecmp(v->name, "resyncthreshold"))
12687 resyncthreshold = atoi(v->value);
12688 else if (!strcasecmp(v->name, "maxjitterinterps"))
12689 maxjitterinterps = atoi(v->value);
12690 else if (!strcasecmp(v->name, "jittertargetextra"))
12691 jittertargetextra = atoi(v->value);
12692 else if (!strcasecmp(v->name, "lagrqtime"))
12693 lagrq_time = atoi(v->value);
12694 else if (!strcasecmp(v->name, "maxregexpire"))
12695 max_reg_expire = atoi(v->value);
12696 else if (!strcasecmp(v->name, "minregexpire"))
12697 min_reg_expire = atoi(v->value);
12698 else if (!strcasecmp(v->name, "bindaddr")) {
12699 if (reload) {
12700 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
12701 } else {
12702 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
12703 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
12704 } else {
12705 if (strchr(v->value, ':'))
12706 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
12707 else
12708 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
12709 if (defaultsockfd < 0)
12710 defaultsockfd = ast_netsock_sockfd(ns);
12711 ast_netsock_unref(ns);
12712 }
12713 }
12714 } else if (!strcasecmp(v->name, "authdebug")) {
12715 authdebug = ast_true(v->value);
12716 } else if (!strcasecmp(v->name, "encryption")) {
12717 iax2_encryption |= get_encrypt_methods(v->value);
12718 if (!iax2_encryption) {
12719 ast_clear_flag((&globalflags), IAX_FORCE_ENCRYPT);
12720 }
12721 } else if (!strcasecmp(v->name, "forceencryption")) {
12722 if (ast_false(v->value)) {
12723 ast_clear_flag((&globalflags), IAX_FORCE_ENCRYPT);
12724 } else {
12725 iax2_encryption |= get_encrypt_methods(v->value);
12726 if (iax2_encryption) {
12727 ast_set_flag((&globalflags), IAX_FORCE_ENCRYPT);
12728 }
12729 }
12730 } else if (!strcasecmp(v->name, "transfer")) {
12731 if (!strcasecmp(v->value, "mediaonly")) {
12732 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12733 } else if (ast_true(v->value)) {
12734 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12735 } else
12736 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12737 } else if (!strcasecmp(v->name, "codecpriority")) {
12738 if(!strcasecmp(v->value, "caller"))
12739 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
12740 else if(!strcasecmp(v->value, "disabled"))
12741 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12742 else if(!strcasecmp(v->value, "reqonly")) {
12743 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
12744 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
12745 }
12746 } else if (!strcasecmp(v->name, "jitterbuffer"))
12747 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
12748 else if (!strcasecmp(v->name, "forcejitterbuffer"))
12749 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
12750 else if (!strcasecmp(v->name, "delayreject"))
12751 delayreject = ast_true(v->value);
12752 else if (!strcasecmp(v->name, "allowfwdownload"))
12753 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
12754 else if (!strcasecmp(v->name, "rtcachefriends"))
12755 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
12756 else if (!strcasecmp(v->name, "rtignoreregexpire"))
12757 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
12758 else if (!strcasecmp(v->name, "rtupdate"))
12759 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
12760 else if (!strcasecmp(v->name, "trunktimestamps"))
12761 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
12762 else if (!strcasecmp(v->name, "rtautoclear")) {
12763 int i = atoi(v->value);
12764 if(i > 0)
12765 global_rtautoclear = i;
12766 else
12767 i = 0;
12768 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
12769 } else if (!strcasecmp(v->name, "trunkfreq")) {
12770 trunkfreq = atoi(v->value);
12771 if (trunkfreq < 10)
12772 trunkfreq = 10;
12773 } else if (!strcasecmp(v->name, "trunkmtu")) {
12774 mtuv = atoi(v->value);
12775 if (mtuv == 0 )
12776 global_max_trunk_mtu = 0;
12777 else if (mtuv >= 172 && mtuv < 4000)
12778 global_max_trunk_mtu = mtuv;
12779 else
12780 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
12781 mtuv, v->lineno);
12782 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
12783 trunkmaxsize = atoi(v->value);
12784 if (trunkmaxsize == 0)
12785 trunkmaxsize = MAX_TRUNKDATA;
12786 } else if (!strcasecmp(v->name, "autokill")) {
12787 if (sscanf(v->value, "%30d", &x) == 1) {
12788 if (x >= 0)
12789 autokill = x;
12790 else
12791 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
12792 } else if (ast_true(v->value)) {
12793 autokill = DEFAULT_MAXMS;
12794 } else {
12795 autokill = 0;
12796 }
12797 } else if (!strcasecmp(v->name, "bandwidth")) {
12798 if (!strcasecmp(v->value, "low")) {
12799 capability = IAX_CAPABILITY_LOWBANDWIDTH;
12800 } else if (!strcasecmp(v->value, "medium")) {
12801 capability = IAX_CAPABILITY_MEDBANDWIDTH;
12802 } else if (!strcasecmp(v->value, "high")) {
12803 capability = IAX_CAPABILITY_FULLBANDWIDTH;
12804 } else
12805 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
12806 } else if (!strcasecmp(v->name, "allow")) {
12807 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
12808 } else if (!strcasecmp(v->name, "disallow")) {
12809 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
12810 } else if (!strcasecmp(v->name, "register")) {
12811 iax2_register(v->value, v->lineno);
12812 } else if (!strcasecmp(v->name, "iaxcompat")) {
12813 iaxcompat = ast_true(v->value);
12814 } else if (!strcasecmp(v->name, "regcontext")) {
12815 ast_copy_string(regcontext, v->value, sizeof(regcontext));
12816
12817 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
12818 } else if (!strcasecmp(v->name, "tos")) {
12819 if (ast_str2tos(v->value, &qos.tos))
12820 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
12821 } else if (!strcasecmp(v->name, "cos")) {
12822 if (ast_str2cos(v->value, &qos.cos))
12823 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
12824 } else if (!strcasecmp(v->name, "parkinglot")) {
12825 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
12826 } else if (!strcasecmp(v->name, "accountcode")) {
12827 ast_copy_string(accountcode, v->value, sizeof(accountcode));
12828 } else if (!strcasecmp(v->name, "mohinterpret")) {
12829 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
12830 } else if (!strcasecmp(v->name, "mohsuggest")) {
12831 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
12832 } else if (!strcasecmp(v->name, "amaflags")) {
12833 format = ast_cdr_amaflags2int(v->value);
12834 if (format < 0) {
12835 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12836 } else {
12837 amaflags = format;
12838 }
12839 } else if (!strcasecmp(v->name, "language")) {
12840 ast_copy_string(language, v->value, sizeof(language));
12841 } else if (!strcasecmp(v->name, "maxauthreq")) {
12842 maxauthreq = atoi(v->value);
12843 if (maxauthreq < 0)
12844 maxauthreq = 0;
12845 } else if (!strcasecmp(v->name, "adsi")) {
12846 adsi = ast_true(v->value);
12847 } else if (!strcasecmp(v->name, "srvlookup")) {
12848 srvlookup = ast_true(v->value);
12849 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12850 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
12851 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
12852 }
12853 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
12854 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
12855 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);
12856 }
12857 } else if (!strcasecmp(v->name, "calltokenoptional")) {
12858 if (add_calltoken_ignore(v->value)) {
12859 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
12860 }
12861 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
12862 if (ast_true(v->value)) {
12863 ast_set_flag((&globalflags), IAX_SHRINKCALLERID);
12864 } else if (ast_false(v->value)) {
12865 ast_clear_flag((&globalflags), IAX_SHRINKCALLERID);
12866 } else {
12867 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
12868 }
12869 }
12870
12871 v = v->next;
12872 }
12873
12874 if (defaultsockfd < 0) {
12875 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
12876 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
12877 } else {
12878 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
12879 defaultsockfd = ast_netsock_sockfd(ns);
12880 ast_netsock_unref(ns);
12881 }
12882 }
12883 if (reload) {
12884 ast_netsock_release(outsock);
12885 outsock = ast_netsock_list_alloc();
12886 if (!outsock) {
12887 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12888 return -1;
12889 }
12890 ast_netsock_init(outsock);
12891 }
12892
12893 if (min_reg_expire > max_reg_expire) {
12894 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
12895 min_reg_expire, max_reg_expire, max_reg_expire);
12896 min_reg_expire = max_reg_expire;
12897 }
12898 iax2_capability = capability;
12899
12900 if (ucfg) {
12901 struct ast_variable *gen;
12902 int genhasiax;
12903 int genregisteriax;
12904 const char *hasiax, *registeriax;
12905
12906 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
12907 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
12908 gen = ast_variable_browse(ucfg, "general");
12909 cat = ast_category_browse(ucfg, NULL);
12910 while (cat) {
12911 if (strcasecmp(cat, "general")) {
12912 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
12913 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
12914 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
12915
12916 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
12917 if (user) {
12918 ao2_link(users, user);
12919 user = user_unref(user);
12920 }
12921 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
12922 if (peer) {
12923 if (ast_test_flag(peer, IAX_DYNAMIC))
12924 reg_source_db(peer);
12925 ao2_link(peers, peer);
12926 peer = peer_unref(peer);
12927 }
12928 }
12929 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
12930 char tmp[256];
12931 const char *host = ast_variable_retrieve(ucfg, cat, "host");
12932 const char *username = ast_variable_retrieve(ucfg, cat, "username");
12933 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
12934 if (!host)
12935 host = ast_variable_retrieve(ucfg, "general", "host");
12936 if (!username)
12937 username = ast_variable_retrieve(ucfg, "general", "username");
12938 if (!secret)
12939 secret = ast_variable_retrieve(ucfg, "general", "secret");
12940 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
12941 if (!ast_strlen_zero(secret))
12942 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
12943 else
12944 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
12945 iax2_register(tmp, 0);
12946 }
12947 }
12948 }
12949 cat = ast_category_browse(ucfg, cat);
12950 }
12951 ast_config_destroy(ucfg);
12952 }
12953
12954 cat = ast_category_browse(cfg, NULL);
12955 while(cat) {
12956 if (strcasecmp(cat, "general")) {
12957 utype = ast_variable_retrieve(cfg, cat, "type");
12958 if (!strcasecmp(cat, "callnumberlimits")) {
12959 build_callno_limits(ast_variable_browse(cfg, cat));
12960 } else if (utype) {
12961 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
12962 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
12963 if (user) {
12964 ao2_link(users, user);
12965 user = user_unref(user);
12966 }
12967 }
12968 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
12969 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
12970 if (peer) {
12971 if (ast_test_flag(peer, IAX_DYNAMIC))
12972 reg_source_db(peer);
12973 ao2_link(peers, peer);
12974 peer = peer_unref(peer);
12975 }
12976 } else if (strcasecmp(utype, "user")) {
12977 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
12978 }
12979 } else
12980 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
12981 }
12982 cat = ast_category_browse(cfg, cat);
12983 }
12984 ast_config_destroy(cfg);
12985 return 1;
12986 }
12987
12988 static void poke_all_peers(void)
12989 {
12990 struct ao2_iterator i;
12991 struct iax2_peer *peer;
12992
12993 i = ao2_iterator_init(peers, 0);
12994 while ((peer = ao2_iterator_next(&i))) {
12995 iax2_poke_peer(peer, 0);
12996 peer_unref(peer);
12997 }
12998 ao2_iterator_destroy(&i);
12999 }
13000 static int reload_config(void)
13001 {
13002 static const char config[] = "iax.conf";
13003 struct iax2_registry *reg;
13004
13005 if (set_config(config, 1) > 0) {
13006 prune_peers();
13007 prune_users();
13008 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13009 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13010 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13011 trunk_timed = trunk_untimed = 0;
13012 trunk_nmaxmtu = trunk_maxmtu = 0;
13013 memset(&debugaddr, '\0', sizeof(debugaddr));
13014
13015 AST_LIST_LOCK(®istrations);
13016 AST_LIST_TRAVERSE(®istrations, reg, entry)
13017 iax2_do_register(reg);
13018 AST_LIST_UNLOCK(®istrations);
13019
13020
13021 poke_all_peers();
13022 }
13023
13024 reload_firmware(0);
13025 iax_provision_reload(1);
13026 ast_unload_realtime("iaxpeers");
13027
13028 return 0;
13029 }
13030
13031 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13032 {
13033 switch (cmd) {
13034 case CLI_INIT:
13035 e->command = "iax2 reload";
13036 e->usage =
13037 "Usage: iax2 reload\n"
13038 " Reloads IAX configuration from iax.conf\n";
13039 return NULL;
13040 case CLI_GENERATE:
13041 return NULL;
13042 }
13043
13044 reload_config();
13045
13046 return CLI_SUCCESS;
13047 }
13048
13049 static int reload(void)
13050 {
13051 return reload_config();
13052 }
13053
13054 static int cache_get_callno_locked(const char *data)
13055 {
13056 struct sockaddr_in sin;
13057 int x;
13058 int callno;
13059 struct iax_ie_data ied;
13060 struct create_addr_info cai;
13061 struct parsed_dial_string pds;
13062 char *tmpstr;
13063
13064 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13065
13066
13067 if (!ast_mutex_trylock(&iaxsl[x])) {
13068 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13069 return x;
13070 ast_mutex_unlock(&iaxsl[x]);
13071 }
13072 }
13073
13074
13075
13076 memset(&cai, 0, sizeof(cai));
13077 memset(&ied, 0, sizeof(ied));
13078 memset(&pds, 0, sizeof(pds));
13079
13080 tmpstr = ast_strdupa(data);
13081 parse_dial_string(tmpstr, &pds);
13082
13083 if (ast_strlen_zero(pds.peer)) {
13084 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13085 return -1;
13086 }
13087
13088
13089 if (create_addr(pds.peer, NULL, &sin, &cai))
13090 return -1;
13091
13092 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13093 pds.peer, pds.username, pds.password, pds.context);
13094
13095 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13096 if (callno < 1) {
13097 ast_log(LOG_WARNING, "Unable to create call\n");
13098 return -1;
13099 }
13100
13101 ast_string_field_set(iaxs[callno], dproot, data);
13102 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13103
13104 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13105 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13106
13107
13108
13109 if (pds.exten)
13110 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13111 if (pds.username)
13112 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13113 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13114 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13115
13116 if (pds.password)
13117 ast_string_field_set(iaxs[callno], secret, pds.password);
13118 if (pds.key)
13119 ast_string_field_set(iaxs[callno], outkey, pds.key);
13120
13121 add_empty_calltoken_ie(iaxs[callno], &ied);
13122 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13123
13124 return callno;
13125 }
13126
13127 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13128 {
13129 struct iax2_dpcache *dp = NULL;
13130 struct timeval now = ast_tvnow();
13131 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13132 struct ast_channel *c = NULL;
13133 struct ast_frame *f = NULL;
13134
13135 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13136 if (ast_tvcmp(now, dp->expiry) > 0) {
13137 AST_LIST_REMOVE_CURRENT(cache_list);
13138 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13139 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13140 else
13141 ast_free(dp);
13142 continue;
13143 }
13144 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13145 break;
13146 }
13147 AST_LIST_TRAVERSE_SAFE_END;
13148
13149 if (!dp) {
13150
13151
13152 if ((callno = cache_get_callno_locked(data)) < 0) {
13153 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13154 return NULL;
13155 }
13156 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13157 ast_mutex_unlock(&iaxsl[callno]);
13158 return NULL;
13159 }
13160 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13161 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13162 dp->expiry = ast_tvnow();
13163 dp->orig = dp->expiry;
13164
13165 dp->expiry.tv_sec += iaxdefaultdpcache;
13166 dp->flags = CACHE_FLAG_PENDING;
13167 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13168 dp->waiters[x] = -1;
13169
13170 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13171 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13172
13173 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13174 iax2_dprequest(dp, callno);
13175 ast_mutex_unlock(&iaxsl[callno]);
13176 }
13177
13178
13179 if (dp->flags & CACHE_FLAG_PENDING) {
13180
13181
13182 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13183
13184 if (dp->waiters[x] < 0)
13185 break;
13186 }
13187 if (x >= ARRAY_LEN(dp->waiters)) {
13188 ast_log(LOG_WARNING, "No more waiter positions available\n");
13189 return NULL;
13190 }
13191 if (pipe(com)) {
13192 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13193 return NULL;
13194 }
13195 dp->waiters[x] = com[1];
13196
13197 timeout = iaxdefaulttimeout * 1000;
13198
13199 AST_LIST_UNLOCK(&dpcache);
13200
13201 if (chan)
13202 old = ast_channel_defer_dtmf(chan);
13203 doabort = 0;
13204 while(timeout) {
13205 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13206 if (outfd > -1)
13207 break;
13208 if (!c)
13209 continue;
13210 if (!(f = ast_read(c))) {
13211 doabort = 1;
13212 break;
13213 }
13214 ast_frfree(f);
13215 }
13216 if (!timeout) {
13217 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13218 }
13219 AST_LIST_LOCK(&dpcache);
13220 dp->waiters[x] = -1;
13221 close(com[1]);
13222 close(com[0]);
13223 if (doabort) {
13224
13225
13226 if (!old && chan)
13227 ast_channel_undefer_dtmf(chan);
13228 return NULL;
13229 }
13230 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13231
13232 if (dp->flags & CACHE_FLAG_PENDING) {
13233
13234
13235 dp->flags &= ~CACHE_FLAG_PENDING;
13236 dp->flags |= CACHE_FLAG_TIMEOUT;
13237
13238
13239 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13240 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13241 if (dp->waiters[x] > -1) {
13242 if (write(dp->waiters[x], "asdf", 4) < 0) {
13243 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13244 }
13245 }
13246 }
13247 }
13248 }
13249
13250 if (!old && chan)
13251 ast_channel_undefer_dtmf(chan);
13252 }
13253 return dp;
13254 }
13255
13256
13257 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13258 {
13259 int res = 0;
13260 struct iax2_dpcache *dp = NULL;
13261 #if 0
13262 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13263 #endif
13264 if ((priority != 1) && (priority != 2))
13265 return 0;
13266
13267 AST_LIST_LOCK(&dpcache);
13268 if ((dp = find_cache(chan, data, context, exten, priority))) {
13269 if (dp->flags & CACHE_FLAG_EXISTS)
13270 res = 1;
13271 } else {
13272 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13273 }
13274 AST_LIST_UNLOCK(&dpcache);
13275
13276 return res;
13277 }
13278
13279
13280 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13281 {
13282 int res = 0;
13283 struct iax2_dpcache *dp = NULL;
13284 #if 0
13285 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13286 #endif
13287 if ((priority != 1) && (priority != 2))
13288 return 0;
13289
13290 AST_LIST_LOCK(&dpcache);
13291 if ((dp = find_cache(chan, data, context, exten, priority))) {
13292 if (dp->flags & CACHE_FLAG_CANEXIST)
13293 res = 1;
13294 } else {
13295 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13296 }
13297 AST_LIST_UNLOCK(&dpcache);
13298
13299 return res;
13300 }
13301
13302
13303 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13304 {
13305 int res = 0;
13306 struct iax2_dpcache *dp = NULL;
13307 #if 0
13308 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13309 #endif
13310 if ((priority != 1) && (priority != 2))
13311 return 0;
13312
13313 AST_LIST_LOCK(&dpcache);
13314 if ((dp = find_cache(chan, data, context, exten, priority))) {
13315 if (dp->flags & CACHE_FLAG_MATCHMORE)
13316 res = 1;
13317 } else {
13318 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13319 }
13320 AST_LIST_UNLOCK(&dpcache);
13321
13322 return res;
13323 }
13324
13325
13326 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13327 {
13328 char odata[256];
13329 char req[256];
13330 char *ncontext;
13331 struct iax2_dpcache *dp = NULL;
13332 struct ast_app *dial = NULL;
13333 #if 0
13334 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);
13335 #endif
13336 if (priority == 2) {
13337
13338 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13339 if (dialstatus) {
13340 dial = pbx_findapp(dialstatus);
13341 if (dial)
13342 pbx_exec(chan, dial, "");
13343 }
13344 return -1;
13345 } else if (priority != 1)
13346 return -1;
13347
13348 AST_LIST_LOCK(&dpcache);
13349 if ((dp = find_cache(chan, data, context, exten, priority))) {
13350 if (dp->flags & CACHE_FLAG_EXISTS) {
13351 ast_copy_string(odata, data, sizeof(odata));
13352 ncontext = strchr(odata, '/');
13353 if (ncontext) {
13354 *ncontext = '\0';
13355 ncontext++;
13356 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13357 } else {
13358 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13359 }
13360 ast_verb(3, "Executing Dial('%s')\n", req);
13361 } else {
13362 AST_LIST_UNLOCK(&dpcache);
13363 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13364 return -1;
13365 }
13366 }
13367 AST_LIST_UNLOCK(&dpcache);
13368
13369 if ((dial = pbx_findapp("Dial")))
13370 return pbx_exec(chan, dial, req);
13371 else
13372 ast_log(LOG_WARNING, "No dial application registered\n");
13373
13374 return -1;
13375 }
13376
13377 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13378 {
13379 struct iax2_peer *peer;
13380 char *peername, *colname;
13381
13382 peername = ast_strdupa(data);
13383
13384
13385 if (!strcmp(peername,"CURRENTCHANNEL")) {
13386 unsigned short callno;
13387 if (chan->tech != &iax2_tech)
13388 return -1;
13389 callno = PTR_TO_CALLNO(chan->tech_pvt);
13390 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13391 return 0;
13392 }
13393
13394 if ((colname = strchr(peername, ',')))
13395 *colname++ = '\0';
13396 else
13397 colname = "ip";
13398
13399 if (!(peer = find_peer(peername, 1)))
13400 return -1;
13401
13402 if (!strcasecmp(colname, "ip")) {
13403 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
13404 } else if (!strcasecmp(colname, "status")) {
13405 peer_status(peer, buf, len);
13406 } else if (!strcasecmp(colname, "mailbox")) {
13407 ast_copy_string(buf, peer->mailbox, len);
13408 } else if (!strcasecmp(colname, "context")) {
13409 ast_copy_string(buf, peer->context, len);
13410 } else if (!strcasecmp(colname, "expire")) {
13411 snprintf(buf, len, "%d", peer->expire);
13412 } else if (!strcasecmp(colname, "dynamic")) {
13413 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13414 } else if (!strcasecmp(colname, "callerid_name")) {
13415 ast_copy_string(buf, peer->cid_name, len);
13416 } else if (!strcasecmp(colname, "callerid_num")) {
13417 ast_copy_string(buf, peer->cid_num, len);
13418 } else if (!strcasecmp(colname, "codecs")) {
13419 ast_getformatname_multiple(buf, len -1, peer->capability);
13420 } else if (!strncasecmp(colname, "codec[", 6)) {
13421 char *codecnum, *ptr;
13422 int codec = 0;
13423
13424 codecnum = strchr(colname, '[');
13425 *codecnum = '\0';
13426 codecnum++;
13427 if ((ptr = strchr(codecnum, ']'))) {
13428 *ptr = '\0';
13429 }
13430 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13431 ast_copy_string(buf, ast_getformatname(codec), len);
13432 } else {
13433 buf[0] = '\0';
13434 }
13435 } else {
13436 buf[0] = '\0';
13437 }
13438
13439 peer_unref(peer);
13440
13441 return 0;
13442 }
13443
13444 struct ast_custom_function iaxpeer_function = {
13445 .name = "IAXPEER",
13446 .read = function_iaxpeer,
13447 };
13448
13449 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13450 {
13451 struct chan_iax2_pvt *pvt;
13452 unsigned int callno;
13453 int res = 0;
13454
13455 if (!chan || chan->tech != &iax2_tech) {
13456 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13457 return -1;
13458 }
13459
13460 callno = PTR_TO_CALLNO(chan->tech_pvt);
13461 ast_mutex_lock(&iaxsl[callno]);
13462 if (!(pvt = iaxs[callno])) {
13463 ast_mutex_unlock(&iaxsl[callno]);
13464 return -1;
13465 }
13466
13467 if (!strcasecmp(args, "osptoken")) {
13468 ast_copy_string(buf, pvt->osptoken, buflen);
13469 } else if (!strcasecmp(args, "peerip")) {
13470 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13471 } else if (!strcasecmp(args, "peername")) {
13472 ast_copy_string(buf, pvt->username, buflen);
13473 } else {
13474 res = -1;
13475 }
13476
13477 ast_mutex_unlock(&iaxsl[callno]);
13478
13479 return res;
13480 }
13481
13482
13483 static int iax2_devicestate(void *data)
13484 {
13485 struct parsed_dial_string pds;
13486 char *tmp = ast_strdupa(data);
13487 struct iax2_peer *p;
13488 int res = AST_DEVICE_INVALID;
13489
13490 memset(&pds, 0, sizeof(pds));
13491 parse_dial_string(tmp, &pds);
13492
13493 if (ast_strlen_zero(pds.peer)) {
13494 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13495 return res;
13496 }
13497
13498 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13499
13500
13501 if (!(p = find_peer(pds.peer, 1)))
13502 return res;
13503
13504 res = AST_DEVICE_UNAVAILABLE;
13505 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13506 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13507
13508 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
13509 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13510
13511
13512 if (p->historicms == 0 || p->historicms <= p->maxms)
13513
13514 res = AST_DEVICE_UNKNOWN;
13515 }
13516
13517 peer_unref(p);
13518
13519 return res;
13520 }
13521
13522 static struct ast_switch iax2_switch =
13523 {
13524 name: "IAX2",
13525 description: "IAX Remote Dialplan Switch",
13526 exists: iax2_exists,
13527 canmatch: iax2_canmatch,
13528 exec: iax2_exec,
13529 matchmore: iax2_matchmore,
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
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
13621
13622
13623
13624
13625
13626
13627
13628
13629
13630
13631
13632
13633
13634
13635
13636 static struct ast_cli_entry cli_iax2[] = {
13637 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
13638 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
13639 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
13640 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
13641 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
13642 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
13643 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
13644 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
13645 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
13646 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
13647 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
13648 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
13649 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
13650 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
13651 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
13652 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
13653 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
13654 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
13655 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
13656 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
13657 #ifdef IAXTESTS
13658 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
13659 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
13660 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
13661 #endif
13662 };
13663
13664 static void cleanup_thread_list(void *head)
13665 {
13666 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
13667 struct iax2_thread_list *list_head = head;
13668 struct iax2_thread *thread;
13669
13670 AST_LIST_LOCK(list_head);
13671 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
13672 pthread_t thread_id = thread->threadid;
13673
13674 thread->stop = 1;
13675 signal_condition(&thread->lock, &thread->cond);
13676
13677 AST_LIST_UNLOCK(list_head);
13678 pthread_join(thread_id, NULL);
13679 AST_LIST_LOCK(list_head);
13680 }
13681 AST_LIST_UNLOCK(list_head);
13682 }
13683
13684 static int __unload_module(void)
13685 {
13686 struct ast_context *con;
13687 int x;
13688
13689 ast_manager_unregister("IAXpeers");
13690 ast_manager_unregister("IAXpeerlist");
13691 ast_manager_unregister("IAXnetstats");
13692 ast_manager_unregister("IAXregistry");
13693 ast_unregister_application(papp);
13694 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
13695 ast_unregister_switch(&iax2_switch);
13696 ast_channel_unregister(&iax2_tech);
13697
13698 if (netthreadid != AST_PTHREADT_NULL) {
13699 AST_LIST_LOCK(&frame_queue);
13700 pthread_cancel(netthreadid);
13701 AST_LIST_UNLOCK(&frame_queue);
13702 pthread_join(netthreadid, NULL);
13703 }
13704
13705 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13706 if (iaxs[x]) {
13707 iax2_destroy(x);
13708 }
13709 }
13710
13711
13712 cleanup_thread_list(&idle_list);
13713 cleanup_thread_list(&active_list);
13714 cleanup_thread_list(&dynamic_list);
13715
13716 ast_netsock_release(netsock);
13717 ast_netsock_release(outsock);
13718
13719 delete_users();
13720 iax_provision_unload();
13721 reload_firmware(1);
13722
13723 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13724 ast_mutex_destroy(&iaxsl[x]);
13725 }
13726
13727 ao2_ref(peers, -1);
13728 ao2_ref(users, -1);
13729 ao2_ref(iax_peercallno_pvts, -1);
13730 ao2_ref(iax_transfercallno_pvts, -1);
13731 ao2_ref(peercnts, -1);
13732 ao2_ref(callno_limits, -1);
13733 ao2_ref(calltoken_ignores, -1);
13734 ao2_ref(callno_pool, -1);
13735 ao2_ref(callno_pool_trunk, -1);
13736 if (timer) {
13737 ast_timer_close(timer);
13738 }
13739 sched = ast_sched_thread_destroy(sched);
13740
13741 con = ast_context_find(regcontext);
13742 if (con)
13743 ast_context_destroy(con, "IAX2");
13744 ast_unload_realtime("iaxpeers");
13745 return 0;
13746 }
13747
13748 static int unload_module(void)
13749 {
13750 ast_custom_function_unregister(&iaxpeer_function);
13751 ast_custom_function_unregister(&iaxvar_function);
13752 return __unload_module();
13753 }
13754
13755 static int peer_set_sock_cb(void *obj, void *arg, int flags)
13756 {
13757 struct iax2_peer *peer = obj;
13758
13759 if (peer->sockfd < 0)
13760 peer->sockfd = defaultsockfd;
13761
13762 return 0;
13763 }
13764
13765 static int pvt_hash_cb(const void *obj, const int flags)
13766 {
13767 const struct chan_iax2_pvt *pvt = obj;
13768
13769 return pvt->peercallno;
13770 }
13771
13772 static int pvt_cmp_cb(void *obj, void *arg, int flags)
13773 {
13774 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13775
13776
13777
13778
13779 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
13780 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13781 }
13782
13783 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
13784 {
13785 const struct chan_iax2_pvt *pvt = obj;
13786
13787 return pvt->transfercallno;
13788 }
13789
13790 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
13791 {
13792 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
13793
13794
13795
13796
13797 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
13798 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
13799 }
13800
13801 static int load_objects(void)
13802 {
13803 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
13804 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
13805
13806 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
13807 goto container_fail;
13808 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
13809 goto container_fail;
13810 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
13811 goto container_fail;
13812 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
13813 goto container_fail;
13814 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
13815 goto container_fail;
13816 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13817 goto container_fail;
13818 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
13819 goto container_fail;
13820 } else if (create_callno_pools()) {
13821 goto container_fail;
13822 }
13823
13824 return 0;
13825
13826 container_fail:
13827 if (peers) {
13828 ao2_ref(peers, -1);
13829 }
13830 if (users) {
13831 ao2_ref(users, -1);
13832 }
13833 if (iax_peercallno_pvts) {
13834 ao2_ref(iax_peercallno_pvts, -1);
13835 }
13836 if (iax_transfercallno_pvts) {
13837 ao2_ref(iax_transfercallno_pvts, -1);
13838 }
13839 if (peercnts) {
13840 ao2_ref(peercnts, -1);
13841 }
13842 if (callno_limits) {
13843 ao2_ref(callno_limits, -1);
13844 }
13845 if (calltoken_ignores) {
13846 ao2_ref(calltoken_ignores, -1);
13847 }
13848 if (callno_pool) {
13849 ao2_ref(callno_pool, -1);
13850 }
13851 if (callno_pool_trunk) {
13852 ao2_ref(callno_pool_trunk, -1);
13853 }
13854 return AST_MODULE_LOAD_FAILURE;
13855 }
13856
13857
13858
13859
13860 static int load_module(void)
13861 {
13862 static const char config[] = "iax.conf";
13863 int x = 0;
13864 struct iax2_registry *reg = NULL;
13865
13866 if (load_objects()) {
13867 return AST_MODULE_LOAD_FAILURE;
13868 }
13869
13870 memset(iaxs, 0, sizeof(iaxs));
13871
13872 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
13873 ast_mutex_init(&iaxsl[x]);
13874 }
13875
13876 if (!(sched = ast_sched_thread_create())) {
13877 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
13878 return AST_MODULE_LOAD_FAILURE;
13879 }
13880
13881 if (!(io = io_context_create())) {
13882 ast_log(LOG_ERROR, "Failed to create I/O context\n");
13883 sched = ast_sched_thread_destroy(sched);
13884 return AST_MODULE_LOAD_FAILURE;
13885 }
13886
13887 if (!(netsock = ast_netsock_list_alloc())) {
13888 ast_log(LOG_ERROR, "Failed to create netsock list\n");
13889 io_context_destroy(io);
13890 sched = ast_sched_thread_destroy(sched);
13891 return AST_MODULE_LOAD_FAILURE;
13892 }
13893 ast_netsock_init(netsock);
13894
13895 outsock = ast_netsock_list_alloc();
13896 if (!outsock) {
13897 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13898 io_context_destroy(io);
13899 sched = ast_sched_thread_destroy(sched);
13900 return AST_MODULE_LOAD_FAILURE;
13901 }
13902 ast_netsock_init(outsock);
13903
13904 randomcalltokendata = ast_random();
13905
13906 iax_set_output(iax_debug_output);
13907 iax_set_error(iax_error_output);
13908 jb_setoutput(jb_error_output, jb_warning_output, NULL);
13909
13910 if ((timer = ast_timer_open())) {
13911 ast_timer_set_rate(timer, trunkfreq);
13912 }
13913
13914 if (set_config(config, 0) == -1) {
13915 if (timer) {
13916 ast_timer_close(timer);
13917 }
13918 return AST_MODULE_LOAD_DECLINE;
13919 }
13920
13921 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
13922
13923 ast_register_application_xml(papp, iax2_prov_app);
13924
13925 ast_custom_function_register(&iaxpeer_function);
13926 ast_custom_function_register(&iaxvar_function);
13927
13928 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
13929 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
13930 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
13931 ast_manager_register( "IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry, "Show IAX registrations");
13932
13933 if (ast_channel_register(&iax2_tech)) {
13934 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
13935 __unload_module();
13936 return AST_MODULE_LOAD_FAILURE;
13937 }
13938
13939 if (ast_register_switch(&iax2_switch)) {
13940 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
13941 }
13942
13943 if (start_network_thread()) {
13944 ast_log(LOG_ERROR, "Unable to start network thread\n");
13945 __unload_module();
13946 return AST_MODULE_LOAD_FAILURE;
13947 } else {
13948 ast_verb(2, "IAX Ready and Listening\n");
13949 }
13950
13951 AST_LIST_LOCK(®istrations);
13952 AST_LIST_TRAVERSE(®istrations, reg, entry)
13953 iax2_do_register(reg);
13954 AST_LIST_UNLOCK(®istrations);
13955
13956 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
13957 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
13958
13959
13960 reload_firmware(0);
13961 iax_provision_reload(0);
13962
13963 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
13964
13965 return AST_MODULE_LOAD_SUCCESS;
13966 }
13967
13968 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
13969 .load = load_module,
13970 .unload = unload_module,
13971 .reload = reload,
13972 );