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
00039 #include "asterisk.h"
00040
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 411313 $")
00042
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <strings.h>
00054 #include <netdb.h>
00055 #include <fcntl.h>
00056 #include <sys/stat.h>
00057 #include <regex.h>
00058
00059 #include "asterisk/paths.h"
00060
00061 #include "asterisk/lock.h"
00062 #include "asterisk/frame.h"
00063 #include "asterisk/channel.h"
00064 #include "asterisk/module.h"
00065 #include "asterisk/pbx.h"
00066 #include "asterisk/sched.h"
00067 #include "asterisk/io.h"
00068 #include "asterisk/config.h"
00069 #include "asterisk/cli.h"
00070 #include "asterisk/translate.h"
00071 #include "asterisk/md5.h"
00072 #include "asterisk/cdr.h"
00073 #include "asterisk/crypto.h"
00074 #include "asterisk/acl.h"
00075 #include "asterisk/manager.h"
00076 #include "asterisk/callerid.h"
00077 #include "asterisk/app.h"
00078 #include "asterisk/astdb.h"
00079 #include "asterisk/musiconhold.h"
00080 #include "asterisk/features.h"
00081 #include "asterisk/utils.h"
00082 #include "asterisk/causes.h"
00083 #include "asterisk/localtime.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 #include "asterisk/taskprocessor.h"
00093 #include "asterisk/test.h"
00094 #include "asterisk/data.h"
00095 #include "asterisk/netsock2.h"
00096
00097 #include "iax2.h"
00098 #include "iax2-parser.h"
00099 #include "iax2-provision.h"
00100 #include "jitterbuf.h"
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
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 #define SCHED_MULTITHREADED
00232
00233
00234
00235 #define DEBUG_SCHED_MULTITHREAD
00236
00237
00238 #ifdef SO_NO_CHECK
00239 static int nochecksums = 0;
00240 #endif
00241
00242 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00243 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00244
00245 #define DEFAULT_THREAD_COUNT 10
00246 #define DEFAULT_MAX_THREAD_COUNT 100
00247 #define DEFAULT_RETRY_TIME 1000
00248 #define MEMORY_SIZE 100
00249 #define DEFAULT_DROP 3
00250
00251 #define DEBUG_SUPPORT
00252
00253 #define MIN_REUSE_TIME 60
00254
00255
00256 #define GAMMA (0.01)
00257
00258 static struct ast_codec_pref prefs;
00259
00260 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00261
00262
00263
00264
00265 #define MAX_TRUNK_MTU 1240
00266
00267 static int global_max_trunk_mtu;
00268 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00269
00270 #define DEFAULT_CONTEXT "default"
00271
00272 static char default_parkinglot[AST_MAX_CONTEXT];
00273
00274 static char language[MAX_LANGUAGE] = "";
00275 static char regcontext[AST_MAX_CONTEXT] = "";
00276
00277 static struct ast_event_sub *network_change_event_subscription;
00278 static int network_change_event_sched_id = -1;
00279
00280 static int maxauthreq = 3;
00281 static int max_retries = 4;
00282 static int ping_time = 21;
00283 static int lagrq_time = 10;
00284 static int maxjitterbuffer=1000;
00285 static int resyncthreshold=1000;
00286 static int maxjitterinterps=10;
00287 static int jittertargetextra = 40;
00288
00289 #define MAX_TRUNKDATA 640 * 200
00290
00291 static int trunkfreq = 20;
00292 static int trunkmaxsize = MAX_TRUNKDATA;
00293
00294 static int authdebug = 1;
00295 static int autokill = 0;
00296 static int iaxcompat = 0;
00297 static int last_authmethod = 0;
00298
00299 static int iaxdefaultdpcache=10 * 60;
00300
00301 static int iaxdefaulttimeout = 5;
00302
00303 static struct {
00304 unsigned int tos;
00305 unsigned int cos;
00306 } qos = { 0, 0 };
00307
00308 static int min_reg_expire;
00309 static int max_reg_expire;
00310
00311 static int srvlookup = 0;
00312
00313 static struct ast_timer *timer;
00314
00315 static struct ast_netsock_list *netsock;
00316 static struct ast_netsock_list *outsock;
00317 static int defaultsockfd = -1;
00318
00319 static int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00320
00321
00322 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00323
00324 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00325 ~AST_FORMAT_SLINEAR & \
00326 ~AST_FORMAT_SLINEAR16 & \
00327 ~AST_FORMAT_SIREN7 & \
00328 ~AST_FORMAT_SIREN14 & \
00329 ~AST_FORMAT_G719 & \
00330 ~AST_FORMAT_ULAW & \
00331 ~AST_FORMAT_ALAW & \
00332 ~AST_FORMAT_G722)
00333
00334 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00335 ~AST_FORMAT_G726 & \
00336 ~AST_FORMAT_G726_AAL2 & \
00337 ~AST_FORMAT_ADPCM)
00338
00339 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00340 ~AST_FORMAT_G723_1)
00341
00342
00343 #define DEFAULT_MAXMS 2000
00344 #define DEFAULT_FREQ_OK 60 * 1000
00345 #define DEFAULT_FREQ_NOTOK 10 * 1000
00346
00347
00348 #define IAX_CALLENCRYPTED(pvt) \
00349 (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))
00350
00351 #define IAX_DEBUGDIGEST(msg, key) do { \
00352 int idx; \
00353 char digest[33] = ""; \
00354 \
00355 if (!iaxdebug) \
00356 break; \
00357 \
00358 for (idx = 0; idx < 16; idx++) \
00359 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00360 \
00361 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00362 } while(0)
00363
00364 static struct io_context *io;
00365 static struct ast_sched_thread *sched;
00366
00367 #define DONT_RESCHEDULE -2
00368
00369 static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00370
00371 static int iaxdebug = 0;
00372
00373 static int iaxtrunkdebug = 0;
00374
00375 static int test_losspct = 0;
00376 #ifdef IAXTESTS
00377 static int test_late = 0;
00378 static int test_resync = 0;
00379 static int test_jit = 0;
00380 static int test_jitpct = 0;
00381 #endif
00382
00383 static char accountcode[AST_MAX_ACCOUNT_CODE];
00384 static char mohinterpret[MAX_MUSICCLASS];
00385 static char mohsuggest[MAX_MUSICCLASS];
00386 static int amaflags = 0;
00387 static int adsi = 0;
00388 static int delayreject = 0;
00389 static int iax2_encryption = 0;
00390
00391 static struct ast_flags64 globalflags = { 0 };
00392
00393 static pthread_t netthreadid = AST_PTHREADT_NULL;
00394
00395 enum iax2_state {
00396 IAX_STATE_STARTED = (1 << 0),
00397 IAX_STATE_AUTHENTICATED = (1 << 1),
00398 IAX_STATE_TBD = (1 << 2),
00399 };
00400
00401 struct iax2_context {
00402 char context[AST_MAX_CONTEXT];
00403 struct iax2_context *next;
00404 };
00405
00406
00407 #define IAX_HASCALLERID (uint64_t)(1 << 0)
00408 #define IAX_DELME (uint64_t)(1 << 1)
00409 #define IAX_TEMPONLY (uint64_t)(1 << 2)
00410 #define IAX_TRUNK (uint64_t)(1 << 3)
00411 #define IAX_NOTRANSFER (uint64_t)(1 << 4)
00412 #define IAX_USEJITTERBUF (uint64_t)(1 << 5)
00413 #define IAX_DYNAMIC (uint64_t)(1 << 6)
00414 #define IAX_SENDANI (uint64_t)(1 << 7)
00415 #define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8)
00416 #define IAX_ALREADYGONE (uint64_t)(1 << 9)
00417 #define IAX_PROVISION (uint64_t)(1 << 10)
00418 #define IAX_QUELCH (uint64_t)(1 << 11)
00419 #define IAX_ENCRYPTED (uint64_t)(1 << 12)
00420 #define IAX_KEYPOPULATED (uint64_t)(1 << 13)
00421 #define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14)
00422 #define IAX_CODEC_NOPREFS (uint64_t)(1 << 15)
00423 #define IAX_CODEC_NOCAP (uint64_t)(1 << 16)
00424 #define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17)
00425 #define IAX_RTUPDATE (uint64_t)(1 << 18)
00426 #define IAX_RTAUTOCLEAR (uint64_t)(1 << 19)
00427 #define IAX_FORCEJITTERBUF (uint64_t)(1 << 20)
00428 #define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21)
00429 #define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22)
00430 #define IAX_TRANSFERMEDIA (uint64_t)(1 << 23)
00431 #define IAX_MAXAUTHREQ (uint64_t)(1 << 24)
00432 #define IAX_DELAYPBXSTART (uint64_t)(1 << 25)
00433 #define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26)
00434 #define IAX_IMMEDIATE (uint64_t)(1 << 27)
00435 #define IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28)
00436 #define IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29)
00437 #define IAX_FORCE_ENCRYPT (uint64_t)(1 << 30)
00438 #define IAX_SHRINKCALLERID (uint64_t)(1 << 31)
00439 static int global_rtautoclear = 120;
00440
00441 static int reload_config(void);
00442
00443
00444
00445
00446 enum calltoken_peer_enum {
00447
00448 CALLTOKEN_DEFAULT = 0,
00449
00450 CALLTOKEN_YES = 1,
00451
00452
00453 CALLTOKEN_AUTO = 2,
00454
00455 CALLTOKEN_NO = 3,
00456 };
00457
00458 struct iax2_user {
00459 AST_DECLARE_STRING_FIELDS(
00460 AST_STRING_FIELD(name);
00461 AST_STRING_FIELD(secret);
00462 AST_STRING_FIELD(dbsecret);
00463 AST_STRING_FIELD(accountcode);
00464 AST_STRING_FIELD(mohinterpret);
00465 AST_STRING_FIELD(mohsuggest);
00466 AST_STRING_FIELD(inkeys);
00467 AST_STRING_FIELD(language);
00468 AST_STRING_FIELD(cid_num);
00469 AST_STRING_FIELD(cid_name);
00470 AST_STRING_FIELD(parkinglot);
00471 );
00472
00473 int authmethods;
00474 int encmethods;
00475 int amaflags;
00476 int adsi;
00477 uint64_t flags;
00478 format_t capability;
00479 int maxauthreq;
00480 int curauthreq;
00481 struct ast_codec_pref prefs;
00482 struct ast_ha *ha;
00483 struct iax2_context *contexts;
00484 struct ast_variable *vars;
00485 enum calltoken_peer_enum calltoken_required;
00486 };
00487
00488 struct iax2_peer {
00489 AST_DECLARE_STRING_FIELDS(
00490 AST_STRING_FIELD(name);
00491 AST_STRING_FIELD(username);
00492 AST_STRING_FIELD(secret);
00493 AST_STRING_FIELD(dbsecret);
00494 AST_STRING_FIELD(outkey);
00495
00496 AST_STRING_FIELD(regexten);
00497 AST_STRING_FIELD(context);
00498 AST_STRING_FIELD(peercontext);
00499 AST_STRING_FIELD(mailbox);
00500 AST_STRING_FIELD(mohinterpret);
00501 AST_STRING_FIELD(mohsuggest);
00502 AST_STRING_FIELD(inkeys);
00503
00504 AST_STRING_FIELD(cid_num);
00505 AST_STRING_FIELD(cid_name);
00506 AST_STRING_FIELD(zonetag);
00507 AST_STRING_FIELD(parkinglot);
00508 );
00509 struct ast_codec_pref prefs;
00510 struct ast_dnsmgr_entry *dnsmgr;
00511 struct ast_sockaddr addr;
00512 int formats;
00513 int sockfd;
00514 struct in_addr mask;
00515 int adsi;
00516 uint64_t flags;
00517
00518
00519 struct sockaddr_in defaddr;
00520 int authmethods;
00521 int encmethods;
00522
00523 int expire;
00524 int expiry;
00525 format_t capability;
00526
00527
00528 int callno;
00529 int pokeexpire;
00530 int lastms;
00531 int maxms;
00532
00533 int pokefreqok;
00534 int pokefreqnotok;
00535 int historicms;
00536 int smoothing;
00537 uint16_t maxcallno;
00538
00539 struct ast_event_sub *mwi_event_sub;
00540
00541 struct ast_ha *ha;
00542 enum calltoken_peer_enum calltoken_required;
00543 };
00544
00545 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00546
00547 struct iax2_trunk_peer {
00548 ast_mutex_t lock;
00549 int sockfd;
00550 struct sockaddr_in addr;
00551 struct timeval txtrunktime;
00552 struct timeval rxtrunktime;
00553 struct timeval lasttxtime;
00554 struct timeval trunkact;
00555 unsigned int lastsent;
00556
00557 unsigned char *trunkdata;
00558 unsigned int trunkdatalen;
00559 unsigned int trunkdataalloc;
00560 int trunkmaxmtu;
00561 int trunkerror;
00562 int calls;
00563 AST_LIST_ENTRY(iax2_trunk_peer) list;
00564 };
00565
00566 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00567
00568 struct iax_firmware {
00569 AST_LIST_ENTRY(iax_firmware) list;
00570 int fd;
00571 int mmaplen;
00572 int dead;
00573 struct ast_iax2_firmware_header *fwh;
00574 unsigned char *buf;
00575 };
00576
00577 enum iax_reg_state {
00578 REG_STATE_UNREGISTERED = 0,
00579 REG_STATE_REGSENT,
00580 REG_STATE_AUTHSENT,
00581 REG_STATE_REGISTERED,
00582 REG_STATE_REJECTED,
00583 REG_STATE_TIMEOUT,
00584 REG_STATE_NOAUTH
00585 };
00586
00587 enum iax_transfer_state {
00588 TRANSFER_NONE = 0,
00589 TRANSFER_BEGIN,
00590 TRANSFER_READY,
00591 TRANSFER_RELEASED,
00592 TRANSFER_PASSTHROUGH,
00593 TRANSFER_MBEGIN,
00594 TRANSFER_MREADY,
00595 TRANSFER_MRELEASED,
00596 TRANSFER_MPASSTHROUGH,
00597 TRANSFER_MEDIA,
00598 TRANSFER_MEDIAPASS
00599 };
00600
00601 struct iax2_registry {
00602 struct ast_sockaddr addr;
00603 char username[80];
00604 char secret[80];
00605 int expire;
00606 int refresh;
00607 enum iax_reg_state regstate;
00608 int messages;
00609 int callno;
00610 struct sockaddr_in us;
00611 struct ast_dnsmgr_entry *dnsmgr;
00612 AST_LIST_ENTRY(iax2_registry) entry;
00613 };
00614
00615 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00616
00617
00618 #define MIN_RETRY_TIME 100
00619 #define MAX_RETRY_TIME 10000
00620
00621 #define MAX_JITTER_BUFFER 50
00622 #define MIN_JITTER_BUFFER 10
00623
00624 #define DEFAULT_TRUNKDATA 640 * 10
00625
00626 #define MAX_TIMESTAMP_SKEW 160
00627
00628
00629 #define TS_GAP_FOR_JB_RESYNC 5000
00630
00631
00632 #define MARK_IAX_SUBCLASS_TX 0x8000
00633
00634 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00635 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00636 static int iaxdynamicthreadcount = 0;
00637 static int iaxdynamicthreadnum = 0;
00638 static int iaxactivethreadcount = 0;
00639
00640 struct iax_rr {
00641 int jitter;
00642 int losspct;
00643 int losscnt;
00644 int packets;
00645 int delay;
00646 int dropped;
00647 int ooo;
00648 };
00649
00650 struct iax2_pvt_ref;
00651
00652 struct chan_iax2_pvt {
00653
00654 int sockfd;
00655
00656 format_t voiceformat;
00657
00658 format_t videoformat;
00659
00660 format_t svoiceformat;
00661
00662 format_t svideoformat;
00663
00664 format_t capability;
00665
00666 unsigned int last;
00667
00668 unsigned int lastsent;
00669
00670 unsigned int lastvsent;
00671
00672 unsigned int nextpred;
00673
00674 int first_iax_message;
00675
00676 int last_iax_message;
00677
00678 unsigned int notsilenttx:1;
00679
00680 unsigned int pingtime;
00681
00682 int maxtime;
00683
00684 struct sockaddr_in addr;
00685
00686 struct ast_codec_pref prefs;
00687
00688 struct ast_codec_pref rprefs;
00689
00690 unsigned short callno;
00691
00692 struct callno_entry *callno_entry;
00693
00694 unsigned short peercallno;
00695
00696
00697
00698 format_t chosenformat;
00699
00700 format_t peerformat;
00701
00702 format_t peercapability;
00703
00704 struct timeval offset;
00705
00706 struct timeval rxcore;
00707
00708 jitterbuf *jb;
00709
00710 int jbid;
00711
00712 int lag;
00713
00714 int error;
00715
00716 struct ast_channel *owner;
00717
00718 struct ast_flags state;
00719
00720 int expiry;
00721
00722 unsigned char oseqno;
00723
00724 unsigned char rseqno;
00725
00726 unsigned char iseqno;
00727
00728 unsigned char aseqno;
00729
00730 AST_DECLARE_STRING_FIELDS(
00731
00732 AST_STRING_FIELD(peer);
00733
00734 AST_STRING_FIELD(context);
00735
00736 AST_STRING_FIELD(cid_num);
00737 AST_STRING_FIELD(cid_name);
00738
00739 AST_STRING_FIELD(ani);
00740
00741 AST_STRING_FIELD(dnid);
00742
00743 AST_STRING_FIELD(rdnis);
00744
00745 AST_STRING_FIELD(exten);
00746
00747 AST_STRING_FIELD(username);
00748
00749 AST_STRING_FIELD(secret);
00750
00751 AST_STRING_FIELD(challenge);
00752
00753 AST_STRING_FIELD(inkeys);
00754
00755 AST_STRING_FIELD(outkey);
00756
00757 AST_STRING_FIELD(language);
00758
00759 AST_STRING_FIELD(host);
00760
00761 AST_STRING_FIELD(dproot);
00762 AST_STRING_FIELD(accountcode);
00763 AST_STRING_FIELD(mohinterpret);
00764 AST_STRING_FIELD(mohsuggest);
00765
00766 AST_STRING_FIELD(osptoken);
00767
00768 AST_STRING_FIELD(parkinglot);
00769 );
00770
00771 int authrej;
00772
00773 int authmethods;
00774
00775 int encmethods;
00776
00777 ast_aes_encrypt_key ecx;
00778
00779 ast_aes_decrypt_key mydcx;
00780
00781 ast_aes_decrypt_key dcx;
00782
00783
00784 int keyrotateid;
00785
00786 unsigned char semirand[32];
00787
00788 struct iax2_registry *reg;
00789
00790 struct iax2_peer *peerpoke;
00791
00792 uint64_t flags;
00793 int adsi;
00794
00795
00796 enum iax_transfer_state transferring;
00797
00798 int transferid;
00799
00800 struct sockaddr_in transfer;
00801
00802 unsigned short transfercallno;
00803
00804 ast_aes_encrypt_key tdcx;
00805
00806
00807 int peeradsicpe;
00808
00809
00810 unsigned short bridgecallno;
00811
00812 int pingid;
00813 int lagid;
00814 int autoid;
00815 int authid;
00816 int authfail;
00817 int initid;
00818 int calling_ton;
00819 int calling_tns;
00820 int calling_pres;
00821 int amaflags;
00822 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00823
00824 struct ast_variable *vars;
00825
00826 struct ast_variable *iaxvars;
00827
00828 struct iax_rr remote_rr;
00829
00830 int min;
00831
00832 int frames_dropped;
00833
00834 int frames_received;
00835
00836 unsigned char calltoken_ie_len;
00837
00838 char hold_signaling;
00839
00840 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00841 };
00842
00843 struct signaling_queue_entry {
00844 struct ast_frame f;
00845 AST_LIST_ENTRY(signaling_queue_entry) next;
00846 };
00847
00848
00849 static struct ao2_container *callno_pool;
00850
00851
00852 static struct ao2_container *callno_pool_trunk;
00853
00854 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 static AST_LIST_HEAD_NOLOCK(, iax_frame) frame_queue[IAX_MAX_CALLS];
00866
00867 static struct ast_taskprocessor *transmit_processor;
00868
00869 static int randomcalltokendata;
00870
00871 static const time_t MAX_CALLTOKEN_DELAY = 10;
00872
00873
00874
00875
00876
00877
00878
00879
00880 #ifdef LOW_MEMORY
00881 #define MAX_PEER_BUCKETS 17
00882 #else
00883 #define MAX_PEER_BUCKETS 563
00884 #endif
00885 static struct ao2_container *peers;
00886
00887 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00888 static struct ao2_container *users;
00889
00890
00891 static struct ao2_container *peercnts;
00892
00893
00894 static struct ao2_container *callno_limits;
00895
00896
00897 static struct ao2_container *calltoken_ignores;
00898
00899 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00900
00901 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00902
00903 static uint16_t global_maxcallno;
00904
00905
00906 static uint16_t global_maxcallno_nonval;
00907
00908 static uint16_t total_nonval_callno_used = 0;
00909
00910
00911
00912 struct peercnt {
00913
00914 unsigned long addr;
00915
00916 uint16_t cur;
00917
00918 uint16_t limit;
00919
00920
00921 unsigned char reg;
00922 };
00923
00924
00925 struct addr_range {
00926
00927 struct ast_ha ha;
00928
00929 uint16_t limit;
00930
00931 unsigned char delme;
00932 };
00933
00934 struct callno_entry {
00935
00936 uint16_t callno;
00937
00938 unsigned char validated;
00939 };
00940
00941 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00942
00943 enum {
00944
00945 CACHE_FLAG_EXISTS = (1 << 0),
00946
00947 CACHE_FLAG_NONEXISTENT = (1 << 1),
00948
00949 CACHE_FLAG_CANEXIST = (1 << 2),
00950
00951 CACHE_FLAG_PENDING = (1 << 3),
00952
00953 CACHE_FLAG_TIMEOUT = (1 << 4),
00954
00955 CACHE_FLAG_TRANSMITTED = (1 << 5),
00956
00957 CACHE_FLAG_UNKNOWN = (1 << 6),
00958
00959 CACHE_FLAG_MATCHMORE = (1 << 7),
00960 };
00961
00962 struct iax2_dpcache {
00963 char peercontext[AST_MAX_CONTEXT];
00964 char exten[AST_MAX_EXTENSION];
00965 struct timeval orig;
00966 struct timeval expiry;
00967 int flags;
00968 unsigned short callno;
00969 int waiters[256];
00970 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00971 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00972 };
00973
00974 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00975
00976 static void reg_source_db(struct iax2_peer *p);
00977 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00978 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00979
00980 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00981 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags);
00982 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00983
00984 enum iax2_thread_iostate {
00985 IAX_IOSTATE_IDLE,
00986 IAX_IOSTATE_READY,
00987 IAX_IOSTATE_PROCESSING,
00988 IAX_IOSTATE_SCHEDREADY,
00989 };
00990
00991 enum iax2_thread_type {
00992 IAX_THREAD_TYPE_POOL,
00993 IAX_THREAD_TYPE_DYNAMIC,
00994 };
00995
00996 struct iax2_pkt_buf {
00997 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00998 size_t len;
00999 unsigned char buf[1];
01000 };
01001
01002 struct iax2_thread {
01003 AST_LIST_ENTRY(iax2_thread) list;
01004 enum iax2_thread_type type;
01005 enum iax2_thread_iostate iostate;
01006 #ifdef SCHED_MULTITHREADED
01007 void (*schedfunc)(const void *);
01008 const void *scheddata;
01009 #endif
01010 #ifdef DEBUG_SCHED_MULTITHREAD
01011 char curfunc[80];
01012 #endif
01013 int actions;
01014 pthread_t threadid;
01015 int threadnum;
01016 struct sockaddr_in iosin;
01017 unsigned char readbuf[4096];
01018 unsigned char *buf;
01019 ssize_t buf_len;
01020 size_t buf_size;
01021 int iofd;
01022 time_t checktime;
01023 ast_mutex_t lock;
01024 ast_cond_t cond;
01025 ast_mutex_t init_lock;
01026 ast_cond_t init_cond;
01027
01028
01029
01030
01031 struct {
01032 unsigned short callno;
01033 struct sockaddr_in sin;
01034 unsigned char type;
01035 unsigned char csub;
01036 } ffinfo;
01037
01038
01039
01040 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
01041 unsigned char stop;
01042 };
01043
01044
01045 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
01046 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
01047 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
01048
01049 static void *iax2_process_thread(void *data);
01050 static void iax2_destroy(int callno);
01051
01052 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
01053 {
01054 ast_mutex_lock(lock);
01055 ast_cond_signal(cond);
01056 ast_mutex_unlock(lock);
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 static struct ao2_container *iax_peercallno_pvts;
01079
01080
01081
01082
01083
01084
01085
01086
01087 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
01088
01089
01090
01091
01092
01093
01094 static struct ao2_container *iax_transfercallno_pvts;
01095
01096
01097
01098 #define TRUNK_CALL_START (IAX_MAX_CALLS / 2)
01099
01100
01101 static struct sockaddr_in debugaddr;
01102
01103 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
01104 {
01105 if (iaxdebug ||
01106 (sin && debugaddr.sin_addr.s_addr &&
01107 (!ntohs(debugaddr.sin_port) ||
01108 debugaddr.sin_port == sin->sin_port) &&
01109 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01110 if (iaxdebug) {
01111 iax_showframe(f, fhi, rx, sin, datalen);
01112 } else {
01113 iaxdebug = 1;
01114 iax_showframe(f, fhi, rx, sin, datalen);
01115 iaxdebug = 0;
01116 }
01117 }
01118 }
01119
01120 static void iax_debug_output(const char *data)
01121 {
01122 if (iaxdebug)
01123 ast_verbose("%s", data);
01124 }
01125
01126 static void iax_error_output(const char *data)
01127 {
01128 ast_log(LOG_WARNING, "%s", data);
01129 }
01130
01131 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
01132 {
01133 va_list args;
01134 char buf[1024];
01135
01136 va_start(args, fmt);
01137 vsnprintf(buf, sizeof(buf), fmt, args);
01138 va_end(args);
01139
01140 ast_log(LOG_ERROR, "%s", buf);
01141 }
01142
01143 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01144 {
01145 va_list args;
01146 char buf[1024];
01147
01148 va_start(args, fmt);
01149 vsnprintf(buf, sizeof(buf), fmt, args);
01150 va_end(args);
01151
01152 ast_log(LOG_WARNING, "%s", buf);
01153 }
01154
01155 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01156 {
01157 va_list args;
01158 char buf[1024];
01159
01160 va_start(args, fmt);
01161 vsnprintf(buf, sizeof(buf), fmt, args);
01162 va_end(args);
01163
01164 ast_verbose("%s", buf);
01165 }
01166
01167 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);
01168 static int expire_registry(const void *data);
01169 static int iax2_answer(struct ast_channel *c);
01170 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01171 static int iax2_devicestate(void *data);
01172 static int iax2_digit_begin(struct ast_channel *c, char digit);
01173 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01174 static int iax2_do_register(struct iax2_registry *reg);
01175 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01176 static int iax2_hangup(struct ast_channel *c);
01177 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01178 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01179 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force);
01180 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01181 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01182 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01183 static int iax2_sendtext(struct ast_channel *c, const char *text);
01184 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01185 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen);
01186 static int iax2_transfer(struct ast_channel *c, const char *dest);
01187 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01188 static int iax2_sched_add(struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data);
01189
01190 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01191 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01192 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01193 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01194 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01195 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01196 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
01197 static struct ast_frame *iax2_read(struct ast_channel *c);
01198 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01199 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01200 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime);
01201 static void *iax2_dup_variable_datastore(void *);
01202 static void prune_peers(void);
01203 static void prune_users(void);
01204 static void iax2_free_variable_datastore(void *);
01205
01206 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01207 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01208 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01209 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01210 static void build_rand_pad(unsigned char *buf, ssize_t len);
01211 static struct callno_entry *get_unused_callno(int trunk, int validated);
01212 static int replace_callno(const void *obj);
01213 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01214 static void network_change_event_cb(const struct ast_event *, void *);
01215
01216 static const struct ast_channel_tech iax2_tech = {
01217 .type = "IAX2",
01218 .description = tdesc,
01219 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01220 .properties = AST_CHAN_TP_WANTSJITTER,
01221 .requester = iax2_request,
01222 .devicestate = iax2_devicestate,
01223 .send_digit_begin = iax2_digit_begin,
01224 .send_digit_end = iax2_digit_end,
01225 .send_text = iax2_sendtext,
01226 .send_image = iax2_sendimage,
01227 .send_html = iax2_sendhtml,
01228 .call = iax2_call,
01229 .hangup = iax2_hangup,
01230 .answer = iax2_answer,
01231 .read = iax2_read,
01232 .write = iax2_write,
01233 .write_video = iax2_write,
01234 .indicate = iax2_indicate,
01235 .setoption = iax2_setoption,
01236 .queryoption = iax2_queryoption,
01237 .bridge = iax2_bridge,
01238 .transfer = iax2_transfer,
01239 .fixup = iax2_fixup,
01240 .func_channel_read = acf_channel_read,
01241 };
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 static void iax2_lock_owner(int callno)
01261 {
01262 for (;;) {
01263 if (!iaxs[callno] || !iaxs[callno]->owner) {
01264
01265 break;
01266 }
01267 if (!ast_channel_trylock(iaxs[callno]->owner)) {
01268
01269 break;
01270 }
01271
01272 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01273 }
01274 }
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284 static int iax2_is_control_frame_allowed(int subtype)
01285 {
01286 enum ast_control_frame_type control = subtype;
01287 int is_allowed;
01288
01289
01290
01291
01292
01293
01294 if (subtype == -1) {
01295 return -1;
01296 }
01297
01298
01299 is_allowed = 0;
01300
01301
01302
01303
01304
01305 switch (control) {
01306
01307
01308
01309 case AST_CONTROL_HANGUP:
01310 case AST_CONTROL_RING:
01311 case AST_CONTROL_RINGING:
01312 case AST_CONTROL_ANSWER:
01313 case AST_CONTROL_BUSY:
01314 case AST_CONTROL_TAKEOFFHOOK:
01315 case AST_CONTROL_OFFHOOK:
01316 case AST_CONTROL_CONGESTION:
01317 case AST_CONTROL_FLASH:
01318 case AST_CONTROL_WINK:
01319 case AST_CONTROL_OPTION:
01320 case AST_CONTROL_RADIO_KEY:
01321 case AST_CONTROL_RADIO_UNKEY:
01322 case AST_CONTROL_PROGRESS:
01323 case AST_CONTROL_PROCEEDING:
01324 case AST_CONTROL_HOLD:
01325 case AST_CONTROL_UNHOLD:
01326 case AST_CONTROL_VIDUPDATE:
01327 case AST_CONTROL_CONNECTED_LINE:
01328 case AST_CONTROL_REDIRECTING:
01329 case AST_CONTROL_T38_PARAMETERS:
01330 case AST_CONTROL_AOC:
01331 case AST_CONTROL_INCOMPLETE:
01332 is_allowed = -1;
01333 break;
01334
01335
01336
01337
01338 case _XXX_AST_CONTROL_T38:
01339
01340 case AST_CONTROL_SRCUPDATE:
01341
01342 case AST_CONTROL_TRANSFER:
01343
01344 case AST_CONTROL_CC:
01345
01346 case AST_CONTROL_SRCCHANGE:
01347
01348 case AST_CONTROL_READ_ACTION:
01349
01350 case AST_CONTROL_END_OF_Q:
01351
01352 case AST_CONTROL_UPDATE_RTP_PEER:
01353
01354 break;
01355 }
01356 return is_allowed;
01357 }
01358
01359 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01360 {
01361
01362
01363
01364 }
01365
01366 static void network_change_event_subscribe(void)
01367 {
01368 if (!network_change_event_subscription) {
01369 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE,
01370 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END);
01371 }
01372 }
01373
01374 static void network_change_event_unsubscribe(void)
01375 {
01376 if (network_change_event_subscription) {
01377 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription);
01378 }
01379 }
01380
01381 static int network_change_event_sched_cb(const void *data)
01382 {
01383 struct iax2_registry *reg;
01384 network_change_event_sched_id = -1;
01385 AST_LIST_LOCK(®istrations);
01386 AST_LIST_TRAVERSE(®istrations, reg, entry) {
01387 iax2_do_register(reg);
01388 }
01389 AST_LIST_UNLOCK(®istrations);
01390
01391 return 0;
01392 }
01393
01394 static void network_change_event_cb(const struct ast_event *event, void *userdata)
01395 {
01396 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n");
01397 if (network_change_event_sched_id == -1) {
01398 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
01399 }
01400
01401 }
01402
01403
01404
01405
01406 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01407 {
01408 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01409 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01410 pvt->owner ? pvt->owner->name : "",
01411 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01412 }
01413
01414 static const struct ast_datastore_info iax2_variable_datastore_info = {
01415 .type = "IAX2_VARIABLE",
01416 .duplicate = iax2_dup_variable_datastore,
01417 .destroy = iax2_free_variable_datastore,
01418 };
01419
01420 static void *iax2_dup_variable_datastore(void *old)
01421 {
01422 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01423 struct ast_var_t *oldvar, *newvar;
01424
01425 newlist = ast_calloc(sizeof(*newlist), 1);
01426 if (!newlist) {
01427 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01428 return NULL;
01429 }
01430
01431 AST_LIST_HEAD_INIT(newlist);
01432 AST_LIST_LOCK(oldlist);
01433 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01434 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01435 if (newvar)
01436 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01437 else
01438 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01439 }
01440 AST_LIST_UNLOCK(oldlist);
01441 return newlist;
01442 }
01443
01444 static void iax2_free_variable_datastore(void *old)
01445 {
01446 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01447 struct ast_var_t *oldvar;
01448
01449 AST_LIST_LOCK(oldlist);
01450 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01451 ast_free(oldvar);
01452 }
01453 AST_LIST_UNLOCK(oldlist);
01454 AST_LIST_HEAD_DESTROY(oldlist);
01455 ast_free(oldlist);
01456 }
01457
01458
01459
01460
01461
01462 static void insert_idle_thread(struct iax2_thread *thread)
01463 {
01464 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01465 AST_LIST_LOCK(&dynamic_list);
01466 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01467 AST_LIST_UNLOCK(&dynamic_list);
01468 } else {
01469 AST_LIST_LOCK(&idle_list);
01470 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01471 AST_LIST_UNLOCK(&idle_list);
01472 }
01473
01474 return;
01475 }
01476
01477 static struct iax2_thread *find_idle_thread(void)
01478 {
01479 struct iax2_thread *thread = NULL;
01480
01481
01482 AST_LIST_LOCK(&idle_list);
01483 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01484 AST_LIST_UNLOCK(&idle_list);
01485
01486
01487 if (thread) {
01488 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01489 return thread;
01490 }
01491
01492
01493 AST_LIST_LOCK(&dynamic_list);
01494 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01495 AST_LIST_UNLOCK(&dynamic_list);
01496
01497
01498 if (thread) {
01499 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01500 return thread;
01501 }
01502
01503
01504 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01505 return NULL;
01506
01507
01508 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01509 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01510 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01511
01512
01513 ast_mutex_init(&thread->lock);
01514 ast_cond_init(&thread->cond, NULL);
01515 ast_mutex_init(&thread->init_lock);
01516 ast_cond_init(&thread->init_cond, NULL);
01517 ast_mutex_lock(&thread->init_lock);
01518
01519
01520 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01521 ast_cond_destroy(&thread->cond);
01522 ast_mutex_destroy(&thread->lock);
01523 ast_mutex_unlock(&thread->init_lock);
01524 ast_cond_destroy(&thread->init_cond);
01525 ast_mutex_destroy(&thread->init_lock);
01526 ast_free(thread);
01527 return NULL;
01528 }
01529
01530
01531
01532 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01533
01534
01535 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01536
01537
01538 ast_mutex_unlock(&thread->init_lock);
01539
01540 return thread;
01541 }
01542
01543 #ifdef SCHED_MULTITHREADED
01544 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01545 {
01546 struct iax2_thread *thread;
01547 static time_t lasterror;
01548 time_t t;
01549
01550 thread = find_idle_thread();
01551 if (thread != NULL) {
01552 thread->schedfunc = func;
01553 thread->scheddata = data;
01554 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01555 #ifdef DEBUG_SCHED_MULTITHREAD
01556 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01557 #endif
01558 signal_condition(&thread->lock, &thread->cond);
01559 return 0;
01560 }
01561 time(&t);
01562 if (t != lasterror) {
01563 lasterror = t;
01564 ast_debug(1, "Out of idle IAX2 threads for scheduling! (%s)\n", funcname);
01565 }
01566
01567 return -1;
01568 }
01569 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01570 #endif
01571
01572 static int iax2_sched_replace(int id, struct ast_sched_thread *st, int when,
01573 ast_sched_cb callback, const void *data)
01574 {
01575 ast_sched_thread_del(st, id);
01576
01577 return ast_sched_thread_add(st, when, callback, data);
01578 }
01579
01580 static int iax2_sched_add(struct ast_sched_thread *st, int when,
01581 ast_sched_cb callback, const void *data)
01582 {
01583 return ast_sched_thread_add(st, when, callback, data);
01584 }
01585
01586 static int send_ping(const void *data);
01587
01588 static void __send_ping(const void *data)
01589 {
01590 int callno = (long) data;
01591
01592 ast_mutex_lock(&iaxsl[callno]);
01593
01594 if (iaxs[callno]) {
01595 if (iaxs[callno]->peercallno) {
01596 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01597 if (iaxs[callno]->pingid != DONT_RESCHEDULE) {
01598 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01599 }
01600 }
01601 } else {
01602 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01603 }
01604
01605 ast_mutex_unlock(&iaxsl[callno]);
01606 }
01607
01608 static int send_ping(const void *data)
01609 {
01610 int callno = (long) data;
01611 ast_mutex_lock(&iaxsl[callno]);
01612 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) {
01613 iaxs[callno]->pingid = -1;
01614 }
01615 ast_mutex_unlock(&iaxsl[callno]);
01616
01617 #ifdef SCHED_MULTITHREADED
01618 if (schedule_action(__send_ping, data))
01619 #endif
01620 __send_ping(data);
01621
01622 return 0;
01623 }
01624
01625 static void encmethods_to_str(int e, struct ast_str **buf)
01626 {
01627 ast_str_set(buf, 0, "(");
01628 if (e & IAX_ENCRYPT_AES128) {
01629 ast_str_append(buf, 0, "aes128");
01630 }
01631 if (e & IAX_ENCRYPT_KEYROTATE) {
01632 ast_str_append(buf, 0, ",keyrotate");
01633 }
01634 if (ast_str_strlen(*buf) > 1) {
01635 ast_str_append(buf, 0, ")");
01636 } else {
01637 ast_str_set(buf, 0, "No");
01638 }
01639 }
01640
01641 static int get_encrypt_methods(const char *s)
01642 {
01643 int e;
01644 if (!strcasecmp(s, "aes128"))
01645 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01646 else if (ast_true(s))
01647 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01648 else
01649 e = 0;
01650 return e;
01651 }
01652
01653 static int send_lagrq(const void *data);
01654
01655 static void __send_lagrq(const void *data)
01656 {
01657 int callno = (long) data;
01658
01659 ast_mutex_lock(&iaxsl[callno]);
01660
01661 if (iaxs[callno]) {
01662 if (iaxs[callno]->peercallno) {
01663 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01664 if (iaxs[callno]->lagid != DONT_RESCHEDULE) {
01665 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01666 }
01667 }
01668 } else {
01669 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01670 }
01671
01672 ast_mutex_unlock(&iaxsl[callno]);
01673 }
01674
01675 static int send_lagrq(const void *data)
01676 {
01677 int callno = (long) data;
01678 ast_mutex_lock(&iaxsl[callno]);
01679 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) {
01680 iaxs[callno]->lagid = -1;
01681 }
01682 ast_mutex_unlock(&iaxsl[callno]);
01683
01684 #ifdef SCHED_MULTITHREADED
01685 if (schedule_action(__send_lagrq, data))
01686 #endif
01687 __send_lagrq(data);
01688 return 0;
01689 }
01690
01691 static unsigned char compress_subclass(format_t subclass)
01692 {
01693 int x;
01694 int power=-1;
01695
01696 if (subclass < IAX_FLAG_SC_LOG)
01697 return subclass;
01698
01699 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01700 if (subclass & (1LL << x)) {
01701 if (power > -1) {
01702 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
01703 return 0;
01704 } else
01705 power = x;
01706 }
01707 }
01708 return power | IAX_FLAG_SC_LOG;
01709 }
01710
01711 static format_t uncompress_subclass(unsigned char csub)
01712 {
01713
01714 if (csub & IAX_FLAG_SC_LOG) {
01715
01716 if (csub == 0xff)
01717 return -1;
01718 else
01719 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01720 }
01721 else
01722 return csub;
01723 }
01724
01725
01726
01727
01728 static int peer_hash_cb(const void *obj, const int flags)
01729 {
01730 const struct iax2_peer *peer = obj;
01731
01732 return ast_str_hash(peer->name);
01733 }
01734
01735
01736
01737
01738 static int peer_cmp_cb(void *obj, void *arg, int flags)
01739 {
01740 struct iax2_peer *peer = obj, *peer2 = arg;
01741
01742 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01743 }
01744
01745
01746
01747
01748 static int user_hash_cb(const void *obj, const int flags)
01749 {
01750 const struct iax2_user *user = obj;
01751
01752 return ast_str_hash(user->name);
01753 }
01754
01755
01756
01757
01758 static int user_cmp_cb(void *obj, void *arg, int flags)
01759 {
01760 struct iax2_user *user = obj, *user2 = arg;
01761
01762 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01763 }
01764
01765
01766
01767
01768
01769 static struct iax2_peer *find_peer(const char *name, int realtime)
01770 {
01771 struct iax2_peer *peer = NULL;
01772 struct iax2_peer tmp_peer = {
01773 .name = name,
01774 };
01775
01776 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01777
01778
01779 if(!peer && realtime)
01780 peer = realtime_peer(name, NULL);
01781
01782 return peer;
01783 }
01784
01785 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01786 {
01787 ao2_ref(peer, +1);
01788 return peer;
01789 }
01790
01791 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01792 {
01793 ao2_ref(peer, -1);
01794 return NULL;
01795 }
01796
01797 static struct iax2_user *find_user(const char *name)
01798 {
01799 struct iax2_user tmp_user = {
01800 .name = name,
01801 };
01802
01803 return ao2_find(users, &tmp_user, OBJ_POINTER);
01804 }
01805 static inline struct iax2_user *user_ref(struct iax2_user *user)
01806 {
01807 ao2_ref(user, +1);
01808 return user;
01809 }
01810
01811 static inline struct iax2_user *user_unref(struct iax2_user *user)
01812 {
01813 ao2_ref(user, -1);
01814 return NULL;
01815 }
01816
01817 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01818 {
01819 struct iax2_peer *peer = NULL;
01820 int res = 0;
01821 struct ao2_iterator i;
01822
01823 i = ao2_iterator_init(peers, 0);
01824 while ((peer = ao2_iterator_next(&i))) {
01825 struct sockaddr_in peer_addr;
01826
01827 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
01828
01829 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01830 (peer_addr.sin_port == sin.sin_port)) {
01831 ast_copy_string(host, peer->name, len);
01832 peer_unref(peer);
01833 res = 1;
01834 break;
01835 }
01836 peer_unref(peer);
01837 }
01838 ao2_iterator_destroy(&i);
01839
01840 if (!peer) {
01841 peer = realtime_peer(NULL, &sin);
01842 if (peer) {
01843 ast_copy_string(host, peer->name, len);
01844 peer_unref(peer);
01845 res = 1;
01846 }
01847 }
01848
01849 return res;
01850 }
01851
01852
01853
01854 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01855 {
01856
01857 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
01858 struct iax2_user *user;
01859 struct iax2_user tmp_user = {
01860 .name = pvt->username,
01861 };
01862
01863 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01864 if (user) {
01865 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01866 user_unref(user);
01867 }
01868
01869 ast_clear_flag64(pvt, IAX_MAXAUTHREQ);
01870 }
01871
01872 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01873 pvt->pingid = DONT_RESCHEDULE;
01874 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01875 pvt->lagid = DONT_RESCHEDULE;
01876 ast_sched_thread_del(sched, pvt->autoid);
01877 ast_sched_thread_del(sched, pvt->authid);
01878 ast_sched_thread_del(sched, pvt->initid);
01879 ast_sched_thread_del(sched, pvt->jbid);
01880 ast_sched_thread_del(sched, pvt->keyrotateid);
01881 }
01882
01883 static void iax2_frame_free(struct iax_frame *fr)
01884 {
01885 ast_sched_thread_del(sched, fr->retrans);
01886 iax_frame_free(fr);
01887 }
01888
01889 static int scheduled_destroy(const void *vid)
01890 {
01891 unsigned short callno = PTR_TO_CALLNO(vid);
01892 ast_mutex_lock(&iaxsl[callno]);
01893 if (iaxs[callno]) {
01894 if (option_debug) {
01895 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01896 }
01897 iax2_destroy(callno);
01898 }
01899 ast_mutex_unlock(&iaxsl[callno]);
01900 return 0;
01901 }
01902
01903 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01904 {
01905 if (s->f.datalen) {
01906 ast_free(s->f.data.ptr);
01907 }
01908 ast_free(s);
01909 }
01910
01911
01912
01913 static void send_signaling(struct chan_iax2_pvt *pvt)
01914 {
01915 struct signaling_queue_entry *s = NULL;
01916
01917 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01918 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01919 free_signaling_queue_entry(s);
01920 }
01921 pvt->hold_signaling = 0;
01922 }
01923
01924
01925
01926 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01927 {
01928 struct signaling_queue_entry *qe;
01929
01930 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01931 return 1;
01932 } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01933 return -1;
01934 }
01935
01936
01937 qe->f = *f;
01938 if (qe->f.datalen) {
01939
01940 if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) {
01941 free_signaling_queue_entry(qe);
01942 return -1;
01943 }
01944 memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen);
01945 }
01946 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, qe, next);
01947
01948 return 0;
01949 }
01950
01951 static void pvt_destructor(void *obj)
01952 {
01953 struct chan_iax2_pvt *pvt = obj;
01954 struct iax_frame *cur = NULL;
01955 struct signaling_queue_entry *s = NULL;
01956
01957 ast_mutex_lock(&iaxsl[pvt->callno]);
01958
01959 iax2_destroy_helper(pvt);
01960
01961 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01962 pvt->callno_entry = NULL;
01963
01964
01965 ast_set_flag64(pvt, IAX_ALREADYGONE);
01966
01967 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
01968
01969 cur->retries = -1;
01970 }
01971
01972 ast_mutex_unlock(&iaxsl[pvt->callno]);
01973
01974 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01975 free_signaling_queue_entry(s);
01976 }
01977
01978 if (pvt->reg) {
01979 pvt->reg->callno = 0;
01980 }
01981
01982 if (!pvt->owner) {
01983 jb_frame frame;
01984 if (pvt->vars) {
01985 ast_variables_destroy(pvt->vars);
01986 pvt->vars = NULL;
01987 }
01988
01989 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01990 iax2_frame_free(frame.data);
01991 }
01992
01993 jb_destroy(pvt->jb);
01994 ast_string_field_free_memory(pvt);
01995 }
01996 }
01997
01998 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01999 {
02000 struct chan_iax2_pvt *tmp;
02001 jb_conf jbconf;
02002
02003 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
02004 return NULL;
02005 }
02006
02007 if (ast_string_field_init(tmp, 32)) {
02008 ao2_ref(tmp, -1);
02009 tmp = NULL;
02010 return NULL;
02011 }
02012
02013 tmp->prefs = prefs;
02014 tmp->pingid = -1;
02015 tmp->lagid = -1;
02016 tmp->autoid = -1;
02017 tmp->authid = -1;
02018 tmp->initid = -1;
02019 tmp->keyrotateid = -1;
02020
02021 ast_string_field_set(tmp,exten, "s");
02022 ast_string_field_set(tmp,host, host);
02023
02024 tmp->jb = jb_new();
02025 tmp->jbid = -1;
02026 jbconf.max_jitterbuf = maxjitterbuffer;
02027 jbconf.resync_threshold = resyncthreshold;
02028 jbconf.max_contig_interp = maxjitterinterps;
02029 jbconf.target_extra = jittertargetextra;
02030 jb_setconf(tmp->jb,&jbconf);
02031
02032 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
02033
02034 tmp->hold_signaling = 1;
02035 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
02036
02037 return tmp;
02038 }
02039
02040 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
02041 {
02042 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
02043 if (new) {
02044 size_t afdatalen = new->afdatalen;
02045 memcpy(new, fr, sizeof(*new));
02046 iax_frame_wrap(new, &fr->af);
02047 new->afdatalen = afdatalen;
02048 new->data = NULL;
02049 new->datalen = 0;
02050 new->direction = DIRECTION_INGRESS;
02051 new->retrans = -1;
02052 }
02053 return new;
02054 }
02055
02056
02057 enum {
02058
02059 NEW_PREVENT = 0,
02060
02061 NEW_ALLOW = 1,
02062
02063 NEW_FORCE = 2,
02064
02065
02066 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
02067 };
02068
02069 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
02070 {
02071 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
02072 (cur->addr.sin_port == sin->sin_port)) {
02073
02074 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
02075 (check_dcallno ? dcallno == cur->callno : 1) ) {
02076
02077 return 1;
02078 }
02079 }
02080 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
02081 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
02082
02083 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
02084 return 1;
02085 }
02086 return 0;
02087 }
02088
02089 #ifdef IAX_OLD_FIND
02090
02091 static int maxtrunkcall = TRUNK_CALL_START;
02092 static int maxnontrunkcall = 1;
02093
02094 #define update_max_trunk() __update_max_trunk()
02095 #define update_max_nontrunk() __update_max_nontrunk()
02096
02097 static void __update_max_trunk(void)
02098 {
02099 int max = TRUNK_CALL_START;
02100 int x;
02101
02102
02103 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
02104 if (iaxs[x]) {
02105 max = x + 1;
02106 }
02107 }
02108
02109 maxtrunkcall = max;
02110 if (iaxdebug)
02111 ast_debug(1, "New max trunk callno is %d\n", max);
02112 }
02113
02114 static void __update_max_nontrunk(void)
02115 {
02116 int max = 1;
02117 int x;
02118
02119 for (x=1;x<TRUNK_CALL_START - 1; x++) {
02120 if (iaxs[x])
02121 max = x + 1;
02122 }
02123 maxnontrunkcall = max;
02124 if (iaxdebug)
02125 ast_debug(1, "New max nontrunk callno is %d\n", max);
02126 }
02127
02128 #else
02129
02130 #define update_max_trunk() do { } while (0)
02131 #define update_max_nontrunk() do { } while (0)
02132
02133 #endif
02134
02135 static int make_trunk(unsigned short callno, int locked)
02136 {
02137 int x;
02138 int res= 0;
02139 struct callno_entry *callno_entry;
02140 if (iaxs[callno]->oseqno) {
02141 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
02142 return -1;
02143 }
02144 if (callno >= TRUNK_CALL_START) {
02145 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
02146 return -1;
02147 }
02148
02149 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
02150 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
02151 return -1;
02152 }
02153
02154 x = callno_entry->callno;
02155 ast_mutex_lock(&iaxsl[x]);
02156
02157
02158
02159
02160
02161 ast_sched_thread_del(sched, iaxs[callno]->pingid);
02162 ast_sched_thread_del(sched, iaxs[callno]->lagid);
02163 iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
02164 iaxs[x] = iaxs[callno];
02165 iaxs[x]->callno = x;
02166
02167
02168
02169 if (iaxs[x]->callno_entry) {
02170 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
02171 }
02172 iaxs[x]->callno_entry = callno_entry;
02173
02174 iaxs[callno] = NULL;
02175
02176 iaxs[x]->pingid = iax2_sched_add(sched,
02177 ping_time * 1000, send_ping, (void *)(long)x);
02178 iaxs[x]->lagid = iax2_sched_add(sched,
02179 lagrq_time * 1000, send_lagrq, (void *)(long)x);
02180
02181 if (locked)
02182 ast_mutex_unlock(&iaxsl[callno]);
02183 res = x;
02184 if (!locked)
02185 ast_mutex_unlock(&iaxsl[x]);
02186
02187 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
02188
02189 update_max_trunk();
02190 update_max_nontrunk();
02191 return res;
02192 }
02193
02194 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
02195 {
02196 if (!pvt->transfercallno) {
02197 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02198 return;
02199 }
02200
02201 ao2_link(iax_transfercallno_pvts, pvt);
02202 }
02203
02204 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
02205 {
02206 if (!pvt->transfercallno) {
02207 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02208 return;
02209 }
02210
02211 ao2_unlink(iax_transfercallno_pvts, pvt);
02212 }
02213 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
02214 {
02215 if (!pvt->peercallno) {
02216 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02217 return;
02218 }
02219
02220 ao2_link(iax_peercallno_pvts, pvt);
02221 }
02222
02223 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
02224 {
02225 if (!pvt->peercallno) {
02226 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02227 return;
02228 }
02229
02230 ao2_unlink(iax_peercallno_pvts, pvt);
02231 }
02232
02233 static int addr_range_delme_cb(void *obj, void *arg, int flags)
02234 {
02235 struct addr_range *lim = obj;
02236 lim->delme = 1;
02237 return 0;
02238 }
02239
02240 static int addr_range_hash_cb(const void *obj, const int flags)
02241 {
02242 const struct addr_range *lim = obj;
02243 struct sockaddr_in sin;
02244 ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02245 return abs((int) sin.sin_addr.s_addr);
02246 }
02247
02248 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
02249 {
02250 struct addr_range *lim1 = obj, *lim2 = arg;
02251 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02252 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02253 CMP_MATCH | CMP_STOP : 0;
02254 }
02255
02256 static int peercnt_hash_cb(const void *obj, const int flags)
02257 {
02258 const struct peercnt *peercnt = obj;
02259 return abs((int) peercnt->addr);
02260 }
02261
02262 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
02263 {
02264 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02265 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02266 }
02267
02268 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
02269 {
02270 struct addr_range *addr_range = obj;
02271 struct sockaddr_in *sin = arg;
02272 struct sockaddr_in ha_netmask_sin;
02273 struct sockaddr_in ha_addr_sin;
02274
02275 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02276 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02277
02278 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02279 return CMP_MATCH | CMP_STOP;
02280 }
02281 return 0;
02282 }
02283
02284
02285
02286
02287
02288
02289 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
02290 {
02291 struct addr_range *addr_range;
02292 struct iax2_peer *peer = NULL;
02293 struct iax2_user *user = NULL;
02294
02295 const char *find = S_OR(name, "guest");
02296 int res = 1;
02297 int optional = 0;
02298 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02299
02300
02301
02302
02303
02304
02305
02306 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02307 ao2_ref(addr_range, -1);
02308 optional = 1;
02309 }
02310
02311
02312 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02313 calltoken_required = user->calltoken_required;
02314 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02315 calltoken_required = user->calltoken_required;
02316 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02317 calltoken_required = peer->calltoken_required;
02318 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02319 calltoken_required = peer->calltoken_required;
02320 }
02321
02322 if (peer) {
02323 peer_unref(peer);
02324 }
02325 if (user) {
02326 user_unref(user);
02327 }
02328
02329 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);
02330 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02331 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02332 res = 0;
02333 }
02334
02335 return res;
02336 }
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348 static void set_peercnt_limit(struct peercnt *peercnt)
02349 {
02350 uint16_t limit = global_maxcallno;
02351 struct addr_range *addr_range;
02352 struct sockaddr_in sin = {
02353 .sin_addr.s_addr = peercnt->addr,
02354 };
02355
02356
02357 if (peercnt->reg && peercnt->limit) {
02358 return;
02359 }
02360
02361 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02362 limit = addr_range->limit;
02363 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02364 ao2_ref(addr_range, -1);
02365 }
02366
02367 peercnt->limit = limit;
02368 }
02369
02370
02371
02372
02373
02374 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02375 {
02376 struct peercnt *peercnt = obj;
02377
02378 set_peercnt_limit(peercnt);
02379 ast_debug(1, "Reset limits for peercnts table\n");
02380
02381 return 0;
02382 }
02383
02384
02385
02386
02387
02388 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02389 {
02390 struct addr_range *addr_range = obj;
02391
02392 return addr_range->delme ? CMP_MATCH : 0;
02393 }
02394
02395
02396
02397
02398
02399 static void peercnt_modify(unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
02400 {
02401
02402 struct peercnt *peercnt;
02403 struct peercnt tmp = {
02404 .addr = 0,
02405 };
02406 struct sockaddr_in sin;
02407
02408 ast_sockaddr_to_sin(sockaddr, &sin);
02409
02410 tmp.addr = sin.sin_addr.s_addr;
02411
02412 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02413 peercnt->reg = reg;
02414 if (limit) {
02415 peercnt->limit = limit;
02416 } else {
02417 set_peercnt_limit(peercnt);
02418 }
02419 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02420 ao2_ref(peercnt, -1);
02421 }
02422 }
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432 static int peercnt_add(struct sockaddr_in *sin)
02433 {
02434 struct peercnt *peercnt;
02435 unsigned long addr = sin->sin_addr.s_addr;
02436 int res = 0;
02437 struct peercnt tmp = {
02438 .addr = addr,
02439 };
02440
02441
02442
02443
02444
02445
02446
02447 ao2_lock(peercnts);
02448 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02449 ao2_lock(peercnt);
02450 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02451 ao2_lock(peercnt);
02452
02453 peercnt->addr = addr;
02454 set_peercnt_limit(peercnt);
02455
02456
02457 ao2_link(peercnts, peercnt);
02458 } else {
02459 ao2_unlock(peercnts);
02460 return -1;
02461 }
02462
02463
02464 if (peercnt->limit > peercnt->cur) {
02465 peercnt->cur++;
02466 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02467 } else {
02468 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02469 res = -1;
02470 }
02471
02472
02473 ao2_unlock(peercnt);
02474 ao2_unlock(peercnts);
02475 ao2_ref(peercnt, -1);
02476
02477 return res;
02478 }
02479
02480
02481
02482
02483
02484 static void peercnt_remove(struct peercnt *peercnt)
02485 {
02486 struct sockaddr_in sin = {
02487 .sin_addr.s_addr = peercnt->addr,
02488 };
02489
02490
02491
02492
02493
02494
02495
02496 ao2_lock(peercnts);
02497 peercnt->cur--;
02498 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02499
02500 if (peercnt->cur == 0) {
02501 ao2_unlink(peercnts, peercnt);
02502 }
02503 ao2_unlock(peercnts);
02504 }
02505
02506
02507
02508
02509
02510 static int peercnt_remove_cb(const void *obj)
02511 {
02512 struct peercnt *peercnt = (struct peercnt *) obj;
02513
02514 peercnt_remove(peercnt);
02515 ao2_ref(peercnt, -1);
02516
02517 return 0;
02518 }
02519
02520
02521
02522
02523
02524 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02525 {
02526 struct peercnt *peercnt;
02527 struct peercnt tmp = {
02528 .addr = sin->sin_addr.s_addr,
02529 };
02530
02531 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02532 peercnt_remove(peercnt);
02533 ao2_ref(peercnt, -1);
02534 }
02535 return 0;
02536 }
02537
02538
02539
02540
02541
02542 static void build_callno_limits(struct ast_variable *v)
02543 {
02544 struct addr_range *addr_range = NULL;
02545 struct addr_range tmp;
02546 struct ast_ha *ha;
02547 int limit;
02548 int error;
02549 int found;
02550
02551 for (; v; v = v->next) {
02552 limit = -1;
02553 error = 0;
02554 found = 0;
02555 ha = ast_append_ha("permit", v->name, NULL, &error);
02556
02557
02558 if (error) {
02559 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02560 continue;
02561 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02562 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02563 ast_free_ha(ha);
02564 continue;
02565 }
02566
02567 ast_copy_ha(ha, &tmp.ha);
02568
02569 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02570 ao2_lock(addr_range);
02571 found = 1;
02572 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02573 ast_free_ha(ha);
02574 return;
02575 }
02576
02577
02578 ast_copy_ha(ha, &addr_range->ha);
02579 ast_free_ha(ha);
02580 addr_range->limit = limit;
02581 addr_range->delme = 0;
02582
02583
02584 if (found) {
02585 ao2_unlock(addr_range);
02586 } else {
02587 ao2_link(callno_limits, addr_range);
02588 }
02589 ao2_ref(addr_range, -1);
02590 }
02591 }
02592
02593
02594
02595
02596
02597 static int add_calltoken_ignore(const char *addr)
02598 {
02599 struct addr_range tmp;
02600 struct addr_range *addr_range = NULL;
02601 struct ast_ha *ha = NULL;
02602 int error = 0;
02603
02604 if (ast_strlen_zero(addr)) {
02605 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02606 return -1;
02607 }
02608
02609 ha = ast_append_ha("permit", addr, NULL, &error);
02610
02611
02612 if (error) {
02613 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02614 return -1;
02615 }
02616
02617 ast_copy_ha(ha, &tmp.ha);
02618
02619 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02620 ao2_lock(addr_range);
02621 addr_range->delme = 0;
02622 ao2_unlock(addr_range);
02623 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02624
02625 ast_copy_ha(ha, &addr_range->ha);
02626 ao2_link(calltoken_ignores, addr_range);
02627 } else {
02628 ast_free_ha(ha);
02629 return -1;
02630 }
02631
02632 ast_free_ha(ha);
02633 ao2_ref(addr_range, -1);
02634
02635 return 0;
02636 }
02637
02638 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02639 {
02640 struct ao2_iterator i;
02641 struct peercnt *peercnt;
02642 struct sockaddr_in sin;
02643 int found = 0;
02644
02645 switch (cmd) {
02646 case CLI_INIT:
02647 e->command = "iax2 show callnumber usage";
02648 e->usage =
02649 "Usage: iax2 show callnumber usage [IP address]\n"
02650 " Shows current IP addresses which are consuming iax2 call numbers\n";
02651 return NULL;
02652 case CLI_GENERATE:
02653 return NULL;
02654 case CLI_HANDLER:
02655 if (a->argc < 4 || a->argc > 5)
02656 return CLI_SHOWUSAGE;
02657
02658 if (a->argc == 4) {
02659 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02660 }
02661
02662 i = ao2_iterator_init(peercnts, 0);
02663 while ((peercnt = ao2_iterator_next(&i))) {
02664 sin.sin_addr.s_addr = peercnt->addr;
02665 if (a->argc == 5) {
02666 if (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr))) {
02667 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02668 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02669 ao2_ref(peercnt, -1);
02670 found = 1;
02671 break;
02672 }
02673 } else {
02674 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02675 }
02676 ao2_ref(peercnt, -1);
02677 }
02678 ao2_iterator_destroy(&i);
02679
02680 if (a->argc == 4) {
02681 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02682 "Non-CallToken Validated Callno Used: %d\n",
02683 global_maxcallno_nonval,
02684 total_nonval_callno_used);
02685
02686 ast_cli(a->fd, "Total Available Callno: %d\n"
02687 "Regular Callno Available: %d\n"
02688 "Trunk Callno Available: %d\n",
02689 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02690 ao2_container_count(callno_pool),
02691 ao2_container_count(callno_pool_trunk));
02692 } else if (a->argc == 5 && !found) {
02693 ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] );
02694 }
02695
02696
02697 return CLI_SUCCESS;
02698 default:
02699 return NULL;
02700 }
02701 }
02702
02703 static struct callno_entry *get_unused_callno(int trunk, int validated)
02704 {
02705 struct callno_entry *callno_entry = NULL;
02706 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02707 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02708
02709 return NULL;
02710 }
02711
02712
02713
02714 ao2_lock(callno_pool);
02715
02716
02717
02718
02719 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02720 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02721 ao2_unlock(callno_pool);
02722 return NULL;
02723 }
02724
02725
02726
02727 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02728
02729 if (callno_entry) {
02730 callno_entry->validated = validated;
02731 if (!validated) {
02732 total_nonval_callno_used++;
02733 }
02734 }
02735
02736 ao2_unlock(callno_pool);
02737 return callno_entry;
02738 }
02739
02740 static int replace_callno(const void *obj)
02741 {
02742 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02743
02744
02745
02746 ao2_lock(callno_pool);
02747
02748 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02749 total_nonval_callno_used--;
02750 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02751 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02752 }
02753
02754 if (callno_entry->callno < TRUNK_CALL_START) {
02755 ao2_link(callno_pool, callno_entry);
02756 } else {
02757 ao2_link(callno_pool_trunk, callno_entry);
02758 }
02759 ao2_ref(callno_entry, -1);
02760
02761 ao2_unlock(callno_pool);
02762 return 0;
02763 }
02764
02765 static int callno_hash(const void *obj, const int flags)
02766 {
02767 return abs(ast_random());
02768 }
02769
02770 static int create_callno_pools(void)
02771 {
02772 uint16_t i;
02773
02774 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02775 return -1;
02776 }
02777
02778 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02779 return -1;
02780 }
02781
02782
02783 for (i = 2; i < IAX_MAX_CALLS; i++) {
02784 struct callno_entry *callno_entry;
02785
02786 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02787 return -1;
02788 }
02789
02790 callno_entry->callno = i;
02791
02792 if (i < TRUNK_CALL_START) {
02793 ao2_link(callno_pool, callno_entry);
02794 } else {
02795 ao2_link(callno_pool_trunk, callno_entry);
02796 }
02797
02798 ao2_ref(callno_entry, -1);
02799 }
02800
02801 return 0;
02802 }
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02813 {
02814 int i;
02815 struct peercnt *peercnt;
02816 struct peercnt tmp = {
02817 .addr = sin->sin_addr.s_addr,
02818 };
02819
02820 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02821
02822 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02823 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02824 if (i == -1) {
02825 ao2_ref(peercnt, -1);
02826 }
02827 }
02828
02829 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02830 }
02831
02832
02833
02834
02835
02836
02837
02838
02839 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02840 {
02841 if (frametype != AST_FRAME_IAX) {
02842 return 0;
02843 }
02844 switch (subclass) {
02845 case IAX_COMMAND_NEW:
02846 case IAX_COMMAND_REGREQ:
02847 case IAX_COMMAND_FWDOWNL:
02848 case IAX_COMMAND_REGREL:
02849 return 1;
02850 case IAX_COMMAND_POKE:
02851 if (!inbound) {
02852 return 1;
02853 }
02854 break;
02855 }
02856 return 0;
02857 }
02858
02859
02860
02861
02862 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02863 {
02864 int res = 0;
02865 int x;
02866
02867
02868 int validated = (new > NEW_ALLOW) ? 1 : 0;
02869 char host[80];
02870
02871 if (new <= NEW_ALLOW) {
02872 if (callno) {
02873 struct chan_iax2_pvt *pvt;
02874 struct chan_iax2_pvt tmp_pvt = {
02875 .callno = dcallno,
02876 .peercallno = callno,
02877 .transfercallno = callno,
02878
02879 .frames_received = check_dcallno,
02880 };
02881
02882 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02883
02884 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02885 if (return_locked) {
02886 ast_mutex_lock(&iaxsl[pvt->callno]);
02887 }
02888 res = pvt->callno;
02889 ao2_ref(pvt, -1);
02890 pvt = NULL;
02891 return res;
02892 }
02893
02894 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02895 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02896 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02897 if (return_locked) {
02898 ast_mutex_lock(&iaxsl[pvt->callno]);
02899 }
02900 res = pvt->callno;
02901 ao2_ref(pvt, -1);
02902 pvt = NULL;
02903 return res;
02904 }
02905 }
02906
02907
02908 if (dcallno) {
02909 ast_mutex_lock(&iaxsl[dcallno]);
02910 }
02911 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02912 iaxs[dcallno]->peercallno = callno;
02913 res = dcallno;
02914 store_by_peercallno(iaxs[dcallno]);
02915 if (!res || !return_locked) {
02916 ast_mutex_unlock(&iaxsl[dcallno]);
02917 }
02918 return res;
02919 }
02920 if (dcallno) {
02921 ast_mutex_unlock(&iaxsl[dcallno]);
02922 }
02923 #ifdef IAX_OLD_FIND
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935 for (x = 1; !res && x < maxnontrunkcall; x++) {
02936 ast_mutex_lock(&iaxsl[x]);
02937 if (iaxs[x]) {
02938
02939 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02940 res = x;
02941 }
02942 }
02943 if (!res || !return_locked)
02944 ast_mutex_unlock(&iaxsl[x]);
02945 }
02946 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02947 ast_mutex_lock(&iaxsl[x]);
02948 if (iaxs[x]) {
02949
02950 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02951 res = x;
02952 }
02953 }
02954 if (!res || !return_locked)
02955 ast_mutex_unlock(&iaxsl[x]);
02956 }
02957 #endif
02958 }
02959 if (!res && (new >= NEW_ALLOW)) {
02960 struct callno_entry *callno_entry;
02961
02962
02963
02964
02965
02966
02967 if (!iax2_getpeername(*sin, host, sizeof(host)))
02968 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02969
02970 if (peercnt_add(sin)) {
02971
02972
02973 return 0;
02974 }
02975
02976 if (!(callno_entry = get_unused_callno(0, validated))) {
02977
02978
02979 peercnt_remove_by_addr(sin);
02980 ast_log(LOG_WARNING, "No more space\n");
02981 return 0;
02982 }
02983 x = callno_entry->callno;
02984 ast_mutex_lock(&iaxsl[x]);
02985
02986 iaxs[x] = new_iax(sin, host);
02987 update_max_nontrunk();
02988 if (iaxs[x]) {
02989 if (iaxdebug)
02990 ast_debug(1, "Creating new call structure %d\n", x);
02991 iaxs[x]->callno_entry = callno_entry;
02992 iaxs[x]->sockfd = sockfd;
02993 iaxs[x]->addr.sin_port = sin->sin_port;
02994 iaxs[x]->addr.sin_family = sin->sin_family;
02995 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02996 iaxs[x]->peercallno = callno;
02997 iaxs[x]->callno = x;
02998 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02999 iaxs[x]->expiry = min_reg_expire;
03000 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
03001 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
03002 iaxs[x]->amaflags = amaflags;
03003 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
03004 ast_string_field_set(iaxs[x], accountcode, accountcode);
03005 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
03006 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
03007 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
03008
03009 if (iaxs[x]->peercallno) {
03010 store_by_peercallno(iaxs[x]);
03011 }
03012 } else {
03013 ast_log(LOG_WARNING, "Out of resources\n");
03014 ast_mutex_unlock(&iaxsl[x]);
03015 replace_callno(callno_entry);
03016 return 0;
03017 }
03018 if (!return_locked)
03019 ast_mutex_unlock(&iaxsl[x]);
03020 res = x;
03021 }
03022 return res;
03023 }
03024
03025 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
03026 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
03027 }
03028
03029 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
03030
03031 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
03032 }
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044 static int iax2_queue_frame(int callno, struct ast_frame *f)
03045 {
03046 iax2_lock_owner(callno);
03047 if (iaxs[callno] && iaxs[callno]->owner) {
03048 ast_queue_frame(iaxs[callno]->owner, f);
03049 ast_channel_unlock(iaxs[callno]->owner);
03050 }
03051 return 0;
03052 }
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067 static int iax2_queue_hangup(int callno)
03068 {
03069 iax2_lock_owner(callno);
03070 if (iaxs[callno] && iaxs[callno]->owner) {
03071 ast_queue_hangup(iaxs[callno]->owner);
03072 ast_channel_unlock(iaxs[callno]->owner);
03073 }
03074 return 0;
03075 }
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090 static int iax2_queue_control_data(int callno,
03091 enum ast_control_frame_type control, const void *data, size_t datalen)
03092 {
03093 iax2_lock_owner(callno);
03094 if (iaxs[callno] && iaxs[callno]->owner) {
03095 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
03096 ast_channel_unlock(iaxs[callno]->owner);
03097 }
03098 return 0;
03099 }
03100 static void destroy_firmware(struct iax_firmware *cur)
03101 {
03102
03103 if (cur->fwh) {
03104 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
03105 }
03106 close(cur->fd);
03107 ast_free(cur);
03108 }
03109
03110 static int try_firmware(char *s)
03111 {
03112 struct stat stbuf;
03113 struct iax_firmware *cur = NULL;
03114 int ifd, fd, res, len, chunk;
03115 struct ast_iax2_firmware_header *fwh, fwh2;
03116 struct MD5Context md5;
03117 unsigned char sum[16], buf[1024];
03118 char *s2, *last;
03119
03120 s2 = ast_alloca(strlen(s) + 100);
03121
03122 last = strrchr(s, '/');
03123 if (last)
03124 last++;
03125 else
03126 last = s;
03127
03128 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03129
03130 if ((res = stat(s, &stbuf) < 0)) {
03131 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03132 return -1;
03133 }
03134
03135
03136 if (S_ISDIR(stbuf.st_mode))
03137 return -1;
03138 ifd = open(s, O_RDONLY);
03139 if (ifd < 0) {
03140 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03141 return -1;
03142 }
03143 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03144 if (fd < 0) {
03145 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03146 close(ifd);
03147 return -1;
03148 }
03149
03150 unlink(s2);
03151
03152
03153 len = stbuf.st_size;
03154 while(len) {
03155 chunk = len;
03156 if (chunk > sizeof(buf))
03157 chunk = sizeof(buf);
03158 res = read(ifd, buf, chunk);
03159 if (res != chunk) {
03160 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03161 close(ifd);
03162 close(fd);
03163 return -1;
03164 }
03165 res = write(fd, buf, chunk);
03166 if (res != chunk) {
03167 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03168 close(ifd);
03169 close(fd);
03170 return -1;
03171 }
03172 len -= chunk;
03173 }
03174 close(ifd);
03175
03176 lseek(fd, 0, SEEK_SET);
03177 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03178 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03179 close(fd);
03180 return -1;
03181 }
03182 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03183 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03184 close(fd);
03185 return -1;
03186 }
03187 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03188 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03189 close(fd);
03190 return -1;
03191 }
03192 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03193 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03194 close(fd);
03195 return -1;
03196 }
03197 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
03198 if (fwh == MAP_FAILED) {
03199 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03200 close(fd);
03201 return -1;
03202 }
03203 MD5Init(&md5);
03204 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03205 MD5Final(sum, &md5);
03206 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03207 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03208 munmap((void*)fwh, stbuf.st_size);
03209 close(fd);
03210 return -1;
03211 }
03212
03213 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03214 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03215
03216 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03217
03218 break;
03219
03220
03221 munmap((void*)fwh, stbuf.st_size);
03222 close(fd);
03223 return 0;
03224 }
03225 }
03226
03227 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03228 cur->fd = -1;
03229 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03230 }
03231
03232 if (cur) {
03233 if (cur->fwh)
03234 munmap((void*)cur->fwh, cur->mmaplen);
03235 if (cur->fd > -1)
03236 close(cur->fd);
03237 cur->fwh = fwh;
03238 cur->fd = fd;
03239 cur->mmaplen = stbuf.st_size;
03240 cur->dead = 0;
03241 }
03242
03243 return 0;
03244 }
03245
03246 static int iax_check_version(char *dev)
03247 {
03248 int res = 0;
03249 struct iax_firmware *cur = NULL;
03250
03251 if (ast_strlen_zero(dev))
03252 return 0;
03253
03254 AST_LIST_LOCK(&firmwares);
03255 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03256 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03257 res = ntohs(cur->fwh->version);
03258 break;
03259 }
03260 }
03261 AST_LIST_UNLOCK(&firmwares);
03262
03263 return res;
03264 }
03265
03266 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03267 {
03268 int res = -1;
03269 unsigned int bs = desc & 0xff;
03270 unsigned int start = (desc >> 8) & 0xffffff;
03271 unsigned int bytes;
03272 struct iax_firmware *cur;
03273
03274 if (ast_strlen_zero((char *)dev) || !bs)
03275 return -1;
03276
03277 start *= bs;
03278
03279 AST_LIST_LOCK(&firmwares);
03280 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03281 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03282 continue;
03283 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03284 if (start < ntohl(cur->fwh->datalen)) {
03285 bytes = ntohl(cur->fwh->datalen) - start;
03286 if (bytes > bs)
03287 bytes = bs;
03288 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03289 } else {
03290 bytes = 0;
03291 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03292 }
03293 if (bytes == bs)
03294 res = 0;
03295 else
03296 res = 1;
03297 break;
03298 }
03299 AST_LIST_UNLOCK(&firmwares);
03300
03301 return res;
03302 }
03303
03304
03305 static void reload_firmware(int unload)
03306 {
03307 struct iax_firmware *cur = NULL;
03308 DIR *fwd;
03309 struct dirent *de;
03310 char dir[256], fn[256];
03311
03312 AST_LIST_LOCK(&firmwares);
03313
03314
03315 AST_LIST_TRAVERSE(&firmwares, cur, list)
03316 cur->dead = 1;
03317
03318
03319 if (!unload) {
03320 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03321 fwd = opendir(dir);
03322 if (fwd) {
03323 while((de = readdir(fwd))) {
03324 if (de->d_name[0] != '.') {
03325 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03326 if (!try_firmware(fn)) {
03327 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03328 }
03329 }
03330 }
03331 closedir(fwd);
03332 } else
03333 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03334 }
03335
03336
03337 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03338 if (!cur->dead)
03339 continue;
03340 AST_LIST_REMOVE_CURRENT(list);
03341 destroy_firmware(cur);
03342 }
03343 AST_LIST_TRAVERSE_SAFE_END;
03344
03345 AST_LIST_UNLOCK(&firmwares);
03346 }
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356 static int __do_deliver(void *data)
03357 {
03358
03359
03360 struct iax_frame *fr = data;
03361 fr->retrans = -1;
03362 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03363 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03364 iax2_queue_frame(fr->callno, &fr->af);
03365
03366 iax2_frame_free(fr);
03367
03368 return 0;
03369 }
03370
03371 static int handle_error(void)
03372 {
03373
03374
03375
03376 #if 0
03377 struct sockaddr_in *sin;
03378 int res;
03379 struct msghdr m;
03380 struct sock_extended_err e;
03381 m.msg_name = NULL;
03382 m.msg_namelen = 0;
03383 m.msg_iov = NULL;
03384 m.msg_control = &e;
03385 m.msg_controllen = sizeof(e);
03386 m.msg_flags = 0;
03387 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03388 if (res < 0)
03389 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03390 else {
03391 if (m.msg_controllen) {
03392 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03393 if (sin)
03394 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03395 else
03396 ast_log(LOG_WARNING, "No address detected??\n");
03397 } else {
03398 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03399 }
03400 }
03401 #endif
03402 return 0;
03403 }
03404
03405 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03406 {
03407 int res;
03408 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03409 sizeof(*sin));
03410 if (res < 0) {
03411 ast_debug(1, "Received error: %s\n", strerror(errno));
03412 handle_error();
03413 } else
03414 res = 0;
03415 return res;
03416 }
03417
03418 static int send_packet(struct iax_frame *f)
03419 {
03420 int res;
03421 int callno = f->callno;
03422
03423
03424 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03425 return -1;
03426
03427
03428 if (iaxdebug)
03429 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));
03430
03431 if (f->transfer) {
03432 iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03433 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03434 } else {
03435 iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03436 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03437 }
03438 if (res < 0) {
03439 if (iaxdebug)
03440 ast_debug(1, "Received error: %s\n", strerror(errno));
03441 handle_error();
03442 } else
03443 res = 0;
03444
03445 return res;
03446 }
03447
03448
03449
03450
03451
03452 static int iax2_predestroy(int callno)
03453 {
03454 struct ast_channel *c = NULL;
03455 struct chan_iax2_pvt *pvt = iaxs[callno];
03456
03457 if (!pvt)
03458 return -1;
03459
03460 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03461 iax2_destroy_helper(pvt);
03462 ast_set_flag64(pvt, IAX_ALREADYGONE);
03463 }
03464
03465 if ((c = pvt->owner)) {
03466 c->tech_pvt = NULL;
03467 iax2_queue_hangup(callno);
03468 pvt->owner = NULL;
03469 ast_module_unref(ast_module_info->self);
03470 }
03471
03472 return 0;
03473 }
03474
03475 static void iax2_destroy(int callno)
03476 {
03477 struct chan_iax2_pvt *pvt = NULL;
03478 struct ast_channel *owner = NULL;
03479
03480 retry:
03481 if ((pvt = iaxs[callno])) {
03482 #if 0
03483
03484
03485
03486
03487
03488
03489
03490 iax2_destroy_helper(pvt);
03491 #endif
03492 }
03493
03494 owner = pvt ? pvt->owner : NULL;
03495
03496 if (owner) {
03497 if (ast_channel_trylock(owner)) {
03498 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03499 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03500 goto retry;
03501 }
03502 }
03503
03504 if (!owner) {
03505 iaxs[callno] = NULL;
03506 }
03507
03508 if (pvt) {
03509 if (!owner) {
03510 pvt->owner = NULL;
03511 } else {
03512
03513
03514
03515 ast_queue_hangup(owner);
03516 }
03517
03518 if (pvt->peercallno) {
03519 remove_by_peercallno(pvt);
03520 }
03521
03522 if (pvt->transfercallno) {
03523 remove_by_transfercallno(pvt);
03524 }
03525
03526 if (!owner) {
03527 ao2_ref(pvt, -1);
03528 pvt = NULL;
03529 }
03530 }
03531
03532 if (owner) {
03533 ast_channel_unlock(owner);
03534 }
03535
03536 if (callno & TRUNK_CALL_START) {
03537 update_max_trunk();
03538 }
03539 }
03540
03541 static int update_packet(struct iax_frame *f)
03542 {
03543
03544 struct ast_iax2_full_hdr *fh = f->data;
03545 struct ast_frame af;
03546
03547
03548 if (f->encmethods) {
03549 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03550 }
03551
03552 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03553
03554 f->iseqno = iaxs[f->callno]->iseqno;
03555 fh->iseqno = f->iseqno;
03556
03557
03558 if (f->encmethods) {
03559
03560
03561 build_rand_pad(f->semirand, sizeof(f->semirand));
03562 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03563 }
03564 return 0;
03565 }
03566
03567 static int attempt_transmit(const void *data);
03568 static void __attempt_transmit(const void *data)
03569 {
03570
03571
03572 struct iax_frame *f = (struct iax_frame *)data;
03573 int freeme = 0;
03574 int callno = f->callno;
03575
03576
03577 if (callno)
03578 ast_mutex_lock(&iaxsl[callno]);
03579 if (callno && iaxs[callno]) {
03580 if (f->retries < 0) {
03581
03582 freeme = 1;
03583 } else if (f->retries >= max_retries) {
03584
03585 if (f->transfer) {
03586
03587 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03588 } else if (f->final) {
03589 iax2_destroy(callno);
03590 } else {
03591 if (iaxs[callno]->owner) {
03592 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n",
03593 ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),
03594 iaxs[f->callno]->owner->name,
03595 f->af.frametype,
03596 f->af.subclass.integer,
03597 f->ts,
03598 f->oseqno);
03599 }
03600 iaxs[callno]->error = ETIMEDOUT;
03601 if (iaxs[callno]->owner) {
03602 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03603
03604 iax2_queue_frame(callno, &fr);
03605
03606 if (iaxs[callno] && iaxs[callno]->owner)
03607 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03608 } else {
03609 if (iaxs[callno]->reg) {
03610 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03611 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03612 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03613 }
03614 iax2_destroy(callno);
03615 }
03616 }
03617 freeme = 1;
03618 } else {
03619
03620 update_packet(f);
03621
03622 send_packet(f);
03623 f->retries++;
03624
03625 f->retrytime *= 10;
03626 if (f->retrytime > MAX_RETRY_TIME)
03627 f->retrytime = MAX_RETRY_TIME;
03628
03629 if (f->transfer && (f->retrytime > 1000))
03630 f->retrytime = 1000;
03631 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03632 }
03633 } else {
03634
03635 f->retries = -1;
03636 freeme = 1;
03637 }
03638
03639 if (freeme) {
03640
03641 AST_LIST_REMOVE(&frame_queue[callno], f, list);
03642 ast_mutex_unlock(&iaxsl[callno]);
03643 f->retrans = -1;
03644
03645 iax2_frame_free(f);
03646 } else if (callno) {
03647 ast_mutex_unlock(&iaxsl[callno]);
03648 }
03649 }
03650
03651 static int attempt_transmit(const void *data)
03652 {
03653 #ifdef SCHED_MULTITHREADED
03654 if (schedule_action(__attempt_transmit, data))
03655 #endif
03656 __attempt_transmit(data);
03657 return 0;
03658 }
03659
03660 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03661 {
03662 struct iax2_peer *peer = NULL;
03663 struct iax2_user *user = NULL;
03664 static const char * const choices[] = { "all", NULL };
03665 char *cmplt;
03666
03667 switch (cmd) {
03668 case CLI_INIT:
03669 e->command = "iax2 prune realtime";
03670 e->usage =
03671 "Usage: iax2 prune realtime [<peername>|all]\n"
03672 " Prunes object(s) from the cache\n";
03673 return NULL;
03674 case CLI_GENERATE:
03675 if (a->pos == 3) {
03676 cmplt = ast_cli_complete(a->word, choices, a->n);
03677 if (!cmplt)
03678 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03679 return cmplt;
03680 }
03681 return NULL;
03682 }
03683 if (a->argc != 4)
03684 return CLI_SHOWUSAGE;
03685 if (!strcmp(a->argv[3], "all")) {
03686 prune_users();
03687 prune_peers();
03688 ast_cli(a->fd, "Cache flushed successfully.\n");
03689 return CLI_SUCCESS;
03690 }
03691 peer = find_peer(a->argv[3], 0);
03692 user = find_user(a->argv[3]);
03693 if (peer || user) {
03694 if (peer) {
03695 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03696 ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03697 expire_registry(peer_ref(peer));
03698 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03699 } else {
03700 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03701 }
03702 peer_unref(peer);
03703 }
03704 if (user) {
03705 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03706 ast_set_flag64(user, IAX_RTAUTOCLEAR);
03707 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03708 } else {
03709 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03710 }
03711 ao2_unlink(users,user);
03712 user_unref(user);
03713 }
03714 } else {
03715 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03716 }
03717
03718 return CLI_SUCCESS;
03719 }
03720
03721 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03722 {
03723 switch (cmd) {
03724 case CLI_INIT:
03725 e->command = "iax2 test losspct";
03726 e->usage =
03727 "Usage: iax2 test losspct <percentage>\n"
03728 " For testing, throws away <percentage> percent of incoming packets\n";
03729 return NULL;
03730 case CLI_GENERATE:
03731 return NULL;
03732 }
03733 if (a->argc != 4)
03734 return CLI_SHOWUSAGE;
03735
03736 test_losspct = atoi(a->argv[3]);
03737
03738 return CLI_SUCCESS;
03739 }
03740
03741 #ifdef IAXTESTS
03742 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03743 {
03744 switch (cmd) {
03745 case CLI_INIT:
03746 e->command = "iax2 test late";
03747 e->usage =
03748 "Usage: iax2 test late <ms>\n"
03749 " For testing, count the next frame as <ms> ms late\n";
03750 return NULL;
03751 case CLI_GENERATE:
03752 return NULL;
03753 }
03754
03755 if (a->argc != 4)
03756 return CLI_SHOWUSAGE;
03757
03758 test_late = atoi(a->argv[3]);
03759
03760 return CLI_SUCCESS;
03761 }
03762
03763 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03764 {
03765 switch (cmd) {
03766 case CLI_INIT:
03767 e->command = "iax2 test resync";
03768 e->usage =
03769 "Usage: iax2 test resync <ms>\n"
03770 " For testing, adjust all future frames by <ms> ms\n";
03771 return NULL;
03772 case CLI_GENERATE:
03773 return NULL;
03774 }
03775
03776 if (a->argc != 4)
03777 return CLI_SHOWUSAGE;
03778
03779 test_resync = atoi(a->argv[3]);
03780
03781 return CLI_SUCCESS;
03782 }
03783
03784 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03785 {
03786 switch (cmd) {
03787 case CLI_INIT:
03788 e->command = "iax2 test jitter";
03789 e->usage =
03790 "Usage: iax2 test jitter <ms> <pct>\n"
03791 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03792 " percentage of packets. If <pct> is not specified, adds\n"
03793 " jitter to all packets.\n";
03794 return NULL;
03795 case CLI_GENERATE:
03796 return NULL;
03797 }
03798
03799 if (a->argc < 4 || a->argc > 5)
03800 return CLI_SHOWUSAGE;
03801
03802 test_jit = atoi(a->argv[3]);
03803 if (a->argc == 5)
03804 test_jitpct = atoi(a->argv[4]);
03805
03806 return CLI_SUCCESS;
03807 }
03808 #endif
03809
03810
03811
03812 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03813 {
03814 int res = 0;
03815 if (peer->maxms) {
03816 if (peer->lastms < 0) {
03817 ast_copy_string(status, "UNREACHABLE", statuslen);
03818 } else if (peer->lastms > peer->maxms) {
03819 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03820 res = 1;
03821 } else if (peer->lastms) {
03822 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03823 res = 1;
03824 } else {
03825 ast_copy_string(status, "UNKNOWN", statuslen);
03826 }
03827 } else {
03828 ast_copy_string(status, "Unmonitored", statuslen);
03829 res = -1;
03830 }
03831 return res;
03832 }
03833
03834
03835 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03836 {
03837 char status[30];
03838 char cbuf[256];
03839 struct iax2_peer *peer;
03840 char codec_buf[512];
03841 struct ast_str *encmethods = ast_str_alloca(256);
03842 int x = 0, codec = 0, load_realtime = 0;
03843
03844 switch (cmd) {
03845 case CLI_INIT:
03846 e->command = "iax2 show peer";
03847 e->usage =
03848 "Usage: iax2 show peer <name>\n"
03849 " Display details on specific IAX peer\n";
03850 return NULL;
03851 case CLI_GENERATE:
03852 if (a->pos == 3)
03853 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03854 return NULL;
03855 }
03856
03857 if (a->argc < 4)
03858 return CLI_SHOWUSAGE;
03859
03860 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03861
03862 peer = find_peer(a->argv[3], load_realtime);
03863 if (peer) {
03864 struct sockaddr_in peer_addr;
03865
03866 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03867
03868 encmethods_to_str(peer->encmethods, &encmethods);
03869 ast_cli(a->fd, "\n\n");
03870 ast_cli(a->fd, " * Name : %s\n", peer->name);
03871 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03872 ast_cli(a->fd, " Context : %s\n", peer->context);
03873 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03874 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03875 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03876 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03877 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03878 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03879 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03880 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03881 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03882 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03883 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));
03884 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03885 ast_cli(a->fd, " Username : %s\n", peer->username);
03886 ast_cli(a->fd, " Codecs : ");
03887 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03888 ast_cli(a->fd, "%s\n", codec_buf);
03889
03890 ast_cli(a->fd, " Codec Order : (");
03891 for(x = 0; x < 32 ; x++) {
03892 codec = ast_codec_pref_index(&peer->prefs,x);
03893 if(!codec)
03894 break;
03895 ast_cli(a->fd, "%s", ast_getformatname(codec));
03896 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03897 ast_cli(a->fd, "|");
03898 }
03899
03900 if (!x)
03901 ast_cli(a->fd, "none");
03902 ast_cli(a->fd, ")\n");
03903
03904 ast_cli(a->fd, " Status : ");
03905 peer_status(peer, status, sizeof(status));
03906 ast_cli(a->fd, "%s\n",status);
03907 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");
03908 ast_cli(a->fd, "\n");
03909 peer_unref(peer);
03910 } else {
03911 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03912 ast_cli(a->fd, "\n");
03913 }
03914
03915 return CLI_SUCCESS;
03916 }
03917
03918 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
03919 {
03920 int which = 0;
03921 struct iax2_peer *peer;
03922 char *res = NULL;
03923 int wordlen = strlen(word);
03924 struct ao2_iterator i;
03925
03926 i = ao2_iterator_init(peers, 0);
03927 while ((peer = ao2_iterator_next(&i))) {
03928 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03929 && (!flags || ast_test_flag64(peer, flags))) {
03930 res = ast_strdup(peer->name);
03931 peer_unref(peer);
03932 break;
03933 }
03934 peer_unref(peer);
03935 }
03936 ao2_iterator_destroy(&i);
03937
03938 return res;
03939 }
03940
03941 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03942 {
03943 struct iax_frame *cur;
03944 int cnt = 0, dead = 0, final = 0, i = 0;
03945
03946 switch (cmd) {
03947 case CLI_INIT:
03948 e->command = "iax2 show stats";
03949 e->usage =
03950 "Usage: iax2 show stats\n"
03951 " Display statistics on IAX channel driver.\n";
03952 return NULL;
03953 case CLI_GENERATE:
03954 return NULL;
03955 }
03956
03957 if (a->argc != 3)
03958 return CLI_SHOWUSAGE;
03959
03960 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03961 ast_mutex_lock(&iaxsl[i]);
03962 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03963 if (cur->retries < 0)
03964 dead++;
03965 if (cur->final)
03966 final++;
03967 cnt++;
03968 }
03969 ast_mutex_unlock(&iaxsl[i]);
03970 }
03971
03972 ast_cli(a->fd, " IAX Statistics\n");
03973 ast_cli(a->fd, "---------------------\n");
03974 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03975 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03976 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03977 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03978
03979 trunk_timed = trunk_untimed = 0;
03980 if (trunk_maxmtu > trunk_nmaxmtu)
03981 trunk_nmaxmtu = trunk_maxmtu;
03982
03983 return CLI_SUCCESS;
03984 }
03985
03986
03987 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03988 {
03989 int mtuv;
03990
03991 switch (cmd) {
03992 case CLI_INIT:
03993 e->command = "iax2 set mtu";
03994 e->usage =
03995 "Usage: iax2 set mtu <value>\n"
03996 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03997 " zero to disable. Disabling means that the operating system\n"
03998 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03999 " packet exceeds the UDP payload size. This is substantially\n"
04000 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
04001 " greater for G.711 samples.\n";
04002 return NULL;
04003 case CLI_GENERATE:
04004 return NULL;
04005 }
04006
04007 if (a->argc != 4)
04008 return CLI_SHOWUSAGE;
04009 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
04010 mtuv = MAX_TRUNK_MTU;
04011 else
04012 mtuv = atoi(a->argv[3]);
04013
04014 if (mtuv == 0) {
04015 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
04016 global_max_trunk_mtu = 0;
04017 return CLI_SUCCESS;
04018 }
04019 if (mtuv < 172 || mtuv > 4000) {
04020 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
04021 return CLI_SHOWUSAGE;
04022 }
04023 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
04024 global_max_trunk_mtu = mtuv;
04025 return CLI_SUCCESS;
04026 }
04027
04028 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
04029 {
04030 struct iax2_dpcache *dp = NULL;
04031 char tmp[1024], *pc = NULL;
04032 int s, x, y;
04033 struct timeval now = ast_tvnow();
04034
04035 switch (cmd) {
04036 case CLI_INIT:
04037 e->command = "iax2 show cache";
04038 e->usage =
04039 "Usage: iax2 show cache\n"
04040 " Display currently cached IAX Dialplan results.\n";
04041 return NULL;
04042 case CLI_GENERATE:
04043 return NULL;
04044 }
04045
04046 AST_LIST_LOCK(&dpcache);
04047
04048 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
04049
04050 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
04051 s = dp->expiry.tv_sec - now.tv_sec;
04052 tmp[0] = '\0';
04053 if (dp->flags & CACHE_FLAG_EXISTS)
04054 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
04055 if (dp->flags & CACHE_FLAG_NONEXISTENT)
04056 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
04057 if (dp->flags & CACHE_FLAG_CANEXIST)
04058 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
04059 if (dp->flags & CACHE_FLAG_PENDING)
04060 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
04061 if (dp->flags & CACHE_FLAG_TIMEOUT)
04062 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
04063 if (dp->flags & CACHE_FLAG_TRANSMITTED)
04064 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
04065 if (dp->flags & CACHE_FLAG_MATCHMORE)
04066 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
04067 if (dp->flags & CACHE_FLAG_UNKNOWN)
04068 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
04069
04070 if (!ast_strlen_zero(tmp)) {
04071 tmp[strlen(tmp) - 1] = '\0';
04072 } else {
04073 ast_copy_string(tmp, "(none)", sizeof(tmp));
04074 }
04075 y = 0;
04076 pc = strchr(dp->peercontext, '@');
04077 if (!pc) {
04078 pc = dp->peercontext;
04079 } else {
04080 pc++;
04081 }
04082 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
04083 if (dp->waiters[x] > -1)
04084 y++;
04085 }
04086 if (s > 0) {
04087 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
04088 } else {
04089 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
04090 }
04091 }
04092
04093 AST_LIST_UNLOCK(&dpcache);
04094
04095 return CLI_SUCCESS;
04096 }
04097
04098 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
04099
04100 static void unwrap_timestamp(struct iax_frame *fr)
04101 {
04102
04103
04104 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
04105 const int lower_mask = (1 << ts_shift) - 1;
04106 const int upper_mask = ~lower_mask;
04107 const int last_upper = iaxs[fr->callno]->last & upper_mask;
04108
04109 if ( (fr->ts & upper_mask) == last_upper ) {
04110 const int x = fr->ts - iaxs[fr->callno]->last;
04111 const int threshold = (ts_shift == 15) ? 25000 : 50000;
04112
04113 if (x < -threshold) {
04114
04115
04116
04117
04118 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04119 if (iaxdebug)
04120 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04121 } else if (x > threshold) {
04122
04123
04124
04125
04126 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04127 if (iaxdebug)
04128 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04129 }
04130 }
04131 }
04132
04133 static int get_from_jb(const void *p);
04134
04135 static void update_jbsched(struct chan_iax2_pvt *pvt)
04136 {
04137 int when;
04138
04139 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04140
04141 when = jb_next(pvt->jb) - when;
04142
04143 if (when <= 0) {
04144
04145 when = 1;
04146 }
04147
04148 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
04149 CALLNO_TO_PTR(pvt->callno));
04150 }
04151
04152 static void __get_from_jb(const void *p)
04153 {
04154 int callno = PTR_TO_CALLNO(p);
04155 struct chan_iax2_pvt *pvt = NULL;
04156 struct iax_frame *fr;
04157 jb_frame frame;
04158 int ret;
04159 long ms;
04160 long next;
04161 struct timeval now = ast_tvnow();
04162
04163
04164 ast_mutex_lock(&iaxsl[callno]);
04165 pvt = iaxs[callno];
04166 if (!pvt) {
04167
04168 ast_mutex_unlock(&iaxsl[callno]);
04169 return;
04170 }
04171
04172 pvt->jbid = -1;
04173
04174
04175
04176
04177 now.tv_usec += 1000;
04178
04179 ms = ast_tvdiff_ms(now, pvt->rxcore);
04180
04181 if(ms >= (next = jb_next(pvt->jb))) {
04182 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
04183 switch(ret) {
04184 case JB_OK:
04185 fr = frame.data;
04186 __do_deliver(fr);
04187
04188 pvt = iaxs[callno];
04189 break;
04190 case JB_INTERP:
04191 {
04192 struct ast_frame af = { 0, };
04193
04194
04195 af.frametype = AST_FRAME_VOICE;
04196 af.subclass.codec = pvt->voiceformat;
04197 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
04198 af.src = "IAX2 JB interpolation";
04199 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04200 af.offset = AST_FRIENDLY_OFFSET;
04201
04202
04203
04204 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04205 iax2_queue_frame(callno, &af);
04206
04207 pvt = iaxs[callno];
04208 }
04209 }
04210 break;
04211 case JB_DROP:
04212 iax2_frame_free(frame.data);
04213 break;
04214 case JB_NOFRAME:
04215 case JB_EMPTY:
04216
04217 break;
04218 default:
04219
04220 break;
04221 }
04222 }
04223 if (pvt)
04224 update_jbsched(pvt);
04225 ast_mutex_unlock(&iaxsl[callno]);
04226 }
04227
04228 static int get_from_jb(const void *data)
04229 {
04230 #ifdef SCHED_MULTITHREADED
04231 if (schedule_action(__get_from_jb, data))
04232 #endif
04233 __get_from_jb(data);
04234 return 0;
04235 }
04236
04237
04238
04239
04240
04241
04242
04243 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
04244 {
04245 int type, len;
04246 int ret;
04247 int needfree = 0;
04248 struct ast_channel *owner = NULL;
04249 struct ast_channel *bridge = NULL;
04250
04251
04252
04253
04254
04255
04256 if (!fr->af.datalen) {
04257 memset(&fr->af.data, 0, sizeof(fr->af.data));
04258 }
04259
04260
04261 unwrap_timestamp(fr);
04262
04263
04264 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04265 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04266 else {
04267 #if 0
04268 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04269 #endif
04270 fr->af.delivery = ast_tv(0,0);
04271 }
04272
04273 type = JB_TYPE_CONTROL;
04274 len = 0;
04275
04276 if(fr->af.frametype == AST_FRAME_VOICE) {
04277 type = JB_TYPE_VOICE;
04278 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04279 } else if(fr->af.frametype == AST_FRAME_CNG) {
04280 type = JB_TYPE_SILENCE;
04281 }
04282
04283 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04284 if (tsout)
04285 *tsout = fr->ts;
04286 __do_deliver(fr);
04287 return -1;
04288 }
04289
04290 iax2_lock_owner(fr->callno);
04291 if (!iaxs[fr->callno]) {
04292
04293 iax2_frame_free(fr);
04294 return -1;
04295 }
04296 if ((owner = iaxs[fr->callno]->owner))
04297 bridge = ast_bridged_channel(owner);
04298
04299
04300
04301 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04302 jb_frame frame;
04303
04304 ast_channel_unlock(owner);
04305
04306
04307 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04308 __do_deliver(frame.data);
04309
04310 if (!iaxs[fr->callno])
04311 return -1;
04312 }
04313
04314 jb_reset(iaxs[fr->callno]->jb);
04315
04316 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04317
04318
04319 if (tsout)
04320 *tsout = fr->ts;
04321 __do_deliver(fr);
04322 return -1;
04323 }
04324 if (owner) {
04325 ast_channel_unlock(owner);
04326 }
04327
04328
04329
04330 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04331 calc_rxstamp(iaxs[fr->callno],fr->ts));
04332 if (ret == JB_DROP) {
04333 needfree++;
04334 } else if (ret == JB_SCHED) {
04335 update_jbsched(iaxs[fr->callno]);
04336 }
04337 if (tsout)
04338 *tsout = fr->ts;
04339 if (needfree) {
04340
04341 iax2_frame_free(fr);
04342 return -1;
04343 }
04344 return 0;
04345 }
04346
04347 static int transmit_frame(void *data)
04348 {
04349 struct iax_frame *fr = data;
04350
04351 ast_mutex_lock(&iaxsl[fr->callno]);
04352
04353 fr->sentyet = 1;
04354
04355 if (iaxs[fr->callno]) {
04356 send_packet(fr);
04357 }
04358
04359 if (fr->retries < 0) {
04360 ast_mutex_unlock(&iaxsl[fr->callno]);
04361
04362 iax_frame_free(fr);
04363 } else {
04364
04365 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04366 fr->retries++;
04367 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04368 ast_mutex_unlock(&iaxsl[fr->callno]);
04369 }
04370
04371 return 0;
04372 }
04373
04374 static int iax2_transmit(struct iax_frame *fr)
04375 {
04376 fr->sentyet = 0;
04377
04378 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04379 }
04380
04381 static int iax2_digit_begin(struct ast_channel *c, char digit)
04382 {
04383 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04384 }
04385
04386 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04387 {
04388 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04389 }
04390
04391 static int iax2_sendtext(struct ast_channel *c, const char *text)
04392 {
04393
04394 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04395 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04396 }
04397
04398 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04399 {
04400 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04401 }
04402
04403 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04404 {
04405 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04406 }
04407
04408 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04409 {
04410 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04411 ast_mutex_lock(&iaxsl[callno]);
04412 if (iaxs[callno])
04413 iaxs[callno]->owner = newchan;
04414 else
04415 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04416 ast_mutex_unlock(&iaxsl[callno]);
04417 return 0;
04418 }
04419
04420
04421
04422
04423
04424 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04425 {
04426 struct ast_variable *var = NULL;
04427 struct ast_variable *tmp;
04428 struct iax2_peer *peer=NULL;
04429 time_t regseconds = 0, nowtime;
04430 int dynamic=0;
04431
04432 if (peername) {
04433 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04434 if (!var && sin)
04435 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04436 } else if (sin) {
04437 char porta[25];
04438 sprintf(porta, "%d", ntohs(sin->sin_port));
04439 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04440 if (var) {
04441
04442 for (tmp = var; tmp; tmp = tmp->next) {
04443 if (!strcasecmp(tmp->name, "name"))
04444 peername = tmp->value;
04445 }
04446 }
04447 }
04448 if (!var && peername) {
04449 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04450
04451
04452
04453
04454
04455
04456 if (var && sin) {
04457 for (tmp = var; tmp; tmp = tmp->next) {
04458 if (!strcasecmp(tmp->name, "host")) {
04459 struct ast_hostent ahp;
04460 struct hostent *hp;
04461 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
04462
04463 ast_variables_destroy(var);
04464 var = NULL;
04465 }
04466 break;
04467 }
04468 }
04469 }
04470 }
04471 if (!var)
04472 return NULL;
04473
04474 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04475
04476 if (!peer) {
04477 ast_variables_destroy(var);
04478 return NULL;
04479 }
04480
04481 for (tmp = var; tmp; tmp = tmp->next) {
04482
04483 if (!strcasecmp(tmp->name, "type")) {
04484 if (strcasecmp(tmp->value, "friend") &&
04485 strcasecmp(tmp->value, "peer")) {
04486
04487 peer = peer_unref(peer);
04488 break;
04489 }
04490 } else if (!strcasecmp(tmp->name, "regseconds")) {
04491 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04492 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04493 if (!ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE)) {
04494 ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name);
04495 }
04496 } else if (!strcasecmp(tmp->name, "port")) {
04497 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04498 } else if (!strcasecmp(tmp->name, "host")) {
04499 if (!strcasecmp(tmp->value, "dynamic"))
04500 dynamic = 1;
04501 }
04502 }
04503
04504 ast_variables_destroy(var);
04505
04506 if (!peer)
04507 return NULL;
04508
04509 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04510 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04511 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04512 if (peer->expire > -1) {
04513 if (!ast_sched_thread_del(sched, peer->expire)) {
04514 peer->expire = -1;
04515 peer_unref(peer);
04516 }
04517 }
04518 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04519 if (peer->expire == -1)
04520 peer_unref(peer);
04521 }
04522 ao2_link(peers, peer);
04523 if (ast_test_flag64(peer, IAX_DYNAMIC))
04524 reg_source_db(peer);
04525 } else {
04526 ast_set_flag64(peer, IAX_TEMPONLY);
04527 }
04528
04529 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04530 time(&nowtime);
04531 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04532 memset(&peer->addr, 0, sizeof(peer->addr));
04533 realtime_update_peer(peer->name, &peer->addr, 0);
04534 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04535 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04536 }
04537 else {
04538 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04539 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04540 }
04541 }
04542
04543 return peer;
04544 }
04545
04546 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04547 {
04548 struct ast_variable *var;
04549 struct ast_variable *tmp;
04550 struct iax2_user *user=NULL;
04551
04552 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04553 if (!var)
04554 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04555 if (!var && sin) {
04556 char porta[6];
04557 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04558 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04559 if (!var)
04560 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04561 }
04562 if (!var) {
04563 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04564
04565
04566
04567
04568
04569
04570 if (var) {
04571 for (tmp = var; tmp; tmp = tmp->next) {
04572 if (!strcasecmp(tmp->name, "host")) {
04573 struct ast_hostent ahp;
04574 struct hostent *hp;
04575 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
04576
04577 ast_variables_destroy(var);
04578 var = NULL;
04579 }
04580 break;
04581 }
04582 }
04583 }
04584 }
04585 if (!var)
04586 return NULL;
04587
04588 tmp = var;
04589 while(tmp) {
04590
04591 if (!strcasecmp(tmp->name, "type")) {
04592 if (strcasecmp(tmp->value, "friend") &&
04593 strcasecmp(tmp->value, "user")) {
04594 return NULL;
04595 }
04596 }
04597 tmp = tmp->next;
04598 }
04599
04600 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04601
04602 ast_variables_destroy(var);
04603
04604 if (!user)
04605 return NULL;
04606
04607 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04608 ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04609 ao2_link(users, user);
04610 } else {
04611 ast_set_flag64(user, IAX_TEMPONLY);
04612 }
04613
04614 return user;
04615 }
04616
04617 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
04618 {
04619 char port[10];
04620 char regseconds[20];
04621 const char *sysname = ast_config_AST_SYSTEM_NAME;
04622 char *syslabel = NULL;
04623
04624 if (ast_strlen_zero(sysname))
04625 sysname = NULL;
04626 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04627 syslabel = "regserver";
04628
04629 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04630 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04631 ast_update_realtime("iaxpeers", "name", peername,
04632 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port,
04633 "regseconds", regseconds, syslabel, sysname, SENTINEL);
04634 }
04635
04636 struct create_addr_info {
04637 format_t capability;
04638 uint64_t flags;
04639 int maxtime;
04640 int encmethods;
04641 int found;
04642 int sockfd;
04643 int adsi;
04644 char username[80];
04645 char secret[80];
04646 char outkey[80];
04647 char timezone[80];
04648 char prefs[32];
04649 char cid_num[80];
04650 char cid_name[80];
04651 char context[AST_MAX_CONTEXT];
04652 char peercontext[AST_MAX_CONTEXT];
04653 char mohinterpret[MAX_MUSICCLASS];
04654 char mohsuggest[MAX_MUSICCLASS];
04655 };
04656
04657 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04658 {
04659 struct iax2_peer *peer;
04660 int res = -1;
04661 struct ast_codec_pref ourprefs;
04662 struct sockaddr_in peer_addr;
04663
04664 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04665 cai->sockfd = defaultsockfd;
04666 cai->maxtime = 0;
04667 sin->sin_family = AF_INET;
04668
04669 if (!(peer = find_peer(peername, 1))) {
04670 struct ast_sockaddr sin_tmp;
04671
04672 cai->found = 0;
04673 sin_tmp.ss.ss_family = AF_INET;
04674 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04675 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04676 return -1;
04677 }
04678 ast_sockaddr_to_sin(&sin_tmp, sin);
04679 if (sin->sin_port == 0) {
04680 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04681 }
04682
04683
04684 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04685 if (c)
04686 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04687 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04688 return 0;
04689 }
04690
04691 cai->found = 1;
04692
04693 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04694
04695
04696 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04697 goto return_unref;
04698 }
04699
04700
04701 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04702 goto return_unref;
04703
04704 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04705 cai->maxtime = peer->maxms;
04706 cai->capability = peer->capability;
04707 cai->encmethods = peer->encmethods;
04708 cai->sockfd = peer->sockfd;
04709 cai->adsi = peer->adsi;
04710 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04711
04712 if (c) {
04713 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04714 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04715 }
04716 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04717 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04718 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04719 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04720 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04721 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04722 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04723 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04724 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04725 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04726 if (ast_strlen_zero(peer->dbsecret)) {
04727 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04728 } else {
04729 char *family;
04730 char *key = NULL;
04731
04732 family = ast_strdupa(peer->dbsecret);
04733 key = strchr(family, '/');
04734 if (key)
04735 *key++ = '\0';
04736 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04737 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04738 goto return_unref;
04739 }
04740 }
04741
04742 if (peer_addr.sin_addr.s_addr) {
04743 sin->sin_addr = peer_addr.sin_addr;
04744 sin->sin_port = peer_addr.sin_port;
04745 } else {
04746 sin->sin_addr = peer->defaddr.sin_addr;
04747 sin->sin_port = peer->defaddr.sin_port;
04748 }
04749
04750 res = 0;
04751
04752 return_unref:
04753 peer_unref(peer);
04754
04755 return res;
04756 }
04757
04758 static void __auto_congest(const void *nothing)
04759 {
04760 int callno = PTR_TO_CALLNO(nothing);
04761 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04762 ast_mutex_lock(&iaxsl[callno]);
04763 if (iaxs[callno]) {
04764 iaxs[callno]->initid = -1;
04765 iax2_queue_frame(callno, &f);
04766 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04767 }
04768 ast_mutex_unlock(&iaxsl[callno]);
04769 }
04770
04771 static int auto_congest(const void *data)
04772 {
04773 #ifdef SCHED_MULTITHREADED
04774 if (schedule_action(__auto_congest, data))
04775 #endif
04776 __auto_congest(data);
04777 return 0;
04778 }
04779
04780 static unsigned int iax2_datetime(const char *tz)
04781 {
04782 struct timeval t = ast_tvnow();
04783 struct ast_tm tm;
04784 unsigned int tmp;
04785 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04786 tmp = (tm.tm_sec >> 1) & 0x1f;
04787 tmp |= (tm.tm_min & 0x3f) << 5;
04788 tmp |= (tm.tm_hour & 0x1f) << 11;
04789 tmp |= (tm.tm_mday & 0x1f) << 16;
04790 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04791 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04792 return tmp;
04793 }
04794
04795 struct parsed_dial_string {
04796 char *username;
04797 char *password;
04798 char *key;
04799 char *peer;
04800 char *port;
04801 char *exten;
04802 char *context;
04803 char *options;
04804 };
04805
04806 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04807 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04808 int sockfd, struct iax_ie_data *ied)
04809 {
04810 struct {
04811 struct ast_iax2_full_hdr f;
04812 struct iax_ie_data ied;
04813 } data;
04814 size_t size = sizeof(struct ast_iax2_full_hdr);
04815
04816 if (ied) {
04817 size += ied->pos;
04818 memcpy(&data.ied, ied->buf, ied->pos);
04819 }
04820
04821 data.f.scallno = htons(0x8000 | callno);
04822 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS);
04823 data.f.ts = htonl(ts);
04824 data.f.iseqno = seqno;
04825 data.f.oseqno = 0;
04826 data.f.type = AST_FRAME_IAX;
04827 data.f.csub = compress_subclass(command);
04828
04829 iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr));
04830
04831 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04832 }
04833
04834 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04835 {
04836
04837 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04838 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04839 ied->buf[ied->pos++] = 0;
04840 pvt->calltoken_ie_len = 2;
04841 }
04842 }
04843
04844 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04845 {
04846 struct chan_iax2_pvt *pvt = iaxs[callno];
04847 int frametype = f->af.frametype;
04848 int subclass = f->af.subclass.integer;
04849 struct {
04850 struct ast_iax2_full_hdr fh;
04851 struct iax_ie_data ied;
04852 } data = {
04853 .ied.buf = { 0 },
04854 .ied.pos = 0,
04855 };
04856
04857 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04858
04859 if (!pvt) {
04860 return;
04861 }
04862
04863
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04875 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04876 (f->datalen > sizeof(data))) {
04877
04878 return;
04879 }
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889
04890
04891
04892
04893
04894
04895 memcpy(&data, f->data, f->datalen);
04896 data.ied.pos = ie_data_pos;
04897
04898
04899
04900 data.ied.pos -= pvt->calltoken_ie_len;
04901 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04902
04903
04904 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04905
04906
04907 AST_LIST_REMOVE(&frame_queue[callno], f, list);
04908
04909
04910 iax2_frame_free(f);
04911
04912
04913 pvt->oseqno = 0;
04914 pvt->rseqno = 0;
04915 pvt->iseqno = 0;
04916 pvt->aseqno = 0;
04917 if (pvt->peercallno) {
04918 remove_by_peercallno(pvt);
04919 pvt->peercallno = 0;
04920 }
04921
04922
04923 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04924 }
04925
04926 static void requirecalltoken_mark_auto(const char *name, int subclass)
04927 {
04928 struct iax2_user *user = NULL;
04929 struct iax2_peer *peer = NULL;
04930
04931 if (ast_strlen_zero(name)) {
04932 return;
04933 }
04934
04935 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04936 user->calltoken_required = CALLTOKEN_YES;
04937 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04938 peer->calltoken_required = CALLTOKEN_YES;
04939 }
04940
04941 if (peer) {
04942 peer_unref(peer);
04943 }
04944 if (user) {
04945 user_unref(user);
04946 }
04947 }
04948
04949
04950
04951
04952
04953
04954
04955
04956
04957
04958
04959
04960
04961
04962
04963
04964
04965
04966 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04967 struct sockaddr_in *sin, int fd)
04968 {
04969 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04970 #define CALLTOKEN_IE_FORMAT "%u?%s"
04971 struct ast_str *buf = ast_str_alloca(256);
04972 time_t t = time(NULL);
04973 char hash[41];
04974 int subclass = uncompress_subclass(fh->csub);
04975
04976
04977 if (ies->calltoken && !ies->calltokendata) {
04978 struct iax_ie_data ied = {
04979 .buf = { 0 },
04980 .pos = 0,
04981 };
04982
04983
04984 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04985 ast_sha1_hash(hash, ast_str_buffer(buf));
04986
04987 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04988 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04989 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04990
04991 return 1;
04992
04993
04994 } else if (ies->calltoken && ies->calltokendata) {
04995 char *rec_hash = NULL;
04996 char *rec_ts = NULL;
04997 unsigned int rec_time;
04998
04999
05000 rec_hash = strchr((char *) ies->calltokendata, '?');
05001 if (rec_hash) {
05002 *rec_hash++ = '\0';
05003 rec_ts = (char *) ies->calltokendata;
05004 }
05005
05006
05007 if (!rec_hash || !rec_ts) {
05008 goto reject;
05009 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
05010 goto reject;
05011 }
05012
05013
05014 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
05015 ast_sha1_hash(hash, ast_str_buffer(buf));
05016
05017
05018 if (strcmp(hash, rec_hash)) {
05019 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
05020 goto reject;
05021 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
05022 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
05023 goto reject;
05024 }
05025
05026
05027
05028 requirecalltoken_mark_auto(ies->username, subclass);
05029 return 0;
05030
05031
05032 } else {
05033 if (calltoken_required(sin, ies->username, subclass)) {
05034 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"));
05035 goto reject;
05036 }
05037 return 0;
05038 }
05039
05040 reject:
05041
05042 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
05043 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
05044 } else {
05045 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
05046 }
05047
05048 return 1;
05049 }
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060
05061
05062
05063
05064
05065
05066
05067
05068
05069 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
05070 {
05071 if (ast_strlen_zero(data))
05072 return;
05073
05074 pds->peer = strsep(&data, "/");
05075 pds->exten = strsep(&data, "/");
05076 pds->options = data;
05077
05078 if (pds->exten) {
05079 data = pds->exten;
05080 pds->exten = strsep(&data, "@");
05081 pds->context = data;
05082 }
05083
05084 if (strchr(pds->peer, '@')) {
05085 data = pds->peer;
05086 pds->username = strsep(&data, "@");
05087 pds->peer = data;
05088 }
05089
05090 if (pds->username) {
05091 data = pds->username;
05092 pds->username = strsep(&data, ":");
05093 pds->password = data;
05094 }
05095
05096 data = pds->peer;
05097 pds->peer = strsep(&data, ":");
05098 pds->port = data;
05099
05100
05101
05102
05103 if (pds->password && (pds->password[0] == '[')) {
05104 pds->key = ast_strip_quoted(pds->password, "[", "]");
05105 pds->password = NULL;
05106 }
05107 }
05108
05109 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
05110 {
05111 struct sockaddr_in sin;
05112 char *l=NULL, *n=NULL, *tmpstr;
05113 struct iax_ie_data ied;
05114 char *defaultrdest = "s";
05115 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05116 struct parsed_dial_string pds;
05117 struct create_addr_info cai;
05118 struct ast_var_t *var;
05119 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
05120 const char* osp_token_ptr;
05121 unsigned int osp_token_length;
05122 unsigned char osp_block_index;
05123 unsigned int osp_block_length;
05124 unsigned char osp_buffer[256];
05125
05126 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
05127 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
05128 return -1;
05129 }
05130
05131 memset(&cai, 0, sizeof(cai));
05132 cai.encmethods = iax2_encryption;
05133
05134 memset(&pds, 0, sizeof(pds));
05135 tmpstr = ast_strdupa(dest);
05136 parse_dial_string(tmpstr, &pds);
05137
05138 if (ast_strlen_zero(pds.peer)) {
05139 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
05140 return -1;
05141 }
05142 if (!pds.exten) {
05143 pds.exten = defaultrdest;
05144 }
05145 if (create_addr(pds.peer, c, &sin, &cai)) {
05146 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
05147 return -1;
05148 }
05149 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
05150 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
05151 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05152 return -1;
05153 }
05154 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
05155 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
05156 return -1;
05157 }
05158 if (!pds.username && !ast_strlen_zero(cai.username))
05159 pds.username = cai.username;
05160 if (!pds.password && !ast_strlen_zero(cai.secret))
05161 pds.password = cai.secret;
05162 if (!pds.key && !ast_strlen_zero(cai.outkey))
05163 pds.key = cai.outkey;
05164 if (!pds.context && !ast_strlen_zero(cai.peercontext))
05165 pds.context = cai.peercontext;
05166
05167
05168 ast_copy_string(c->context, cai.context, sizeof(c->context));
05169
05170 if (pds.port)
05171 sin.sin_port = htons(atoi(pds.port));
05172
05173 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
05174 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
05175
05176
05177 memset(&ied, 0, sizeof(ied));
05178
05179
05180 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
05181 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
05182 if (pds.options && strchr(pds.options, 'a')) {
05183
05184 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
05185 }
05186
05187
05188 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
05189
05190 if (l) {
05191 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
05192 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05193 ast_party_id_presentation(&c->connected.id));
05194 } else if (n) {
05195 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05196 ast_party_id_presentation(&c->connected.id));
05197 } else {
05198 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
05199 }
05200
05201 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
05202 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
05203
05204 if (n)
05205 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
05206 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
05207 && c->connected.ani.number.valid
05208 && c->connected.ani.number.str) {
05209 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str);
05210 }
05211
05212 if (!ast_strlen_zero(c->language))
05213 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
05214 if (!ast_strlen_zero(c->dialed.number.str)) {
05215 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
05216 }
05217 if (c->redirecting.from.number.valid
05218 && !ast_strlen_zero(c->redirecting.from.number.str)) {
05219 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
05220 }
05221
05222 if (pds.context)
05223 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
05224
05225 if (pds.username)
05226 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
05227
05228 if (cai.encmethods)
05229 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
05230
05231 ast_mutex_lock(&iaxsl[callno]);
05232
05233 if (!ast_strlen_zero(c->context))
05234 ast_string_field_set(iaxs[callno], context, c->context);
05235
05236 if (pds.username)
05237 ast_string_field_set(iaxs[callno], username, pds.username);
05238
05239 iaxs[callno]->encmethods = cai.encmethods;
05240
05241 iaxs[callno]->adsi = cai.adsi;
05242
05243 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
05244 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
05245
05246 if (pds.key)
05247 ast_string_field_set(iaxs[callno], outkey, pds.key);
05248 if (pds.password)
05249 ast_string_field_set(iaxs[callno], secret, pds.password);
05250
05251 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
05252 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
05253 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
05254 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
05255 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
05256 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
05257
05258 if (iaxs[callno]->maxtime) {
05259
05260 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
05261 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
05262 } else if (autokill) {
05263 iaxs[callno]->pingtime = autokill / 2;
05264 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
05265 }
05266
05267
05268 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
05269 if (!ast_strlen_zero(osp_token_ptr)) {
05270 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
05271 osp_block_index = 0;
05272 while (osp_token_length > 0) {
05273 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
05274 osp_buffer[0] = osp_block_index;
05275 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
05276 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
05277 osp_block_index++;
05278 osp_token_ptr += osp_block_length;
05279 osp_token_length -= osp_block_length;
05280 }
05281 } else
05282 ast_log(LOG_WARNING, "OSP token is too long\n");
05283 } else if (iaxdebug)
05284 ast_debug(1, "OSP token is undefined\n");
05285
05286
05287 iaxs[callno]->sockfd = cai.sockfd;
05288
05289
05290 if (variablestore) {
05291 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
05292 ast_debug(1, "Found an IAX variable store on this channel\n");
05293 AST_LIST_LOCK(variablelist);
05294 AST_LIST_TRAVERSE(variablelist, var, entries) {
05295 char tmp[256];
05296 int i;
05297 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
05298
05299 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
05300 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
05301 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
05302 }
05303 }
05304 AST_LIST_UNLOCK(variablelist);
05305 }
05306
05307
05308 add_empty_calltoken_ie(iaxs[callno], &ied);
05309 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
05310
05311 ast_mutex_unlock(&iaxsl[callno]);
05312 ast_setstate(c, AST_STATE_RINGING);
05313
05314 return 0;
05315 }
05316
05317 static int iax2_hangup(struct ast_channel *c)
05318 {
05319 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05320 struct iax_ie_data ied;
05321 int alreadygone;
05322 memset(&ied, 0, sizeof(ied));
05323 ast_mutex_lock(&iaxsl[callno]);
05324 if (callno && iaxs[callno]) {
05325 ast_debug(1, "We're hanging up %s now...\n", c->name);
05326 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05327
05328 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05329 if (!iaxs[callno]->error && !alreadygone) {
05330 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05331 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05332 }
05333 if (!iaxs[callno]) {
05334 ast_mutex_unlock(&iaxsl[callno]);
05335 return 0;
05336 }
05337 }
05338
05339 iax2_predestroy(callno);
05340
05341 if (iaxs[callno] && alreadygone) {
05342 ast_debug(1, "Really destroying %s now...\n", c->name);
05343 iax2_destroy(callno);
05344 } else if (iaxs[callno]) {
05345 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05346 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05347 iax2_destroy(callno);
05348 }
05349 }
05350 } else if (c->tech_pvt) {
05351
05352
05353
05354
05355 c->tech_pvt = NULL;
05356 }
05357 ast_mutex_unlock(&iaxsl[callno]);
05358 ast_verb(3, "Hungup '%s'\n", c->name);
05359 return 0;
05360 }
05361
05362
05363
05364
05365 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05366 {
05367 unsigned short callno = pvt->callno;
05368
05369 if (!pvt->peercallno) {
05370
05371 int count = 10;
05372 while (count-- && pvt && !pvt->peercallno) {
05373 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05374 pvt = iaxs[callno];
05375 }
05376 if (!pvt || !pvt->peercallno) {
05377 return -1;
05378 }
05379 }
05380
05381 return 0;
05382 }
05383
05384 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05385 {
05386 struct ast_option_header *h;
05387 int res;
05388
05389 switch (option) {
05390 case AST_OPTION_TXGAIN:
05391 case AST_OPTION_RXGAIN:
05392
05393 errno = ENOSYS;
05394 return -1;
05395 case AST_OPTION_OPRMODE:
05396 errno = EINVAL;
05397 return -1;
05398 case AST_OPTION_SECURE_SIGNALING:
05399 case AST_OPTION_SECURE_MEDIA:
05400 {
05401 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05402 ast_mutex_lock(&iaxsl[callno]);
05403 if ((*(int *) data)) {
05404 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05405 } else {
05406 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05407 }
05408 ast_mutex_unlock(&iaxsl[callno]);
05409 return 0;
05410 }
05411
05412
05413
05414
05415 case AST_OPTION_TONE_VERIFY:
05416 case AST_OPTION_TDD:
05417 case AST_OPTION_RELAXDTMF:
05418 case AST_OPTION_AUDIO_MODE:
05419 case AST_OPTION_DIGIT_DETECT:
05420 case AST_OPTION_FAX_DETECT:
05421 {
05422 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05423 struct chan_iax2_pvt *pvt;
05424
05425 ast_mutex_lock(&iaxsl[callno]);
05426 pvt = iaxs[callno];
05427
05428 if (wait_for_peercallno(pvt)) {
05429 ast_mutex_unlock(&iaxsl[callno]);
05430 return -1;
05431 }
05432
05433 ast_mutex_unlock(&iaxsl[callno]);
05434
05435 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05436 return -1;
05437 }
05438
05439 h->flag = AST_OPTION_FLAG_REQUEST;
05440 h->option = htons(option);
05441 memcpy(h->data, data, datalen);
05442 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05443 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05444 datalen + sizeof(*h), -1);
05445 ast_free(h);
05446 return res;
05447 }
05448 default:
05449 return -1;
05450 }
05451
05452
05453 return -1;
05454 }
05455
05456 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
05457 {
05458 switch (option) {
05459 case AST_OPTION_SECURE_SIGNALING:
05460 case AST_OPTION_SECURE_MEDIA:
05461 {
05462 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05463 ast_mutex_lock(&iaxsl[callno]);
05464 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05465 ast_mutex_unlock(&iaxsl[callno]);
05466 return 0;
05467 }
05468 default:
05469 return -1;
05470 }
05471 }
05472
05473 static struct ast_frame *iax2_read(struct ast_channel *c)
05474 {
05475 ast_debug(1, "I should never be called!\n");
05476 return &ast_null_frame;
05477 }
05478
05479 static int iax2_key_rotate(const void *vpvt)
05480 {
05481 int res = 0;
05482 struct chan_iax2_pvt *pvt = (void *) vpvt;
05483 struct MD5Context md5;
05484 char key[17] = "";
05485 struct iax_ie_data ied = {
05486 .pos = 0,
05487 };
05488
05489 ast_mutex_lock(&iaxsl[pvt->callno]);
05490 pvt->keyrotateid =
05491 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05492
05493 snprintf(key, sizeof(key), "%lX", ast_random());
05494
05495 MD5Init(&md5);
05496 MD5Update(&md5, (unsigned char *) key, strlen(key));
05497 MD5Final((unsigned char *) key, &md5);
05498
05499 IAX_DEBUGDIGEST("Sending", key);
05500
05501 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05502
05503 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05504
05505 build_ecx_key((unsigned char *) key, pvt);
05506
05507 ast_mutex_unlock(&iaxsl[pvt->callno]);
05508
05509 return res;
05510 }
05511
05512 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05513 {
05514 int res;
05515 struct iax_ie_data ied0;
05516 struct iax_ie_data ied1;
05517 unsigned int transferid = (unsigned int)ast_random();
05518
05519 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05520 ast_debug(1, "transfers are not supported for encrypted calls at this time\n");
05521 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05522 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05523 return 0;
05524 }
05525
05526 memset(&ied0, 0, sizeof(ied0));
05527 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05528 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05529 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05530
05531 memset(&ied1, 0, sizeof(ied1));
05532 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05533 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05534 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05535
05536 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05537 if (res)
05538 return -1;
05539 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05540 if (res)
05541 return -1;
05542 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05543 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05544 return 0;
05545 }
05546
05547 static void lock_both(unsigned short callno0, unsigned short callno1)
05548 {
05549 ast_mutex_lock(&iaxsl[callno0]);
05550 while (ast_mutex_trylock(&iaxsl[callno1])) {
05551 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05552 }
05553 }
05554
05555 static void unlock_both(unsigned short callno0, unsigned short callno1)
05556 {
05557 ast_mutex_unlock(&iaxsl[callno1]);
05558 ast_mutex_unlock(&iaxsl[callno0]);
05559 }
05560
05561 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)
05562 {
05563 struct ast_channel *cs[3];
05564 struct ast_channel *who, *other;
05565 int to = -1;
05566 int res = -1;
05567 int transferstarted=0;
05568 struct ast_frame *f;
05569 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05570 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05571 struct timeval waittimer = {0, 0};
05572
05573
05574 if (timeoutms > 0) {
05575 return AST_BRIDGE_FAILED;
05576 }
05577
05578 timeoutms = -1;
05579
05580 lock_both(callno0, callno1);
05581 if (!iaxs[callno0] || !iaxs[callno1]) {
05582 unlock_both(callno0, callno1);
05583 return AST_BRIDGE_FAILED;
05584 }
05585
05586 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05587 iaxs[callno0]->bridgecallno = callno1;
05588 iaxs[callno1]->bridgecallno = callno0;
05589 }
05590 unlock_both(callno0, callno1);
05591
05592
05593 cs[0] = c0;
05594 cs[1] = c1;
05595 for (;;) {
05596
05597 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05598 ast_verb(3, "Can't masquerade, we're different...\n");
05599
05600 if (c0->tech == &iax2_tech) {
05601 ast_mutex_lock(&iaxsl[callno0]);
05602 iaxs[callno0]->bridgecallno = 0;
05603 ast_mutex_unlock(&iaxsl[callno0]);
05604 }
05605 if (c1->tech == &iax2_tech) {
05606 ast_mutex_lock(&iaxsl[callno1]);
05607 iaxs[callno1]->bridgecallno = 0;
05608 ast_mutex_unlock(&iaxsl[callno1]);
05609 }
05610 return AST_BRIDGE_FAILED_NOWARN;
05611 }
05612 if (c0->nativeformats != c1->nativeformats) {
05613 char buf0[256];
05614 char buf1[256];
05615 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05616 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05617 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05618
05619 lock_both(callno0, callno1);
05620 if (iaxs[callno0])
05621 iaxs[callno0]->bridgecallno = 0;
05622 if (iaxs[callno1])
05623 iaxs[callno1]->bridgecallno = 0;
05624 unlock_both(callno0, callno1);
05625 return AST_BRIDGE_FAILED_NOWARN;
05626 }
05627
05628 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05629
05630 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05631 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05632 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05633 transferstarted = 1;
05634 }
05635 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05636
05637 struct timeval now = ast_tvnow();
05638 if (ast_tvzero(waittimer)) {
05639 waittimer = now;
05640 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05641 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05642 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05643 *fo = NULL;
05644 *rc = c0;
05645 res = AST_BRIDGE_COMPLETE;
05646 break;
05647 }
05648 }
05649 to = 1000;
05650 who = ast_waitfor_n(cs, 2, &to);
05651
05652
05653
05654
05655
05656 if (timeoutms > -1) {
05657 timeoutms -= (1000 - to);
05658 if (timeoutms < 0)
05659 timeoutms = 0;
05660 }
05661 if (!who) {
05662 if (!timeoutms) {
05663 res = AST_BRIDGE_RETRY;
05664 break;
05665 }
05666 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05667 res = AST_BRIDGE_FAILED;
05668 break;
05669 }
05670 continue;
05671 }
05672 f = ast_read(who);
05673 if (!f) {
05674 *fo = NULL;
05675 *rc = who;
05676 res = AST_BRIDGE_COMPLETE;
05677 break;
05678 }
05679 other = (who == c0) ? c1 : c0;
05680 if (f->frametype == AST_FRAME_CONTROL && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
05681 switch (f->subclass.integer) {
05682 case AST_CONTROL_VIDUPDATE:
05683 case AST_CONTROL_SRCUPDATE:
05684 case AST_CONTROL_SRCCHANGE:
05685 case AST_CONTROL_T38_PARAMETERS:
05686 ast_write(other, f);
05687 break;
05688 default:
05689 *fo = f;
05690 *rc = who;
05691 res = AST_BRIDGE_COMPLETE;
05692 break;
05693 }
05694 if (res == AST_BRIDGE_COMPLETE) {
05695 break;
05696 }
05697 } else if (f->frametype == AST_FRAME_VOICE
05698 || f->frametype == AST_FRAME_TEXT
05699 || f->frametype == AST_FRAME_VIDEO
05700 || f->frametype == AST_FRAME_IMAGE) {
05701 ast_write(other, f);
05702 } else if (f->frametype == AST_FRAME_DTMF) {
05703
05704
05705
05706 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05707
05708 if (flags & monitored_source) {
05709 *rc = who;
05710 *fo = f;
05711 res = AST_BRIDGE_COMPLETE;
05712
05713 break;
05714 }
05715 ast_write(other, f);
05716 }
05717 ast_frfree(f);
05718
05719 cs[2] = cs[0];
05720 cs[0] = cs[1];
05721 cs[1] = cs[2];
05722 }
05723 lock_both(callno0, callno1);
05724 if(iaxs[callno0])
05725 iaxs[callno0]->bridgecallno = 0;
05726 if(iaxs[callno1])
05727 iaxs[callno1]->bridgecallno = 0;
05728 unlock_both(callno0, callno1);
05729 return res;
05730 }
05731
05732 static int iax2_answer(struct ast_channel *c)
05733 {
05734 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05735 ast_debug(1, "Answering IAX2 call\n");
05736 ast_mutex_lock(&iaxsl[callno]);
05737 if (iaxs[callno])
05738 iax2_ami_channelupdate(iaxs[callno]);
05739 ast_mutex_unlock(&iaxsl[callno]);
05740 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05741 }
05742
05743 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05744 {
05745 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05746 struct chan_iax2_pvt *pvt;
05747 int res = 0;
05748
05749 if (iaxdebug)
05750 ast_debug(1, "Indicating condition %d\n", condition);
05751
05752 ast_mutex_lock(&iaxsl[callno]);
05753 pvt = iaxs[callno];
05754
05755 if (wait_for_peercallno(pvt)) {
05756 res = -1;
05757 goto done;
05758 }
05759
05760 switch (condition) {
05761 case AST_CONTROL_HOLD:
05762 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05763 ast_moh_start(c, data, pvt->mohinterpret);
05764 goto done;
05765 }
05766 break;
05767 case AST_CONTROL_UNHOLD:
05768 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05769 ast_moh_stop(c);
05770 goto done;
05771 }
05772 break;
05773 case AST_CONTROL_CONNECTED_LINE:
05774 case AST_CONTROL_REDIRECTING:
05775 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) {
05776
05777 ast_debug(2, "Callno %u: Config blocked sending control frame %d.\n",
05778 callno, condition);
05779 goto done;
05780 }
05781 break;
05782 }
05783
05784 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05785
05786 done:
05787 ast_mutex_unlock(&iaxsl[callno]);
05788
05789 return res;
05790 }
05791
05792 static int iax2_transfer(struct ast_channel *c, const char *dest)
05793 {
05794 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05795 struct iax_ie_data ied = { "", };
05796 char tmp[256], *context;
05797 enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05798 ast_copy_string(tmp, dest, sizeof(tmp));
05799 context = strchr(tmp, '@');
05800 if (context) {
05801 *context = '\0';
05802 context++;
05803 }
05804 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05805 if (context)
05806 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05807 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05808 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05809 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05810 }
05811
05812 static int iax2_getpeertrunk(struct sockaddr_in sin)
05813 {
05814 struct iax2_peer *peer;
05815 int res = 0;
05816 struct ao2_iterator i;
05817
05818 i = ao2_iterator_init(peers, 0);
05819 while ((peer = ao2_iterator_next(&i))) {
05820 struct sockaddr_in peer_addr;
05821
05822 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05823
05824 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05825 (peer_addr.sin_port == sin.sin_port)) {
05826 res = ast_test_flag64(peer, IAX_TRUNK);
05827 peer_unref(peer);
05828 break;
05829 }
05830 peer_unref(peer);
05831 }
05832 ao2_iterator_destroy(&i);
05833
05834 return res;
05835 }
05836
05837
05838 static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid, unsigned int cachable)
05839 {
05840 struct ast_channel *tmp;
05841 struct chan_iax2_pvt *i;
05842 struct ast_variable *v = NULL;
05843
05844 if (!(i = iaxs[callno])) {
05845 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05846 return NULL;
05847 }
05848
05849
05850 ast_mutex_unlock(&iaxsl[callno]);
05851 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
05852 ast_mutex_lock(&iaxsl[callno]);
05853 if (i != iaxs[callno]) {
05854 if (tmp) {
05855
05856 ast_mutex_unlock(&iaxsl[callno]);
05857 tmp = ast_channel_release(tmp);
05858 ast_mutex_lock(&iaxsl[callno]);
05859 }
05860 return NULL;
05861 }
05862 iax2_ami_channelupdate(i);
05863 if (!tmp)
05864 return NULL;
05865 tmp->tech = &iax2_tech;
05866
05867 tmp->nativeformats = capability;
05868 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05869 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05870 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05871
05872 if (!ast_strlen_zero(i->parkinglot))
05873 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05874
05875
05876 if (!ast_strlen_zero(i->ani)) {
05877 tmp->caller.ani.number.valid = 1;
05878 tmp->caller.ani.number.str = ast_strdup(i->ani);
05879 } else if (!ast_strlen_zero(i->cid_num)) {
05880 tmp->caller.ani.number.valid = 1;
05881 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05882 }
05883 tmp->dialed.number.str = ast_strdup(i->dnid);
05884 if (!ast_strlen_zero(i->rdnis)) {
05885 tmp->redirecting.from.number.valid = 1;
05886 tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05887 }
05888 tmp->caller.id.name.presentation = i->calling_pres;
05889 tmp->caller.id.number.presentation = i->calling_pres;
05890 tmp->caller.id.number.plan = i->calling_ton;
05891 tmp->dialed.transit_network_select = i->calling_tns;
05892 if (!ast_strlen_zero(i->language))
05893 ast_string_field_set(tmp, language, i->language);
05894 if (!ast_strlen_zero(i->accountcode))
05895 ast_string_field_set(tmp, accountcode, i->accountcode);
05896 if (i->amaflags)
05897 tmp->amaflags = i->amaflags;
05898 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05899 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05900 if (i->adsi)
05901 tmp->adsicpe = i->peeradsicpe;
05902 else
05903 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05904 i->owner = tmp;
05905 i->capability = capability;
05906
05907 if (!cachable) {
05908 tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
05909 }
05910
05911
05912 if (i->vars) {
05913 for (v = i->vars ; v ; v = v->next)
05914 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05915 }
05916 if (i->iaxvars) {
05917 struct ast_datastore *variablestore;
05918 struct ast_variable *var, *prev = NULL;
05919 AST_LIST_HEAD(, ast_var_t) *varlist;
05920 ast_debug(1, "Loading up the channel with IAXVARs\n");
05921 varlist = ast_calloc(1, sizeof(*varlist));
05922 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05923 if (variablestore && varlist) {
05924 variablestore->data = varlist;
05925 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05926 AST_LIST_HEAD_INIT(varlist);
05927 for (var = i->iaxvars; var; var = var->next) {
05928 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05929 if (prev)
05930 ast_free(prev);
05931 prev = var;
05932 if (!newvar) {
05933
05934 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05935 } else {
05936 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05937 }
05938 }
05939 if (prev)
05940 ast_free(prev);
05941 i->iaxvars = NULL;
05942 ast_channel_datastore_add(i->owner, variablestore);
05943 } else {
05944 if (variablestore) {
05945 ast_datastore_free(variablestore);
05946 }
05947 if (varlist) {
05948 ast_free(varlist);
05949 }
05950 }
05951 }
05952
05953 if (state != AST_STATE_DOWN) {
05954 if (ast_pbx_start(tmp)) {
05955 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05956 ast_hangup(tmp);
05957 i->owner = NULL;
05958 return NULL;
05959 }
05960 }
05961
05962 ast_module_ref(ast_module_info->self);
05963 return tmp;
05964 }
05965
05966 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05967 {
05968 unsigned long int mssincetx;
05969 long int ms, pred;
05970
05971 tpeer->trunkact = *now;
05972 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05973 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05974
05975 tpeer->txtrunktime = *now;
05976 tpeer->lastsent = 999999;
05977 }
05978
05979 tpeer->lasttxtime = *now;
05980
05981
05982 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05983
05984 pred = tpeer->lastsent + sampms;
05985 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05986 ms = pred;
05987
05988
05989 if (ms == tpeer->lastsent)
05990 ms = tpeer->lastsent + 1;
05991 tpeer->lastsent = ms;
05992 return ms;
05993 }
05994
05995 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05996 {
05997 long ms;
05998 if (ast_tvzero(iaxs[callno]->rxcore)) {
05999
06000 iaxs[callno]->rxcore = ast_tvnow();
06001
06002 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
06003 }
06004
06005 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
06006
06007 return ms + ts;
06008 }
06009
06010 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
06011 {
06012 int ms;
06013 int voice = 0;
06014 int genuine = 0;
06015 int adjust;
06016 int rate = ast_format_rate(f->subclass.codec) / 1000;
06017 struct timeval *delivery = NULL;
06018
06019
06020
06021
06022
06023
06024
06025
06026 if (f->frametype == AST_FRAME_VOICE) {
06027 voice = 1;
06028 delivery = &f->delivery;
06029 } else if (f->frametype == AST_FRAME_IAX) {
06030 genuine = 1;
06031 } else if (f->frametype == AST_FRAME_CNG) {
06032 p->notsilenttx = 0;
06033 }
06034
06035 if (ast_tvzero(p->offset)) {
06036 p->offset = ast_tvnow();
06037
06038 p->offset.tv_usec -= p->offset.tv_usec % 20000;
06039 }
06040
06041 if (ts)
06042 return ts;
06043
06044 if (delivery && !ast_tvzero(*delivery)) {
06045 ms = ast_tvdiff_ms(*delivery, p->offset);
06046 if (ms < 0) {
06047 ms = 0;
06048 }
06049 if (iaxdebug)
06050 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
06051 } else {
06052 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
06053 if (ms < 0)
06054 ms = 0;
06055 if (voice) {
06056
06057 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
06058
06059
06060
06061
06062
06063
06064
06065
06066
06067
06068
06069
06070
06071
06072
06073
06074
06075
06076 adjust = (ms - p->nextpred);
06077 if (adjust < 0)
06078 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
06079 else if (adjust > 0)
06080 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
06081
06082 if (!p->nextpred) {
06083 p->nextpred = ms;
06084 if (p->nextpred <= p->lastsent)
06085 p->nextpred = p->lastsent + 3;
06086 }
06087 ms = p->nextpred;
06088 } else {
06089
06090
06091
06092
06093
06094
06095
06096
06097
06098 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
06099 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
06100 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
06101
06102 if (f->samples >= rate)
06103 {
06104 int diff = ms % (f->samples / rate);
06105 if (diff)
06106 ms += f->samples/rate - diff;
06107 }
06108
06109 p->nextpred = ms;
06110 p->notsilenttx = 1;
06111 }
06112 } else if ( f->frametype == AST_FRAME_VIDEO ) {
06113
06114
06115
06116
06117
06118
06119
06120
06121 if ( (unsigned int)ms < p->lastsent )
06122 ms = p->lastsent;
06123 } else {
06124
06125
06126 if (genuine) {
06127
06128 if (ms <= p->lastsent)
06129 ms = p->lastsent + 3;
06130 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
06131
06132 ms = p->lastsent + 3;
06133 }
06134 }
06135 }
06136 p->lastsent = ms;
06137 if (voice)
06138 p->nextpred = p->nextpred + f->samples / rate;
06139 return ms;
06140 }
06141
06142 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
06143 {
06144
06145
06146 int ms;
06147 #ifdef IAXTESTS
06148 int jit;
06149 #endif
06150
06151 if (ast_tvzero(p->rxcore)) {
06152 p->rxcore = ast_tvnow();
06153 if (iaxdebug)
06154 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06155 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06156 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06157 #if 1
06158 if (iaxdebug)
06159 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06160 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06161 #endif
06162 }
06163
06164 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06165 #ifdef IAXTESTS
06166 if (test_jit) {
06167 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06168 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06169 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06170 jit = -jit;
06171 ms += jit;
06172 }
06173 }
06174 if (test_late) {
06175 ms += test_late;
06176 test_late = 0;
06177 }
06178 #endif
06179 return ms;
06180 }
06181
06182 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
06183 {
06184 struct iax2_trunk_peer *tpeer = NULL;
06185
06186
06187 AST_LIST_LOCK(&tpeers);
06188
06189 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06190 if (!inaddrcmp(&tpeer->addr, sin)) {
06191 ast_mutex_lock(&tpeer->lock);
06192 break;
06193 }
06194 }
06195
06196 if (!tpeer) {
06197 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06198 ast_mutex_init(&tpeer->lock);
06199 tpeer->lastsent = 9999;
06200 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06201 tpeer->trunkact = ast_tvnow();
06202 ast_mutex_lock(&tpeer->lock);
06203 tpeer->sockfd = fd;
06204 #ifdef SO_NO_CHECK
06205 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06206 #endif
06207 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06208 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06209 }
06210 }
06211
06212 AST_LIST_UNLOCK(&tpeers);
06213
06214 return tpeer;
06215 }
06216
06217 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
06218 {
06219 struct ast_frame *f;
06220 struct iax2_trunk_peer *tpeer;
06221 void *tmp, *ptr;
06222 struct timeval now;
06223 struct ast_iax2_meta_trunk_entry *met;
06224 struct ast_iax2_meta_trunk_mini *mtm;
06225
06226 f = &fr->af;
06227 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06228 if (tpeer) {
06229 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06230
06231 if (tpeer->trunkdataalloc < trunkmaxsize) {
06232 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06233 ast_mutex_unlock(&tpeer->lock);
06234 return -1;
06235 }
06236
06237 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06238 tpeer->trunkdata = tmp;
06239 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);
06240 } else {
06241 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));
06242 ast_mutex_unlock(&tpeer->lock);
06243 return -1;
06244 }
06245 }
06246
06247
06248 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06249 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06250 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06251 mtm->len = htons(f->datalen);
06252 mtm->mini.callno = htons(pvt->callno);
06253 mtm->mini.ts = htons(0xffff & fr->ts);
06254 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06255 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06256 } else {
06257 met = (struct ast_iax2_meta_trunk_entry *)ptr;
06258
06259 met->callno = htons(pvt->callno);
06260 met->len = htons(f->datalen);
06261
06262 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06263 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06264 }
06265
06266 memcpy(ptr, f->data.ptr, f->datalen);
06267 tpeer->trunkdatalen += f->datalen;
06268
06269 tpeer->calls++;
06270
06271
06272 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
06273 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
06274
06275
06276 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06277 now = ast_tvnow();
06278 send_trunk(tpeer, &now);
06279 trunk_untimed ++;
06280 }
06281
06282 ast_mutex_unlock(&tpeer->lock);
06283 }
06284 return 0;
06285 }
06286
06287
06288
06289 static void build_rand_pad(unsigned char *buf, ssize_t len)
06290 {
06291 long tmp;
06292 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06293 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06294 buf += sizeof(tmp);
06295 len -= sizeof(tmp);
06296 }
06297 }
06298
06299 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06300 {
06301 build_ecx_key(digest, pvt);
06302 ast_aes_set_decrypt_key(digest, &pvt->dcx);
06303 }
06304
06305 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06306 {
06307
06308
06309
06310 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06311 ast_aes_set_encrypt_key(digest, &pvt->ecx);
06312 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06313 }
06314
06315 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
06316 {
06317 #if 0
06318
06319 int x;
06320 if (len % 16)
06321 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06322 for (x=0;x<len;x++)
06323 dst[x] = src[x] ^ 0xff;
06324 #else
06325 unsigned char lastblock[16] = { 0 };
06326 int x;
06327 while(len > 0) {
06328 ast_aes_decrypt(src, dst, dcx);
06329 for (x=0;x<16;x++)
06330 dst[x] ^= lastblock[x];
06331 memcpy(lastblock, src, sizeof(lastblock));
06332 dst += 16;
06333 src += 16;
06334 len -= 16;
06335 }
06336 #endif
06337 }
06338
06339 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
06340 {
06341 #if 0
06342
06343 int x;
06344 if (len % 16)
06345 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06346 for (x=0;x<len;x++)
06347 dst[x] = src[x] ^ 0xff;
06348 #else
06349 unsigned char curblock[16] = { 0 };
06350 int x;
06351 while(len > 0) {
06352 for (x=0;x<16;x++)
06353 curblock[x] ^= src[x];
06354 ast_aes_encrypt(curblock, dst, ecx);
06355 memcpy(curblock, dst, sizeof(curblock));
06356 dst += 16;
06357 src += 16;
06358 len -= 16;
06359 }
06360 #endif
06361 }
06362
06363 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06364 {
06365 int padding;
06366 unsigned char *workspace;
06367
06368 workspace = ast_alloca(*datalen);
06369 memset(f, 0, sizeof(*f));
06370 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06371 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06372 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06373 return -1;
06374
06375 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06376
06377 padding = 16 + (workspace[15] & 0x0f);
06378 if (iaxdebug)
06379 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06380 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06381 return -1;
06382
06383 *datalen -= padding;
06384 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06385 f->frametype = fh->type;
06386 if (f->frametype == AST_FRAME_VIDEO) {
06387 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06388 } else if (f->frametype == AST_FRAME_VOICE) {
06389 f->subclass.codec = uncompress_subclass(fh->csub);
06390 } else {
06391 f->subclass.integer = uncompress_subclass(fh->csub);
06392 }
06393 } else {
06394 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06395 if (iaxdebug)
06396 ast_debug(1, "Decoding mini with length %d\n", *datalen);
06397 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06398 return -1;
06399
06400 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06401 padding = 16 + (workspace[15] & 0x0f);
06402 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06403 return -1;
06404 *datalen -= padding;
06405 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06406 }
06407 return 0;
06408 }
06409
06410 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06411 {
06412 int padding;
06413 unsigned char *workspace;
06414 workspace = ast_alloca(*datalen + 32);
06415 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06416 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06417 if (iaxdebug)
06418 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06419 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06420 padding = 16 + (padding & 0xf);
06421 memcpy(workspace, poo, padding);
06422 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06423 workspace[15] &= 0xf0;
06424 workspace[15] |= (padding & 0xf);
06425 if (iaxdebug)
06426 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06427 *datalen += padding;
06428 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06429 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06430 memcpy(poo, workspace + *datalen - 32, 32);
06431 } else {
06432 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06433 if (iaxdebug)
06434 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06435 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06436 padding = 16 + (padding & 0xf);
06437 memcpy(workspace, poo, padding);
06438 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06439 workspace[15] &= 0xf0;
06440 workspace[15] |= (padding & 0x0f);
06441 *datalen += padding;
06442 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06443 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06444 memcpy(poo, workspace + *datalen - 32, 32);
06445 }
06446 return 0;
06447 }
06448
06449 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06450 {
06451 int res=-1;
06452 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06453
06454 struct MD5Context md5;
06455 unsigned char digest[16];
06456 char *tmppw, *stringp;
06457
06458 tmppw = ast_strdupa(iaxs[callno]->secret);
06459 stringp = tmppw;
06460 while ((tmppw = strsep(&stringp, ";"))) {
06461 MD5Init(&md5);
06462 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06463 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06464 MD5Final(digest, &md5);
06465 build_encryption_keys(digest, iaxs[callno]);
06466 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06467 if (!res) {
06468 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06469 break;
06470 }
06471 }
06472 } else
06473 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06474 return res;
06475 }
06476
06477 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06478 {
06479
06480
06481
06482 struct ast_iax2_full_hdr *fh;
06483 struct ast_iax2_mini_hdr *mh;
06484 struct ast_iax2_video_hdr *vh;
06485 struct {
06486 struct iax_frame fr2;
06487 unsigned char buffer[4096];
06488 } frb;
06489 struct iax_frame *fr;
06490 int res;
06491 int sendmini=0;
06492 unsigned int lastsent;
06493 unsigned int fts;
06494
06495 frb.fr2.afdatalen = sizeof(frb.buffer);
06496
06497 if (!pvt) {
06498 ast_log(LOG_WARNING, "No private structure for packet?\n");
06499 return -1;
06500 }
06501
06502 lastsent = pvt->lastsent;
06503
06504
06505 fts = calc_timestamp(pvt, ts, f);
06506
06507
06508
06509
06510 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06511 return 0;
06512 #if 0
06513 ast_log(LOG_NOTICE,
06514 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06515 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06516 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06517 pvt->keyrotateid != -1 ? "" : "no "
06518 );
06519 #endif
06520 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06521 iax2_key_rotate(pvt);
06522 }
06523
06524 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
06525 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06526 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06527 &&
06528 (f->frametype == AST_FRAME_VOICE)
06529 &&
06530 (f->subclass.codec == pvt->svoiceformat)
06531 ) {
06532
06533 now = 1;
06534
06535 sendmini = 1;
06536 }
06537 if ( f->frametype == AST_FRAME_VIDEO ) {
06538
06539
06540
06541
06542
06543 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06544 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
06545 ) {
06546 now = 1;
06547 sendmini = 1;
06548 } else {
06549 now = 0;
06550 sendmini = 0;
06551 }
06552 pvt->lastvsent = fts;
06553 }
06554 if (f->frametype == AST_FRAME_IAX) {
06555
06556 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06557 if (!pvt->first_iax_message) {
06558 pvt->first_iax_message = pvt->last_iax_message;
06559 }
06560 }
06561
06562 if (now) {
06563 fr = &frb.fr2;
06564 } else
06565 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag64(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
06566 if (!fr) {
06567 ast_log(LOG_WARNING, "Out of memory\n");
06568 return -1;
06569 }
06570
06571 iax_frame_wrap(fr, f);
06572
06573 fr->ts = fts;
06574 fr->callno = pvt->callno;
06575 fr->transfer = transfer;
06576 fr->final = final;
06577 fr->encmethods = 0;
06578 if (!sendmini) {
06579
06580 if (seqno > -1)
06581 fr->oseqno = seqno;
06582 else
06583 fr->oseqno = pvt->oseqno++;
06584 fr->iseqno = pvt->iseqno;
06585 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06586 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06587 fh->ts = htonl(fr->ts);
06588 fh->oseqno = fr->oseqno;
06589 if (transfer) {
06590 fh->iseqno = 0;
06591 } else
06592 fh->iseqno = fr->iseqno;
06593
06594 if (!transfer)
06595 pvt->aseqno = fr->iseqno;
06596 fh->type = fr->af.frametype & 0xFF;
06597
06598 if (fr->af.frametype == AST_FRAME_VIDEO) {
06599 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
06600 } else if (fr->af.frametype == AST_FRAME_VOICE) {
06601 fh->csub = compress_subclass(fr->af.subclass.codec);
06602 } else {
06603 fh->csub = compress_subclass(fr->af.subclass.integer);
06604 }
06605
06606 if (transfer) {
06607 fr->dcallno = pvt->transfercallno;
06608 } else
06609 fr->dcallno = pvt->peercallno;
06610 fh->dcallno = htons(fr->dcallno);
06611 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06612 fr->data = fh;
06613 fr->retries = 0;
06614
06615 fr->retrytime = pvt->pingtime * 2;
06616 if (fr->retrytime < MIN_RETRY_TIME)
06617 fr->retrytime = MIN_RETRY_TIME;
06618 if (fr->retrytime > MAX_RETRY_TIME)
06619 fr->retrytime = MAX_RETRY_TIME;
06620
06621 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06622 fr->retries = -1;
06623 else if (f->frametype == AST_FRAME_VOICE)
06624 pvt->svoiceformat = f->subclass.codec;
06625 else if (f->frametype == AST_FRAME_VIDEO)
06626 pvt->svideoformat = f->subclass.codec & ~0x1LL;
06627 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06628 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06629 if (fr->transfer)
06630 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06631 else
06632 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06633 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06634 fr->encmethods = pvt->encmethods;
06635 fr->ecx = pvt->ecx;
06636 fr->mydcx = pvt->mydcx;
06637 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06638 } else
06639 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06640 }
06641
06642 if (now) {
06643 res = send_packet(fr);
06644 } else
06645 res = iax2_transmit(fr);
06646 } else {
06647 if (ast_test_flag64(pvt, IAX_TRUNK)) {
06648 iax2_trunk_queue(pvt, fr);
06649 res = 0;
06650 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06651
06652 fr->oseqno = -1;
06653 fr->iseqno = -1;
06654 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06655 vh->zeros = 0;
06656 vh->callno = htons(0x8000 | fr->callno);
06657 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
06658 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06659 fr->data = vh;
06660 fr->retries = -1;
06661 res = send_packet(fr);
06662 } else {
06663
06664 fr->oseqno = -1;
06665 fr->iseqno = -1;
06666
06667 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06668 mh->callno = htons(fr->callno);
06669 mh->ts = htons(fr->ts & 0xFFFF);
06670 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06671 fr->data = mh;
06672 fr->retries = -1;
06673 if (pvt->transferring == TRANSFER_MEDIAPASS)
06674 fr->transfer = 1;
06675 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06676 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06677 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06678 } else
06679 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06680 }
06681 res = send_packet(fr);
06682 }
06683 }
06684 return res;
06685 }
06686
06687 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06688 {
06689 regex_t regexbuf;
06690 int havepattern = 0;
06691
06692 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06693 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06694
06695 struct iax2_user *user = NULL;
06696 char auth[90];
06697 char *pstr = "";
06698 struct ao2_iterator i;
06699
06700 switch (cmd) {
06701 case CLI_INIT:
06702 e->command = "iax2 show users [like]";
06703 e->usage =
06704 "Usage: iax2 show users [like <pattern>]\n"
06705 " Lists all known IAX2 users.\n"
06706 " Optional regular expression pattern is used to filter the user list.\n";
06707 return NULL;
06708 case CLI_GENERATE:
06709 return NULL;
06710 }
06711
06712 switch (a->argc) {
06713 case 5:
06714 if (!strcasecmp(a->argv[3], "like")) {
06715 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06716 return CLI_SHOWUSAGE;
06717 havepattern = 1;
06718 } else
06719 return CLI_SHOWUSAGE;
06720 case 3:
06721 break;
06722 default:
06723 return CLI_SHOWUSAGE;
06724 }
06725
06726 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06727 i = ao2_iterator_init(users, 0);
06728 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
06729 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06730 continue;
06731
06732 if (!ast_strlen_zero(user->secret)) {
06733 ast_copy_string(auth,user->secret, sizeof(auth));
06734 } else if (!ast_strlen_zero(user->inkeys)) {
06735 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06736 } else
06737 ast_copy_string(auth, "-no secret-", sizeof(auth));
06738
06739 if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06740 pstr = "REQ Only";
06741 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06742 pstr = "Disabled";
06743 else
06744 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06745
06746 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06747 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06748 user->ha ? "Yes" : "No", pstr);
06749 }
06750 ao2_iterator_destroy(&i);
06751
06752 if (havepattern)
06753 regfree(®exbuf);
06754
06755 return CLI_SUCCESS;
06756 #undef FORMAT
06757 #undef FORMAT2
06758 }
06759
06760 static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char * const argv[])
06761 {
06762 regex_t regexbuf;
06763 int havepattern = 0;
06764 int total_peers = 0;
06765 int online_peers = 0;
06766 int offline_peers = 0;
06767 int unmonitored_peers = 0;
06768 struct ao2_iterator i;
06769
06770 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n"
06771 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n"
06772
06773 struct iax2_peer *peer = NULL;
06774 char name[256];
06775 struct ast_str *encmethods = ast_str_alloca(256);
06776 int registeredonly=0;
06777 char idtext[256] = "";
06778 switch (argc) {
06779 case 6:
06780 if (!strcasecmp(argv[3], "registered"))
06781 registeredonly = 1;
06782 else
06783 return RESULT_SHOWUSAGE;
06784 if (!strcasecmp(argv[4], "like")) {
06785 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06786 return RESULT_SHOWUSAGE;
06787 havepattern = 1;
06788 } else
06789 return RESULT_SHOWUSAGE;
06790 break;
06791 case 5:
06792 if (!strcasecmp(argv[3], "like")) {
06793 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06794 return RESULT_SHOWUSAGE;
06795 havepattern = 1;
06796 } else
06797 return RESULT_SHOWUSAGE;
06798 break;
06799 case 4:
06800 if (!strcasecmp(argv[3], "registered"))
06801 registeredonly = 1;
06802 else
06803 return RESULT_SHOWUSAGE;
06804 break;
06805 case 3:
06806 break;
06807 default:
06808 return RESULT_SHOWUSAGE;
06809 }
06810
06811
06812 if (!s)
06813 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status");
06814
06815 i = ao2_iterator_init(peers, 0);
06816 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06817 char nm[20];
06818 char status[20];
06819 int retstatus;
06820 struct sockaddr_in peer_addr;
06821
06822 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06823
06824 if (registeredonly && !peer_addr.sin_addr.s_addr) {
06825 continue;
06826 }
06827 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
06828 continue;
06829 }
06830
06831 if (!ast_strlen_zero(peer->username))
06832 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06833 else
06834 ast_copy_string(name, peer->name, sizeof(name));
06835
06836 encmethods_to_str(peer->encmethods, &encmethods);
06837 retstatus = peer_status(peer, status, sizeof(status));
06838 if (retstatus > 0)
06839 online_peers++;
06840 else if (!retstatus)
06841 offline_peers++;
06842 else
06843 unmonitored_peers++;
06844
06845 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06846
06847 if (s) {
06848 astman_append(s,
06849 "Event: PeerEntry\r\n%s"
06850 "Channeltype: IAX2\r\n"
06851 "ObjectName: %s\r\n"
06852 "ChanObjectType: peer\r\n"
06853 "IPaddress: %s\r\n"
06854 "IPport: %d\r\n"
06855 "Dynamic: %s\r\n"
06856 "Trunk: %s\r\n"
06857 "Encryption: %s\r\n"
06858 "Status: %s\r\n\r\n",
06859 idtext,
06860 name,
06861 ast_sockaddr_stringify_addr(&peer->addr),
06862 ast_sockaddr_port(&peer->addr),
06863 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06864 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06865 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06866 status);
06867 } else {
06868 ast_cli(fd, FORMAT, name,
06869 ast_sockaddr_stringify_addr(&peer->addr),
06870 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06871 nm,
06872 ast_sockaddr_port(&peer->addr),
06873 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
06874 peer->encmethods ? "(E)" : " ",
06875 status);
06876 }
06877 total_peers++;
06878 }
06879 ao2_iterator_destroy(&i);
06880
06881 if (!s)
06882 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06883 total_peers, online_peers, offline_peers, unmonitored_peers);
06884
06885 if (havepattern)
06886 regfree(®exbuf);
06887
06888 if (total)
06889 *total = total_peers;
06890
06891 return RESULT_SUCCESS;
06892 #undef FORMAT
06893 #undef FORMAT2
06894 }
06895
06896 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06897 {
06898 struct iax2_thread *thread = NULL;
06899 time_t t;
06900 int threadcount = 0, dynamiccount = 0;
06901 char type;
06902
06903 switch (cmd) {
06904 case CLI_INIT:
06905 e->command = "iax2 show threads";
06906 e->usage =
06907 "Usage: iax2 show threads\n"
06908 " Lists status of IAX helper threads\n";
06909 return NULL;
06910 case CLI_GENERATE:
06911 return NULL;
06912 }
06913 if (a->argc != 3)
06914 return CLI_SHOWUSAGE;
06915
06916 ast_cli(a->fd, "IAX2 Thread Information\n");
06917 time(&t);
06918 ast_cli(a->fd, "Idle Threads:\n");
06919 AST_LIST_LOCK(&idle_list);
06920 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06921 #ifdef DEBUG_SCHED_MULTITHREAD
06922 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06923 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06924 #else
06925 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06926 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06927 #endif
06928 threadcount++;
06929 }
06930 AST_LIST_UNLOCK(&idle_list);
06931 ast_cli(a->fd, "Active Threads:\n");
06932 AST_LIST_LOCK(&active_list);
06933 AST_LIST_TRAVERSE(&active_list, thread, list) {
06934 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06935 type = 'D';
06936 else
06937 type = 'P';
06938 #ifdef DEBUG_SCHED_MULTITHREAD
06939 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06940 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06941 #else
06942 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06943 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06944 #endif
06945 threadcount++;
06946 }
06947 AST_LIST_UNLOCK(&active_list);
06948 ast_cli(a->fd, "Dynamic Threads:\n");
06949 AST_LIST_LOCK(&dynamic_list);
06950 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06951 #ifdef DEBUG_SCHED_MULTITHREAD
06952 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06953 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06954 #else
06955 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06956 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06957 #endif
06958 dynamiccount++;
06959 }
06960 AST_LIST_UNLOCK(&dynamic_list);
06961 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06962 return CLI_SUCCESS;
06963 }
06964
06965 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06966 {
06967 struct iax2_peer *p;
06968
06969 switch (cmd) {
06970 case CLI_INIT:
06971 e->command = "iax2 unregister";
06972 e->usage =
06973 "Usage: iax2 unregister <peername>\n"
06974 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06975 return NULL;
06976 case CLI_GENERATE:
06977 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06978 }
06979
06980 if (a->argc != 3)
06981 return CLI_SHOWUSAGE;
06982
06983 p = find_peer(a->argv[2], 1);
06984 if (p) {
06985 if (p->expire > 0) {
06986 struct iax2_peer tmp_peer = {
06987 .name = a->argv[2],
06988 };
06989 struct iax2_peer *peer;
06990
06991 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06992 if (peer) {
06993 expire_registry(peer_ref(peer));
06994 peer_unref(peer);
06995 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06996 } else {
06997 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06998 }
06999 } else {
07000 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
07001 }
07002 peer_unref(p);
07003 } else {
07004 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
07005 }
07006 return CLI_SUCCESS;
07007 }
07008
07009 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
07010 {
07011 int which = 0;
07012 struct iax2_peer *p = NULL;
07013 char *res = NULL;
07014 int wordlen = strlen(word);
07015
07016
07017 if (pos == 2) {
07018 struct ao2_iterator i = ao2_iterator_init(peers, 0);
07019 while ((p = ao2_iterator_next(&i))) {
07020 if (!strncasecmp(p->name, word, wordlen) &&
07021 ++which > state && p->expire > 0) {
07022 res = ast_strdup(p->name);
07023 peer_unref(p);
07024 break;
07025 }
07026 peer_unref(p);
07027 }
07028 ao2_iterator_destroy(&i);
07029 }
07030
07031 return res;
07032 }
07033
07034 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07035 {
07036 switch (cmd) {
07037 case CLI_INIT:
07038 e->command = "iax2 show peers";
07039 e->usage =
07040 "Usage: iax2 show peers [registered] [like <pattern>]\n"
07041 " Lists all known IAX2 peers.\n"
07042 " Optional 'registered' argument lists only peers with known addresses.\n"
07043 " Optional regular expression pattern is used to filter the peer list.\n";
07044 return NULL;
07045 case CLI_GENERATE:
07046 return NULL;
07047 }
07048
07049 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
07050 case RESULT_SHOWUSAGE:
07051 return CLI_SHOWUSAGE;
07052 case RESULT_FAILURE:
07053 return CLI_FAILURE;
07054 default:
07055 return CLI_SUCCESS;
07056 }
07057 }
07058
07059 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
07060 {
07061 ast_cli_netstats(s, -1, 0);
07062 astman_append(s, "\r\n");
07063 return RESULT_SUCCESS;
07064 }
07065
07066 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07067 {
07068 struct iax_firmware *cur = NULL;
07069
07070 switch (cmd) {
07071 case CLI_INIT:
07072 e->command = "iax2 show firmware";
07073 e->usage =
07074 "Usage: iax2 show firmware\n"
07075 " Lists all known IAX firmware images.\n";
07076 return NULL;
07077 case CLI_GENERATE:
07078 return NULL;
07079 }
07080
07081 if (a->argc != 3 && a->argc != 4)
07082 return CLI_SHOWUSAGE;
07083
07084 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
07085 AST_LIST_LOCK(&firmwares);
07086 AST_LIST_TRAVERSE(&firmwares, cur, list) {
07087 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
07088 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
07089 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
07090 }
07091 }
07092 AST_LIST_UNLOCK(&firmwares);
07093
07094 return CLI_SUCCESS;
07095 }
07096
07097
07098 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
07099 {
07100 static const char * const a[] = { "iax2", "show", "peers" };
07101 const char *id = astman_get_header(m,"ActionID");
07102 char idtext[256] = "";
07103 int total = 0;
07104
07105 if (!ast_strlen_zero(id))
07106 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07107
07108 astman_send_listack(s, m, "Peer status list will follow", "start");
07109
07110 __iax2_show_peers(-1, &total, s, 3, a);
07111
07112 astman_append(s,
07113 "Event: PeerlistComplete\r\n"
07114 "EventList: Complete\r\n"
07115 "ListItems: %d\r\n"
07116 "%s"
07117 "\r\n", total, idtext);
07118 return 0;
07119 }
07120
07121
07122 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
07123 {
07124 struct iax2_peer *peer = NULL;
07125 int peer_count = 0;
07126 char nm[20];
07127 char status[20];
07128 const char *id = astman_get_header(m,"ActionID");
07129 char idtext[256] = "";
07130 struct ast_str *encmethods = ast_str_alloca(256);
07131 struct ao2_iterator i;
07132
07133 if (!ast_strlen_zero(id))
07134 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07135
07136 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
07137
07138
07139 i = ao2_iterator_init(peers, 0);
07140 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
07141 encmethods_to_str(peer->encmethods, &encmethods);
07142 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
07143 if (!ast_strlen_zero(peer->username)) {
07144 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07145 } else {
07146 astman_append(s, "ObjectName: %s\r\n", peer->name);
07147 }
07148 astman_append(s, "ChanObjectType: peer\r\n");
07149 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07150 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07151 astman_append(s, "Mask: %s\r\n", nm);
07152 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07153 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07154 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07155 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07156 peer_status(peer, status, sizeof(status));
07157 astman_append(s, "Status: %s\r\n\r\n", status);
07158 peer_count++;
07159 }
07160 ao2_iterator_destroy(&i);
07161
07162 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07163 return RESULT_SUCCESS;
07164 }
07165
07166
07167 static char *regstate2str(int regstate)
07168 {
07169 switch(regstate) {
07170 case REG_STATE_UNREGISTERED:
07171 return "Unregistered";
07172 case REG_STATE_REGSENT:
07173 return "Request Sent";
07174 case REG_STATE_AUTHSENT:
07175 return "Auth. Sent";
07176 case REG_STATE_REGISTERED:
07177 return "Registered";
07178 case REG_STATE_REJECTED:
07179 return "Rejected";
07180 case REG_STATE_TIMEOUT:
07181 return "Timeout";
07182 case REG_STATE_NOAUTH:
07183 return "No Authentication";
07184 default:
07185 return "Unknown";
07186 }
07187 }
07188
07189 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07190 {
07191 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
07192 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
07193 struct iax2_registry *reg = NULL;
07194 char host[80];
07195 char perceived[80];
07196 int counter = 0;
07197
07198 switch (cmd) {
07199 case CLI_INIT:
07200 e->command = "iax2 show registry";
07201 e->usage =
07202 "Usage: iax2 show registry\n"
07203 " Lists all registration requests and status.\n";
07204 return NULL;
07205 case CLI_GENERATE:
07206 return NULL;
07207 }
07208 if (a->argc != 3)
07209 return CLI_SHOWUSAGE;
07210 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07211 AST_LIST_LOCK(®istrations);
07212 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07213 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07214 if (reg->us.sin_addr.s_addr)
07215 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07216 else
07217 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07218 ast_cli(a->fd, FORMAT, host,
07219 (reg->dnsmgr) ? "Y" : "N",
07220 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07221 counter++;
07222 }
07223 AST_LIST_UNLOCK(®istrations);
07224 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07225 return CLI_SUCCESS;
07226 #undef FORMAT
07227 #undef FORMAT2
07228 }
07229
07230 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
07231 {
07232 const char *id = astman_get_header(m, "ActionID");
07233 struct iax2_registry *reg = NULL;
07234 char idtext[256] = "";
07235 char host[80] = "";
07236 char perceived[80] = "";
07237 int total = 0;
07238
07239 if (!ast_strlen_zero(id))
07240 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07241
07242 astman_send_listack(s, m, "Registrations will follow", "start");
07243
07244 AST_LIST_LOCK(®istrations);
07245 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07246 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07247
07248 if (reg->us.sin_addr.s_addr) {
07249 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07250 } else {
07251 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07252 }
07253
07254 astman_append(s,
07255 "Event: RegistryEntry\r\n"
07256 "%s"
07257 "Host: %s\r\n"
07258 "DNSmanager: %s\r\n"
07259 "Username: %s\r\n"
07260 "Perceived: %s\r\n"
07261 "Refresh: %d\r\n"
07262 "State: %s\r\n"
07263 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
07264 reg->refresh, regstate2str(reg->regstate));
07265
07266 total++;
07267 }
07268 AST_LIST_UNLOCK(®istrations);
07269
07270 astman_append(s,
07271 "Event: RegistrationsComplete\r\n"
07272 "EventList: Complete\r\n"
07273 "ListItems: %d\r\n"
07274 "%s"
07275 "\r\n", total, idtext);
07276
07277 return 0;
07278 }
07279
07280 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07281 {
07282 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
07283 #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"
07284 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
07285 int x;
07286 int numchans = 0;
07287 char first_message[10] = { 0, };
07288 char last_message[10] = { 0, };
07289
07290 switch (cmd) {
07291 case CLI_INIT:
07292 e->command = "iax2 show channels";
07293 e->usage =
07294 "Usage: iax2 show channels\n"
07295 " Lists all currently active IAX channels.\n";
07296 return NULL;
07297 case CLI_GENERATE:
07298 return NULL;
07299 }
07300
07301 if (a->argc != 3)
07302 return CLI_SHOWUSAGE;
07303 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07304 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07305 ast_mutex_lock(&iaxsl[x]);
07306 if (iaxs[x]) {
07307 int lag, jitter, localdelay;
07308 jb_info jbinfo;
07309 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07310 jb_getinfo(iaxs[x]->jb, &jbinfo);
07311 jitter = jbinfo.jitter;
07312 localdelay = jbinfo.current - jbinfo.min;
07313 } else {
07314 jitter = -1;
07315 localdelay = 0;
07316 }
07317
07318 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07319 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07320 lag = iaxs[x]->remote_rr.delay;
07321 ast_cli(a->fd, FORMAT,
07322 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07323 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07324 S_OR(iaxs[x]->username, "(None)"),
07325 iaxs[x]->callno, iaxs[x]->peercallno,
07326 iaxs[x]->oseqno, iaxs[x]->iseqno,
07327 lag,
07328 jitter,
07329 localdelay,
07330 ast_getformatname(iaxs[x]->voiceformat),
07331 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07332 first_message,
07333 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07334 last_message);
07335 numchans++;
07336 }
07337 ast_mutex_unlock(&iaxsl[x]);
07338 }
07339 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07340 return CLI_SUCCESS;
07341 #undef FORMAT
07342 #undef FORMAT2
07343 #undef FORMATB
07344 }
07345
07346 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
07347 {
07348 int x;
07349 int numchans = 0;
07350 char first_message[10] = { 0, };
07351 char last_message[10] = { 0, };
07352 #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"
07353 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07354 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07355 ast_mutex_lock(&iaxsl[x]);
07356 if (iaxs[x]) {
07357 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07358 jb_info jbinfo;
07359 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07360 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07361
07362 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07363 jb_getinfo(iaxs[x]->jb, &jbinfo);
07364 localjitter = jbinfo.jitter;
07365 localdelay = jbinfo.current - jbinfo.min;
07366 locallost = jbinfo.frames_lost;
07367 locallosspct = jbinfo.losspct/1000;
07368 localdropped = jbinfo.frames_dropped;
07369 localooo = jbinfo.frames_ooo;
07370 } else {
07371 localjitter = -1;
07372 localdelay = 0;
07373 locallost = -1;
07374 locallosspct = -1;
07375 localdropped = 0;
07376 localooo = -1;
07377 }
07378 if (s)
07379 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07380 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07381 iaxs[x]->pingtime,
07382 localjitter,
07383 localdelay,
07384 locallost,
07385 locallosspct,
07386 localdropped,
07387 localooo,
07388 iaxs[x]->frames_received/1000,
07389 iaxs[x]->remote_rr.jitter,
07390 iaxs[x]->remote_rr.delay,
07391 iaxs[x]->remote_rr.losscnt,
07392 iaxs[x]->remote_rr.losspct,
07393 iaxs[x]->remote_rr.dropped,
07394 iaxs[x]->remote_rr.ooo,
07395 iaxs[x]->remote_rr.packets/1000,
07396 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07397 first_message,
07398 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07399 last_message);
07400 else
07401 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07402 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07403 iaxs[x]->pingtime,
07404 localjitter,
07405 localdelay,
07406 locallost,
07407 locallosspct,
07408 localdropped,
07409 localooo,
07410 iaxs[x]->frames_received/1000,
07411 iaxs[x]->remote_rr.jitter,
07412 iaxs[x]->remote_rr.delay,
07413 iaxs[x]->remote_rr.losscnt,
07414 iaxs[x]->remote_rr.losspct,
07415 iaxs[x]->remote_rr.dropped,
07416 iaxs[x]->remote_rr.ooo,
07417 iaxs[x]->remote_rr.packets/1000,
07418 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07419 first_message,
07420 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07421 last_message);
07422 numchans++;
07423 }
07424 ast_mutex_unlock(&iaxsl[x]);
07425 }
07426
07427 return numchans;
07428 }
07429
07430 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07431 {
07432 int numchans = 0;
07433
07434 switch (cmd) {
07435 case CLI_INIT:
07436 e->command = "iax2 show netstats";
07437 e->usage =
07438 "Usage: iax2 show netstats\n"
07439 " Lists network status for all currently active IAX channels.\n";
07440 return NULL;
07441 case CLI_GENERATE:
07442 return NULL;
07443 }
07444 if (a->argc != 3)
07445 return CLI_SHOWUSAGE;
07446 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07447 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07448 numchans = ast_cli_netstats(NULL, a->fd, 1);
07449 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07450 return CLI_SUCCESS;
07451 }
07452
07453 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07454 {
07455 switch (cmd) {
07456 case CLI_INIT:
07457 e->command = "iax2 set debug {on|off|peer}";
07458 e->usage =
07459 "Usage: iax2 set debug {on|off|peer peername}\n"
07460 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07461 return NULL;
07462 case CLI_GENERATE:
07463 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07464 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07465 return NULL;
07466 }
07467
07468 if (a->argc < e->args || a->argc > e->args + 1)
07469 return CLI_SHOWUSAGE;
07470
07471 if (!strcasecmp(a->argv[3], "peer")) {
07472 struct iax2_peer *peer;
07473 struct sockaddr_in peer_addr;
07474
07475
07476 if (a->argc != e->args + 1)
07477 return CLI_SHOWUSAGE;
07478
07479 peer = find_peer(a->argv[4], 1);
07480
07481 if (!peer) {
07482 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07483 return CLI_FAILURE;
07484 }
07485
07486 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07487
07488 debugaddr.sin_addr = peer_addr.sin_addr;
07489 debugaddr.sin_port = peer_addr.sin_port;
07490
07491 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07492 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07493
07494 ao2_ref(peer, -1);
07495 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07496 iaxdebug = 1;
07497 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07498 } else {
07499 iaxdebug = 0;
07500 memset(&debugaddr, 0, sizeof(debugaddr));
07501 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07502 }
07503 return CLI_SUCCESS;
07504 }
07505
07506 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07507 {
07508 switch (cmd) {
07509 case CLI_INIT:
07510 e->command = "iax2 set debug trunk {on|off}";
07511 e->usage =
07512 "Usage: iax2 set debug trunk {on|off}\n"
07513 " Enables/Disables debugging of IAX trunking\n";
07514 return NULL;
07515 case CLI_GENERATE:
07516 return NULL;
07517 }
07518
07519 if (a->argc != e->args)
07520 return CLI_SHOWUSAGE;
07521
07522 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07523 iaxtrunkdebug = 1;
07524 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07525 } else {
07526 iaxtrunkdebug = 0;
07527 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07528 }
07529 return CLI_SUCCESS;
07530 }
07531
07532 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07533 {
07534 switch (cmd) {
07535 case CLI_INIT:
07536 e->command = "iax2 set debug jb {on|off}";
07537 e->usage =
07538 "Usage: iax2 set debug jb {on|off}\n"
07539 " Enables/Disables jitterbuffer debugging information\n";
07540 return NULL;
07541 case CLI_GENERATE:
07542 return NULL;
07543 }
07544
07545 if (a->argc != e->args)
07546 return CLI_SHOWUSAGE;
07547
07548 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07549 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07550 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07551 } else {
07552 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07553 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07554 }
07555 return CLI_SUCCESS;
07556 }
07557
07558 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07559 {
07560 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07561 int res = -1;
07562 ast_mutex_lock(&iaxsl[callno]);
07563 if (iaxs[callno]) {
07564
07565 if (!iaxs[callno]->error) {
07566 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07567 res = 0;
07568
07569 else if (f->frametype == AST_FRAME_NULL)
07570 res = 0;
07571 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07572 res = 0;
07573 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07574 res = 0;
07575 else
07576
07577 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07578 } else {
07579 ast_debug(1, "Write error: %s\n", strerror(errno));
07580 }
07581 }
07582
07583 ast_mutex_unlock(&iaxsl[callno]);
07584 return res;
07585 }
07586
07587 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07588 int now, int transfer, int final)
07589 {
07590 struct ast_frame f = { 0, };
07591 int res = 0;
07592
07593 f.frametype = type;
07594 f.subclass.integer = command;
07595 f.datalen = datalen;
07596 f.src = __FUNCTION__;
07597 f.data.ptr = (void *) data;
07598
07599 if ((res = queue_signalling(i, &f)) <= 0) {
07600 return res;
07601 }
07602
07603 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07604 }
07605
07606 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07607 {
07608 if (type == AST_FRAME_CONTROL && !iax2_is_control_frame_allowed(command)) {
07609
07610 ast_debug(2, "Callno %u: Blocked sending control frame %d.\n",
07611 i->callno, command);
07612 return 0;
07613 }
07614 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07615 }
07616
07617 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07618 {
07619 int res;
07620 ast_mutex_lock(&iaxsl[callno]);
07621 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07622 ast_mutex_unlock(&iaxsl[callno]);
07623 return res;
07624 }
07625
07626
07627
07628
07629
07630
07631 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)
07632 {
07633 int call_num = i->callno;
07634
07635 iax2_predestroy(i->callno);
07636 if (!iaxs[call_num])
07637 return -1;
07638 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07639 }
07640
07641 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)
07642 {
07643 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07644 }
07645
07646 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07647 {
07648 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07649 }
07650
07651 static int apply_context(struct iax2_context *con, const char *context)
07652 {
07653 while(con) {
07654 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07655 return -1;
07656 con = con->next;
07657 }
07658 return 0;
07659 }
07660
07661
07662 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07663 {
07664
07665 int res = -1;
07666 int version = 2;
07667 struct iax2_user *user = NULL, *best = NULL;
07668 int bestscore = 0;
07669 int gotcapability = 0;
07670 struct ast_variable *v = NULL, *tmpvar = NULL;
07671 struct ao2_iterator i;
07672 struct ast_sockaddr addr;
07673
07674 if (!iaxs[callno])
07675 return res;
07676 if (ies->called_number)
07677 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07678 if (ies->calling_number) {
07679 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07680 ast_shrink_phone_number(ies->calling_number);
07681 }
07682 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07683 }
07684 if (ies->calling_name)
07685 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07686 if (ies->calling_ani)
07687 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07688 if (ies->dnid)
07689 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07690 if (ies->rdnis)
07691 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07692 if (ies->called_context)
07693 ast_string_field_set(iaxs[callno], context, ies->called_context);
07694 if (ies->language)
07695 ast_string_field_set(iaxs[callno], language, ies->language);
07696 if (ies->username)
07697 ast_string_field_set(iaxs[callno], username, ies->username);
07698 if (ies->calling_ton > -1)
07699 iaxs[callno]->calling_ton = ies->calling_ton;
07700 if (ies->calling_tns > -1)
07701 iaxs[callno]->calling_tns = ies->calling_tns;
07702 if (ies->calling_pres > -1)
07703 iaxs[callno]->calling_pres = ies->calling_pres;
07704 if (ies->format)
07705 iaxs[callno]->peerformat = ies->format;
07706 if (ies->adsicpe)
07707 iaxs[callno]->peeradsicpe = ies->adsicpe;
07708 if (ies->capability) {
07709 gotcapability = 1;
07710 iaxs[callno]->peercapability = ies->capability;
07711 }
07712 if (ies->version)
07713 version = ies->version;
07714
07715
07716 if (ies->codec_prefs) {
07717 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07718 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07719 }
07720
07721 if (!gotcapability)
07722 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07723 if (version > IAX_PROTO_VERSION) {
07724 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07725 ast_inet_ntoa(sin->sin_addr), version);
07726 return res;
07727 }
07728
07729 ast_sockaddr_from_sin(&addr, sin);
07730 i = ao2_iterator_init(users, 0);
07731 while ((user = ao2_iterator_next(&i))) {
07732 if ((ast_strlen_zero(iaxs[callno]->username) ||
07733 !strcmp(iaxs[callno]->username, user->name))
07734 && ast_apply_ha(user->ha, &addr) == AST_SENSE_ALLOW
07735 && (ast_strlen_zero(iaxs[callno]->context) ||
07736 apply_context(user->contexts, iaxs[callno]->context))) {
07737 if (!ast_strlen_zero(iaxs[callno]->username)) {
07738
07739 if (best)
07740 user_unref(best);
07741 best = user;
07742 break;
07743 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07744
07745 if (user->ha) {
07746
07747 if (bestscore < 4) {
07748 bestscore = 4;
07749 if (best)
07750 user_unref(best);
07751 best = user;
07752 continue;
07753 }
07754 } else {
07755
07756 if (bestscore < 3) {
07757 bestscore = 3;
07758 if (best)
07759 user_unref(best);
07760 best = user;
07761 continue;
07762 }
07763 }
07764 } else {
07765 if (user->ha) {
07766
07767 if (bestscore < 2) {
07768 bestscore = 2;
07769 if (best)
07770 user_unref(best);
07771 best = user;
07772 continue;
07773 }
07774 } else {
07775
07776 if (bestscore < 1) {
07777 bestscore = 1;
07778 if (best)
07779 user_unref(best);
07780 best = user;
07781 continue;
07782 }
07783 }
07784 }
07785 }
07786 user_unref(user);
07787 }
07788 ao2_iterator_destroy(&i);
07789 user = best;
07790 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07791 user = realtime_user(iaxs[callno]->username, sin);
07792 if (user && (ast_apply_ha(user->ha, &addr) == AST_SENSE_DENY
07793 || (!ast_strlen_zero(iaxs[callno]->context) &&
07794 !apply_context(user->contexts, iaxs[callno]->context)))) {
07795 user = user_unref(user);
07796 }
07797 }
07798 if (user) {
07799
07800
07801 for (v = user->vars ; v ; v = v->next) {
07802 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07803 tmpvar->next = iaxs[callno]->vars;
07804 iaxs[callno]->vars = tmpvar;
07805 }
07806 }
07807
07808 if (user->maxauthreq > 0)
07809 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07810 iaxs[callno]->prefs = user->prefs;
07811 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07812 iaxs[callno]->encmethods = user->encmethods;
07813
07814 if (ast_strlen_zero(iaxs[callno]->username))
07815 ast_string_field_set(iaxs[callno], username, user->name);
07816
07817 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07818 iaxs[callno]->capability = user->capability;
07819
07820 if (ast_strlen_zero(iaxs[callno]->context)) {
07821 if (user->contexts)
07822 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07823 else
07824 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07825 }
07826
07827 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07828
07829 iaxs[callno]->authmethods = user->authmethods;
07830 iaxs[callno]->adsi = user->adsi;
07831
07832 if (ast_test_flag64(user, IAX_HASCALLERID)) {
07833 iaxs[callno]->calling_tns = 0;
07834 iaxs[callno]->calling_ton = 0;
07835 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07836 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07837 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07838 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07839 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07840 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07841 }
07842 if (!ast_strlen_zero(user->accountcode))
07843 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07844 if (!ast_strlen_zero(user->mohinterpret))
07845 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07846 if (!ast_strlen_zero(user->mohsuggest))
07847 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07848 if (!ast_strlen_zero(user->parkinglot))
07849 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07850 if (user->amaflags)
07851 iaxs[callno]->amaflags = user->amaflags;
07852 if (!ast_strlen_zero(user->language))
07853 ast_string_field_set(iaxs[callno], language, user->language);
07854 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
07855
07856 if (!ast_strlen_zero(user->dbsecret)) {
07857 char *family, *key=NULL;
07858 char buf[80];
07859 family = ast_strdupa(user->dbsecret);
07860 key = strchr(family, '/');
07861 if (key) {
07862 *key = '\0';
07863 key++;
07864 }
07865 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07866 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07867 else
07868 ast_string_field_set(iaxs[callno], secret, buf);
07869 } else
07870 ast_string_field_set(iaxs[callno], secret, user->secret);
07871 res = 0;
07872 user = user_unref(user);
07873 } else {
07874
07875
07876
07877
07878 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07879 ast_string_field_set(iaxs[callno], secret, "badsecret");
07880 iaxs[callno]->authrej = 1;
07881 if (!ast_strlen_zero(iaxs[callno]->username)) {
07882
07883 res = 0;
07884 }
07885 }
07886 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07887 return res;
07888 }
07889
07890 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07891 {
07892 struct ast_iax2_full_hdr fh;
07893 fh.scallno = htons(src | IAX_FLAG_FULL);
07894 fh.dcallno = htons(dst);
07895 fh.ts = 0;
07896 fh.oseqno = 0;
07897 fh.iseqno = 0;
07898 fh.type = AST_FRAME_IAX;
07899 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07900 iax_outputframe(NULL, &fh, 0, sin, 0);
07901 #if 0
07902 if (option_debug)
07903 #endif
07904 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07905 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07906 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07907 }
07908
07909 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07910 {
07911
07912 p->encmethods &= enc;
07913 if (p->encmethods) {
07914 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07915 p->keyrotateid = -2;
07916 }
07917 if (p->encmethods & IAX_ENCRYPT_AES128)
07918 p->encmethods = IAX_ENCRYPT_AES128;
07919 else
07920 p->encmethods = 0;
07921 }
07922 }
07923
07924
07925
07926
07927
07928
07929
07930 static int authenticate_request(int call_num)
07931 {
07932 struct iax_ie_data ied;
07933 int res = -1, authreq_restrict = 0;
07934 char challenge[10];
07935 struct chan_iax2_pvt *p = iaxs[call_num];
07936
07937 memset(&ied, 0, sizeof(ied));
07938
07939
07940 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07941 struct iax2_user *user, tmp_user = {
07942 .name = p->username,
07943 };
07944
07945 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07946 if (user) {
07947 if (user->curauthreq == user->maxauthreq)
07948 authreq_restrict = 1;
07949 else
07950 user->curauthreq++;
07951 user = user_unref(user);
07952 }
07953 }
07954
07955
07956 if (authreq_restrict) {
07957 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07958 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07959 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07960 return 0;
07961 }
07962
07963 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07964 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07965 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07966 ast_string_field_set(p, challenge, challenge);
07967
07968 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07969 }
07970 if (p->encmethods)
07971 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07972
07973 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07974
07975 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07976
07977 if (p->encmethods)
07978 ast_set_flag64(p, IAX_ENCRYPTED);
07979
07980 return res;
07981 }
07982
07983 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07984 {
07985 char requeststr[256];
07986 char md5secret[256] = "";
07987 char secret[256] = "";
07988 char rsasecret[256] = "";
07989 int res = -1;
07990 int x;
07991 struct iax2_user *user, tmp_user = {
07992 .name = p->username,
07993 };
07994
07995 if (p->authrej) {
07996 return res;
07997 }
07998 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07999 if (user) {
08000 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
08001 ast_atomic_fetchadd_int(&user->curauthreq, -1);
08002 ast_clear_flag64(p, IAX_MAXAUTHREQ);
08003 }
08004 ast_string_field_set(p, host, user->name);
08005 user = user_unref(user);
08006 }
08007 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
08008 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n");
08009 return res;
08010 }
08011 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
08012 return res;
08013 if (ies->password)
08014 ast_copy_string(secret, ies->password, sizeof(secret));
08015 if (ies->md5_result)
08016 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
08017 if (ies->rsa_result)
08018 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
08019 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
08020 struct ast_key *key;
08021 char *keyn;
08022 char tmpkey[256];
08023 char *stringp=NULL;
08024 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
08025 stringp=tmpkey;
08026 keyn = strsep(&stringp, ":");
08027 while(keyn) {
08028 key = ast_key_get(keyn, AST_KEY_PUBLIC);
08029 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
08030 res = 0;
08031 break;
08032 } else if (!key)
08033 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
08034 keyn = strsep(&stringp, ":");
08035 }
08036 } else if (p->authmethods & IAX_AUTH_MD5) {
08037 struct MD5Context md5;
08038 unsigned char digest[16];
08039 char *tmppw, *stringp;
08040
08041 tmppw = ast_strdupa(p->secret);
08042 stringp = tmppw;
08043 while((tmppw = strsep(&stringp, ";"))) {
08044 MD5Init(&md5);
08045 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
08046 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08047 MD5Final(digest, &md5);
08048
08049 for (x=0;x<16;x++)
08050 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
08051 if (!strcasecmp(requeststr, md5secret)) {
08052 res = 0;
08053 break;
08054 }
08055 }
08056 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
08057 if (!strcmp(secret, p->secret))
08058 res = 0;
08059 }
08060 return res;
08061 }
08062
08063
08064 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
08065 {
08066 char requeststr[256] = "";
08067 char peer[256] = "";
08068 char md5secret[256] = "";
08069 char rsasecret[256] = "";
08070 char secret[256] = "";
08071 struct iax2_peer *p = NULL;
08072 struct ast_key *key;
08073 char *keyn;
08074 int x;
08075 int expire = 0;
08076 int res = -1;
08077 struct ast_sockaddr addr;
08078
08079 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08080
08081 if (ies->username)
08082 ast_copy_string(peer, ies->username, sizeof(peer));
08083 if (ies->password)
08084 ast_copy_string(secret, ies->password, sizeof(secret));
08085 if (ies->md5_result)
08086 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
08087 if (ies->rsa_result)
08088 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
08089 if (ies->refresh)
08090 expire = ies->refresh;
08091
08092 if (ast_strlen_zero(peer)) {
08093 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
08094 return -1;
08095 }
08096
08097
08098 ast_mutex_unlock(&iaxsl[callno]);
08099 p = find_peer(peer, 1);
08100 ast_mutex_lock(&iaxsl[callno]);
08101 if (!p || !iaxs[callno]) {
08102 if (iaxs[callno]) {
08103 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
08104
08105 ast_string_field_set(iaxs[callno], secret, "badsecret");
08106
08107
08108
08109
08110
08111
08112
08113
08114
08115 if (ast_strlen_zero(iaxs[callno]->challenge) &&
08116 !(!ast_strlen_zero(secret) && plaintext)) {
08117
08118 res = 0;
08119 }
08120 }
08121 if (authdebug && !p)
08122 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08123 goto return_unref;
08124 }
08125
08126 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
08127 if (authdebug)
08128 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08129 goto return_unref;
08130 }
08131
08132 ast_sockaddr_from_sin(&addr, sin);
08133 if (!ast_apply_ha(p->ha, &addr)) {
08134 if (authdebug)
08135 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08136 goto return_unref;
08137 }
08138 ast_string_field_set(iaxs[callno], secret, p->secret);
08139 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
08140
08141 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08142 if (!ast_strlen_zero(p->inkeys)) {
08143 char tmpkeys[256];
08144 char *stringp=NULL;
08145 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
08146 stringp=tmpkeys;
08147 keyn = strsep(&stringp, ":");
08148 while(keyn) {
08149 key = ast_key_get(keyn, AST_KEY_PUBLIC);
08150 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
08151 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08152 break;
08153 } else if (!key)
08154 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08155 keyn = strsep(&stringp, ":");
08156 }
08157 if (!keyn) {
08158 if (authdebug)
08159 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08160 goto return_unref;
08161 }
08162 } else {
08163 if (authdebug)
08164 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08165 goto return_unref;
08166 }
08167 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08168 struct MD5Context md5;
08169 unsigned char digest[16];
08170 char *tmppw, *stringp;
08171
08172 tmppw = ast_strdupa(p->secret);
08173 stringp = tmppw;
08174 while((tmppw = strsep(&stringp, ";"))) {
08175 MD5Init(&md5);
08176 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08177 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08178 MD5Final(digest, &md5);
08179 for (x=0;x<16;x++)
08180 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
08181 if (!strcasecmp(requeststr, md5secret))
08182 break;
08183 }
08184 if (tmppw) {
08185 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08186 } else {
08187 if (authdebug)
08188 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08189 goto return_unref;
08190 }
08191 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08192
08193 if (strcmp(secret, p->secret)) {
08194 if (authdebug)
08195 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08196 goto return_unref;
08197 } else
08198 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08199 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08200
08201 goto return_unref;
08202 }
08203 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08204
08205
08206 res = 0;
08207
08208 return_unref:
08209 if (iaxs[callno]) {
08210 ast_string_field_set(iaxs[callno], peer, peer);
08211
08212
08213 if (expire && (expire < iaxs[callno]->expiry)) {
08214 iaxs[callno]->expiry = expire;
08215 }
08216 }
08217
08218 if (p) {
08219 peer_unref(p);
08220 }
08221 return res;
08222 }
08223
08224 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)
08225 {
08226 int res = -1;
08227 int x;
08228 if (!ast_strlen_zero(keyn)) {
08229 if (!(authmethods & IAX_AUTH_RSA)) {
08230 if (ast_strlen_zero(secret))
08231 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));
08232 } else if (ast_strlen_zero(challenge)) {
08233 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08234 } else {
08235 char sig[256];
08236 struct ast_key *key;
08237 key = ast_key_get(keyn, AST_KEY_PRIVATE);
08238 if (!key) {
08239 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08240 } else {
08241 if (ast_sign(key, (char*)challenge, sig)) {
08242 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08243 res = -1;
08244 } else {
08245 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08246 res = 0;
08247 }
08248 }
08249 }
08250 }
08251
08252 if (res && !ast_strlen_zero(secret)) {
08253 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08254 struct MD5Context md5;
08255 unsigned char digest[16];
08256 char digres[128];
08257 MD5Init(&md5);
08258 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08259 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08260 MD5Final(digest, &md5);
08261
08262 for (x=0;x<16;x++)
08263 sprintf(digres + (x << 1), "%2.2x", digest[x]);
08264 if (pvt) {
08265 build_encryption_keys(digest, pvt);
08266 }
08267 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08268 res = 0;
08269 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08270 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08271 res = 0;
08272 } else
08273 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08274 }
08275 return res;
08276 }
08277
08278
08279
08280
08281
08282 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
08283 {
08284 struct iax2_peer *peer = NULL;
08285
08286 int res = -1;
08287 int authmethods = 0;
08288 struct iax_ie_data ied;
08289 uint16_t callno = p->callno;
08290
08291 memset(&ied, 0, sizeof(ied));
08292
08293 if (ies->username)
08294 ast_string_field_set(p, username, ies->username);
08295 if (ies->challenge)
08296 ast_string_field_set(p, challenge, ies->challenge);
08297 if (ies->authmethods)
08298 authmethods = ies->authmethods;
08299 if (authmethods & IAX_AUTH_MD5)
08300 merge_encryption(p, ies->encmethods);
08301 else
08302 p->encmethods = 0;
08303
08304
08305 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08306
08307 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08308 } else {
08309 struct ao2_iterator i = ao2_iterator_init(peers, 0);
08310 while ((peer = ao2_iterator_next(&i))) {
08311 struct sockaddr_in peer_addr;
08312
08313 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08314
08315 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08316
08317 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08318
08319 && (!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)))
08320
08321 ) {
08322 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08323 if (!res) {
08324 peer_unref(peer);
08325 break;
08326 }
08327 }
08328 peer_unref(peer);
08329 }
08330 ao2_iterator_destroy(&i);
08331 if (!peer) {
08332
08333
08334 const char *peer_name = ast_strdupa(p->peer);
08335 ast_mutex_unlock(&iaxsl[callno]);
08336 if ((peer = realtime_peer(peer_name, NULL))) {
08337 ast_mutex_lock(&iaxsl[callno]);
08338 if (!(p = iaxs[callno])) {
08339 peer_unref(peer);
08340 return -1;
08341 }
08342 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08343 peer_unref(peer);
08344 }
08345 if (!peer) {
08346 ast_mutex_lock(&iaxsl[callno]);
08347 if (!(p = iaxs[callno]))
08348 return -1;
08349 }
08350 }
08351 }
08352
08353 if (ies->encmethods) {
08354 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08355 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08356 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n");
08357 return -1;
08358 }
08359 if (!res) {
08360 struct ast_datastore *variablestore;
08361 struct ast_variable *var, *prev = NULL;
08362 AST_LIST_HEAD(, ast_var_t) *varlist;
08363 varlist = ast_calloc(1, sizeof(*varlist));
08364 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08365 if (variablestore && varlist && p->owner) {
08366 variablestore->data = varlist;
08367 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08368 AST_LIST_HEAD_INIT(varlist);
08369 for (var = ies->vars; var; var = var->next) {
08370 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08371 if (prev)
08372 ast_free(prev);
08373 prev = var;
08374 if (!newvar) {
08375
08376 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08377 } else {
08378 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08379 }
08380 }
08381 if (prev)
08382 ast_free(prev);
08383 ies->vars = NULL;
08384 ast_channel_datastore_add(p->owner, variablestore);
08385 } else {
08386 if (p->owner)
08387 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08388 if (variablestore)
08389 ast_datastore_free(variablestore);
08390 if (varlist)
08391 ast_free(varlist);
08392 }
08393 }
08394
08395 if (!res)
08396 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08397 return res;
08398 }
08399
08400 static int iax2_do_register(struct iax2_registry *reg);
08401
08402 static void __iax2_do_register_s(const void *data)
08403 {
08404 struct iax2_registry *reg = (struct iax2_registry *)data;
08405 reg->expire = -1;
08406 iax2_do_register(reg);
08407 }
08408
08409 static int iax2_do_register_s(const void *data)
08410 {
08411 #ifdef SCHED_MULTITHREADED
08412 if (schedule_action(__iax2_do_register_s, data))
08413 #endif
08414 __iax2_do_register_s(data);
08415 return 0;
08416 }
08417
08418 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08419 {
08420 int newcall = 0;
08421 char newip[256];
08422 struct iax_ie_data ied;
08423 struct sockaddr_in new = { 0, };
08424
08425 memset(&ied, 0, sizeof(ied));
08426 if (ies->apparent_addr)
08427 memmove(&new, ies->apparent_addr, sizeof(new));
08428 if (ies->callno)
08429 newcall = ies->callno;
08430 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08431 ast_log(LOG_WARNING, "Invalid transfer request\n");
08432 return -1;
08433 }
08434 pvt->transfercallno = newcall;
08435 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08436 inet_aton(newip, &pvt->transfer.sin_addr);
08437 pvt->transfer.sin_family = AF_INET;
08438 pvt->transferid = ies->transferid;
08439
08440
08441 if (pvt->transferring == TRANSFER_NONE) {
08442 store_by_transfercallno(pvt);
08443 }
08444 pvt->transferring = TRANSFER_BEGIN;
08445
08446 if (ies->transferid)
08447 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08448 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08449 return 0;
08450 }
08451
08452 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08453 {
08454 char exten[256] = "";
08455 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08456 struct iax2_dpcache *dp = NULL;
08457
08458 if (ies->called_number)
08459 ast_copy_string(exten, ies->called_number, sizeof(exten));
08460
08461 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08462 status = CACHE_FLAG_EXISTS;
08463 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08464 status = CACHE_FLAG_CANEXIST;
08465 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08466 status = CACHE_FLAG_NONEXISTENT;
08467
08468 if (ies->refresh)
08469 expiry = ies->refresh;
08470 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08471 matchmore = CACHE_FLAG_MATCHMORE;
08472
08473 AST_LIST_LOCK(&dpcache);
08474 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08475 if (strcmp(dp->exten, exten))
08476 continue;
08477 AST_LIST_REMOVE_CURRENT(peer_list);
08478 dp->callno = 0;
08479 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08480 if (dp->flags & CACHE_FLAG_PENDING) {
08481 dp->flags &= ~CACHE_FLAG_PENDING;
08482 dp->flags |= status;
08483 dp->flags |= matchmore;
08484 }
08485
08486 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08487 if (dp->waiters[x] > -1) {
08488 if (write(dp->waiters[x], "asdf", 4) < 0) {
08489 }
08490 }
08491 }
08492 }
08493 AST_LIST_TRAVERSE_SAFE_END;
08494 AST_LIST_UNLOCK(&dpcache);
08495
08496 return 0;
08497 }
08498
08499 static int complete_transfer(int callno, struct iax_ies *ies)
08500 {
08501 int peercallno = 0;
08502 struct chan_iax2_pvt *pvt = iaxs[callno];
08503 struct iax_frame *cur;
08504 jb_frame frame;
08505
08506 if (ies->callno)
08507 peercallno = ies->callno;
08508
08509 if (peercallno < 1) {
08510 ast_log(LOG_WARNING, "Invalid transfer request\n");
08511 return -1;
08512 }
08513 remove_by_transfercallno(pvt);
08514
08515
08516
08517 peercnt_remove_by_addr(&pvt->addr);
08518 peercnt_add(&pvt->transfer);
08519
08520 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08521 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08522
08523 pvt->oseqno = 0;
08524 pvt->rseqno = 0;
08525 pvt->iseqno = 0;
08526 pvt->aseqno = 0;
08527
08528 if (pvt->peercallno) {
08529 remove_by_peercallno(pvt);
08530 }
08531 pvt->peercallno = peercallno;
08532
08533 store_by_peercallno(pvt);
08534 pvt->transferring = TRANSFER_NONE;
08535 pvt->svoiceformat = -1;
08536 pvt->voiceformat = 0;
08537 pvt->svideoformat = -1;
08538 pvt->videoformat = 0;
08539 pvt->transfercallno = 0;
08540 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08541 memset(&pvt->offset, 0, sizeof(pvt->offset));
08542
08543 while(jb_getall(pvt->jb,&frame) == JB_OK)
08544 iax2_frame_free(frame.data);
08545 jb_reset(pvt->jb);
08546 pvt->lag = 0;
08547 pvt->last = 0;
08548 pvt->lastsent = 0;
08549 pvt->nextpred = 0;
08550 pvt->pingtime = DEFAULT_RETRY_TIME;
08551 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08552
08553
08554
08555 cur->retries = -1;
08556 }
08557 return 0;
08558 }
08559
08560
08561 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08562 {
08563 struct iax2_registry *reg;
08564
08565 char peer[256] = "";
08566 char msgstatus[60];
08567 int refresh = 60;
08568 char ourip[256] = "<Unspecified>";
08569 struct sockaddr_in oldus;
08570 struct sockaddr_in us;
08571 int oldmsgs;
08572 struct sockaddr_in reg_addr;
08573
08574 memset(&us, 0, sizeof(us));
08575 if (ies->apparent_addr) {
08576 memmove(&us, ies->apparent_addr, sizeof(us));
08577 }
08578 if (ies->username) {
08579 ast_copy_string(peer, ies->username, sizeof(peer));
08580 }
08581 if (ies->refresh) {
08582 refresh = ies->refresh;
08583 }
08584 if (ies->calling_number) {
08585
08586 }
08587 reg = iaxs[callno]->reg;
08588 if (!reg) {
08589 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08590 return -1;
08591 }
08592 memcpy(&oldus, ®->us, sizeof(oldus));
08593 oldmsgs = reg->messages;
08594 ast_sockaddr_to_sin(®->addr, ®_addr);
08595 if (inaddrcmp(®_addr, sin)) {
08596 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08597 return -1;
08598 }
08599 memcpy(®->us, &us, sizeof(reg->us));
08600 if (ies->msgcount >= 0) {
08601 reg->messages = ies->msgcount & 0xffff;
08602 }
08603
08604
08605
08606 reg->refresh = refresh;
08607 reg->expire = iax2_sched_replace(reg->expire, sched,
08608 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08609 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08610 if (reg->messages > 255) {
08611 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08612 } else if (reg->messages > 1) {
08613 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08614 } else if (reg->messages > 0) {
08615 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08616 } else {
08617 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08618 }
08619 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08620 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08621 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08622 }
08623 reg->regstate = REG_STATE_REGISTERED;
08624 return 0;
08625 }
08626
08627 static int iax2_append_register(const char *hostname, const char *username,
08628 const char *secret, const char *porta)
08629 {
08630 struct iax2_registry *reg;
08631
08632 if (!(reg = ast_calloc(1, sizeof(*reg))))
08633 return -1;
08634
08635 reg->addr.ss.ss_family = AF_INET;
08636 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08637 ast_free(reg);
08638 return -1;
08639 }
08640
08641 ast_copy_string(reg->username, username, sizeof(reg->username));
08642
08643 if (secret)
08644 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08645
08646 reg->expire = -1;
08647 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08648 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08649
08650 AST_LIST_LOCK(®istrations);
08651 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08652 AST_LIST_UNLOCK(®istrations);
08653
08654 return 0;
08655 }
08656
08657 static int iax2_register(const char *value, int lineno)
08658 {
08659 char copy[256];
08660 char *username, *hostname, *secret;
08661 char *porta;
08662 char *stringp=NULL;
08663
08664 if (!value)
08665 return -1;
08666
08667 ast_copy_string(copy, value, sizeof(copy));
08668 stringp = copy;
08669 username = strsep(&stringp, "@");
08670 hostname = strsep(&stringp, "@");
08671
08672 if (!hostname) {
08673 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08674 return -1;
08675 }
08676
08677 stringp = username;
08678 username = strsep(&stringp, ":");
08679 secret = strsep(&stringp, ":");
08680 stringp = hostname;
08681 hostname = strsep(&stringp, ":");
08682 porta = strsep(&stringp, ":");
08683
08684 if (porta && !atoi(porta)) {
08685 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08686 return -1;
08687 }
08688
08689 return iax2_append_register(hostname, username, secret, porta);
08690 }
08691
08692
08693 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08694 {
08695 char multi[256];
08696 char *stringp, *ext;
08697 if (!ast_strlen_zero(regcontext)) {
08698 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08699 stringp = multi;
08700 while((ext = strsep(&stringp, "&"))) {
08701 if (onoff) {
08702 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08703 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08704 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08705 } else
08706 ast_context_remove_extension(regcontext, ext, 1, NULL);
08707 }
08708 }
08709 }
08710 static void prune_peers(void);
08711
08712 static void unlink_peer(struct iax2_peer *peer)
08713 {
08714 if (peer->expire > -1) {
08715 if (!ast_sched_thread_del(sched, peer->expire)) {
08716 peer->expire = -1;
08717 peer_unref(peer);
08718 }
08719 }
08720
08721 if (peer->pokeexpire > -1) {
08722 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08723 peer->pokeexpire = -1;
08724 peer_unref(peer);
08725 }
08726 }
08727
08728 ao2_unlink(peers, peer);
08729 }
08730
08731 static void __expire_registry(const void *data)
08732 {
08733 struct iax2_peer *peer = (struct iax2_peer *) data;
08734
08735 if (!peer)
08736 return;
08737 if (peer->expire == -1) {
08738
08739 return;
08740 }
08741
08742 peer->expire = -1;
08743
08744 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08745 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08746 realtime_update_peer(peer->name, &peer->addr, 0);
08747 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08748
08749 peercnt_modify((unsigned char) 0, 0, &peer->addr);
08750
08751 memset(&peer->addr, 0, sizeof(peer->addr));
08752
08753 peer->expiry = min_reg_expire;
08754 if (!ast_test_flag64(peer, IAX_TEMPONLY))
08755 ast_db_del("IAX/Registry", peer->name);
08756 register_peer_exten(peer, 0);
08757 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
08758 if (iax2_regfunk)
08759 iax2_regfunk(peer->name, 0);
08760
08761 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08762 unlink_peer(peer);
08763
08764 peer_unref(peer);
08765 }
08766
08767 static int expire_registry(const void *data)
08768 {
08769 #ifdef SCHED_MULTITHREADED
08770 if (schedule_action(__expire_registry, data))
08771 #endif
08772 __expire_registry(data);
08773 return 0;
08774 }
08775
08776 static void reg_source_db(struct iax2_peer *p)
08777 {
08778 char data[80];
08779 char *expiry;
08780
08781 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08782 return;
08783 }
08784
08785 expiry = strrchr(data, ':');
08786 if (!expiry) {
08787 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08788 return;
08789 }
08790 *expiry++ = '\0';
08791
08792 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08793 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08794 return;
08795 }
08796
08797 p->expiry = atoi(expiry);
08798
08799 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08800 ast_sockaddr_stringify(&p->addr), p->expiry);
08801
08802 iax2_poke_peer(p, 0);
08803 if (p->expire > -1) {
08804 if (!ast_sched_thread_del(sched, p->expire)) {
08805 p->expire = -1;
08806 peer_unref(p);
08807 }
08808 }
08809
08810 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08811
08812 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08813 if (p->expire == -1) {
08814 peer_unref(p);
08815 }
08816
08817 if (iax2_regfunk) {
08818 iax2_regfunk(p->name, 1);
08819 }
08820
08821 register_peer_exten(p, 1);
08822 }
08823
08824
08825
08826
08827
08828
08829
08830 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08831 {
08832
08833 struct iax_ie_data ied = {
08834 .pos = 0,
08835 };
08836 struct iax2_peer *p;
08837 int msgcount;
08838 char data[80];
08839 int version;
08840 const char *peer_name;
08841 int res = -1;
08842 struct ast_sockaddr sockaddr;
08843
08844 ast_sockaddr_from_sin(&sockaddr, sin);
08845
08846 peer_name = ast_strdupa(iaxs[callno]->peer);
08847
08848
08849 ast_mutex_unlock(&iaxsl[callno]);
08850 if (!(p = find_peer(peer_name, 1))) {
08851 ast_mutex_lock(&iaxsl[callno]);
08852 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08853 return -1;
08854 }
08855 ast_mutex_lock(&iaxsl[callno]);
08856 if (!iaxs[callno])
08857 goto return_unref;
08858
08859 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08860 if (sin->sin_addr.s_addr) {
08861 time_t nowtime;
08862 time(&nowtime);
08863 realtime_update_peer(peer_name, &sockaddr, nowtime);
08864 } else {
08865 realtime_update_peer(peer_name, &sockaddr, 0);
08866 }
08867 }
08868
08869
08870 if (!refresh) {
08871 refresh = min_reg_expire;
08872 }
08873 if (refresh > max_reg_expire) {
08874 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08875 p->name, max_reg_expire, refresh);
08876 p->expiry = max_reg_expire;
08877 } else if (refresh < min_reg_expire) {
08878 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08879 p->name, min_reg_expire, refresh);
08880 p->expiry = min_reg_expire;
08881 } else {
08882 p->expiry = refresh;
08883 }
08884
08885 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08886 if (iax2_regfunk) {
08887 iax2_regfunk(p->name, 1);
08888 }
08889
08890
08891 peercnt_modify((unsigned char) 0, 0, &p->addr);
08892
08893
08894 ast_sockaddr_from_sin(&p->addr, sin);
08895
08896 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08897 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08898 ast_db_put("IAX/Registry", p->name, data);
08899 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08900 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08901 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08902 register_peer_exten(p, 1);
08903 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08904 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08905 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08906 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08907 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08908 register_peer_exten(p, 0);
08909 ast_db_del("IAX/Registry", p->name);
08910 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08911 }
08912
08913
08914 iax2_poke_peer(p, callno);
08915 }
08916
08917
08918 if (p->maxcallno) {
08919 peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr);
08920 }
08921
08922
08923 if (!iaxs[callno]) {
08924 res = -1;
08925 goto return_unref;
08926 }
08927
08928
08929 p->sockfd = fd;
08930
08931 if (p->expire > -1) {
08932 if (!ast_sched_thread_del(sched, p->expire)) {
08933 p->expire = -1;
08934 peer_unref(p);
08935 }
08936 }
08937
08938 if (p->expiry && sin->sin_addr.s_addr) {
08939 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08940 if (p->expire == -1)
08941 peer_unref(p);
08942 }
08943 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08944 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08945 if (sin->sin_addr.s_addr) {
08946 struct sockaddr_in peer_addr;
08947
08948 ast_sockaddr_to_sin(&p->addr, &peer_addr);
08949
08950 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08951 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08952 if (!ast_strlen_zero(p->mailbox)) {
08953 struct ast_event *event;
08954 int new, old;
08955 char *mailbox, *context;
08956
08957 context = mailbox = ast_strdupa(p->mailbox);
08958 strsep(&context, "@");
08959 if (ast_strlen_zero(context))
08960 context = "default";
08961
08962 event = ast_event_get_cached(AST_EVENT_MWI,
08963 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08964 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08965 AST_EVENT_IE_END);
08966 if (event) {
08967 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08968 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08969 ast_event_destroy(event);
08970 } else {
08971 ast_app_inboxcount(p->mailbox, &new, &old);
08972 }
08973
08974 if (new > 255) {
08975 new = 255;
08976 }
08977 if (old > 255) {
08978 old = 255;
08979 }
08980 msgcount = (old << 8) | new;
08981
08982 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08983 }
08984 if (ast_test_flag64(p, IAX_HASCALLERID)) {
08985 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08986 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08987 }
08988 }
08989 version = iax_check_version(devtype);
08990 if (version)
08991 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08992
08993 res = 0;
08994
08995 return_unref:
08996 peer_unref(p);
08997
08998 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08999 }
09000
09001 static int registry_authrequest(int callno)
09002 {
09003 struct iax_ie_data ied;
09004 struct iax2_peer *p;
09005 char challenge[10];
09006 const char *peer_name;
09007 int sentauthmethod;
09008
09009 peer_name = ast_strdupa(iaxs[callno]->peer);
09010
09011
09012 ast_mutex_unlock(&iaxsl[callno]);
09013 if ((p = find_peer(peer_name, 1))) {
09014 last_authmethod = p->authmethods;
09015 }
09016
09017 ast_mutex_lock(&iaxsl[callno]);
09018 if (!iaxs[callno])
09019 goto return_unref;
09020
09021 memset(&ied, 0, sizeof(ied));
09022
09023
09024
09025
09026
09027
09028 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
09029 if (!p) {
09030 iaxs[callno]->authmethods = sentauthmethod;
09031 }
09032 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
09033 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
09034
09035 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
09036 ast_string_field_set(iaxs[callno], challenge, challenge);
09037 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
09038 }
09039 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
09040
09041 return_unref:
09042 if (p) {
09043 peer_unref(p);
09044 }
09045
09046 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
09047 }
09048
09049 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
09050 {
09051 struct iax2_registry *reg;
09052
09053 struct iax_ie_data ied;
09054 char peer[256] = "";
09055 char challenge[256] = "";
09056 int res;
09057 int authmethods = 0;
09058 if (ies->authmethods)
09059 authmethods = ies->authmethods;
09060 if (ies->username)
09061 ast_copy_string(peer, ies->username, sizeof(peer));
09062 if (ies->challenge)
09063 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
09064 memset(&ied, 0, sizeof(ied));
09065 reg = iaxs[callno]->reg;
09066 if (reg) {
09067 struct sockaddr_in reg_addr;
09068
09069 ast_sockaddr_to_sin(®->addr, ®_addr);
09070
09071 if (inaddrcmp(®_addr, sin)) {
09072 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
09073 return -1;
09074 }
09075 if (ast_strlen_zero(reg->secret)) {
09076 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
09077 reg->regstate = REG_STATE_NOAUTH;
09078 return -1;
09079 }
09080 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
09081 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
09082 if (reg->secret[0] == '[') {
09083 char tmpkey[256];
09084 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
09085 tmpkey[strlen(tmpkey) - 1] = '\0';
09086 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
09087 } else
09088 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
09089 if (!res) {
09090 reg->regstate = REG_STATE_AUTHSENT;
09091 add_empty_calltoken_ie(iaxs[callno], &ied);
09092 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
09093 } else
09094 return -1;
09095 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
09096 } else
09097 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
09098 return -1;
09099 }
09100
09101 static void stop_stuff(int callno)
09102 {
09103 iax2_destroy_helper(iaxs[callno]);
09104 }
09105
09106 static void __auth_reject(const void *nothing)
09107 {
09108
09109 int callno = (int)(long)(nothing);
09110 struct iax_ie_data ied;
09111 ast_mutex_lock(&iaxsl[callno]);
09112 if (iaxs[callno]) {
09113 memset(&ied, 0, sizeof(ied));
09114 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
09115 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
09116 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
09117 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
09118 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
09119 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09120 }
09121 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
09122 }
09123 ast_mutex_unlock(&iaxsl[callno]);
09124 }
09125
09126 static int auth_reject(const void *data)
09127 {
09128 int callno = (int)(long)(data);
09129 ast_mutex_lock(&iaxsl[callno]);
09130 if (iaxs[callno])
09131 iaxs[callno]->authid = -1;
09132 ast_mutex_unlock(&iaxsl[callno]);
09133 #ifdef SCHED_MULTITHREADED
09134 if (schedule_action(__auth_reject, data))
09135 #endif
09136 __auth_reject(data);
09137 return 0;
09138 }
09139
09140 static int auth_fail(int callno, int failcode)
09141 {
09142
09143
09144 if (iaxs[callno]) {
09145 iaxs[callno]->authfail = failcode;
09146 if (delayreject) {
09147 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
09148 sched, 1000, auth_reject, (void *)(long)callno);
09149 } else
09150 auth_reject((void *)(long)callno);
09151 }
09152 return 0;
09153 }
09154
09155 static void __auto_hangup(const void *nothing)
09156 {
09157
09158 int callno = (int)(long)(nothing);
09159 struct iax_ie_data ied;
09160 ast_mutex_lock(&iaxsl[callno]);
09161 if (iaxs[callno]) {
09162 memset(&ied, 0, sizeof(ied));
09163 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09164 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09165 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09166 }
09167 ast_mutex_unlock(&iaxsl[callno]);
09168 }
09169
09170 static int auto_hangup(const void *data)
09171 {
09172 int callno = (int)(long)(data);
09173 ast_mutex_lock(&iaxsl[callno]);
09174 if (iaxs[callno]) {
09175 iaxs[callno]->autoid = -1;
09176 }
09177 ast_mutex_unlock(&iaxsl[callno]);
09178 #ifdef SCHED_MULTITHREADED
09179 if (schedule_action(__auto_hangup, data))
09180 #endif
09181 __auto_hangup(data);
09182 return 0;
09183 }
09184
09185 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
09186 {
09187 struct iax_ie_data ied;
09188
09189 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
09190 sched, 30000, auto_hangup, (void *)(long)callno);
09191 memset(&ied, 0, sizeof(ied));
09192 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09193 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09194 dp->flags |= CACHE_FLAG_TRANSMITTED;
09195 }
09196
09197 static int iax2_vnak(int callno)
09198 {
09199 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09200 }
09201
09202 static void vnak_retransmit(int callno, int last)
09203 {
09204 struct iax_frame *f;
09205
09206 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09207
09208 if (((unsigned char) (f->oseqno - last) < 128) &&
09209 (f->retries >= 0)) {
09210 send_packet(f);
09211 }
09212 }
09213 }
09214
09215 static void __iax2_poke_peer_s(const void *data)
09216 {
09217 struct iax2_peer *peer = (struct iax2_peer *)data;
09218 iax2_poke_peer(peer, 0);
09219 peer_unref(peer);
09220 }
09221
09222 static int iax2_poke_peer_s(const void *data)
09223 {
09224 struct iax2_peer *peer = (struct iax2_peer *)data;
09225 peer->pokeexpire = -1;
09226 #ifdef SCHED_MULTITHREADED
09227 if (schedule_action(__iax2_poke_peer_s, data))
09228 #endif
09229 __iax2_poke_peer_s(data);
09230 return 0;
09231 }
09232
09233 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
09234 {
09235 int res = 0;
09236 struct iax_frame *fr;
09237 struct ast_iax2_meta_hdr *meta;
09238 struct ast_iax2_meta_trunk_hdr *mth;
09239 int calls = 0;
09240
09241
09242 fr = (struct iax_frame *)tpeer->trunkdata;
09243
09244 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09245 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09246 if (tpeer->trunkdatalen) {
09247
09248 meta->zeros = 0;
09249 meta->metacmd = IAX_META_TRUNK;
09250 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09251 meta->cmddata = IAX_META_TRUNK_MINI;
09252 else
09253 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09254 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09255
09256 fr->direction = DIRECTION_OUTGRESS;
09257 fr->retrans = -1;
09258 fr->transfer = 0;
09259
09260 fr->data = fr->afdata;
09261 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09262 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09263 calls = tpeer->calls;
09264 #if 0
09265 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));
09266 #endif
09267
09268 tpeer->trunkdatalen = 0;
09269 tpeer->calls = 0;
09270 }
09271 if (res < 0)
09272 return res;
09273 return calls;
09274 }
09275
09276 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
09277 {
09278
09279 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
09280 return 1;
09281 return 0;
09282 }
09283
09284 static int timing_read(int *id, int fd, short events, void *cbdata)
09285 {
09286 int res, processed = 0, totalcalls = 0;
09287 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09288 struct timeval now = ast_tvnow();
09289
09290 if (iaxtrunkdebug)
09291 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09292
09293 if (timer) {
09294 if (ast_timer_ack(timer, 1) < 0) {
09295 ast_log(LOG_ERROR, "Timer failed acknowledge\n");
09296 return 0;
09297 }
09298 }
09299
09300
09301 AST_LIST_LOCK(&tpeers);
09302 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09303 processed++;
09304 res = 0;
09305 ast_mutex_lock(&tpeer->lock);
09306
09307
09308 if (!drop && iax2_trunk_expired(tpeer, &now)) {
09309
09310
09311 AST_LIST_REMOVE_CURRENT(list);
09312 drop = tpeer;
09313 } else {
09314 res = send_trunk(tpeer, &now);
09315 trunk_timed++;
09316 if (iaxtrunkdebug)
09317 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);
09318 }
09319 totalcalls += res;
09320 res = 0;
09321 ast_mutex_unlock(&tpeer->lock);
09322 }
09323 AST_LIST_TRAVERSE_SAFE_END;
09324 AST_LIST_UNLOCK(&tpeers);
09325
09326 if (drop) {
09327 ast_mutex_lock(&drop->lock);
09328
09329
09330 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09331 if (drop->trunkdata) {
09332 ast_free(drop->trunkdata);
09333 drop->trunkdata = NULL;
09334 }
09335 ast_mutex_unlock(&drop->lock);
09336 ast_mutex_destroy(&drop->lock);
09337 ast_free(drop);
09338
09339 }
09340
09341 if (iaxtrunkdebug)
09342 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09343 iaxtrunkdebug = 0;
09344
09345 return 1;
09346 }
09347
09348 struct dpreq_data {
09349 int callno;
09350 char context[AST_MAX_EXTENSION];
09351 char callednum[AST_MAX_EXTENSION];
09352 char *callerid;
09353 };
09354
09355 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
09356 {
09357 unsigned short dpstatus = 0;
09358 struct iax_ie_data ied1;
09359 int mm;
09360
09361 memset(&ied1, 0, sizeof(ied1));
09362 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09363
09364 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09365 dpstatus = IAX_DPSTATUS_EXISTS;
09366 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09367 dpstatus = IAX_DPSTATUS_CANEXIST;
09368 } else {
09369 dpstatus = IAX_DPSTATUS_NONEXISTENT;
09370 }
09371 if (ast_ignore_pattern(context, callednum))
09372 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09373 if (mm)
09374 dpstatus |= IAX_DPSTATUS_MATCHMORE;
09375 if (!skiplock)
09376 ast_mutex_lock(&iaxsl[callno]);
09377 if (iaxs[callno]) {
09378 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09379 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09380 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09381 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09382 }
09383 if (!skiplock)
09384 ast_mutex_unlock(&iaxsl[callno]);
09385 }
09386
09387 static void *dp_lookup_thread(void *data)
09388 {
09389
09390 struct dpreq_data *dpr = data;
09391 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09392 if (dpr->callerid)
09393 ast_free(dpr->callerid);
09394 ast_free(dpr);
09395 return NULL;
09396 }
09397
09398 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
09399 {
09400 pthread_t newthread;
09401 struct dpreq_data *dpr;
09402
09403 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09404 return;
09405
09406 dpr->callno = callno;
09407 ast_copy_string(dpr->context, context, sizeof(dpr->context));
09408 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09409 if (callerid)
09410 dpr->callerid = ast_strdup(callerid);
09411 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09412 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09413 }
09414 }
09415
09416 struct iax_dual {
09417 struct ast_channel *chan1;
09418 struct ast_channel *chan2;
09419 char *park_exten;
09420 char *park_context;
09421 };
09422
09423 static void *iax_park_thread(void *stuff)
09424 {
09425 struct iax_dual *d;
09426 int res;
09427 int ext = 0;
09428
09429 d = stuff;
09430
09431 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09432 d->chan2->name, d->chan1->name);
09433
09434 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09435 if (res) {
09436
09437 ast_hangup(d->chan1);
09438 } else {
09439 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09440 }
09441 ast_hangup(d->chan2);
09442
09443 ast_free(d->park_exten);
09444 ast_free(d->park_context);
09445 ast_free(d);
09446 return NULL;
09447 }
09448
09449
09450 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
09451 {
09452 struct iax_dual *d;
09453 struct ast_channel *chan1m, *chan2m;
09454 pthread_t th;
09455
09456 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09457 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09458 d = ast_calloc(1, sizeof(*d));
09459 if (!chan1m || !chan2m || !d) {
09460 if (chan1m) {
09461 ast_hangup(chan1m);
09462 }
09463 if (chan2m) {
09464 ast_hangup(chan2m);
09465 }
09466 ast_free(d);
09467 return -1;
09468 }
09469 d->park_exten = ast_strdup(park_exten);
09470 d->park_context = ast_strdup(park_context);
09471 if (!d->park_exten || !d->park_context) {
09472 ast_hangup(chan1m);
09473 ast_hangup(chan2m);
09474 ast_free(d->park_exten);
09475 ast_free(d->park_context);
09476 ast_free(d);
09477 return -1;
09478 }
09479
09480
09481 chan1m->readformat = chan1->readformat;
09482 chan1m->writeformat = chan1->writeformat;
09483
09484
09485 if (ast_channel_masquerade(chan1m, chan1)) {
09486 ast_hangup(chan1m);
09487 ast_hangup(chan2m);
09488 ast_free(d->park_exten);
09489 ast_free(d->park_context);
09490 ast_free(d);
09491 return -1;
09492 }
09493
09494
09495 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09496 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09497 chan1m->priority = chan1->priority;
09498
09499 ast_do_masquerade(chan1m);
09500
09501
09502
09503
09504
09505 chan2m->readformat = chan2->readformat;
09506 chan2m->writeformat = chan2->writeformat;
09507 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot);
09508
09509
09510 if (ast_channel_masquerade(chan2m, chan2)) {
09511 ast_hangup(chan1m);
09512 ast_hangup(chan2m);
09513 ast_free(d->park_exten);
09514 ast_free(d->park_context);
09515 ast_free(d);
09516 return -1;
09517 }
09518
09519
09520 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09521 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09522 chan2m->priority = chan2->priority;
09523
09524 ast_do_masquerade(chan2m);
09525
09526 d->chan1 = chan1m;
09527 d->chan2 = chan2m;
09528 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09529
09530 ast_hangup(chan1m);
09531 ast_hangup(chan2m);
09532 ast_free(d->park_exten);
09533 ast_free(d->park_context);
09534 ast_free(d);
09535 return -1;
09536 }
09537 return 0;
09538 }
09539
09540 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09541 {
09542 unsigned int ourver;
09543 char rsi[80];
09544 snprintf(rsi, sizeof(rsi), "si-%s", si);
09545 if (iax_provision_version(&ourver, rsi, 1))
09546 return 0;
09547 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09548 if (ourver != ver)
09549 iax2_provision(sin, sockfd, NULL, rsi, 1);
09550 return 0;
09551 }
09552
09553 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09554 {
09555 jb_info stats;
09556 jb_getinfo(pvt->jb, &stats);
09557
09558 memset(iep, 0, sizeof(*iep));
09559
09560 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09561 if(stats.frames_in == 0) stats.frames_in = 1;
09562 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09563 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09564 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09565 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09566 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09567 }
09568
09569 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09570 {
09571 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09572 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09573 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09574 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09575 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09576 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09577 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09578 }
09579
09580 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09581 {
09582 int i;
09583 unsigned int length, offset = 0;
09584 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09585
09586 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09587 length = ies->ospblocklength[i];
09588 if (length != 0) {
09589 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09590
09591 offset = 0;
09592 break;
09593 } else {
09594 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09595 offset += length;
09596 }
09597 } else {
09598 break;
09599 }
09600 }
09601 *(full_osptoken + offset) = '\0';
09602 if (strlen(full_osptoken) != offset) {
09603
09604 *full_osptoken = '\0';
09605 }
09606
09607 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09608 }
09609
09610 static void log_jitterstats(unsigned short callno)
09611 {
09612 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09613 jb_info jbinfo;
09614
09615 ast_mutex_lock(&iaxsl[callno]);
09616 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09617 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09618 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09619 localjitter = jbinfo.jitter;
09620 localdelay = jbinfo.current - jbinfo.min;
09621 locallost = jbinfo.frames_lost;
09622 locallosspct = jbinfo.losspct/1000;
09623 localdropped = jbinfo.frames_dropped;
09624 localooo = jbinfo.frames_ooo;
09625 localpackets = jbinfo.frames_in;
09626 }
09627 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",
09628 iaxs[callno]->owner->name,
09629 iaxs[callno]->pingtime,
09630 localjitter,
09631 localdelay,
09632 locallost,
09633 locallosspct,
09634 localdropped,
09635 localooo,
09636 localpackets,
09637 iaxs[callno]->remote_rr.jitter,
09638 iaxs[callno]->remote_rr.delay,
09639 iaxs[callno]->remote_rr.losscnt,
09640 iaxs[callno]->remote_rr.losspct/1000,
09641 iaxs[callno]->remote_rr.dropped,
09642 iaxs[callno]->remote_rr.ooo,
09643 iaxs[callno]->remote_rr.packets);
09644 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",
09645 iaxs[callno]->owner->name,
09646 iaxs[callno]->pingtime,
09647 localjitter,
09648 localdelay,
09649 locallost,
09650 locallosspct,
09651 localdropped,
09652 localooo,
09653 localpackets,
09654 iaxs[callno]->remote_rr.jitter,
09655 iaxs[callno]->remote_rr.delay,
09656 iaxs[callno]->remote_rr.losscnt,
09657 iaxs[callno]->remote_rr.losspct/1000,
09658 iaxs[callno]->remote_rr.dropped,
09659 iaxs[callno]->remote_rr.ooo,
09660 iaxs[callno]->remote_rr.packets);
09661 }
09662 ast_mutex_unlock(&iaxsl[callno]);
09663 }
09664
09665 static int socket_process(struct iax2_thread *thread);
09666
09667
09668
09669
09670 static void handle_deferred_full_frames(struct iax2_thread *thread)
09671 {
09672 struct iax2_pkt_buf *pkt_buf;
09673
09674 ast_mutex_lock(&thread->lock);
09675
09676 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09677 ast_mutex_unlock(&thread->lock);
09678
09679 thread->buf = pkt_buf->buf;
09680 thread->buf_len = pkt_buf->len;
09681 thread->buf_size = pkt_buf->len + 1;
09682
09683 socket_process(thread);
09684
09685 thread->buf = NULL;
09686 ast_free(pkt_buf);
09687
09688 ast_mutex_lock(&thread->lock);
09689 }
09690
09691 ast_mutex_unlock(&thread->lock);
09692 }
09693
09694
09695
09696
09697
09698
09699
09700 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09701 {
09702 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09703 struct ast_iax2_full_hdr *fh, *cur_fh;
09704
09705 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09706 return;
09707
09708 pkt_buf->len = from_here->buf_len;
09709 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09710
09711 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09712 ast_mutex_lock(&to_here->lock);
09713 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09714 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09715 if (fh->oseqno < cur_fh->oseqno) {
09716 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09717 break;
09718 }
09719 }
09720 AST_LIST_TRAVERSE_SAFE_END
09721
09722 if (!cur_pkt_buf)
09723 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09724
09725 to_here->iostate = IAX_IOSTATE_READY;
09726 ast_cond_signal(&to_here->cond);
09727
09728 ast_mutex_unlock(&to_here->lock);
09729 }
09730
09731 static int socket_read(int *id, int fd, short events, void *cbdata)
09732 {
09733 struct iax2_thread *thread;
09734 socklen_t len;
09735 time_t t;
09736 static time_t last_errtime = 0;
09737 struct ast_iax2_full_hdr *fh;
09738
09739 if (!(thread = find_idle_thread())) {
09740 time(&t);
09741 if (t != last_errtime) {
09742 last_errtime = t;
09743 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09744 }
09745 usleep(1);
09746 return 1;
09747 }
09748
09749 len = sizeof(thread->iosin);
09750 thread->iofd = fd;
09751 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09752 thread->buf_size = sizeof(thread->readbuf);
09753 thread->buf = thread->readbuf;
09754 if (thread->buf_len < 0) {
09755 if (errno != ECONNREFUSED && errno != EAGAIN)
09756 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09757 handle_error();
09758 thread->iostate = IAX_IOSTATE_IDLE;
09759 signal_condition(&thread->lock, &thread->cond);
09760 return 1;
09761 }
09762 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09763 thread->iostate = IAX_IOSTATE_IDLE;
09764 signal_condition(&thread->lock, &thread->cond);
09765 return 1;
09766 }
09767
09768
09769
09770
09771 fh = (struct ast_iax2_full_hdr *) thread->buf;
09772 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09773 struct iax2_thread *cur = NULL;
09774 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09775
09776 AST_LIST_LOCK(&active_list);
09777 AST_LIST_TRAVERSE(&active_list, cur, list) {
09778 if ((cur->ffinfo.callno == callno) &&
09779 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09780 break;
09781 }
09782 if (cur) {
09783
09784
09785 defer_full_frame(thread, cur);
09786 AST_LIST_UNLOCK(&active_list);
09787 thread->iostate = IAX_IOSTATE_IDLE;
09788 signal_condition(&thread->lock, &thread->cond);
09789 return 1;
09790 } else {
09791
09792 thread->ffinfo.callno = callno;
09793 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09794 thread->ffinfo.type = fh->type;
09795 thread->ffinfo.csub = fh->csub;
09796 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09797 }
09798 AST_LIST_UNLOCK(&active_list);
09799 }
09800
09801
09802 thread->iostate = IAX_IOSTATE_READY;
09803 #ifdef DEBUG_SCHED_MULTITHREAD
09804 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09805 #endif
09806 signal_condition(&thread->lock, &thread->cond);
09807
09808 return 1;
09809 }
09810
09811 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09812 struct iax_frame *fr)
09813 {
09814 unsigned char metatype;
09815 struct ast_iax2_meta_trunk_mini *mtm;
09816 struct ast_iax2_meta_trunk_hdr *mth;
09817 struct ast_iax2_meta_trunk_entry *mte;
09818 struct iax2_trunk_peer *tpeer;
09819 unsigned int ts;
09820 void *ptr;
09821 struct timeval rxtrunktime;
09822 struct ast_frame f = { 0, };
09823
09824 if (packet_len < sizeof(*meta)) {
09825 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09826 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09827 return 1;
09828 }
09829
09830 if (meta->metacmd != IAX_META_TRUNK)
09831 return 1;
09832
09833 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09834 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09835 (int) (sizeof(*meta) + sizeof(*mth)));
09836 return 1;
09837 }
09838 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09839 ts = ntohl(mth->ts);
09840 metatype = meta->cmddata;
09841 packet_len -= (sizeof(*meta) + sizeof(*mth));
09842 ptr = mth->data;
09843 tpeer = find_tpeer(sin, sockfd);
09844 if (!tpeer) {
09845 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09846 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09847 return 1;
09848 }
09849 tpeer->trunkact = ast_tvnow();
09850 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09851 tpeer->rxtrunktime = tpeer->trunkact;
09852 rxtrunktime = tpeer->rxtrunktime;
09853 ast_mutex_unlock(&tpeer->lock);
09854 while (packet_len >= sizeof(*mte)) {
09855
09856 unsigned short callno, trunked_ts, len;
09857
09858 if (metatype == IAX_META_TRUNK_MINI) {
09859 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09860 ptr += sizeof(*mtm);
09861 packet_len -= sizeof(*mtm);
09862 len = ntohs(mtm->len);
09863 callno = ntohs(mtm->mini.callno);
09864 trunked_ts = ntohs(mtm->mini.ts);
09865 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09866 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09867 ptr += sizeof(*mte);
09868 packet_len -= sizeof(*mte);
09869 len = ntohs(mte->len);
09870 callno = ntohs(mte->callno);
09871 trunked_ts = 0;
09872 } else {
09873 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09874 break;
09875 }
09876
09877 if (len > packet_len)
09878 break;
09879 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09880 if (!fr->callno)
09881 continue;
09882
09883
09884
09885
09886 memset(&f, 0, sizeof(f));
09887 f.frametype = AST_FRAME_VOICE;
09888 if (!iaxs[fr->callno]) {
09889
09890 } else if (iaxs[fr->callno]->voiceformat == 0) {
09891 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09892 iax2_vnak(fr->callno);
09893 } else {
09894 f.subclass.codec = iaxs[fr->callno]->voiceformat;
09895 f.datalen = len;
09896 if (f.datalen >= 0) {
09897 if (f.datalen)
09898 f.data.ptr = ptr;
09899 else
09900 f.data.ptr = NULL;
09901 if (trunked_ts)
09902 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09903 else
09904 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09905
09906 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09907 struct iax_frame *duped_fr;
09908
09909
09910 f.src = "IAX2";
09911 f.mallocd = 0;
09912 f.offset = 0;
09913 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09914 f.samples = ast_codec_get_samples(&f);
09915 else
09916 f.samples = 0;
09917 fr->outoforder = 0;
09918 iax_frame_wrap(fr, &f);
09919 duped_fr = iaxfrdup2(fr);
09920 if (duped_fr)
09921 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09922 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09923 iaxs[fr->callno]->last = fr->ts;
09924 }
09925 } else {
09926 ast_log(LOG_WARNING, "Datalen < 0?\n");
09927 }
09928 }
09929 ast_mutex_unlock(&iaxsl[fr->callno]);
09930 ptr += len;
09931 packet_len -= len;
09932 }
09933
09934 return 1;
09935 }
09936
09937 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09938 {
09939 struct ast_datastore *variablestore;
09940 AST_LIST_HEAD(, ast_var_t) *varlist;
09941 struct ast_var_t *var;
09942
09943 if (!chan) {
09944 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
09945 return -1;
09946 }
09947
09948 variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09949
09950 if (!variablestore) {
09951 *buf = '\0';
09952 return 0;
09953 }
09954 varlist = variablestore->data;
09955
09956 AST_LIST_LOCK(varlist);
09957 AST_LIST_TRAVERSE(varlist, var, entries) {
09958 if (strcmp(var->name, data) == 0) {
09959 ast_copy_string(buf, var->value, len);
09960 break;
09961 }
09962 }
09963 AST_LIST_UNLOCK(varlist);
09964 return 0;
09965 }
09966
09967 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09968 {
09969 struct ast_datastore *variablestore;
09970 AST_LIST_HEAD(, ast_var_t) *varlist;
09971 struct ast_var_t *var;
09972
09973 if (!chan) {
09974 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
09975 return -1;
09976 }
09977
09978 variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09979
09980 if (!variablestore) {
09981 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09982 if (!variablestore) {
09983 ast_log(LOG_ERROR, "Memory allocation error\n");
09984 return -1;
09985 }
09986 varlist = ast_calloc(1, sizeof(*varlist));
09987 if (!varlist) {
09988 ast_datastore_free(variablestore);
09989 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09990 return -1;
09991 }
09992
09993 AST_LIST_HEAD_INIT(varlist);
09994 variablestore->data = varlist;
09995 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09996 ast_channel_datastore_add(chan, variablestore);
09997 } else
09998 varlist = variablestore->data;
09999
10000 AST_LIST_LOCK(varlist);
10001 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
10002 if (strcmp(var->name, data) == 0) {
10003 AST_LIST_REMOVE_CURRENT(entries);
10004 ast_var_delete(var);
10005 break;
10006 }
10007 }
10008 AST_LIST_TRAVERSE_SAFE_END;
10009 var = ast_var_assign(data, value);
10010 if (var)
10011 AST_LIST_INSERT_TAIL(varlist, var, entries);
10012 else
10013 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
10014 AST_LIST_UNLOCK(varlist);
10015 return 0;
10016 }
10017
10018 static struct ast_custom_function iaxvar_function = {
10019 .name = "IAXVAR",
10020 .read = acf_iaxvar_read,
10021 .write = acf_iaxvar_write,
10022 };
10023
10024 static void set_hangup_source_and_cause(int callno, unsigned char causecode)
10025 {
10026 iax2_lock_owner(callno);
10027 if (iaxs[callno] && iaxs[callno]->owner) {
10028 struct ast_channel *owner;
10029 const char *name;
10030
10031 owner = iaxs[callno]->owner;
10032 if (causecode) {
10033 owner->hangupcause = causecode;
10034 }
10035 name = ast_strdupa(owner->name);
10036 ast_channel_ref(owner);
10037 ast_channel_unlock(owner);
10038 ast_mutex_unlock(&iaxsl[callno]);
10039 ast_set_hangupsource(owner, name, 0);
10040 ast_channel_unref(owner);
10041 ast_mutex_lock(&iaxsl[callno]);
10042 }
10043 }
10044
10045 static int socket_process(struct iax2_thread *thread)
10046 {
10047 struct sockaddr_in sin;
10048 int res;
10049 int updatehistory=1;
10050 int new = NEW_PREVENT;
10051 int dcallno = 0;
10052 char decrypted = 0;
10053 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
10054 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
10055 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
10056 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
10057 struct iax_frame *fr;
10058 struct iax_frame *cur;
10059 struct ast_frame f = { 0, };
10060 struct ast_channel *c = NULL;
10061 struct iax2_dpcache *dp;
10062 struct iax2_peer *peer;
10063 struct iax_ies ies;
10064 struct iax_ie_data ied0, ied1;
10065 format_t format;
10066 int fd;
10067 int exists;
10068 int minivid = 0;
10069 char empty[32]="";
10070 struct iax_frame *duped_fr;
10071 char host_pref_buf[128];
10072 char caller_pref_buf[128];
10073 struct ast_codec_pref pref;
10074 char *using_prefs = "mine";
10075
10076
10077 fr = ast_alloca(sizeof(*fr) + 4096);
10078 memset(fr, 0, sizeof(*fr));
10079 fr->afdatalen = 4096;
10080
10081
10082 res = thread->buf_len;
10083 fd = thread->iofd;
10084 memcpy(&sin, &thread->iosin, sizeof(sin));
10085
10086 if (res < sizeof(*mh)) {
10087 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
10088 return 1;
10089 }
10090 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
10091 if (res < sizeof(*vh)) {
10092 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));
10093 return 1;
10094 }
10095
10096
10097 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
10098 minivid = 1;
10099 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
10100 return socket_process_meta(res, meta, &sin, fd, fr);
10101
10102 #ifdef DEBUG_SUPPORT
10103 if (res >= sizeof(*fh))
10104 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
10105 #endif
10106 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10107 if (res < sizeof(*fh)) {
10108 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));
10109 return 1;
10110 }
10111
10112
10113 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
10114
10115
10116
10117
10118
10119
10120 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
10121 ast_mutex_lock(&iaxsl[fr->callno]);
10122 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
10123 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10124 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10125 ast_mutex_unlock(&iaxsl[fr->callno]);
10126 return 1;
10127 }
10128 decrypted = 1;
10129 }
10130 ast_mutex_unlock(&iaxsl[fr->callno]);
10131 }
10132
10133
10134 f.frametype = fh->type;
10135 if (f.frametype == AST_FRAME_VIDEO) {
10136 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
10137 } else if (f.frametype == AST_FRAME_VOICE) {
10138 f.subclass.codec = uncompress_subclass(fh->csub);
10139 } else {
10140 f.subclass.integer = uncompress_subclass(fh->csub);
10141 }
10142
10143
10144 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
10145
10146 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10147 return 1;
10148 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10149
10150 return 1;
10151 }
10152
10153 f.datalen = res - sizeof(*fh);
10154 if (f.datalen) {
10155 if (f.frametype == AST_FRAME_IAX) {
10156 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10157 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
10158 ast_variables_destroy(ies.vars);
10159 return 1;
10160 }
10161 f.data.ptr = NULL;
10162 f.datalen = 0;
10163 } else {
10164 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10165 memset(&ies, 0, sizeof(ies));
10166 }
10167 } else {
10168 if (f.frametype == AST_FRAME_IAX)
10169 f.data.ptr = NULL;
10170 else
10171 f.data.ptr = empty;
10172 memset(&ies, 0, sizeof(ies));
10173 }
10174
10175 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10176
10177 if (handle_call_token(fh, &ies, &sin, fd)) {
10178 ast_variables_destroy(ies.vars);
10179 return 1;
10180 }
10181
10182 if (ies.calltoken && ies.calltokendata) {
10183
10184
10185
10186
10187 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10188 } else {
10189 new = NEW_ALLOW;
10190 }
10191 }
10192 } else {
10193
10194 f.frametype = AST_FRAME_NULL;
10195 f.subclass.integer = 0;
10196 memset(&ies, 0, sizeof(ies));
10197 }
10198
10199 if (!fr->callno) {
10200 int check_dcallno = 0;
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10211 check_dcallno = 1;
10212 }
10213
10214 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10215 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10216 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10217 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10218 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10219 }
10220 ast_variables_destroy(ies.vars);
10221 return 1;
10222 }
10223 }
10224
10225 if (fr->callno > 0)
10226 ast_mutex_lock(&iaxsl[fr->callno]);
10227
10228 if (!fr->callno || !iaxs[fr->callno]) {
10229
10230
10231 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10232
10233 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10234 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10235 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10236 (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10237 (f.frametype != AST_FRAME_IAX))
10238 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10239 fd);
10240 }
10241 if (fr->callno > 0)
10242 ast_mutex_unlock(&iaxsl[fr->callno]);
10243 ast_variables_destroy(ies.vars);
10244 return 1;
10245 }
10246 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10247 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10248 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10249 ast_variables_destroy(ies.vars);
10250 ast_mutex_unlock(&iaxsl[fr->callno]);
10251 return 1;
10252 }
10253 decrypted = 1;
10254 }
10255
10256 #ifdef DEBUG_SUPPORT
10257 if (decrypted) {
10258 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10259 }
10260 #endif
10261
10262
10263
10264 iaxs[fr->callno]->frames_received++;
10265
10266 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10267 f.subclass.integer != IAX_COMMAND_TXCNT &&
10268 f.subclass.integer != IAX_COMMAND_TXACC) {
10269 unsigned short new_peercallno;
10270
10271 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10272 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10273 if (iaxs[fr->callno]->peercallno) {
10274 remove_by_peercallno(iaxs[fr->callno]);
10275 }
10276 iaxs[fr->callno]->peercallno = new_peercallno;
10277 store_by_peercallno(iaxs[fr->callno]);
10278 }
10279 }
10280 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10281 if (iaxdebug)
10282 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10283
10284 fr->oseqno = fh->oseqno;
10285 fr->iseqno = fh->iseqno;
10286 fr->ts = ntohl(fh->ts);
10287 #ifdef IAXTESTS
10288 if (test_resync) {
10289 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10290 fr->ts += test_resync;
10291 }
10292 #endif
10293 #if 0
10294 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10295 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10296 (f.subclass == IAX_COMMAND_NEW ||
10297 f.subclass == IAX_COMMAND_AUTHREQ ||
10298 f.subclass == IAX_COMMAND_ACCEPT ||
10299 f.subclass == IAX_COMMAND_REJECT)) ) )
10300 #endif
10301 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10302 updatehistory = 0;
10303 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10304 (iaxs[fr->callno]->iseqno ||
10305 ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10306 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10307 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10308 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10309 (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10310 (f.frametype != AST_FRAME_IAX))) {
10311 if (
10312 ((f.subclass.integer != IAX_COMMAND_ACK) &&
10313 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10314 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10315 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10316 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10317 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10318 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10319 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10320 (f.frametype != AST_FRAME_IAX)) {
10321
10322 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
10323 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10324
10325
10326 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10327
10328 if ((f.frametype != AST_FRAME_IAX) ||
10329 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10330 ast_debug(1, "Acking anyway\n");
10331
10332
10333 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10334 }
10335 } else {
10336
10337 iax2_vnak(fr->callno);
10338 }
10339 ast_variables_destroy(ies.vars);
10340 ast_mutex_unlock(&iaxsl[fr->callno]);
10341 return 1;
10342 }
10343 } else {
10344
10345 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10346 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10347 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10348 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10349 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10350 (f.frametype != AST_FRAME_IAX))
10351 iaxs[fr->callno]->iseqno++;
10352 }
10353
10354 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10355 if (res < thread->buf_size)
10356 thread->buf[res++] = '\0';
10357 else
10358 thread->buf[res - 1] = '\0';
10359 }
10360
10361
10362
10363 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10364 ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10365 (f.frametype != AST_FRAME_IAX))) {
10366 unsigned char x;
10367 int call_to_destroy;
10368
10369 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10370 x = fr->iseqno;
10371 else
10372 x = iaxs[fr->callno]->oseqno;
10373 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10374
10375
10376 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10377
10378 if (iaxdebug)
10379 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10380 call_to_destroy = 0;
10381 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10382
10383 if (x == cur->oseqno) {
10384 cur->retries = -1;
10385
10386 if (cur->final)
10387 call_to_destroy = fr->callno;
10388 }
10389 }
10390 if (call_to_destroy) {
10391 if (iaxdebug)
10392 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10393 ast_mutex_lock(&iaxsl[call_to_destroy]);
10394 iax2_destroy(call_to_destroy);
10395 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10396 }
10397 }
10398
10399 if (iaxs[fr->callno])
10400 iaxs[fr->callno]->rseqno = fr->iseqno;
10401 else {
10402
10403 ast_variables_destroy(ies.vars);
10404 ast_mutex_unlock(&iaxsl[fr->callno]);
10405 return 1;
10406 }
10407 } else {
10408 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10409 }
10410 }
10411 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10412 ((f.frametype != AST_FRAME_IAX) ||
10413 ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10414 (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10415
10416 ast_variables_destroy(ies.vars);
10417 ast_mutex_unlock(&iaxsl[fr->callno]);
10418 return 1;
10419 }
10420
10421
10422
10423
10424 if ((f.frametype == AST_FRAME_VOICE) ||
10425 (f.frametype == AST_FRAME_VIDEO) ||
10426 (f.frametype == AST_FRAME_IAX)) {
10427 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10428 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10429 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
10430 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
10431 ast_variables_destroy(ies.vars);
10432 ast_mutex_unlock(&iaxsl[fr->callno]);
10433 return 1;
10434 }
10435 }
10436
10437 if (ies.vars) {
10438 struct ast_datastore *variablestore = NULL;
10439 struct ast_variable *var, *prev = NULL;
10440 AST_LIST_HEAD(, ast_var_t) *varlist;
10441
10442 iax2_lock_owner(fr->callno);
10443 if (!iaxs[fr->callno]) {
10444 ast_variables_destroy(ies.vars);
10445 ast_mutex_unlock(&iaxsl[fr->callno]);
10446 return 1;
10447 }
10448 if ((c = iaxs[fr->callno]->owner)) {
10449 varlist = ast_calloc(1, sizeof(*varlist));
10450 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10451
10452 if (variablestore && varlist) {
10453 variablestore->data = varlist;
10454 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10455 AST_LIST_HEAD_INIT(varlist);
10456 ast_debug(1, "I can haz IAX vars?\n");
10457 for (var = ies.vars; var; var = var->next) {
10458 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10459 if (prev) {
10460 ast_free(prev);
10461 }
10462 prev = var;
10463 if (!newvar) {
10464
10465 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10466 } else {
10467 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10468 }
10469 }
10470 if (prev) {
10471 ast_free(prev);
10472 }
10473 ies.vars = NULL;
10474 ast_channel_datastore_add(c, variablestore);
10475 } else {
10476 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10477 if (variablestore) {
10478 ast_datastore_free(variablestore);
10479 }
10480 if (varlist) {
10481 ast_free(varlist);
10482 }
10483 }
10484 ast_channel_unlock(c);
10485 } else {
10486
10487
10488 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10489 for (var = ies.vars; var && var->next; var = var->next);
10490 if (var) {
10491 var->next = iaxs[fr->callno]->iaxvars;
10492 iaxs[fr->callno]->iaxvars = ies.vars;
10493 ies.vars = NULL;
10494 }
10495 }
10496 }
10497
10498 if (ies.vars) {
10499 ast_debug(1, "I have IAX variables, but they were not processed\n");
10500 }
10501 }
10502
10503
10504
10505 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10506 send_signaling(iaxs[fr->callno]);
10507 }
10508
10509 if (f.frametype == AST_FRAME_VOICE) {
10510 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10511 iaxs[fr->callno]->voiceformat = f.subclass.codec;
10512 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10513 if (iaxs[fr->callno]->owner) {
10514 iax2_lock_owner(fr->callno);
10515 if (iaxs[fr->callno]) {
10516 if (iaxs[fr->callno]->owner) {
10517 format_t orignative;
10518
10519 orignative = iaxs[fr->callno]->owner->nativeformats;
10520 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10521 if (iaxs[fr->callno]->owner->readformat)
10522 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10523 iaxs[fr->callno]->owner->nativeformats = orignative;
10524 ast_channel_unlock(iaxs[fr->callno]->owner);
10525 }
10526 } else {
10527 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10528
10529 if (ies.vars) {
10530 ast_variables_destroy(ies.vars);
10531 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10532 ies.vars = NULL;
10533 }
10534 ast_mutex_unlock(&iaxsl[fr->callno]);
10535 return 1;
10536 }
10537 }
10538 }
10539 }
10540 if (f.frametype == AST_FRAME_VIDEO) {
10541 if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10542 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10543 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10544 }
10545 }
10546 if (f.frametype == AST_FRAME_IAX) {
10547 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10548
10549 if (iaxdebug)
10550 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10551
10552
10553 if (iaxs[fr->callno]->last < fr->ts &&
10554 f.subclass.integer != IAX_COMMAND_ACK &&
10555 f.subclass.integer != IAX_COMMAND_PONG &&
10556 f.subclass.integer != IAX_COMMAND_LAGRP) {
10557 iaxs[fr->callno]->last = fr->ts;
10558 if (iaxdebug)
10559 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10560 }
10561 iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10562 if (!iaxs[fr->callno]->first_iax_message) {
10563 iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10564 }
10565 switch(f.subclass.integer) {
10566 case IAX_COMMAND_ACK:
10567
10568 break;
10569 case IAX_COMMAND_QUELCH:
10570 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10571
10572 if (iaxs[fr->callno]->owner) {
10573 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10574 "Status: On\r\n"
10575 "Channel: %s\r\n"
10576 "Uniqueid: %s\r\n",
10577 iaxs[fr->callno]->owner->name,
10578 iaxs[fr->callno]->owner->uniqueid);
10579 }
10580
10581 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10582 if (ies.musiconhold) {
10583 iax2_lock_owner(fr->callno);
10584 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10585 break;
10586 }
10587 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10588 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10589
10590
10591
10592
10593
10594 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10595 S_OR(moh_suggest, NULL),
10596 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10597 }
10598 ast_channel_unlock(iaxs[fr->callno]->owner);
10599 }
10600 }
10601 break;
10602 case IAX_COMMAND_UNQUELCH:
10603 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10604 iax2_lock_owner(fr->callno);
10605 if (!iaxs[fr->callno]) {
10606 break;
10607 }
10608
10609 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10610 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10611 "Status: Off\r\n"
10612 "Channel: %s\r\n"
10613 "Uniqueid: %s\r\n",
10614 iaxs[fr->callno]->owner->name,
10615 iaxs[fr->callno]->owner->uniqueid);
10616 }
10617
10618 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10619 if (!iaxs[fr->callno]->owner) {
10620 break;
10621 }
10622 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10623
10624
10625
10626
10627 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10628 }
10629 ast_channel_unlock(iaxs[fr->callno]->owner);
10630 }
10631 break;
10632 case IAX_COMMAND_TXACC:
10633 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10634
10635 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10636
10637 if (cur->transfer) {
10638 cur->retries = -1;
10639 }
10640 }
10641 memset(&ied1, 0, sizeof(ied1));
10642 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10643 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10644 iaxs[fr->callno]->transferring = TRANSFER_READY;
10645 }
10646 break;
10647 case IAX_COMMAND_NEW:
10648
10649 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10650 break;
10651 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10652 ast_mutex_unlock(&iaxsl[fr->callno]);
10653 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10654 ast_mutex_lock(&iaxsl[fr->callno]);
10655 if (!iaxs[fr->callno]) {
10656 break;
10657 }
10658 }
10659
10660 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10661 int new_callno;
10662 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10663 fr->callno = new_callno;
10664 }
10665
10666 if (delayreject)
10667 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10668 if (check_access(fr->callno, &sin, &ies)) {
10669
10670 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10671 if (authdebug)
10672 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);
10673 break;
10674 }
10675 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10676 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10677 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10678 break;
10679 }
10680 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10681 const char *context, *exten, *cid_num;
10682
10683 context = ast_strdupa(iaxs[fr->callno]->context);
10684 exten = ast_strdupa(iaxs[fr->callno]->exten);
10685 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10686
10687
10688 ast_mutex_unlock(&iaxsl[fr->callno]);
10689 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10690 ast_mutex_lock(&iaxsl[fr->callno]);
10691
10692 if (!iaxs[fr->callno]) {
10693 break;
10694 }
10695 } else
10696 exists = 0;
10697
10698 save_osptoken(fr, &ies);
10699 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10700 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10701 memset(&ied0, 0, sizeof(ied0));
10702 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10703 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10704 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10705 if (!iaxs[fr->callno]) {
10706 break;
10707 }
10708 if (authdebug)
10709 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);
10710 } else {
10711
10712
10713 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10714 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10715 using_prefs = "reqonly";
10716 } else {
10717 using_prefs = "disabled";
10718 }
10719 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10720 memset(&pref, 0, sizeof(pref));
10721 strcpy(caller_pref_buf, "disabled");
10722 strcpy(host_pref_buf, "disabled");
10723 } else {
10724 using_prefs = "mine";
10725
10726 if (ies.codec_prefs)
10727 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10728 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10729
10730 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10731 pref = iaxs[fr->callno]->rprefs;
10732 using_prefs = "caller";
10733 } else {
10734 pref = iaxs[fr->callno]->prefs;
10735 }
10736 } else
10737 pref = iaxs[fr->callno]->prefs;
10738
10739 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10740 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10741 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10742 }
10743 if (!format) {
10744 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10745 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10746 if (!format) {
10747 memset(&ied0, 0, sizeof(ied0));
10748 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10749 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10750 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10751 if (!iaxs[fr->callno]) {
10752 break;
10753 }
10754 if (authdebug) {
10755 char tmp[256], tmp2[256], tmp3[256];
10756 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10757 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10758 ast_inet_ntoa(sin.sin_addr),
10759 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10760 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10761 } else {
10762 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10763 ast_inet_ntoa(sin.sin_addr),
10764 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10765 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10766 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10767 }
10768 }
10769 } else {
10770
10771 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10772 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10773 format = 0;
10774 } else {
10775 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10776 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10777 memset(&pref, 0, sizeof(pref));
10778 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10779 strcpy(caller_pref_buf,"disabled");
10780 strcpy(host_pref_buf,"disabled");
10781 } else {
10782 using_prefs = "mine";
10783 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10784
10785 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10786 pref = iaxs[fr->callno]->prefs;
10787 } else {
10788 pref = iaxs[fr->callno]->rprefs;
10789 using_prefs = "caller";
10790 }
10791 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10792 } else
10793 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10794 }
10795 }
10796
10797 if (!format) {
10798 char tmp[256], tmp2[256], tmp3[256];
10799 memset(&ied0, 0, sizeof(ied0));
10800 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10801 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10802 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10803 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10804 if (!iaxs[fr->callno]) {
10805 break;
10806 }
10807 if (authdebug) {
10808 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10809 ast_inet_ntoa(sin.sin_addr),
10810 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10811 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10812 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10813 }
10814 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10815 break;
10816 }
10817 }
10818 }
10819 if (format) {
10820
10821 memset(&ied1, 0, sizeof(ied1));
10822 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10823 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10824 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10825 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10826 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10827 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10828 "%srequested format = %s,\n"
10829 "%srequested prefs = %s,\n"
10830 "%sactual format = %s,\n"
10831 "%shost prefs = %s,\n"
10832 "%spriority = %s\n",
10833 ast_inet_ntoa(sin.sin_addr),
10834 VERBOSE_PREFIX_4,
10835 ast_getformatname(iaxs[fr->callno]->peerformat),
10836 VERBOSE_PREFIX_4,
10837 caller_pref_buf,
10838 VERBOSE_PREFIX_4,
10839 ast_getformatname(format),
10840 VERBOSE_PREFIX_4,
10841 host_pref_buf,
10842 VERBOSE_PREFIX_4,
10843 using_prefs);
10844
10845 iaxs[fr->callno]->chosenformat = format;
10846 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10847 } else {
10848 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10849
10850 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10851 }
10852 }
10853 }
10854 break;
10855 }
10856 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10857 merge_encryption(iaxs[fr->callno],ies.encmethods);
10858 else
10859 iaxs[fr->callno]->encmethods = 0;
10860 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10861 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10862 break;
10863 case IAX_COMMAND_DPREQ:
10864
10865 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10866 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10867 if (iaxcompat) {
10868
10869 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10870 } else {
10871
10872 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10873 }
10874 }
10875 break;
10876 case IAX_COMMAND_HANGUP:
10877 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10878 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10879
10880 if (iaxs[fr->callno]->owner) {
10881 set_hangup_source_and_cause(fr->callno, ies.causecode);
10882 if (!iaxs[fr->callno]) {
10883 break;
10884 }
10885 }
10886
10887
10888 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10889 iax2_destroy(fr->callno);
10890 break;
10891 case IAX_COMMAND_REJECT:
10892
10893 if (iaxs[fr->callno]->owner) {
10894 set_hangup_source_and_cause(fr->callno, ies.causecode);
10895 if (!iaxs[fr->callno]) {
10896 break;
10897 }
10898 }
10899
10900 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10901 if (iaxs[fr->callno]->owner && authdebug)
10902 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10903 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10904 ies.cause ? ies.cause : "<Unknown>");
10905 ast_debug(1, "Immediately destroying %d, having received reject\n",
10906 fr->callno);
10907 }
10908
10909 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10910 fr->ts, NULL, 0, fr->iseqno);
10911 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10912 iaxs[fr->callno]->error = EPERM;
10913 iax2_destroy(fr->callno);
10914 break;
10915 case IAX_COMMAND_TRANSFER:
10916 {
10917 struct ast_channel *bridged_chan;
10918 struct ast_channel *owner;
10919
10920 iax2_lock_owner(fr->callno);
10921 if (!iaxs[fr->callno]) {
10922
10923 break;
10924 }
10925 owner = iaxs[fr->callno]->owner;
10926 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10927 if (bridged_chan && ies.called_number) {
10928 const char *context;
10929
10930 context = ast_strdupa(iaxs[fr->callno]->context);
10931
10932 ast_channel_ref(owner);
10933 ast_channel_ref(bridged_chan);
10934 ast_channel_unlock(owner);
10935 ast_mutex_unlock(&iaxsl[fr->callno]);
10936
10937
10938 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10939 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10940
10941
10942 if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10943 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10944 if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10945 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10946 bridged_chan->name);
10947 }
10948 } else {
10949 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10950 ast_log(LOG_WARNING,
10951 "Async goto of '%s' to '%s@%s' failed\n",
10952 bridged_chan->name, ies.called_number, context);
10953 } else {
10954 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10955 bridged_chan->name, ies.called_number, context);
10956 }
10957 }
10958 ast_channel_unref(owner);
10959 ast_channel_unref(bridged_chan);
10960
10961 ast_mutex_lock(&iaxsl[fr->callno]);
10962 } else {
10963 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10964 if (owner) {
10965 ast_channel_unlock(owner);
10966 }
10967 }
10968
10969 break;
10970 }
10971 case IAX_COMMAND_ACCEPT:
10972
10973 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10974 break;
10975 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10976
10977 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10978 iax2_destroy(fr->callno);
10979 break;
10980 }
10981 if (ies.format) {
10982 iaxs[fr->callno]->peerformat = ies.format;
10983 } else {
10984 if (iaxs[fr->callno]->owner)
10985 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10986 else
10987 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10988 }
10989 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));
10990 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10991 memset(&ied0, 0, sizeof(ied0));
10992 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10993 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10994 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10995 if (!iaxs[fr->callno]) {
10996 break;
10997 }
10998 if (authdebug) {
10999 char tmp1[256], tmp2[256];
11000 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
11001 ast_inet_ntoa(sin.sin_addr),
11002 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11003 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11004 }
11005 } else {
11006 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11007 iax2_lock_owner(fr->callno);
11008 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11009
11010 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
11011 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
11012
11013
11014 if (iaxs[fr->callno]->owner->writeformat)
11015 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
11016 if (iaxs[fr->callno]->owner->readformat)
11017 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
11018 ast_channel_unlock(iaxs[fr->callno]->owner);
11019 }
11020 }
11021 if (iaxs[fr->callno]) {
11022 AST_LIST_LOCK(&dpcache);
11023 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
11024 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
11025 iax2_dprequest(dp, fr->callno);
11026 AST_LIST_UNLOCK(&dpcache);
11027 }
11028 break;
11029 case IAX_COMMAND_POKE:
11030
11031 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
11032 break;
11033 case IAX_COMMAND_PING:
11034 {
11035 struct iax_ie_data pingied;
11036 construct_rr(iaxs[fr->callno], &pingied);
11037
11038 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
11039 }
11040 break;
11041 case IAX_COMMAND_PONG:
11042
11043 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
11044
11045 save_rr(fr, &ies);
11046
11047
11048 log_jitterstats(fr->callno);
11049
11050 if (iaxs[fr->callno]->peerpoke) {
11051 peer = iaxs[fr->callno]->peerpoke;
11052 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
11053 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
11054 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
11055 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);
11056 ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
11057 }
11058 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
11059 if (iaxs[fr->callno]->pingtime > peer->maxms) {
11060 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
11061 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);
11062 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
11063 }
11064 }
11065 peer->lastms = iaxs[fr->callno]->pingtime;
11066 if (peer->smoothing && (peer->lastms > -1))
11067 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
11068 else if (peer->smoothing && peer->lastms < 0)
11069 peer->historicms = (0 + peer->historicms) / 2;
11070 else
11071 peer->historicms = iaxs[fr->callno]->pingtime;
11072
11073
11074 if (peer->pokeexpire > -1) {
11075 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
11076 peer_unref(peer);
11077 peer->pokeexpire = -1;
11078 }
11079 }
11080
11081 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
11082 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11083 else
11084 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
11085 if (peer->pokeexpire == -1)
11086 peer_unref(peer);
11087
11088 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11089
11090 iax2_destroy(fr->callno);
11091 peer->callno = 0;
11092 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
11093 }
11094 break;
11095 case IAX_COMMAND_LAGRQ:
11096 case IAX_COMMAND_LAGRP:
11097 f.src = "LAGRQ";
11098 f.mallocd = 0;
11099 f.offset = 0;
11100 f.samples = 0;
11101 iax_frame_wrap(fr, &f);
11102 if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
11103
11104 fr->af.subclass.integer = IAX_COMMAND_LAGRP;
11105 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
11106 } else {
11107
11108 unsigned int ts;
11109
11110 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
11111 iaxs[fr->callno]->lag = ts - fr->ts;
11112 if (iaxdebug)
11113 ast_debug(1, "Peer %s lag measured as %dms\n",
11114 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
11115 }
11116 break;
11117 case IAX_COMMAND_AUTHREQ:
11118 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11119 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>");
11120 break;
11121 }
11122 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
11123 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11124 .subclass.integer = AST_CONTROL_HANGUP,
11125 };
11126 ast_log(LOG_WARNING,
11127 "I don't know how to authenticate %s to %s\n",
11128 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
11129 iax2_queue_frame(fr->callno, &hangup_fr);
11130 }
11131 break;
11132 case IAX_COMMAND_AUTHREP:
11133
11134 if (delayreject)
11135 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11136
11137 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11138 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>");
11139 break;
11140 }
11141 if (authenticate_verify(iaxs[fr->callno], &ies)) {
11142 if (authdebug)
11143 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);
11144 memset(&ied0, 0, sizeof(ied0));
11145 auth_fail(fr->callno, IAX_COMMAND_REJECT);
11146 break;
11147 }
11148 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11149
11150 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
11151 } else
11152 exists = 0;
11153 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11154 if (authdebug)
11155 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);
11156 memset(&ied0, 0, sizeof(ied0));
11157 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11158 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11159 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11160 if (!iaxs[fr->callno]) {
11161 break;
11162 }
11163 } else {
11164
11165 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11166 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11167 using_prefs = "reqonly";
11168 } else {
11169 using_prefs = "disabled";
11170 }
11171 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11172 memset(&pref, 0, sizeof(pref));
11173 strcpy(caller_pref_buf, "disabled");
11174 strcpy(host_pref_buf, "disabled");
11175 } else {
11176 using_prefs = "mine";
11177 if (ies.codec_prefs)
11178 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11179 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11180 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11181 pref = iaxs[fr->callno]->rprefs;
11182 using_prefs = "caller";
11183 } else {
11184 pref = iaxs[fr->callno]->prefs;
11185 }
11186 } else
11187 pref = iaxs[fr->callno]->prefs;
11188 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11189 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11190 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11191 }
11192 if (!format) {
11193 char tmp1[256], tmp2[256], tmp3[256];
11194 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11195 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11196 ast_getformatname(iaxs[fr->callno]->peerformat),
11197 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11198 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11199 }
11200 if (!format) {
11201 if (authdebug) {
11202 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11203 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11204 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11205 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11206 } else {
11207 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11208 ast_inet_ntoa(sin.sin_addr),
11209 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11210 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11211 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11212 }
11213 }
11214 memset(&ied0, 0, sizeof(ied0));
11215 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11216 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11217 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11218 if (!iaxs[fr->callno]) {
11219 break;
11220 }
11221 } else {
11222
11223 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11224 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11225 format = 0;
11226 } else {
11227 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11228 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11229 memset(&pref, 0, sizeof(pref));
11230 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11231 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11232 strcpy(caller_pref_buf,"disabled");
11233 strcpy(host_pref_buf,"disabled");
11234 } else {
11235 using_prefs = "mine";
11236 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11237
11238 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11239 pref = iaxs[fr->callno]->prefs;
11240 } else {
11241 pref = iaxs[fr->callno]->rprefs;
11242 using_prefs = "caller";
11243 }
11244 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11245 } else
11246 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11247 }
11248 }
11249 if (!format) {
11250 char tmp1[256], tmp2[256], tmp3[256];
11251 ast_log(LOG_ERROR, "No best format in %s???\n",
11252 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11253 if (authdebug) {
11254 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11255 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11256 ast_inet_ntoa(sin.sin_addr),
11257 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11258 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11259 } else {
11260 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11261 ast_inet_ntoa(sin.sin_addr),
11262 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11263 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11264 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11265 }
11266 }
11267 memset(&ied0, 0, sizeof(ied0));
11268 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11269 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11270 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11271 if (!iaxs[fr->callno]) {
11272 break;
11273 }
11274 }
11275 }
11276 }
11277 if (format) {
11278
11279 memset(&ied1, 0, sizeof(ied1));
11280 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11281 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11282 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11283 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11284 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11285 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11286 "%srequested format = %s,\n"
11287 "%srequested prefs = %s,\n"
11288 "%sactual format = %s,\n"
11289 "%shost prefs = %s,\n"
11290 "%spriority = %s\n",
11291 ast_inet_ntoa(sin.sin_addr),
11292 VERBOSE_PREFIX_4,
11293 ast_getformatname(iaxs[fr->callno]->peerformat),
11294 VERBOSE_PREFIX_4,
11295 caller_pref_buf,
11296 VERBOSE_PREFIX_4,
11297 ast_getformatname(format),
11298 VERBOSE_PREFIX_4,
11299 host_pref_buf,
11300 VERBOSE_PREFIX_4,
11301 using_prefs);
11302
11303 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11304 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
11305 iax2_destroy(fr->callno);
11306 else if (ies.vars) {
11307 struct ast_datastore *variablestore;
11308 struct ast_variable *var, *prev = NULL;
11309 AST_LIST_HEAD(, ast_var_t) *varlist;
11310 varlist = ast_calloc(1, sizeof(*varlist));
11311 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11312 if (variablestore && varlist) {
11313 variablestore->data = varlist;
11314 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11315 AST_LIST_HEAD_INIT(varlist);
11316 ast_debug(1, "I can haz IAX vars? w00t\n");
11317 for (var = ies.vars; var; var = var->next) {
11318 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11319 if (prev)
11320 ast_free(prev);
11321 prev = var;
11322 if (!newvar) {
11323
11324 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11325 } else {
11326 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11327 }
11328 }
11329 if (prev)
11330 ast_free(prev);
11331 ies.vars = NULL;
11332 ast_channel_datastore_add(c, variablestore);
11333 } else {
11334 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11335 if (variablestore)
11336 ast_datastore_free(variablestore);
11337 if (varlist)
11338 ast_free(varlist);
11339 }
11340 }
11341 } else {
11342 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11343
11344 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11345 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11346 goto immediatedial;
11347 }
11348 }
11349 }
11350 }
11351 break;
11352 case IAX_COMMAND_DIAL:
11353 immediatedial:
11354 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11355 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11356 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11357 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11358 if (authdebug)
11359 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);
11360 memset(&ied0, 0, sizeof(ied0));
11361 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11362 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11363 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11364 if (!iaxs[fr->callno]) {
11365 break;
11366 }
11367 } else {
11368 char tmp[256];
11369 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11370 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11371 ast_inet_ntoa(sin.sin_addr),
11372 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11373 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11374 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11375 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
11376 iax2_destroy(fr->callno);
11377 else if (ies.vars) {
11378 struct ast_datastore *variablestore;
11379 struct ast_variable *var, *prev = NULL;
11380 AST_LIST_HEAD(, ast_var_t) *varlist;
11381 varlist = ast_calloc(1, sizeof(*varlist));
11382 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11383 ast_debug(1, "I can haz IAX vars? w00t\n");
11384 if (variablestore && varlist) {
11385 variablestore->data = varlist;
11386 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11387 AST_LIST_HEAD_INIT(varlist);
11388 for (var = ies.vars; var; var = var->next) {
11389 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11390 if (prev)
11391 ast_free(prev);
11392 prev = var;
11393 if (!newvar) {
11394
11395 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11396 } else {
11397 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11398 }
11399 }
11400 if (prev)
11401 ast_free(prev);
11402 ies.vars = NULL;
11403 ast_channel_datastore_add(c, variablestore);
11404 } else {
11405 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11406 if (variablestore)
11407 ast_datastore_free(variablestore);
11408 if (varlist)
11409 ast_free(varlist);
11410 }
11411 }
11412 }
11413 }
11414 break;
11415 case IAX_COMMAND_INVAL:
11416 iaxs[fr->callno]->error = ENOTCONN;
11417 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11418 iax2_destroy(fr->callno);
11419 ast_debug(1, "Destroying call %d\n", fr->callno);
11420 break;
11421 case IAX_COMMAND_VNAK:
11422 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11423
11424 vnak_retransmit(fr->callno, fr->iseqno);
11425 break;
11426 case IAX_COMMAND_REGREQ:
11427 case IAX_COMMAND_REGREL:
11428
11429 if (delayreject)
11430 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11431 if (register_verify(fr->callno, &sin, &ies)) {
11432 if (!iaxs[fr->callno]) {
11433 break;
11434 }
11435
11436 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11437 break;
11438 }
11439 if (!iaxs[fr->callno]) {
11440 break;
11441 }
11442 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11443 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11444
11445 if (f.subclass.integer == IAX_COMMAND_REGREL) {
11446 memset(&sin, 0, sizeof(sin));
11447 sin.sin_family = AF_INET;
11448 }
11449 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11450 ast_log(LOG_WARNING, "Registry error\n");
11451 }
11452 if (!iaxs[fr->callno]) {
11453 break;
11454 }
11455 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11456 ast_mutex_unlock(&iaxsl[fr->callno]);
11457 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11458 ast_mutex_lock(&iaxsl[fr->callno]);
11459 }
11460 break;
11461 }
11462 registry_authrequest(fr->callno);
11463 break;
11464 case IAX_COMMAND_REGACK:
11465 if (iax2_ack_registry(&ies, &sin, fr->callno))
11466 ast_log(LOG_WARNING, "Registration failure\n");
11467
11468 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11469 iax2_destroy(fr->callno);
11470 break;
11471 case IAX_COMMAND_REGREJ:
11472 if (iaxs[fr->callno]->reg) {
11473 if (authdebug) {
11474 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));
11475 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>");
11476 }
11477 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11478 }
11479
11480 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11481 iax2_destroy(fr->callno);
11482 break;
11483 case IAX_COMMAND_REGAUTH:
11484
11485 if (registry_rerequest(&ies, fr->callno, &sin)) {
11486 memset(&ied0, 0, sizeof(ied0));
11487 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11488 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11489 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11490 }
11491 break;
11492 case IAX_COMMAND_TXREJ:
11493 while (iaxs[fr->callno]
11494 && iaxs[fr->callno]->bridgecallno
11495 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
11496 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
11497 }
11498 if (!iaxs[fr->callno]) {
11499 break;
11500 }
11501
11502 iaxs[fr->callno]->transferring = TRANSFER_NONE;
11503 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11504 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11505
11506 if (!iaxs[fr->callno]->bridgecallno) {
11507 break;
11508 }
11509
11510 if (iaxs[iaxs[fr->callno]->bridgecallno]
11511 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11512 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE;
11513 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11514 }
11515 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11516 break;
11517 case IAX_COMMAND_TXREADY:
11518 while (iaxs[fr->callno]
11519 && iaxs[fr->callno]->bridgecallno
11520 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
11521 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
11522 }
11523 if (!iaxs[fr->callno]) {
11524 break;
11525 }
11526
11527 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
11528 iaxs[fr->callno]->transferring = TRANSFER_READY;
11529 } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) {
11530 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11531 } else {
11532 if (iaxs[fr->callno]->bridgecallno) {
11533 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11534 }
11535 break;
11536 }
11537 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11538
11539 if (!iaxs[fr->callno]->bridgecallno) {
11540 break;
11541 }
11542
11543 if (!iaxs[iaxs[fr->callno]->bridgecallno]
11544 || (iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_READY
11545 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_MREADY)) {
11546 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11547 break;
11548 }
11549
11550
11551
11552
11553
11554 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11555 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11556 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11557
11558 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11559 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11560
11561 memset(&ied0, 0, sizeof(ied0));
11562 memset(&ied1, 0, sizeof(ied1));
11563 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11564 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11565 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11566 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11567 } else {
11568 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11569 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11570
11571 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11572 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11573 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11574 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11575
11576
11577 stop_stuff(fr->callno);
11578 stop_stuff(iaxs[fr->callno]->bridgecallno);
11579
11580 memset(&ied0, 0, sizeof(ied0));
11581 memset(&ied1, 0, sizeof(ied1));
11582 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11583 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11584 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11585 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11586 }
11587 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11588 break;
11589 case IAX_COMMAND_TXREQ:
11590 try_transfer(iaxs[fr->callno], &ies);
11591 break;
11592 case IAX_COMMAND_TXCNT:
11593 if (iaxs[fr->callno]->transferring)
11594 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11595 break;
11596 case IAX_COMMAND_TXREL:
11597
11598 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11599 complete_transfer(fr->callno, &ies);
11600 stop_stuff(fr->callno);
11601 break;
11602 case IAX_COMMAND_TXMEDIA:
11603 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11604 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11605
11606 if (cur->transfer) {
11607 cur->retries = -1;
11608 }
11609 }
11610
11611 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11612 }
11613 break;
11614 case IAX_COMMAND_RTKEY:
11615 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11616 ast_log(LOG_WARNING,
11617 "we've been told to rotate our encryption key, "
11618 "but this isn't an encrypted call. bad things will happen.\n"
11619 );
11620 break;
11621 }
11622
11623 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11624
11625 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11626 break;
11627 case IAX_COMMAND_DPREP:
11628 complete_dpreply(iaxs[fr->callno], &ies);
11629 break;
11630 case IAX_COMMAND_UNSUPPORT:
11631 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11632 break;
11633 case IAX_COMMAND_FWDOWNL:
11634
11635 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11636 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11637 break;
11638 }
11639 memset(&ied0, 0, sizeof(ied0));
11640 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11641 if (res < 0)
11642 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11643 else if (res > 0)
11644 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11645 else
11646 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11647 break;
11648 case IAX_COMMAND_CALLTOKEN:
11649 {
11650 struct iax_frame *cur;
11651
11652 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11653 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11654 }
11655 break;
11656 }
11657 default:
11658 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11659 memset(&ied0, 0, sizeof(ied0));
11660 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11661 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11662 }
11663
11664 if (ies.vars) {
11665 ast_variables_destroy(ies.vars);
11666 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11667 ies.vars = NULL;
11668 }
11669
11670
11671 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11672 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11673 (f.subclass.integer != IAX_COMMAND_TXACC) &&
11674 (f.subclass.integer != IAX_COMMAND_INVAL) &&
11675 (f.subclass.integer != IAX_COMMAND_VNAK)) {
11676 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) {
11677 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11678 }
11679 }
11680 ast_mutex_unlock(&iaxsl[fr->callno]);
11681 return 1;
11682 }
11683
11684 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11685 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11686 } else if (minivid) {
11687 f.frametype = AST_FRAME_VIDEO;
11688 if (iaxs[fr->callno]->videoformat > 0)
11689 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11690 else {
11691 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11692 iax2_vnak(fr->callno);
11693 ast_variables_destroy(ies.vars);
11694 ast_mutex_unlock(&iaxsl[fr->callno]);
11695 return 1;
11696 }
11697 f.datalen = res - sizeof(*vh);
11698 if (f.datalen)
11699 f.data.ptr = thread->buf + sizeof(*vh);
11700 else
11701 f.data.ptr = NULL;
11702 #ifdef IAXTESTS
11703 if (test_resync) {
11704 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11705 } else
11706 #endif
11707 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11708 } else {
11709
11710 f.frametype = AST_FRAME_VOICE;
11711 if (iaxs[fr->callno]->voiceformat > 0)
11712 f.subclass.codec = iaxs[fr->callno]->voiceformat;
11713 else {
11714 ast_debug(1, "Received mini frame before first full voice frame\n");
11715 iax2_vnak(fr->callno);
11716 ast_variables_destroy(ies.vars);
11717 ast_mutex_unlock(&iaxsl[fr->callno]);
11718 return 1;
11719 }
11720 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11721 if (f.datalen < 0) {
11722 ast_log(LOG_WARNING, "Datalen < 0?\n");
11723 ast_variables_destroy(ies.vars);
11724 ast_mutex_unlock(&iaxsl[fr->callno]);
11725 return 1;
11726 }
11727 if (f.datalen)
11728 f.data.ptr = thread->buf + sizeof(*mh);
11729 else
11730 f.data.ptr = NULL;
11731 #ifdef IAXTESTS
11732 if (test_resync) {
11733 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11734 } else
11735 #endif
11736 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11737
11738 }
11739
11740
11741 if (!iaxs[fr->callno]
11742 || !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11743 ast_variables_destroy(ies.vars);
11744 ast_mutex_unlock(&iaxsl[fr->callno]);
11745 return 1;
11746 }
11747
11748 if (f.frametype == AST_FRAME_CONTROL) {
11749 if (!iax2_is_control_frame_allowed(f.subclass.integer)) {
11750
11751 ast_debug(2, "Callno %u: Blocked receiving control frame %d.\n",
11752 fr->callno, f.subclass.integer);
11753 ast_variables_destroy(ies.vars);
11754 ast_mutex_unlock(&iaxsl[fr->callno]);
11755 return 1;
11756 }
11757 if (f.subclass.integer == AST_CONTROL_CONNECTED_LINE
11758 || f.subclass.integer == AST_CONTROL_REDIRECTING) {
11759 if (iaxs[fr->callno]
11760 && !ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11761
11762 ast_debug(2, "Callno %u: Config blocked receiving control frame %d.\n",
11763 fr->callno, f.subclass.integer);
11764 ast_variables_destroy(ies.vars);
11765 ast_mutex_unlock(&iaxsl[fr->callno]);
11766 return 1;
11767 }
11768 }
11769
11770 iax2_lock_owner(fr->callno);
11771 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11772 if (f.subclass.integer == AST_CONTROL_BUSY) {
11773 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
11774 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
11775 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
11776 }
11777 ast_channel_unlock(iaxs[fr->callno]->owner);
11778 }
11779 }
11780
11781 if (f.frametype == AST_FRAME_CONTROL
11782 && f.subclass.integer == AST_CONTROL_CONNECTED_LINE
11783 && iaxs[fr->callno]) {
11784 struct ast_party_connected_line connected;
11785
11786
11787
11788
11789
11790
11791 ast_party_connected_line_init(&connected);
11792 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11793 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11794
11795 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11796 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11797 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11798 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11799
11800 iax2_lock_owner(fr->callno);
11801 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11802 ast_set_callerid(iaxs[fr->callno]->owner,
11803 S_COR(connected.id.number.valid, connected.id.number.str, ""),
11804 S_COR(connected.id.name.valid, connected.id.name.str, ""),
11805 NULL);
11806 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11807 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11808 ast_channel_unlock(iaxs[fr->callno]->owner);
11809 }
11810 }
11811 ast_party_connected_line_free(&connected);
11812 }
11813
11814
11815 f.src = "IAX2";
11816 f.mallocd = 0;
11817 f.offset = 0;
11818 f.len = 0;
11819 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11820 f.samples = ast_codec_get_samples(&f);
11821
11822 if (f.subclass.codec == AST_FORMAT_SLINEAR)
11823 ast_frame_byteswap_be(&f);
11824 } else
11825 f.samples = 0;
11826 iax_frame_wrap(fr, &f);
11827
11828
11829 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11830
11831 fr->outoforder = 0;
11832 } else {
11833 if (iaxdebug && iaxs[fr->callno]) {
11834 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last);
11835 }
11836 fr->outoforder = -1;
11837 }
11838 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11839 if (iaxs[fr->callno]) {
11840 duped_fr = iaxfrdup2(fr);
11841 if (duped_fr) {
11842 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11843 }
11844 }
11845 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11846 iaxs[fr->callno]->last = fr->ts;
11847 #if 1
11848 if (iaxdebug)
11849 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11850 #endif
11851 }
11852
11853
11854 ast_variables_destroy(ies.vars);
11855 ast_mutex_unlock(&iaxsl[fr->callno]);
11856 return 1;
11857 }
11858
11859
11860 static void iax2_process_thread_cleanup(void *data)
11861 {
11862 struct iax2_thread *thread = data;
11863 ast_mutex_destroy(&thread->lock);
11864 ast_cond_destroy(&thread->cond);
11865 ast_mutex_destroy(&thread->init_lock);
11866 ast_cond_destroy(&thread->init_cond);
11867 ast_free(thread);
11868
11869 ast_atomic_dec_and_test(&iaxactivethreadcount);
11870 }
11871
11872 static void *iax2_process_thread(void *data)
11873 {
11874 struct iax2_thread *thread = data;
11875 struct timeval wait;
11876 struct timespec ts;
11877 int put_into_idle = 0;
11878 int first_time = 1;
11879 int old_state;
11880
11881 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11882
11883 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11884 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11885
11886 for (;;) {
11887
11888 ast_mutex_lock(&thread->lock);
11889
11890 if (thread->stop) {
11891 ast_mutex_unlock(&thread->lock);
11892 break;
11893 }
11894
11895
11896 if (first_time) {
11897 signal_condition(&thread->init_lock, &thread->init_cond);
11898 first_time = 0;
11899 }
11900
11901
11902 if (put_into_idle) {
11903 insert_idle_thread(thread);
11904 }
11905
11906 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11907 struct iax2_thread *t = NULL;
11908
11909 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11910 ts.tv_sec = wait.tv_sec;
11911 ts.tv_nsec = wait.tv_usec * 1000;
11912 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11913
11914
11915 if (!put_into_idle || thread->stop) {
11916 ast_mutex_unlock(&thread->lock);
11917 break;
11918 }
11919 AST_LIST_LOCK(&dynamic_list);
11920
11921 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11922 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11923 AST_LIST_UNLOCK(&dynamic_list);
11924 if (t) {
11925
11926
11927
11928 ast_mutex_unlock(&thread->lock);
11929 break;
11930 }
11931
11932
11933
11934 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11935 ts.tv_sec = wait.tv_sec;
11936 ts.tv_nsec = wait.tv_usec * 1000;
11937 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11938 ast_mutex_unlock(&thread->lock);
11939 break;
11940 }
11941 }
11942 } else {
11943 ast_cond_wait(&thread->cond, &thread->lock);
11944 }
11945
11946
11947 put_into_idle = 1;
11948
11949 ast_mutex_unlock(&thread->lock);
11950
11951 if (thread->stop) {
11952 break;
11953 }
11954
11955
11956 switch (thread->iostate) {
11957 case IAX_IOSTATE_IDLE:
11958 continue;
11959 case IAX_IOSTATE_READY:
11960 thread->actions++;
11961 thread->iostate = IAX_IOSTATE_PROCESSING;
11962 socket_process(thread);
11963 handle_deferred_full_frames(thread);
11964 break;
11965 case IAX_IOSTATE_SCHEDREADY:
11966 thread->actions++;
11967 thread->iostate = IAX_IOSTATE_PROCESSING;
11968 #ifdef SCHED_MULTITHREADED
11969 thread->schedfunc(thread->scheddata);
11970 #endif
11971 break;
11972 default:
11973 break;
11974 }
11975
11976
11977
11978
11979 AST_LIST_LOCK(&active_list);
11980 AST_LIST_REMOVE(&active_list, thread, list);
11981 AST_LIST_UNLOCK(&active_list);
11982
11983
11984 handle_deferred_full_frames(thread);
11985
11986 time(&thread->checktime);
11987 thread->iostate = IAX_IOSTATE_IDLE;
11988 #ifdef DEBUG_SCHED_MULTITHREAD
11989 thread->curfunc[0]='\0';
11990 #endif
11991 }
11992
11993
11994
11995
11996
11997
11998 AST_LIST_LOCK(&idle_list);
11999 AST_LIST_REMOVE(&idle_list, thread, list);
12000 AST_LIST_UNLOCK(&idle_list);
12001
12002 AST_LIST_LOCK(&dynamic_list);
12003 AST_LIST_REMOVE(&dynamic_list, thread, list);
12004 AST_LIST_UNLOCK(&dynamic_list);
12005
12006 if (!thread->stop) {
12007
12008 pthread_detach(pthread_self());
12009 }
12010
12011
12012
12013
12014 pthread_cleanup_pop(1);
12015 return NULL;
12016 }
12017
12018 static int iax2_do_register(struct iax2_registry *reg)
12019 {
12020 struct iax_ie_data ied;
12021 if (iaxdebug)
12022 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
12023
12024 if (reg->dnsmgr &&
12025 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) {
12026
12027 ast_dnsmgr_refresh(reg->dnsmgr);
12028 }
12029
12030
12031
12032
12033
12034 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
12035 int callno = reg->callno;
12036 ast_mutex_lock(&iaxsl[callno]);
12037 iax2_destroy(callno);
12038 ast_mutex_unlock(&iaxsl[callno]);
12039 reg->callno = 0;
12040 }
12041 if (!ast_sockaddr_ipv4(®->addr)) {
12042 if (iaxdebug)
12043 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
12044
12045 reg->expire = iax2_sched_replace(reg->expire, sched,
12046 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12047 return -1;
12048 }
12049
12050 if (!reg->callno) {
12051 struct sockaddr_in reg_addr;
12052
12053 ast_debug(3, "Allocate call number\n");
12054
12055 ast_sockaddr_to_sin(®->addr, ®_addr);
12056
12057 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0);
12058 if (reg->callno < 1) {
12059 ast_log(LOG_WARNING, "Unable to create call for registration\n");
12060 return -1;
12061 } else
12062 ast_debug(3, "Registration created on call %d\n", reg->callno);
12063 iaxs[reg->callno]->reg = reg;
12064 ast_mutex_unlock(&iaxsl[reg->callno]);
12065 }
12066
12067 reg->expire = iax2_sched_replace(reg->expire, sched,
12068 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12069
12070 memset(&ied, 0, sizeof(ied));
12071 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
12072 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
12073 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
12074 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
12075 reg->regstate = REG_STATE_REGSENT;
12076 return 0;
12077 }
12078
12079 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
12080 {
12081
12082
12083 struct iax_ie_data provdata;
12084 struct iax_ie_data ied;
12085 unsigned int sig;
12086 struct sockaddr_in sin;
12087 int callno;
12088 struct create_addr_info cai;
12089
12090 memset(&cai, 0, sizeof(cai));
12091
12092 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
12093
12094 if (iax_provision_build(&provdata, &sig, template, force)) {
12095 ast_debug(1, "No provisioning found for template '%s'\n", template);
12096 return 0;
12097 }
12098
12099 if (end) {
12100 memcpy(&sin, end, sizeof(sin));
12101 cai.sockfd = sockfd;
12102 } else if (create_addr(dest, NULL, &sin, &cai))
12103 return -1;
12104
12105
12106 memset(&ied, 0, sizeof(ied));
12107 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
12108
12109 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12110 if (!callno)
12111 return -1;
12112
12113 if (iaxs[callno]) {
12114
12115 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
12116 sched, 15000, auto_hangup, (void *)(long)callno);
12117 ast_set_flag64(iaxs[callno], IAX_PROVISION);
12118
12119 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
12120 }
12121 ast_mutex_unlock(&iaxsl[callno]);
12122
12123 return 1;
12124 }
12125
12126 static char *papp = "IAX2Provision";
12127
12128
12129
12130
12131 static int iax2_prov_app(struct ast_channel *chan, const char *data)
12132 {
12133 int res;
12134 char *sdata;
12135 char *opts;
12136 int force =0;
12137 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
12138 if (ast_strlen_zero(data))
12139 data = "default";
12140 sdata = ast_strdupa(data);
12141 opts = strchr(sdata, '|');
12142 if (opts)
12143 *opts='\0';
12144
12145 if (chan->tech != &iax2_tech) {
12146 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
12147 return -1;
12148 }
12149 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
12150 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
12151 return -1;
12152 }
12153 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
12154 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
12155 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
12156 sdata, res);
12157 return res;
12158 }
12159
12160 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
12161 {
12162 int force = 0;
12163 int res;
12164
12165 switch (cmd) {
12166 case CLI_INIT:
12167 e->command = "iax2 provision";
12168 e->usage =
12169 "Usage: iax2 provision <host> <template> [forced]\n"
12170 " Provisions the given peer or IP address using a template\n"
12171 " matching either 'template' or '*' if the template is not\n"
12172 " found. If 'forced' is specified, even empty provisioning\n"
12173 " fields will be provisioned as empty fields.\n";
12174 return NULL;
12175 case CLI_GENERATE:
12176 if (a->pos == 3)
12177 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
12178 return NULL;
12179 }
12180
12181 if (a->argc < 4)
12182 return CLI_SHOWUSAGE;
12183 if (a->argc > 4) {
12184 if (!strcasecmp(a->argv[4], "forced"))
12185 force = 1;
12186 else
12187 return CLI_SHOWUSAGE;
12188 }
12189 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
12190 if (res < 0)
12191 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
12192 else if (res < 1)
12193 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
12194 else
12195 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
12196 return CLI_SUCCESS;
12197 }
12198
12199 static void __iax2_poke_noanswer(const void *data)
12200 {
12201 struct iax2_peer *peer = (struct iax2_peer *)data;
12202 int callno;
12203
12204 if (peer->lastms > -1) {
12205 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12206 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
12207 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
12208 }
12209 if ((callno = peer->callno) > 0) {
12210 ast_mutex_lock(&iaxsl[callno]);
12211 iax2_destroy(callno);
12212 ast_mutex_unlock(&iaxsl[callno]);
12213 }
12214 peer->callno = 0;
12215 peer->lastms = -1;
12216
12217 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
12218 if (peer->pokeexpire == -1)
12219 peer_unref(peer);
12220 }
12221
12222 static int iax2_poke_noanswer(const void *data)
12223 {
12224 struct iax2_peer *peer = (struct iax2_peer *)data;
12225 peer->pokeexpire = -1;
12226 #ifdef SCHED_MULTITHREADED
12227 if (schedule_action(__iax2_poke_noanswer, data))
12228 #endif
12229 __iax2_poke_noanswer(data);
12230 peer_unref(peer);
12231 return 0;
12232 }
12233
12234 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
12235 {
12236 struct iax2_peer *peer = obj;
12237
12238 iax2_poke_peer(peer, 0);
12239
12240 return 0;
12241 }
12242
12243 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
12244 {
12245 int callno;
12246 struct sockaddr_in peer_addr;
12247
12248 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
12249
12250
12251 peer->lastms = 0;
12252 peer->historicms = 0;
12253 peer->pokeexpire = -1;
12254 peer->callno = 0;
12255 return 0;
12256 }
12257
12258 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
12259
12260
12261 if ((callno = peer->callno) > 0) {
12262 ast_log(LOG_NOTICE, "Still have a callno...\n");
12263 ast_mutex_lock(&iaxsl[callno]);
12264 iax2_destroy(callno);
12265 ast_mutex_unlock(&iaxsl[callno]);
12266 }
12267 if (heldcall)
12268 ast_mutex_unlock(&iaxsl[heldcall]);
12269 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12270 if (heldcall)
12271 ast_mutex_lock(&iaxsl[heldcall]);
12272 if (peer->callno < 1) {
12273 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12274 return -1;
12275 }
12276
12277
12278 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12279 iaxs[peer->callno]->peerpoke = peer;
12280
12281 if (peer->pokeexpire > -1) {
12282 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
12283 peer->pokeexpire = -1;
12284 peer_unref(peer);
12285 }
12286 }
12287
12288
12289
12290 if (peer->lastms < 0)
12291 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12292 else
12293 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12294
12295 if (peer->pokeexpire == -1)
12296 peer_unref(peer);
12297
12298
12299 ast_mutex_lock(&iaxsl[callno]);
12300 if (iaxs[callno]) {
12301 struct iax_ie_data ied = {
12302 .buf = { 0 },
12303 .pos = 0,
12304 };
12305 add_empty_calltoken_ie(iaxs[callno], &ied);
12306 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12307 }
12308 ast_mutex_unlock(&iaxsl[callno]);
12309
12310 return 0;
12311 }
12312
12313 static void free_context(struct iax2_context *con)
12314 {
12315 struct iax2_context *conl;
12316 while(con) {
12317 conl = con;
12318 con = con->next;
12319 ast_free(conl);
12320 }
12321 }
12322
12323 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
12324 {
12325 int callno;
12326 int res;
12327 format_t fmt, native;
12328 struct sockaddr_in sin;
12329 struct ast_channel *c;
12330 struct parsed_dial_string pds;
12331 struct create_addr_info cai;
12332 char *tmpstr;
12333
12334 memset(&pds, 0, sizeof(pds));
12335 tmpstr = ast_strdupa(data);
12336 parse_dial_string(tmpstr, &pds);
12337
12338 if (ast_strlen_zero(pds.peer)) {
12339 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12340 return NULL;
12341 }
12342
12343 memset(&cai, 0, sizeof(cai));
12344 cai.capability = iax2_capability;
12345
12346 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12347
12348
12349 if (create_addr(pds.peer, NULL, &sin, &cai)) {
12350 *cause = AST_CAUSE_UNREGISTERED;
12351 return NULL;
12352 }
12353
12354 if (pds.port)
12355 sin.sin_port = htons(atoi(pds.port));
12356
12357 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12358 if (callno < 1) {
12359 ast_log(LOG_WARNING, "Unable to create call\n");
12360 *cause = AST_CAUSE_CONGESTION;
12361 return NULL;
12362 }
12363
12364
12365 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12366 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12367 int new_callno;
12368 if ((new_callno = make_trunk(callno, 1)) != -1)
12369 callno = new_callno;
12370 }
12371 iaxs[callno]->maxtime = cai.maxtime;
12372 if (cai.found)
12373 ast_string_field_set(iaxs[callno], host, pds.peer);
12374
12375 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found);
12376
12377 ast_mutex_unlock(&iaxsl[callno]);
12378
12379 if (c) {
12380
12381 if (c->nativeformats & format)
12382 c->nativeformats &= format;
12383 else {
12384 native = c->nativeformats;
12385 fmt = format;
12386 res = ast_translator_best_choice(&fmt, &native);
12387 if (res < 0) {
12388 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12389 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12390 ast_hangup(c);
12391 return NULL;
12392 }
12393 c->nativeformats = native;
12394 }
12395 c->readformat = ast_best_codec(c->nativeformats);
12396 c->writeformat = c->readformat;
12397 }
12398
12399 return c;
12400 }
12401
12402 static void *network_thread(void *ignore)
12403 {
12404 if (timer) {
12405 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12406 }
12407
12408 for (;;) {
12409 pthread_testcancel();
12410
12411
12412
12413 if (ast_io_wait(io, 1000) <= 0) {
12414 break;
12415 }
12416 }
12417
12418 return NULL;
12419 }
12420
12421 static int start_network_thread(void)
12422 {
12423 struct iax2_thread *thread;
12424 int threadcount = 0;
12425 int x;
12426 for (x = 0; x < iaxthreadcount; x++) {
12427 thread = ast_calloc(1, sizeof(*thread));
12428 if (thread) {
12429 thread->type = IAX_THREAD_TYPE_POOL;
12430 thread->threadnum = ++threadcount;
12431 ast_mutex_init(&thread->lock);
12432 ast_cond_init(&thread->cond, NULL);
12433 ast_mutex_init(&thread->init_lock);
12434 ast_cond_init(&thread->init_cond, NULL);
12435
12436 ast_mutex_lock(&thread->init_lock);
12437
12438 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12439 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12440 ast_mutex_destroy(&thread->lock);
12441 ast_cond_destroy(&thread->cond);
12442 ast_mutex_unlock(&thread->init_lock);
12443 ast_mutex_destroy(&thread->init_lock);
12444 ast_cond_destroy(&thread->init_cond);
12445 ast_free(thread);
12446 thread = NULL;
12447 continue;
12448 }
12449
12450 ast_cond_wait(&thread->init_cond, &thread->init_lock);
12451
12452
12453 ast_mutex_unlock(&thread->init_lock);
12454
12455 AST_LIST_LOCK(&idle_list);
12456 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12457 AST_LIST_UNLOCK(&idle_list);
12458 }
12459 }
12460 if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) {
12461 ast_log(LOG_ERROR, "Failed to create new thread!\n");
12462 return -1;
12463 }
12464 ast_verb(2, "%d helper threads started\n", threadcount);
12465 return 0;
12466 }
12467
12468 static struct iax2_context *build_context(const char *context)
12469 {
12470 struct iax2_context *con;
12471
12472 if ((con = ast_calloc(1, sizeof(*con))))
12473 ast_copy_string(con->context, context, sizeof(con->context));
12474
12475 return con;
12476 }
12477
12478 static int get_auth_methods(const char *value)
12479 {
12480 int methods = 0;
12481 if (strstr(value, "rsa"))
12482 methods |= IAX_AUTH_RSA;
12483 if (strstr(value, "md5"))
12484 methods |= IAX_AUTH_MD5;
12485 if (strstr(value, "plaintext"))
12486 methods |= IAX_AUTH_PLAINTEXT;
12487 return methods;
12488 }
12489
12490
12491
12492
12493
12494 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
12495 {
12496 int sd;
12497 int res;
12498
12499 sd = socket(AF_INET, SOCK_DGRAM, 0);
12500 if (sd < 0) {
12501 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12502 return -1;
12503 }
12504
12505 res = bind(sd, sa, salen);
12506 if (res < 0) {
12507 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12508 close(sd);
12509 return 1;
12510 }
12511
12512 close(sd);
12513 return 0;
12514 }
12515
12516
12517
12518
12519 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12520 {
12521 struct sockaddr_in sin;
12522 struct ast_sockaddr sin_tmp;
12523 int nonlocal = 1;
12524 int port = IAX_DEFAULT_PORTNO;
12525 int sockfd = defaultsockfd;
12526 char *tmp;
12527 char *addr;
12528 char *portstr;
12529
12530 tmp = ast_strdupa(srcaddr);
12531 addr = strsep(&tmp, ":");
12532 portstr = tmp;
12533
12534 if (portstr) {
12535 port = atoi(portstr);
12536 if (port < 1)
12537 port = IAX_DEFAULT_PORTNO;
12538 }
12539
12540 sin_tmp.ss.ss_family = AF_INET;
12541 if (!ast_get_ip(&sin_tmp, addr)) {
12542 struct ast_netsock *sock;
12543 int res;
12544
12545 ast_sockaddr_to_sin(&sin_tmp, &sin);
12546 sin.sin_port = 0;
12547 sin.sin_family = AF_INET;
12548 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12549 if (res == 0) {
12550
12551 sin.sin_port = htons(port);
12552 if (!(sock = ast_netsock_find(netsock, &sin)))
12553 sock = ast_netsock_find(outsock, &sin);
12554 if (sock) {
12555 sockfd = ast_netsock_sockfd(sock);
12556 nonlocal = 0;
12557 } else {
12558 unsigned int orig_saddr = sin.sin_addr.s_addr;
12559
12560 sin.sin_addr.s_addr = INADDR_ANY;
12561 if (ast_netsock_find(netsock, &sin)) {
12562 sin.sin_addr.s_addr = orig_saddr;
12563 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12564 if (sock) {
12565 sockfd = ast_netsock_sockfd(sock);
12566 ast_netsock_unref(sock);
12567 nonlocal = 0;
12568 } else {
12569 nonlocal = 2;
12570 }
12571 }
12572 }
12573 }
12574 }
12575
12576 peer->sockfd = sockfd;
12577
12578 if (nonlocal == 1) {
12579 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12580 srcaddr, peer->name);
12581 return -1;
12582 } else if (nonlocal == 2) {
12583 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12584 srcaddr, peer->name);
12585 return -1;
12586 } else {
12587 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12588 return 0;
12589 }
12590 }
12591
12592 static void peer_destructor(void *obj)
12593 {
12594 struct iax2_peer *peer = obj;
12595 int callno = peer->callno;
12596
12597 ast_free_ha(peer->ha);
12598
12599 if (callno > 0) {
12600 ast_mutex_lock(&iaxsl[callno]);
12601 iax2_destroy(callno);
12602 ast_mutex_unlock(&iaxsl[callno]);
12603 }
12604
12605 register_peer_exten(peer, 0);
12606
12607 if (peer->dnsmgr)
12608 ast_dnsmgr_release(peer->dnsmgr);
12609
12610 if (peer->mwi_event_sub)
12611 ast_event_unsubscribe(peer->mwi_event_sub);
12612
12613 ast_string_field_free_memory(peer);
12614 }
12615
12616
12617 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12618 {
12619 struct iax2_peer *peer = NULL;
12620 struct ast_ha *oldha = NULL;
12621 int maskfound = 0;
12622 int found = 0;
12623 int firstpass = 1;
12624 struct iax2_peer tmp_peer = {
12625 .name = name,
12626 };
12627
12628 if (!temponly) {
12629 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12630 if (peer && !ast_test_flag64(peer, IAX_DELME))
12631 firstpass = 0;
12632 }
12633
12634 if (peer) {
12635 found++;
12636 if (firstpass) {
12637 oldha = peer->ha;
12638 peer->ha = NULL;
12639 }
12640 unlink_peer(peer);
12641 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12642 peer->expire = -1;
12643 peer->pokeexpire = -1;
12644 peer->sockfd = defaultsockfd;
12645 peer->addr.ss.ss_family = AF_INET;
12646 peer->addr.len = sizeof(struct sockaddr_in);
12647 if (ast_string_field_init(peer, 32))
12648 peer = peer_unref(peer);
12649 }
12650
12651 if (peer) {
12652 if (firstpass) {
12653 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12654 peer->encmethods = iax2_encryption;
12655 peer->adsi = adsi;
12656 ast_string_field_set(peer,secret,"");
12657 if (!found) {
12658 ast_string_field_set(peer, name, name);
12659 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12660 peer->expiry = min_reg_expire;
12661 }
12662 peer->prefs = prefs;
12663 peer->capability = iax2_capability;
12664 peer->smoothing = 0;
12665 peer->pokefreqok = DEFAULT_FREQ_OK;
12666 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12667 peer->maxcallno = 0;
12668 peercnt_modify((unsigned char) 0, 0, &peer->addr);
12669 peer->calltoken_required = CALLTOKEN_DEFAULT;
12670 ast_string_field_set(peer,context,"");
12671 ast_string_field_set(peer,peercontext,"");
12672 ast_clear_flag64(peer, IAX_HASCALLERID);
12673 ast_string_field_set(peer, cid_name, "");
12674 ast_string_field_set(peer, cid_num, "");
12675 ast_string_field_set(peer, mohinterpret, mohinterpret);
12676 ast_string_field_set(peer, mohsuggest, mohsuggest);
12677 }
12678
12679 if (!v) {
12680 v = alt;
12681 alt = NULL;
12682 }
12683 while(v) {
12684 if (!strcasecmp(v->name, "secret")) {
12685 ast_string_field_set(peer, secret, v->value);
12686 } else if (!strcasecmp(v->name, "mailbox")) {
12687 ast_string_field_set(peer, mailbox, v->value);
12688 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12689 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12690 ast_string_field_set(peer, mailbox, name);
12691 }
12692 } else if (!strcasecmp(v->name, "mohinterpret")) {
12693 ast_string_field_set(peer, mohinterpret, v->value);
12694 } else if (!strcasecmp(v->name, "mohsuggest")) {
12695 ast_string_field_set(peer, mohsuggest, v->value);
12696 } else if (!strcasecmp(v->name, "dbsecret")) {
12697 ast_string_field_set(peer, dbsecret, v->value);
12698 } else if (!strcasecmp(v->name, "trunk")) {
12699 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12700 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12701 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12702 ast_clear_flag64(peer, IAX_TRUNK);
12703 }
12704 } else if (!strcasecmp(v->name, "auth")) {
12705 peer->authmethods = get_auth_methods(v->value);
12706 } else if (!strcasecmp(v->name, "encryption")) {
12707 peer->encmethods |= get_encrypt_methods(v->value);
12708 if (!peer->encmethods) {
12709 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12710 }
12711 } else if (!strcasecmp(v->name, "forceencryption")) {
12712 if (ast_false(v->value)) {
12713 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12714 } else {
12715 peer->encmethods |= get_encrypt_methods(v->value);
12716 if (peer->encmethods) {
12717 ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12718 }
12719 }
12720 } else if (!strcasecmp(v->name, "transfer")) {
12721 if (!strcasecmp(v->value, "mediaonly")) {
12722 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12723 } else if (ast_true(v->value)) {
12724 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12725 } else
12726 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12727 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12728 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12729 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12730 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12731 } else if (!strcasecmp(v->name, "host")) {
12732 if (!strcasecmp(v->value, "dynamic")) {
12733
12734 ast_set_flag64(peer, IAX_DYNAMIC);
12735 if (!found) {
12736
12737
12738 if (ast_sockaddr_port(&peer->addr)) {
12739 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12740 }
12741 ast_sockaddr_setnull(&peer->addr);
12742 }
12743 } else {
12744
12745 ast_sched_thread_del(sched, peer->expire);
12746 ast_clear_flag64(peer, IAX_DYNAMIC);
12747 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12748 return peer_unref(peer);
12749 if (!ast_sockaddr_port(&peer->addr)) {
12750 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12751 }
12752 }
12753 if (!maskfound)
12754 inet_aton("255.255.255.255", &peer->mask);
12755 } else if (!strcasecmp(v->name, "defaultip")) {
12756 struct ast_sockaddr peer_defaddr_tmp;
12757
12758 peer_defaddr_tmp.ss.ss_family = AF_INET;
12759 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12760 return peer_unref(peer);
12761 }
12762 ast_sockaddr_to_sin(&peer_defaddr_tmp,
12763 &peer->defaddr);
12764 } else if (!strcasecmp(v->name, "sourceaddress")) {
12765 peer_set_srcaddr(peer, v->value);
12766 } else if (!strcasecmp(v->name, "permit") ||
12767 !strcasecmp(v->name, "deny")) {
12768 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12769 } else if (!strcasecmp(v->name, "mask")) {
12770 maskfound++;
12771 inet_aton(v->value, &peer->mask);
12772 } else if (!strcasecmp(v->name, "context")) {
12773 ast_string_field_set(peer, context, v->value);
12774 } else if (!strcasecmp(v->name, "regexten")) {
12775 ast_string_field_set(peer, regexten, v->value);
12776 } else if (!strcasecmp(v->name, "peercontext")) {
12777 ast_string_field_set(peer, peercontext, v->value);
12778 } else if (!strcasecmp(v->name, "port")) {
12779 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12780 peer->defaddr.sin_port = htons(atoi(v->value));
12781 } else {
12782 ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12783 }
12784 } else if (!strcasecmp(v->name, "username")) {
12785 ast_string_field_set(peer, username, v->value);
12786 } else if (!strcasecmp(v->name, "allow")) {
12787 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12788 } else if (!strcasecmp(v->name, "disallow")) {
12789 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12790 } else if (!strcasecmp(v->name, "callerid")) {
12791 if (!ast_strlen_zero(v->value)) {
12792 char name2[80];
12793 char num2[80];
12794 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12795 ast_string_field_set(peer, cid_name, name2);
12796 ast_string_field_set(peer, cid_num, num2);
12797 } else {
12798 ast_string_field_set(peer, cid_name, "");
12799 ast_string_field_set(peer, cid_num, "");
12800 }
12801 ast_set_flag64(peer, IAX_HASCALLERID);
12802 } else if (!strcasecmp(v->name, "fullname")) {
12803 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12804 ast_set_flag64(peer, IAX_HASCALLERID);
12805 } else if (!strcasecmp(v->name, "cid_number")) {
12806 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12807 ast_set_flag64(peer, IAX_HASCALLERID);
12808 } else if (!strcasecmp(v->name, "sendani")) {
12809 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12810 } else if (!strcasecmp(v->name, "inkeys")) {
12811 ast_string_field_set(peer, inkeys, v->value);
12812 } else if (!strcasecmp(v->name, "outkey")) {
12813 ast_string_field_set(peer, outkey, v->value);
12814 } else if (!strcasecmp(v->name, "qualify")) {
12815 if (!strcasecmp(v->value, "no")) {
12816 peer->maxms = 0;
12817 } else if (!strcasecmp(v->value, "yes")) {
12818 peer->maxms = DEFAULT_MAXMS;
12819 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12820 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);
12821 peer->maxms = 0;
12822 }
12823 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12824 peer->smoothing = ast_true(v->value);
12825 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12826 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12827 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);
12828 }
12829 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12830 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12831 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);
12832 }
12833 } else if (!strcasecmp(v->name, "timezone")) {
12834 ast_string_field_set(peer, zonetag, v->value);
12835 } else if (!strcasecmp(v->name, "adsi")) {
12836 peer->adsi = ast_true(v->value);
12837 } else if (!strcasecmp(v->name, "connectedline")) {
12838 if (ast_true(v->value)) {
12839 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12840 } else if (!strcasecmp(v->value, "send")) {
12841 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12842 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12843 } else if (!strcasecmp(v->value, "receive")) {
12844 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12845 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12846 } else {
12847 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12848 }
12849 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12850 if (sscanf(v->value, "%10hu", &peer->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 } else {
12853 peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr);
12854 }
12855 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12856
12857 if (ast_false(v->value)) {
12858 peer->calltoken_required = CALLTOKEN_NO;
12859 } else if (!strcasecmp(v->value, "auto")) {
12860 peer->calltoken_required = CALLTOKEN_AUTO;
12861 } else if (ast_true(v->value)) {
12862 peer->calltoken_required = CALLTOKEN_YES;
12863 } else {
12864 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12865 }
12866 }
12867
12868 v = v->next;
12869 if (!v) {
12870 v = alt;
12871 alt = NULL;
12872 }
12873 }
12874 if (!peer->authmethods)
12875 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12876 ast_clear_flag64(peer, IAX_DELME);
12877 }
12878
12879 if (oldha)
12880 ast_free_ha(oldha);
12881
12882 if (!ast_strlen_zero(peer->mailbox)) {
12883 char *mailbox, *context;
12884 context = mailbox = ast_strdupa(peer->mailbox);
12885 strsep(&context, "@");
12886 if (ast_strlen_zero(context))
12887 context = "default";
12888 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12889 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12890 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12891 AST_EVENT_IE_END);
12892 }
12893
12894 return peer;
12895 }
12896
12897 static void user_destructor(void *obj)
12898 {
12899 struct iax2_user *user = obj;
12900
12901 ast_free_ha(user->ha);
12902 free_context(user->contexts);
12903 if(user->vars) {
12904 ast_variables_destroy(user->vars);
12905 user->vars = NULL;
12906 }
12907 ast_string_field_free_memory(user);
12908 }
12909
12910
12911 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12912 {
12913 struct iax2_user *user = NULL;
12914 struct iax2_context *con, *conl = NULL;
12915 struct ast_ha *oldha = NULL;
12916 struct iax2_context *oldcon = NULL;
12917 int format;
12918 int firstpass=1;
12919 int oldcurauthreq = 0;
12920 char *varname = NULL, *varval = NULL;
12921 struct ast_variable *tmpvar = NULL;
12922 struct iax2_user tmp_user = {
12923 .name = name,
12924 };
12925
12926 if (!temponly) {
12927 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12928 if (user && !ast_test_flag64(user, IAX_DELME))
12929 firstpass = 0;
12930 }
12931
12932 if (user) {
12933 if (firstpass) {
12934 oldcurauthreq = user->curauthreq;
12935 oldha = user->ha;
12936 oldcon = user->contexts;
12937 user->ha = NULL;
12938 user->contexts = NULL;
12939 }
12940
12941 ao2_unlink(users, user);
12942 } else {
12943 user = ao2_alloc(sizeof(*user), user_destructor);
12944 }
12945
12946 if (user) {
12947 if (firstpass) {
12948 ast_string_field_free_memory(user);
12949 memset(user, 0, sizeof(struct iax2_user));
12950 if (ast_string_field_init(user, 32)) {
12951 user = user_unref(user);
12952 goto cleanup;
12953 }
12954 user->maxauthreq = maxauthreq;
12955 user->curauthreq = oldcurauthreq;
12956 user->prefs = prefs;
12957 user->capability = iax2_capability;
12958 user->encmethods = iax2_encryption;
12959 user->adsi = adsi;
12960 user->calltoken_required = CALLTOKEN_DEFAULT;
12961 ast_string_field_set(user, name, name);
12962 ast_string_field_set(user, language, language);
12963 ast_copy_flags64(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12964 ast_clear_flag64(user, IAX_HASCALLERID);
12965 ast_string_field_set(user, cid_name, "");
12966 ast_string_field_set(user, cid_num, "");
12967 ast_string_field_set(user, accountcode, accountcode);
12968 ast_string_field_set(user, mohinterpret, mohinterpret);
12969 ast_string_field_set(user, mohsuggest, mohsuggest);
12970 }
12971 if (!v) {
12972 v = alt;
12973 alt = NULL;
12974 }
12975 while(v) {
12976 if (!strcasecmp(v->name, "context")) {
12977 con = build_context(v->value);
12978 if (con) {
12979 if (conl)
12980 conl->next = con;
12981 else
12982 user->contexts = con;
12983 conl = con;
12984 }
12985 } else if (!strcasecmp(v->name, "permit") ||
12986 !strcasecmp(v->name, "deny")) {
12987 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12988 } else if (!strcasecmp(v->name, "setvar")) {
12989 varname = ast_strdupa(v->value);
12990 if ((varval = strchr(varname, '='))) {
12991 *varval = '\0';
12992 varval++;
12993 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12994 tmpvar->next = user->vars;
12995 user->vars = tmpvar;
12996 }
12997 }
12998 } else if (!strcasecmp(v->name, "allow")) {
12999 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
13000 } else if (!strcasecmp(v->name, "disallow")) {
13001 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
13002 } else if (!strcasecmp(v->name, "trunk")) {
13003 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
13004 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
13005 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
13006 ast_clear_flag64(user, IAX_TRUNK);
13007 }
13008 } else if (!strcasecmp(v->name, "auth")) {
13009 user->authmethods = get_auth_methods(v->value);
13010 } else if (!strcasecmp(v->name, "encryption")) {
13011 user->encmethods |= get_encrypt_methods(v->value);
13012 if (!user->encmethods) {
13013 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
13014 }
13015 } else if (!strcasecmp(v->name, "forceencryption")) {
13016 if (ast_false(v->value)) {
13017 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
13018 } else {
13019 user->encmethods |= get_encrypt_methods(v->value);
13020 if (user->encmethods) {
13021 ast_set_flag64(user, IAX_FORCE_ENCRYPT);
13022 }
13023 }
13024 } else if (!strcasecmp(v->name, "transfer")) {
13025 if (!strcasecmp(v->value, "mediaonly")) {
13026 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13027 } else if (ast_true(v->value)) {
13028 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13029 } else
13030 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13031 } else if (!strcasecmp(v->name, "codecpriority")) {
13032 if(!strcasecmp(v->value, "caller"))
13033 ast_set_flag64(user, IAX_CODEC_USER_FIRST);
13034 else if(!strcasecmp(v->value, "disabled"))
13035 ast_set_flag64(user, IAX_CODEC_NOPREFS);
13036 else if(!strcasecmp(v->value, "reqonly")) {
13037 ast_set_flag64(user, IAX_CODEC_NOCAP);
13038 ast_set_flag64(user, IAX_CODEC_NOPREFS);
13039 }
13040 } else if (!strcasecmp(v->name, "immediate")) {
13041 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
13042 } else if (!strcasecmp(v->name, "jitterbuffer")) {
13043 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
13044 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
13045 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
13046 } else if (!strcasecmp(v->name, "dbsecret")) {
13047 ast_string_field_set(user, dbsecret, v->value);
13048 } else if (!strcasecmp(v->name, "secret")) {
13049 if (!ast_strlen_zero(user->secret)) {
13050 char *old = ast_strdupa(user->secret);
13051
13052 ast_string_field_build(user, secret, "%s;%s", old, v->value);
13053 } else
13054 ast_string_field_set(user, secret, v->value);
13055 } else if (!strcasecmp(v->name, "callerid")) {
13056 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
13057 char name2[80];
13058 char num2[80];
13059 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13060 ast_string_field_set(user, cid_name, name2);
13061 ast_string_field_set(user, cid_num, num2);
13062 ast_set_flag64(user, IAX_HASCALLERID);
13063 } else {
13064 ast_clear_flag64(user, IAX_HASCALLERID);
13065 ast_string_field_set(user, cid_name, "");
13066 ast_string_field_set(user, cid_num, "");
13067 }
13068 } else if (!strcasecmp(v->name, "fullname")) {
13069 if (!ast_strlen_zero(v->value)) {
13070 ast_string_field_set(user, cid_name, v->value);
13071 ast_set_flag64(user, IAX_HASCALLERID);
13072 } else {
13073 ast_string_field_set(user, cid_name, "");
13074 if (ast_strlen_zero(user->cid_num))
13075 ast_clear_flag64(user, IAX_HASCALLERID);
13076 }
13077 } else if (!strcasecmp(v->name, "cid_number")) {
13078 if (!ast_strlen_zero(v->value)) {
13079 ast_string_field_set(user, cid_num, v->value);
13080 ast_set_flag64(user, IAX_HASCALLERID);
13081 } else {
13082 ast_string_field_set(user, cid_num, "");
13083 if (ast_strlen_zero(user->cid_name))
13084 ast_clear_flag64(user, IAX_HASCALLERID);
13085 }
13086 } else if (!strcasecmp(v->name, "accountcode")) {
13087 ast_string_field_set(user, accountcode, v->value);
13088 } else if (!strcasecmp(v->name, "mohinterpret")) {
13089 ast_string_field_set(user, mohinterpret, v->value);
13090 } else if (!strcasecmp(v->name, "mohsuggest")) {
13091 ast_string_field_set(user, mohsuggest, v->value);
13092 } else if (!strcasecmp(v->name, "parkinglot")) {
13093 ast_string_field_set(user, parkinglot, v->value);
13094 } else if (!strcasecmp(v->name, "language")) {
13095 ast_string_field_set(user, language, v->value);
13096 } else if (!strcasecmp(v->name, "amaflags")) {
13097 format = ast_cdr_amaflags2int(v->value);
13098 if (format < 0) {
13099 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13100 } else {
13101 user->amaflags = format;
13102 }
13103 } else if (!strcasecmp(v->name, "inkeys")) {
13104 ast_string_field_set(user, inkeys, v->value);
13105 } else if (!strcasecmp(v->name, "maxauthreq")) {
13106 user->maxauthreq = atoi(v->value);
13107 if (user->maxauthreq < 0)
13108 user->maxauthreq = 0;
13109 } else if (!strcasecmp(v->name, "adsi")) {
13110 user->adsi = ast_true(v->value);
13111 } else if (!strcasecmp(v->name, "connectedline")) {
13112 if (ast_true(v->value)) {
13113 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13114 } else if (!strcasecmp(v->value, "send")) {
13115 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
13116 ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
13117 } else if (!strcasecmp(v->value, "receive")) {
13118 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
13119 ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
13120 } else {
13121 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13122 }
13123 } else if (!strcasecmp(v->name, "requirecalltoken")) {
13124
13125 if (ast_false(v->value)) {
13126 user->calltoken_required = CALLTOKEN_NO;
13127 } else if (!strcasecmp(v->value, "auto")) {
13128 user->calltoken_required = CALLTOKEN_AUTO;
13129 } else if (ast_true(v->value)) {
13130 user->calltoken_required = CALLTOKEN_YES;
13131 } else {
13132 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13133 }
13134 }
13135
13136 v = v->next;
13137 if (!v) {
13138 v = alt;
13139 alt = NULL;
13140 }
13141 }
13142 if (!user->authmethods) {
13143 if (!ast_strlen_zero(user->secret)) {
13144 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
13145 if (!ast_strlen_zero(user->inkeys))
13146 user->authmethods |= IAX_AUTH_RSA;
13147 } else if (!ast_strlen_zero(user->inkeys)) {
13148 user->authmethods = IAX_AUTH_RSA;
13149 } else {
13150 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
13151 }
13152 }
13153 ast_clear_flag64(user, IAX_DELME);
13154 }
13155 cleanup:
13156 if (oldha)
13157 ast_free_ha(oldha);
13158 if (oldcon)
13159 free_context(oldcon);
13160 return user;
13161 }
13162
13163 static int peer_delme_cb(void *obj, void *arg, int flags)
13164 {
13165 struct iax2_peer *peer = obj;
13166
13167 ast_set_flag64(peer, IAX_DELME);
13168
13169 return 0;
13170 }
13171
13172 static int user_delme_cb(void *obj, void *arg, int flags)
13173 {
13174 struct iax2_user *user = obj;
13175
13176 ast_set_flag64(user, IAX_DELME);
13177
13178 return 0;
13179 }
13180
13181 static void delete_users(void)
13182 {
13183 struct iax2_registry *reg;
13184
13185 ao2_callback(users, 0, user_delme_cb, NULL);
13186
13187 AST_LIST_LOCK(®istrations);
13188 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
13189 if (sched) {
13190 ast_sched_thread_del(sched, reg->expire);
13191 }
13192 if (reg->callno) {
13193 int callno = reg->callno;
13194 ast_mutex_lock(&iaxsl[callno]);
13195 if (iaxs[callno]) {
13196 iaxs[callno]->reg = NULL;
13197 iax2_destroy(callno);
13198 }
13199 ast_mutex_unlock(&iaxsl[callno]);
13200 }
13201 if (reg->dnsmgr)
13202 ast_dnsmgr_release(reg->dnsmgr);
13203 ast_free(reg);
13204 }
13205 AST_LIST_UNLOCK(®istrations);
13206
13207 ao2_callback(peers, 0, peer_delme_cb, NULL);
13208 }
13209
13210 static void prune_users(void)
13211 {
13212 struct iax2_user *user;
13213 struct ao2_iterator i;
13214
13215 i = ao2_iterator_init(users, 0);
13216 while ((user = ao2_iterator_next(&i))) {
13217 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
13218 ao2_unlink(users, user);
13219 }
13220 user_unref(user);
13221 }
13222 ao2_iterator_destroy(&i);
13223 }
13224
13225
13226 static void prune_peers(void)
13227 {
13228 struct iax2_peer *peer;
13229 struct ao2_iterator i;
13230
13231 i = ao2_iterator_init(peers, 0);
13232 while ((peer = ao2_iterator_next(&i))) {
13233 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
13234 unlink_peer(peer);
13235 }
13236 peer_unref(peer);
13237 }
13238 ao2_iterator_destroy(&i);
13239 }
13240
13241 static void set_config_destroy(void)
13242 {
13243 strcpy(accountcode, "");
13244 strcpy(language, "");
13245 strcpy(mohinterpret, "");
13246 strcpy(mohsuggest, "");
13247 trunkmaxsize = MAX_TRUNKDATA;
13248 amaflags = 0;
13249 delayreject = 0;
13250 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF |
13251 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13252 delete_users();
13253 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
13254 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
13255 }
13256
13257
13258 static int set_config(const char *config_file, int reload)
13259 {
13260 struct ast_config *cfg, *ucfg;
13261 format_t capability = iax2_capability;
13262 struct ast_variable *v;
13263 char *cat;
13264 const char *utype;
13265 const char *tosval;
13266 int format;
13267 int portno = IAX_DEFAULT_PORTNO;
13268 int x;
13269 int mtuv;
13270 int subscribe_network_change = 1;
13271 struct iax2_user *user;
13272 struct iax2_peer *peer;
13273 struct ast_netsock *ns;
13274 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13275 #if 0
13276 static unsigned short int last_port=0;
13277 #endif
13278
13279 cfg = ast_config_load(config_file, config_flags);
13280
13281 if (!cfg) {
13282 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13283 return -1;
13284 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13285 ucfg = ast_config_load("users.conf", config_flags);
13286 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13287 return 0;
13288
13289 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13290 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13291 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13292 ast_config_destroy(ucfg);
13293 return 0;
13294 }
13295 if (!cfg) {
13296
13297 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file);
13298 return -1;
13299 }
13300 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13301 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13302 return 0;
13303 } else {
13304 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13305 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13306 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
13307 ast_config_destroy(cfg);
13308 return 0;
13309 }
13310 }
13311
13312 if (reload) {
13313 set_config_destroy();
13314 }
13315
13316
13317 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13318
13319
13320 memset(&globalflags, 0, sizeof(globalflags));
13321 ast_set_flag64(&globalflags, IAX_RTUPDATE);
13322 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13323
13324 #ifdef SO_NO_CHECK
13325 nochecksums = 0;
13326 #endif
13327
13328 default_parkinglot[0] = '\0';
13329
13330 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13331 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13332 global_max_trunk_mtu = MAX_TRUNK_MTU;
13333 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13334 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13335
13336 maxauthreq = 3;
13337
13338 srvlookup = 0;
13339
13340 v = ast_variable_browse(cfg, "general");
13341
13342
13343 tosval = ast_variable_retrieve(cfg, "general", "tos");
13344 if (tosval) {
13345 if (ast_str2tos(tosval, &qos.tos))
13346 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13347 }
13348
13349 tosval = ast_variable_retrieve(cfg, "general", "cos");
13350 if (tosval) {
13351 if (ast_str2cos(tosval, &qos.cos))
13352 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13353 }
13354 while(v) {
13355 if (!strcasecmp(v->name, "bindport")){
13356 if (reload)
13357 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13358 else
13359 portno = atoi(v->value);
13360 } else if (!strcasecmp(v->name, "pingtime"))
13361 ping_time = atoi(v->value);
13362 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13363 if (reload) {
13364 if (atoi(v->value) != iaxthreadcount)
13365 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13366 } else {
13367 iaxthreadcount = atoi(v->value);
13368 if (iaxthreadcount < 1) {
13369 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13370 iaxthreadcount = 1;
13371 } else if (iaxthreadcount > 256) {
13372 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13373 iaxthreadcount = 256;
13374 }
13375 }
13376 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13377 if (reload) {
13378 AST_LIST_LOCK(&dynamic_list);
13379 iaxmaxthreadcount = atoi(v->value);
13380 AST_LIST_UNLOCK(&dynamic_list);
13381 } else {
13382 iaxmaxthreadcount = atoi(v->value);
13383 if (iaxmaxthreadcount < 0) {
13384 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13385 iaxmaxthreadcount = 0;
13386 } else if (iaxmaxthreadcount > 256) {
13387 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13388 iaxmaxthreadcount = 256;
13389 }
13390 }
13391 } else if (!strcasecmp(v->name, "nochecksums")) {
13392 #ifdef SO_NO_CHECK
13393 if (ast_true(v->value))
13394 nochecksums = 1;
13395 else
13396 nochecksums = 0;
13397 #else
13398 if (ast_true(v->value))
13399 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13400 #endif
13401 }
13402 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13403 maxjitterbuffer = atoi(v->value);
13404 else if (!strcasecmp(v->name, "resyncthreshold"))
13405 resyncthreshold = atoi(v->value);
13406 else if (!strcasecmp(v->name, "maxjitterinterps"))
13407 maxjitterinterps = atoi(v->value);
13408 else if (!strcasecmp(v->name, "jittertargetextra"))
13409 jittertargetextra = atoi(v->value);
13410 else if (!strcasecmp(v->name, "lagrqtime"))
13411 lagrq_time = atoi(v->value);
13412 else if (!strcasecmp(v->name, "maxregexpire"))
13413 max_reg_expire = atoi(v->value);
13414 else if (!strcasecmp(v->name, "minregexpire"))
13415 min_reg_expire = atoi(v->value);
13416 else if (!strcasecmp(v->name, "bindaddr")) {
13417 if (reload) {
13418 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13419 } else {
13420 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13421 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13422 } else {
13423 if (strchr(v->value, ':'))
13424 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13425 else
13426 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13427 if (defaultsockfd < 0)
13428 defaultsockfd = ast_netsock_sockfd(ns);
13429 ast_netsock_unref(ns);
13430 }
13431 }
13432 } else if (!strcasecmp(v->name, "authdebug")) {
13433 authdebug = ast_true(v->value);
13434 } else if (!strcasecmp(v->name, "encryption")) {
13435 iax2_encryption |= get_encrypt_methods(v->value);
13436 if (!iax2_encryption) {
13437 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13438 }
13439 } else if (!strcasecmp(v->name, "forceencryption")) {
13440 if (ast_false(v->value)) {
13441 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13442 } else {
13443 iax2_encryption |= get_encrypt_methods(v->value);
13444 if (iax2_encryption) {
13445 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13446 }
13447 }
13448 } else if (!strcasecmp(v->name, "transfer")) {
13449 if (!strcasecmp(v->value, "mediaonly")) {
13450 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13451 } else if (ast_true(v->value)) {
13452 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13453 } else
13454 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13455 } else if (!strcasecmp(v->name, "codecpriority")) {
13456 if(!strcasecmp(v->value, "caller"))
13457 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13458 else if(!strcasecmp(v->value, "disabled"))
13459 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13460 else if(!strcasecmp(v->value, "reqonly")) {
13461 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13462 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13463 }
13464 } else if (!strcasecmp(v->name, "jitterbuffer"))
13465 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13466 else if (!strcasecmp(v->name, "forcejitterbuffer"))
13467 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13468 else if (!strcasecmp(v->name, "delayreject"))
13469 delayreject = ast_true(v->value);
13470 else if (!strcasecmp(v->name, "allowfwdownload"))
13471 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13472 else if (!strcasecmp(v->name, "rtcachefriends"))
13473 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13474 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13475 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13476 else if (!strcasecmp(v->name, "rtupdate"))
13477 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13478 else if (!strcasecmp(v->name, "rtsavesysname"))
13479 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13480 else if (!strcasecmp(v->name, "trunktimestamps"))
13481 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13482 else if (!strcasecmp(v->name, "rtautoclear")) {
13483 int i = atoi(v->value);
13484 if(i > 0)
13485 global_rtautoclear = i;
13486 else
13487 i = 0;
13488 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13489 } else if (!strcasecmp(v->name, "trunkfreq")) {
13490 trunkfreq = atoi(v->value);
13491 if (trunkfreq < 10) {
13492 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13493 trunkfreq = 10;
13494 } else if (trunkfreq > 1000) {
13495 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13496 trunkfreq = 1000;
13497 }
13498 if (timer) {
13499 ast_timer_set_rate(timer, 1000 / trunkfreq);
13500 }
13501 } else if (!strcasecmp(v->name, "trunkmtu")) {
13502 mtuv = atoi(v->value);
13503 if (mtuv == 0 )
13504 global_max_trunk_mtu = 0;
13505 else if (mtuv >= 172 && mtuv < 4000)
13506 global_max_trunk_mtu = mtuv;
13507 else
13508 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13509 mtuv, v->lineno);
13510 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13511 trunkmaxsize = atoi(v->value);
13512 if (trunkmaxsize == 0)
13513 trunkmaxsize = MAX_TRUNKDATA;
13514 } else if (!strcasecmp(v->name, "autokill")) {
13515 if (sscanf(v->value, "%30d", &x) == 1) {
13516 if (x >= 0)
13517 autokill = x;
13518 else
13519 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13520 } else if (ast_true(v->value)) {
13521 autokill = DEFAULT_MAXMS;
13522 } else {
13523 autokill = 0;
13524 }
13525 } else if (!strcasecmp(v->name, "bandwidth")) {
13526 if (!strcasecmp(v->value, "low")) {
13527 capability = IAX_CAPABILITY_LOWBANDWIDTH;
13528 } else if (!strcasecmp(v->value, "medium")) {
13529 capability = IAX_CAPABILITY_MEDBANDWIDTH;
13530 } else if (!strcasecmp(v->value, "high")) {
13531 capability = IAX_CAPABILITY_FULLBANDWIDTH;
13532 } else
13533 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13534 } else if (!strcasecmp(v->name, "allow")) {
13535 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13536 } else if (!strcasecmp(v->name, "disallow")) {
13537 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13538 } else if (!strcasecmp(v->name, "register")) {
13539 iax2_register(v->value, v->lineno);
13540 } else if (!strcasecmp(v->name, "iaxcompat")) {
13541 iaxcompat = ast_true(v->value);
13542 } else if (!strcasecmp(v->name, "regcontext")) {
13543 ast_copy_string(regcontext, v->value, sizeof(regcontext));
13544
13545 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13546 } else if (!strcasecmp(v->name, "tos")) {
13547 if (ast_str2tos(v->value, &qos.tos))
13548 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13549 } else if (!strcasecmp(v->name, "cos")) {
13550 if (ast_str2cos(v->value, &qos.cos))
13551 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13552 } else if (!strcasecmp(v->name, "parkinglot")) {
13553 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13554 } else if (!strcasecmp(v->name, "accountcode")) {
13555 ast_copy_string(accountcode, v->value, sizeof(accountcode));
13556 } else if (!strcasecmp(v->name, "mohinterpret")) {
13557 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13558 } else if (!strcasecmp(v->name, "mohsuggest")) {
13559 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13560 } else if (!strcasecmp(v->name, "amaflags")) {
13561 format = ast_cdr_amaflags2int(v->value);
13562 if (format < 0) {
13563 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13564 } else {
13565 amaflags = format;
13566 }
13567 } else if (!strcasecmp(v->name, "language")) {
13568 ast_copy_string(language, v->value, sizeof(language));
13569 } else if (!strcasecmp(v->name, "maxauthreq")) {
13570 maxauthreq = atoi(v->value);
13571 if (maxauthreq < 0)
13572 maxauthreq = 0;
13573 } else if (!strcasecmp(v->name, "adsi")) {
13574 adsi = ast_true(v->value);
13575 } else if (!strcasecmp(v->name, "srvlookup")) {
13576 srvlookup = ast_true(v->value);
13577 } else if (!strcasecmp(v->name, "connectedline")) {
13578 if (ast_true(v->value)) {
13579 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13580 } else if (!strcasecmp(v->value, "send")) {
13581 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13582 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13583 } else if (!strcasecmp(v->value, "receive")) {
13584 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13585 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13586 } else {
13587 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13588 }
13589 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13590 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13591 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
13592 }
13593 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13594 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13595 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);
13596 }
13597 } else if (!strcasecmp(v->name, "calltokenoptional")) {
13598 if (add_calltoken_ignore(v->value)) {
13599 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13600 }
13601 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13602 if (ast_true(v->value)) {
13603 subscribe_network_change = 1;
13604 } else if (ast_false(v->value)) {
13605 subscribe_network_change = 0;
13606 } else {
13607 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13608 }
13609 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13610 if (ast_true(v->value)) {
13611 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13612 } else if (ast_false(v->value)) {
13613 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13614 } else {
13615 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13616 }
13617 }
13618
13619 v = v->next;
13620 }
13621
13622 if (subscribe_network_change) {
13623 network_change_event_subscribe();
13624 } else {
13625 network_change_event_unsubscribe();
13626 }
13627
13628 if (defaultsockfd < 0) {
13629 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13630 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13631 } else {
13632 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13633 defaultsockfd = ast_netsock_sockfd(ns);
13634 ast_netsock_unref(ns);
13635 }
13636 }
13637 if (reload) {
13638 ast_netsock_release(outsock);
13639 outsock = ast_netsock_list_alloc();
13640 if (!outsock) {
13641 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13642 return -1;
13643 }
13644 ast_netsock_init(outsock);
13645 }
13646
13647 if (min_reg_expire > max_reg_expire) {
13648 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13649 min_reg_expire, max_reg_expire, max_reg_expire);
13650 min_reg_expire = max_reg_expire;
13651 }
13652 iax2_capability = capability;
13653
13654 if (ucfg) {
13655 struct ast_variable *gen;
13656 int genhasiax;
13657 int genregisteriax;
13658 const char *hasiax, *registeriax;
13659
13660 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13661 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13662 gen = ast_variable_browse(ucfg, "general");
13663 cat = ast_category_browse(ucfg, NULL);
13664 while (cat) {
13665 if (strcasecmp(cat, "general")) {
13666 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13667 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13668 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13669
13670 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13671 if (user) {
13672 ao2_link(users, user);
13673 user = user_unref(user);
13674 }
13675 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13676 if (peer) {
13677 if (ast_test_flag64(peer, IAX_DYNAMIC))
13678 reg_source_db(peer);
13679 ao2_link(peers, peer);
13680 peer = peer_unref(peer);
13681 }
13682 }
13683 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13684 char tmp[256];
13685 const char *host = ast_variable_retrieve(ucfg, cat, "host");
13686 const char *username = ast_variable_retrieve(ucfg, cat, "username");
13687 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13688 if (!host)
13689 host = ast_variable_retrieve(ucfg, "general", "host");
13690 if (!username)
13691 username = ast_variable_retrieve(ucfg, "general", "username");
13692 if (!secret)
13693 secret = ast_variable_retrieve(ucfg, "general", "secret");
13694 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13695 if (!ast_strlen_zero(secret))
13696 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13697 else
13698 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13699 iax2_register(tmp, 0);
13700 }
13701 }
13702 }
13703 cat = ast_category_browse(ucfg, cat);
13704 }
13705 ast_config_destroy(ucfg);
13706 }
13707
13708 cat = ast_category_browse(cfg, NULL);
13709 while(cat) {
13710 if (strcasecmp(cat, "general")) {
13711 utype = ast_variable_retrieve(cfg, cat, "type");
13712 if (!strcasecmp(cat, "callnumberlimits")) {
13713 build_callno_limits(ast_variable_browse(cfg, cat));
13714 } else if (utype) {
13715 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13716 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13717 if (user) {
13718 ao2_link(users, user);
13719 user = user_unref(user);
13720 }
13721 }
13722 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13723 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13724 if (peer) {
13725 if (ast_test_flag64(peer, IAX_DYNAMIC))
13726 reg_source_db(peer);
13727 ao2_link(peers, peer);
13728 peer = peer_unref(peer);
13729 }
13730 } else if (strcasecmp(utype, "user")) {
13731 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13732 }
13733 } else
13734 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13735 }
13736 cat = ast_category_browse(cfg, cat);
13737 }
13738 ast_config_destroy(cfg);
13739 return 1;
13740 }
13741
13742 static void poke_all_peers(void)
13743 {
13744 struct ao2_iterator i;
13745 struct iax2_peer *peer;
13746
13747 i = ao2_iterator_init(peers, 0);
13748 while ((peer = ao2_iterator_next(&i))) {
13749 iax2_poke_peer(peer, 0);
13750 peer_unref(peer);
13751 }
13752 ao2_iterator_destroy(&i);
13753 }
13754 static int reload_config(void)
13755 {
13756 static const char config[] = "iax.conf";
13757 struct iax2_registry *reg;
13758
13759 if (set_config(config, 1) > 0) {
13760 prune_peers();
13761 prune_users();
13762 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13763 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13764 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13765 trunk_timed = trunk_untimed = 0;
13766 trunk_nmaxmtu = trunk_maxmtu = 0;
13767 memset(&debugaddr, '\0', sizeof(debugaddr));
13768
13769 AST_LIST_LOCK(®istrations);
13770 AST_LIST_TRAVERSE(®istrations, reg, entry)
13771 iax2_do_register(reg);
13772 AST_LIST_UNLOCK(®istrations);
13773
13774
13775 poke_all_peers();
13776 }
13777
13778 reload_firmware(0);
13779 iax_provision_reload(1);
13780 ast_unload_realtime("iaxpeers");
13781
13782 return 0;
13783 }
13784
13785 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13786 {
13787 switch (cmd) {
13788 case CLI_INIT:
13789 e->command = "iax2 reload";
13790 e->usage =
13791 "Usage: iax2 reload\n"
13792 " Reloads IAX configuration from iax.conf\n";
13793 return NULL;
13794 case CLI_GENERATE:
13795 return NULL;
13796 }
13797
13798 reload_config();
13799
13800 return CLI_SUCCESS;
13801 }
13802
13803 static int reload(void)
13804 {
13805 return reload_config();
13806 }
13807
13808 static int cache_get_callno_locked(const char *data)
13809 {
13810 struct sockaddr_in sin;
13811 int x;
13812 int callno;
13813 struct iax_ie_data ied;
13814 struct create_addr_info cai;
13815 struct parsed_dial_string pds;
13816 char *tmpstr;
13817
13818 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13819
13820
13821 if (!ast_mutex_trylock(&iaxsl[x])) {
13822 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13823 return x;
13824 ast_mutex_unlock(&iaxsl[x]);
13825 }
13826 }
13827
13828
13829
13830 memset(&cai, 0, sizeof(cai));
13831 memset(&ied, 0, sizeof(ied));
13832 memset(&pds, 0, sizeof(pds));
13833
13834 tmpstr = ast_strdupa(data);
13835 parse_dial_string(tmpstr, &pds);
13836
13837 if (ast_strlen_zero(pds.peer)) {
13838 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13839 return -1;
13840 }
13841
13842
13843 if (create_addr(pds.peer, NULL, &sin, &cai))
13844 return -1;
13845
13846 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13847 pds.peer, pds.username, pds.password, pds.context);
13848
13849 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13850 if (callno < 1) {
13851 ast_log(LOG_WARNING, "Unable to create call\n");
13852 return -1;
13853 }
13854
13855 ast_string_field_set(iaxs[callno], dproot, data);
13856 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13857
13858 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13859 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13860
13861
13862
13863 if (pds.exten)
13864 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13865 if (pds.username)
13866 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13867 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13868 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13869
13870 if (pds.password)
13871 ast_string_field_set(iaxs[callno], secret, pds.password);
13872 if (pds.key)
13873 ast_string_field_set(iaxs[callno], outkey, pds.key);
13874
13875 add_empty_calltoken_ie(iaxs[callno], &ied);
13876 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13877
13878 return callno;
13879 }
13880
13881 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13882 {
13883 struct iax2_dpcache *dp = NULL;
13884 struct timeval now = ast_tvnow();
13885 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13886 struct ast_channel *c = NULL;
13887 struct ast_frame *f = NULL;
13888
13889 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13890 if (ast_tvcmp(now, dp->expiry) > 0) {
13891 AST_LIST_REMOVE_CURRENT(cache_list);
13892 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13893 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13894 else
13895 ast_free(dp);
13896 continue;
13897 }
13898 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13899 break;
13900 }
13901 AST_LIST_TRAVERSE_SAFE_END;
13902
13903 if (!dp) {
13904
13905
13906 if ((callno = cache_get_callno_locked(data)) < 0) {
13907 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13908 return NULL;
13909 }
13910 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13911 ast_mutex_unlock(&iaxsl[callno]);
13912 return NULL;
13913 }
13914 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13915 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13916 dp->expiry = ast_tvnow();
13917 dp->orig = dp->expiry;
13918
13919 dp->expiry.tv_sec += iaxdefaultdpcache;
13920 dp->flags = CACHE_FLAG_PENDING;
13921 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13922 dp->waiters[x] = -1;
13923
13924 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13925 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13926
13927 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13928 iax2_dprequest(dp, callno);
13929 ast_mutex_unlock(&iaxsl[callno]);
13930 }
13931
13932
13933 if (dp->flags & CACHE_FLAG_PENDING) {
13934 struct timeval start;
13935 int ms;
13936
13937
13938 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13939
13940 if (dp->waiters[x] < 0)
13941 break;
13942 }
13943 if (x >= ARRAY_LEN(dp->waiters)) {
13944 ast_log(LOG_WARNING, "No more waiter positions available\n");
13945 return NULL;
13946 }
13947 if (pipe(com)) {
13948 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13949 return NULL;
13950 }
13951 dp->waiters[x] = com[1];
13952
13953 timeout = iaxdefaulttimeout * 1000;
13954
13955 AST_LIST_UNLOCK(&dpcache);
13956
13957 if (chan)
13958 old = ast_channel_defer_dtmf(chan);
13959 doabort = 0;
13960 start = ast_tvnow();
13961 while ((ms = ast_remaining_ms(start, timeout))) {
13962 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms);
13963 if (outfd > -1)
13964 break;
13965 if (!c)
13966 continue;
13967 if (!(f = ast_read(c))) {
13968 doabort = 1;
13969 break;
13970 }
13971 ast_frfree(f);
13972 }
13973 if (!ms) {
13974 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13975 }
13976 AST_LIST_LOCK(&dpcache);
13977 dp->waiters[x] = -1;
13978 close(com[1]);
13979 close(com[0]);
13980 if (doabort) {
13981
13982
13983 if (!old && chan)
13984 ast_channel_undefer_dtmf(chan);
13985 return NULL;
13986 }
13987 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13988
13989 if (dp->flags & CACHE_FLAG_PENDING) {
13990
13991
13992 dp->flags &= ~CACHE_FLAG_PENDING;
13993 dp->flags |= CACHE_FLAG_TIMEOUT;
13994
13995
13996 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13997 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13998 if (dp->waiters[x] > -1) {
13999 if (write(dp->waiters[x], "asdf", 4) < 0) {
14000 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
14001 }
14002 }
14003 }
14004 }
14005 }
14006
14007 if (!old && chan)
14008 ast_channel_undefer_dtmf(chan);
14009 }
14010 return dp;
14011 }
14012
14013
14014 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14015 {
14016 int res = 0;
14017 struct iax2_dpcache *dp = NULL;
14018 #if 0
14019 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14020 #endif
14021 if ((priority != 1) && (priority != 2))
14022 return 0;
14023
14024 AST_LIST_LOCK(&dpcache);
14025 if ((dp = find_cache(chan, data, context, exten, priority))) {
14026 if (dp->flags & CACHE_FLAG_EXISTS)
14027 res = 1;
14028 } else {
14029 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14030 }
14031 AST_LIST_UNLOCK(&dpcache);
14032
14033 return res;
14034 }
14035
14036
14037 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14038 {
14039 int res = 0;
14040 struct iax2_dpcache *dp = NULL;
14041 #if 0
14042 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14043 #endif
14044 if ((priority != 1) && (priority != 2))
14045 return 0;
14046
14047 AST_LIST_LOCK(&dpcache);
14048 if ((dp = find_cache(chan, data, context, exten, priority))) {
14049 if (dp->flags & CACHE_FLAG_CANEXIST)
14050 res = 1;
14051 } else {
14052 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14053 }
14054 AST_LIST_UNLOCK(&dpcache);
14055
14056 return res;
14057 }
14058
14059
14060 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14061 {
14062 int res = 0;
14063 struct iax2_dpcache *dp = NULL;
14064 #if 0
14065 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14066 #endif
14067 if ((priority != 1) && (priority != 2))
14068 return 0;
14069
14070 AST_LIST_LOCK(&dpcache);
14071 if ((dp = find_cache(chan, data, context, exten, priority))) {
14072 if (dp->flags & CACHE_FLAG_MATCHMORE)
14073 res = 1;
14074 } else {
14075 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14076 }
14077 AST_LIST_UNLOCK(&dpcache);
14078
14079 return res;
14080 }
14081
14082
14083 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14084 {
14085 char odata[256];
14086 char req[256];
14087 char *ncontext;
14088 struct iax2_dpcache *dp = NULL;
14089 struct ast_app *dial = NULL;
14090 #if 0
14091 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);
14092 #endif
14093 if (priority == 2) {
14094
14095 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
14096 if (dialstatus) {
14097 dial = pbx_findapp(dialstatus);
14098 if (dial)
14099 pbx_exec(chan, dial, "");
14100 }
14101 return -1;
14102 } else if (priority != 1)
14103 return -1;
14104
14105 AST_LIST_LOCK(&dpcache);
14106 if ((dp = find_cache(chan, data, context, exten, priority))) {
14107 if (dp->flags & CACHE_FLAG_EXISTS) {
14108 ast_copy_string(odata, data, sizeof(odata));
14109 ncontext = strchr(odata, '/');
14110 if (ncontext) {
14111 *ncontext = '\0';
14112 ncontext++;
14113 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
14114 } else {
14115 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
14116 }
14117 ast_verb(3, "Executing Dial('%s')\n", req);
14118 } else {
14119 AST_LIST_UNLOCK(&dpcache);
14120 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
14121 return -1;
14122 }
14123 }
14124 AST_LIST_UNLOCK(&dpcache);
14125
14126 if ((dial = pbx_findapp("Dial")))
14127 return pbx_exec(chan, dial, req);
14128 else
14129 ast_log(LOG_WARNING, "No dial application registered\n");
14130
14131 return -1;
14132 }
14133
14134 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
14135 {
14136 struct iax2_peer *peer;
14137 char *peername, *colname;
14138
14139 peername = ast_strdupa(data);
14140
14141
14142 if (!strcmp(peername,"CURRENTCHANNEL")) {
14143 unsigned short callno;
14144 if (!chan || chan->tech != &iax2_tech) {
14145 return -1;
14146 }
14147 callno = PTR_TO_CALLNO(chan->tech_pvt);
14148 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
14149 return 0;
14150 }
14151
14152 if ((colname = strchr(peername, ',')))
14153 *colname++ = '\0';
14154 else
14155 colname = "ip";
14156
14157 if (!(peer = find_peer(peername, 1)))
14158 return -1;
14159
14160 if (!strcasecmp(colname, "ip")) {
14161 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
14162 } else if (!strcasecmp(colname, "status")) {
14163 peer_status(peer, buf, len);
14164 } else if (!strcasecmp(colname, "mailbox")) {
14165 ast_copy_string(buf, peer->mailbox, len);
14166 } else if (!strcasecmp(colname, "context")) {
14167 ast_copy_string(buf, peer->context, len);
14168 } else if (!strcasecmp(colname, "expire")) {
14169 snprintf(buf, len, "%d", peer->expire);
14170 } else if (!strcasecmp(colname, "dynamic")) {
14171 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
14172 } else if (!strcasecmp(colname, "callerid_name")) {
14173 ast_copy_string(buf, peer->cid_name, len);
14174 } else if (!strcasecmp(colname, "callerid_num")) {
14175 ast_copy_string(buf, peer->cid_num, len);
14176 } else if (!strcasecmp(colname, "codecs")) {
14177 ast_getformatname_multiple(buf, len -1, peer->capability);
14178 } else if (!strncasecmp(colname, "codec[", 6)) {
14179 char *codecnum, *ptr;
14180 int codec = 0;
14181
14182
14183 codecnum = colname + 5;
14184 *codecnum = '\0';
14185 codecnum++;
14186 if ((ptr = strchr(codecnum, ']'))) {
14187 *ptr = '\0';
14188 }
14189 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
14190 ast_copy_string(buf, ast_getformatname(codec), len);
14191 } else {
14192 buf[0] = '\0';
14193 }
14194 } else {
14195 buf[0] = '\0';
14196 }
14197
14198 peer_unref(peer);
14199
14200 return 0;
14201 }
14202
14203 static struct ast_custom_function iaxpeer_function = {
14204 .name = "IAXPEER",
14205 .read = function_iaxpeer,
14206 };
14207
14208 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
14209 {
14210 struct chan_iax2_pvt *pvt;
14211 unsigned int callno;
14212 int res = 0;
14213
14214 if (!chan || chan->tech != &iax2_tech) {
14215 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14216 return -1;
14217 }
14218
14219 callno = PTR_TO_CALLNO(chan->tech_pvt);
14220 ast_mutex_lock(&iaxsl[callno]);
14221 if (!(pvt = iaxs[callno])) {
14222 ast_mutex_unlock(&iaxsl[callno]);
14223 return -1;
14224 }
14225
14226 if (!strcasecmp(args, "osptoken")) {
14227 ast_copy_string(buf, pvt->osptoken, buflen);
14228 } else if (!strcasecmp(args, "peerip")) {
14229 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
14230 } else if (!strcasecmp(args, "peername")) {
14231 ast_copy_string(buf, pvt->username, buflen);
14232 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14233 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14234 } else {
14235 res = -1;
14236 }
14237
14238 ast_mutex_unlock(&iaxsl[callno]);
14239
14240 return res;
14241 }
14242
14243
14244 static int iax2_devicestate(void *data)
14245 {
14246 struct parsed_dial_string pds;
14247 char *tmp = ast_strdupa(data);
14248 struct iax2_peer *p;
14249 int res = AST_DEVICE_INVALID;
14250
14251 memset(&pds, 0, sizeof(pds));
14252 parse_dial_string(tmp, &pds);
14253
14254 if (ast_strlen_zero(pds.peer)) {
14255 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
14256 return res;
14257 }
14258
14259 ast_debug(3, "Checking device state for device %s\n", pds.peer);
14260
14261
14262 if (!(p = find_peer(pds.peer, 1)))
14263 return res;
14264
14265 res = AST_DEVICE_UNAVAILABLE;
14266 ast_debug(3, "Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
14267 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
14268
14269 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
14270 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14271
14272
14273 if (p->historicms == 0 || p->historicms <= p->maxms)
14274
14275 res = AST_DEVICE_UNKNOWN;
14276 }
14277
14278 peer_unref(p);
14279
14280 return res;
14281 }
14282
14283 static struct ast_switch iax2_switch =
14284 {
14285 .name = "IAX2",
14286 .description = "IAX Remote Dialplan Switch",
14287 .exists = iax2_exists,
14288 .canmatch = iax2_canmatch,
14289 .exec = iax2_exec,
14290 .matchmore = iax2_matchmore,
14291 };
14292
14293
14294
14295
14296
14297
14298
14299
14300
14301
14302
14303
14304
14305
14306
14307
14308
14309
14310
14311
14312
14313
14314
14315
14316
14317
14318
14319
14320
14321
14322
14323
14324
14325
14326
14327
14328
14329
14330
14331
14332
14333
14334
14335
14336
14337
14338
14339
14340
14341
14342
14343
14344
14345
14346
14347
14348
14349
14350
14351
14352
14353
14354
14355
14356
14357
14358
14359
14360
14361
14362
14363
14364
14365
14366
14367
14368
14369
14370
14371
14372
14373
14374
14375
14376
14377
14378
14379
14380
14381
14382
14383
14384
14385
14386
14387
14388
14389
14390
14391
14392
14393
14394
14395
14396
14397 static struct ast_cli_entry cli_iax2[] = {
14398 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14399 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14400 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14401 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14402 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14403 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14404 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14405 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14406 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14407 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14408 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14409 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14410 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14411 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14412 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14413 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14414 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14415 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14416 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14417 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14418 #ifdef IAXTESTS
14419 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14420 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14421 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14422 #endif
14423 };
14424
14425 #ifdef TEST_FRAMEWORK
14426 AST_TEST_DEFINE(test_iax2_peers_get)
14427 {
14428 struct ast_data_query query = {
14429 .path = "/asterisk/channel/iax2/peers",
14430 .search = "peers/peer/name=test_peer_data_provider"
14431 };
14432 struct ast_data *node;
14433 struct iax2_peer *peer;
14434
14435 switch (cmd) {
14436 case TEST_INIT:
14437 info->name = "iax2_peers_get_data_test";
14438 info->category = "/main/data/iax2/peers/";
14439 info->summary = "IAX2 peers data providers unit test";
14440 info->description =
14441 "Tests whether the IAX2 peers data provider implementation works as expected.";
14442 return AST_TEST_NOT_RUN;
14443 case TEST_EXECUTE:
14444 break;
14445 }
14446
14447
14448 peer = build_peer("test_peer_data_provider", NULL, NULL, 0);
14449 if (!peer) {
14450 return AST_TEST_FAIL;
14451 }
14452 peer->expiry= 1010;
14453 ao2_link(peers, peer);
14454
14455 node = ast_data_get(&query);
14456 if (!node) {
14457 ao2_unlink(peers, peer);
14458 peer_unref(peer);
14459 return AST_TEST_FAIL;
14460 }
14461
14462
14463 if (strcmp(ast_data_retrieve_string(node, "peer/name"), "test_peer_data_provider")) {
14464 ao2_unlink(peers, peer);
14465 peer_unref(peer);
14466 ast_data_free(node);
14467 return AST_TEST_FAIL;
14468 }
14469
14470 if (ast_data_retrieve_int(node, "peer/expiry") != 1010) {
14471 ao2_unlink(peers, peer);
14472 peer_unref(peer);
14473 ast_data_free(node);
14474 return AST_TEST_FAIL;
14475 }
14476
14477
14478 ast_data_free(node);
14479
14480 ao2_unlink(peers, peer);
14481 peer_unref(peer);
14482
14483 return AST_TEST_PASS;
14484 }
14485
14486 AST_TEST_DEFINE(test_iax2_users_get)
14487 {
14488 struct ast_data_query query = {
14489 .path = "/asterisk/channel/iax2/users",
14490 .search = "users/user/name=test_user_data_provider"
14491 };
14492 struct ast_data *node;
14493 struct iax2_user *user;
14494
14495 switch (cmd) {
14496 case TEST_INIT:
14497 info->name = "iax2_users_get_data_test";
14498 info->category = "/main/data/iax2/users/";
14499 info->summary = "IAX2 users data providers unit test";
14500 info->description =
14501 "Tests whether the IAX2 users data provider implementation works as expected.";
14502 return AST_TEST_NOT_RUN;
14503 case TEST_EXECUTE:
14504 break;
14505 }
14506
14507 user = build_user("test_user_data_provider", NULL, NULL, 0);
14508 if (!user) {
14509 ast_test_status_update(test, "Failed to build a test user\n");
14510 return AST_TEST_FAIL;
14511 }
14512 user->amaflags = 1010;
14513 ao2_link(users, user);
14514
14515 node = ast_data_get(&query);
14516 if (!node) {
14517 ast_test_status_update(test, "The data query to find our test user failed\n");
14518 ao2_unlink(users, user);
14519 user_unref(user);
14520 return AST_TEST_FAIL;
14521 }
14522
14523 if (strcmp(ast_data_retrieve_string(node, "user/name"), "test_user_data_provider")) {
14524 ast_test_status_update(test, "Our data results did not return the test user created in the previous step.\n");
14525 ao2_unlink(users, user);
14526 user_unref(user);
14527 ast_data_free(node);
14528 return AST_TEST_FAIL;
14529 }
14530
14531 if (ast_data_retrieve_int(node, "user/amaflags/value") != 1010) {
14532 ast_test_status_update(test, "The amaflags field in our test user was '%d' not the expected value '1010'\n", ast_data_retrieve_int(node, "user/amaflags/value"));
14533 ao2_unlink(users, user);
14534 user_unref(user);
14535 ast_data_free(node);
14536 return AST_TEST_FAIL;
14537 }
14538
14539 ast_data_free(node);
14540
14541 ao2_unlink(users, user);
14542 user_unref(user);
14543
14544 return AST_TEST_PASS;
14545 }
14546 #endif
14547
14548 static void cleanup_thread_list(void *head)
14549 {
14550 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14551 struct iax2_thread_list *list_head = head;
14552 struct iax2_thread *thread;
14553
14554 AST_LIST_LOCK(list_head);
14555 while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) {
14556 pthread_t thread_id = thread->threadid;
14557
14558 thread->stop = 1;
14559 signal_condition(&thread->lock, &thread->cond);
14560
14561 AST_LIST_UNLOCK(list_head);
14562 pthread_join(thread_id, NULL);
14563 AST_LIST_LOCK(list_head);
14564 }
14565 AST_LIST_UNLOCK(list_head);
14566 }
14567
14568 static int __unload_module(void)
14569 {
14570 struct ast_context *con;
14571 int x;
14572
14573 network_change_event_unsubscribe();
14574
14575 ast_manager_unregister("IAXpeers");
14576 ast_manager_unregister("IAXpeerlist");
14577 ast_manager_unregister("IAXnetstats");
14578 ast_manager_unregister("IAXregistry");
14579 ast_unregister_application(papp);
14580 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14581 ast_unregister_switch(&iax2_switch);
14582 ast_channel_unregister(&iax2_tech);
14583
14584 if (netthreadid != AST_PTHREADT_NULL) {
14585 pthread_cancel(netthreadid);
14586 pthread_kill(netthreadid, SIGURG);
14587 pthread_join(netthreadid, NULL);
14588 }
14589
14590 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14591 if (iaxs[x]) {
14592 iax2_destroy(x);
14593 }
14594 }
14595
14596
14597 cleanup_thread_list(&active_list);
14598 cleanup_thread_list(&dynamic_list);
14599 cleanup_thread_list(&idle_list);
14600
14601 ast_netsock_release(netsock);
14602 ast_netsock_release(outsock);
14603 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14604 if (iaxs[x]) {
14605 iax2_destroy(x);
14606 }
14607 }
14608 ast_manager_unregister( "IAXpeers" );
14609 ast_manager_unregister( "IAXpeerlist" );
14610 ast_manager_unregister( "IAXnetstats" );
14611 ast_manager_unregister( "IAXregistry" );
14612 ast_unregister_application(papp);
14613 #ifdef TEST_FRAMEWORK
14614 AST_TEST_UNREGISTER(test_iax2_peers_get);
14615 AST_TEST_UNREGISTER(test_iax2_users_get);
14616 #endif
14617 ast_data_unregister(NULL);
14618 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14619 ast_unregister_switch(&iax2_switch);
14620 ast_channel_unregister(&iax2_tech);
14621 delete_users();
14622 iax_provision_unload();
14623 reload_firmware(1);
14624
14625 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14626 ast_mutex_destroy(&iaxsl[x]);
14627 }
14628
14629 ao2_ref(peers, -1);
14630 ao2_ref(users, -1);
14631 ao2_ref(iax_peercallno_pvts, -1);
14632 ao2_ref(iax_transfercallno_pvts, -1);
14633 ao2_ref(peercnts, -1);
14634 ao2_ref(callno_limits, -1);
14635 ao2_ref(calltoken_ignores, -1);
14636 ao2_ref(callno_pool, -1);
14637 ao2_ref(callno_pool_trunk, -1);
14638 if (timer) {
14639 ast_timer_close(timer);
14640 timer = NULL;
14641 }
14642 transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14643 sched = ast_sched_thread_destroy(sched);
14644
14645 con = ast_context_find(regcontext);
14646 if (con)
14647 ast_context_destroy(con, "IAX2");
14648 ast_unload_realtime("iaxpeers");
14649 return 0;
14650 }
14651
14652 static int unload_module(void)
14653 {
14654 ast_custom_function_unregister(&iaxpeer_function);
14655 ast_custom_function_unregister(&iaxvar_function);
14656 return __unload_module();
14657 }
14658
14659 static int peer_set_sock_cb(void *obj, void *arg, int flags)
14660 {
14661 struct iax2_peer *peer = obj;
14662
14663 if (peer->sockfd < 0)
14664 peer->sockfd = defaultsockfd;
14665
14666 return 0;
14667 }
14668
14669 static int pvt_hash_cb(const void *obj, const int flags)
14670 {
14671 const struct chan_iax2_pvt *pvt = obj;
14672
14673 return pvt->peercallno;
14674 }
14675
14676 static int pvt_cmp_cb(void *obj, void *arg, int flags)
14677 {
14678 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14679
14680
14681
14682
14683 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14684 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14685 }
14686
14687 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14688 {
14689 const struct chan_iax2_pvt *pvt = obj;
14690
14691 return pvt->transfercallno;
14692 }
14693
14694 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14695 {
14696 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14697
14698
14699
14700
14701 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14702 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14703 }
14704
14705 static int load_objects(void)
14706 {
14707 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14708 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14709
14710 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14711 goto container_fail;
14712 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14713 goto container_fail;
14714 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14715 goto container_fail;
14716 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14717 goto container_fail;
14718 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14719 goto container_fail;
14720 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14721 goto container_fail;
14722 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14723 goto container_fail;
14724 } else if (create_callno_pools()) {
14725 goto container_fail;
14726 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14727 goto container_fail;
14728 }
14729
14730 return 0;
14731
14732 container_fail:
14733 if (peers) {
14734 ao2_ref(peers, -1);
14735 }
14736 if (users) {
14737 ao2_ref(users, -1);
14738 }
14739 if (iax_peercallno_pvts) {
14740 ao2_ref(iax_peercallno_pvts, -1);
14741 }
14742 if (iax_transfercallno_pvts) {
14743 ao2_ref(iax_transfercallno_pvts, -1);
14744 }
14745 if (peercnts) {
14746 ao2_ref(peercnts, -1);
14747 }
14748 if (callno_limits) {
14749 ao2_ref(callno_limits, -1);
14750 }
14751 if (calltoken_ignores) {
14752 ao2_ref(calltoken_ignores, -1);
14753 }
14754 if (callno_pool) {
14755 ao2_ref(callno_pool, -1);
14756 }
14757 if (callno_pool_trunk) {
14758 ao2_ref(callno_pool_trunk, -1);
14759 }
14760 return AST_MODULE_LOAD_FAILURE;
14761 }
14762
14763
14764 #define DATA_EXPORT_IAX2_PEER(MEMBER) \
14765 MEMBER(iax2_peer, name, AST_DATA_STRING) \
14766 MEMBER(iax2_peer, username, AST_DATA_STRING) \
14767 MEMBER(iax2_peer, secret, AST_DATA_PASSWORD) \
14768 MEMBER(iax2_peer, dbsecret, AST_DATA_PASSWORD) \
14769 MEMBER(iax2_peer, outkey, AST_DATA_STRING) \
14770 MEMBER(iax2_peer, regexten, AST_DATA_STRING) \
14771 MEMBER(iax2_peer, context, AST_DATA_STRING) \
14772 MEMBER(iax2_peer, peercontext, AST_DATA_STRING) \
14773 MEMBER(iax2_peer, mailbox, AST_DATA_STRING) \
14774 MEMBER(iax2_peer, mohinterpret, AST_DATA_STRING) \
14775 MEMBER(iax2_peer, mohsuggest, AST_DATA_STRING) \
14776 MEMBER(iax2_peer, inkeys, AST_DATA_STRING) \
14777 MEMBER(iax2_peer, cid_num, AST_DATA_STRING) \
14778 MEMBER(iax2_peer, cid_name, AST_DATA_STRING) \
14779 MEMBER(iax2_peer, zonetag, AST_DATA_STRING) \
14780 MEMBER(iax2_peer, parkinglot, AST_DATA_STRING) \
14781 MEMBER(iax2_peer, expiry, AST_DATA_SECONDS) \
14782 MEMBER(iax2_peer, callno, AST_DATA_INTEGER) \
14783 MEMBER(iax2_peer, lastms, AST_DATA_MILLISECONDS) \
14784 MEMBER(iax2_peer, maxms, AST_DATA_MILLISECONDS) \
14785 MEMBER(iax2_peer, pokefreqok, AST_DATA_MILLISECONDS) \
14786 MEMBER(iax2_peer, pokefreqnotok, AST_DATA_MILLISECONDS) \
14787 MEMBER(iax2_peer, historicms, AST_DATA_INTEGER) \
14788 MEMBER(iax2_peer, smoothing, AST_DATA_BOOLEAN) \
14789 MEMBER(iax2_peer, maxcallno, AST_DATA_INTEGER)
14790
14791 AST_DATA_STRUCTURE(iax2_peer, DATA_EXPORT_IAX2_PEER);
14792
14793 static int peers_data_provider_get(const struct ast_data_search *search,
14794 struct ast_data *data_root)
14795 {
14796 struct ast_data *data_peer;
14797 struct iax2_peer *peer;
14798 struct ao2_iterator i;
14799 char status[20];
14800 struct ast_str *encmethods = ast_str_alloca(256);
14801
14802 i = ao2_iterator_init(peers, 0);
14803 while ((peer = ao2_iterator_next(&i))) {
14804 data_peer = ast_data_add_node(data_root, "peer");
14805 if (!data_peer) {
14806 peer_unref(peer);
14807 continue;
14808 }
14809
14810 ast_data_add_structure(iax2_peer, data_peer, peer);
14811
14812 ast_data_add_codecs(data_peer, "codecs", peer->capability);
14813
14814 peer_status(peer, status, sizeof(status));
14815 ast_data_add_str(data_peer, "status", status);
14816
14817 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14818
14819 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14820
14821 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14822
14823 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14824
14825 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14826
14827 encmethods_to_str(peer->encmethods, &encmethods);
14828 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14829
14830 peer_unref(peer);
14831
14832 if (!ast_data_search_match(search, data_peer)) {
14833 ast_data_remove_node(data_root, data_peer);
14834 }
14835 }
14836 ao2_iterator_destroy(&i);
14837
14838 return 0;
14839 }
14840
14841 #define DATA_EXPORT_IAX2_USER(MEMBER) \
14842 MEMBER(iax2_user, name, AST_DATA_STRING) \
14843 MEMBER(iax2_user, dbsecret, AST_DATA_PASSWORD) \
14844 MEMBER(iax2_user, accountcode, AST_DATA_STRING) \
14845 MEMBER(iax2_user, mohinterpret, AST_DATA_STRING) \
14846 MEMBER(iax2_user, mohsuggest, AST_DATA_STRING) \
14847 MEMBER(iax2_user, inkeys, AST_DATA_STRING) \
14848 MEMBER(iax2_user, language, AST_DATA_STRING) \
14849 MEMBER(iax2_user, cid_num, AST_DATA_STRING) \
14850 MEMBER(iax2_user, cid_name, AST_DATA_STRING) \
14851 MEMBER(iax2_user, parkinglot, AST_DATA_STRING) \
14852 MEMBER(iax2_user, maxauthreq, AST_DATA_INTEGER) \
14853 MEMBER(iax2_user, curauthreq, AST_DATA_INTEGER)
14854
14855 AST_DATA_STRUCTURE(iax2_user, DATA_EXPORT_IAX2_USER);
14856
14857 static int users_data_provider_get(const struct ast_data_search *search,
14858 struct ast_data *data_root)
14859 {
14860 struct ast_data *data_user, *data_authmethods, *data_enum_node;
14861 struct iax2_user *user;
14862 struct ao2_iterator i;
14863 char auth[90];
14864 char *pstr = "";
14865
14866 i = ao2_iterator_init(users, 0);
14867 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14868 data_user = ast_data_add_node(data_root, "user");
14869 if (!data_user) {
14870 continue;
14871 }
14872
14873 ast_data_add_structure(iax2_user, data_user, user);
14874
14875 ast_data_add_codecs(data_user, "codecs", user->capability);
14876
14877 if (!ast_strlen_zero(user->secret)) {
14878 ast_copy_string(auth, user->secret, sizeof(auth));
14879 } else if (!ast_strlen_zero(user->inkeys)) {
14880 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14881 } else {
14882 ast_copy_string(auth, "no secret", sizeof(auth));
14883 }
14884 ast_data_add_password(data_user, "secret", auth);
14885
14886 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14887
14888
14889 data_authmethods = ast_data_add_node(data_user, "authmethods");
14890 if (!data_authmethods) {
14891 ast_data_remove_node(data_root, data_user);
14892 continue;
14893 }
14894 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14895 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14896 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14897
14898
14899 data_enum_node = ast_data_add_node(data_user, "amaflags");
14900 if (!data_enum_node) {
14901 ast_data_remove_node(data_root, data_user);
14902 continue;
14903 }
14904 ast_data_add_int(data_enum_node, "value", user->amaflags);
14905 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14906
14907 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14908
14909 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14910 pstr = "REQ only";
14911 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14912 pstr = "disabled";
14913 } else {
14914 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14915 }
14916 ast_data_add_str(data_user, "codec-preferences", pstr);
14917
14918 if (!ast_data_search_match(search, data_user)) {
14919 ast_data_remove_node(data_root, data_user);
14920 }
14921 }
14922 ao2_iterator_destroy(&i);
14923
14924 return 0;
14925 }
14926
14927 static const struct ast_data_handler peers_data_provider = {
14928 .version = AST_DATA_HANDLER_VERSION,
14929 .get = peers_data_provider_get
14930 };
14931
14932 static const struct ast_data_handler users_data_provider = {
14933 .version = AST_DATA_HANDLER_VERSION,
14934 .get = users_data_provider_get
14935 };
14936
14937 static const struct ast_data_entry iax2_data_providers[] = {
14938 AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
14939 AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
14940 };
14941
14942
14943 static int load_module(void)
14944 {
14945 static const char config[] = "iax.conf";
14946 int x = 0;
14947 struct iax2_registry *reg = NULL;
14948
14949 if (load_objects()) {
14950 return AST_MODULE_LOAD_FAILURE;
14951 }
14952
14953 memset(iaxs, 0, sizeof(iaxs));
14954
14955 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14956 ast_mutex_init(&iaxsl[x]);
14957 }
14958
14959 if (!(sched = ast_sched_thread_create())) {
14960 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14961 return AST_MODULE_LOAD_FAILURE;
14962 }
14963
14964 if (!(io = io_context_create())) {
14965 ast_log(LOG_ERROR, "Failed to create I/O context\n");
14966 sched = ast_sched_thread_destroy(sched);
14967 return AST_MODULE_LOAD_FAILURE;
14968 }
14969
14970 if (!(netsock = ast_netsock_list_alloc())) {
14971 ast_log(LOG_ERROR, "Failed to create netsock list\n");
14972 io_context_destroy(io);
14973 sched = ast_sched_thread_destroy(sched);
14974 return AST_MODULE_LOAD_FAILURE;
14975 }
14976 ast_netsock_init(netsock);
14977
14978 outsock = ast_netsock_list_alloc();
14979 if (!outsock) {
14980 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14981 io_context_destroy(io);
14982 sched = ast_sched_thread_destroy(sched);
14983 return AST_MODULE_LOAD_FAILURE;
14984 }
14985 ast_netsock_init(outsock);
14986
14987 randomcalltokendata = ast_random();
14988
14989 iax_set_output(iax_debug_output);
14990 iax_set_error(iax_error_output);
14991 jb_setoutput(jb_error_output, jb_warning_output, NULL);
14992
14993 if ((timer = ast_timer_open())) {
14994 ast_timer_set_rate(timer, 1000 / trunkfreq);
14995 }
14996
14997 if (set_config(config, 0) == -1) {
14998 if (timer) {
14999 ast_timer_close(timer);
15000 timer = NULL;
15001 }
15002 return AST_MODULE_LOAD_DECLINE;
15003 }
15004
15005 #ifdef TEST_FRAMEWORK
15006 AST_TEST_REGISTER(test_iax2_peers_get);
15007 AST_TEST_REGISTER(test_iax2_users_get);
15008 #endif
15009
15010
15011 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
15012 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
15013
15014 ast_register_application_xml(papp, iax2_prov_app);
15015
15016 ast_custom_function_register(&iaxpeer_function);
15017 ast_custom_function_register(&iaxvar_function);
15018
15019 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
15020 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
15021 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
15022 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
15023
15024 if (ast_channel_register(&iax2_tech)) {
15025 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
15026 __unload_module();
15027 return AST_MODULE_LOAD_FAILURE;
15028 }
15029
15030 if (ast_register_switch(&iax2_switch)) {
15031 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
15032 }
15033
15034 if (start_network_thread()) {
15035 ast_log(LOG_ERROR, "Unable to start network thread\n");
15036 __unload_module();
15037 return AST_MODULE_LOAD_FAILURE;
15038 } else {
15039 ast_verb(2, "IAX Ready and Listening\n");
15040 }
15041
15042 AST_LIST_LOCK(®istrations);
15043 AST_LIST_TRAVERSE(®istrations, reg, entry)
15044 iax2_do_register(reg);
15045 AST_LIST_UNLOCK(®istrations);
15046
15047 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
15048 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
15049
15050
15051 reload_firmware(0);
15052 iax_provision_reload(0);
15053
15054 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
15055
15056 network_change_event_subscribe();
15057
15058 return AST_MODULE_LOAD_SUCCESS;
15059 }
15060
15061 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
15062 .load = load_module,
15063 .unload = unload_module,
15064 .reload = reload,
15065 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
15066 .nonoptreq = "res_crypto",
15067 );