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: 413586 $")
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) 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 = %u\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, 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 %u 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 = %u, subclass = %d, ts=%u, 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", (unsigned long)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 %d: 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 (%d) > max (%d), 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 - %ums\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 %u 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, (unsigned)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, (unsigned)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=%u, 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=%u, 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=%u, 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=%u, 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=%u, 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=%u, 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 int usedchans = 0;
07288 char first_message[10] = { 0, };
07289 char last_message[10] = { 0, };
07290
07291 switch (cmd) {
07292 case CLI_INIT:
07293 e->command = "iax2 show channels";
07294 e->usage =
07295 "Usage: iax2 show channels\n"
07296 " Lists all currently active IAX channels.\n";
07297 return NULL;
07298 case CLI_GENERATE:
07299 return NULL;
07300 }
07301
07302 if (a->argc != 3)
07303 return CLI_SHOWUSAGE;
07304 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07305 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07306 ast_mutex_lock(&iaxsl[x]);
07307 if (iaxs[x]) {
07308 int lag, jitter, localdelay;
07309 jb_info jbinfo;
07310 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07311 jb_getinfo(iaxs[x]->jb, &jbinfo);
07312 jitter = jbinfo.jitter;
07313 localdelay = jbinfo.current - jbinfo.min;
07314 } else {
07315 jitter = -1;
07316 localdelay = 0;
07317 }
07318
07319 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07320 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07321 lag = iaxs[x]->remote_rr.delay;
07322 ast_cli(a->fd, FORMAT,
07323 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07324 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07325 S_OR(iaxs[x]->username, "(None)"),
07326 iaxs[x]->callno, iaxs[x]->peercallno,
07327 iaxs[x]->oseqno, iaxs[x]->iseqno,
07328 lag,
07329 jitter,
07330 localdelay,
07331 ast_getformatname(iaxs[x]->voiceformat),
07332 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07333 first_message,
07334 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07335 last_message);
07336 numchans++;
07337 if (iaxs[x]->owner) {
07338 usedchans++;
07339 }
07340 }
07341 ast_mutex_unlock(&iaxsl[x]);
07342 }
07343 ast_cli(a->fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : "");
07344 ast_cli(a->fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : "");
07345
07346 return CLI_SUCCESS;
07347 #undef FORMAT
07348 #undef FORMAT2
07349 #undef FORMATB
07350 }
07351
07352 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
07353 {
07354 int x;
07355 int numchans = 0;
07356 char first_message[10] = { 0, };
07357 char last_message[10] = { 0, };
07358 #define ACN_FORMAT1 "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
07359 #define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07360 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07361 ast_mutex_lock(&iaxsl[x]);
07362 if (iaxs[x]) {
07363 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07364 jb_info jbinfo;
07365 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07366 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07367
07368 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07369 jb_getinfo(iaxs[x]->jb, &jbinfo);
07370 localjitter = jbinfo.jitter;
07371 localdelay = jbinfo.current - jbinfo.min;
07372 locallost = jbinfo.frames_lost;
07373 locallosspct = jbinfo.losspct/1000;
07374 localdropped = jbinfo.frames_dropped;
07375 localooo = jbinfo.frames_ooo;
07376 } else {
07377 localjitter = -1;
07378 localdelay = 0;
07379 locallost = -1;
07380 locallosspct = -1;
07381 localdropped = 0;
07382 localooo = -1;
07383 }
07384 if (s)
07385 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07386 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07387 iaxs[x]->pingtime,
07388 localjitter,
07389 localdelay,
07390 locallost,
07391 locallosspct,
07392 localdropped,
07393 localooo,
07394 iaxs[x]->frames_received/1000,
07395 iaxs[x]->remote_rr.jitter,
07396 iaxs[x]->remote_rr.delay,
07397 iaxs[x]->remote_rr.losscnt,
07398 iaxs[x]->remote_rr.losspct,
07399 iaxs[x]->remote_rr.dropped,
07400 iaxs[x]->remote_rr.ooo,
07401 iaxs[x]->remote_rr.packets/1000,
07402 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07403 first_message,
07404 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07405 last_message);
07406 else
07407 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07408 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07409 iaxs[x]->pingtime,
07410 localjitter,
07411 localdelay,
07412 locallost,
07413 locallosspct,
07414 localdropped,
07415 localooo,
07416 iaxs[x]->frames_received/1000,
07417 iaxs[x]->remote_rr.jitter,
07418 iaxs[x]->remote_rr.delay,
07419 iaxs[x]->remote_rr.losscnt,
07420 iaxs[x]->remote_rr.losspct,
07421 iaxs[x]->remote_rr.dropped,
07422 iaxs[x]->remote_rr.ooo,
07423 iaxs[x]->remote_rr.packets/1000,
07424 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07425 first_message,
07426 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07427 last_message);
07428 numchans++;
07429 }
07430 ast_mutex_unlock(&iaxsl[x]);
07431 }
07432
07433 return numchans;
07434 }
07435
07436 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07437 {
07438 int numchans = 0;
07439
07440 switch (cmd) {
07441 case CLI_INIT:
07442 e->command = "iax2 show netstats";
07443 e->usage =
07444 "Usage: iax2 show netstats\n"
07445 " Lists network status for all currently active IAX channels.\n";
07446 return NULL;
07447 case CLI_GENERATE:
07448 return NULL;
07449 }
07450 if (a->argc != 3)
07451 return CLI_SHOWUSAGE;
07452 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07453 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07454 numchans = ast_cli_netstats(NULL, a->fd, 1);
07455 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07456 return CLI_SUCCESS;
07457 }
07458
07459 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07460 {
07461 switch (cmd) {
07462 case CLI_INIT:
07463 e->command = "iax2 set debug {on|off|peer}";
07464 e->usage =
07465 "Usage: iax2 set debug {on|off|peer peername}\n"
07466 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07467 return NULL;
07468 case CLI_GENERATE:
07469 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07470 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07471 return NULL;
07472 }
07473
07474 if (a->argc < e->args || a->argc > e->args + 1)
07475 return CLI_SHOWUSAGE;
07476
07477 if (!strcasecmp(a->argv[3], "peer")) {
07478 struct iax2_peer *peer;
07479 struct sockaddr_in peer_addr;
07480
07481
07482 if (a->argc != e->args + 1)
07483 return CLI_SHOWUSAGE;
07484
07485 peer = find_peer(a->argv[4], 1);
07486
07487 if (!peer) {
07488 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07489 return CLI_FAILURE;
07490 }
07491
07492 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07493
07494 debugaddr.sin_addr = peer_addr.sin_addr;
07495 debugaddr.sin_port = peer_addr.sin_port;
07496
07497 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07498 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07499
07500 ao2_ref(peer, -1);
07501 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07502 iaxdebug = 1;
07503 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07504 } else {
07505 iaxdebug = 0;
07506 memset(&debugaddr, 0, sizeof(debugaddr));
07507 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07508 }
07509 return CLI_SUCCESS;
07510 }
07511
07512 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07513 {
07514 switch (cmd) {
07515 case CLI_INIT:
07516 e->command = "iax2 set debug trunk {on|off}";
07517 e->usage =
07518 "Usage: iax2 set debug trunk {on|off}\n"
07519 " Enables/Disables debugging of IAX trunking\n";
07520 return NULL;
07521 case CLI_GENERATE:
07522 return NULL;
07523 }
07524
07525 if (a->argc != e->args)
07526 return CLI_SHOWUSAGE;
07527
07528 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07529 iaxtrunkdebug = 1;
07530 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07531 } else {
07532 iaxtrunkdebug = 0;
07533 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07534 }
07535 return CLI_SUCCESS;
07536 }
07537
07538 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07539 {
07540 switch (cmd) {
07541 case CLI_INIT:
07542 e->command = "iax2 set debug jb {on|off}";
07543 e->usage =
07544 "Usage: iax2 set debug jb {on|off}\n"
07545 " Enables/Disables jitterbuffer debugging information\n";
07546 return NULL;
07547 case CLI_GENERATE:
07548 return NULL;
07549 }
07550
07551 if (a->argc != e->args)
07552 return CLI_SHOWUSAGE;
07553
07554 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07555 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07556 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07557 } else {
07558 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07559 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07560 }
07561 return CLI_SUCCESS;
07562 }
07563
07564 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07565 {
07566 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07567 int res = -1;
07568 ast_mutex_lock(&iaxsl[callno]);
07569 if (iaxs[callno]) {
07570
07571 if (!iaxs[callno]->error) {
07572 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07573 res = 0;
07574
07575 else if (f->frametype == AST_FRAME_NULL)
07576 res = 0;
07577 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07578 res = 0;
07579 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07580 res = 0;
07581 else
07582
07583 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07584 } else {
07585 ast_debug(1, "Write error: %s\n", strerror(errno));
07586 }
07587 }
07588
07589 ast_mutex_unlock(&iaxsl[callno]);
07590 return res;
07591 }
07592
07593 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07594 int now, int transfer, int final)
07595 {
07596 struct ast_frame f = { 0, };
07597 int res = 0;
07598
07599 f.frametype = type;
07600 f.subclass.integer = command;
07601 f.datalen = datalen;
07602 f.src = __FUNCTION__;
07603 f.data.ptr = (void *) data;
07604
07605 if ((res = queue_signalling(i, &f)) <= 0) {
07606 return res;
07607 }
07608
07609 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07610 }
07611
07612 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07613 {
07614 if (type == AST_FRAME_CONTROL && !iax2_is_control_frame_allowed(command)) {
07615
07616 ast_debug(2, "Callno %d: Blocked sending control frame %d.\n",
07617 i->callno, command);
07618 return 0;
07619 }
07620 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07621 }
07622
07623 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07624 {
07625 int res;
07626 ast_mutex_lock(&iaxsl[callno]);
07627 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07628 ast_mutex_unlock(&iaxsl[callno]);
07629 return res;
07630 }
07631
07632
07633
07634
07635
07636
07637 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)
07638 {
07639 int call_num = i->callno;
07640
07641 iax2_predestroy(i->callno);
07642 if (!iaxs[call_num])
07643 return -1;
07644 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07645 }
07646
07647 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)
07648 {
07649 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07650 }
07651
07652 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07653 {
07654 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07655 }
07656
07657 static int apply_context(struct iax2_context *con, const char *context)
07658 {
07659 while(con) {
07660 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07661 return -1;
07662 con = con->next;
07663 }
07664 return 0;
07665 }
07666
07667
07668 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07669 {
07670
07671 int res = -1;
07672 int version = 2;
07673 struct iax2_user *user = NULL, *best = NULL;
07674 int bestscore = 0;
07675 int gotcapability = 0;
07676 struct ast_variable *v = NULL, *tmpvar = NULL;
07677 struct ao2_iterator i;
07678 struct ast_sockaddr addr;
07679
07680 if (!iaxs[callno])
07681 return res;
07682 if (ies->called_number)
07683 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07684 if (ies->calling_number) {
07685 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07686 ast_shrink_phone_number(ies->calling_number);
07687 }
07688 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07689 }
07690 if (ies->calling_name)
07691 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07692 if (ies->calling_ani)
07693 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07694 if (ies->dnid)
07695 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07696 if (ies->rdnis)
07697 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07698 if (ies->called_context)
07699 ast_string_field_set(iaxs[callno], context, ies->called_context);
07700 if (ies->language)
07701 ast_string_field_set(iaxs[callno], language, ies->language);
07702 if (ies->username)
07703 ast_string_field_set(iaxs[callno], username, ies->username);
07704 if (ies->calling_ton > -1)
07705 iaxs[callno]->calling_ton = ies->calling_ton;
07706 if (ies->calling_tns > -1)
07707 iaxs[callno]->calling_tns = ies->calling_tns;
07708 if (ies->calling_pres > -1)
07709 iaxs[callno]->calling_pres = ies->calling_pres;
07710 if (ies->format)
07711 iaxs[callno]->peerformat = ies->format;
07712 if (ies->adsicpe)
07713 iaxs[callno]->peeradsicpe = ies->adsicpe;
07714 if (ies->capability) {
07715 gotcapability = 1;
07716 iaxs[callno]->peercapability = ies->capability;
07717 }
07718 if (ies->version)
07719 version = ies->version;
07720
07721
07722 if (ies->codec_prefs) {
07723 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07724 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07725 }
07726
07727 if (!gotcapability)
07728 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07729 if (version > IAX_PROTO_VERSION) {
07730 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07731 ast_inet_ntoa(sin->sin_addr), version);
07732 return res;
07733 }
07734
07735 ast_sockaddr_from_sin(&addr, sin);
07736 i = ao2_iterator_init(users, 0);
07737 while ((user = ao2_iterator_next(&i))) {
07738 if ((ast_strlen_zero(iaxs[callno]->username) ||
07739 !strcmp(iaxs[callno]->username, user->name))
07740 && ast_apply_ha(user->ha, &addr) == AST_SENSE_ALLOW
07741 && (ast_strlen_zero(iaxs[callno]->context) ||
07742 apply_context(user->contexts, iaxs[callno]->context))) {
07743 if (!ast_strlen_zero(iaxs[callno]->username)) {
07744
07745 if (best)
07746 user_unref(best);
07747 best = user;
07748 break;
07749 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07750
07751 if (user->ha) {
07752
07753 if (bestscore < 4) {
07754 bestscore = 4;
07755 if (best)
07756 user_unref(best);
07757 best = user;
07758 continue;
07759 }
07760 } else {
07761
07762 if (bestscore < 3) {
07763 bestscore = 3;
07764 if (best)
07765 user_unref(best);
07766 best = user;
07767 continue;
07768 }
07769 }
07770 } else {
07771 if (user->ha) {
07772
07773 if (bestscore < 2) {
07774 bestscore = 2;
07775 if (best)
07776 user_unref(best);
07777 best = user;
07778 continue;
07779 }
07780 } else {
07781
07782 if (bestscore < 1) {
07783 bestscore = 1;
07784 if (best)
07785 user_unref(best);
07786 best = user;
07787 continue;
07788 }
07789 }
07790 }
07791 }
07792 user_unref(user);
07793 }
07794 ao2_iterator_destroy(&i);
07795 user = best;
07796 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07797 user = realtime_user(iaxs[callno]->username, sin);
07798 if (user && (ast_apply_ha(user->ha, &addr) == AST_SENSE_DENY
07799 || (!ast_strlen_zero(iaxs[callno]->context) &&
07800 !apply_context(user->contexts, iaxs[callno]->context)))) {
07801 user = user_unref(user);
07802 }
07803 }
07804 if (user) {
07805
07806
07807 for (v = user->vars ; v ; v = v->next) {
07808 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07809 tmpvar->next = iaxs[callno]->vars;
07810 iaxs[callno]->vars = tmpvar;
07811 }
07812 }
07813
07814 if (user->maxauthreq > 0)
07815 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07816 iaxs[callno]->prefs = user->prefs;
07817 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07818 iaxs[callno]->encmethods = user->encmethods;
07819
07820 if (ast_strlen_zero(iaxs[callno]->username))
07821 ast_string_field_set(iaxs[callno], username, user->name);
07822
07823 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07824 iaxs[callno]->capability = user->capability;
07825
07826 if (ast_strlen_zero(iaxs[callno]->context)) {
07827 if (user->contexts)
07828 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07829 else
07830 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07831 }
07832
07833 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07834
07835 iaxs[callno]->authmethods = user->authmethods;
07836 iaxs[callno]->adsi = user->adsi;
07837
07838 if (ast_test_flag64(user, IAX_HASCALLERID)) {
07839 iaxs[callno]->calling_tns = 0;
07840 iaxs[callno]->calling_ton = 0;
07841 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07842 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07843 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07844 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07845 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07846 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07847 }
07848 if (!ast_strlen_zero(user->accountcode))
07849 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07850 if (!ast_strlen_zero(user->mohinterpret))
07851 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07852 if (!ast_strlen_zero(user->mohsuggest))
07853 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07854 if (!ast_strlen_zero(user->parkinglot))
07855 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07856 if (user->amaflags)
07857 iaxs[callno]->amaflags = user->amaflags;
07858 if (!ast_strlen_zero(user->language))
07859 ast_string_field_set(iaxs[callno], language, user->language);
07860 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
07861
07862 if (!ast_strlen_zero(user->dbsecret)) {
07863 char *family, *key=NULL;
07864 char buf[80];
07865 family = ast_strdupa(user->dbsecret);
07866 key = strchr(family, '/');
07867 if (key) {
07868 *key = '\0';
07869 key++;
07870 }
07871 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07872 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07873 else
07874 ast_string_field_set(iaxs[callno], secret, buf);
07875 } else
07876 ast_string_field_set(iaxs[callno], secret, user->secret);
07877 res = 0;
07878 user = user_unref(user);
07879 } else {
07880
07881
07882
07883
07884 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07885 ast_string_field_set(iaxs[callno], secret, "badsecret");
07886 iaxs[callno]->authrej = 1;
07887 if (!ast_strlen_zero(iaxs[callno]->username)) {
07888
07889 res = 0;
07890 }
07891 }
07892 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07893 return res;
07894 }
07895
07896 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07897 {
07898 struct ast_iax2_full_hdr fh;
07899 fh.scallno = htons(src | IAX_FLAG_FULL);
07900 fh.dcallno = htons(dst);
07901 fh.ts = 0;
07902 fh.oseqno = 0;
07903 fh.iseqno = 0;
07904 fh.type = AST_FRAME_IAX;
07905 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07906 iax_outputframe(NULL, &fh, 0, sin, 0);
07907 #if 0
07908 if (option_debug)
07909 #endif
07910 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07911 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07912 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07913 }
07914
07915 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07916 {
07917
07918 p->encmethods &= enc;
07919 if (p->encmethods) {
07920 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07921 p->keyrotateid = -2;
07922 }
07923 if (p->encmethods & IAX_ENCRYPT_AES128)
07924 p->encmethods = IAX_ENCRYPT_AES128;
07925 else
07926 p->encmethods = 0;
07927 }
07928 }
07929
07930
07931
07932
07933
07934
07935
07936 static int authenticate_request(int call_num)
07937 {
07938 struct iax_ie_data ied;
07939 int res = -1, authreq_restrict = 0;
07940 char challenge[10];
07941 struct chan_iax2_pvt *p = iaxs[call_num];
07942
07943 memset(&ied, 0, sizeof(ied));
07944
07945
07946 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07947 struct iax2_user *user, tmp_user = {
07948 .name = p->username,
07949 };
07950
07951 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07952 if (user) {
07953 if (user->curauthreq == user->maxauthreq)
07954 authreq_restrict = 1;
07955 else
07956 user->curauthreq++;
07957 user = user_unref(user);
07958 }
07959 }
07960
07961
07962 if (authreq_restrict) {
07963 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07964 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07965 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07966 return 0;
07967 }
07968
07969 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07970 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07971 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07972 ast_string_field_set(p, challenge, challenge);
07973
07974 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07975 }
07976 if (p->encmethods)
07977 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07978
07979 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07980
07981 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07982
07983 if (p->encmethods)
07984 ast_set_flag64(p, IAX_ENCRYPTED);
07985
07986 return res;
07987 }
07988
07989 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07990 {
07991 char requeststr[256];
07992 char md5secret[256] = "";
07993 char secret[256] = "";
07994 char rsasecret[256] = "";
07995 int res = -1;
07996 int x;
07997 struct iax2_user *user, tmp_user = {
07998 .name = p->username,
07999 };
08000
08001 if (p->authrej) {
08002 return res;
08003 }
08004 user = ao2_find(users, &tmp_user, OBJ_POINTER);
08005 if (user) {
08006 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
08007 ast_atomic_fetchadd_int(&user->curauthreq, -1);
08008 ast_clear_flag64(p, IAX_MAXAUTHREQ);
08009 }
08010 ast_string_field_set(p, host, user->name);
08011 user = user_unref(user);
08012 }
08013 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
08014 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n");
08015 return res;
08016 }
08017 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
08018 return res;
08019 if (ies->password)
08020 ast_copy_string(secret, ies->password, sizeof(secret));
08021 if (ies->md5_result)
08022 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
08023 if (ies->rsa_result)
08024 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
08025 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
08026 struct ast_key *key;
08027 char *keyn;
08028 char tmpkey[256];
08029 char *stringp=NULL;
08030 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
08031 stringp=tmpkey;
08032 keyn = strsep(&stringp, ":");
08033 while(keyn) {
08034 key = ast_key_get(keyn, AST_KEY_PUBLIC);
08035 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
08036 res = 0;
08037 break;
08038 } else if (!key)
08039 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
08040 keyn = strsep(&stringp, ":");
08041 }
08042 } else if (p->authmethods & IAX_AUTH_MD5) {
08043 struct MD5Context md5;
08044 unsigned char digest[16];
08045 char *tmppw, *stringp;
08046
08047 tmppw = ast_strdupa(p->secret);
08048 stringp = tmppw;
08049 while((tmppw = strsep(&stringp, ";"))) {
08050 MD5Init(&md5);
08051 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
08052 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08053 MD5Final(digest, &md5);
08054
08055 for (x=0;x<16;x++)
08056 sprintf(requeststr + (x << 1), "%2.2x", (unsigned)digest[x]);
08057 if (!strcasecmp(requeststr, md5secret)) {
08058 res = 0;
08059 break;
08060 }
08061 }
08062 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
08063 if (!strcmp(secret, p->secret))
08064 res = 0;
08065 }
08066 return res;
08067 }
08068
08069
08070 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
08071 {
08072 char requeststr[256] = "";
08073 char peer[256] = "";
08074 char md5secret[256] = "";
08075 char rsasecret[256] = "";
08076 char secret[256] = "";
08077 struct iax2_peer *p = NULL;
08078 struct ast_key *key;
08079 char *keyn;
08080 int x;
08081 int expire = 0;
08082 int res = -1;
08083 struct ast_sockaddr addr;
08084
08085 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08086
08087 if (ies->username)
08088 ast_copy_string(peer, ies->username, sizeof(peer));
08089 if (ies->password)
08090 ast_copy_string(secret, ies->password, sizeof(secret));
08091 if (ies->md5_result)
08092 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
08093 if (ies->rsa_result)
08094 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
08095 if (ies->refresh)
08096 expire = ies->refresh;
08097
08098 if (ast_strlen_zero(peer)) {
08099 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
08100 return -1;
08101 }
08102
08103
08104 ast_mutex_unlock(&iaxsl[callno]);
08105 p = find_peer(peer, 1);
08106 ast_mutex_lock(&iaxsl[callno]);
08107 if (!p || !iaxs[callno]) {
08108 if (iaxs[callno]) {
08109 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
08110
08111 ast_string_field_set(iaxs[callno], secret, "badsecret");
08112
08113
08114
08115
08116
08117
08118
08119
08120
08121 if (ast_strlen_zero(iaxs[callno]->challenge) &&
08122 !(!ast_strlen_zero(secret) && plaintext)) {
08123
08124 res = 0;
08125 }
08126 }
08127 if (authdebug && !p)
08128 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08129 goto return_unref;
08130 }
08131
08132 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
08133 if (authdebug)
08134 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08135 goto return_unref;
08136 }
08137
08138 ast_sockaddr_from_sin(&addr, sin);
08139 if (!ast_apply_ha(p->ha, &addr)) {
08140 if (authdebug)
08141 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08142 goto return_unref;
08143 }
08144 ast_string_field_set(iaxs[callno], secret, p->secret);
08145 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
08146
08147 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08148 if (!ast_strlen_zero(p->inkeys)) {
08149 char tmpkeys[256];
08150 char *stringp=NULL;
08151 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
08152 stringp=tmpkeys;
08153 keyn = strsep(&stringp, ":");
08154 while(keyn) {
08155 key = ast_key_get(keyn, AST_KEY_PUBLIC);
08156 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
08157 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08158 break;
08159 } else if (!key)
08160 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08161 keyn = strsep(&stringp, ":");
08162 }
08163 if (!keyn) {
08164 if (authdebug)
08165 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08166 goto return_unref;
08167 }
08168 } else {
08169 if (authdebug)
08170 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08171 goto return_unref;
08172 }
08173 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08174 struct MD5Context md5;
08175 unsigned char digest[16];
08176 char *tmppw, *stringp;
08177
08178 tmppw = ast_strdupa(p->secret);
08179 stringp = tmppw;
08180 while((tmppw = strsep(&stringp, ";"))) {
08181 MD5Init(&md5);
08182 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08183 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08184 MD5Final(digest, &md5);
08185 for (x=0;x<16;x++)
08186 sprintf(requeststr + (x << 1), "%2.2x", (unsigned)digest[x]);
08187 if (!strcasecmp(requeststr, md5secret))
08188 break;
08189 }
08190 if (tmppw) {
08191 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08192 } else {
08193 if (authdebug)
08194 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08195 goto return_unref;
08196 }
08197 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08198
08199 if (strcmp(secret, p->secret)) {
08200 if (authdebug)
08201 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08202 goto return_unref;
08203 } else
08204 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08205 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08206
08207 goto return_unref;
08208 }
08209 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08210
08211
08212 res = 0;
08213
08214 return_unref:
08215 if (iaxs[callno]) {
08216 ast_string_field_set(iaxs[callno], peer, peer);
08217
08218
08219 if (expire && (expire < iaxs[callno]->expiry)) {
08220 iaxs[callno]->expiry = expire;
08221 }
08222 }
08223
08224 if (p) {
08225 peer_unref(p);
08226 }
08227 return res;
08228 }
08229
08230 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)
08231 {
08232 int res = -1;
08233 int x;
08234 if (!ast_strlen_zero(keyn)) {
08235 if (!(authmethods & IAX_AUTH_RSA)) {
08236 if (ast_strlen_zero(secret))
08237 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));
08238 } else if (ast_strlen_zero(challenge)) {
08239 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08240 } else {
08241 char sig[256];
08242 struct ast_key *key;
08243 key = ast_key_get(keyn, AST_KEY_PRIVATE);
08244 if (!key) {
08245 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08246 } else {
08247 if (ast_sign(key, (char*)challenge, sig)) {
08248 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08249 res = -1;
08250 } else {
08251 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08252 res = 0;
08253 }
08254 }
08255 }
08256 }
08257
08258 if (res && !ast_strlen_zero(secret)) {
08259 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08260 struct MD5Context md5;
08261 unsigned char digest[16];
08262 char digres[128];
08263 MD5Init(&md5);
08264 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08265 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08266 MD5Final(digest, &md5);
08267
08268 for (x=0;x<16;x++)
08269 sprintf(digres + (x << 1), "%2.2x", (unsigned)digest[x]);
08270 if (pvt) {
08271 build_encryption_keys(digest, pvt);
08272 }
08273 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08274 res = 0;
08275 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08276 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08277 res = 0;
08278 } else
08279 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08280 }
08281 return res;
08282 }
08283
08284
08285
08286
08287
08288 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
08289 {
08290 struct iax2_peer *peer = NULL;
08291
08292 int res = -1;
08293 int authmethods = 0;
08294 struct iax_ie_data ied;
08295 uint16_t callno = p->callno;
08296
08297 memset(&ied, 0, sizeof(ied));
08298
08299 if (ies->username)
08300 ast_string_field_set(p, username, ies->username);
08301 if (ies->challenge)
08302 ast_string_field_set(p, challenge, ies->challenge);
08303 if (ies->authmethods)
08304 authmethods = ies->authmethods;
08305 if (authmethods & IAX_AUTH_MD5)
08306 merge_encryption(p, ies->encmethods);
08307 else
08308 p->encmethods = 0;
08309
08310
08311 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08312
08313 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08314 } else {
08315 struct ao2_iterator i = ao2_iterator_init(peers, 0);
08316 while ((peer = ao2_iterator_next(&i))) {
08317 struct sockaddr_in peer_addr;
08318
08319 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08320
08321 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08322
08323 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08324
08325 && (!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)))
08326
08327 ) {
08328 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08329 if (!res) {
08330 peer_unref(peer);
08331 break;
08332 }
08333 }
08334 peer_unref(peer);
08335 }
08336 ao2_iterator_destroy(&i);
08337 if (!peer) {
08338
08339
08340 const char *peer_name = ast_strdupa(p->peer);
08341 ast_mutex_unlock(&iaxsl[callno]);
08342 if ((peer = realtime_peer(peer_name, NULL))) {
08343 ast_mutex_lock(&iaxsl[callno]);
08344 if (!(p = iaxs[callno])) {
08345 peer_unref(peer);
08346 return -1;
08347 }
08348 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08349 peer_unref(peer);
08350 }
08351 if (!peer) {
08352 ast_mutex_lock(&iaxsl[callno]);
08353 if (!(p = iaxs[callno]))
08354 return -1;
08355 }
08356 }
08357 }
08358
08359 if (ies->encmethods) {
08360 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08361 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08362 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n");
08363 return -1;
08364 }
08365 if (!res) {
08366 struct ast_datastore *variablestore;
08367 struct ast_variable *var, *prev = NULL;
08368 AST_LIST_HEAD(, ast_var_t) *varlist;
08369 varlist = ast_calloc(1, sizeof(*varlist));
08370 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08371 if (variablestore && varlist && p->owner) {
08372 variablestore->data = varlist;
08373 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08374 AST_LIST_HEAD_INIT(varlist);
08375 for (var = ies->vars; var; var = var->next) {
08376 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08377 if (prev)
08378 ast_free(prev);
08379 prev = var;
08380 if (!newvar) {
08381
08382 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08383 } else {
08384 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08385 }
08386 }
08387 if (prev)
08388 ast_free(prev);
08389 ies->vars = NULL;
08390 ast_channel_datastore_add(p->owner, variablestore);
08391 } else {
08392 if (p->owner)
08393 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08394 if (variablestore)
08395 ast_datastore_free(variablestore);
08396 if (varlist)
08397 ast_free(varlist);
08398 }
08399 }
08400
08401 if (!res)
08402 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08403 return res;
08404 }
08405
08406 static int iax2_do_register(struct iax2_registry *reg);
08407
08408 static void __iax2_do_register_s(const void *data)
08409 {
08410 struct iax2_registry *reg = (struct iax2_registry *)data;
08411 reg->expire = -1;
08412 iax2_do_register(reg);
08413 }
08414
08415 static int iax2_do_register_s(const void *data)
08416 {
08417 #ifdef SCHED_MULTITHREADED
08418 if (schedule_action(__iax2_do_register_s, data))
08419 #endif
08420 __iax2_do_register_s(data);
08421 return 0;
08422 }
08423
08424 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08425 {
08426 int newcall = 0;
08427 char newip[256];
08428 struct iax_ie_data ied;
08429 struct sockaddr_in new = { 0, };
08430
08431 memset(&ied, 0, sizeof(ied));
08432 if (ies->apparent_addr)
08433 memmove(&new, ies->apparent_addr, sizeof(new));
08434 if (ies->callno)
08435 newcall = ies->callno;
08436 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08437 ast_log(LOG_WARNING, "Invalid transfer request\n");
08438 return -1;
08439 }
08440 pvt->transfercallno = newcall;
08441 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08442 inet_aton(newip, &pvt->transfer.sin_addr);
08443 pvt->transfer.sin_family = AF_INET;
08444 pvt->transferid = ies->transferid;
08445
08446
08447 if (pvt->transferring == TRANSFER_NONE) {
08448 store_by_transfercallno(pvt);
08449 }
08450 pvt->transferring = TRANSFER_BEGIN;
08451
08452 if (ies->transferid)
08453 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08454 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08455 return 0;
08456 }
08457
08458 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08459 {
08460 char exten[256] = "";
08461 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08462 struct iax2_dpcache *dp = NULL;
08463
08464 if (ies->called_number)
08465 ast_copy_string(exten, ies->called_number, sizeof(exten));
08466
08467 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08468 status = CACHE_FLAG_EXISTS;
08469 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08470 status = CACHE_FLAG_CANEXIST;
08471 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08472 status = CACHE_FLAG_NONEXISTENT;
08473
08474 if (ies->refresh)
08475 expiry = ies->refresh;
08476 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08477 matchmore = CACHE_FLAG_MATCHMORE;
08478
08479 AST_LIST_LOCK(&dpcache);
08480 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08481 if (strcmp(dp->exten, exten))
08482 continue;
08483 AST_LIST_REMOVE_CURRENT(peer_list);
08484 dp->callno = 0;
08485 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08486 if (dp->flags & CACHE_FLAG_PENDING) {
08487 dp->flags &= ~CACHE_FLAG_PENDING;
08488 dp->flags |= status;
08489 dp->flags |= matchmore;
08490 }
08491
08492 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08493 if (dp->waiters[x] > -1) {
08494 if (write(dp->waiters[x], "asdf", 4) < 0) {
08495 }
08496 }
08497 }
08498 }
08499 AST_LIST_TRAVERSE_SAFE_END;
08500 AST_LIST_UNLOCK(&dpcache);
08501
08502 return 0;
08503 }
08504
08505 static int complete_transfer(int callno, struct iax_ies *ies)
08506 {
08507 int peercallno = 0;
08508 struct chan_iax2_pvt *pvt = iaxs[callno];
08509 struct iax_frame *cur;
08510 jb_frame frame;
08511
08512 if (ies->callno)
08513 peercallno = ies->callno;
08514
08515 if (peercallno < 1) {
08516 ast_log(LOG_WARNING, "Invalid transfer request\n");
08517 return -1;
08518 }
08519 remove_by_transfercallno(pvt);
08520
08521
08522
08523 peercnt_remove_by_addr(&pvt->addr);
08524 peercnt_add(&pvt->transfer);
08525
08526 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08527 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08528
08529 pvt->oseqno = 0;
08530 pvt->rseqno = 0;
08531 pvt->iseqno = 0;
08532 pvt->aseqno = 0;
08533
08534 if (pvt->peercallno) {
08535 remove_by_peercallno(pvt);
08536 }
08537 pvt->peercallno = peercallno;
08538
08539 store_by_peercallno(pvt);
08540 pvt->transferring = TRANSFER_NONE;
08541 pvt->svoiceformat = -1;
08542 pvt->voiceformat = 0;
08543 pvt->svideoformat = -1;
08544 pvt->videoformat = 0;
08545 pvt->transfercallno = 0;
08546 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08547 memset(&pvt->offset, 0, sizeof(pvt->offset));
08548
08549 while(jb_getall(pvt->jb,&frame) == JB_OK)
08550 iax2_frame_free(frame.data);
08551 jb_reset(pvt->jb);
08552 pvt->lag = 0;
08553 pvt->last = 0;
08554 pvt->lastsent = 0;
08555 pvt->nextpred = 0;
08556 pvt->pingtime = DEFAULT_RETRY_TIME;
08557 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08558
08559
08560
08561 cur->retries = -1;
08562 }
08563 return 0;
08564 }
08565
08566
08567 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08568 {
08569 struct iax2_registry *reg;
08570
08571 char peer[256] = "";
08572 char msgstatus[60];
08573 int refresh = 60;
08574 char ourip[256] = "<Unspecified>";
08575 struct sockaddr_in oldus;
08576 struct sockaddr_in us;
08577 int oldmsgs;
08578 struct sockaddr_in reg_addr;
08579
08580 memset(&us, 0, sizeof(us));
08581 if (ies->apparent_addr) {
08582 memmove(&us, ies->apparent_addr, sizeof(us));
08583 }
08584 if (ies->username) {
08585 ast_copy_string(peer, ies->username, sizeof(peer));
08586 }
08587 if (ies->refresh) {
08588 refresh = ies->refresh;
08589 }
08590 if (ies->calling_number) {
08591
08592 }
08593 reg = iaxs[callno]->reg;
08594 if (!reg) {
08595 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08596 return -1;
08597 }
08598 memcpy(&oldus, ®->us, sizeof(oldus));
08599 oldmsgs = reg->messages;
08600 ast_sockaddr_to_sin(®->addr, ®_addr);
08601 if (inaddrcmp(®_addr, sin)) {
08602 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08603 return -1;
08604 }
08605 memcpy(®->us, &us, sizeof(reg->us));
08606 if (ies->msgcount >= 0) {
08607 reg->messages = ies->msgcount & 0xffff;
08608 }
08609
08610
08611
08612 reg->refresh = refresh;
08613 reg->expire = iax2_sched_replace(reg->expire, sched,
08614 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08615 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08616 if (reg->messages > 255) {
08617 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08618 } else if (reg->messages > 1) {
08619 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08620 } else if (reg->messages > 0) {
08621 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08622 } else {
08623 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08624 }
08625 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08626 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08627 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08628 }
08629 reg->regstate = REG_STATE_REGISTERED;
08630 return 0;
08631 }
08632
08633 static int iax2_append_register(const char *hostname, const char *username,
08634 const char *secret, const char *porta)
08635 {
08636 struct iax2_registry *reg;
08637
08638 if (!(reg = ast_calloc(1, sizeof(*reg))))
08639 return -1;
08640
08641 reg->addr.ss.ss_family = AF_INET;
08642 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08643 ast_free(reg);
08644 return -1;
08645 }
08646
08647 ast_copy_string(reg->username, username, sizeof(reg->username));
08648
08649 if (secret)
08650 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08651
08652 reg->expire = -1;
08653 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08654 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08655
08656 AST_LIST_LOCK(®istrations);
08657 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08658 AST_LIST_UNLOCK(®istrations);
08659
08660 return 0;
08661 }
08662
08663 static int iax2_register(const char *value, int lineno)
08664 {
08665 char copy[256];
08666 char *username, *hostname, *secret;
08667 char *porta;
08668 char *stringp=NULL;
08669
08670 if (!value)
08671 return -1;
08672
08673 ast_copy_string(copy, value, sizeof(copy));
08674 stringp = copy;
08675 username = strsep(&stringp, "@");
08676 hostname = strsep(&stringp, "@");
08677
08678 if (!hostname) {
08679 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08680 return -1;
08681 }
08682
08683 stringp = username;
08684 username = strsep(&stringp, ":");
08685 secret = strsep(&stringp, ":");
08686 stringp = hostname;
08687 hostname = strsep(&stringp, ":");
08688 porta = strsep(&stringp, ":");
08689
08690 if (porta && !atoi(porta)) {
08691 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08692 return -1;
08693 }
08694
08695 return iax2_append_register(hostname, username, secret, porta);
08696 }
08697
08698
08699 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08700 {
08701 char multi[256];
08702 char *stringp, *ext;
08703 if (!ast_strlen_zero(regcontext)) {
08704 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08705 stringp = multi;
08706 while((ext = strsep(&stringp, "&"))) {
08707 if (onoff) {
08708 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08709 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08710 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08711 } else
08712 ast_context_remove_extension(regcontext, ext, 1, NULL);
08713 }
08714 }
08715 }
08716 static void prune_peers(void);
08717
08718 static void unlink_peer(struct iax2_peer *peer)
08719 {
08720 if (peer->expire > -1) {
08721 if (!ast_sched_thread_del(sched, peer->expire)) {
08722 peer->expire = -1;
08723 peer_unref(peer);
08724 }
08725 }
08726
08727 if (peer->pokeexpire > -1) {
08728 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08729 peer->pokeexpire = -1;
08730 peer_unref(peer);
08731 }
08732 }
08733
08734 ao2_unlink(peers, peer);
08735 }
08736
08737 static void __expire_registry(const void *data)
08738 {
08739 struct iax2_peer *peer = (struct iax2_peer *) data;
08740
08741 if (!peer)
08742 return;
08743 if (peer->expire == -1) {
08744
08745 return;
08746 }
08747
08748 peer->expire = -1;
08749
08750 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08751 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08752 realtime_update_peer(peer->name, &peer->addr, 0);
08753 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08754
08755 peercnt_modify((unsigned char) 0, 0, &peer->addr);
08756
08757 memset(&peer->addr, 0, sizeof(peer->addr));
08758
08759 peer->expiry = min_reg_expire;
08760 if (!ast_test_flag64(peer, IAX_TEMPONLY))
08761 ast_db_del("IAX/Registry", peer->name);
08762 register_peer_exten(peer, 0);
08763 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
08764 if (iax2_regfunk)
08765 iax2_regfunk(peer->name, 0);
08766
08767 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08768 unlink_peer(peer);
08769
08770 peer_unref(peer);
08771 }
08772
08773 static int expire_registry(const void *data)
08774 {
08775 #ifdef SCHED_MULTITHREADED
08776 if (schedule_action(__expire_registry, data))
08777 #endif
08778 __expire_registry(data);
08779 return 0;
08780 }
08781
08782 static void reg_source_db(struct iax2_peer *p)
08783 {
08784 char data[80];
08785 char *expiry;
08786
08787 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08788 return;
08789 }
08790
08791 expiry = strrchr(data, ':');
08792 if (!expiry) {
08793 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08794 return;
08795 }
08796 *expiry++ = '\0';
08797
08798 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08799 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08800 return;
08801 }
08802
08803 p->expiry = atoi(expiry);
08804
08805 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08806 ast_sockaddr_stringify(&p->addr), p->expiry);
08807
08808 iax2_poke_peer(p, 0);
08809 if (p->expire > -1) {
08810 if (!ast_sched_thread_del(sched, p->expire)) {
08811 p->expire = -1;
08812 peer_unref(p);
08813 }
08814 }
08815
08816 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08817
08818 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08819 if (p->expire == -1) {
08820 peer_unref(p);
08821 }
08822
08823 if (iax2_regfunk) {
08824 iax2_regfunk(p->name, 1);
08825 }
08826
08827 register_peer_exten(p, 1);
08828 }
08829
08830
08831
08832
08833
08834
08835
08836 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08837 {
08838
08839 struct iax_ie_data ied = {
08840 .pos = 0,
08841 };
08842 struct iax2_peer *p;
08843 int msgcount;
08844 char data[80];
08845 int version;
08846 const char *peer_name;
08847 int res = -1;
08848 struct ast_sockaddr sockaddr;
08849
08850 ast_sockaddr_from_sin(&sockaddr, sin);
08851
08852 peer_name = ast_strdupa(iaxs[callno]->peer);
08853
08854
08855 ast_mutex_unlock(&iaxsl[callno]);
08856 if (!(p = find_peer(peer_name, 1))) {
08857 ast_mutex_lock(&iaxsl[callno]);
08858 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08859 return -1;
08860 }
08861 ast_mutex_lock(&iaxsl[callno]);
08862 if (!iaxs[callno])
08863 goto return_unref;
08864
08865 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08866 if (sin->sin_addr.s_addr) {
08867 time_t nowtime;
08868 time(&nowtime);
08869 realtime_update_peer(peer_name, &sockaddr, nowtime);
08870 } else {
08871 realtime_update_peer(peer_name, &sockaddr, 0);
08872 }
08873 }
08874
08875
08876 if (!refresh) {
08877 refresh = min_reg_expire;
08878 }
08879 if (refresh > max_reg_expire) {
08880 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08881 p->name, max_reg_expire, refresh);
08882 p->expiry = max_reg_expire;
08883 } else if (refresh < min_reg_expire) {
08884 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08885 p->name, min_reg_expire, refresh);
08886 p->expiry = min_reg_expire;
08887 } else {
08888 p->expiry = refresh;
08889 }
08890
08891 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08892 if (iax2_regfunk) {
08893 iax2_regfunk(p->name, 1);
08894 }
08895
08896
08897 peercnt_modify((unsigned char) 0, 0, &p->addr);
08898
08899
08900 ast_sockaddr_from_sin(&p->addr, sin);
08901
08902 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08903 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08904 ast_db_put("IAX/Registry", p->name, data);
08905 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08906 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08907 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08908 register_peer_exten(p, 1);
08909 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08910 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08911 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08912 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08913 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08914 register_peer_exten(p, 0);
08915 ast_db_del("IAX/Registry", p->name);
08916 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08917 }
08918
08919
08920 iax2_poke_peer(p, callno);
08921 }
08922
08923
08924 if (p->maxcallno) {
08925 peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr);
08926 }
08927
08928
08929 if (!iaxs[callno]) {
08930 res = -1;
08931 goto return_unref;
08932 }
08933
08934
08935 p->sockfd = fd;
08936
08937 if (p->expire > -1) {
08938 if (!ast_sched_thread_del(sched, p->expire)) {
08939 p->expire = -1;
08940 peer_unref(p);
08941 }
08942 }
08943
08944 if (p->expiry && sin->sin_addr.s_addr) {
08945 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08946 if (p->expire == -1)
08947 peer_unref(p);
08948 }
08949 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08950 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08951 if (sin->sin_addr.s_addr) {
08952 struct sockaddr_in peer_addr;
08953
08954 ast_sockaddr_to_sin(&p->addr, &peer_addr);
08955
08956 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08957 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08958 if (!ast_strlen_zero(p->mailbox)) {
08959 struct ast_event *event;
08960 int new, old;
08961 char *mailbox, *context;
08962
08963 context = mailbox = ast_strdupa(p->mailbox);
08964 strsep(&context, "@");
08965 if (ast_strlen_zero(context))
08966 context = "default";
08967
08968 event = ast_event_get_cached(AST_EVENT_MWI,
08969 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08970 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08971 AST_EVENT_IE_END);
08972 if (event) {
08973 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08974 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08975 ast_event_destroy(event);
08976 } else {
08977 ast_app_inboxcount(p->mailbox, &new, &old);
08978 }
08979
08980 if (new > 255) {
08981 new = 255;
08982 }
08983 if (old > 255) {
08984 old = 255;
08985 }
08986 msgcount = (old << 8) | new;
08987
08988 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08989 }
08990 if (ast_test_flag64(p, IAX_HASCALLERID)) {
08991 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08992 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08993 }
08994 }
08995 version = iax_check_version(devtype);
08996 if (version)
08997 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08998
08999 res = 0;
09000
09001 return_unref:
09002 peer_unref(p);
09003
09004 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
09005 }
09006
09007 static int registry_authrequest(int callno)
09008 {
09009 struct iax_ie_data ied;
09010 struct iax2_peer *p;
09011 char challenge[10];
09012 const char *peer_name;
09013 int sentauthmethod;
09014
09015 peer_name = ast_strdupa(iaxs[callno]->peer);
09016
09017
09018 ast_mutex_unlock(&iaxsl[callno]);
09019 if ((p = find_peer(peer_name, 1))) {
09020 last_authmethod = p->authmethods;
09021 }
09022
09023 ast_mutex_lock(&iaxsl[callno]);
09024 if (!iaxs[callno])
09025 goto return_unref;
09026
09027 memset(&ied, 0, sizeof(ied));
09028
09029
09030
09031
09032
09033
09034 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
09035 if (!p) {
09036 iaxs[callno]->authmethods = sentauthmethod;
09037 }
09038 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
09039 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
09040
09041 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
09042 ast_string_field_set(iaxs[callno], challenge, challenge);
09043 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
09044 }
09045 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
09046
09047 return_unref:
09048 if (p) {
09049 peer_unref(p);
09050 }
09051
09052 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
09053 }
09054
09055 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
09056 {
09057 struct iax2_registry *reg;
09058
09059 struct iax_ie_data ied;
09060 char peer[256] = "";
09061 char challenge[256] = "";
09062 int res;
09063 int authmethods = 0;
09064 if (ies->authmethods)
09065 authmethods = ies->authmethods;
09066 if (ies->username)
09067 ast_copy_string(peer, ies->username, sizeof(peer));
09068 if (ies->challenge)
09069 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
09070 memset(&ied, 0, sizeof(ied));
09071 reg = iaxs[callno]->reg;
09072 if (reg) {
09073 struct sockaddr_in reg_addr;
09074
09075 ast_sockaddr_to_sin(®->addr, ®_addr);
09076
09077 if (inaddrcmp(®_addr, sin)) {
09078 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
09079 return -1;
09080 }
09081 if (ast_strlen_zero(reg->secret)) {
09082 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
09083 reg->regstate = REG_STATE_NOAUTH;
09084 return -1;
09085 }
09086 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
09087 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
09088 if (reg->secret[0] == '[') {
09089 char tmpkey[256];
09090 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
09091 tmpkey[strlen(tmpkey) - 1] = '\0';
09092 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
09093 } else
09094 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
09095 if (!res) {
09096 reg->regstate = REG_STATE_AUTHSENT;
09097 add_empty_calltoken_ie(iaxs[callno], &ied);
09098 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
09099 } else
09100 return -1;
09101 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
09102 } else
09103 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
09104 return -1;
09105 }
09106
09107 static void stop_stuff(int callno)
09108 {
09109 iax2_destroy_helper(iaxs[callno]);
09110 }
09111
09112 static void __auth_reject(const void *nothing)
09113 {
09114
09115 int callno = (int)(long)(nothing);
09116 struct iax_ie_data ied;
09117 ast_mutex_lock(&iaxsl[callno]);
09118 if (iaxs[callno]) {
09119 memset(&ied, 0, sizeof(ied));
09120 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
09121 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
09122 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
09123 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
09124 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
09125 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09126 }
09127 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
09128 }
09129 ast_mutex_unlock(&iaxsl[callno]);
09130 }
09131
09132 static int auth_reject(const void *data)
09133 {
09134 int callno = (int)(long)(data);
09135 ast_mutex_lock(&iaxsl[callno]);
09136 if (iaxs[callno])
09137 iaxs[callno]->authid = -1;
09138 ast_mutex_unlock(&iaxsl[callno]);
09139 #ifdef SCHED_MULTITHREADED
09140 if (schedule_action(__auth_reject, data))
09141 #endif
09142 __auth_reject(data);
09143 return 0;
09144 }
09145
09146 static int auth_fail(int callno, int failcode)
09147 {
09148
09149
09150 if (iaxs[callno]) {
09151 iaxs[callno]->authfail = failcode;
09152 if (delayreject) {
09153 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
09154 sched, 1000, auth_reject, (void *)(long)callno);
09155 } else
09156 auth_reject((void *)(long)callno);
09157 }
09158 return 0;
09159 }
09160
09161 static void __auto_hangup(const void *nothing)
09162 {
09163
09164 int callno = (int)(long)(nothing);
09165 struct iax_ie_data ied;
09166 ast_mutex_lock(&iaxsl[callno]);
09167 if (iaxs[callno]) {
09168 memset(&ied, 0, sizeof(ied));
09169 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09170 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09171 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09172 }
09173 ast_mutex_unlock(&iaxsl[callno]);
09174 }
09175
09176 static int auto_hangup(const void *data)
09177 {
09178 int callno = (int)(long)(data);
09179 ast_mutex_lock(&iaxsl[callno]);
09180 if (iaxs[callno]) {
09181 iaxs[callno]->autoid = -1;
09182 }
09183 ast_mutex_unlock(&iaxsl[callno]);
09184 #ifdef SCHED_MULTITHREADED
09185 if (schedule_action(__auto_hangup, data))
09186 #endif
09187 __auto_hangup(data);
09188 return 0;
09189 }
09190
09191 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
09192 {
09193 struct iax_ie_data ied;
09194
09195 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
09196 sched, 30000, auto_hangup, (void *)(long)callno);
09197 memset(&ied, 0, sizeof(ied));
09198 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09199 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09200 dp->flags |= CACHE_FLAG_TRANSMITTED;
09201 }
09202
09203 static int iax2_vnak(int callno)
09204 {
09205 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09206 }
09207
09208 static void vnak_retransmit(int callno, int last)
09209 {
09210 struct iax_frame *f;
09211
09212 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09213
09214 if (((unsigned char) (f->oseqno - last) < 128) &&
09215 (f->retries >= 0)) {
09216 send_packet(f);
09217 }
09218 }
09219 }
09220
09221 static void __iax2_poke_peer_s(const void *data)
09222 {
09223 struct iax2_peer *peer = (struct iax2_peer *)data;
09224 iax2_poke_peer(peer, 0);
09225 peer_unref(peer);
09226 }
09227
09228 static int iax2_poke_peer_s(const void *data)
09229 {
09230 struct iax2_peer *peer = (struct iax2_peer *)data;
09231 peer->pokeexpire = -1;
09232 #ifdef SCHED_MULTITHREADED
09233 if (schedule_action(__iax2_poke_peer_s, data))
09234 #endif
09235 __iax2_poke_peer_s(data);
09236 return 0;
09237 }
09238
09239 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
09240 {
09241 int res = 0;
09242 struct iax_frame *fr;
09243 struct ast_iax2_meta_hdr *meta;
09244 struct ast_iax2_meta_trunk_hdr *mth;
09245 int calls = 0;
09246
09247
09248 fr = (struct iax_frame *)tpeer->trunkdata;
09249
09250 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09251 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09252 if (tpeer->trunkdatalen) {
09253
09254 meta->zeros = 0;
09255 meta->metacmd = IAX_META_TRUNK;
09256 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09257 meta->cmddata = IAX_META_TRUNK_MINI;
09258 else
09259 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09260 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09261
09262 fr->direction = DIRECTION_OUTGRESS;
09263 fr->retrans = -1;
09264 fr->transfer = 0;
09265
09266 fr->data = fr->afdata;
09267 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09268 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09269 calls = tpeer->calls;
09270 #if 0
09271 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));
09272 #endif
09273
09274 tpeer->trunkdatalen = 0;
09275 tpeer->calls = 0;
09276 }
09277 if (res < 0)
09278 return res;
09279 return calls;
09280 }
09281
09282 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
09283 {
09284
09285 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
09286 return 1;
09287 return 0;
09288 }
09289
09290 static int timing_read(int *id, int fd, short events, void *cbdata)
09291 {
09292 int res, processed = 0, totalcalls = 0;
09293 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09294 struct timeval now = ast_tvnow();
09295
09296 if (iaxtrunkdebug)
09297 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09298
09299 if (timer) {
09300 if (ast_timer_ack(timer, 1) < 0) {
09301 ast_log(LOG_ERROR, "Timer failed acknowledge\n");
09302 return 0;
09303 }
09304 }
09305
09306
09307 AST_LIST_LOCK(&tpeers);
09308 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09309 processed++;
09310 res = 0;
09311 ast_mutex_lock(&tpeer->lock);
09312
09313
09314 if (!drop && iax2_trunk_expired(tpeer, &now)) {
09315
09316
09317 AST_LIST_REMOVE_CURRENT(list);
09318 drop = tpeer;
09319 } else {
09320 res = send_trunk(tpeer, &now);
09321 trunk_timed++;
09322 if (iaxtrunkdebug)
09323 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %u bytes backloged and has hit a high water mark of %u bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
09324 }
09325 totalcalls += res;
09326 res = 0;
09327 ast_mutex_unlock(&tpeer->lock);
09328 }
09329 AST_LIST_TRAVERSE_SAFE_END;
09330 AST_LIST_UNLOCK(&tpeers);
09331
09332 if (drop) {
09333 ast_mutex_lock(&drop->lock);
09334
09335
09336 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09337 if (drop->trunkdata) {
09338 ast_free(drop->trunkdata);
09339 drop->trunkdata = NULL;
09340 }
09341 ast_mutex_unlock(&drop->lock);
09342 ast_mutex_destroy(&drop->lock);
09343 ast_free(drop);
09344
09345 }
09346
09347 if (iaxtrunkdebug)
09348 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09349 iaxtrunkdebug = 0;
09350
09351 return 1;
09352 }
09353
09354 struct dpreq_data {
09355 int callno;
09356 char context[AST_MAX_EXTENSION];
09357 char callednum[AST_MAX_EXTENSION];
09358 char *callerid;
09359 };
09360
09361 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
09362 {
09363 unsigned short dpstatus = 0;
09364 struct iax_ie_data ied1;
09365 int mm;
09366
09367 memset(&ied1, 0, sizeof(ied1));
09368 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09369
09370 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09371 dpstatus = IAX_DPSTATUS_EXISTS;
09372 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09373 dpstatus = IAX_DPSTATUS_CANEXIST;
09374 } else {
09375 dpstatus = IAX_DPSTATUS_NONEXISTENT;
09376 }
09377 if (ast_ignore_pattern(context, callednum))
09378 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09379 if (mm)
09380 dpstatus |= IAX_DPSTATUS_MATCHMORE;
09381 if (!skiplock)
09382 ast_mutex_lock(&iaxsl[callno]);
09383 if (iaxs[callno]) {
09384 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09385 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09386 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09387 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09388 }
09389 if (!skiplock)
09390 ast_mutex_unlock(&iaxsl[callno]);
09391 }
09392
09393 static void *dp_lookup_thread(void *data)
09394 {
09395
09396 struct dpreq_data *dpr = data;
09397 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09398 if (dpr->callerid)
09399 ast_free(dpr->callerid);
09400 ast_free(dpr);
09401 return NULL;
09402 }
09403
09404 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
09405 {
09406 pthread_t newthread;
09407 struct dpreq_data *dpr;
09408
09409 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09410 return;
09411
09412 dpr->callno = callno;
09413 ast_copy_string(dpr->context, context, sizeof(dpr->context));
09414 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09415 if (callerid)
09416 dpr->callerid = ast_strdup(callerid);
09417 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09418 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09419 }
09420 }
09421
09422 struct iax_dual {
09423 struct ast_channel *chan1;
09424 struct ast_channel *chan2;
09425 char *park_exten;
09426 char *park_context;
09427 };
09428
09429 static void *iax_park_thread(void *stuff)
09430 {
09431 struct iax_dual *d;
09432 int res;
09433 int ext = 0;
09434
09435 d = stuff;
09436
09437 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09438 d->chan2->name, d->chan1->name);
09439
09440 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09441 if (res) {
09442
09443 ast_hangup(d->chan1);
09444 } else {
09445 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09446 }
09447 ast_hangup(d->chan2);
09448
09449 ast_free(d->park_exten);
09450 ast_free(d->park_context);
09451 ast_free(d);
09452 return NULL;
09453 }
09454
09455
09456 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
09457 {
09458 struct iax_dual *d;
09459 struct ast_channel *chan1m, *chan2m;
09460 pthread_t th;
09461
09462 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09463 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09464 d = ast_calloc(1, sizeof(*d));
09465 if (!chan1m || !chan2m || !d) {
09466 if (chan1m) {
09467 ast_hangup(chan1m);
09468 }
09469 if (chan2m) {
09470 ast_hangup(chan2m);
09471 }
09472 ast_free(d);
09473 return -1;
09474 }
09475 d->park_exten = ast_strdup(park_exten);
09476 d->park_context = ast_strdup(park_context);
09477 if (!d->park_exten || !d->park_context) {
09478 ast_hangup(chan1m);
09479 ast_hangup(chan2m);
09480 ast_free(d->park_exten);
09481 ast_free(d->park_context);
09482 ast_free(d);
09483 return -1;
09484 }
09485
09486
09487 chan1m->readformat = chan1->readformat;
09488 chan1m->writeformat = chan1->writeformat;
09489
09490
09491 if (ast_channel_masquerade(chan1m, chan1)) {
09492 ast_hangup(chan1m);
09493 ast_hangup(chan2m);
09494 ast_free(d->park_exten);
09495 ast_free(d->park_context);
09496 ast_free(d);
09497 return -1;
09498 }
09499
09500
09501 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09502 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09503 chan1m->priority = chan1->priority;
09504
09505 ast_do_masquerade(chan1m);
09506
09507
09508
09509
09510
09511 chan2m->readformat = chan2->readformat;
09512 chan2m->writeformat = chan2->writeformat;
09513 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot);
09514
09515
09516 if (ast_channel_masquerade(chan2m, chan2)) {
09517 ast_hangup(chan1m);
09518 ast_hangup(chan2m);
09519 ast_free(d->park_exten);
09520 ast_free(d->park_context);
09521 ast_free(d);
09522 return -1;
09523 }
09524
09525
09526 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09527 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09528 chan2m->priority = chan2->priority;
09529
09530 ast_do_masquerade(chan2m);
09531
09532 d->chan1 = chan1m;
09533 d->chan2 = chan2m;
09534 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09535
09536 ast_hangup(chan1m);
09537 ast_hangup(chan2m);
09538 ast_free(d->park_exten);
09539 ast_free(d->park_context);
09540 ast_free(d);
09541 return -1;
09542 }
09543 return 0;
09544 }
09545
09546 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09547 {
09548 unsigned int ourver;
09549 char rsi[80];
09550 snprintf(rsi, sizeof(rsi), "si-%s", si);
09551 if (iax_provision_version(&ourver, rsi, 1))
09552 return 0;
09553 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09554 if (ourver != ver)
09555 iax2_provision(sin, sockfd, NULL, rsi, 1);
09556 return 0;
09557 }
09558
09559 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09560 {
09561 jb_info stats;
09562 jb_getinfo(pvt->jb, &stats);
09563
09564 memset(iep, 0, sizeof(*iep));
09565
09566 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09567 if(stats.frames_in == 0) stats.frames_in = 1;
09568 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09569 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09570 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09571 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09572 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09573 }
09574
09575 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09576 {
09577 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09578 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09579 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09580 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09581 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09582 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09583 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09584 }
09585
09586 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09587 {
09588 int i;
09589 unsigned int length, offset = 0;
09590 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09591
09592 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09593 length = ies->ospblocklength[i];
09594 if (length != 0) {
09595 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09596
09597 offset = 0;
09598 break;
09599 } else {
09600 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09601 offset += length;
09602 }
09603 } else {
09604 break;
09605 }
09606 }
09607 *(full_osptoken + offset) = '\0';
09608 if (strlen(full_osptoken) != offset) {
09609
09610 *full_osptoken = '\0';
09611 }
09612
09613 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09614 }
09615
09616 static void log_jitterstats(unsigned short callno)
09617 {
09618 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09619 jb_info jbinfo;
09620
09621 ast_mutex_lock(&iaxsl[callno]);
09622 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09623 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09624 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09625 localjitter = jbinfo.jitter;
09626 localdelay = jbinfo.current - jbinfo.min;
09627 locallost = jbinfo.frames_lost;
09628 locallosspct = jbinfo.losspct/1000;
09629 localdropped = jbinfo.frames_dropped;
09630 localooo = jbinfo.frames_ooo;
09631 localpackets = jbinfo.frames_in;
09632 }
09633 ast_debug(3, "JB STATS:%s ping=%u 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",
09634 iaxs[callno]->owner->name,
09635 iaxs[callno]->pingtime,
09636 localjitter,
09637 localdelay,
09638 locallost,
09639 locallosspct,
09640 localdropped,
09641 localooo,
09642 localpackets,
09643 iaxs[callno]->remote_rr.jitter,
09644 iaxs[callno]->remote_rr.delay,
09645 iaxs[callno]->remote_rr.losscnt,
09646 iaxs[callno]->remote_rr.losspct/1000,
09647 iaxs[callno]->remote_rr.dropped,
09648 iaxs[callno]->remote_rr.ooo,
09649 iaxs[callno]->remote_rr.packets);
09650 manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %u\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",
09651 iaxs[callno]->owner->name,
09652 iaxs[callno]->pingtime,
09653 localjitter,
09654 localdelay,
09655 locallost,
09656 locallosspct,
09657 localdropped,
09658 localooo,
09659 localpackets,
09660 iaxs[callno]->remote_rr.jitter,
09661 iaxs[callno]->remote_rr.delay,
09662 iaxs[callno]->remote_rr.losscnt,
09663 iaxs[callno]->remote_rr.losspct/1000,
09664 iaxs[callno]->remote_rr.dropped,
09665 iaxs[callno]->remote_rr.ooo,
09666 iaxs[callno]->remote_rr.packets);
09667 }
09668 ast_mutex_unlock(&iaxsl[callno]);
09669 }
09670
09671 static int socket_process(struct iax2_thread *thread);
09672
09673
09674
09675
09676 static void handle_deferred_full_frames(struct iax2_thread *thread)
09677 {
09678 struct iax2_pkt_buf *pkt_buf;
09679
09680 ast_mutex_lock(&thread->lock);
09681
09682 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09683 ast_mutex_unlock(&thread->lock);
09684
09685 thread->buf = pkt_buf->buf;
09686 thread->buf_len = pkt_buf->len;
09687 thread->buf_size = pkt_buf->len + 1;
09688
09689 socket_process(thread);
09690
09691 thread->buf = NULL;
09692 ast_free(pkt_buf);
09693
09694 ast_mutex_lock(&thread->lock);
09695 }
09696
09697 ast_mutex_unlock(&thread->lock);
09698 }
09699
09700
09701
09702
09703
09704
09705
09706 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09707 {
09708 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09709 struct ast_iax2_full_hdr *fh, *cur_fh;
09710
09711 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09712 return;
09713
09714 pkt_buf->len = from_here->buf_len;
09715 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09716
09717 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09718 ast_mutex_lock(&to_here->lock);
09719 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09720 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09721 if (fh->oseqno < cur_fh->oseqno) {
09722 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09723 break;
09724 }
09725 }
09726 AST_LIST_TRAVERSE_SAFE_END
09727
09728 if (!cur_pkt_buf)
09729 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09730
09731 to_here->iostate = IAX_IOSTATE_READY;
09732 ast_cond_signal(&to_here->cond);
09733
09734 ast_mutex_unlock(&to_here->lock);
09735 }
09736
09737 static int socket_read(int *id, int fd, short events, void *cbdata)
09738 {
09739 struct iax2_thread *thread;
09740 socklen_t len;
09741 time_t t;
09742 static time_t last_errtime = 0;
09743 struct ast_iax2_full_hdr *fh;
09744
09745 if (!(thread = find_idle_thread())) {
09746 time(&t);
09747 if (t != last_errtime) {
09748 last_errtime = t;
09749 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09750 }
09751 usleep(1);
09752 return 1;
09753 }
09754
09755 len = sizeof(thread->iosin);
09756 thread->iofd = fd;
09757 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09758 thread->buf_size = sizeof(thread->readbuf);
09759 thread->buf = thread->readbuf;
09760 if (thread->buf_len < 0) {
09761 if (errno != ECONNREFUSED && errno != EAGAIN)
09762 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09763 handle_error();
09764 thread->iostate = IAX_IOSTATE_IDLE;
09765 signal_condition(&thread->lock, &thread->cond);
09766 return 1;
09767 }
09768 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09769 thread->iostate = IAX_IOSTATE_IDLE;
09770 signal_condition(&thread->lock, &thread->cond);
09771 return 1;
09772 }
09773
09774
09775
09776
09777 fh = (struct ast_iax2_full_hdr *) thread->buf;
09778 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09779 struct iax2_thread *cur = NULL;
09780 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09781
09782 AST_LIST_LOCK(&active_list);
09783 AST_LIST_TRAVERSE(&active_list, cur, list) {
09784 if ((cur->ffinfo.callno == callno) &&
09785 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09786 break;
09787 }
09788 if (cur) {
09789
09790
09791 defer_full_frame(thread, cur);
09792 AST_LIST_UNLOCK(&active_list);
09793 thread->iostate = IAX_IOSTATE_IDLE;
09794 signal_condition(&thread->lock, &thread->cond);
09795 return 1;
09796 } else {
09797
09798 thread->ffinfo.callno = callno;
09799 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09800 thread->ffinfo.type = fh->type;
09801 thread->ffinfo.csub = fh->csub;
09802 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09803 }
09804 AST_LIST_UNLOCK(&active_list);
09805 }
09806
09807
09808 thread->iostate = IAX_IOSTATE_READY;
09809 #ifdef DEBUG_SCHED_MULTITHREAD
09810 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09811 #endif
09812 signal_condition(&thread->lock, &thread->cond);
09813
09814 return 1;
09815 }
09816
09817 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09818 struct iax_frame *fr)
09819 {
09820 unsigned char metatype;
09821 struct ast_iax2_meta_trunk_mini *mtm;
09822 struct ast_iax2_meta_trunk_hdr *mth;
09823 struct ast_iax2_meta_trunk_entry *mte;
09824 struct iax2_trunk_peer *tpeer;
09825 unsigned int ts;
09826 void *ptr;
09827 struct timeval rxtrunktime;
09828 struct ast_frame f = { 0, };
09829
09830 if (packet_len < sizeof(*meta)) {
09831 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09832 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09833 return 1;
09834 }
09835
09836 if (meta->metacmd != IAX_META_TRUNK)
09837 return 1;
09838
09839 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09840 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09841 (int) (sizeof(*meta) + sizeof(*mth)));
09842 return 1;
09843 }
09844 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09845 ts = ntohl(mth->ts);
09846 metatype = meta->cmddata;
09847 packet_len -= (sizeof(*meta) + sizeof(*mth));
09848 ptr = mth->data;
09849 tpeer = find_tpeer(sin, sockfd);
09850 if (!tpeer) {
09851 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09852 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09853 return 1;
09854 }
09855 tpeer->trunkact = ast_tvnow();
09856 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09857 tpeer->rxtrunktime = tpeer->trunkact;
09858 rxtrunktime = tpeer->rxtrunktime;
09859 ast_mutex_unlock(&tpeer->lock);
09860 while (packet_len >= sizeof(*mte)) {
09861
09862 unsigned short callno, trunked_ts, len;
09863
09864 if (metatype == IAX_META_TRUNK_MINI) {
09865 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09866 ptr += sizeof(*mtm);
09867 packet_len -= sizeof(*mtm);
09868 len = ntohs(mtm->len);
09869 callno = ntohs(mtm->mini.callno);
09870 trunked_ts = ntohs(mtm->mini.ts);
09871 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09872 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09873 ptr += sizeof(*mte);
09874 packet_len -= sizeof(*mte);
09875 len = ntohs(mte->len);
09876 callno = ntohs(mte->callno);
09877 trunked_ts = 0;
09878 } else {
09879 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09880 break;
09881 }
09882
09883 if (len > packet_len)
09884 break;
09885 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09886 if (!fr->callno)
09887 continue;
09888
09889
09890
09891
09892 memset(&f, 0, sizeof(f));
09893 f.frametype = AST_FRAME_VOICE;
09894 if (!iaxs[fr->callno]) {
09895
09896 } else if (iaxs[fr->callno]->voiceformat == 0) {
09897 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09898 iax2_vnak(fr->callno);
09899 } else {
09900 f.subclass.codec = iaxs[fr->callno]->voiceformat;
09901 f.datalen = len;
09902 if (f.datalen >= 0) {
09903 if (f.datalen)
09904 f.data.ptr = ptr;
09905 else
09906 f.data.ptr = NULL;
09907 if (trunked_ts)
09908 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09909 else
09910 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09911
09912 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09913 struct iax_frame *duped_fr;
09914
09915
09916 f.src = "IAX2";
09917 f.mallocd = 0;
09918 f.offset = 0;
09919 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09920 f.samples = ast_codec_get_samples(&f);
09921 else
09922 f.samples = 0;
09923 fr->outoforder = 0;
09924 iax_frame_wrap(fr, &f);
09925 duped_fr = iaxfrdup2(fr);
09926 if (duped_fr)
09927 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09928 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09929 iaxs[fr->callno]->last = fr->ts;
09930 }
09931 } else {
09932 ast_log(LOG_WARNING, "Datalen < 0?\n");
09933 }
09934 }
09935 ast_mutex_unlock(&iaxsl[fr->callno]);
09936 ptr += len;
09937 packet_len -= len;
09938 }
09939
09940 return 1;
09941 }
09942
09943 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09944 {
09945 struct ast_datastore *variablestore;
09946 AST_LIST_HEAD(, ast_var_t) *varlist;
09947 struct ast_var_t *var;
09948
09949 if (!chan) {
09950 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
09951 return -1;
09952 }
09953
09954 variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09955
09956 if (!variablestore) {
09957 *buf = '\0';
09958 return 0;
09959 }
09960 varlist = variablestore->data;
09961
09962 AST_LIST_LOCK(varlist);
09963 AST_LIST_TRAVERSE(varlist, var, entries) {
09964 if (strcmp(var->name, data) == 0) {
09965 ast_copy_string(buf, var->value, len);
09966 break;
09967 }
09968 }
09969 AST_LIST_UNLOCK(varlist);
09970 return 0;
09971 }
09972
09973 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09974 {
09975 struct ast_datastore *variablestore;
09976 AST_LIST_HEAD(, ast_var_t) *varlist;
09977 struct ast_var_t *var;
09978
09979 if (!chan) {
09980 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
09981 return -1;
09982 }
09983
09984 variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09985
09986 if (!variablestore) {
09987 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09988 if (!variablestore) {
09989 ast_log(LOG_ERROR, "Memory allocation error\n");
09990 return -1;
09991 }
09992 varlist = ast_calloc(1, sizeof(*varlist));
09993 if (!varlist) {
09994 ast_datastore_free(variablestore);
09995 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09996 return -1;
09997 }
09998
09999 AST_LIST_HEAD_INIT(varlist);
10000 variablestore->data = varlist;
10001 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10002 ast_channel_datastore_add(chan, variablestore);
10003 } else
10004 varlist = variablestore->data;
10005
10006 AST_LIST_LOCK(varlist);
10007 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
10008 if (strcmp(var->name, data) == 0) {
10009 AST_LIST_REMOVE_CURRENT(entries);
10010 ast_var_delete(var);
10011 break;
10012 }
10013 }
10014 AST_LIST_TRAVERSE_SAFE_END;
10015 var = ast_var_assign(data, value);
10016 if (var)
10017 AST_LIST_INSERT_TAIL(varlist, var, entries);
10018 else
10019 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
10020 AST_LIST_UNLOCK(varlist);
10021 return 0;
10022 }
10023
10024 static struct ast_custom_function iaxvar_function = {
10025 .name = "IAXVAR",
10026 .read = acf_iaxvar_read,
10027 .write = acf_iaxvar_write,
10028 };
10029
10030 static void set_hangup_source_and_cause(int callno, unsigned char causecode)
10031 {
10032 iax2_lock_owner(callno);
10033 if (iaxs[callno] && iaxs[callno]->owner) {
10034 struct ast_channel *owner;
10035 const char *name;
10036
10037 owner = iaxs[callno]->owner;
10038 if (causecode) {
10039 owner->hangupcause = causecode;
10040 }
10041 name = ast_strdupa(owner->name);
10042 ast_channel_ref(owner);
10043 ast_channel_unlock(owner);
10044 ast_mutex_unlock(&iaxsl[callno]);
10045 ast_set_hangupsource(owner, name, 0);
10046 ast_channel_unref(owner);
10047 ast_mutex_lock(&iaxsl[callno]);
10048 }
10049 }
10050
10051 static int socket_process(struct iax2_thread *thread)
10052 {
10053 struct sockaddr_in sin;
10054 int res;
10055 int updatehistory=1;
10056 int new = NEW_PREVENT;
10057 int dcallno = 0;
10058 char decrypted = 0;
10059 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
10060 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
10061 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
10062 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
10063 struct iax_frame *fr;
10064 struct iax_frame *cur;
10065 struct ast_frame f = { 0, };
10066 struct ast_channel *c = NULL;
10067 struct iax2_dpcache *dp;
10068 struct iax2_peer *peer;
10069 struct iax_ies ies;
10070 struct iax_ie_data ied0, ied1;
10071 format_t format;
10072 int fd;
10073 int exists;
10074 int minivid = 0;
10075 char empty[32]="";
10076 struct iax_frame *duped_fr;
10077 char host_pref_buf[128];
10078 char caller_pref_buf[128];
10079 struct ast_codec_pref pref;
10080 char *using_prefs = "mine";
10081
10082
10083 fr = ast_alloca(sizeof(*fr) + 4096);
10084 memset(fr, 0, sizeof(*fr));
10085 fr->afdatalen = 4096;
10086
10087
10088 res = thread->buf_len;
10089 fd = thread->iofd;
10090 memcpy(&sin, &thread->iosin, sizeof(sin));
10091
10092 if (res < sizeof(*mh)) {
10093 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
10094 return 1;
10095 }
10096 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
10097 if (res < sizeof(*vh)) {
10098 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));
10099 return 1;
10100 }
10101
10102
10103 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
10104 minivid = 1;
10105 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
10106 return socket_process_meta(res, meta, &sin, fd, fr);
10107
10108 #ifdef DEBUG_SUPPORT
10109 if (res >= sizeof(*fh))
10110 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
10111 #endif
10112 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10113 if (res < sizeof(*fh)) {
10114 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));
10115 return 1;
10116 }
10117
10118
10119 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
10120
10121
10122
10123
10124
10125
10126 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
10127 ast_mutex_lock(&iaxsl[fr->callno]);
10128 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
10129 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10130 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10131 ast_mutex_unlock(&iaxsl[fr->callno]);
10132 return 1;
10133 }
10134 decrypted = 1;
10135 }
10136 ast_mutex_unlock(&iaxsl[fr->callno]);
10137 }
10138
10139
10140 f.frametype = fh->type;
10141 if (f.frametype == AST_FRAME_VIDEO) {
10142 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
10143 } else if (f.frametype == AST_FRAME_VOICE) {
10144 f.subclass.codec = uncompress_subclass(fh->csub);
10145 } else {
10146 f.subclass.integer = uncompress_subclass(fh->csub);
10147 }
10148
10149
10150 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
10151
10152 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10153 return 1;
10154 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10155
10156 return 1;
10157 }
10158
10159 f.datalen = res - sizeof(*fh);
10160 if (f.datalen) {
10161 if (f.frametype == AST_FRAME_IAX) {
10162 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10163 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
10164 ast_variables_destroy(ies.vars);
10165 return 1;
10166 }
10167 f.data.ptr = NULL;
10168 f.datalen = 0;
10169 } else {
10170 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10171 memset(&ies, 0, sizeof(ies));
10172 }
10173 } else {
10174 if (f.frametype == AST_FRAME_IAX)
10175 f.data.ptr = NULL;
10176 else
10177 f.data.ptr = empty;
10178 memset(&ies, 0, sizeof(ies));
10179 }
10180
10181 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10182
10183 if (handle_call_token(fh, &ies, &sin, fd)) {
10184 ast_variables_destroy(ies.vars);
10185 return 1;
10186 }
10187
10188 if (ies.calltoken && ies.calltokendata) {
10189
10190
10191
10192
10193 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10194 } else {
10195 new = NEW_ALLOW;
10196 }
10197 }
10198 } else {
10199
10200 f.frametype = AST_FRAME_NULL;
10201 f.subclass.integer = 0;
10202 memset(&ies, 0, sizeof(ies));
10203 }
10204
10205 if (!fr->callno) {
10206 int check_dcallno = 0;
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10217 check_dcallno = 1;
10218 }
10219
10220 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10221 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10222 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10223 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10224 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10225 }
10226 ast_variables_destroy(ies.vars);
10227 return 1;
10228 }
10229 }
10230
10231 if (fr->callno > 0)
10232 ast_mutex_lock(&iaxsl[fr->callno]);
10233
10234 if (!fr->callno || !iaxs[fr->callno]) {
10235
10236
10237 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10238
10239 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10240 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10241 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10242 (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10243 (f.frametype != AST_FRAME_IAX))
10244 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10245 fd);
10246 }
10247 if (fr->callno > 0)
10248 ast_mutex_unlock(&iaxsl[fr->callno]);
10249 ast_variables_destroy(ies.vars);
10250 return 1;
10251 }
10252 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10253 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10254 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10255 ast_variables_destroy(ies.vars);
10256 ast_mutex_unlock(&iaxsl[fr->callno]);
10257 return 1;
10258 }
10259 decrypted = 1;
10260 }
10261
10262 #ifdef DEBUG_SUPPORT
10263 if (decrypted) {
10264 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10265 }
10266 #endif
10267
10268
10269
10270 iaxs[fr->callno]->frames_received++;
10271
10272 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10273 f.subclass.integer != IAX_COMMAND_TXCNT &&
10274 f.subclass.integer != IAX_COMMAND_TXACC) {
10275 unsigned short new_peercallno;
10276
10277 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10278 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10279 if (iaxs[fr->callno]->peercallno) {
10280 remove_by_peercallno(iaxs[fr->callno]);
10281 }
10282 iaxs[fr->callno]->peercallno = new_peercallno;
10283 store_by_peercallno(iaxs[fr->callno]);
10284 }
10285 }
10286 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10287 if (iaxdebug)
10288 ast_debug(1, "Received packet %d, (%u, %d)\n", fh->oseqno, f.frametype, f.subclass.integer);
10289
10290 fr->oseqno = fh->oseqno;
10291 fr->iseqno = fh->iseqno;
10292 fr->ts = ntohl(fh->ts);
10293 #ifdef IAXTESTS
10294 if (test_resync) {
10295 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10296 fr->ts += test_resync;
10297 }
10298 #endif
10299 #if 0
10300 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10301 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10302 (f.subclass == IAX_COMMAND_NEW ||
10303 f.subclass == IAX_COMMAND_AUTHREQ ||
10304 f.subclass == IAX_COMMAND_ACCEPT ||
10305 f.subclass == IAX_COMMAND_REJECT)) ) )
10306 #endif
10307 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10308 updatehistory = 0;
10309 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10310 (iaxs[fr->callno]->iseqno ||
10311 ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10312 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10313 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10314 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10315 (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10316 (f.frametype != AST_FRAME_IAX))) {
10317 if (
10318 ((f.subclass.integer != IAX_COMMAND_ACK) &&
10319 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10320 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10321 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10322 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10323 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10324 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10325 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10326 (f.frametype != AST_FRAME_IAX)) {
10327
10328 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %u, subclass = %d)\n",
10329 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10330
10331
10332 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10333
10334 if ((f.frametype != AST_FRAME_IAX) ||
10335 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10336 ast_debug(1, "Acking anyway\n");
10337
10338
10339 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10340 }
10341 } else {
10342
10343 iax2_vnak(fr->callno);
10344 }
10345 ast_variables_destroy(ies.vars);
10346 ast_mutex_unlock(&iaxsl[fr->callno]);
10347 return 1;
10348 }
10349 } else {
10350
10351 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10352 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10353 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10354 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10355 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10356 (f.frametype != AST_FRAME_IAX))
10357 iaxs[fr->callno]->iseqno++;
10358 }
10359
10360 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10361 if (res < thread->buf_size)
10362 thread->buf[res++] = '\0';
10363 else
10364 thread->buf[res - 1] = '\0';
10365 }
10366
10367
10368
10369 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10370 ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10371 (f.frametype != AST_FRAME_IAX))) {
10372 unsigned char x;
10373 int call_to_destroy;
10374
10375 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10376 x = fr->iseqno;
10377 else
10378 x = iaxs[fr->callno]->oseqno;
10379 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10380
10381
10382 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10383
10384 if (iaxdebug)
10385 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10386 call_to_destroy = 0;
10387 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10388
10389 if (x == cur->oseqno) {
10390 cur->retries = -1;
10391
10392 if (cur->final)
10393 call_to_destroy = fr->callno;
10394 }
10395 }
10396 if (call_to_destroy) {
10397 if (iaxdebug)
10398 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10399 ast_mutex_lock(&iaxsl[call_to_destroy]);
10400 iax2_destroy(call_to_destroy);
10401 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10402 }
10403 }
10404
10405 if (iaxs[fr->callno])
10406 iaxs[fr->callno]->rseqno = fr->iseqno;
10407 else {
10408
10409 ast_variables_destroy(ies.vars);
10410 ast_mutex_unlock(&iaxsl[fr->callno]);
10411 return 1;
10412 }
10413 } else {
10414 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10415 }
10416 }
10417 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10418 ((f.frametype != AST_FRAME_IAX) ||
10419 ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10420 (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10421
10422 ast_variables_destroy(ies.vars);
10423 ast_mutex_unlock(&iaxsl[fr->callno]);
10424 return 1;
10425 }
10426
10427
10428
10429
10430 if ((f.frametype == AST_FRAME_VOICE) ||
10431 (f.frametype == AST_FRAME_VIDEO) ||
10432 (f.frametype == AST_FRAME_IAX)) {
10433 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10434 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10435 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
10436 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
10437 ast_variables_destroy(ies.vars);
10438 ast_mutex_unlock(&iaxsl[fr->callno]);
10439 return 1;
10440 }
10441 }
10442
10443 if (ies.vars) {
10444 struct ast_datastore *variablestore = NULL;
10445 struct ast_variable *var, *prev = NULL;
10446 AST_LIST_HEAD(, ast_var_t) *varlist;
10447
10448 iax2_lock_owner(fr->callno);
10449 if (!iaxs[fr->callno]) {
10450 ast_variables_destroy(ies.vars);
10451 ast_mutex_unlock(&iaxsl[fr->callno]);
10452 return 1;
10453 }
10454 if ((c = iaxs[fr->callno]->owner)) {
10455 varlist = ast_calloc(1, sizeof(*varlist));
10456 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10457
10458 if (variablestore && varlist) {
10459 variablestore->data = varlist;
10460 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10461 AST_LIST_HEAD_INIT(varlist);
10462 ast_debug(1, "I can haz IAX vars?\n");
10463 for (var = ies.vars; var; var = var->next) {
10464 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10465 if (prev) {
10466 ast_free(prev);
10467 }
10468 prev = var;
10469 if (!newvar) {
10470
10471 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10472 } else {
10473 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10474 }
10475 }
10476 if (prev) {
10477 ast_free(prev);
10478 }
10479 ies.vars = NULL;
10480 ast_channel_datastore_add(c, variablestore);
10481 } else {
10482 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10483 if (variablestore) {
10484 ast_datastore_free(variablestore);
10485 }
10486 if (varlist) {
10487 ast_free(varlist);
10488 }
10489 }
10490 ast_channel_unlock(c);
10491 } else {
10492
10493
10494 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10495 for (var = ies.vars; var && var->next; var = var->next);
10496 if (var) {
10497 var->next = iaxs[fr->callno]->iaxvars;
10498 iaxs[fr->callno]->iaxvars = ies.vars;
10499 ies.vars = NULL;
10500 }
10501 }
10502 }
10503
10504 if (ies.vars) {
10505 ast_debug(1, "I have IAX variables, but they were not processed\n");
10506 }
10507 }
10508
10509
10510
10511 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10512 send_signaling(iaxs[fr->callno]);
10513 }
10514
10515 if (f.frametype == AST_FRAME_VOICE) {
10516 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10517 iaxs[fr->callno]->voiceformat = f.subclass.codec;
10518 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10519 if (iaxs[fr->callno]->owner) {
10520 iax2_lock_owner(fr->callno);
10521 if (iaxs[fr->callno]) {
10522 if (iaxs[fr->callno]->owner) {
10523 format_t orignative;
10524
10525 orignative = iaxs[fr->callno]->owner->nativeformats;
10526 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10527 if (iaxs[fr->callno]->owner->readformat)
10528 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10529 iaxs[fr->callno]->owner->nativeformats = orignative;
10530 ast_channel_unlock(iaxs[fr->callno]->owner);
10531 }
10532 } else {
10533 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10534
10535 if (ies.vars) {
10536 ast_variables_destroy(ies.vars);
10537 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10538 ies.vars = NULL;
10539 }
10540 ast_mutex_unlock(&iaxsl[fr->callno]);
10541 return 1;
10542 }
10543 }
10544 }
10545 }
10546 if (f.frametype == AST_FRAME_VIDEO) {
10547 if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10548 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10549 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10550 }
10551 }
10552 if (f.frametype == AST_FRAME_IAX) {
10553 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10554
10555 if (iaxdebug)
10556 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10557
10558
10559 if (iaxs[fr->callno]->last < fr->ts &&
10560 f.subclass.integer != IAX_COMMAND_ACK &&
10561 f.subclass.integer != IAX_COMMAND_PONG &&
10562 f.subclass.integer != IAX_COMMAND_LAGRP) {
10563 iaxs[fr->callno]->last = fr->ts;
10564 if (iaxdebug)
10565 ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts);
10566 }
10567 iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10568 if (!iaxs[fr->callno]->first_iax_message) {
10569 iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10570 }
10571 switch(f.subclass.integer) {
10572 case IAX_COMMAND_ACK:
10573
10574 break;
10575 case IAX_COMMAND_QUELCH:
10576 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10577
10578 if (iaxs[fr->callno]->owner) {
10579 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10580 "Status: On\r\n"
10581 "Channel: %s\r\n"
10582 "Uniqueid: %s\r\n",
10583 iaxs[fr->callno]->owner->name,
10584 iaxs[fr->callno]->owner->uniqueid);
10585 }
10586
10587 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10588 if (ies.musiconhold) {
10589 iax2_lock_owner(fr->callno);
10590 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10591 break;
10592 }
10593 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10594 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10595
10596
10597
10598
10599
10600 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10601 S_OR(moh_suggest, NULL),
10602 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10603 }
10604 ast_channel_unlock(iaxs[fr->callno]->owner);
10605 }
10606 }
10607 break;
10608 case IAX_COMMAND_UNQUELCH:
10609 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10610 iax2_lock_owner(fr->callno);
10611 if (!iaxs[fr->callno]) {
10612 break;
10613 }
10614
10615 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10616 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10617 "Status: Off\r\n"
10618 "Channel: %s\r\n"
10619 "Uniqueid: %s\r\n",
10620 iaxs[fr->callno]->owner->name,
10621 iaxs[fr->callno]->owner->uniqueid);
10622 }
10623
10624 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10625 if (!iaxs[fr->callno]->owner) {
10626 break;
10627 }
10628 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10629
10630
10631
10632
10633 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10634 }
10635 ast_channel_unlock(iaxs[fr->callno]->owner);
10636 }
10637 break;
10638 case IAX_COMMAND_TXACC:
10639 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10640
10641 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10642
10643 if (cur->transfer) {
10644 cur->retries = -1;
10645 }
10646 }
10647 memset(&ied1, 0, sizeof(ied1));
10648 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10649 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10650 iaxs[fr->callno]->transferring = TRANSFER_READY;
10651 }
10652 break;
10653 case IAX_COMMAND_NEW:
10654
10655 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10656 break;
10657 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10658 ast_mutex_unlock(&iaxsl[fr->callno]);
10659 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10660 ast_mutex_lock(&iaxsl[fr->callno]);
10661 if (!iaxs[fr->callno]) {
10662 break;
10663 }
10664 }
10665
10666 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10667 int new_callno;
10668 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10669 fr->callno = new_callno;
10670 }
10671
10672 if (delayreject)
10673 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10674 if (check_access(fr->callno, &sin, &ies)) {
10675
10676 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10677 if (authdebug)
10678 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);
10679 break;
10680 }
10681 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10682 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10683 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10684 break;
10685 }
10686 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10687 const char *context, *exten, *cid_num;
10688
10689 context = ast_strdupa(iaxs[fr->callno]->context);
10690 exten = ast_strdupa(iaxs[fr->callno]->exten);
10691 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10692
10693
10694 ast_mutex_unlock(&iaxsl[fr->callno]);
10695 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10696 ast_mutex_lock(&iaxsl[fr->callno]);
10697
10698 if (!iaxs[fr->callno]) {
10699 break;
10700 }
10701 } else
10702 exists = 0;
10703
10704 save_osptoken(fr, &ies);
10705 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10706 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10707 memset(&ied0, 0, sizeof(ied0));
10708 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10709 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10710 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10711 if (!iaxs[fr->callno]) {
10712 break;
10713 }
10714 if (authdebug)
10715 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);
10716 } else {
10717
10718
10719 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10720 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10721 using_prefs = "reqonly";
10722 } else {
10723 using_prefs = "disabled";
10724 }
10725 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10726 memset(&pref, 0, sizeof(pref));
10727 strcpy(caller_pref_buf, "disabled");
10728 strcpy(host_pref_buf, "disabled");
10729 } else {
10730 using_prefs = "mine";
10731
10732 if (ies.codec_prefs)
10733 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10734 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10735
10736 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10737 pref = iaxs[fr->callno]->rprefs;
10738 using_prefs = "caller";
10739 } else {
10740 pref = iaxs[fr->callno]->prefs;
10741 }
10742 } else
10743 pref = iaxs[fr->callno]->prefs;
10744
10745 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10746 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10747 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10748 }
10749 if (!format) {
10750 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10751 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10752 if (!format) {
10753 memset(&ied0, 0, sizeof(ied0));
10754 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10755 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10756 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10757 if (!iaxs[fr->callno]) {
10758 break;
10759 }
10760 if (authdebug) {
10761 char tmp[256], tmp2[256], tmp3[256];
10762 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10763 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10764 ast_inet_ntoa(sin.sin_addr),
10765 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10766 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10767 } else {
10768 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10769 ast_inet_ntoa(sin.sin_addr),
10770 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10771 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10772 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10773 }
10774 }
10775 } else {
10776
10777 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10778 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10779 format = 0;
10780 } else {
10781 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10782 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10783 memset(&pref, 0, sizeof(pref));
10784 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10785 strcpy(caller_pref_buf,"disabled");
10786 strcpy(host_pref_buf,"disabled");
10787 } else {
10788 using_prefs = "mine";
10789 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10790
10791 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10792 pref = iaxs[fr->callno]->prefs;
10793 } else {
10794 pref = iaxs[fr->callno]->rprefs;
10795 using_prefs = "caller";
10796 }
10797 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10798 } else
10799 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10800 }
10801 }
10802
10803 if (!format) {
10804 char tmp[256], tmp2[256], tmp3[256];
10805 memset(&ied0, 0, sizeof(ied0));
10806 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10807 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10808 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10809 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10810 if (!iaxs[fr->callno]) {
10811 break;
10812 }
10813 if (authdebug) {
10814 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10815 ast_inet_ntoa(sin.sin_addr),
10816 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10817 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10818 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10819 }
10820 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10821 break;
10822 }
10823 }
10824 }
10825 if (format) {
10826
10827 memset(&ied1, 0, sizeof(ied1));
10828 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10829 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10830 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10831 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10832 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10833 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10834 "%srequested format = %s,\n"
10835 "%srequested prefs = %s,\n"
10836 "%sactual format = %s,\n"
10837 "%shost prefs = %s,\n"
10838 "%spriority = %s\n",
10839 ast_inet_ntoa(sin.sin_addr),
10840 VERBOSE_PREFIX_4,
10841 ast_getformatname(iaxs[fr->callno]->peerformat),
10842 VERBOSE_PREFIX_4,
10843 caller_pref_buf,
10844 VERBOSE_PREFIX_4,
10845 ast_getformatname(format),
10846 VERBOSE_PREFIX_4,
10847 host_pref_buf,
10848 VERBOSE_PREFIX_4,
10849 using_prefs);
10850
10851 iaxs[fr->callno]->chosenformat = format;
10852 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10853 } else {
10854 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10855
10856 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10857 }
10858 }
10859 }
10860 break;
10861 }
10862 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10863 merge_encryption(iaxs[fr->callno],ies.encmethods);
10864 else
10865 iaxs[fr->callno]->encmethods = 0;
10866 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10867 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10868 break;
10869 case IAX_COMMAND_DPREQ:
10870
10871 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10872 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10873 if (iaxcompat) {
10874
10875 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10876 } else {
10877
10878 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10879 }
10880 }
10881 break;
10882 case IAX_COMMAND_HANGUP:
10883 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10884 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10885
10886 if (iaxs[fr->callno]->owner) {
10887 set_hangup_source_and_cause(fr->callno, ies.causecode);
10888 if (!iaxs[fr->callno]) {
10889 break;
10890 }
10891 }
10892
10893
10894 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10895 iax2_destroy(fr->callno);
10896 break;
10897 case IAX_COMMAND_REJECT:
10898
10899 if (iaxs[fr->callno]->owner) {
10900 set_hangup_source_and_cause(fr->callno, ies.causecode);
10901 if (!iaxs[fr->callno]) {
10902 break;
10903 }
10904 }
10905
10906 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10907 if (iaxs[fr->callno]->owner && authdebug)
10908 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10909 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10910 ies.cause ? ies.cause : "<Unknown>");
10911 ast_debug(1, "Immediately destroying %d, having received reject\n",
10912 fr->callno);
10913 }
10914
10915 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10916 fr->ts, NULL, 0, fr->iseqno);
10917 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10918 iaxs[fr->callno]->error = EPERM;
10919 iax2_destroy(fr->callno);
10920 break;
10921 case IAX_COMMAND_TRANSFER:
10922 {
10923 struct ast_channel *bridged_chan;
10924 struct ast_channel *owner;
10925
10926 iax2_lock_owner(fr->callno);
10927 if (!iaxs[fr->callno]) {
10928
10929 break;
10930 }
10931 owner = iaxs[fr->callno]->owner;
10932 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10933 if (bridged_chan && ies.called_number) {
10934 const char *context;
10935
10936 context = ast_strdupa(iaxs[fr->callno]->context);
10937
10938 ast_channel_ref(owner);
10939 ast_channel_ref(bridged_chan);
10940 ast_channel_unlock(owner);
10941 ast_mutex_unlock(&iaxsl[fr->callno]);
10942
10943
10944 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10945 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10946
10947
10948 if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10949 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10950 if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10951 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10952 bridged_chan->name);
10953 }
10954 } else {
10955 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10956 ast_log(LOG_WARNING,
10957 "Async goto of '%s' to '%s@%s' failed\n",
10958 bridged_chan->name, ies.called_number, context);
10959 } else {
10960 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10961 bridged_chan->name, ies.called_number, context);
10962 }
10963 }
10964 ast_channel_unref(owner);
10965 ast_channel_unref(bridged_chan);
10966
10967 ast_mutex_lock(&iaxsl[fr->callno]);
10968 } else {
10969 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10970 if (owner) {
10971 ast_channel_unlock(owner);
10972 }
10973 }
10974
10975 break;
10976 }
10977 case IAX_COMMAND_ACCEPT:
10978
10979 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10980 break;
10981 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10982
10983 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10984 iax2_destroy(fr->callno);
10985 break;
10986 }
10987 if (ies.format) {
10988 iaxs[fr->callno]->peerformat = ies.format;
10989 } else {
10990 if (iaxs[fr->callno]->owner)
10991 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10992 else
10993 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10994 }
10995 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));
10996 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10997 memset(&ied0, 0, sizeof(ied0));
10998 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10999 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11000 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11001 if (!iaxs[fr->callno]) {
11002 break;
11003 }
11004 if (authdebug) {
11005 char tmp1[256], tmp2[256];
11006 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
11007 ast_inet_ntoa(sin.sin_addr),
11008 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11009 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11010 }
11011 } else {
11012 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11013 iax2_lock_owner(fr->callno);
11014 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11015
11016 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
11017 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
11018
11019
11020 if (iaxs[fr->callno]->owner->writeformat)
11021 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
11022 if (iaxs[fr->callno]->owner->readformat)
11023 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
11024 ast_channel_unlock(iaxs[fr->callno]->owner);
11025 }
11026 }
11027 if (iaxs[fr->callno]) {
11028 AST_LIST_LOCK(&dpcache);
11029 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
11030 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
11031 iax2_dprequest(dp, fr->callno);
11032 AST_LIST_UNLOCK(&dpcache);
11033 }
11034 break;
11035 case IAX_COMMAND_POKE:
11036
11037 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
11038 break;
11039 case IAX_COMMAND_PING:
11040 {
11041 struct iax_ie_data pingied;
11042 construct_rr(iaxs[fr->callno], &pingied);
11043
11044 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
11045 }
11046 break;
11047 case IAX_COMMAND_PONG:
11048
11049 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
11050
11051 save_rr(fr, &ies);
11052
11053
11054 log_jitterstats(fr->callno);
11055
11056 if (iaxs[fr->callno]->peerpoke) {
11057 peer = iaxs[fr->callno]->peerpoke;
11058 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
11059 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
11060 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %u\n", peer->name, iaxs[fr->callno]->pingtime);
11061 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %u\r\n", peer->name, iaxs[fr->callno]->pingtime);
11062 ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
11063 }
11064 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
11065 if (iaxs[fr->callno]->pingtime > peer->maxms) {
11066 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%u ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
11067 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %u\r\n", peer->name, iaxs[fr->callno]->pingtime);
11068 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
11069 }
11070 }
11071 peer->lastms = iaxs[fr->callno]->pingtime;
11072 if (peer->smoothing && (peer->lastms > -1))
11073 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
11074 else if (peer->smoothing && peer->lastms < 0)
11075 peer->historicms = (0 + peer->historicms) / 2;
11076 else
11077 peer->historicms = iaxs[fr->callno]->pingtime;
11078
11079
11080 if (peer->pokeexpire > -1) {
11081 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
11082 peer_unref(peer);
11083 peer->pokeexpire = -1;
11084 }
11085 }
11086
11087 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
11088 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11089 else
11090 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
11091 if (peer->pokeexpire == -1)
11092 peer_unref(peer);
11093
11094 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11095
11096 iax2_destroy(fr->callno);
11097 peer->callno = 0;
11098 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
11099 }
11100 break;
11101 case IAX_COMMAND_LAGRQ:
11102 case IAX_COMMAND_LAGRP:
11103 f.src = "LAGRQ";
11104 f.mallocd = 0;
11105 f.offset = 0;
11106 f.samples = 0;
11107 iax_frame_wrap(fr, &f);
11108 if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
11109
11110 fr->af.subclass.integer = IAX_COMMAND_LAGRP;
11111 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
11112 } else {
11113
11114 unsigned int ts;
11115
11116 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
11117 iaxs[fr->callno]->lag = ts - fr->ts;
11118 if (iaxdebug)
11119 ast_debug(1, "Peer %s lag measured as %dms\n",
11120 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
11121 }
11122 break;
11123 case IAX_COMMAND_AUTHREQ:
11124 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11125 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>");
11126 break;
11127 }
11128 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
11129 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11130 .subclass.integer = AST_CONTROL_HANGUP,
11131 };
11132 ast_log(LOG_WARNING,
11133 "I don't know how to authenticate %s to %s\n",
11134 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
11135 iax2_queue_frame(fr->callno, &hangup_fr);
11136 }
11137 break;
11138 case IAX_COMMAND_AUTHREP:
11139
11140 if (delayreject)
11141 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11142
11143 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11144 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>");
11145 break;
11146 }
11147 if (authenticate_verify(iaxs[fr->callno], &ies)) {
11148 if (authdebug)
11149 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);
11150 memset(&ied0, 0, sizeof(ied0));
11151 auth_fail(fr->callno, IAX_COMMAND_REJECT);
11152 break;
11153 }
11154 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11155
11156 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
11157 } else
11158 exists = 0;
11159 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11160 if (authdebug)
11161 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);
11162 memset(&ied0, 0, sizeof(ied0));
11163 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11164 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11165 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11166 if (!iaxs[fr->callno]) {
11167 break;
11168 }
11169 } else {
11170
11171 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11172 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11173 using_prefs = "reqonly";
11174 } else {
11175 using_prefs = "disabled";
11176 }
11177 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11178 memset(&pref, 0, sizeof(pref));
11179 strcpy(caller_pref_buf, "disabled");
11180 strcpy(host_pref_buf, "disabled");
11181 } else {
11182 using_prefs = "mine";
11183 if (ies.codec_prefs)
11184 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11185 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11186 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11187 pref = iaxs[fr->callno]->rprefs;
11188 using_prefs = "caller";
11189 } else {
11190 pref = iaxs[fr->callno]->prefs;
11191 }
11192 } else
11193 pref = iaxs[fr->callno]->prefs;
11194 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11195 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11196 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11197 }
11198 if (!format) {
11199 char tmp1[256], tmp2[256], tmp3[256];
11200 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11201 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11202 ast_getformatname(iaxs[fr->callno]->peerformat),
11203 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11204 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11205 }
11206 if (!format) {
11207 if (authdebug) {
11208 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11209 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11210 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11211 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11212 } else {
11213 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11214 ast_inet_ntoa(sin.sin_addr),
11215 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11216 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11217 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11218 }
11219 }
11220 memset(&ied0, 0, sizeof(ied0));
11221 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11222 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11223 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11224 if (!iaxs[fr->callno]) {
11225 break;
11226 }
11227 } else {
11228
11229 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11230 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11231 format = 0;
11232 } else {
11233 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11234 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11235 memset(&pref, 0, sizeof(pref));
11236 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11237 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11238 strcpy(caller_pref_buf,"disabled");
11239 strcpy(host_pref_buf,"disabled");
11240 } else {
11241 using_prefs = "mine";
11242 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11243
11244 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11245 pref = iaxs[fr->callno]->prefs;
11246 } else {
11247 pref = iaxs[fr->callno]->rprefs;
11248 using_prefs = "caller";
11249 }
11250 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11251 } else
11252 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11253 }
11254 }
11255 if (!format) {
11256 char tmp1[256], tmp2[256], tmp3[256];
11257 ast_log(LOG_ERROR, "No best format in %s???\n",
11258 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11259 if (authdebug) {
11260 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11261 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11262 ast_inet_ntoa(sin.sin_addr),
11263 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11264 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11265 } else {
11266 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11267 ast_inet_ntoa(sin.sin_addr),
11268 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11269 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11270 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11271 }
11272 }
11273 memset(&ied0, 0, sizeof(ied0));
11274 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11275 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11276 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11277 if (!iaxs[fr->callno]) {
11278 break;
11279 }
11280 }
11281 }
11282 }
11283 if (format) {
11284
11285 memset(&ied1, 0, sizeof(ied1));
11286 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11287 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11288 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11289 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11290 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11291 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11292 "%srequested format = %s,\n"
11293 "%srequested prefs = %s,\n"
11294 "%sactual format = %s,\n"
11295 "%shost prefs = %s,\n"
11296 "%spriority = %s\n",
11297 ast_inet_ntoa(sin.sin_addr),
11298 VERBOSE_PREFIX_4,
11299 ast_getformatname(iaxs[fr->callno]->peerformat),
11300 VERBOSE_PREFIX_4,
11301 caller_pref_buf,
11302 VERBOSE_PREFIX_4,
11303 ast_getformatname(format),
11304 VERBOSE_PREFIX_4,
11305 host_pref_buf,
11306 VERBOSE_PREFIX_4,
11307 using_prefs);
11308
11309 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11310 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
11311 iax2_destroy(fr->callno);
11312 else if (ies.vars) {
11313 struct ast_datastore *variablestore;
11314 struct ast_variable *var, *prev = NULL;
11315 AST_LIST_HEAD(, ast_var_t) *varlist;
11316 varlist = ast_calloc(1, sizeof(*varlist));
11317 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11318 if (variablestore && varlist) {
11319 variablestore->data = varlist;
11320 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11321 AST_LIST_HEAD_INIT(varlist);
11322 ast_debug(1, "I can haz IAX vars? w00t\n");
11323 for (var = ies.vars; var; var = var->next) {
11324 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11325 if (prev)
11326 ast_free(prev);
11327 prev = var;
11328 if (!newvar) {
11329
11330 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11331 } else {
11332 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11333 }
11334 }
11335 if (prev)
11336 ast_free(prev);
11337 ies.vars = NULL;
11338 ast_channel_datastore_add(c, variablestore);
11339 } else {
11340 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11341 if (variablestore)
11342 ast_datastore_free(variablestore);
11343 if (varlist)
11344 ast_free(varlist);
11345 }
11346 }
11347 } else {
11348 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11349
11350 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11351 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11352 goto immediatedial;
11353 }
11354 }
11355 }
11356 }
11357 break;
11358 case IAX_COMMAND_DIAL:
11359 immediatedial:
11360 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11361 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11362 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11363 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11364 if (authdebug)
11365 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);
11366 memset(&ied0, 0, sizeof(ied0));
11367 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11368 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11369 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11370 if (!iaxs[fr->callno]) {
11371 break;
11372 }
11373 } else {
11374 char tmp[256];
11375 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11376 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11377 ast_inet_ntoa(sin.sin_addr),
11378 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11379 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11380 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11381 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
11382 iax2_destroy(fr->callno);
11383 else if (ies.vars) {
11384 struct ast_datastore *variablestore;
11385 struct ast_variable *var, *prev = NULL;
11386 AST_LIST_HEAD(, ast_var_t) *varlist;
11387 varlist = ast_calloc(1, sizeof(*varlist));
11388 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11389 ast_debug(1, "I can haz IAX vars? w00t\n");
11390 if (variablestore && varlist) {
11391 variablestore->data = varlist;
11392 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11393 AST_LIST_HEAD_INIT(varlist);
11394 for (var = ies.vars; var; var = var->next) {
11395 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11396 if (prev)
11397 ast_free(prev);
11398 prev = var;
11399 if (!newvar) {
11400
11401 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11402 } else {
11403 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11404 }
11405 }
11406 if (prev)
11407 ast_free(prev);
11408 ies.vars = NULL;
11409 ast_channel_datastore_add(c, variablestore);
11410 } else {
11411 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11412 if (variablestore)
11413 ast_datastore_free(variablestore);
11414 if (varlist)
11415 ast_free(varlist);
11416 }
11417 }
11418 }
11419 }
11420 break;
11421 case IAX_COMMAND_INVAL:
11422 iaxs[fr->callno]->error = ENOTCONN;
11423 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11424 iax2_destroy(fr->callno);
11425 ast_debug(1, "Destroying call %d\n", fr->callno);
11426 break;
11427 case IAX_COMMAND_VNAK:
11428 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11429
11430 vnak_retransmit(fr->callno, fr->iseqno);
11431 break;
11432 case IAX_COMMAND_REGREQ:
11433 case IAX_COMMAND_REGREL:
11434
11435 if (delayreject)
11436 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11437 if (register_verify(fr->callno, &sin, &ies)) {
11438 if (!iaxs[fr->callno]) {
11439 break;
11440 }
11441
11442 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11443 break;
11444 }
11445 if (!iaxs[fr->callno]) {
11446 break;
11447 }
11448 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11449 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11450
11451 if (f.subclass.integer == IAX_COMMAND_REGREL) {
11452 memset(&sin, 0, sizeof(sin));
11453 sin.sin_family = AF_INET;
11454 }
11455 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11456 ast_log(LOG_WARNING, "Registry error\n");
11457 }
11458 if (!iaxs[fr->callno]) {
11459 break;
11460 }
11461 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11462 ast_mutex_unlock(&iaxsl[fr->callno]);
11463 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11464 ast_mutex_lock(&iaxsl[fr->callno]);
11465 }
11466 break;
11467 }
11468 registry_authrequest(fr->callno);
11469 break;
11470 case IAX_COMMAND_REGACK:
11471 if (iax2_ack_registry(&ies, &sin, fr->callno))
11472 ast_log(LOG_WARNING, "Registration failure\n");
11473
11474 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11475 iax2_destroy(fr->callno);
11476 break;
11477 case IAX_COMMAND_REGREJ:
11478 if (iaxs[fr->callno]->reg) {
11479 if (authdebug) {
11480 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));
11481 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>");
11482 }
11483 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11484 }
11485
11486 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11487 iax2_destroy(fr->callno);
11488 break;
11489 case IAX_COMMAND_REGAUTH:
11490
11491 if (registry_rerequest(&ies, fr->callno, &sin)) {
11492 memset(&ied0, 0, sizeof(ied0));
11493 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11494 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11495 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11496 }
11497 break;
11498 case IAX_COMMAND_TXREJ:
11499 while (iaxs[fr->callno]
11500 && iaxs[fr->callno]->bridgecallno
11501 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
11502 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
11503 }
11504 if (!iaxs[fr->callno]) {
11505 break;
11506 }
11507
11508 iaxs[fr->callno]->transferring = TRANSFER_NONE;
11509 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11510 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11511
11512 if (!iaxs[fr->callno]->bridgecallno) {
11513 break;
11514 }
11515
11516 if (iaxs[iaxs[fr->callno]->bridgecallno]
11517 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11518 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE;
11519 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11520 }
11521 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11522 break;
11523 case IAX_COMMAND_TXREADY:
11524 while (iaxs[fr->callno]
11525 && iaxs[fr->callno]->bridgecallno
11526 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
11527 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
11528 }
11529 if (!iaxs[fr->callno]) {
11530 break;
11531 }
11532
11533 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
11534 iaxs[fr->callno]->transferring = TRANSFER_READY;
11535 } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) {
11536 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11537 } else {
11538 if (iaxs[fr->callno]->bridgecallno) {
11539 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11540 }
11541 break;
11542 }
11543 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11544
11545 if (!iaxs[fr->callno]->bridgecallno) {
11546 break;
11547 }
11548
11549 if (!iaxs[iaxs[fr->callno]->bridgecallno]
11550 || (iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_READY
11551 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_MREADY)) {
11552 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11553 break;
11554 }
11555
11556
11557
11558
11559
11560 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11561 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11562 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11563
11564 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11565 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11566
11567 memset(&ied0, 0, sizeof(ied0));
11568 memset(&ied1, 0, sizeof(ied1));
11569 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11570 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11571 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11572 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11573 } else {
11574 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11575 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11576
11577 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11578 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11579 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11580 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11581
11582
11583 stop_stuff(fr->callno);
11584 stop_stuff(iaxs[fr->callno]->bridgecallno);
11585
11586 memset(&ied0, 0, sizeof(ied0));
11587 memset(&ied1, 0, sizeof(ied1));
11588 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11589 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11590 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11591 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11592 }
11593 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11594 break;
11595 case IAX_COMMAND_TXREQ:
11596 try_transfer(iaxs[fr->callno], &ies);
11597 break;
11598 case IAX_COMMAND_TXCNT:
11599 if (iaxs[fr->callno]->transferring)
11600 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11601 break;
11602 case IAX_COMMAND_TXREL:
11603
11604 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11605 complete_transfer(fr->callno, &ies);
11606 stop_stuff(fr->callno);
11607 break;
11608 case IAX_COMMAND_TXMEDIA:
11609 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11610 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11611
11612 if (cur->transfer) {
11613 cur->retries = -1;
11614 }
11615 }
11616
11617 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11618 }
11619 break;
11620 case IAX_COMMAND_RTKEY:
11621 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11622 ast_log(LOG_WARNING,
11623 "we've been told to rotate our encryption key, "
11624 "but this isn't an encrypted call. bad things will happen.\n"
11625 );
11626 break;
11627 }
11628
11629 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11630
11631 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11632 break;
11633 case IAX_COMMAND_DPREP:
11634 complete_dpreply(iaxs[fr->callno], &ies);
11635 break;
11636 case IAX_COMMAND_UNSUPPORT:
11637 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11638 break;
11639 case IAX_COMMAND_FWDOWNL:
11640
11641 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11642 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11643 break;
11644 }
11645 memset(&ied0, 0, sizeof(ied0));
11646 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11647 if (res < 0)
11648 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11649 else if (res > 0)
11650 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11651 else
11652 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11653 break;
11654 case IAX_COMMAND_CALLTOKEN:
11655 {
11656 struct iax_frame *cur;
11657
11658 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11659 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11660 }
11661 break;
11662 }
11663 default:
11664 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11665 memset(&ied0, 0, sizeof(ied0));
11666 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11667 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11668 }
11669
11670 if (ies.vars) {
11671 ast_variables_destroy(ies.vars);
11672 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11673 ies.vars = NULL;
11674 }
11675
11676
11677 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11678 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11679 (f.subclass.integer != IAX_COMMAND_TXACC) &&
11680 (f.subclass.integer != IAX_COMMAND_INVAL) &&
11681 (f.subclass.integer != IAX_COMMAND_VNAK)) {
11682 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) {
11683 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11684 }
11685 }
11686 ast_mutex_unlock(&iaxsl[fr->callno]);
11687 return 1;
11688 }
11689
11690 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11691 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11692 } else if (minivid) {
11693 f.frametype = AST_FRAME_VIDEO;
11694 if (iaxs[fr->callno]->videoformat > 0)
11695 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11696 else {
11697 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11698 iax2_vnak(fr->callno);
11699 ast_variables_destroy(ies.vars);
11700 ast_mutex_unlock(&iaxsl[fr->callno]);
11701 return 1;
11702 }
11703 f.datalen = res - sizeof(*vh);
11704 if (f.datalen)
11705 f.data.ptr = thread->buf + sizeof(*vh);
11706 else
11707 f.data.ptr = NULL;
11708 #ifdef IAXTESTS
11709 if (test_resync) {
11710 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11711 } else
11712 #endif
11713 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11714 } else {
11715
11716 f.frametype = AST_FRAME_VOICE;
11717 if (iaxs[fr->callno]->voiceformat > 0)
11718 f.subclass.codec = iaxs[fr->callno]->voiceformat;
11719 else {
11720 ast_debug(1, "Received mini frame before first full voice frame\n");
11721 iax2_vnak(fr->callno);
11722 ast_variables_destroy(ies.vars);
11723 ast_mutex_unlock(&iaxsl[fr->callno]);
11724 return 1;
11725 }
11726 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11727 if (f.datalen < 0) {
11728 ast_log(LOG_WARNING, "Datalen < 0?\n");
11729 ast_variables_destroy(ies.vars);
11730 ast_mutex_unlock(&iaxsl[fr->callno]);
11731 return 1;
11732 }
11733 if (f.datalen)
11734 f.data.ptr = thread->buf + sizeof(*mh);
11735 else
11736 f.data.ptr = NULL;
11737 #ifdef IAXTESTS
11738 if (test_resync) {
11739 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11740 } else
11741 #endif
11742 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11743
11744 }
11745
11746
11747 if (!iaxs[fr->callno]
11748 || !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11749 ast_variables_destroy(ies.vars);
11750 ast_mutex_unlock(&iaxsl[fr->callno]);
11751 return 1;
11752 }
11753
11754 if (f.frametype == AST_FRAME_CONTROL) {
11755 if (!iax2_is_control_frame_allowed(f.subclass.integer)) {
11756
11757 ast_debug(2, "Callno %d: Blocked receiving control frame %d.\n",
11758 fr->callno, f.subclass.integer);
11759 ast_variables_destroy(ies.vars);
11760 ast_mutex_unlock(&iaxsl[fr->callno]);
11761 return 1;
11762 }
11763 if (f.subclass.integer == AST_CONTROL_CONNECTED_LINE
11764 || f.subclass.integer == AST_CONTROL_REDIRECTING) {
11765 if (iaxs[fr->callno]
11766 && !ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11767
11768 ast_debug(2, "Callno %d: Config blocked receiving control frame %d.\n",
11769 fr->callno, f.subclass.integer);
11770 ast_variables_destroy(ies.vars);
11771 ast_mutex_unlock(&iaxsl[fr->callno]);
11772 return 1;
11773 }
11774 }
11775
11776 iax2_lock_owner(fr->callno);
11777 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11778 if (f.subclass.integer == AST_CONTROL_BUSY) {
11779 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
11780 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
11781 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
11782 }
11783 ast_channel_unlock(iaxs[fr->callno]->owner);
11784 }
11785 }
11786
11787 if (f.frametype == AST_FRAME_CONTROL
11788 && f.subclass.integer == AST_CONTROL_CONNECTED_LINE
11789 && iaxs[fr->callno]) {
11790 struct ast_party_connected_line connected;
11791
11792
11793
11794
11795
11796
11797 ast_party_connected_line_init(&connected);
11798 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11799 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11800
11801 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11802 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11803 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11804 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11805
11806 iax2_lock_owner(fr->callno);
11807 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11808 ast_set_callerid(iaxs[fr->callno]->owner,
11809 S_COR(connected.id.number.valid, connected.id.number.str, ""),
11810 S_COR(connected.id.name.valid, connected.id.name.str, ""),
11811 NULL);
11812 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11813 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11814 ast_channel_unlock(iaxs[fr->callno]->owner);
11815 }
11816 }
11817 ast_party_connected_line_free(&connected);
11818 }
11819
11820
11821 f.src = "IAX2";
11822 f.mallocd = 0;
11823 f.offset = 0;
11824 f.len = 0;
11825 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11826 f.samples = ast_codec_get_samples(&f);
11827
11828 if (f.subclass.codec == AST_FORMAT_SLINEAR)
11829 ast_frame_byteswap_be(&f);
11830 } else
11831 f.samples = 0;
11832 iax_frame_wrap(fr, &f);
11833
11834
11835 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11836
11837 fr->outoforder = 0;
11838 } else {
11839 if (iaxdebug && iaxs[fr->callno]) {
11840 ast_debug(1, "Received out of order packet... (type=%u, subclass %d, ts = %u, last = %u)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last);
11841 }
11842 fr->outoforder = -1;
11843 }
11844 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11845 if (iaxs[fr->callno]) {
11846 duped_fr = iaxfrdup2(fr);
11847 if (duped_fr) {
11848 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11849 }
11850 }
11851 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11852 iaxs[fr->callno]->last = fr->ts;
11853 #if 1
11854 if (iaxdebug)
11855 ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts);
11856 #endif
11857 }
11858
11859
11860 ast_variables_destroy(ies.vars);
11861 ast_mutex_unlock(&iaxsl[fr->callno]);
11862 return 1;
11863 }
11864
11865
11866 static void iax2_process_thread_cleanup(void *data)
11867 {
11868 struct iax2_thread *thread = data;
11869 ast_mutex_destroy(&thread->lock);
11870 ast_cond_destroy(&thread->cond);
11871 ast_mutex_destroy(&thread->init_lock);
11872 ast_cond_destroy(&thread->init_cond);
11873 ast_free(thread);
11874
11875 ast_atomic_dec_and_test(&iaxactivethreadcount);
11876 }
11877
11878 static void *iax2_process_thread(void *data)
11879 {
11880 struct iax2_thread *thread = data;
11881 struct timeval wait;
11882 struct timespec ts;
11883 int put_into_idle = 0;
11884 int first_time = 1;
11885 int old_state;
11886
11887 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11888
11889 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11890 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11891
11892 for (;;) {
11893
11894 ast_mutex_lock(&thread->lock);
11895
11896 if (thread->stop) {
11897 ast_mutex_unlock(&thread->lock);
11898 break;
11899 }
11900
11901
11902 if (first_time) {
11903 signal_condition(&thread->init_lock, &thread->init_cond);
11904 first_time = 0;
11905 }
11906
11907
11908 if (put_into_idle) {
11909 insert_idle_thread(thread);
11910 }
11911
11912 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11913 struct iax2_thread *t = NULL;
11914
11915 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11916 ts.tv_sec = wait.tv_sec;
11917 ts.tv_nsec = wait.tv_usec * 1000;
11918 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11919
11920
11921 if (!put_into_idle || thread->stop) {
11922 ast_mutex_unlock(&thread->lock);
11923 break;
11924 }
11925 AST_LIST_LOCK(&dynamic_list);
11926
11927 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11928 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11929 AST_LIST_UNLOCK(&dynamic_list);
11930 if (t) {
11931
11932
11933
11934 ast_mutex_unlock(&thread->lock);
11935 break;
11936 }
11937
11938
11939
11940 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11941 ts.tv_sec = wait.tv_sec;
11942 ts.tv_nsec = wait.tv_usec * 1000;
11943 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11944 ast_mutex_unlock(&thread->lock);
11945 break;
11946 }
11947 }
11948 } else {
11949 ast_cond_wait(&thread->cond, &thread->lock);
11950 }
11951
11952
11953 put_into_idle = 1;
11954
11955 ast_mutex_unlock(&thread->lock);
11956
11957 if (thread->stop) {
11958 break;
11959 }
11960
11961
11962 switch (thread->iostate) {
11963 case IAX_IOSTATE_IDLE:
11964 continue;
11965 case IAX_IOSTATE_READY:
11966 thread->actions++;
11967 thread->iostate = IAX_IOSTATE_PROCESSING;
11968 socket_process(thread);
11969 handle_deferred_full_frames(thread);
11970 break;
11971 case IAX_IOSTATE_SCHEDREADY:
11972 thread->actions++;
11973 thread->iostate = IAX_IOSTATE_PROCESSING;
11974 #ifdef SCHED_MULTITHREADED
11975 thread->schedfunc(thread->scheddata);
11976 #endif
11977 break;
11978 default:
11979 break;
11980 }
11981
11982
11983
11984
11985 AST_LIST_LOCK(&active_list);
11986 AST_LIST_REMOVE(&active_list, thread, list);
11987 AST_LIST_UNLOCK(&active_list);
11988
11989
11990 handle_deferred_full_frames(thread);
11991
11992 time(&thread->checktime);
11993 thread->iostate = IAX_IOSTATE_IDLE;
11994 #ifdef DEBUG_SCHED_MULTITHREAD
11995 thread->curfunc[0]='\0';
11996 #endif
11997 }
11998
11999
12000
12001
12002
12003
12004 AST_LIST_LOCK(&idle_list);
12005 AST_LIST_REMOVE(&idle_list, thread, list);
12006 AST_LIST_UNLOCK(&idle_list);
12007
12008 AST_LIST_LOCK(&dynamic_list);
12009 AST_LIST_REMOVE(&dynamic_list, thread, list);
12010 AST_LIST_UNLOCK(&dynamic_list);
12011
12012 if (!thread->stop) {
12013
12014 pthread_detach(pthread_self());
12015 }
12016
12017
12018
12019
12020 pthread_cleanup_pop(1);
12021 return NULL;
12022 }
12023
12024 static int iax2_do_register(struct iax2_registry *reg)
12025 {
12026 struct iax_ie_data ied;
12027 if (iaxdebug)
12028 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
12029
12030 if (reg->dnsmgr &&
12031 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) {
12032
12033 ast_dnsmgr_refresh(reg->dnsmgr);
12034 }
12035
12036
12037
12038
12039
12040 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
12041 int callno = reg->callno;
12042 ast_mutex_lock(&iaxsl[callno]);
12043 iax2_destroy(callno);
12044 ast_mutex_unlock(&iaxsl[callno]);
12045 reg->callno = 0;
12046 }
12047 if (!ast_sockaddr_ipv4(®->addr)) {
12048 if (iaxdebug)
12049 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
12050
12051 reg->expire = iax2_sched_replace(reg->expire, sched,
12052 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12053 return -1;
12054 }
12055
12056 if (!reg->callno) {
12057 struct sockaddr_in reg_addr;
12058
12059 ast_debug(3, "Allocate call number\n");
12060
12061 ast_sockaddr_to_sin(®->addr, ®_addr);
12062
12063 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0);
12064 if (reg->callno < 1) {
12065 ast_log(LOG_WARNING, "Unable to create call for registration\n");
12066 return -1;
12067 } else
12068 ast_debug(3, "Registration created on call %d\n", reg->callno);
12069 iaxs[reg->callno]->reg = reg;
12070 ast_mutex_unlock(&iaxsl[reg->callno]);
12071 }
12072
12073 reg->expire = iax2_sched_replace(reg->expire, sched,
12074 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
12075
12076 memset(&ied, 0, sizeof(ied));
12077 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
12078 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
12079 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
12080 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
12081 reg->regstate = REG_STATE_REGSENT;
12082 return 0;
12083 }
12084
12085 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
12086 {
12087
12088
12089 struct iax_ie_data provdata;
12090 struct iax_ie_data ied;
12091 unsigned int sig;
12092 struct sockaddr_in sin;
12093 int callno;
12094 struct create_addr_info cai;
12095
12096 memset(&cai, 0, sizeof(cai));
12097
12098 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
12099
12100 if (iax_provision_build(&provdata, &sig, template, force)) {
12101 ast_debug(1, "No provisioning found for template '%s'\n", template);
12102 return 0;
12103 }
12104
12105 if (end) {
12106 memcpy(&sin, end, sizeof(sin));
12107 cai.sockfd = sockfd;
12108 } else if (create_addr(dest, NULL, &sin, &cai))
12109 return -1;
12110
12111
12112 memset(&ied, 0, sizeof(ied));
12113 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
12114
12115 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12116 if (!callno)
12117 return -1;
12118
12119 if (iaxs[callno]) {
12120
12121 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
12122 sched, 15000, auto_hangup, (void *)(long)callno);
12123 ast_set_flag64(iaxs[callno], IAX_PROVISION);
12124
12125 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
12126 }
12127 ast_mutex_unlock(&iaxsl[callno]);
12128
12129 return 1;
12130 }
12131
12132 static char *papp = "IAX2Provision";
12133
12134
12135
12136
12137 static int iax2_prov_app(struct ast_channel *chan, const char *data)
12138 {
12139 int res;
12140 char *sdata;
12141 char *opts;
12142 int force =0;
12143 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
12144 if (ast_strlen_zero(data))
12145 data = "default";
12146 sdata = ast_strdupa(data);
12147 opts = strchr(sdata, '|');
12148 if (opts)
12149 *opts='\0';
12150
12151 if (chan->tech != &iax2_tech) {
12152 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
12153 return -1;
12154 }
12155 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
12156 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
12157 return -1;
12158 }
12159 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
12160 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
12161 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
12162 sdata, res);
12163 return res;
12164 }
12165
12166 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
12167 {
12168 int force = 0;
12169 int res;
12170
12171 switch (cmd) {
12172 case CLI_INIT:
12173 e->command = "iax2 provision";
12174 e->usage =
12175 "Usage: iax2 provision <host> <template> [forced]\n"
12176 " Provisions the given peer or IP address using a template\n"
12177 " matching either 'template' or '*' if the template is not\n"
12178 " found. If 'forced' is specified, even empty provisioning\n"
12179 " fields will be provisioned as empty fields.\n";
12180 return NULL;
12181 case CLI_GENERATE:
12182 if (a->pos == 3)
12183 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
12184 return NULL;
12185 }
12186
12187 if (a->argc < 4)
12188 return CLI_SHOWUSAGE;
12189 if (a->argc > 4) {
12190 if (!strcasecmp(a->argv[4], "forced"))
12191 force = 1;
12192 else
12193 return CLI_SHOWUSAGE;
12194 }
12195 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
12196 if (res < 0)
12197 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
12198 else if (res < 1)
12199 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
12200 else
12201 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
12202 return CLI_SUCCESS;
12203 }
12204
12205 static void __iax2_poke_noanswer(const void *data)
12206 {
12207 struct iax2_peer *peer = (struct iax2_peer *)data;
12208 int callno;
12209
12210 if (peer->lastms > -1) {
12211 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12212 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
12213 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
12214 }
12215 if ((callno = peer->callno) > 0) {
12216 ast_mutex_lock(&iaxsl[callno]);
12217 iax2_destroy(callno);
12218 ast_mutex_unlock(&iaxsl[callno]);
12219 }
12220 peer->callno = 0;
12221 peer->lastms = -1;
12222
12223 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
12224 if (peer->pokeexpire == -1)
12225 peer_unref(peer);
12226 }
12227
12228 static int iax2_poke_noanswer(const void *data)
12229 {
12230 struct iax2_peer *peer = (struct iax2_peer *)data;
12231 peer->pokeexpire = -1;
12232 #ifdef SCHED_MULTITHREADED
12233 if (schedule_action(__iax2_poke_noanswer, data))
12234 #endif
12235 __iax2_poke_noanswer(data);
12236 peer_unref(peer);
12237 return 0;
12238 }
12239
12240 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
12241 {
12242 struct iax2_peer *peer = obj;
12243
12244 iax2_poke_peer(peer, 0);
12245
12246 return 0;
12247 }
12248
12249 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
12250 {
12251 int callno;
12252 struct sockaddr_in peer_addr;
12253
12254 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
12255
12256
12257 peer->lastms = 0;
12258 peer->historicms = 0;
12259 peer->pokeexpire = -1;
12260 peer->callno = 0;
12261 return 0;
12262 }
12263
12264 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
12265
12266
12267 if ((callno = peer->callno) > 0) {
12268 ast_log(LOG_NOTICE, "Still have a callno...\n");
12269 ast_mutex_lock(&iaxsl[callno]);
12270 iax2_destroy(callno);
12271 ast_mutex_unlock(&iaxsl[callno]);
12272 }
12273 if (heldcall)
12274 ast_mutex_unlock(&iaxsl[heldcall]);
12275 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12276 if (heldcall)
12277 ast_mutex_lock(&iaxsl[heldcall]);
12278 if (peer->callno < 1) {
12279 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12280 return -1;
12281 }
12282
12283
12284 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12285 iaxs[peer->callno]->peerpoke = peer;
12286
12287 if (peer->pokeexpire > -1) {
12288 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
12289 peer->pokeexpire = -1;
12290 peer_unref(peer);
12291 }
12292 }
12293
12294
12295
12296 if (peer->lastms < 0)
12297 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12298 else
12299 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12300
12301 if (peer->pokeexpire == -1)
12302 peer_unref(peer);
12303
12304
12305 ast_mutex_lock(&iaxsl[callno]);
12306 if (iaxs[callno]) {
12307 struct iax_ie_data ied = {
12308 .buf = { 0 },
12309 .pos = 0,
12310 };
12311 add_empty_calltoken_ie(iaxs[callno], &ied);
12312 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12313 }
12314 ast_mutex_unlock(&iaxsl[callno]);
12315
12316 return 0;
12317 }
12318
12319 static void free_context(struct iax2_context *con)
12320 {
12321 struct iax2_context *conl;
12322 while(con) {
12323 conl = con;
12324 con = con->next;
12325 ast_free(conl);
12326 }
12327 }
12328
12329 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
12330 {
12331 int callno;
12332 int res;
12333 format_t fmt, native;
12334 struct sockaddr_in sin;
12335 struct ast_channel *c;
12336 struct parsed_dial_string pds;
12337 struct create_addr_info cai;
12338 char *tmpstr;
12339
12340 memset(&pds, 0, sizeof(pds));
12341 tmpstr = ast_strdupa(data);
12342 parse_dial_string(tmpstr, &pds);
12343
12344 if (ast_strlen_zero(pds.peer)) {
12345 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12346 return NULL;
12347 }
12348
12349 memset(&cai, 0, sizeof(cai));
12350 cai.capability = iax2_capability;
12351
12352 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12353
12354
12355 if (create_addr(pds.peer, NULL, &sin, &cai)) {
12356 *cause = AST_CAUSE_UNREGISTERED;
12357 return NULL;
12358 }
12359
12360 if (pds.port)
12361 sin.sin_port = htons(atoi(pds.port));
12362
12363 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12364 if (callno < 1) {
12365 ast_log(LOG_WARNING, "Unable to create call\n");
12366 *cause = AST_CAUSE_CONGESTION;
12367 return NULL;
12368 }
12369
12370
12371 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12372 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12373 int new_callno;
12374 if ((new_callno = make_trunk(callno, 1)) != -1)
12375 callno = new_callno;
12376 }
12377 iaxs[callno]->maxtime = cai.maxtime;
12378 if (cai.found)
12379 ast_string_field_set(iaxs[callno], host, pds.peer);
12380
12381 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found);
12382
12383 ast_mutex_unlock(&iaxsl[callno]);
12384
12385 if (c) {
12386
12387 if (c->nativeformats & format)
12388 c->nativeformats &= format;
12389 else {
12390 native = c->nativeformats;
12391 fmt = format;
12392 res = ast_translator_best_choice(&fmt, &native);
12393 if (res < 0) {
12394 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12395 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12396 ast_hangup(c);
12397 return NULL;
12398 }
12399 c->nativeformats = native;
12400 }
12401 c->readformat = ast_best_codec(c->nativeformats);
12402 c->writeformat = c->readformat;
12403 }
12404
12405 return c;
12406 }
12407
12408 static void *network_thread(void *ignore)
12409 {
12410 if (timer) {
12411 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12412 }
12413
12414 for (;;) {
12415 pthread_testcancel();
12416
12417
12418
12419 if (ast_io_wait(io, 1000) <= 0) {
12420 break;
12421 }
12422 }
12423
12424 return NULL;
12425 }
12426
12427 static int start_network_thread(void)
12428 {
12429 struct iax2_thread *thread;
12430 int threadcount = 0;
12431 int x;
12432 for (x = 0; x < iaxthreadcount; x++) {
12433 thread = ast_calloc(1, sizeof(*thread));
12434 if (thread) {
12435 thread->type = IAX_THREAD_TYPE_POOL;
12436 thread->threadnum = ++threadcount;
12437 ast_mutex_init(&thread->lock);
12438 ast_cond_init(&thread->cond, NULL);
12439 ast_mutex_init(&thread->init_lock);
12440 ast_cond_init(&thread->init_cond, NULL);
12441
12442 ast_mutex_lock(&thread->init_lock);
12443
12444 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12445 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12446 ast_mutex_destroy(&thread->lock);
12447 ast_cond_destroy(&thread->cond);
12448 ast_mutex_unlock(&thread->init_lock);
12449 ast_mutex_destroy(&thread->init_lock);
12450 ast_cond_destroy(&thread->init_cond);
12451 ast_free(thread);
12452 thread = NULL;
12453 continue;
12454 }
12455
12456 ast_cond_wait(&thread->init_cond, &thread->init_lock);
12457
12458
12459 ast_mutex_unlock(&thread->init_lock);
12460
12461 AST_LIST_LOCK(&idle_list);
12462 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12463 AST_LIST_UNLOCK(&idle_list);
12464 }
12465 }
12466 if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) {
12467 ast_log(LOG_ERROR, "Failed to create new thread!\n");
12468 return -1;
12469 }
12470 ast_verb(2, "%d helper threads started\n", threadcount);
12471 return 0;
12472 }
12473
12474 static struct iax2_context *build_context(const char *context)
12475 {
12476 struct iax2_context *con;
12477
12478 if ((con = ast_calloc(1, sizeof(*con))))
12479 ast_copy_string(con->context, context, sizeof(con->context));
12480
12481 return con;
12482 }
12483
12484 static int get_auth_methods(const char *value)
12485 {
12486 int methods = 0;
12487 if (strstr(value, "rsa"))
12488 methods |= IAX_AUTH_RSA;
12489 if (strstr(value, "md5"))
12490 methods |= IAX_AUTH_MD5;
12491 if (strstr(value, "plaintext"))
12492 methods |= IAX_AUTH_PLAINTEXT;
12493 return methods;
12494 }
12495
12496
12497
12498
12499
12500 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
12501 {
12502 int sd;
12503 int res;
12504
12505 sd = socket(AF_INET, SOCK_DGRAM, 0);
12506 if (sd < 0) {
12507 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12508 return -1;
12509 }
12510
12511 res = bind(sd, sa, salen);
12512 if (res < 0) {
12513 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12514 close(sd);
12515 return 1;
12516 }
12517
12518 close(sd);
12519 return 0;
12520 }
12521
12522
12523
12524
12525 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12526 {
12527 struct sockaddr_in sin;
12528 struct ast_sockaddr sin_tmp;
12529 int nonlocal = 1;
12530 int port = IAX_DEFAULT_PORTNO;
12531 int sockfd = defaultsockfd;
12532 char *tmp;
12533 char *addr;
12534 char *portstr;
12535
12536 tmp = ast_strdupa(srcaddr);
12537 addr = strsep(&tmp, ":");
12538 portstr = tmp;
12539
12540 if (portstr) {
12541 port = atoi(portstr);
12542 if (port < 1)
12543 port = IAX_DEFAULT_PORTNO;
12544 }
12545
12546 sin_tmp.ss.ss_family = AF_INET;
12547 if (!ast_get_ip(&sin_tmp, addr)) {
12548 struct ast_netsock *sock;
12549 int res;
12550
12551 ast_sockaddr_to_sin(&sin_tmp, &sin);
12552 sin.sin_port = 0;
12553 sin.sin_family = AF_INET;
12554 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12555 if (res == 0) {
12556
12557 sin.sin_port = htons(port);
12558 if (!(sock = ast_netsock_find(netsock, &sin)))
12559 sock = ast_netsock_find(outsock, &sin);
12560 if (sock) {
12561 sockfd = ast_netsock_sockfd(sock);
12562 nonlocal = 0;
12563 } else {
12564 unsigned int orig_saddr = sin.sin_addr.s_addr;
12565
12566 sin.sin_addr.s_addr = INADDR_ANY;
12567 if (ast_netsock_find(netsock, &sin)) {
12568 sin.sin_addr.s_addr = orig_saddr;
12569 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12570 if (sock) {
12571 sockfd = ast_netsock_sockfd(sock);
12572 ast_netsock_unref(sock);
12573 nonlocal = 0;
12574 } else {
12575 nonlocal = 2;
12576 }
12577 }
12578 }
12579 }
12580 }
12581
12582 peer->sockfd = sockfd;
12583
12584 if (nonlocal == 1) {
12585 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12586 srcaddr, peer->name);
12587 return -1;
12588 } else if (nonlocal == 2) {
12589 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12590 srcaddr, peer->name);
12591 return -1;
12592 } else {
12593 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12594 return 0;
12595 }
12596 }
12597
12598 static void peer_destructor(void *obj)
12599 {
12600 struct iax2_peer *peer = obj;
12601 int callno = peer->callno;
12602
12603 ast_free_ha(peer->ha);
12604
12605 if (callno > 0) {
12606 ast_mutex_lock(&iaxsl[callno]);
12607 iax2_destroy(callno);
12608 ast_mutex_unlock(&iaxsl[callno]);
12609 }
12610
12611 register_peer_exten(peer, 0);
12612
12613 if (peer->dnsmgr)
12614 ast_dnsmgr_release(peer->dnsmgr);
12615
12616 if (peer->mwi_event_sub)
12617 ast_event_unsubscribe(peer->mwi_event_sub);
12618
12619 ast_string_field_free_memory(peer);
12620 }
12621
12622
12623 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12624 {
12625 struct iax2_peer *peer = NULL;
12626 struct ast_ha *oldha = NULL;
12627 int maskfound = 0;
12628 int found = 0;
12629 int firstpass = 1;
12630 struct iax2_peer tmp_peer = {
12631 .name = name,
12632 };
12633
12634 if (!temponly) {
12635 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12636 if (peer && !ast_test_flag64(peer, IAX_DELME))
12637 firstpass = 0;
12638 }
12639
12640 if (peer) {
12641 found++;
12642 if (firstpass) {
12643 oldha = peer->ha;
12644 peer->ha = NULL;
12645 }
12646 unlink_peer(peer);
12647 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12648 peer->expire = -1;
12649 peer->pokeexpire = -1;
12650 peer->sockfd = defaultsockfd;
12651 peer->addr.ss.ss_family = AF_INET;
12652 peer->addr.len = sizeof(struct sockaddr_in);
12653 if (ast_string_field_init(peer, 32))
12654 peer = peer_unref(peer);
12655 }
12656
12657 if (peer) {
12658 if (firstpass) {
12659 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12660 peer->encmethods = iax2_encryption;
12661 peer->adsi = adsi;
12662 ast_string_field_set(peer,secret,"");
12663 if (!found) {
12664 ast_string_field_set(peer, name, name);
12665 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12666 peer->expiry = min_reg_expire;
12667 }
12668 peer->prefs = prefs;
12669 peer->capability = iax2_capability;
12670 peer->smoothing = 0;
12671 peer->pokefreqok = DEFAULT_FREQ_OK;
12672 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12673 peer->maxcallno = 0;
12674 peercnt_modify((unsigned char) 0, 0, &peer->addr);
12675 peer->calltoken_required = CALLTOKEN_DEFAULT;
12676 ast_string_field_set(peer,context,"");
12677 ast_string_field_set(peer,peercontext,"");
12678 ast_clear_flag64(peer, IAX_HASCALLERID);
12679 ast_string_field_set(peer, cid_name, "");
12680 ast_string_field_set(peer, cid_num, "");
12681 ast_string_field_set(peer, mohinterpret, mohinterpret);
12682 ast_string_field_set(peer, mohsuggest, mohsuggest);
12683 }
12684
12685 if (!v) {
12686 v = alt;
12687 alt = NULL;
12688 }
12689 while(v) {
12690 if (!strcasecmp(v->name, "secret")) {
12691 ast_string_field_set(peer, secret, v->value);
12692 } else if (!strcasecmp(v->name, "mailbox")) {
12693 ast_string_field_set(peer, mailbox, v->value);
12694 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12695 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12696 ast_string_field_set(peer, mailbox, name);
12697 }
12698 } else if (!strcasecmp(v->name, "mohinterpret")) {
12699 ast_string_field_set(peer, mohinterpret, v->value);
12700 } else if (!strcasecmp(v->name, "mohsuggest")) {
12701 ast_string_field_set(peer, mohsuggest, v->value);
12702 } else if (!strcasecmp(v->name, "dbsecret")) {
12703 ast_string_field_set(peer, dbsecret, v->value);
12704 } else if (!strcasecmp(v->name, "trunk")) {
12705 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12706 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12707 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12708 ast_clear_flag64(peer, IAX_TRUNK);
12709 }
12710 } else if (!strcasecmp(v->name, "auth")) {
12711 peer->authmethods = get_auth_methods(v->value);
12712 } else if (!strcasecmp(v->name, "encryption")) {
12713 peer->encmethods |= get_encrypt_methods(v->value);
12714 if (!peer->encmethods) {
12715 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12716 }
12717 } else if (!strcasecmp(v->name, "forceencryption")) {
12718 if (ast_false(v->value)) {
12719 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12720 } else {
12721 peer->encmethods |= get_encrypt_methods(v->value);
12722 if (peer->encmethods) {
12723 ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12724 }
12725 }
12726 } else if (!strcasecmp(v->name, "transfer")) {
12727 if (!strcasecmp(v->value, "mediaonly")) {
12728 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12729 } else if (ast_true(v->value)) {
12730 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12731 } else
12732 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12733 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12734 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12735 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12736 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12737 } else if (!strcasecmp(v->name, "host")) {
12738 if (!strcasecmp(v->value, "dynamic")) {
12739
12740 ast_set_flag64(peer, IAX_DYNAMIC);
12741 if (!found) {
12742
12743
12744 if (ast_sockaddr_port(&peer->addr)) {
12745 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12746 }
12747 ast_sockaddr_setnull(&peer->addr);
12748 }
12749 } else {
12750
12751 ast_sched_thread_del(sched, peer->expire);
12752 ast_clear_flag64(peer, IAX_DYNAMIC);
12753 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12754 return peer_unref(peer);
12755 if (!ast_sockaddr_port(&peer->addr)) {
12756 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12757 }
12758 }
12759 if (!maskfound)
12760 inet_aton("255.255.255.255", &peer->mask);
12761 } else if (!strcasecmp(v->name, "defaultip")) {
12762 struct ast_sockaddr peer_defaddr_tmp;
12763
12764 peer_defaddr_tmp.ss.ss_family = AF_INET;
12765 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12766 return peer_unref(peer);
12767 }
12768 ast_sockaddr_to_sin(&peer_defaddr_tmp,
12769 &peer->defaddr);
12770 } else if (!strcasecmp(v->name, "sourceaddress")) {
12771 peer_set_srcaddr(peer, v->value);
12772 } else if (!strcasecmp(v->name, "permit") ||
12773 !strcasecmp(v->name, "deny")) {
12774 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12775 } else if (!strcasecmp(v->name, "mask")) {
12776 maskfound++;
12777 inet_aton(v->value, &peer->mask);
12778 } else if (!strcasecmp(v->name, "context")) {
12779 ast_string_field_set(peer, context, v->value);
12780 } else if (!strcasecmp(v->name, "regexten")) {
12781 ast_string_field_set(peer, regexten, v->value);
12782 } else if (!strcasecmp(v->name, "peercontext")) {
12783 ast_string_field_set(peer, peercontext, v->value);
12784 } else if (!strcasecmp(v->name, "port")) {
12785 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12786 peer->defaddr.sin_port = htons(atoi(v->value));
12787 } else {
12788 ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12789 }
12790 } else if (!strcasecmp(v->name, "username")) {
12791 ast_string_field_set(peer, username, v->value);
12792 } else if (!strcasecmp(v->name, "allow")) {
12793 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12794 } else if (!strcasecmp(v->name, "disallow")) {
12795 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12796 } else if (!strcasecmp(v->name, "callerid")) {
12797 if (!ast_strlen_zero(v->value)) {
12798 char name2[80];
12799 char num2[80];
12800 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12801 ast_string_field_set(peer, cid_name, name2);
12802 ast_string_field_set(peer, cid_num, num2);
12803 } else {
12804 ast_string_field_set(peer, cid_name, "");
12805 ast_string_field_set(peer, cid_num, "");
12806 }
12807 ast_set_flag64(peer, IAX_HASCALLERID);
12808 } else if (!strcasecmp(v->name, "fullname")) {
12809 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12810 ast_set_flag64(peer, IAX_HASCALLERID);
12811 } else if (!strcasecmp(v->name, "cid_number")) {
12812 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12813 ast_set_flag64(peer, IAX_HASCALLERID);
12814 } else if (!strcasecmp(v->name, "sendani")) {
12815 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12816 } else if (!strcasecmp(v->name, "inkeys")) {
12817 ast_string_field_set(peer, inkeys, v->value);
12818 } else if (!strcasecmp(v->name, "outkey")) {
12819 ast_string_field_set(peer, outkey, v->value);
12820 } else if (!strcasecmp(v->name, "qualify")) {
12821 if (!strcasecmp(v->value, "no")) {
12822 peer->maxms = 0;
12823 } else if (!strcasecmp(v->value, "yes")) {
12824 peer->maxms = DEFAULT_MAXMS;
12825 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12826 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);
12827 peer->maxms = 0;
12828 }
12829 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12830 peer->smoothing = ast_true(v->value);
12831 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12832 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12833 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);
12834 }
12835 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12836 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12837 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);
12838 }
12839 } else if (!strcasecmp(v->name, "timezone")) {
12840 ast_string_field_set(peer, zonetag, v->value);
12841 } else if (!strcasecmp(v->name, "adsi")) {
12842 peer->adsi = ast_true(v->value);
12843 } else if (!strcasecmp(v->name, "connectedline")) {
12844 if (ast_true(v->value)) {
12845 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12846 } else if (!strcasecmp(v->value, "send")) {
12847 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12848 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12849 } else if (!strcasecmp(v->value, "receive")) {
12850 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12851 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12852 } else {
12853 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12854 }
12855 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12856 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12857 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12858 } else {
12859 peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr);
12860 }
12861 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12862
12863 if (ast_false(v->value)) {
12864 peer->calltoken_required = CALLTOKEN_NO;
12865 } else if (!strcasecmp(v->value, "auto")) {
12866 peer->calltoken_required = CALLTOKEN_AUTO;
12867 } else if (ast_true(v->value)) {
12868 peer->calltoken_required = CALLTOKEN_YES;
12869 } else {
12870 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12871 }
12872 }
12873
12874 v = v->next;
12875 if (!v) {
12876 v = alt;
12877 alt = NULL;
12878 }
12879 }
12880 if (!peer->authmethods)
12881 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12882 ast_clear_flag64(peer, IAX_DELME);
12883 }
12884
12885 if (oldha)
12886 ast_free_ha(oldha);
12887
12888 if (!ast_strlen_zero(peer->mailbox)) {
12889 char *mailbox, *context;
12890 context = mailbox = ast_strdupa(peer->mailbox);
12891 strsep(&context, "@");
12892 if (ast_strlen_zero(context))
12893 context = "default";
12894 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12895 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12896 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12897 AST_EVENT_IE_END);
12898 }
12899
12900 return peer;
12901 }
12902
12903 static void user_destructor(void *obj)
12904 {
12905 struct iax2_user *user = obj;
12906
12907 ast_free_ha(user->ha);
12908 free_context(user->contexts);
12909 if(user->vars) {
12910 ast_variables_destroy(user->vars);
12911 user->vars = NULL;
12912 }
12913 ast_string_field_free_memory(user);
12914 }
12915
12916
12917 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12918 {
12919 struct iax2_user *user = NULL;
12920 struct iax2_context *con, *conl = NULL;
12921 struct ast_ha *oldha = NULL;
12922 struct iax2_context *oldcon = NULL;
12923 int format;
12924 int firstpass=1;
12925 int oldcurauthreq = 0;
12926 char *varname = NULL, *varval = NULL;
12927 struct ast_variable *tmpvar = NULL;
12928 struct iax2_user tmp_user = {
12929 .name = name,
12930 };
12931
12932 if (!temponly) {
12933 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12934 if (user && !ast_test_flag64(user, IAX_DELME))
12935 firstpass = 0;
12936 }
12937
12938 if (user) {
12939 if (firstpass) {
12940 oldcurauthreq = user->curauthreq;
12941 oldha = user->ha;
12942 oldcon = user->contexts;
12943 user->ha = NULL;
12944 user->contexts = NULL;
12945 }
12946
12947 ao2_unlink(users, user);
12948 } else {
12949 user = ao2_alloc(sizeof(*user), user_destructor);
12950 }
12951
12952 if (user) {
12953 if (firstpass) {
12954 ast_string_field_free_memory(user);
12955 memset(user, 0, sizeof(struct iax2_user));
12956 if (ast_string_field_init(user, 32)) {
12957 user = user_unref(user);
12958 goto cleanup;
12959 }
12960 user->maxauthreq = maxauthreq;
12961 user->curauthreq = oldcurauthreq;
12962 user->prefs = prefs;
12963 user->capability = iax2_capability;
12964 user->encmethods = iax2_encryption;
12965 user->adsi = adsi;
12966 user->calltoken_required = CALLTOKEN_DEFAULT;
12967 ast_string_field_set(user, name, name);
12968 ast_string_field_set(user, language, language);
12969 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);
12970 ast_clear_flag64(user, IAX_HASCALLERID);
12971 ast_string_field_set(user, cid_name, "");
12972 ast_string_field_set(user, cid_num, "");
12973 ast_string_field_set(user, accountcode, accountcode);
12974 ast_string_field_set(user, mohinterpret, mohinterpret);
12975 ast_string_field_set(user, mohsuggest, mohsuggest);
12976 }
12977 if (!v) {
12978 v = alt;
12979 alt = NULL;
12980 }
12981 while(v) {
12982 if (!strcasecmp(v->name, "context")) {
12983 con = build_context(v->value);
12984 if (con) {
12985 if (conl)
12986 conl->next = con;
12987 else
12988 user->contexts = con;
12989 conl = con;
12990 }
12991 } else if (!strcasecmp(v->name, "permit") ||
12992 !strcasecmp(v->name, "deny")) {
12993 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12994 } else if (!strcasecmp(v->name, "setvar")) {
12995 varname = ast_strdupa(v->value);
12996 if ((varval = strchr(varname, '='))) {
12997 *varval = '\0';
12998 varval++;
12999 if((tmpvar = ast_variable_new(varname, varval, ""))) {
13000 tmpvar->next = user->vars;
13001 user->vars = tmpvar;
13002 }
13003 }
13004 } else if (!strcasecmp(v->name, "allow")) {
13005 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
13006 } else if (!strcasecmp(v->name, "disallow")) {
13007 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
13008 } else if (!strcasecmp(v->name, "trunk")) {
13009 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
13010 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
13011 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
13012 ast_clear_flag64(user, IAX_TRUNK);
13013 }
13014 } else if (!strcasecmp(v->name, "auth")) {
13015 user->authmethods = get_auth_methods(v->value);
13016 } else if (!strcasecmp(v->name, "encryption")) {
13017 user->encmethods |= get_encrypt_methods(v->value);
13018 if (!user->encmethods) {
13019 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
13020 }
13021 } else if (!strcasecmp(v->name, "forceencryption")) {
13022 if (ast_false(v->value)) {
13023 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
13024 } else {
13025 user->encmethods |= get_encrypt_methods(v->value);
13026 if (user->encmethods) {
13027 ast_set_flag64(user, IAX_FORCE_ENCRYPT);
13028 }
13029 }
13030 } else if (!strcasecmp(v->name, "transfer")) {
13031 if (!strcasecmp(v->value, "mediaonly")) {
13032 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13033 } else if (ast_true(v->value)) {
13034 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13035 } else
13036 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13037 } else if (!strcasecmp(v->name, "codecpriority")) {
13038 if(!strcasecmp(v->value, "caller"))
13039 ast_set_flag64(user, IAX_CODEC_USER_FIRST);
13040 else if(!strcasecmp(v->value, "disabled"))
13041 ast_set_flag64(user, IAX_CODEC_NOPREFS);
13042 else if(!strcasecmp(v->value, "reqonly")) {
13043 ast_set_flag64(user, IAX_CODEC_NOCAP);
13044 ast_set_flag64(user, IAX_CODEC_NOPREFS);
13045 }
13046 } else if (!strcasecmp(v->name, "immediate")) {
13047 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
13048 } else if (!strcasecmp(v->name, "jitterbuffer")) {
13049 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
13050 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
13051 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
13052 } else if (!strcasecmp(v->name, "dbsecret")) {
13053 ast_string_field_set(user, dbsecret, v->value);
13054 } else if (!strcasecmp(v->name, "secret")) {
13055 if (!ast_strlen_zero(user->secret)) {
13056 char *old = ast_strdupa(user->secret);
13057
13058 ast_string_field_build(user, secret, "%s;%s", old, v->value);
13059 } else
13060 ast_string_field_set(user, secret, v->value);
13061 } else if (!strcasecmp(v->name, "callerid")) {
13062 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
13063 char name2[80];
13064 char num2[80];
13065 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
13066 ast_string_field_set(user, cid_name, name2);
13067 ast_string_field_set(user, cid_num, num2);
13068 ast_set_flag64(user, IAX_HASCALLERID);
13069 } else {
13070 ast_clear_flag64(user, IAX_HASCALLERID);
13071 ast_string_field_set(user, cid_name, "");
13072 ast_string_field_set(user, cid_num, "");
13073 }
13074 } else if (!strcasecmp(v->name, "fullname")) {
13075 if (!ast_strlen_zero(v->value)) {
13076 ast_string_field_set(user, cid_name, v->value);
13077 ast_set_flag64(user, IAX_HASCALLERID);
13078 } else {
13079 ast_string_field_set(user, cid_name, "");
13080 if (ast_strlen_zero(user->cid_num))
13081 ast_clear_flag64(user, IAX_HASCALLERID);
13082 }
13083 } else if (!strcasecmp(v->name, "cid_number")) {
13084 if (!ast_strlen_zero(v->value)) {
13085 ast_string_field_set(user, cid_num, v->value);
13086 ast_set_flag64(user, IAX_HASCALLERID);
13087 } else {
13088 ast_string_field_set(user, cid_num, "");
13089 if (ast_strlen_zero(user->cid_name))
13090 ast_clear_flag64(user, IAX_HASCALLERID);
13091 }
13092 } else if (!strcasecmp(v->name, "accountcode")) {
13093 ast_string_field_set(user, accountcode, v->value);
13094 } else if (!strcasecmp(v->name, "mohinterpret")) {
13095 ast_string_field_set(user, mohinterpret, v->value);
13096 } else if (!strcasecmp(v->name, "mohsuggest")) {
13097 ast_string_field_set(user, mohsuggest, v->value);
13098 } else if (!strcasecmp(v->name, "parkinglot")) {
13099 ast_string_field_set(user, parkinglot, v->value);
13100 } else if (!strcasecmp(v->name, "language")) {
13101 ast_string_field_set(user, language, v->value);
13102 } else if (!strcasecmp(v->name, "amaflags")) {
13103 format = ast_cdr_amaflags2int(v->value);
13104 if (format < 0) {
13105 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13106 } else {
13107 user->amaflags = format;
13108 }
13109 } else if (!strcasecmp(v->name, "inkeys")) {
13110 ast_string_field_set(user, inkeys, v->value);
13111 } else if (!strcasecmp(v->name, "maxauthreq")) {
13112 user->maxauthreq = atoi(v->value);
13113 if (user->maxauthreq < 0)
13114 user->maxauthreq = 0;
13115 } else if (!strcasecmp(v->name, "adsi")) {
13116 user->adsi = ast_true(v->value);
13117 } else if (!strcasecmp(v->name, "connectedline")) {
13118 if (ast_true(v->value)) {
13119 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13120 } else if (!strcasecmp(v->value, "send")) {
13121 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
13122 ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
13123 } else if (!strcasecmp(v->value, "receive")) {
13124 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
13125 ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
13126 } else {
13127 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13128 }
13129 } else if (!strcasecmp(v->name, "requirecalltoken")) {
13130
13131 if (ast_false(v->value)) {
13132 user->calltoken_required = CALLTOKEN_NO;
13133 } else if (!strcasecmp(v->value, "auto")) {
13134 user->calltoken_required = CALLTOKEN_AUTO;
13135 } else if (ast_true(v->value)) {
13136 user->calltoken_required = CALLTOKEN_YES;
13137 } else {
13138 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
13139 }
13140 }
13141
13142 v = v->next;
13143 if (!v) {
13144 v = alt;
13145 alt = NULL;
13146 }
13147 }
13148 if (!user->authmethods) {
13149 if (!ast_strlen_zero(user->secret)) {
13150 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
13151 if (!ast_strlen_zero(user->inkeys))
13152 user->authmethods |= IAX_AUTH_RSA;
13153 } else if (!ast_strlen_zero(user->inkeys)) {
13154 user->authmethods = IAX_AUTH_RSA;
13155 } else {
13156 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
13157 }
13158 }
13159 ast_clear_flag64(user, IAX_DELME);
13160 }
13161 cleanup:
13162 if (oldha)
13163 ast_free_ha(oldha);
13164 if (oldcon)
13165 free_context(oldcon);
13166 return user;
13167 }
13168
13169 static int peer_delme_cb(void *obj, void *arg, int flags)
13170 {
13171 struct iax2_peer *peer = obj;
13172
13173 ast_set_flag64(peer, IAX_DELME);
13174
13175 return 0;
13176 }
13177
13178 static int user_delme_cb(void *obj, void *arg, int flags)
13179 {
13180 struct iax2_user *user = obj;
13181
13182 ast_set_flag64(user, IAX_DELME);
13183
13184 return 0;
13185 }
13186
13187 static void delete_users(void)
13188 {
13189 struct iax2_registry *reg;
13190
13191 ao2_callback(users, 0, user_delme_cb, NULL);
13192
13193 AST_LIST_LOCK(®istrations);
13194 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
13195 if (sched) {
13196 ast_sched_thread_del(sched, reg->expire);
13197 }
13198 if (reg->callno) {
13199 int callno = reg->callno;
13200 ast_mutex_lock(&iaxsl[callno]);
13201 if (iaxs[callno]) {
13202 iaxs[callno]->reg = NULL;
13203 iax2_destroy(callno);
13204 }
13205 ast_mutex_unlock(&iaxsl[callno]);
13206 }
13207 if (reg->dnsmgr)
13208 ast_dnsmgr_release(reg->dnsmgr);
13209 ast_free(reg);
13210 }
13211 AST_LIST_UNLOCK(®istrations);
13212
13213 ao2_callback(peers, 0, peer_delme_cb, NULL);
13214 }
13215
13216 static void prune_users(void)
13217 {
13218 struct iax2_user *user;
13219 struct ao2_iterator i;
13220
13221 i = ao2_iterator_init(users, 0);
13222 while ((user = ao2_iterator_next(&i))) {
13223 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
13224 ao2_unlink(users, user);
13225 }
13226 user_unref(user);
13227 }
13228 ao2_iterator_destroy(&i);
13229 }
13230
13231
13232 static void prune_peers(void)
13233 {
13234 struct iax2_peer *peer;
13235 struct ao2_iterator i;
13236
13237 i = ao2_iterator_init(peers, 0);
13238 while ((peer = ao2_iterator_next(&i))) {
13239 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
13240 unlink_peer(peer);
13241 }
13242 peer_unref(peer);
13243 }
13244 ao2_iterator_destroy(&i);
13245 }
13246
13247 static void set_config_destroy(void)
13248 {
13249 strcpy(accountcode, "");
13250 strcpy(language, "");
13251 strcpy(mohinterpret, "");
13252 strcpy(mohsuggest, "");
13253 trunkmaxsize = MAX_TRUNKDATA;
13254 amaflags = 0;
13255 delayreject = 0;
13256 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF |
13257 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13258 delete_users();
13259 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
13260 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
13261 }
13262
13263
13264 static int set_config(const char *config_file, int reload)
13265 {
13266 struct ast_config *cfg, *ucfg;
13267 format_t capability = iax2_capability;
13268 struct ast_variable *v;
13269 char *cat;
13270 const char *utype;
13271 const char *tosval;
13272 int format;
13273 int portno = IAX_DEFAULT_PORTNO;
13274 int x;
13275 int mtuv;
13276 int subscribe_network_change = 1;
13277 struct iax2_user *user;
13278 struct iax2_peer *peer;
13279 struct ast_netsock *ns;
13280 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13281 #if 0
13282 static unsigned short int last_port=0;
13283 #endif
13284
13285 cfg = ast_config_load(config_file, config_flags);
13286
13287 if (!cfg) {
13288 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13289 return -1;
13290 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13291 ucfg = ast_config_load("users.conf", config_flags);
13292 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13293 return 0;
13294
13295 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13296 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13297 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13298 ast_config_destroy(ucfg);
13299 return 0;
13300 }
13301 if (!cfg) {
13302
13303 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file);
13304 return -1;
13305 }
13306 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13307 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13308 return 0;
13309 } else {
13310 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13311 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13312 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
13313 ast_config_destroy(cfg);
13314 return 0;
13315 }
13316 }
13317
13318 if (reload) {
13319 set_config_destroy();
13320 }
13321
13322
13323 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13324
13325
13326 memset(&globalflags, 0, sizeof(globalflags));
13327 ast_set_flag64(&globalflags, IAX_RTUPDATE);
13328 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13329
13330 #ifdef SO_NO_CHECK
13331 nochecksums = 0;
13332 #endif
13333
13334 default_parkinglot[0] = '\0';
13335
13336 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13337 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13338 global_max_trunk_mtu = MAX_TRUNK_MTU;
13339 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13340 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13341
13342 maxauthreq = 3;
13343
13344 srvlookup = 0;
13345
13346 v = ast_variable_browse(cfg, "general");
13347
13348
13349 tosval = ast_variable_retrieve(cfg, "general", "tos");
13350 if (tosval) {
13351 if (ast_str2tos(tosval, &qos.tos))
13352 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13353 }
13354
13355 tosval = ast_variable_retrieve(cfg, "general", "cos");
13356 if (tosval) {
13357 if (ast_str2cos(tosval, &qos.cos))
13358 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13359 }
13360 while(v) {
13361 if (!strcasecmp(v->name, "bindport")){
13362 if (reload)
13363 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13364 else
13365 portno = atoi(v->value);
13366 } else if (!strcasecmp(v->name, "pingtime"))
13367 ping_time = atoi(v->value);
13368 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13369 if (reload) {
13370 if (atoi(v->value) != iaxthreadcount)
13371 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13372 } else {
13373 iaxthreadcount = atoi(v->value);
13374 if (iaxthreadcount < 1) {
13375 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13376 iaxthreadcount = 1;
13377 } else if (iaxthreadcount > 256) {
13378 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13379 iaxthreadcount = 256;
13380 }
13381 }
13382 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13383 if (reload) {
13384 AST_LIST_LOCK(&dynamic_list);
13385 iaxmaxthreadcount = atoi(v->value);
13386 AST_LIST_UNLOCK(&dynamic_list);
13387 } else {
13388 iaxmaxthreadcount = atoi(v->value);
13389 if (iaxmaxthreadcount < 0) {
13390 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13391 iaxmaxthreadcount = 0;
13392 } else if (iaxmaxthreadcount > 256) {
13393 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13394 iaxmaxthreadcount = 256;
13395 }
13396 }
13397 } else if (!strcasecmp(v->name, "nochecksums")) {
13398 #ifdef SO_NO_CHECK
13399 if (ast_true(v->value))
13400 nochecksums = 1;
13401 else
13402 nochecksums = 0;
13403 #else
13404 if (ast_true(v->value))
13405 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13406 #endif
13407 }
13408 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13409 maxjitterbuffer = atoi(v->value);
13410 else if (!strcasecmp(v->name, "resyncthreshold"))
13411 resyncthreshold = atoi(v->value);
13412 else if (!strcasecmp(v->name, "maxjitterinterps"))
13413 maxjitterinterps = atoi(v->value);
13414 else if (!strcasecmp(v->name, "jittertargetextra"))
13415 jittertargetextra = atoi(v->value);
13416 else if (!strcasecmp(v->name, "lagrqtime"))
13417 lagrq_time = atoi(v->value);
13418 else if (!strcasecmp(v->name, "maxregexpire"))
13419 max_reg_expire = atoi(v->value);
13420 else if (!strcasecmp(v->name, "minregexpire"))
13421 min_reg_expire = atoi(v->value);
13422 else if (!strcasecmp(v->name, "bindaddr")) {
13423 if (reload) {
13424 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13425 } else {
13426 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13427 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13428 } else {
13429 if (strchr(v->value, ':'))
13430 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13431 else
13432 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13433 if (defaultsockfd < 0)
13434 defaultsockfd = ast_netsock_sockfd(ns);
13435 ast_netsock_unref(ns);
13436 }
13437 }
13438 } else if (!strcasecmp(v->name, "authdebug")) {
13439 authdebug = ast_true(v->value);
13440 } else if (!strcasecmp(v->name, "encryption")) {
13441 iax2_encryption |= get_encrypt_methods(v->value);
13442 if (!iax2_encryption) {
13443 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13444 }
13445 } else if (!strcasecmp(v->name, "forceencryption")) {
13446 if (ast_false(v->value)) {
13447 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13448 } else {
13449 iax2_encryption |= get_encrypt_methods(v->value);
13450 if (iax2_encryption) {
13451 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13452 }
13453 }
13454 } else if (!strcasecmp(v->name, "transfer")) {
13455 if (!strcasecmp(v->value, "mediaonly")) {
13456 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13457 } else if (ast_true(v->value)) {
13458 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13459 } else
13460 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13461 } else if (!strcasecmp(v->name, "codecpriority")) {
13462 if(!strcasecmp(v->value, "caller"))
13463 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13464 else if(!strcasecmp(v->value, "disabled"))
13465 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13466 else if(!strcasecmp(v->value, "reqonly")) {
13467 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13468 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13469 }
13470 } else if (!strcasecmp(v->name, "jitterbuffer"))
13471 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13472 else if (!strcasecmp(v->name, "forcejitterbuffer"))
13473 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13474 else if (!strcasecmp(v->name, "delayreject"))
13475 delayreject = ast_true(v->value);
13476 else if (!strcasecmp(v->name, "allowfwdownload"))
13477 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13478 else if (!strcasecmp(v->name, "rtcachefriends"))
13479 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13480 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13481 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13482 else if (!strcasecmp(v->name, "rtupdate"))
13483 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13484 else if (!strcasecmp(v->name, "rtsavesysname"))
13485 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13486 else if (!strcasecmp(v->name, "trunktimestamps"))
13487 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13488 else if (!strcasecmp(v->name, "rtautoclear")) {
13489 int i = atoi(v->value);
13490 if(i > 0)
13491 global_rtautoclear = i;
13492 else
13493 i = 0;
13494 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13495 } else if (!strcasecmp(v->name, "trunkfreq")) {
13496 trunkfreq = atoi(v->value);
13497 if (trunkfreq < 10) {
13498 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13499 trunkfreq = 10;
13500 } else if (trunkfreq > 1000) {
13501 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13502 trunkfreq = 1000;
13503 }
13504 if (timer) {
13505 ast_timer_set_rate(timer, 1000 / trunkfreq);
13506 }
13507 } else if (!strcasecmp(v->name, "trunkmtu")) {
13508 mtuv = atoi(v->value);
13509 if (mtuv == 0 )
13510 global_max_trunk_mtu = 0;
13511 else if (mtuv >= 172 && mtuv < 4000)
13512 global_max_trunk_mtu = mtuv;
13513 else
13514 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13515 mtuv, v->lineno);
13516 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13517 trunkmaxsize = atoi(v->value);
13518 if (trunkmaxsize == 0)
13519 trunkmaxsize = MAX_TRUNKDATA;
13520 } else if (!strcasecmp(v->name, "autokill")) {
13521 if (sscanf(v->value, "%30d", &x) == 1) {
13522 if (x >= 0)
13523 autokill = x;
13524 else
13525 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13526 } else if (ast_true(v->value)) {
13527 autokill = DEFAULT_MAXMS;
13528 } else {
13529 autokill = 0;
13530 }
13531 } else if (!strcasecmp(v->name, "bandwidth")) {
13532 if (!strcasecmp(v->value, "low")) {
13533 capability = IAX_CAPABILITY_LOWBANDWIDTH;
13534 } else if (!strcasecmp(v->value, "medium")) {
13535 capability = IAX_CAPABILITY_MEDBANDWIDTH;
13536 } else if (!strcasecmp(v->value, "high")) {
13537 capability = IAX_CAPABILITY_FULLBANDWIDTH;
13538 } else
13539 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13540 } else if (!strcasecmp(v->name, "allow")) {
13541 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13542 } else if (!strcasecmp(v->name, "disallow")) {
13543 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13544 } else if (!strcasecmp(v->name, "register")) {
13545 iax2_register(v->value, v->lineno);
13546 } else if (!strcasecmp(v->name, "iaxcompat")) {
13547 iaxcompat = ast_true(v->value);
13548 } else if (!strcasecmp(v->name, "regcontext")) {
13549 ast_copy_string(regcontext, v->value, sizeof(regcontext));
13550
13551 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13552 } else if (!strcasecmp(v->name, "tos")) {
13553 if (ast_str2tos(v->value, &qos.tos))
13554 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13555 } else if (!strcasecmp(v->name, "cos")) {
13556 if (ast_str2cos(v->value, &qos.cos))
13557 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13558 } else if (!strcasecmp(v->name, "parkinglot")) {
13559 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13560 } else if (!strcasecmp(v->name, "accountcode")) {
13561 ast_copy_string(accountcode, v->value, sizeof(accountcode));
13562 } else if (!strcasecmp(v->name, "mohinterpret")) {
13563 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13564 } else if (!strcasecmp(v->name, "mohsuggest")) {
13565 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13566 } else if (!strcasecmp(v->name, "amaflags")) {
13567 format = ast_cdr_amaflags2int(v->value);
13568 if (format < 0) {
13569 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13570 } else {
13571 amaflags = format;
13572 }
13573 } else if (!strcasecmp(v->name, "language")) {
13574 ast_copy_string(language, v->value, sizeof(language));
13575 } else if (!strcasecmp(v->name, "maxauthreq")) {
13576 maxauthreq = atoi(v->value);
13577 if (maxauthreq < 0)
13578 maxauthreq = 0;
13579 } else if (!strcasecmp(v->name, "adsi")) {
13580 adsi = ast_true(v->value);
13581 } else if (!strcasecmp(v->name, "srvlookup")) {
13582 srvlookup = ast_true(v->value);
13583 } else if (!strcasecmp(v->name, "connectedline")) {
13584 if (ast_true(v->value)) {
13585 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13586 } else if (!strcasecmp(v->value, "send")) {
13587 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13588 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13589 } else if (!strcasecmp(v->value, "receive")) {
13590 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13591 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13592 } else {
13593 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13594 }
13595 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13596 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13597 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
13598 }
13599 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13600 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13601 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);
13602 }
13603 } else if (!strcasecmp(v->name, "calltokenoptional")) {
13604 if (add_calltoken_ignore(v->value)) {
13605 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13606 }
13607 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13608 if (ast_true(v->value)) {
13609 subscribe_network_change = 1;
13610 } else if (ast_false(v->value)) {
13611 subscribe_network_change = 0;
13612 } else {
13613 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13614 }
13615 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13616 if (ast_true(v->value)) {
13617 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13618 } else if (ast_false(v->value)) {
13619 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13620 } else {
13621 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13622 }
13623 }
13624
13625 v = v->next;
13626 }
13627
13628 if (subscribe_network_change) {
13629 network_change_event_subscribe();
13630 } else {
13631 network_change_event_unsubscribe();
13632 }
13633
13634 if (defaultsockfd < 0) {
13635 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13636 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13637 } else {
13638 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13639 defaultsockfd = ast_netsock_sockfd(ns);
13640 ast_netsock_unref(ns);
13641 }
13642 }
13643 if (reload) {
13644 ast_netsock_release(outsock);
13645 outsock = ast_netsock_list_alloc();
13646 if (!outsock) {
13647 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13648 return -1;
13649 }
13650 ast_netsock_init(outsock);
13651 }
13652
13653 if (min_reg_expire > max_reg_expire) {
13654 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13655 min_reg_expire, max_reg_expire, max_reg_expire);
13656 min_reg_expire = max_reg_expire;
13657 }
13658 iax2_capability = capability;
13659
13660 if (ucfg) {
13661 struct ast_variable *gen;
13662 int genhasiax;
13663 int genregisteriax;
13664 const char *hasiax, *registeriax;
13665
13666 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13667 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13668 gen = ast_variable_browse(ucfg, "general");
13669 cat = ast_category_browse(ucfg, NULL);
13670 while (cat) {
13671 if (strcasecmp(cat, "general")) {
13672 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13673 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13674 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13675
13676 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13677 if (user) {
13678 ao2_link(users, user);
13679 user = user_unref(user);
13680 }
13681 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13682 if (peer) {
13683 if (ast_test_flag64(peer, IAX_DYNAMIC))
13684 reg_source_db(peer);
13685 ao2_link(peers, peer);
13686 peer = peer_unref(peer);
13687 }
13688 }
13689 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13690 char tmp[256];
13691 const char *host = ast_variable_retrieve(ucfg, cat, "host");
13692 const char *username = ast_variable_retrieve(ucfg, cat, "username");
13693 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13694 if (!host)
13695 host = ast_variable_retrieve(ucfg, "general", "host");
13696 if (!username)
13697 username = ast_variable_retrieve(ucfg, "general", "username");
13698 if (!secret)
13699 secret = ast_variable_retrieve(ucfg, "general", "secret");
13700 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13701 if (!ast_strlen_zero(secret))
13702 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13703 else
13704 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13705 iax2_register(tmp, 0);
13706 }
13707 }
13708 }
13709 cat = ast_category_browse(ucfg, cat);
13710 }
13711 ast_config_destroy(ucfg);
13712 }
13713
13714 cat = ast_category_browse(cfg, NULL);
13715 while(cat) {
13716 if (strcasecmp(cat, "general")) {
13717 utype = ast_variable_retrieve(cfg, cat, "type");
13718 if (!strcasecmp(cat, "callnumberlimits")) {
13719 build_callno_limits(ast_variable_browse(cfg, cat));
13720 } else if (utype) {
13721 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13722 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13723 if (user) {
13724 ao2_link(users, user);
13725 user = user_unref(user);
13726 }
13727 }
13728 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13729 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13730 if (peer) {
13731 if (ast_test_flag64(peer, IAX_DYNAMIC))
13732 reg_source_db(peer);
13733 ao2_link(peers, peer);
13734 peer = peer_unref(peer);
13735 }
13736 } else if (strcasecmp(utype, "user")) {
13737 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13738 }
13739 } else
13740 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13741 }
13742 cat = ast_category_browse(cfg, cat);
13743 }
13744 ast_config_destroy(cfg);
13745 return 1;
13746 }
13747
13748 static void poke_all_peers(void)
13749 {
13750 struct ao2_iterator i;
13751 struct iax2_peer *peer;
13752
13753 i = ao2_iterator_init(peers, 0);
13754 while ((peer = ao2_iterator_next(&i))) {
13755 iax2_poke_peer(peer, 0);
13756 peer_unref(peer);
13757 }
13758 ao2_iterator_destroy(&i);
13759 }
13760 static int reload_config(void)
13761 {
13762 static const char config[] = "iax.conf";
13763 struct iax2_registry *reg;
13764
13765 if (set_config(config, 1) > 0) {
13766 prune_peers();
13767 prune_users();
13768 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13769 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13770 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13771 trunk_timed = trunk_untimed = 0;
13772 trunk_nmaxmtu = trunk_maxmtu = 0;
13773 memset(&debugaddr, '\0', sizeof(debugaddr));
13774
13775 AST_LIST_LOCK(®istrations);
13776 AST_LIST_TRAVERSE(®istrations, reg, entry)
13777 iax2_do_register(reg);
13778 AST_LIST_UNLOCK(®istrations);
13779
13780
13781 poke_all_peers();
13782 }
13783
13784 reload_firmware(0);
13785 iax_provision_reload(1);
13786 ast_unload_realtime("iaxpeers");
13787
13788 return 0;
13789 }
13790
13791 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13792 {
13793 switch (cmd) {
13794 case CLI_INIT:
13795 e->command = "iax2 reload";
13796 e->usage =
13797 "Usage: iax2 reload\n"
13798 " Reloads IAX configuration from iax.conf\n";
13799 return NULL;
13800 case CLI_GENERATE:
13801 return NULL;
13802 }
13803
13804 reload_config();
13805
13806 return CLI_SUCCESS;
13807 }
13808
13809 static int reload(void)
13810 {
13811 return reload_config();
13812 }
13813
13814 static int cache_get_callno_locked(const char *data)
13815 {
13816 struct sockaddr_in sin;
13817 int x;
13818 int callno;
13819 struct iax_ie_data ied;
13820 struct create_addr_info cai;
13821 struct parsed_dial_string pds;
13822 char *tmpstr;
13823
13824 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13825
13826
13827 if (!ast_mutex_trylock(&iaxsl[x])) {
13828 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13829 return x;
13830 ast_mutex_unlock(&iaxsl[x]);
13831 }
13832 }
13833
13834
13835
13836 memset(&cai, 0, sizeof(cai));
13837 memset(&ied, 0, sizeof(ied));
13838 memset(&pds, 0, sizeof(pds));
13839
13840 tmpstr = ast_strdupa(data);
13841 parse_dial_string(tmpstr, &pds);
13842
13843 if (ast_strlen_zero(pds.peer)) {
13844 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13845 return -1;
13846 }
13847
13848
13849 if (create_addr(pds.peer, NULL, &sin, &cai))
13850 return -1;
13851
13852 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13853 pds.peer, pds.username, pds.password, pds.context);
13854
13855 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13856 if (callno < 1) {
13857 ast_log(LOG_WARNING, "Unable to create call\n");
13858 return -1;
13859 }
13860
13861 ast_string_field_set(iaxs[callno], dproot, data);
13862 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13863
13864 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13865 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13866
13867
13868
13869 if (pds.exten)
13870 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13871 if (pds.username)
13872 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13873 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13874 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13875
13876 if (pds.password)
13877 ast_string_field_set(iaxs[callno], secret, pds.password);
13878 if (pds.key)
13879 ast_string_field_set(iaxs[callno], outkey, pds.key);
13880
13881 add_empty_calltoken_ie(iaxs[callno], &ied);
13882 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13883
13884 return callno;
13885 }
13886
13887 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13888 {
13889 struct iax2_dpcache *dp = NULL;
13890 struct timeval now = ast_tvnow();
13891 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13892 struct ast_channel *c = NULL;
13893 struct ast_frame *f = NULL;
13894
13895 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13896 if (ast_tvcmp(now, dp->expiry) > 0) {
13897 AST_LIST_REMOVE_CURRENT(cache_list);
13898 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13899 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13900 else
13901 ast_free(dp);
13902 continue;
13903 }
13904 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13905 break;
13906 }
13907 AST_LIST_TRAVERSE_SAFE_END;
13908
13909 if (!dp) {
13910
13911
13912 if ((callno = cache_get_callno_locked(data)) < 0) {
13913 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13914 return NULL;
13915 }
13916 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13917 ast_mutex_unlock(&iaxsl[callno]);
13918 return NULL;
13919 }
13920 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13921 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13922 dp->expiry = ast_tvnow();
13923 dp->orig = dp->expiry;
13924
13925 dp->expiry.tv_sec += iaxdefaultdpcache;
13926 dp->flags = CACHE_FLAG_PENDING;
13927 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13928 dp->waiters[x] = -1;
13929
13930 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13931 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13932
13933 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13934 iax2_dprequest(dp, callno);
13935 ast_mutex_unlock(&iaxsl[callno]);
13936 }
13937
13938
13939 if (dp->flags & CACHE_FLAG_PENDING) {
13940 struct timeval start;
13941 int ms;
13942
13943
13944 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13945
13946 if (dp->waiters[x] < 0)
13947 break;
13948 }
13949 if (x >= ARRAY_LEN(dp->waiters)) {
13950 ast_log(LOG_WARNING, "No more waiter positions available\n");
13951 return NULL;
13952 }
13953 if (pipe(com)) {
13954 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13955 return NULL;
13956 }
13957 dp->waiters[x] = com[1];
13958
13959 timeout = iaxdefaulttimeout * 1000;
13960
13961 AST_LIST_UNLOCK(&dpcache);
13962
13963 if (chan)
13964 old = ast_channel_defer_dtmf(chan);
13965 doabort = 0;
13966 start = ast_tvnow();
13967 while ((ms = ast_remaining_ms(start, timeout))) {
13968 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms);
13969 if (outfd > -1)
13970 break;
13971 if (!c)
13972 continue;
13973 if (!(f = ast_read(c))) {
13974 doabort = 1;
13975 break;
13976 }
13977 ast_frfree(f);
13978 }
13979 if (!ms) {
13980 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13981 }
13982 AST_LIST_LOCK(&dpcache);
13983 dp->waiters[x] = -1;
13984 close(com[1]);
13985 close(com[0]);
13986 if (doabort) {
13987
13988
13989 if (!old && chan)
13990 ast_channel_undefer_dtmf(chan);
13991 return NULL;
13992 }
13993 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13994
13995 if (dp->flags & CACHE_FLAG_PENDING) {
13996
13997
13998 dp->flags &= ~CACHE_FLAG_PENDING;
13999 dp->flags |= CACHE_FLAG_TIMEOUT;
14000
14001
14002 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
14003 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
14004 if (dp->waiters[x] > -1) {
14005 if (write(dp->waiters[x], "asdf", 4) < 0) {
14006 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
14007 }
14008 }
14009 }
14010 }
14011 }
14012
14013 if (!old && chan)
14014 ast_channel_undefer_dtmf(chan);
14015 }
14016 return dp;
14017 }
14018
14019
14020 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14021 {
14022 int res = 0;
14023 struct iax2_dpcache *dp = NULL;
14024 #if 0
14025 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14026 #endif
14027 if ((priority != 1) && (priority != 2))
14028 return 0;
14029
14030 AST_LIST_LOCK(&dpcache);
14031 if ((dp = find_cache(chan, data, context, exten, priority))) {
14032 if (dp->flags & CACHE_FLAG_EXISTS)
14033 res = 1;
14034 } else {
14035 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14036 }
14037 AST_LIST_UNLOCK(&dpcache);
14038
14039 return res;
14040 }
14041
14042
14043 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14044 {
14045 int res = 0;
14046 struct iax2_dpcache *dp = NULL;
14047 #if 0
14048 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14049 #endif
14050 if ((priority != 1) && (priority != 2))
14051 return 0;
14052
14053 AST_LIST_LOCK(&dpcache);
14054 if ((dp = find_cache(chan, data, context, exten, priority))) {
14055 if (dp->flags & CACHE_FLAG_CANEXIST)
14056 res = 1;
14057 } else {
14058 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14059 }
14060 AST_LIST_UNLOCK(&dpcache);
14061
14062 return res;
14063 }
14064
14065
14066 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14067 {
14068 int res = 0;
14069 struct iax2_dpcache *dp = NULL;
14070 #if 0
14071 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
14072 #endif
14073 if ((priority != 1) && (priority != 2))
14074 return 0;
14075
14076 AST_LIST_LOCK(&dpcache);
14077 if ((dp = find_cache(chan, data, context, exten, priority))) {
14078 if (dp->flags & CACHE_FLAG_MATCHMORE)
14079 res = 1;
14080 } else {
14081 ast_log(LOG_WARNING, "Unable to make DP cache\n");
14082 }
14083 AST_LIST_UNLOCK(&dpcache);
14084
14085 return res;
14086 }
14087
14088
14089 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
14090 {
14091 char odata[256];
14092 char req[256];
14093 char *ncontext;
14094 struct iax2_dpcache *dp = NULL;
14095 struct ast_app *dial = NULL;
14096 #if 0
14097 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);
14098 #endif
14099 if (priority == 2) {
14100
14101 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
14102 if (dialstatus) {
14103 dial = pbx_findapp(dialstatus);
14104 if (dial)
14105 pbx_exec(chan, dial, "");
14106 }
14107 return -1;
14108 } else if (priority != 1)
14109 return -1;
14110
14111 AST_LIST_LOCK(&dpcache);
14112 if ((dp = find_cache(chan, data, context, exten, priority))) {
14113 if (dp->flags & CACHE_FLAG_EXISTS) {
14114 ast_copy_string(odata, data, sizeof(odata));
14115 ncontext = strchr(odata, '/');
14116 if (ncontext) {
14117 *ncontext = '\0';
14118 ncontext++;
14119 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
14120 } else {
14121 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
14122 }
14123 ast_verb(3, "Executing Dial('%s')\n", req);
14124 } else {
14125 AST_LIST_UNLOCK(&dpcache);
14126 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
14127 return -1;
14128 }
14129 }
14130 AST_LIST_UNLOCK(&dpcache);
14131
14132 if ((dial = pbx_findapp("Dial")))
14133 return pbx_exec(chan, dial, req);
14134 else
14135 ast_log(LOG_WARNING, "No dial application registered\n");
14136
14137 return -1;
14138 }
14139
14140 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
14141 {
14142 struct iax2_peer *peer;
14143 char *peername, *colname;
14144
14145 peername = ast_strdupa(data);
14146
14147
14148 if (!strcmp(peername,"CURRENTCHANNEL")) {
14149 unsigned short callno;
14150 if (!chan || chan->tech != &iax2_tech) {
14151 return -1;
14152 }
14153 callno = PTR_TO_CALLNO(chan->tech_pvt);
14154 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
14155 return 0;
14156 }
14157
14158 if ((colname = strchr(peername, ',')))
14159 *colname++ = '\0';
14160 else
14161 colname = "ip";
14162
14163 if (!(peer = find_peer(peername, 1)))
14164 return -1;
14165
14166 if (!strcasecmp(colname, "ip")) {
14167 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
14168 } else if (!strcasecmp(colname, "status")) {
14169 peer_status(peer, buf, len);
14170 } else if (!strcasecmp(colname, "mailbox")) {
14171 ast_copy_string(buf, peer->mailbox, len);
14172 } else if (!strcasecmp(colname, "context")) {
14173 ast_copy_string(buf, peer->context, len);
14174 } else if (!strcasecmp(colname, "expire")) {
14175 snprintf(buf, len, "%d", peer->expire);
14176 } else if (!strcasecmp(colname, "dynamic")) {
14177 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
14178 } else if (!strcasecmp(colname, "callerid_name")) {
14179 ast_copy_string(buf, peer->cid_name, len);
14180 } else if (!strcasecmp(colname, "callerid_num")) {
14181 ast_copy_string(buf, peer->cid_num, len);
14182 } else if (!strcasecmp(colname, "codecs")) {
14183 ast_getformatname_multiple(buf, len -1, peer->capability);
14184 } else if (!strncasecmp(colname, "codec[", 6)) {
14185 char *codecnum, *ptr;
14186 int codec = 0;
14187
14188
14189 codecnum = colname + 5;
14190 *codecnum = '\0';
14191 codecnum++;
14192 if ((ptr = strchr(codecnum, ']'))) {
14193 *ptr = '\0';
14194 }
14195 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
14196 ast_copy_string(buf, ast_getformatname(codec), len);
14197 } else {
14198 buf[0] = '\0';
14199 }
14200 } else {
14201 buf[0] = '\0';
14202 }
14203
14204 peer_unref(peer);
14205
14206 return 0;
14207 }
14208
14209 static struct ast_custom_function iaxpeer_function = {
14210 .name = "IAXPEER",
14211 .read = function_iaxpeer,
14212 };
14213
14214 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
14215 {
14216 struct chan_iax2_pvt *pvt;
14217 unsigned int callno;
14218 int res = 0;
14219
14220 if (!chan || chan->tech != &iax2_tech) {
14221 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14222 return -1;
14223 }
14224
14225 callno = PTR_TO_CALLNO(chan->tech_pvt);
14226 ast_mutex_lock(&iaxsl[callno]);
14227 if (!(pvt = iaxs[callno])) {
14228 ast_mutex_unlock(&iaxsl[callno]);
14229 return -1;
14230 }
14231
14232 if (!strcasecmp(args, "osptoken")) {
14233 ast_copy_string(buf, pvt->osptoken, buflen);
14234 } else if (!strcasecmp(args, "peerip")) {
14235 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
14236 } else if (!strcasecmp(args, "peername")) {
14237 ast_copy_string(buf, pvt->username, buflen);
14238 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14239 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14240 } else {
14241 res = -1;
14242 }
14243
14244 ast_mutex_unlock(&iaxsl[callno]);
14245
14246 return res;
14247 }
14248
14249
14250 static int iax2_devicestate(void *data)
14251 {
14252 struct parsed_dial_string pds;
14253 char *tmp = ast_strdupa(data);
14254 struct iax2_peer *p;
14255 int res = AST_DEVICE_INVALID;
14256
14257 memset(&pds, 0, sizeof(pds));
14258 parse_dial_string(tmp, &pds);
14259
14260 if (ast_strlen_zero(pds.peer)) {
14261 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
14262 return res;
14263 }
14264
14265 ast_debug(3, "Checking device state for device %s\n", pds.peer);
14266
14267
14268 if (!(p = find_peer(pds.peer, 1)))
14269 return res;
14270
14271 res = AST_DEVICE_UNAVAILABLE;
14272 ast_debug(3, "Found peer. What's device state of %s? addr=%u, defaddr=%u maxms=%d, lastms=%d\n",
14273 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
14274
14275 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
14276 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14277
14278
14279 if (p->historicms == 0 || p->historicms <= p->maxms)
14280
14281 res = AST_DEVICE_UNKNOWN;
14282 }
14283
14284 peer_unref(p);
14285
14286 return res;
14287 }
14288
14289 static struct ast_switch iax2_switch =
14290 {
14291 .name = "IAX2",
14292 .description = "IAX Remote Dialplan Switch",
14293 .exists = iax2_exists,
14294 .canmatch = iax2_canmatch,
14295 .exec = iax2_exec,
14296 .matchmore = iax2_matchmore,
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
14398
14399
14400
14401
14402
14403 static struct ast_cli_entry cli_iax2[] = {
14404 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14405 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14406 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14407 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14408 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14409 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14410 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14411 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14412 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14413 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14414 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14415 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14416 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14417 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14418 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14419 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14420 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14421 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14422 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14423 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14424 #ifdef IAXTESTS
14425 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14426 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14427 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14428 #endif
14429 };
14430
14431 #ifdef TEST_FRAMEWORK
14432 AST_TEST_DEFINE(test_iax2_peers_get)
14433 {
14434 struct ast_data_query query = {
14435 .path = "/asterisk/channel/iax2/peers",
14436 .search = "peers/peer/name=test_peer_data_provider"
14437 };
14438 struct ast_data *node;
14439 struct iax2_peer *peer;
14440
14441 switch (cmd) {
14442 case TEST_INIT:
14443 info->name = "iax2_peers_get_data_test";
14444 info->category = "/main/data/iax2/peers/";
14445 info->summary = "IAX2 peers data providers unit test";
14446 info->description =
14447 "Tests whether the IAX2 peers data provider implementation works as expected.";
14448 return AST_TEST_NOT_RUN;
14449 case TEST_EXECUTE:
14450 break;
14451 }
14452
14453
14454 peer = build_peer("test_peer_data_provider", NULL, NULL, 0);
14455 if (!peer) {
14456 return AST_TEST_FAIL;
14457 }
14458 peer->expiry= 1010;
14459 ao2_link(peers, peer);
14460
14461 node = ast_data_get(&query);
14462 if (!node) {
14463 ao2_unlink(peers, peer);
14464 peer_unref(peer);
14465 return AST_TEST_FAIL;
14466 }
14467
14468
14469 if (strcmp(ast_data_retrieve_string(node, "peer/name"), "test_peer_data_provider")) {
14470 ao2_unlink(peers, peer);
14471 peer_unref(peer);
14472 ast_data_free(node);
14473 return AST_TEST_FAIL;
14474 }
14475
14476 if (ast_data_retrieve_int(node, "peer/expiry") != 1010) {
14477 ao2_unlink(peers, peer);
14478 peer_unref(peer);
14479 ast_data_free(node);
14480 return AST_TEST_FAIL;
14481 }
14482
14483
14484 ast_data_free(node);
14485
14486 ao2_unlink(peers, peer);
14487 peer_unref(peer);
14488
14489 return AST_TEST_PASS;
14490 }
14491
14492 AST_TEST_DEFINE(test_iax2_users_get)
14493 {
14494 struct ast_data_query query = {
14495 .path = "/asterisk/channel/iax2/users",
14496 .search = "users/user/name=test_user_data_provider"
14497 };
14498 struct ast_data *node;
14499 struct iax2_user *user;
14500
14501 switch (cmd) {
14502 case TEST_INIT:
14503 info->name = "iax2_users_get_data_test";
14504 info->category = "/main/data/iax2/users/";
14505 info->summary = "IAX2 users data providers unit test";
14506 info->description =
14507 "Tests whether the IAX2 users data provider implementation works as expected.";
14508 return AST_TEST_NOT_RUN;
14509 case TEST_EXECUTE:
14510 break;
14511 }
14512
14513 user = build_user("test_user_data_provider", NULL, NULL, 0);
14514 if (!user) {
14515 ast_test_status_update(test, "Failed to build a test user\n");
14516 return AST_TEST_FAIL;
14517 }
14518 user->amaflags = 1010;
14519 ao2_link(users, user);
14520
14521 node = ast_data_get(&query);
14522 if (!node) {
14523 ast_test_status_update(test, "The data query to find our test user failed\n");
14524 ao2_unlink(users, user);
14525 user_unref(user);
14526 return AST_TEST_FAIL;
14527 }
14528
14529 if (strcmp(ast_data_retrieve_string(node, "user/name"), "test_user_data_provider")) {
14530 ast_test_status_update(test, "Our data results did not return the test user created in the previous step.\n");
14531 ao2_unlink(users, user);
14532 user_unref(user);
14533 ast_data_free(node);
14534 return AST_TEST_FAIL;
14535 }
14536
14537 if (ast_data_retrieve_int(node, "user/amaflags/value") != 1010) {
14538 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"));
14539 ao2_unlink(users, user);
14540 user_unref(user);
14541 ast_data_free(node);
14542 return AST_TEST_FAIL;
14543 }
14544
14545 ast_data_free(node);
14546
14547 ao2_unlink(users, user);
14548 user_unref(user);
14549
14550 return AST_TEST_PASS;
14551 }
14552 #endif
14553
14554 static void cleanup_thread_list(void *head)
14555 {
14556 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14557 struct iax2_thread_list *list_head = head;
14558 struct iax2_thread *thread;
14559
14560 AST_LIST_LOCK(list_head);
14561 while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) {
14562 pthread_t thread_id = thread->threadid;
14563
14564 thread->stop = 1;
14565 signal_condition(&thread->lock, &thread->cond);
14566
14567 AST_LIST_UNLOCK(list_head);
14568 pthread_join(thread_id, NULL);
14569 AST_LIST_LOCK(list_head);
14570 }
14571 AST_LIST_UNLOCK(list_head);
14572 }
14573
14574 static int __unload_module(void)
14575 {
14576 struct ast_context *con;
14577 int x;
14578
14579 network_change_event_unsubscribe();
14580
14581 ast_manager_unregister("IAXpeers");
14582 ast_manager_unregister("IAXpeerlist");
14583 ast_manager_unregister("IAXnetstats");
14584 ast_manager_unregister("IAXregistry");
14585 ast_unregister_application(papp);
14586 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14587 ast_unregister_switch(&iax2_switch);
14588 ast_channel_unregister(&iax2_tech);
14589
14590 if (netthreadid != AST_PTHREADT_NULL) {
14591 pthread_cancel(netthreadid);
14592 pthread_kill(netthreadid, SIGURG);
14593 pthread_join(netthreadid, NULL);
14594 }
14595
14596 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14597 if (iaxs[x]) {
14598 iax2_destroy(x);
14599 }
14600 }
14601
14602
14603 cleanup_thread_list(&active_list);
14604 cleanup_thread_list(&dynamic_list);
14605 cleanup_thread_list(&idle_list);
14606
14607 ast_netsock_release(netsock);
14608 ast_netsock_release(outsock);
14609 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14610 if (iaxs[x]) {
14611 iax2_destroy(x);
14612 }
14613 }
14614 ast_manager_unregister( "IAXpeers" );
14615 ast_manager_unregister( "IAXpeerlist" );
14616 ast_manager_unregister( "IAXnetstats" );
14617 ast_manager_unregister( "IAXregistry" );
14618 ast_unregister_application(papp);
14619 #ifdef TEST_FRAMEWORK
14620 AST_TEST_UNREGISTER(test_iax2_peers_get);
14621 AST_TEST_UNREGISTER(test_iax2_users_get);
14622 #endif
14623 ast_data_unregister(NULL);
14624 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14625 ast_unregister_switch(&iax2_switch);
14626 ast_channel_unregister(&iax2_tech);
14627 delete_users();
14628 iax_provision_unload();
14629 reload_firmware(1);
14630
14631 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14632 ast_mutex_destroy(&iaxsl[x]);
14633 }
14634
14635 ao2_ref(peers, -1);
14636 ao2_ref(users, -1);
14637 ao2_ref(iax_peercallno_pvts, -1);
14638 ao2_ref(iax_transfercallno_pvts, -1);
14639 ao2_ref(peercnts, -1);
14640 ao2_ref(callno_limits, -1);
14641 ao2_ref(calltoken_ignores, -1);
14642 ao2_ref(callno_pool, -1);
14643 ao2_ref(callno_pool_trunk, -1);
14644 if (timer) {
14645 ast_timer_close(timer);
14646 timer = NULL;
14647 }
14648 transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14649 sched = ast_sched_thread_destroy(sched);
14650
14651 con = ast_context_find(regcontext);
14652 if (con)
14653 ast_context_destroy(con, "IAX2");
14654 ast_unload_realtime("iaxpeers");
14655 return 0;
14656 }
14657
14658 static int unload_module(void)
14659 {
14660 ast_custom_function_unregister(&iaxpeer_function);
14661 ast_custom_function_unregister(&iaxvar_function);
14662 return __unload_module();
14663 }
14664
14665 static int peer_set_sock_cb(void *obj, void *arg, int flags)
14666 {
14667 struct iax2_peer *peer = obj;
14668
14669 if (peer->sockfd < 0)
14670 peer->sockfd = defaultsockfd;
14671
14672 return 0;
14673 }
14674
14675 static int pvt_hash_cb(const void *obj, const int flags)
14676 {
14677 const struct chan_iax2_pvt *pvt = obj;
14678
14679 return pvt->peercallno;
14680 }
14681
14682 static int pvt_cmp_cb(void *obj, void *arg, int flags)
14683 {
14684 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14685
14686
14687
14688
14689 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14690 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14691 }
14692
14693 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14694 {
14695 const struct chan_iax2_pvt *pvt = obj;
14696
14697 return pvt->transfercallno;
14698 }
14699
14700 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14701 {
14702 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14703
14704
14705
14706
14707 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14708 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14709 }
14710
14711 static int load_objects(void)
14712 {
14713 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14714 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14715
14716 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14717 goto container_fail;
14718 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14719 goto container_fail;
14720 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14721 goto container_fail;
14722 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14723 goto container_fail;
14724 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14725 goto container_fail;
14726 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14727 goto container_fail;
14728 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14729 goto container_fail;
14730 } else if (create_callno_pools()) {
14731 goto container_fail;
14732 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14733 goto container_fail;
14734 }
14735
14736 return 0;
14737
14738 container_fail:
14739 if (peers) {
14740 ao2_ref(peers, -1);
14741 }
14742 if (users) {
14743 ao2_ref(users, -1);
14744 }
14745 if (iax_peercallno_pvts) {
14746 ao2_ref(iax_peercallno_pvts, -1);
14747 }
14748 if (iax_transfercallno_pvts) {
14749 ao2_ref(iax_transfercallno_pvts, -1);
14750 }
14751 if (peercnts) {
14752 ao2_ref(peercnts, -1);
14753 }
14754 if (callno_limits) {
14755 ao2_ref(callno_limits, -1);
14756 }
14757 if (calltoken_ignores) {
14758 ao2_ref(calltoken_ignores, -1);
14759 }
14760 if (callno_pool) {
14761 ao2_ref(callno_pool, -1);
14762 }
14763 if (callno_pool_trunk) {
14764 ao2_ref(callno_pool_trunk, -1);
14765 }
14766 return AST_MODULE_LOAD_FAILURE;
14767 }
14768
14769
14770 #define DATA_EXPORT_IAX2_PEER(MEMBER) \
14771 MEMBER(iax2_peer, name, AST_DATA_STRING) \
14772 MEMBER(iax2_peer, username, AST_DATA_STRING) \
14773 MEMBER(iax2_peer, secret, AST_DATA_PASSWORD) \
14774 MEMBER(iax2_peer, dbsecret, AST_DATA_PASSWORD) \
14775 MEMBER(iax2_peer, outkey, AST_DATA_STRING) \
14776 MEMBER(iax2_peer, regexten, AST_DATA_STRING) \
14777 MEMBER(iax2_peer, context, AST_DATA_STRING) \
14778 MEMBER(iax2_peer, peercontext, AST_DATA_STRING) \
14779 MEMBER(iax2_peer, mailbox, AST_DATA_STRING) \
14780 MEMBER(iax2_peer, mohinterpret, AST_DATA_STRING) \
14781 MEMBER(iax2_peer, mohsuggest, AST_DATA_STRING) \
14782 MEMBER(iax2_peer, inkeys, AST_DATA_STRING) \
14783 MEMBER(iax2_peer, cid_num, AST_DATA_STRING) \
14784 MEMBER(iax2_peer, cid_name, AST_DATA_STRING) \
14785 MEMBER(iax2_peer, zonetag, AST_DATA_STRING) \
14786 MEMBER(iax2_peer, parkinglot, AST_DATA_STRING) \
14787 MEMBER(iax2_peer, expiry, AST_DATA_SECONDS) \
14788 MEMBER(iax2_peer, callno, AST_DATA_INTEGER) \
14789 MEMBER(iax2_peer, lastms, AST_DATA_MILLISECONDS) \
14790 MEMBER(iax2_peer, maxms, AST_DATA_MILLISECONDS) \
14791 MEMBER(iax2_peer, pokefreqok, AST_DATA_MILLISECONDS) \
14792 MEMBER(iax2_peer, pokefreqnotok, AST_DATA_MILLISECONDS) \
14793 MEMBER(iax2_peer, historicms, AST_DATA_INTEGER) \
14794 MEMBER(iax2_peer, smoothing, AST_DATA_BOOLEAN) \
14795 MEMBER(iax2_peer, maxcallno, AST_DATA_INTEGER)
14796
14797 AST_DATA_STRUCTURE(iax2_peer, DATA_EXPORT_IAX2_PEER);
14798
14799 static int peers_data_provider_get(const struct ast_data_search *search,
14800 struct ast_data *data_root)
14801 {
14802 struct ast_data *data_peer;
14803 struct iax2_peer *peer;
14804 struct ao2_iterator i;
14805 char status[20];
14806 struct ast_str *encmethods = ast_str_alloca(256);
14807
14808 i = ao2_iterator_init(peers, 0);
14809 while ((peer = ao2_iterator_next(&i))) {
14810 data_peer = ast_data_add_node(data_root, "peer");
14811 if (!data_peer) {
14812 peer_unref(peer);
14813 continue;
14814 }
14815
14816 ast_data_add_structure(iax2_peer, data_peer, peer);
14817
14818 ast_data_add_codecs(data_peer, "codecs", peer->capability);
14819
14820 peer_status(peer, status, sizeof(status));
14821 ast_data_add_str(data_peer, "status", status);
14822
14823 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14824
14825 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14826
14827 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14828
14829 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14830
14831 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14832
14833 encmethods_to_str(peer->encmethods, &encmethods);
14834 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14835
14836 peer_unref(peer);
14837
14838 if (!ast_data_search_match(search, data_peer)) {
14839 ast_data_remove_node(data_root, data_peer);
14840 }
14841 }
14842 ao2_iterator_destroy(&i);
14843
14844 return 0;
14845 }
14846
14847 #define DATA_EXPORT_IAX2_USER(MEMBER) \
14848 MEMBER(iax2_user, name, AST_DATA_STRING) \
14849 MEMBER(iax2_user, dbsecret, AST_DATA_PASSWORD) \
14850 MEMBER(iax2_user, accountcode, AST_DATA_STRING) \
14851 MEMBER(iax2_user, mohinterpret, AST_DATA_STRING) \
14852 MEMBER(iax2_user, mohsuggest, AST_DATA_STRING) \
14853 MEMBER(iax2_user, inkeys, AST_DATA_STRING) \
14854 MEMBER(iax2_user, language, AST_DATA_STRING) \
14855 MEMBER(iax2_user, cid_num, AST_DATA_STRING) \
14856 MEMBER(iax2_user, cid_name, AST_DATA_STRING) \
14857 MEMBER(iax2_user, parkinglot, AST_DATA_STRING) \
14858 MEMBER(iax2_user, maxauthreq, AST_DATA_INTEGER) \
14859 MEMBER(iax2_user, curauthreq, AST_DATA_INTEGER)
14860
14861 AST_DATA_STRUCTURE(iax2_user, DATA_EXPORT_IAX2_USER);
14862
14863 static int users_data_provider_get(const struct ast_data_search *search,
14864 struct ast_data *data_root)
14865 {
14866 struct ast_data *data_user, *data_authmethods, *data_enum_node;
14867 struct iax2_user *user;
14868 struct ao2_iterator i;
14869 char auth[90];
14870 char *pstr = "";
14871
14872 i = ao2_iterator_init(users, 0);
14873 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14874 data_user = ast_data_add_node(data_root, "user");
14875 if (!data_user) {
14876 continue;
14877 }
14878
14879 ast_data_add_structure(iax2_user, data_user, user);
14880
14881 ast_data_add_codecs(data_user, "codecs", user->capability);
14882
14883 if (!ast_strlen_zero(user->secret)) {
14884 ast_copy_string(auth, user->secret, sizeof(auth));
14885 } else if (!ast_strlen_zero(user->inkeys)) {
14886 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14887 } else {
14888 ast_copy_string(auth, "no secret", sizeof(auth));
14889 }
14890 ast_data_add_password(data_user, "secret", auth);
14891
14892 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14893
14894
14895 data_authmethods = ast_data_add_node(data_user, "authmethods");
14896 if (!data_authmethods) {
14897 ast_data_remove_node(data_root, data_user);
14898 continue;
14899 }
14900 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14901 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14902 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14903
14904
14905 data_enum_node = ast_data_add_node(data_user, "amaflags");
14906 if (!data_enum_node) {
14907 ast_data_remove_node(data_root, data_user);
14908 continue;
14909 }
14910 ast_data_add_int(data_enum_node, "value", user->amaflags);
14911 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14912
14913 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14914
14915 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14916 pstr = "REQ only";
14917 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14918 pstr = "disabled";
14919 } else {
14920 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14921 }
14922 ast_data_add_str(data_user, "codec-preferences", pstr);
14923
14924 if (!ast_data_search_match(search, data_user)) {
14925 ast_data_remove_node(data_root, data_user);
14926 }
14927 }
14928 ao2_iterator_destroy(&i);
14929
14930 return 0;
14931 }
14932
14933 static const struct ast_data_handler peers_data_provider = {
14934 .version = AST_DATA_HANDLER_VERSION,
14935 .get = peers_data_provider_get
14936 };
14937
14938 static const struct ast_data_handler users_data_provider = {
14939 .version = AST_DATA_HANDLER_VERSION,
14940 .get = users_data_provider_get
14941 };
14942
14943 static const struct ast_data_entry iax2_data_providers[] = {
14944 AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
14945 AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
14946 };
14947
14948
14949 static int load_module(void)
14950 {
14951 static const char config[] = "iax.conf";
14952 int x = 0;
14953 struct iax2_registry *reg = NULL;
14954
14955 if (load_objects()) {
14956 return AST_MODULE_LOAD_FAILURE;
14957 }
14958
14959 memset(iaxs, 0, sizeof(iaxs));
14960
14961 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14962 ast_mutex_init(&iaxsl[x]);
14963 }
14964
14965 if (!(sched = ast_sched_thread_create())) {
14966 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14967 return AST_MODULE_LOAD_FAILURE;
14968 }
14969
14970 if (!(io = io_context_create())) {
14971 ast_log(LOG_ERROR, "Failed to create I/O context\n");
14972 sched = ast_sched_thread_destroy(sched);
14973 return AST_MODULE_LOAD_FAILURE;
14974 }
14975
14976 if (!(netsock = ast_netsock_list_alloc())) {
14977 ast_log(LOG_ERROR, "Failed to create netsock list\n");
14978 io_context_destroy(io);
14979 sched = ast_sched_thread_destroy(sched);
14980 return AST_MODULE_LOAD_FAILURE;
14981 }
14982 ast_netsock_init(netsock);
14983
14984 outsock = ast_netsock_list_alloc();
14985 if (!outsock) {
14986 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14987 io_context_destroy(io);
14988 sched = ast_sched_thread_destroy(sched);
14989 return AST_MODULE_LOAD_FAILURE;
14990 }
14991 ast_netsock_init(outsock);
14992
14993 randomcalltokendata = ast_random();
14994
14995 iax_set_output(iax_debug_output);
14996 iax_set_error(iax_error_output);
14997 jb_setoutput(jb_error_output, jb_warning_output, NULL);
14998
14999 if ((timer = ast_timer_open())) {
15000 ast_timer_set_rate(timer, 1000 / trunkfreq);
15001 }
15002
15003 if (set_config(config, 0) == -1) {
15004 if (timer) {
15005 ast_timer_close(timer);
15006 timer = NULL;
15007 }
15008 return AST_MODULE_LOAD_DECLINE;
15009 }
15010
15011 #ifdef TEST_FRAMEWORK
15012 AST_TEST_REGISTER(test_iax2_peers_get);
15013 AST_TEST_REGISTER(test_iax2_users_get);
15014 #endif
15015
15016
15017 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
15018 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
15019
15020 ast_register_application_xml(papp, iax2_prov_app);
15021
15022 ast_custom_function_register(&iaxpeer_function);
15023 ast_custom_function_register(&iaxvar_function);
15024
15025 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
15026 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
15027 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
15028 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
15029
15030 if (ast_channel_register(&iax2_tech)) {
15031 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
15032 __unload_module();
15033 return AST_MODULE_LOAD_FAILURE;
15034 }
15035
15036 if (ast_register_switch(&iax2_switch)) {
15037 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
15038 }
15039
15040 if (start_network_thread()) {
15041 ast_log(LOG_ERROR, "Unable to start network thread\n");
15042 __unload_module();
15043 return AST_MODULE_LOAD_FAILURE;
15044 } else {
15045 ast_verb(2, "IAX Ready and Listening\n");
15046 }
15047
15048 AST_LIST_LOCK(®istrations);
15049 AST_LIST_TRAVERSE(®istrations, reg, entry)
15050 iax2_do_register(reg);
15051 AST_LIST_UNLOCK(®istrations);
15052
15053 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
15054 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
15055
15056
15057 reload_firmware(0);
15058 iax_provision_reload(0);
15059
15060 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
15061
15062 network_change_event_subscribe();
15063
15064 return AST_MODULE_LOAD_SUCCESS;
15065 }
15066
15067 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
15068 .load = load_module,
15069 .unload = unload_module,
15070 .reload = reload,
15071 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
15072 .nonoptreq = "res_crypto",
15073 );