00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "asterisk.h"
00039
00040 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 300521 $")
00041
00042 #include <sys/mman.h>
00043 #include <dirent.h>
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 #include <arpa/inet.h>
00047 #include <netinet/in_systm.h>
00048 #include <netinet/ip.h>
00049 #include <sys/time.h>
00050 #include <sys/signal.h>
00051 #include <signal.h>
00052 #include <strings.h>
00053 #include <netdb.h>
00054 #include <fcntl.h>
00055 #include <sys/stat.h>
00056 #include <regex.h>
00057
00058 #include "asterisk/paths.h"
00059
00060 #include "asterisk/lock.h"
00061 #include "asterisk/frame.h"
00062 #include "asterisk/channel.h"
00063 #include "asterisk/module.h"
00064 #include "asterisk/pbx.h"
00065 #include "asterisk/sched.h"
00066 #include "asterisk/io.h"
00067 #include "asterisk/config.h"
00068 #include "asterisk/cli.h"
00069 #include "asterisk/translate.h"
00070 #include "asterisk/md5.h"
00071 #include "asterisk/cdr.h"
00072 #include "asterisk/crypto.h"
00073 #include "asterisk/acl.h"
00074 #include "asterisk/manager.h"
00075 #include "asterisk/callerid.h"
00076 #include "asterisk/app.h"
00077 #include "asterisk/astdb.h"
00078 #include "asterisk/musiconhold.h"
00079 #include "asterisk/features.h"
00080 #include "asterisk/utils.h"
00081 #include "asterisk/causes.h"
00082 #include "asterisk/localtime.h"
00083 #include "asterisk/dnsmgr.h"
00084 #include "asterisk/devicestate.h"
00085 #include "asterisk/netsock.h"
00086 #include "asterisk/stringfields.h"
00087 #include "asterisk/linkedlists.h"
00088 #include "asterisk/event.h"
00089 #include "asterisk/astobj2.h"
00090 #include "asterisk/timing.h"
00091 #include "asterisk/taskprocessor.h"
00092 #include "asterisk/test.h"
00093 #include "asterisk/data.h"
00094 #include "asterisk/netsock2.h"
00095
00096 #include "iax2.h"
00097 #include "iax2-parser.h"
00098 #include "iax2-provision.h"
00099 #include "jitterbuf.h"
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
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 #define SCHED_MULTITHREADED
00227
00228
00229
00230 #define DEBUG_SCHED_MULTITHREAD
00231
00232
00233 #ifdef SO_NO_CHECK
00234 static int nochecksums = 0;
00235 #endif
00236
00237 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00238 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00239
00240 #define DEFAULT_THREAD_COUNT 10
00241 #define DEFAULT_MAX_THREAD_COUNT 100
00242 #define DEFAULT_RETRY_TIME 1000
00243 #define MEMORY_SIZE 100
00244 #define DEFAULT_DROP 3
00245
00246 #define DEBUG_SUPPORT
00247
00248 #define MIN_REUSE_TIME 60
00249
00250
00251 #define GAMMA (0.01)
00252
00253 static struct ast_codec_pref prefs;
00254
00255 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00256
00257
00258
00259
00260 #define MAX_TRUNK_MTU 1240
00261
00262 static int global_max_trunk_mtu;
00263 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00264
00265 #define DEFAULT_CONTEXT "default"
00266
00267 static char default_parkinglot[AST_MAX_CONTEXT];
00268
00269 static char language[MAX_LANGUAGE] = "";
00270 static char regcontext[AST_MAX_CONTEXT] = "";
00271
00272 static struct ast_event_sub *network_change_event_subscription;
00273 static int network_change_event_sched_id = -1;
00274
00275 static int maxauthreq = 3;
00276 static int max_retries = 4;
00277 static int ping_time = 21;
00278 static int lagrq_time = 10;
00279 static int maxjitterbuffer=1000;
00280 static int resyncthreshold=1000;
00281 static int maxjitterinterps=10;
00282 static int jittertargetextra = 40;
00283
00284 #define MAX_TRUNKDATA 640 * 200
00285
00286 static int trunkfreq = 20;
00287 static int trunkmaxsize = MAX_TRUNKDATA;
00288
00289 static int authdebug = 1;
00290 static int autokill = 0;
00291 static int iaxcompat = 0;
00292 static int last_authmethod = 0;
00293
00294 static int iaxdefaultdpcache=10 * 60;
00295
00296 static int iaxdefaulttimeout = 5;
00297
00298 static struct {
00299 unsigned int tos;
00300 unsigned int cos;
00301 } qos = { 0, 0 };
00302
00303 static int min_reg_expire;
00304 static int max_reg_expire;
00305
00306 static int srvlookup = 0;
00307
00308 static struct ast_timer *timer;
00309
00310 static struct ast_netsock_list *netsock;
00311 static struct ast_netsock_list *outsock;
00312 static int defaultsockfd = -1;
00313
00314 static int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00315
00316
00317 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00318
00319 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00320 ~AST_FORMAT_SLINEAR & \
00321 ~AST_FORMAT_SLINEAR16 & \
00322 ~AST_FORMAT_SIREN7 & \
00323 ~AST_FORMAT_SIREN14 & \
00324 ~AST_FORMAT_G719 & \
00325 ~AST_FORMAT_ULAW & \
00326 ~AST_FORMAT_ALAW & \
00327 ~AST_FORMAT_G722)
00328
00329 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00330 ~AST_FORMAT_G726 & \
00331 ~AST_FORMAT_G726_AAL2 & \
00332 ~AST_FORMAT_ADPCM)
00333
00334 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00335 ~AST_FORMAT_G723_1)
00336
00337
00338 #define DEFAULT_MAXMS 2000
00339 #define DEFAULT_FREQ_OK 60 * 1000
00340 #define DEFAULT_FREQ_NOTOK 10 * 1000
00341
00342
00343 #define IAX_CALLENCRYPTED(pvt) \
00344 (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))
00345
00346 #define IAX_DEBUGDIGEST(msg, key) do { \
00347 int idx; \
00348 char digest[33] = ""; \
00349 \
00350 if (!iaxdebug) \
00351 break; \
00352 \
00353 for (idx = 0; idx < 16; idx++) \
00354 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00355 \
00356 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00357 } while(0)
00358
00359 static struct io_context *io;
00360 static struct ast_sched_thread *sched;
00361
00362 #define DONT_RESCHEDULE -2
00363
00364 static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00365
00366 static int iaxdebug = 0;
00367
00368 static int iaxtrunkdebug = 0;
00369
00370 static int test_losspct = 0;
00371 #ifdef IAXTESTS
00372 static int test_late = 0;
00373 static int test_resync = 0;
00374 static int test_jit = 0;
00375 static int test_jitpct = 0;
00376 #endif
00377
00378 static char accountcode[AST_MAX_ACCOUNT_CODE];
00379 static char mohinterpret[MAX_MUSICCLASS];
00380 static char mohsuggest[MAX_MUSICCLASS];
00381 static int amaflags = 0;
00382 static int adsi = 0;
00383 static int delayreject = 0;
00384 static int iax2_encryption = 0;
00385
00386 static struct ast_flags64 globalflags = { 0 };
00387
00388 static pthread_t netthreadid = AST_PTHREADT_NULL;
00389
00390 enum iax2_state {
00391 IAX_STATE_STARTED = (1 << 0),
00392 IAX_STATE_AUTHENTICATED = (1 << 1),
00393 IAX_STATE_TBD = (1 << 2),
00394 };
00395
00396 struct iax2_context {
00397 char context[AST_MAX_CONTEXT];
00398 struct iax2_context *next;
00399 };
00400
00401
00402 #define IAX_HASCALLERID (uint64_t)(1 << 0)
00403 #define IAX_DELME (uint64_t)(1 << 1)
00404 #define IAX_TEMPONLY (uint64_t)(1 << 2)
00405 #define IAX_TRUNK (uint64_t)(1 << 3)
00406 #define IAX_NOTRANSFER (uint64_t)(1 << 4)
00407 #define IAX_USEJITTERBUF (uint64_t)(1 << 5)
00408 #define IAX_DYNAMIC (uint64_t)(1 << 6)
00409 #define IAX_SENDANI (uint64_t)(1 << 7)
00410 #define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8)
00411 #define IAX_ALREADYGONE (uint64_t)(1 << 9)
00412 #define IAX_PROVISION (uint64_t)(1 << 10)
00413 #define IAX_QUELCH (uint64_t)(1 << 11)
00414 #define IAX_ENCRYPTED (uint64_t)(1 << 12)
00415 #define IAX_KEYPOPULATED (uint64_t)(1 << 13)
00416 #define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14)
00417 #define IAX_CODEC_NOPREFS (uint64_t)(1 << 15)
00418 #define IAX_CODEC_NOCAP (uint64_t)(1 << 16)
00419 #define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17)
00420 #define IAX_RTUPDATE (uint64_t)(1 << 18)
00421 #define IAX_RTAUTOCLEAR (uint64_t)(1 << 19)
00422 #define IAX_FORCEJITTERBUF (uint64_t)(1 << 20)
00423 #define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21)
00424 #define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22)
00425 #define IAX_TRANSFERMEDIA (uint64_t)(1 << 23)
00426 #define IAX_MAXAUTHREQ (uint64_t)(1 << 24)
00427 #define IAX_DELAYPBXSTART (uint64_t)(1 << 25)
00428 #define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26)
00429 #define IAX_IMMEDIATE (uint64_t)(1 << 27)
00430 #define IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28)
00431 #define IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29)
00432 #define IAX_FORCE_ENCRYPT (uint64_t)(1 << 30)
00433 #define IAX_SHRINKCALLERID (uint64_t)(1 << 31)
00434 static int global_rtautoclear = 120;
00435
00436 static int reload_config(void);
00437
00438
00439
00440
00441 enum calltoken_peer_enum {
00442
00443 CALLTOKEN_DEFAULT = 0,
00444
00445 CALLTOKEN_YES = 1,
00446
00447
00448 CALLTOKEN_AUTO = 2,
00449
00450 CALLTOKEN_NO = 3,
00451 };
00452
00453 struct iax2_user {
00454 AST_DECLARE_STRING_FIELDS(
00455 AST_STRING_FIELD(name);
00456 AST_STRING_FIELD(secret);
00457 AST_STRING_FIELD(dbsecret);
00458 AST_STRING_FIELD(accountcode);
00459 AST_STRING_FIELD(mohinterpret);
00460 AST_STRING_FIELD(mohsuggest);
00461 AST_STRING_FIELD(inkeys);
00462 AST_STRING_FIELD(language);
00463 AST_STRING_FIELD(cid_num);
00464 AST_STRING_FIELD(cid_name);
00465 AST_STRING_FIELD(parkinglot);
00466 );
00467
00468 int authmethods;
00469 int encmethods;
00470 int amaflags;
00471 int adsi;
00472 uint64_t flags;
00473 format_t capability;
00474 int maxauthreq;
00475 int curauthreq;
00476 struct ast_codec_pref prefs;
00477 struct ast_ha *ha;
00478 struct iax2_context *contexts;
00479 struct ast_variable *vars;
00480 enum calltoken_peer_enum calltoken_required;
00481 };
00482
00483 struct iax2_peer {
00484 AST_DECLARE_STRING_FIELDS(
00485 AST_STRING_FIELD(name);
00486 AST_STRING_FIELD(username);
00487 AST_STRING_FIELD(secret);
00488 AST_STRING_FIELD(dbsecret);
00489 AST_STRING_FIELD(outkey);
00490
00491 AST_STRING_FIELD(regexten);
00492 AST_STRING_FIELD(context);
00493 AST_STRING_FIELD(peercontext);
00494 AST_STRING_FIELD(mailbox);
00495 AST_STRING_FIELD(mohinterpret);
00496 AST_STRING_FIELD(mohsuggest);
00497 AST_STRING_FIELD(inkeys);
00498
00499 AST_STRING_FIELD(cid_num);
00500 AST_STRING_FIELD(cid_name);
00501 AST_STRING_FIELD(zonetag);
00502 AST_STRING_FIELD(parkinglot);
00503 );
00504 struct ast_codec_pref prefs;
00505 struct ast_dnsmgr_entry *dnsmgr;
00506 struct ast_sockaddr addr;
00507 int formats;
00508 int sockfd;
00509 struct in_addr mask;
00510 int adsi;
00511 uint64_t flags;
00512
00513
00514 struct sockaddr_in defaddr;
00515 int authmethods;
00516 int encmethods;
00517
00518 int expire;
00519 int expiry;
00520 format_t capability;
00521
00522
00523 int callno;
00524 int pokeexpire;
00525 int lastms;
00526 int maxms;
00527
00528 int pokefreqok;
00529 int pokefreqnotok;
00530 int historicms;
00531 int smoothing;
00532 uint16_t maxcallno;
00533
00534 struct ast_event_sub *mwi_event_sub;
00535
00536 struct ast_ha *ha;
00537 enum calltoken_peer_enum calltoken_required;
00538 };
00539
00540 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00541
00542 struct iax2_trunk_peer {
00543 ast_mutex_t lock;
00544 int sockfd;
00545 struct sockaddr_in addr;
00546 struct timeval txtrunktime;
00547 struct timeval rxtrunktime;
00548 struct timeval lasttxtime;
00549 struct timeval trunkact;
00550 unsigned int lastsent;
00551
00552 unsigned char *trunkdata;
00553 unsigned int trunkdatalen;
00554 unsigned int trunkdataalloc;
00555 int trunkmaxmtu;
00556 int trunkerror;
00557 int calls;
00558 AST_LIST_ENTRY(iax2_trunk_peer) list;
00559 };
00560
00561 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00562
00563 struct iax_firmware {
00564 AST_LIST_ENTRY(iax_firmware) list;
00565 int fd;
00566 int mmaplen;
00567 int dead;
00568 struct ast_iax2_firmware_header *fwh;
00569 unsigned char *buf;
00570 };
00571
00572 enum iax_reg_state {
00573 REG_STATE_UNREGISTERED = 0,
00574 REG_STATE_REGSENT,
00575 REG_STATE_AUTHSENT,
00576 REG_STATE_REGISTERED,
00577 REG_STATE_REJECTED,
00578 REG_STATE_TIMEOUT,
00579 REG_STATE_NOAUTH
00580 };
00581
00582 enum iax_transfer_state {
00583 TRANSFER_NONE = 0,
00584 TRANSFER_BEGIN,
00585 TRANSFER_READY,
00586 TRANSFER_RELEASED,
00587 TRANSFER_PASSTHROUGH,
00588 TRANSFER_MBEGIN,
00589 TRANSFER_MREADY,
00590 TRANSFER_MRELEASED,
00591 TRANSFER_MPASSTHROUGH,
00592 TRANSFER_MEDIA,
00593 TRANSFER_MEDIAPASS
00594 };
00595
00596 struct iax2_registry {
00597 struct ast_sockaddr addr;
00598 char username[80];
00599 char secret[80];
00600 int expire;
00601 int refresh;
00602 enum iax_reg_state regstate;
00603 int messages;
00604 int callno;
00605 struct sockaddr_in us;
00606 struct ast_dnsmgr_entry *dnsmgr;
00607 AST_LIST_ENTRY(iax2_registry) entry;
00608 };
00609
00610 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00611
00612
00613 #define MIN_RETRY_TIME 100
00614 #define MAX_RETRY_TIME 10000
00615
00616 #define MAX_JITTER_BUFFER 50
00617 #define MIN_JITTER_BUFFER 10
00618
00619 #define DEFAULT_TRUNKDATA 640 * 10
00620
00621 #define MAX_TIMESTAMP_SKEW 160
00622
00623
00624 #define TS_GAP_FOR_JB_RESYNC 5000
00625
00626
00627 #define MARK_IAX_SUBCLASS_TX 0x8000
00628
00629 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00630 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00631 static int iaxdynamicthreadcount = 0;
00632 static int iaxdynamicthreadnum = 0;
00633 static int iaxactivethreadcount = 0;
00634
00635 struct iax_rr {
00636 int jitter;
00637 int losspct;
00638 int losscnt;
00639 int packets;
00640 int delay;
00641 int dropped;
00642 int ooo;
00643 };
00644
00645 struct iax2_pvt_ref;
00646
00647 struct chan_iax2_pvt {
00648
00649 int sockfd;
00650
00651 format_t voiceformat;
00652
00653 format_t videoformat;
00654
00655 format_t svoiceformat;
00656
00657 format_t svideoformat;
00658
00659 format_t capability;
00660
00661 unsigned int last;
00662
00663 unsigned int lastsent;
00664
00665 unsigned int lastvsent;
00666
00667 unsigned int nextpred;
00668
00669 int first_iax_message;
00670
00671 int last_iax_message;
00672
00673 unsigned int notsilenttx:1;
00674
00675 unsigned int pingtime;
00676
00677 int maxtime;
00678
00679 struct sockaddr_in addr;
00680
00681 struct ast_codec_pref prefs;
00682
00683 struct ast_codec_pref rprefs;
00684
00685 unsigned short callno;
00686
00687 struct callno_entry *callno_entry;
00688
00689 unsigned short peercallno;
00690
00691
00692
00693 format_t chosenformat;
00694
00695 format_t peerformat;
00696
00697 format_t peercapability;
00698
00699 struct timeval offset;
00700
00701 struct timeval rxcore;
00702
00703 jitterbuf *jb;
00704
00705 int jbid;
00706
00707 int lag;
00708
00709 int error;
00710
00711 struct ast_channel *owner;
00712
00713 struct ast_flags state;
00714
00715 int expiry;
00716
00717 unsigned char oseqno;
00718
00719 unsigned char rseqno;
00720
00721 unsigned char iseqno;
00722
00723 unsigned char aseqno;
00724
00725 AST_DECLARE_STRING_FIELDS(
00726
00727 AST_STRING_FIELD(peer);
00728
00729 AST_STRING_FIELD(context);
00730
00731 AST_STRING_FIELD(cid_num);
00732 AST_STRING_FIELD(cid_name);
00733
00734 AST_STRING_FIELD(ani);
00735
00736 AST_STRING_FIELD(dnid);
00737
00738 AST_STRING_FIELD(rdnis);
00739
00740 AST_STRING_FIELD(exten);
00741
00742 AST_STRING_FIELD(username);
00743
00744 AST_STRING_FIELD(secret);
00745
00746 AST_STRING_FIELD(challenge);
00747
00748 AST_STRING_FIELD(inkeys);
00749
00750 AST_STRING_FIELD(outkey);
00751
00752 AST_STRING_FIELD(language);
00753
00754 AST_STRING_FIELD(host);
00755
00756 AST_STRING_FIELD(dproot);
00757 AST_STRING_FIELD(accountcode);
00758 AST_STRING_FIELD(mohinterpret);
00759 AST_STRING_FIELD(mohsuggest);
00760
00761 AST_STRING_FIELD(osptoken);
00762
00763 AST_STRING_FIELD(parkinglot);
00764 );
00765
00766 int authrej;
00767
00768 int authmethods;
00769
00770 int encmethods;
00771
00772 ast_aes_encrypt_key ecx;
00773
00774 ast_aes_decrypt_key mydcx;
00775
00776 ast_aes_decrypt_key dcx;
00777
00778
00779 int keyrotateid;
00780
00781 unsigned char semirand[32];
00782
00783 struct iax2_registry *reg;
00784
00785 struct iax2_peer *peerpoke;
00786
00787 uint64_t flags;
00788 int adsi;
00789
00790
00791 enum iax_transfer_state transferring;
00792
00793 int transferid;
00794
00795 struct sockaddr_in transfer;
00796
00797 unsigned short transfercallno;
00798
00799 ast_aes_encrypt_key tdcx;
00800
00801
00802 int peeradsicpe;
00803
00804
00805 unsigned short bridgecallno;
00806
00807 int pingid;
00808 int lagid;
00809 int autoid;
00810 int authid;
00811 int authfail;
00812 int initid;
00813 int calling_ton;
00814 int calling_tns;
00815 int calling_pres;
00816 int amaflags;
00817 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00818
00819 struct ast_variable *vars;
00820
00821 struct ast_variable *iaxvars;
00822
00823 struct iax_rr remote_rr;
00824
00825 int min;
00826
00827 int frames_dropped;
00828
00829 int frames_received;
00830
00831 unsigned char calltoken_ie_len;
00832
00833 char hold_signaling;
00834
00835 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00836 };
00837
00838 struct signaling_queue_entry {
00839 struct ast_frame f;
00840 AST_LIST_ENTRY(signaling_queue_entry) next;
00841 };
00842
00843
00844 static struct ao2_container *callno_pool;
00845
00846
00847 static struct ao2_container *callno_pool_trunk;
00848
00849 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860 static AST_LIST_HEAD_NOLOCK(, iax_frame) frame_queue[IAX_MAX_CALLS + 1];
00861
00862 static struct ast_taskprocessor *transmit_processor;
00863
00864 static int randomcalltokendata;
00865
00866 static const time_t MAX_CALLTOKEN_DELAY = 10;
00867
00868
00869
00870
00871
00872
00873
00874
00875 #ifdef LOW_MEMORY
00876 #define MAX_PEER_BUCKETS 17
00877 #else
00878 #define MAX_PEER_BUCKETS 563
00879 #endif
00880 static struct ao2_container *peers;
00881
00882 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00883 static struct ao2_container *users;
00884
00885
00886 static struct ao2_container *peercnts;
00887
00888
00889 static struct ao2_container *callno_limits;
00890
00891
00892 static struct ao2_container *calltoken_ignores;
00893
00894 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00895
00896 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00897
00898 static uint16_t global_maxcallno;
00899
00900
00901 static uint16_t global_maxcallno_nonval;
00902
00903 static uint16_t total_nonval_callno_used = 0;
00904
00905
00906
00907 struct peercnt {
00908
00909 unsigned long addr;
00910
00911 uint16_t cur;
00912
00913 uint16_t limit;
00914
00915
00916 unsigned char reg;
00917 };
00918
00919
00920 struct addr_range {
00921
00922 struct ast_ha ha;
00923
00924 uint16_t limit;
00925
00926 unsigned char delme;
00927 };
00928
00929 struct callno_entry {
00930
00931 uint16_t callno;
00932
00933 unsigned char validated;
00934 };
00935
00936 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00937
00938 enum {
00939
00940 CACHE_FLAG_EXISTS = (1 << 0),
00941
00942 CACHE_FLAG_NONEXISTENT = (1 << 1),
00943
00944 CACHE_FLAG_CANEXIST = (1 << 2),
00945
00946 CACHE_FLAG_PENDING = (1 << 3),
00947
00948 CACHE_FLAG_TIMEOUT = (1 << 4),
00949
00950 CACHE_FLAG_TRANSMITTED = (1 << 5),
00951
00952 CACHE_FLAG_UNKNOWN = (1 << 6),
00953
00954 CACHE_FLAG_MATCHMORE = (1 << 7),
00955 };
00956
00957 struct iax2_dpcache {
00958 char peercontext[AST_MAX_CONTEXT];
00959 char exten[AST_MAX_EXTENSION];
00960 struct timeval orig;
00961 struct timeval expiry;
00962 int flags;
00963 unsigned short callno;
00964 int waiters[256];
00965 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00966 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00967 };
00968
00969 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00970
00971 static void reg_source_db(struct iax2_peer *p);
00972 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00973 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00974
00975 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00976 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags);
00977 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00978
00979 enum iax2_thread_iostate {
00980 IAX_IOSTATE_IDLE,
00981 IAX_IOSTATE_READY,
00982 IAX_IOSTATE_PROCESSING,
00983 IAX_IOSTATE_SCHEDREADY,
00984 };
00985
00986 enum iax2_thread_type {
00987 IAX_THREAD_TYPE_POOL,
00988 IAX_THREAD_TYPE_DYNAMIC,
00989 };
00990
00991 struct iax2_pkt_buf {
00992 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00993 size_t len;
00994 unsigned char buf[1];
00995 };
00996
00997 struct iax2_thread {
00998 AST_LIST_ENTRY(iax2_thread) list;
00999 enum iax2_thread_type type;
01000 enum iax2_thread_iostate iostate;
01001 #ifdef SCHED_MULTITHREADED
01002 void (*schedfunc)(const void *);
01003 const void *scheddata;
01004 #endif
01005 #ifdef DEBUG_SCHED_MULTITHREAD
01006 char curfunc[80];
01007 #endif
01008 int actions;
01009 pthread_t threadid;
01010 int threadnum;
01011 struct sockaddr_in iosin;
01012 unsigned char readbuf[4096];
01013 unsigned char *buf;
01014 ssize_t buf_len;
01015 size_t buf_size;
01016 int iofd;
01017 time_t checktime;
01018 ast_mutex_t lock;
01019 ast_cond_t cond;
01020 ast_mutex_t init_lock;
01021 ast_cond_t init_cond;
01022
01023
01024
01025
01026 struct {
01027 unsigned short callno;
01028 struct sockaddr_in sin;
01029 unsigned char type;
01030 unsigned char csub;
01031 } ffinfo;
01032
01033
01034
01035 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
01036 unsigned char stop;
01037 };
01038
01039
01040 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
01041 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
01042 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
01043
01044 static void *iax2_process_thread(void *data);
01045 static void iax2_destroy(int callno);
01046
01047 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
01048 {
01049 ast_mutex_lock(lock);
01050 ast_cond_signal(cond);
01051 ast_mutex_unlock(lock);
01052 }
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS + 1];
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 static struct ao2_container *iax_peercallno_pvts;
01074
01075
01076
01077
01078
01079
01080
01081
01082 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
01083
01084
01085
01086
01087
01088
01089 static struct ao2_container *iax_transfercallno_pvts;
01090
01091
01092
01093 #define TRUNK_CALL_START IAX_MAX_CALLS / 2
01094
01095
01096 static struct sockaddr_in debugaddr;
01097
01098 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
01099 {
01100 if (iaxdebug ||
01101 (sin && debugaddr.sin_addr.s_addr &&
01102 (!ntohs(debugaddr.sin_port) ||
01103 debugaddr.sin_port == sin->sin_port) &&
01104 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01105 if (iaxdebug) {
01106 iax_showframe(f, fhi, rx, sin, datalen);
01107 } else {
01108 iaxdebug = 1;
01109 iax_showframe(f, fhi, rx, sin, datalen);
01110 iaxdebug = 0;
01111 }
01112 }
01113 }
01114
01115 static void iax_debug_output(const char *data)
01116 {
01117 if (iaxdebug)
01118 ast_verbose("%s", data);
01119 }
01120
01121 static void iax_error_output(const char *data)
01122 {
01123 ast_log(LOG_WARNING, "%s", data);
01124 }
01125
01126 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
01127 {
01128 va_list args;
01129 char buf[1024];
01130
01131 va_start(args, fmt);
01132 vsnprintf(buf, sizeof(buf), fmt, args);
01133 va_end(args);
01134
01135 ast_log(LOG_ERROR, "%s", buf);
01136 }
01137
01138 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01139 {
01140 va_list args;
01141 char buf[1024];
01142
01143 va_start(args, fmt);
01144 vsnprintf(buf, sizeof(buf), fmt, args);
01145 va_end(args);
01146
01147 ast_log(LOG_WARNING, "%s", buf);
01148 }
01149
01150 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01151 {
01152 va_list args;
01153 char buf[1024];
01154
01155 va_start(args, fmt);
01156 vsnprintf(buf, sizeof(buf), fmt, args);
01157 va_end(args);
01158
01159 ast_verbose("%s", buf);
01160 }
01161
01162 static int maxtrunkcall = TRUNK_CALL_START;
01163 static int maxnontrunkcall = 1;
01164
01165 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);
01166 static int expire_registry(const void *data);
01167 static int iax2_answer(struct ast_channel *c);
01168 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01169 static int iax2_devicestate(void *data);
01170 static int iax2_digit_begin(struct ast_channel *c, char digit);
01171 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01172 static int iax2_do_register(struct iax2_registry *reg);
01173 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01174 static int iax2_hangup(struct ast_channel *c);
01175 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01176 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01177 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force);
01178 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01179 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01180 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01181 static int iax2_sendtext(struct ast_channel *c, const char *text);
01182 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01183 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen);
01184 static int iax2_transfer(struct ast_channel *c, const char *dest);
01185 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01186 static int iax2_sched_add(struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data);
01187
01188 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01189 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01190 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01191 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01192 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01193 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01194 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
01195 static struct ast_frame *iax2_read(struct ast_channel *c);
01196 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01197 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01198 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime);
01199 static void *iax2_dup_variable_datastore(void *);
01200 static void prune_peers(void);
01201 static void prune_users(void);
01202 static void iax2_free_variable_datastore(void *);
01203
01204 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01205 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01206 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01207 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01208 static void build_rand_pad(unsigned char *buf, ssize_t len);
01209 static struct callno_entry *get_unused_callno(int trunk, int validated);
01210 static int replace_callno(const void *obj);
01211 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01212 static void network_change_event_cb(const struct ast_event *, void *);
01213
01214 static const struct ast_channel_tech iax2_tech = {
01215 .type = "IAX2",
01216 .description = tdesc,
01217 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01218 .properties = AST_CHAN_TP_WANTSJITTER,
01219 .requester = iax2_request,
01220 .devicestate = iax2_devicestate,
01221 .send_digit_begin = iax2_digit_begin,
01222 .send_digit_end = iax2_digit_end,
01223 .send_text = iax2_sendtext,
01224 .send_image = iax2_sendimage,
01225 .send_html = iax2_sendhtml,
01226 .call = iax2_call,
01227 .hangup = iax2_hangup,
01228 .answer = iax2_answer,
01229 .read = iax2_read,
01230 .write = iax2_write,
01231 .write_video = iax2_write,
01232 .indicate = iax2_indicate,
01233 .setoption = iax2_setoption,
01234 .queryoption = iax2_queryoption,
01235 .bridge = iax2_bridge,
01236 .transfer = iax2_transfer,
01237 .fixup = iax2_fixup,
01238 .func_channel_read = acf_channel_read,
01239 };
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258 static void iax2_lock_owner(int callno)
01259 {
01260 for (;;) {
01261 if (!iaxs[callno] || !iaxs[callno]->owner) {
01262
01263 break;
01264 }
01265 if (!ast_channel_trylock(iaxs[callno]->owner)) {
01266
01267 break;
01268 }
01269
01270 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01271 }
01272 }
01273
01274 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01275 {
01276
01277
01278
01279 }
01280
01281 static void network_change_event_subscribe(void)
01282 {
01283 if (!network_change_event_subscription) {
01284 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE,
01285 network_change_event_cb,
01286 "SIP Network Change ",
01287 NULL,
01288 AST_EVENT_IE_END);
01289 }
01290 }
01291
01292 static void network_change_event_unsubscribe(void)
01293 {
01294 if (network_change_event_subscription) {
01295 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription);
01296 }
01297 }
01298
01299 static int network_change_event_sched_cb(const void *data)
01300 {
01301 struct iax2_registry *reg;
01302 network_change_event_sched_id = -1;
01303 AST_LIST_LOCK(®istrations);
01304 AST_LIST_TRAVERSE(®istrations, reg, entry) {
01305 iax2_do_register(reg);
01306 }
01307 AST_LIST_UNLOCK(®istrations);
01308
01309 return 0;
01310 }
01311
01312 static void network_change_event_cb(const struct ast_event *event, void *userdata)
01313 {
01314 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n");
01315 if (network_change_event_sched_id == -1) {
01316 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
01317 }
01318
01319 }
01320
01321
01322
01323
01324 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01325 {
01326 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01327 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01328 pvt->owner ? pvt->owner->name : "",
01329 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01330 }
01331
01332 static struct ast_datastore_info iax2_variable_datastore_info = {
01333 .type = "IAX2_VARIABLE",
01334 .duplicate = iax2_dup_variable_datastore,
01335 .destroy = iax2_free_variable_datastore,
01336 };
01337
01338 static void *iax2_dup_variable_datastore(void *old)
01339 {
01340 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01341 struct ast_var_t *oldvar, *newvar;
01342
01343 newlist = ast_calloc(sizeof(*newlist), 1);
01344 if (!newlist) {
01345 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01346 return NULL;
01347 }
01348
01349 AST_LIST_HEAD_INIT(newlist);
01350 AST_LIST_LOCK(oldlist);
01351 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01352 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01353 if (newvar)
01354 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01355 else
01356 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01357 }
01358 AST_LIST_UNLOCK(oldlist);
01359 return newlist;
01360 }
01361
01362 static void iax2_free_variable_datastore(void *old)
01363 {
01364 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01365 struct ast_var_t *oldvar;
01366
01367 AST_LIST_LOCK(oldlist);
01368 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01369 ast_free(oldvar);
01370 }
01371 AST_LIST_UNLOCK(oldlist);
01372 AST_LIST_HEAD_DESTROY(oldlist);
01373 ast_free(oldlist);
01374 }
01375
01376
01377
01378
01379
01380 static void insert_idle_thread(struct iax2_thread *thread)
01381 {
01382 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01383 AST_LIST_LOCK(&dynamic_list);
01384 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01385 AST_LIST_UNLOCK(&dynamic_list);
01386 } else {
01387 AST_LIST_LOCK(&idle_list);
01388 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01389 AST_LIST_UNLOCK(&idle_list);
01390 }
01391
01392 return;
01393 }
01394
01395 static struct iax2_thread *find_idle_thread(void)
01396 {
01397 struct iax2_thread *thread = NULL;
01398
01399
01400 AST_LIST_LOCK(&idle_list);
01401 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01402 AST_LIST_UNLOCK(&idle_list);
01403
01404
01405 if (thread) {
01406 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01407 return thread;
01408 }
01409
01410
01411 AST_LIST_LOCK(&dynamic_list);
01412 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01413 AST_LIST_UNLOCK(&dynamic_list);
01414
01415
01416 if (thread) {
01417 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01418 return thread;
01419 }
01420
01421
01422 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01423 return NULL;
01424
01425
01426 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01427 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01428 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01429
01430
01431 ast_mutex_init(&thread->lock);
01432 ast_cond_init(&thread->cond, NULL);
01433 ast_mutex_init(&thread->init_lock);
01434 ast_cond_init(&thread->init_cond, NULL);
01435 ast_mutex_lock(&thread->init_lock);
01436
01437
01438 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01439 ast_cond_destroy(&thread->cond);
01440 ast_mutex_destroy(&thread->lock);
01441 ast_mutex_unlock(&thread->init_lock);
01442 ast_cond_destroy(&thread->init_cond);
01443 ast_mutex_destroy(&thread->init_lock);
01444 ast_free(thread);
01445 return NULL;
01446 }
01447
01448
01449
01450 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01451
01452
01453 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01454
01455
01456 ast_mutex_unlock(&thread->init_lock);
01457
01458 return thread;
01459 }
01460
01461 #ifdef SCHED_MULTITHREADED
01462 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01463 {
01464 struct iax2_thread *thread = NULL;
01465 static time_t lasterror;
01466 static time_t t;
01467
01468 thread = find_idle_thread();
01469
01470 if (thread != NULL) {
01471 thread->schedfunc = func;
01472 thread->scheddata = data;
01473 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01474 #ifdef DEBUG_SCHED_MULTITHREAD
01475 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01476 #endif
01477 signal_condition(&thread->lock, &thread->cond);
01478 return 0;
01479 }
01480 time(&t);
01481 if (t != lasterror)
01482 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01483 lasterror = t;
01484
01485 return -1;
01486 }
01487 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01488 #endif
01489
01490 static int iax2_sched_replace(int id, struct ast_sched_thread *st, int when,
01491 ast_sched_cb callback, const void *data)
01492 {
01493 ast_sched_thread_del(st, id);
01494
01495 return ast_sched_thread_add(st, when, callback, data);
01496 }
01497
01498 static int iax2_sched_add(struct ast_sched_thread *st, int when,
01499 ast_sched_cb callback, const void *data)
01500 {
01501 return ast_sched_thread_add(st, when, callback, data);
01502 }
01503
01504 static int send_ping(const void *data);
01505
01506 static void __send_ping(const void *data)
01507 {
01508 int callno = (long) data;
01509
01510 ast_mutex_lock(&iaxsl[callno]);
01511
01512 if (iaxs[callno]) {
01513 if (iaxs[callno]->peercallno) {
01514 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01515 if (iaxs[callno]->pingid != DONT_RESCHEDULE) {
01516 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01517 }
01518 }
01519 } else {
01520 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01521 }
01522
01523 ast_mutex_unlock(&iaxsl[callno]);
01524 }
01525
01526 static int send_ping(const void *data)
01527 {
01528 int callno = (long) data;
01529 ast_mutex_lock(&iaxsl[callno]);
01530 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) {
01531 iaxs[callno]->pingid = -1;
01532 }
01533 ast_mutex_unlock(&iaxsl[callno]);
01534
01535 #ifdef SCHED_MULTITHREADED
01536 if (schedule_action(__send_ping, data))
01537 #endif
01538 __send_ping(data);
01539
01540 return 0;
01541 }
01542
01543 static void encmethods_to_str(int e, struct ast_str *buf)
01544 {
01545 ast_str_set(&buf, 0, "(");
01546 if (e & IAX_ENCRYPT_AES128) {
01547 ast_str_append(&buf, 0, "aes128");
01548 }
01549 if (e & IAX_ENCRYPT_KEYROTATE) {
01550 ast_str_append(&buf, 0, ",keyrotate");
01551 }
01552 if (ast_str_strlen(buf) > 1) {
01553 ast_str_append(&buf, 0, ")");
01554 } else {
01555 ast_str_set(&buf, 0, "No");
01556 }
01557 }
01558
01559 static int get_encrypt_methods(const char *s)
01560 {
01561 int e;
01562 if (!strcasecmp(s, "aes128"))
01563 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01564 else if (ast_true(s))
01565 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01566 else
01567 e = 0;
01568 return e;
01569 }
01570
01571 static int send_lagrq(const void *data);
01572
01573 static void __send_lagrq(const void *data)
01574 {
01575 int callno = (long) data;
01576
01577 ast_mutex_lock(&iaxsl[callno]);
01578
01579 if (iaxs[callno]) {
01580 if (iaxs[callno]->peercallno) {
01581 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01582 if (iaxs[callno]->lagid != DONT_RESCHEDULE) {
01583 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01584 }
01585 }
01586 } else {
01587 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01588 }
01589
01590 ast_mutex_unlock(&iaxsl[callno]);
01591 }
01592
01593 static int send_lagrq(const void *data)
01594 {
01595 int callno = (long) data;
01596 ast_mutex_lock(&iaxsl[callno]);
01597 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) {
01598 iaxs[callno]->lagid = -1;
01599 }
01600 ast_mutex_unlock(&iaxsl[callno]);
01601
01602 #ifdef SCHED_MULTITHREADED
01603 if (schedule_action(__send_lagrq, data))
01604 #endif
01605 __send_lagrq(data);
01606 return 0;
01607 }
01608
01609 static unsigned char compress_subclass(format_t subclass)
01610 {
01611 int x;
01612 int power=-1;
01613
01614 if (subclass < IAX_FLAG_SC_LOG)
01615 return subclass;
01616
01617 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01618 if (subclass & (1LL << x)) {
01619 if (power > -1) {
01620 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
01621 return 0;
01622 } else
01623 power = x;
01624 }
01625 }
01626 return power | IAX_FLAG_SC_LOG;
01627 }
01628
01629 static format_t uncompress_subclass(unsigned char csub)
01630 {
01631
01632 if (csub & IAX_FLAG_SC_LOG) {
01633
01634 if (csub == 0xff)
01635 return -1;
01636 else
01637 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01638 }
01639 else
01640 return csub;
01641 }
01642
01643
01644
01645
01646 static int peer_hash_cb(const void *obj, const int flags)
01647 {
01648 const struct iax2_peer *peer = obj;
01649
01650 return ast_str_hash(peer->name);
01651 }
01652
01653
01654
01655
01656 static int peer_cmp_cb(void *obj, void *arg, int flags)
01657 {
01658 struct iax2_peer *peer = obj, *peer2 = arg;
01659
01660 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01661 }
01662
01663
01664
01665
01666 static int user_hash_cb(const void *obj, const int flags)
01667 {
01668 const struct iax2_user *user = obj;
01669
01670 return ast_str_hash(user->name);
01671 }
01672
01673
01674
01675
01676 static int user_cmp_cb(void *obj, void *arg, int flags)
01677 {
01678 struct iax2_user *user = obj, *user2 = arg;
01679
01680 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01681 }
01682
01683
01684
01685
01686
01687 static struct iax2_peer *find_peer(const char *name, int realtime)
01688 {
01689 struct iax2_peer *peer = NULL;
01690 struct iax2_peer tmp_peer = {
01691 .name = name,
01692 };
01693
01694 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01695
01696
01697 if(!peer && realtime)
01698 peer = realtime_peer(name, NULL);
01699
01700 return peer;
01701 }
01702
01703 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01704 {
01705 ao2_ref(peer, +1);
01706 return peer;
01707 }
01708
01709 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01710 {
01711 ao2_ref(peer, -1);
01712 return NULL;
01713 }
01714
01715 static struct iax2_user *find_user(const char *name)
01716 {
01717 struct iax2_user tmp_user = {
01718 .name = name,
01719 };
01720
01721 return ao2_find(users, &tmp_user, OBJ_POINTER);
01722 }
01723 static inline struct iax2_user *user_ref(struct iax2_user *user)
01724 {
01725 ao2_ref(user, +1);
01726 return user;
01727 }
01728
01729 static inline struct iax2_user *user_unref(struct iax2_user *user)
01730 {
01731 ao2_ref(user, -1);
01732 return NULL;
01733 }
01734
01735 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01736 {
01737 struct iax2_peer *peer = NULL;
01738 int res = 0;
01739 struct ao2_iterator i;
01740
01741 i = ao2_iterator_init(peers, 0);
01742 while ((peer = ao2_iterator_next(&i))) {
01743 struct sockaddr_in peer_addr;
01744
01745 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
01746
01747 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01748 (peer_addr.sin_port == sin.sin_port)) {
01749 ast_copy_string(host, peer->name, len);
01750 peer_unref(peer);
01751 res = 1;
01752 break;
01753 }
01754 peer_unref(peer);
01755 }
01756 ao2_iterator_destroy(&i);
01757
01758 if (!peer) {
01759 peer = realtime_peer(NULL, &sin);
01760 if (peer) {
01761 ast_copy_string(host, peer->name, len);
01762 peer_unref(peer);
01763 res = 1;
01764 }
01765 }
01766
01767 return res;
01768 }
01769
01770
01771
01772 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01773 {
01774
01775 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
01776 struct iax2_user *user;
01777 struct iax2_user tmp_user = {
01778 .name = pvt->username,
01779 };
01780
01781 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01782 if (user) {
01783 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01784 user_unref(user);
01785 }
01786
01787 ast_clear_flag64(pvt, IAX_MAXAUTHREQ);
01788 }
01789
01790 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01791 pvt->pingid = DONT_RESCHEDULE;
01792 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01793 pvt->lagid = DONT_RESCHEDULE;
01794 ast_sched_thread_del(sched, pvt->autoid);
01795 ast_sched_thread_del(sched, pvt->authid);
01796 ast_sched_thread_del(sched, pvt->initid);
01797 ast_sched_thread_del(sched, pvt->jbid);
01798 ast_sched_thread_del(sched, pvt->keyrotateid);
01799 }
01800
01801 static void iax2_frame_free(struct iax_frame *fr)
01802 {
01803 ast_sched_thread_del(sched, fr->retrans);
01804 iax_frame_free(fr);
01805 }
01806
01807 static int scheduled_destroy(const void *vid)
01808 {
01809 unsigned short callno = PTR_TO_CALLNO(vid);
01810 ast_mutex_lock(&iaxsl[callno]);
01811 if (iaxs[callno]) {
01812 if (option_debug) {
01813 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01814 }
01815 iax2_destroy(callno);
01816 }
01817 ast_mutex_unlock(&iaxsl[callno]);
01818 return 0;
01819 }
01820
01821 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01822 {
01823 ast_free(s->f.data.ptr);
01824 ast_free(s);
01825 }
01826
01827
01828
01829 static void send_signaling(struct chan_iax2_pvt *pvt)
01830 {
01831 struct signaling_queue_entry *s = NULL;
01832
01833 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01834 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01835 free_signaling_queue_entry(s);
01836 }
01837 pvt->hold_signaling = 0;
01838 }
01839
01840
01841
01842 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01843 {
01844 struct signaling_queue_entry *new;
01845
01846 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01847 return 1;
01848 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01849 return -1;
01850 }
01851
01852 memcpy(&new->f, f, sizeof(new->f));
01853
01854 if (new->f.datalen) {
01855 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01856 free_signaling_queue_entry(new);
01857 return -1;
01858 }
01859 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01860 }
01861 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01862
01863 return 0;
01864 }
01865
01866 static void pvt_destructor(void *obj)
01867 {
01868 struct chan_iax2_pvt *pvt = obj;
01869 struct iax_frame *cur = NULL;
01870 struct signaling_queue_entry *s = NULL;
01871
01872 ast_mutex_lock(&iaxsl[pvt->callno]);
01873
01874 iax2_destroy_helper(pvt);
01875
01876 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01877 pvt->callno_entry = NULL;
01878
01879
01880 ast_set_flag64(pvt, IAX_ALREADYGONE);
01881
01882 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
01883
01884 cur->retries = -1;
01885 }
01886
01887 ast_mutex_unlock(&iaxsl[pvt->callno]);
01888
01889 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01890 free_signaling_queue_entry(s);
01891 }
01892
01893 if (pvt->reg) {
01894 pvt->reg->callno = 0;
01895 }
01896
01897 if (!pvt->owner) {
01898 jb_frame frame;
01899 if (pvt->vars) {
01900 ast_variables_destroy(pvt->vars);
01901 pvt->vars = NULL;
01902 }
01903
01904 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01905 iax2_frame_free(frame.data);
01906 }
01907
01908 jb_destroy(pvt->jb);
01909 ast_string_field_free_memory(pvt);
01910 }
01911 }
01912
01913 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01914 {
01915 struct chan_iax2_pvt *tmp;
01916 jb_conf jbconf;
01917
01918 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01919 return NULL;
01920 }
01921
01922 if (ast_string_field_init(tmp, 32)) {
01923 ao2_ref(tmp, -1);
01924 tmp = NULL;
01925 return NULL;
01926 }
01927
01928 tmp->prefs = prefs;
01929 tmp->pingid = -1;
01930 tmp->lagid = -1;
01931 tmp->autoid = -1;
01932 tmp->authid = -1;
01933 tmp->initid = -1;
01934 tmp->keyrotateid = -1;
01935
01936 ast_string_field_set(tmp,exten, "s");
01937 ast_string_field_set(tmp,host, host);
01938
01939 tmp->jb = jb_new();
01940 tmp->jbid = -1;
01941 jbconf.max_jitterbuf = maxjitterbuffer;
01942 jbconf.resync_threshold = resyncthreshold;
01943 jbconf.max_contig_interp = maxjitterinterps;
01944 jbconf.target_extra = jittertargetextra;
01945 jb_setconf(tmp->jb,&jbconf);
01946
01947 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01948
01949 tmp->hold_signaling = 1;
01950 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01951
01952 return tmp;
01953 }
01954
01955 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01956 {
01957 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01958 if (new) {
01959 size_t afdatalen = new->afdatalen;
01960 memcpy(new, fr, sizeof(*new));
01961 iax_frame_wrap(new, &fr->af);
01962 new->afdatalen = afdatalen;
01963 new->data = NULL;
01964 new->datalen = 0;
01965 new->direction = DIRECTION_INGRESS;
01966 new->retrans = -1;
01967 }
01968 return new;
01969 }
01970
01971
01972 enum {
01973
01974 NEW_PREVENT = 0,
01975
01976 NEW_ALLOW = 1,
01977
01978 NEW_FORCE = 2,
01979
01980
01981 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01982 };
01983
01984 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01985 {
01986 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01987 (cur->addr.sin_port == sin->sin_port)) {
01988
01989 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01990 (check_dcallno ? dcallno == cur->callno : 1) ) {
01991
01992 return 1;
01993 }
01994 }
01995 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01996 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01997
01998 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01999 return 1;
02000 }
02001 return 0;
02002 }
02003
02004 static void update_max_trunk(void)
02005 {
02006 int max = TRUNK_CALL_START;
02007 int x;
02008
02009
02010 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
02011 if (iaxs[x]) {
02012 max = x + 1;
02013 }
02014 }
02015
02016 maxtrunkcall = max;
02017 if (iaxdebug)
02018 ast_debug(1, "New max trunk callno is %d\n", max);
02019 }
02020
02021 static void update_max_nontrunk(void)
02022 {
02023 int max = 1;
02024 int x;
02025
02026 for (x=1;x<TRUNK_CALL_START - 1; x++) {
02027 if (iaxs[x])
02028 max = x + 1;
02029 }
02030 maxnontrunkcall = max;
02031 if (iaxdebug)
02032 ast_debug(1, "New max nontrunk callno is %d\n", max);
02033 }
02034
02035 static int make_trunk(unsigned short callno, int locked)
02036 {
02037 int x;
02038 int res= 0;
02039 struct callno_entry *callno_entry;
02040 if (iaxs[callno]->oseqno) {
02041 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
02042 return -1;
02043 }
02044 if (callno & TRUNK_CALL_START) {
02045 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
02046 return -1;
02047 }
02048
02049 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
02050 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
02051 return -1;
02052 }
02053
02054 x = callno_entry->callno;
02055 ast_mutex_lock(&iaxsl[x]);
02056
02057
02058
02059
02060
02061 ast_sched_thread_del(sched, iaxs[callno]->pingid);
02062 ast_sched_thread_del(sched, iaxs[callno]->lagid);
02063 iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
02064 iaxs[x] = iaxs[callno];
02065 iaxs[x]->callno = x;
02066
02067
02068
02069 if (iaxs[x]->callno_entry) {
02070 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
02071 }
02072 iaxs[x]->callno_entry = callno_entry;
02073
02074 iaxs[callno] = NULL;
02075
02076 iaxs[x]->pingid = iax2_sched_add(sched,
02077 ping_time * 1000, send_ping, (void *)(long)x);
02078 iaxs[x]->lagid = iax2_sched_add(sched,
02079 lagrq_time * 1000, send_lagrq, (void *)(long)x);
02080
02081 if (locked)
02082 ast_mutex_unlock(&iaxsl[callno]);
02083 res = x;
02084 if (!locked)
02085 ast_mutex_unlock(&iaxsl[x]);
02086
02087 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
02088
02089 update_max_trunk();
02090 update_max_nontrunk();
02091 return res;
02092 }
02093
02094 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
02095 {
02096 if (!pvt->transfercallno) {
02097 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02098 return;
02099 }
02100
02101 ao2_link(iax_transfercallno_pvts, pvt);
02102 }
02103
02104 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
02105 {
02106 if (!pvt->transfercallno) {
02107 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02108 return;
02109 }
02110
02111 ao2_unlink(iax_transfercallno_pvts, pvt);
02112 }
02113 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
02114 {
02115 if (!pvt->peercallno) {
02116 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02117 return;
02118 }
02119
02120 ao2_link(iax_peercallno_pvts, pvt);
02121 }
02122
02123 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
02124 {
02125 if (!pvt->peercallno) {
02126 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02127 return;
02128 }
02129
02130 ao2_unlink(iax_peercallno_pvts, pvt);
02131 }
02132
02133 static int addr_range_delme_cb(void *obj, void *arg, int flags)
02134 {
02135 struct addr_range *lim = obj;
02136 lim->delme = 1;
02137 return 0;
02138 }
02139
02140 static int addr_range_hash_cb(const void *obj, const int flags)
02141 {
02142 const struct addr_range *lim = obj;
02143 struct sockaddr_in sin;
02144 ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02145 return abs((int) sin.sin_addr.s_addr);
02146 }
02147
02148 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
02149 {
02150 struct addr_range *lim1 = obj, *lim2 = arg;
02151 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02152 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02153 CMP_MATCH | CMP_STOP : 0;
02154 }
02155
02156 static int peercnt_hash_cb(const void *obj, const int flags)
02157 {
02158 const struct peercnt *peercnt = obj;
02159 return abs((int) peercnt->addr);
02160 }
02161
02162 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
02163 {
02164 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02165 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02166 }
02167
02168 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
02169 {
02170 struct addr_range *addr_range = obj;
02171 struct sockaddr_in *sin = arg;
02172 struct sockaddr_in ha_netmask_sin;
02173 struct sockaddr_in ha_addr_sin;
02174
02175 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02176 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02177
02178 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02179 return CMP_MATCH | CMP_STOP;
02180 }
02181 return 0;
02182 }
02183
02184
02185
02186
02187
02188
02189 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
02190 {
02191 struct addr_range *addr_range;
02192 struct iax2_peer *peer = NULL;
02193 struct iax2_user *user = NULL;
02194
02195 const char *find = S_OR(name, "guest");
02196 int res = 1;
02197 int optional = 0;
02198 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02199
02200
02201
02202
02203
02204
02205
02206 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02207 ao2_ref(addr_range, -1);
02208 optional = 1;
02209 }
02210
02211
02212 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02213 calltoken_required = user->calltoken_required;
02214 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02215 calltoken_required = user->calltoken_required;
02216 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02217 calltoken_required = peer->calltoken_required;
02218 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02219 calltoken_required = peer->calltoken_required;
02220 }
02221
02222 if (peer) {
02223 peer_unref(peer);
02224 }
02225 if (user) {
02226 user_unref(user);
02227 }
02228
02229 ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required);
02230 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02231 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02232 res = 0;
02233 }
02234
02235 return res;
02236 }
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 static void set_peercnt_limit(struct peercnt *peercnt)
02249 {
02250 uint16_t limit = global_maxcallno;
02251 struct addr_range *addr_range;
02252 struct sockaddr_in sin = {
02253 .sin_addr.s_addr = peercnt->addr,
02254 };
02255
02256
02257 if (peercnt->reg && peercnt->limit) {
02258 return;
02259 }
02260
02261 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02262 limit = addr_range->limit;
02263 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02264 ao2_ref(addr_range, -1);
02265 }
02266
02267 peercnt->limit = limit;
02268 }
02269
02270
02271
02272
02273
02274 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02275 {
02276 struct peercnt *peercnt = obj;
02277
02278 set_peercnt_limit(peercnt);
02279 ast_debug(1, "Reset limits for peercnts table\n");
02280
02281 return 0;
02282 }
02283
02284
02285
02286
02287
02288 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02289 {
02290 struct addr_range *addr_range = obj;
02291
02292 return addr_range->delme ? CMP_MATCH : 0;
02293 }
02294
02295
02296
02297
02298
02299 static void peercnt_modify(unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
02300 {
02301
02302 struct peercnt *peercnt;
02303 struct peercnt tmp = {
02304 .addr = 0,
02305 };
02306 struct sockaddr_in sin;
02307
02308 ast_sockaddr_to_sin(sockaddr, &sin);
02309
02310 tmp.addr = sin.sin_addr.s_addr;
02311
02312 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02313 peercnt->reg = reg;
02314 if (limit) {
02315 peercnt->limit = limit;
02316 } else {
02317 set_peercnt_limit(peercnt);
02318 }
02319 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02320 ao2_ref(peercnt, -1);
02321 }
02322 }
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332 static int peercnt_add(struct sockaddr_in *sin)
02333 {
02334 struct peercnt *peercnt;
02335 unsigned long addr = sin->sin_addr.s_addr;
02336 int res = 0;
02337 struct peercnt tmp = {
02338 .addr = addr,
02339 };
02340
02341
02342
02343
02344
02345
02346
02347 ao2_lock(peercnts);
02348 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02349 ao2_lock(peercnt);
02350 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02351 ao2_lock(peercnt);
02352
02353 peercnt->addr = addr;
02354 set_peercnt_limit(peercnt);
02355
02356
02357 ao2_link(peercnts, peercnt);
02358 } else {
02359 ao2_unlock(peercnts);
02360 return -1;
02361 }
02362
02363
02364 if (peercnt->limit > peercnt->cur) {
02365 peercnt->cur++;
02366 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02367 } else {
02368 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02369 res = -1;
02370 }
02371
02372
02373 ao2_unlock(peercnt);
02374 ao2_unlock(peercnts);
02375 ao2_ref(peercnt, -1);
02376
02377 return res;
02378 }
02379
02380
02381
02382
02383
02384 static void peercnt_remove(struct peercnt *peercnt)
02385 {
02386 struct sockaddr_in sin = {
02387 .sin_addr.s_addr = peercnt->addr,
02388 };
02389
02390 if (peercnt) {
02391
02392
02393
02394 ao2_lock(peercnts);
02395 peercnt->cur--;
02396 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02397
02398 if (peercnt->cur == 0) {
02399 ao2_unlink(peercnts, peercnt);
02400 }
02401 ao2_unlock(peercnts);
02402 }
02403 }
02404
02405
02406
02407
02408
02409 static int peercnt_remove_cb(const void *obj)
02410 {
02411 struct peercnt *peercnt = (struct peercnt *) obj;
02412
02413 peercnt_remove(peercnt);
02414 ao2_ref(peercnt, -1);
02415
02416 return 0;
02417 }
02418
02419
02420
02421
02422
02423 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02424 {
02425 struct peercnt *peercnt;
02426 struct peercnt tmp = {
02427 .addr = sin->sin_addr.s_addr,
02428 };
02429
02430 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02431 peercnt_remove(peercnt);
02432 ao2_ref(peercnt, -1);
02433 }
02434 return 0;
02435 }
02436
02437
02438
02439
02440
02441 static void build_callno_limits(struct ast_variable *v)
02442 {
02443 struct addr_range *addr_range = NULL;
02444 struct addr_range tmp;
02445 struct ast_ha *ha;
02446 int limit;
02447 int error;
02448 int found;
02449
02450 for (; v; v = v->next) {
02451 limit = -1;
02452 error = 0;
02453 found = 0;
02454 ha = ast_append_ha("permit", v->name, NULL, &error);
02455
02456
02457 if (error) {
02458 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02459 continue;
02460 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02461 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02462 ast_free_ha(ha);
02463 continue;
02464 }
02465
02466 ast_copy_ha(ha, &tmp.ha);
02467
02468 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02469 ao2_lock(addr_range);
02470 found = 1;
02471 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02472 ast_free_ha(ha);
02473 return;
02474 }
02475
02476
02477 ast_copy_ha(ha, &addr_range->ha);
02478 ast_free_ha(ha);
02479 addr_range->limit = limit;
02480 addr_range->delme = 0;
02481
02482
02483 if (found) {
02484 ao2_unlock(addr_range);
02485 } else {
02486 ao2_link(callno_limits, addr_range);
02487 }
02488 ao2_ref(addr_range, -1);
02489 }
02490 }
02491
02492
02493
02494
02495
02496 static int add_calltoken_ignore(const char *addr)
02497 {
02498 struct addr_range tmp;
02499 struct addr_range *addr_range = NULL;
02500 struct ast_ha *ha = NULL;
02501 int error = 0;
02502
02503 if (ast_strlen_zero(addr)) {
02504 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02505 return -1;
02506 }
02507
02508 ha = ast_append_ha("permit", addr, NULL, &error);
02509
02510
02511 if (error) {
02512 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02513 return -1;
02514 }
02515
02516 ast_copy_ha(ha, &tmp.ha);
02517
02518 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02519 ao2_lock(addr_range);
02520 addr_range->delme = 0;
02521 ao2_unlock(addr_range);
02522 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02523
02524 ast_copy_ha(ha, &addr_range->ha);
02525 ao2_link(calltoken_ignores, addr_range);
02526 } else {
02527 ast_free_ha(ha);
02528 return -1;
02529 }
02530
02531 ast_free_ha(ha);
02532 ao2_ref(addr_range, -1);
02533
02534 return 0;
02535 }
02536
02537 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02538 {
02539 struct ao2_iterator i;
02540 struct peercnt *peercnt;
02541 struct sockaddr_in sin;
02542 int found = 0;
02543
02544 switch (cmd) {
02545 case CLI_INIT:
02546 e->command = "iax2 show callnumber usage";
02547 e->usage =
02548 "Usage: iax2 show callnumber usage [IP address]\n"
02549 " Shows current IP addresses which are consuming iax2 call numbers\n";
02550 return NULL;
02551 case CLI_GENERATE:
02552 return NULL;
02553 case CLI_HANDLER:
02554 if (a->argc < 4 || a->argc > 5)
02555 return CLI_SHOWUSAGE;
02556
02557 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02558 i = ao2_iterator_init(peercnts, 0);
02559 while ((peercnt = ao2_iterator_next(&i))) {
02560 sin.sin_addr.s_addr = peercnt->addr;
02561 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02562 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02563 found = 1;
02564 break;
02565 } else {
02566 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02567 }
02568 ao2_ref(peercnt, -1);
02569 }
02570 ao2_iterator_destroy(&i);
02571
02572 if (a->argc == 4) {
02573 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02574 "Non-CallToken Validated Callno Used: %d\n",
02575 global_maxcallno_nonval,
02576 total_nonval_callno_used);
02577
02578 ast_cli(a->fd, "Total Available Callno: %d\n"
02579 "Regular Callno Available: %d\n"
02580 "Trunk Callno Available: %d\n",
02581 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02582 ao2_container_count(callno_pool),
02583 ao2_container_count(callno_pool_trunk));
02584 } else if (a->argc == 5 && !found) {
02585 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02586 }
02587
02588
02589 return CLI_SUCCESS;
02590 default:
02591 return NULL;
02592 }
02593 }
02594
02595 static struct callno_entry *get_unused_callno(int trunk, int validated)
02596 {
02597 struct callno_entry *callno_entry = NULL;
02598 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02599 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02600
02601 return NULL;
02602 }
02603
02604
02605
02606 ao2_lock(callno_pool);
02607
02608
02609
02610
02611 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02612 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02613 ao2_unlock(callno_pool);
02614 return NULL;
02615 }
02616
02617
02618
02619 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02620
02621 if (callno_entry) {
02622 callno_entry->validated = validated;
02623 if (!validated) {
02624 total_nonval_callno_used++;
02625 }
02626 }
02627
02628 ao2_unlock(callno_pool);
02629 return callno_entry;
02630 }
02631
02632 static int replace_callno(const void *obj)
02633 {
02634 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02635
02636
02637
02638 ao2_lock(callno_pool);
02639
02640 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02641 total_nonval_callno_used--;
02642 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02643 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02644 }
02645
02646 if (callno_entry->callno < TRUNK_CALL_START) {
02647 ao2_link(callno_pool, callno_entry);
02648 } else {
02649 ao2_link(callno_pool_trunk, callno_entry);
02650 }
02651 ao2_ref(callno_entry, -1);
02652
02653 ao2_unlock(callno_pool);
02654 return 0;
02655 }
02656
02657 static int callno_hash(const void *obj, const int flags)
02658 {
02659 return abs(ast_random());
02660 }
02661
02662 static int create_callno_pools(void)
02663 {
02664 uint16_t i;
02665
02666 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02667 return -1;
02668 }
02669
02670 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02671 return -1;
02672 }
02673
02674
02675 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02676 struct callno_entry *callno_entry;
02677
02678 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02679 return -1;
02680 }
02681
02682 callno_entry->callno = i;
02683
02684 if (i < TRUNK_CALL_START) {
02685 ao2_link(callno_pool, callno_entry);
02686 } else {
02687 ao2_link(callno_pool_trunk, callno_entry);
02688 }
02689
02690 ao2_ref(callno_entry, -1);
02691 }
02692
02693 return 0;
02694 }
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02705 {
02706 int i;
02707 struct peercnt *peercnt;
02708 struct peercnt tmp = {
02709 .addr = sin->sin_addr.s_addr,
02710 };
02711
02712 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02713
02714 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02715 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02716 if (i == -1) {
02717 ao2_ref(peercnt, -1);
02718 }
02719 }
02720
02721 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02722 }
02723
02724
02725
02726
02727
02728
02729
02730
02731 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02732 {
02733 if (frametype != AST_FRAME_IAX) {
02734 return 0;
02735 }
02736 switch (subclass) {
02737 case IAX_COMMAND_NEW:
02738 case IAX_COMMAND_REGREQ:
02739 case IAX_COMMAND_FWDOWNL:
02740 case IAX_COMMAND_REGREL:
02741 return 1;
02742 case IAX_COMMAND_POKE:
02743 if (!inbound) {
02744 return 1;
02745 }
02746 break;
02747 }
02748 return 0;
02749 }
02750
02751
02752
02753
02754 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02755 {
02756 int res = 0;
02757 int x;
02758
02759
02760 int validated = (new > NEW_ALLOW) ? 1 : 0;
02761 char host[80];
02762
02763 if (new <= NEW_ALLOW) {
02764 if (callno) {
02765 struct chan_iax2_pvt *pvt;
02766 struct chan_iax2_pvt tmp_pvt = {
02767 .callno = dcallno,
02768 .peercallno = callno,
02769 .transfercallno = callno,
02770
02771 .frames_received = check_dcallno,
02772 };
02773
02774 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02775
02776 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02777 if (return_locked) {
02778 ast_mutex_lock(&iaxsl[pvt->callno]);
02779 }
02780 res = pvt->callno;
02781 ao2_ref(pvt, -1);
02782 pvt = NULL;
02783 return res;
02784 }
02785
02786 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02787 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02788 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02789 if (return_locked) {
02790 ast_mutex_lock(&iaxsl[pvt->callno]);
02791 }
02792 res = pvt->callno;
02793 ao2_ref(pvt, -1);
02794 pvt = NULL;
02795 return res;
02796 }
02797 }
02798
02799
02800 if (dcallno) {
02801 ast_mutex_lock(&iaxsl[dcallno]);
02802 }
02803 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02804 iaxs[dcallno]->peercallno = callno;
02805 res = dcallno;
02806 store_by_peercallno(iaxs[dcallno]);
02807 if (!res || !return_locked) {
02808 ast_mutex_unlock(&iaxsl[dcallno]);
02809 }
02810 return res;
02811 }
02812 if (dcallno) {
02813 ast_mutex_unlock(&iaxsl[dcallno]);
02814 }
02815 #ifdef IAX_OLD_FIND
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827 for (x = 1; !res && x < maxnontrunkcall; x++) {
02828 ast_mutex_lock(&iaxsl[x]);
02829 if (iaxs[x]) {
02830
02831 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02832 res = x;
02833 }
02834 }
02835 if (!res || !return_locked)
02836 ast_mutex_unlock(&iaxsl[x]);
02837 }
02838 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02839 ast_mutex_lock(&iaxsl[x]);
02840 if (iaxs[x]) {
02841
02842 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02843 res = x;
02844 }
02845 }
02846 if (!res || !return_locked)
02847 ast_mutex_unlock(&iaxsl[x]);
02848 }
02849 #endif
02850 }
02851 if (!res && (new >= NEW_ALLOW)) {
02852 struct callno_entry *callno_entry;
02853
02854
02855
02856
02857
02858
02859 if (!iax2_getpeername(*sin, host, sizeof(host)))
02860 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02861
02862 if (peercnt_add(sin)) {
02863
02864
02865 return 0;
02866 }
02867
02868 if (!(callno_entry = get_unused_callno(0, validated))) {
02869
02870
02871 peercnt_remove_by_addr(sin);
02872 ast_log(LOG_WARNING, "No more space\n");
02873 return 0;
02874 }
02875 x = callno_entry->callno;
02876 ast_mutex_lock(&iaxsl[x]);
02877
02878 iaxs[x] = new_iax(sin, host);
02879 update_max_nontrunk();
02880 if (iaxs[x]) {
02881 if (iaxdebug)
02882 ast_debug(1, "Creating new call structure %d\n", x);
02883 iaxs[x]->callno_entry = callno_entry;
02884 iaxs[x]->sockfd = sockfd;
02885 iaxs[x]->addr.sin_port = sin->sin_port;
02886 iaxs[x]->addr.sin_family = sin->sin_family;
02887 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02888 iaxs[x]->peercallno = callno;
02889 iaxs[x]->callno = x;
02890 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02891 iaxs[x]->expiry = min_reg_expire;
02892 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02893 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02894 iaxs[x]->amaflags = amaflags;
02895 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
02896 ast_string_field_set(iaxs[x], accountcode, accountcode);
02897 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02898 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02899 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02900
02901 if (iaxs[x]->peercallno) {
02902 store_by_peercallno(iaxs[x]);
02903 }
02904 } else {
02905 ast_log(LOG_WARNING, "Out of resources\n");
02906 ast_mutex_unlock(&iaxsl[x]);
02907 replace_callno(callno_entry);
02908 return 0;
02909 }
02910 if (!return_locked)
02911 ast_mutex_unlock(&iaxsl[x]);
02912 res = x;
02913 }
02914 return res;
02915 }
02916
02917 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02918 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02919 }
02920
02921 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02922
02923 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02924 }
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936 static int iax2_queue_frame(int callno, struct ast_frame *f)
02937 {
02938 iax2_lock_owner(callno);
02939 if (iaxs[callno] && iaxs[callno]->owner) {
02940 ast_queue_frame(iaxs[callno]->owner, f);
02941 ast_channel_unlock(iaxs[callno]->owner);
02942 }
02943 return 0;
02944 }
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959 static int iax2_queue_hangup(int callno)
02960 {
02961 iax2_lock_owner(callno);
02962 if (iaxs[callno] && iaxs[callno]->owner) {
02963 ast_queue_hangup(iaxs[callno]->owner);
02964 ast_channel_unlock(iaxs[callno]->owner);
02965 }
02966 return 0;
02967 }
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982 static int iax2_queue_control_data(int callno,
02983 enum ast_control_frame_type control, const void *data, size_t datalen)
02984 {
02985 iax2_lock_owner(callno);
02986 if (iaxs[callno] && iaxs[callno]->owner) {
02987 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02988 ast_channel_unlock(iaxs[callno]->owner);
02989 }
02990 return 0;
02991 }
02992 static void destroy_firmware(struct iax_firmware *cur)
02993 {
02994
02995 if (cur->fwh) {
02996 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02997 }
02998 close(cur->fd);
02999 ast_free(cur);
03000 }
03001
03002 static int try_firmware(char *s)
03003 {
03004 struct stat stbuf;
03005 struct iax_firmware *cur = NULL;
03006 int ifd, fd, res, len, chunk;
03007 struct ast_iax2_firmware_header *fwh, fwh2;
03008 struct MD5Context md5;
03009 unsigned char sum[16], buf[1024];
03010 char *s2, *last;
03011
03012 if (!(s2 = alloca(strlen(s) + 100))) {
03013 ast_log(LOG_WARNING, "Alloca failed!\n");
03014 return -1;
03015 }
03016
03017 last = strrchr(s, '/');
03018 if (last)
03019 last++;
03020 else
03021 last = s;
03022
03023 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03024
03025 if ((res = stat(s, &stbuf) < 0)) {
03026 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03027 return -1;
03028 }
03029
03030
03031 if (S_ISDIR(stbuf.st_mode))
03032 return -1;
03033 ifd = open(s, O_RDONLY);
03034 if (ifd < 0) {
03035 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03036 return -1;
03037 }
03038 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03039 if (fd < 0) {
03040 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03041 close(ifd);
03042 return -1;
03043 }
03044
03045 unlink(s2);
03046
03047
03048 len = stbuf.st_size;
03049 while(len) {
03050 chunk = len;
03051 if (chunk > sizeof(buf))
03052 chunk = sizeof(buf);
03053 res = read(ifd, buf, chunk);
03054 if (res != chunk) {
03055 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03056 close(ifd);
03057 close(fd);
03058 return -1;
03059 }
03060 res = write(fd, buf, chunk);
03061 if (res != chunk) {
03062 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03063 close(ifd);
03064 close(fd);
03065 return -1;
03066 }
03067 len -= chunk;
03068 }
03069 close(ifd);
03070
03071 lseek(fd, 0, SEEK_SET);
03072 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03073 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03074 close(fd);
03075 return -1;
03076 }
03077 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03078 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03079 close(fd);
03080 return -1;
03081 }
03082 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03083 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03084 close(fd);
03085 return -1;
03086 }
03087 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03088 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03089 close(fd);
03090 return -1;
03091 }
03092 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
03093 if (fwh == MAP_FAILED) {
03094 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03095 close(fd);
03096 return -1;
03097 }
03098 MD5Init(&md5);
03099 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03100 MD5Final(sum, &md5);
03101 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03102 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03103 munmap((void*)fwh, stbuf.st_size);
03104 close(fd);
03105 return -1;
03106 }
03107
03108 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03109 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03110
03111 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03112
03113 break;
03114
03115
03116 munmap((void*)fwh, stbuf.st_size);
03117 close(fd);
03118 return 0;
03119 }
03120 }
03121
03122 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03123 cur->fd = -1;
03124 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03125 }
03126
03127 if (cur) {
03128 if (cur->fwh)
03129 munmap((void*)cur->fwh, cur->mmaplen);
03130 if (cur->fd > -1)
03131 close(cur->fd);
03132 cur->fwh = fwh;
03133 cur->fd = fd;
03134 cur->mmaplen = stbuf.st_size;
03135 cur->dead = 0;
03136 }
03137
03138 return 0;
03139 }
03140
03141 static int iax_check_version(char *dev)
03142 {
03143 int res = 0;
03144 struct iax_firmware *cur = NULL;
03145
03146 if (ast_strlen_zero(dev))
03147 return 0;
03148
03149 AST_LIST_LOCK(&firmwares);
03150 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03151 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03152 res = ntohs(cur->fwh->version);
03153 break;
03154 }
03155 }
03156 AST_LIST_UNLOCK(&firmwares);
03157
03158 return res;
03159 }
03160
03161 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03162 {
03163 int res = -1;
03164 unsigned int bs = desc & 0xff;
03165 unsigned int start = (desc >> 8) & 0xffffff;
03166 unsigned int bytes;
03167 struct iax_firmware *cur;
03168
03169 if (ast_strlen_zero((char *)dev) || !bs)
03170 return -1;
03171
03172 start *= bs;
03173
03174 AST_LIST_LOCK(&firmwares);
03175 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03176 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03177 continue;
03178 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03179 if (start < ntohl(cur->fwh->datalen)) {
03180 bytes = ntohl(cur->fwh->datalen) - start;
03181 if (bytes > bs)
03182 bytes = bs;
03183 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03184 } else {
03185 bytes = 0;
03186 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03187 }
03188 if (bytes == bs)
03189 res = 0;
03190 else
03191 res = 1;
03192 break;
03193 }
03194 AST_LIST_UNLOCK(&firmwares);
03195
03196 return res;
03197 }
03198
03199
03200 static void reload_firmware(int unload)
03201 {
03202 struct iax_firmware *cur = NULL;
03203 DIR *fwd;
03204 struct dirent *de;
03205 char dir[256], fn[256];
03206
03207 AST_LIST_LOCK(&firmwares);
03208
03209
03210 AST_LIST_TRAVERSE(&firmwares, cur, list)
03211 cur->dead = 1;
03212
03213
03214 if (!unload) {
03215 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03216 fwd = opendir(dir);
03217 if (fwd) {
03218 while((de = readdir(fwd))) {
03219 if (de->d_name[0] != '.') {
03220 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03221 if (!try_firmware(fn)) {
03222 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03223 }
03224 }
03225 }
03226 closedir(fwd);
03227 } else
03228 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03229 }
03230
03231
03232 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03233 if (!cur->dead)
03234 continue;
03235 AST_LIST_REMOVE_CURRENT(list);
03236 destroy_firmware(cur);
03237 }
03238 AST_LIST_TRAVERSE_SAFE_END;
03239
03240 AST_LIST_UNLOCK(&firmwares);
03241 }
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251 static int __do_deliver(void *data)
03252 {
03253
03254
03255 struct iax_frame *fr = data;
03256 fr->retrans = -1;
03257 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03258 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03259 iax2_queue_frame(fr->callno, &fr->af);
03260
03261 iax2_frame_free(fr);
03262
03263 return 0;
03264 }
03265
03266 static int handle_error(void)
03267 {
03268
03269
03270
03271 #if 0
03272 struct sockaddr_in *sin;
03273 int res;
03274 struct msghdr m;
03275 struct sock_extended_err e;
03276 m.msg_name = NULL;
03277 m.msg_namelen = 0;
03278 m.msg_iov = NULL;
03279 m.msg_control = &e;
03280 m.msg_controllen = sizeof(e);
03281 m.msg_flags = 0;
03282 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03283 if (res < 0)
03284 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03285 else {
03286 if (m.msg_controllen) {
03287 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03288 if (sin)
03289 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03290 else
03291 ast_log(LOG_WARNING, "No address detected??\n");
03292 } else {
03293 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03294 }
03295 }
03296 #endif
03297 return 0;
03298 }
03299
03300 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03301 {
03302 int res;
03303 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03304 sizeof(*sin));
03305 if (res < 0) {
03306 ast_debug(1, "Received error: %s\n", strerror(errno));
03307 handle_error();
03308 } else
03309 res = 0;
03310 return res;
03311 }
03312
03313 static int send_packet(struct iax_frame *f)
03314 {
03315 int res;
03316 int callno = f->callno;
03317
03318
03319 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03320 return -1;
03321
03322
03323 if (iaxdebug)
03324 ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
03325
03326 if (f->transfer) {
03327 if (iaxdebug)
03328 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03329 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03330 } else {
03331 if (iaxdebug)
03332 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03333 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03334 }
03335 if (res < 0) {
03336 if (iaxdebug)
03337 ast_debug(1, "Received error: %s\n", strerror(errno));
03338 handle_error();
03339 } else
03340 res = 0;
03341
03342 return res;
03343 }
03344
03345
03346
03347
03348
03349 static int iax2_predestroy(int callno)
03350 {
03351 struct ast_channel *c = NULL;
03352 struct chan_iax2_pvt *pvt = iaxs[callno];
03353
03354 if (!pvt)
03355 return -1;
03356
03357 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03358 iax2_destroy_helper(pvt);
03359 ast_set_flag64(pvt, IAX_ALREADYGONE);
03360 }
03361
03362 if ((c = pvt->owner)) {
03363 c->tech_pvt = NULL;
03364 iax2_queue_hangup(callno);
03365 pvt->owner = NULL;
03366 ast_module_unref(ast_module_info->self);
03367 }
03368
03369 return 0;
03370 }
03371
03372 static void iax2_destroy(int callno)
03373 {
03374 struct chan_iax2_pvt *pvt = NULL;
03375 struct ast_channel *owner = NULL;
03376
03377 retry:
03378 if ((pvt = iaxs[callno])) {
03379 #if 0
03380
03381
03382
03383
03384
03385
03386
03387 iax2_destroy_helper(pvt);
03388 #endif
03389 }
03390
03391 owner = pvt ? pvt->owner : NULL;
03392
03393 if (owner) {
03394 if (ast_channel_trylock(owner)) {
03395 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03396 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03397 goto retry;
03398 }
03399 }
03400
03401 if (!owner) {
03402 iaxs[callno] = NULL;
03403 }
03404
03405 if (pvt) {
03406 if (!owner) {
03407 pvt->owner = NULL;
03408 } else {
03409
03410
03411
03412 ast_queue_hangup(owner);
03413 }
03414
03415 if (pvt->peercallno) {
03416 remove_by_peercallno(pvt);
03417 }
03418
03419 if (pvt->transfercallno) {
03420 remove_by_transfercallno(pvt);
03421 }
03422
03423 if (!owner) {
03424 ao2_ref(pvt, -1);
03425 pvt = NULL;
03426 }
03427 }
03428
03429 if (owner) {
03430 ast_channel_unlock(owner);
03431 }
03432
03433 if (callno & 0x4000) {
03434 update_max_trunk();
03435 }
03436 }
03437
03438 static int update_packet(struct iax_frame *f)
03439 {
03440
03441 struct ast_iax2_full_hdr *fh = f->data;
03442 struct ast_frame af;
03443
03444
03445 if (f->encmethods) {
03446 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03447 }
03448
03449 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03450
03451 f->iseqno = iaxs[f->callno]->iseqno;
03452 fh->iseqno = f->iseqno;
03453
03454
03455 if (f->encmethods) {
03456
03457
03458 build_rand_pad(f->semirand, sizeof(f->semirand));
03459 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03460 }
03461 return 0;
03462 }
03463
03464 static int attempt_transmit(const void *data);
03465 static void __attempt_transmit(const void *data)
03466 {
03467
03468
03469 struct iax_frame *f = (struct iax_frame *)data;
03470 int freeme = 0;
03471 int callno = f->callno;
03472
03473 if (callno)
03474 ast_mutex_lock(&iaxsl[callno]);
03475 if (callno && iaxs[callno]) {
03476 if ((f->retries < 0) ||
03477 (f->retries >= max_retries) ) {
03478
03479 if (f->retries >= max_retries) {
03480 if (f->transfer) {
03481
03482 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03483 } else if (f->final) {
03484 iax2_destroy(callno);
03485 } else {
03486 if (iaxs[callno]->owner)
03487 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass.integer, f->ts, f->oseqno);
03488 iaxs[callno]->error = ETIMEDOUT;
03489 if (iaxs[callno]->owner) {
03490 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03491
03492 iax2_queue_frame(callno, &fr);
03493
03494 if (iaxs[callno] && iaxs[callno]->owner)
03495 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03496 } else {
03497 if (iaxs[callno]->reg) {
03498 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03499 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03500 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03501 }
03502 iax2_destroy(callno);
03503 }
03504 }
03505
03506 }
03507 freeme = 1;
03508 } else {
03509
03510 update_packet(f);
03511
03512 send_packet(f);
03513 f->retries++;
03514
03515 f->retrytime *= 10;
03516 if (f->retrytime > MAX_RETRY_TIME)
03517 f->retrytime = MAX_RETRY_TIME;
03518
03519 if (f->transfer && (f->retrytime > 1000))
03520 f->retrytime = 1000;
03521 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03522 }
03523 } else {
03524
03525 f->retries = -1;
03526 freeme = 1;
03527 }
03528
03529 if (freeme) {
03530
03531 AST_LIST_REMOVE(&frame_queue[callno], f, list);
03532 ast_mutex_unlock(&iaxsl[callno]);
03533 f->retrans = -1;
03534
03535 iax2_frame_free(f);
03536 } else if (callno) {
03537 ast_mutex_unlock(&iaxsl[callno]);
03538 }
03539 }
03540
03541 static int attempt_transmit(const void *data)
03542 {
03543 #ifdef SCHED_MULTITHREADED
03544 if (schedule_action(__attempt_transmit, data))
03545 #endif
03546 __attempt_transmit(data);
03547 return 0;
03548 }
03549
03550 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03551 {
03552 struct iax2_peer *peer = NULL;
03553 struct iax2_user *user = NULL;
03554 static const char * const choices[] = { "all", NULL };
03555 char *cmplt;
03556
03557 switch (cmd) {
03558 case CLI_INIT:
03559 e->command = "iax2 prune realtime";
03560 e->usage =
03561 "Usage: iax2 prune realtime [<peername>|all]\n"
03562 " Prunes object(s) from the cache\n";
03563 return NULL;
03564 case CLI_GENERATE:
03565 if (a->pos == 3) {
03566 cmplt = ast_cli_complete(a->word, choices, a->n);
03567 if (!cmplt)
03568 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03569 return cmplt;
03570 }
03571 return NULL;
03572 }
03573 if (a->argc != 4)
03574 return CLI_SHOWUSAGE;
03575 if (!strcmp(a->argv[3], "all")) {
03576 prune_users();
03577 prune_peers();
03578 ast_cli(a->fd, "Cache flushed successfully.\n");
03579 return CLI_SUCCESS;
03580 }
03581 peer = find_peer(a->argv[3], 0);
03582 user = find_user(a->argv[3]);
03583 if (peer || user) {
03584 if (peer) {
03585 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03586 ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03587 expire_registry(peer_ref(peer));
03588 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03589 } else {
03590 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03591 }
03592 peer_unref(peer);
03593 }
03594 if (user) {
03595 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03596 ast_set_flag64(user, IAX_RTAUTOCLEAR);
03597 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03598 } else {
03599 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03600 }
03601 ao2_unlink(users,user);
03602 user_unref(user);
03603 }
03604 } else {
03605 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03606 }
03607
03608 return CLI_SUCCESS;
03609 }
03610
03611 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03612 {
03613 switch (cmd) {
03614 case CLI_INIT:
03615 e->command = "iax2 test losspct";
03616 e->usage =
03617 "Usage: iax2 test losspct <percentage>\n"
03618 " For testing, throws away <percentage> percent of incoming packets\n";
03619 return NULL;
03620 case CLI_GENERATE:
03621 return NULL;
03622 }
03623 if (a->argc != 4)
03624 return CLI_SHOWUSAGE;
03625
03626 test_losspct = atoi(a->argv[3]);
03627
03628 return CLI_SUCCESS;
03629 }
03630
03631 #ifdef IAXTESTS
03632 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03633 {
03634 switch (cmd) {
03635 case CLI_INIT:
03636 e->command = "iax2 test late";
03637 e->usage =
03638 "Usage: iax2 test late <ms>\n"
03639 " For testing, count the next frame as <ms> ms late\n";
03640 return NULL;
03641 case CLI_GENERATE:
03642 return NULL;
03643 }
03644
03645 if (a->argc != 4)
03646 return CLI_SHOWUSAGE;
03647
03648 test_late = atoi(a->argv[3]);
03649
03650 return CLI_SUCCESS;
03651 }
03652
03653 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03654 {
03655 switch (cmd) {
03656 case CLI_INIT:
03657 e->command = "iax2 test resync";
03658 e->usage =
03659 "Usage: iax2 test resync <ms>\n"
03660 " For testing, adjust all future frames by <ms> ms\n";
03661 return NULL;
03662 case CLI_GENERATE:
03663 return NULL;
03664 }
03665
03666 if (a->argc != 4)
03667 return CLI_SHOWUSAGE;
03668
03669 test_resync = atoi(a->argv[3]);
03670
03671 return CLI_SUCCESS;
03672 }
03673
03674 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03675 {
03676 switch (cmd) {
03677 case CLI_INIT:
03678 e->command = "iax2 test jitter";
03679 e->usage =
03680 "Usage: iax2 test jitter <ms> <pct>\n"
03681 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03682 " percentage of packets. If <pct> is not specified, adds\n"
03683 " jitter to all packets.\n";
03684 return NULL;
03685 case CLI_GENERATE:
03686 return NULL;
03687 }
03688
03689 if (a->argc < 4 || a->argc > 5)
03690 return CLI_SHOWUSAGE;
03691
03692 test_jit = atoi(a->argv[3]);
03693 if (a->argc == 5)
03694 test_jitpct = atoi(a->argv[4]);
03695
03696 return CLI_SUCCESS;
03697 }
03698 #endif
03699
03700
03701
03702 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03703 {
03704 int res = 0;
03705 if (peer->maxms) {
03706 if (peer->lastms < 0) {
03707 ast_copy_string(status, "UNREACHABLE", statuslen);
03708 } else if (peer->lastms > peer->maxms) {
03709 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03710 res = 1;
03711 } else if (peer->lastms) {
03712 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03713 res = 1;
03714 } else {
03715 ast_copy_string(status, "UNKNOWN", statuslen);
03716 }
03717 } else {
03718 ast_copy_string(status, "Unmonitored", statuslen);
03719 res = -1;
03720 }
03721 return res;
03722 }
03723
03724
03725 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03726 {
03727 char status[30];
03728 char cbuf[256];
03729 struct iax2_peer *peer;
03730 char codec_buf[512];
03731 struct ast_str *encmethods = ast_str_alloca(256);
03732 int x = 0, codec = 0, load_realtime = 0;
03733
03734 switch (cmd) {
03735 case CLI_INIT:
03736 e->command = "iax2 show peer";
03737 e->usage =
03738 "Usage: iax2 show peer <name>\n"
03739 " Display details on specific IAX peer\n";
03740 return NULL;
03741 case CLI_GENERATE:
03742 if (a->pos == 3)
03743 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03744 return NULL;
03745 }
03746
03747 if (a->argc < 4)
03748 return CLI_SHOWUSAGE;
03749
03750 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03751
03752 peer = find_peer(a->argv[3], load_realtime);
03753 if (peer) {
03754 struct sockaddr_in peer_addr;
03755
03756 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03757
03758 encmethods_to_str(peer->encmethods, encmethods);
03759 ast_cli(a->fd, "\n\n");
03760 ast_cli(a->fd, " * Name : %s\n", peer->name);
03761 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03762 ast_cli(a->fd, " Context : %s\n", peer->context);
03763 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03764 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03765 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03766 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03767 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03768 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03769 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03770 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03771 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03772 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03773 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));
03774 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03775 ast_cli(a->fd, " Username : %s\n", peer->username);
03776 ast_cli(a->fd, " Codecs : ");
03777 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03778 ast_cli(a->fd, "%s\n", codec_buf);
03779
03780 ast_cli(a->fd, " Codec Order : (");
03781 for(x = 0; x < 32 ; x++) {
03782 codec = ast_codec_pref_index(&peer->prefs,x);
03783 if(!codec)
03784 break;
03785 ast_cli(a->fd, "%s", ast_getformatname(codec));
03786 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03787 ast_cli(a->fd, "|");
03788 }
03789
03790 if (!x)
03791 ast_cli(a->fd, "none");
03792 ast_cli(a->fd, ")\n");
03793
03794 ast_cli(a->fd, " Status : ");
03795 peer_status(peer, status, sizeof(status));
03796 ast_cli(a->fd, "%s\n",status);
03797 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");
03798 ast_cli(a->fd, "\n");
03799 peer_unref(peer);
03800 } else {
03801 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03802 ast_cli(a->fd, "\n");
03803 }
03804
03805 return CLI_SUCCESS;
03806 }
03807
03808 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
03809 {
03810 int which = 0;
03811 struct iax2_peer *peer;
03812 char *res = NULL;
03813 int wordlen = strlen(word);
03814 struct ao2_iterator i;
03815
03816 i = ao2_iterator_init(peers, 0);
03817 while ((peer = ao2_iterator_next(&i))) {
03818 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03819 && (!flags || ast_test_flag64(peer, flags))) {
03820 res = ast_strdup(peer->name);
03821 peer_unref(peer);
03822 break;
03823 }
03824 peer_unref(peer);
03825 }
03826 ao2_iterator_destroy(&i);
03827
03828 return res;
03829 }
03830
03831 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03832 {
03833 struct iax_frame *cur;
03834 int cnt = 0, dead = 0, final = 0, i = 0;
03835
03836 switch (cmd) {
03837 case CLI_INIT:
03838 e->command = "iax2 show stats";
03839 e->usage =
03840 "Usage: iax2 show stats\n"
03841 " Display statistics on IAX channel driver.\n";
03842 return NULL;
03843 case CLI_GENERATE:
03844 return NULL;
03845 }
03846
03847 if (a->argc != 3)
03848 return CLI_SHOWUSAGE;
03849
03850 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03851 ast_mutex_lock(&iaxsl[i]);
03852 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03853 if (cur->retries < 0)
03854 dead++;
03855 if (cur->final)
03856 final++;
03857 cnt++;
03858 }
03859 ast_mutex_unlock(&iaxsl[i]);
03860 }
03861
03862 ast_cli(a->fd, " IAX Statistics\n");
03863 ast_cli(a->fd, "---------------------\n");
03864 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03865 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03866 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03867 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03868
03869 trunk_timed = trunk_untimed = 0;
03870 if (trunk_maxmtu > trunk_nmaxmtu)
03871 trunk_nmaxmtu = trunk_maxmtu;
03872
03873 return CLI_SUCCESS;
03874 }
03875
03876
03877 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03878 {
03879 int mtuv;
03880
03881 switch (cmd) {
03882 case CLI_INIT:
03883 e->command = "iax2 set mtu";
03884 e->usage =
03885 "Usage: iax2 set mtu <value>\n"
03886 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03887 " zero to disable. Disabling means that the operating system\n"
03888 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03889 " packet exceeds the UDP payload size. This is substantially\n"
03890 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03891 " greater for G.711 samples.\n";
03892 return NULL;
03893 case CLI_GENERATE:
03894 return NULL;
03895 }
03896
03897 if (a->argc != 4)
03898 return CLI_SHOWUSAGE;
03899 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03900 mtuv = MAX_TRUNK_MTU;
03901 else
03902 mtuv = atoi(a->argv[3]);
03903
03904 if (mtuv == 0) {
03905 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03906 global_max_trunk_mtu = 0;
03907 return CLI_SUCCESS;
03908 }
03909 if (mtuv < 172 || mtuv > 4000) {
03910 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03911 return CLI_SHOWUSAGE;
03912 }
03913 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03914 global_max_trunk_mtu = mtuv;
03915 return CLI_SUCCESS;
03916 }
03917
03918 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03919 {
03920 struct iax2_dpcache *dp = NULL;
03921 char tmp[1024], *pc = NULL;
03922 int s, x, y;
03923 struct timeval now = ast_tvnow();
03924
03925 switch (cmd) {
03926 case CLI_INIT:
03927 e->command = "iax2 show cache";
03928 e->usage =
03929 "Usage: iax2 show cache\n"
03930 " Display currently cached IAX Dialplan results.\n";
03931 return NULL;
03932 case CLI_GENERATE:
03933 return NULL;
03934 }
03935
03936 AST_LIST_LOCK(&dpcache);
03937
03938 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03939
03940 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03941 s = dp->expiry.tv_sec - now.tv_sec;
03942 tmp[0] = '\0';
03943 if (dp->flags & CACHE_FLAG_EXISTS)
03944 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03945 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03946 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03947 if (dp->flags & CACHE_FLAG_CANEXIST)
03948 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03949 if (dp->flags & CACHE_FLAG_PENDING)
03950 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03951 if (dp->flags & CACHE_FLAG_TIMEOUT)
03952 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03953 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03954 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03955 if (dp->flags & CACHE_FLAG_MATCHMORE)
03956 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03957 if (dp->flags & CACHE_FLAG_UNKNOWN)
03958 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03959
03960 if (!ast_strlen_zero(tmp)) {
03961 tmp[strlen(tmp) - 1] = '\0';
03962 } else {
03963 ast_copy_string(tmp, "(none)", sizeof(tmp));
03964 }
03965 y = 0;
03966 pc = strchr(dp->peercontext, '@');
03967 if (!pc) {
03968 pc = dp->peercontext;
03969 } else {
03970 pc++;
03971 }
03972 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03973 if (dp->waiters[x] > -1)
03974 y++;
03975 }
03976 if (s > 0) {
03977 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03978 } else {
03979 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03980 }
03981 }
03982
03983 AST_LIST_UNLOCK(&dpcache);
03984
03985 return CLI_SUCCESS;
03986 }
03987
03988 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03989
03990 static void unwrap_timestamp(struct iax_frame *fr)
03991 {
03992
03993
03994 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03995 const int lower_mask = (1 << ts_shift) - 1;
03996 const int upper_mask = ~lower_mask;
03997 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03998
03999 if ( (fr->ts & upper_mask) == last_upper ) {
04000 const int x = fr->ts - iaxs[fr->callno]->last;
04001 const int threshold = (ts_shift == 15) ? 25000 : 50000;
04002
04003 if (x < -threshold) {
04004
04005
04006
04007
04008 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04009 if (iaxdebug)
04010 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04011 } else if (x > threshold) {
04012
04013
04014
04015
04016 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04017 if (iaxdebug)
04018 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04019 }
04020 }
04021 }
04022
04023 static int get_from_jb(const void *p);
04024
04025 static void update_jbsched(struct chan_iax2_pvt *pvt)
04026 {
04027 int when;
04028
04029 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04030
04031 when = jb_next(pvt->jb) - when;
04032
04033 if (when <= 0) {
04034
04035 when = 1;
04036 }
04037
04038 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
04039 CALLNO_TO_PTR(pvt->callno));
04040 }
04041
04042 static void __get_from_jb(const void *p)
04043 {
04044 int callno = PTR_TO_CALLNO(p);
04045 struct chan_iax2_pvt *pvt = NULL;
04046 struct iax_frame *fr;
04047 jb_frame frame;
04048 int ret;
04049 long ms;
04050 long next;
04051 struct timeval now = ast_tvnow();
04052
04053
04054 ast_mutex_lock(&iaxsl[callno]);
04055 pvt = iaxs[callno];
04056 if (!pvt) {
04057
04058 ast_mutex_unlock(&iaxsl[callno]);
04059 return;
04060 }
04061
04062 pvt->jbid = -1;
04063
04064
04065
04066
04067 now.tv_usec += 1000;
04068
04069 ms = ast_tvdiff_ms(now, pvt->rxcore);
04070
04071 if(ms >= (next = jb_next(pvt->jb))) {
04072 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
04073 switch(ret) {
04074 case JB_OK:
04075 fr = frame.data;
04076 __do_deliver(fr);
04077
04078 pvt = iaxs[callno];
04079 break;
04080 case JB_INTERP:
04081 {
04082 struct ast_frame af = { 0, };
04083
04084
04085 af.frametype = AST_FRAME_VOICE;
04086 af.subclass.codec = pvt->voiceformat;
04087 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
04088 af.src = "IAX2 JB interpolation";
04089 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04090 af.offset = AST_FRIENDLY_OFFSET;
04091
04092
04093
04094 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04095 iax2_queue_frame(callno, &af);
04096
04097 pvt = iaxs[callno];
04098 }
04099 }
04100 break;
04101 case JB_DROP:
04102 iax2_frame_free(frame.data);
04103 break;
04104 case JB_NOFRAME:
04105 case JB_EMPTY:
04106
04107 break;
04108 default:
04109
04110 break;
04111 }
04112 }
04113 if (pvt)
04114 update_jbsched(pvt);
04115 ast_mutex_unlock(&iaxsl[callno]);
04116 }
04117
04118 static int get_from_jb(const void *data)
04119 {
04120 #ifdef SCHED_MULTITHREADED
04121 if (schedule_action(__get_from_jb, data))
04122 #endif
04123 __get_from_jb(data);
04124 return 0;
04125 }
04126
04127
04128
04129
04130
04131
04132
04133 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
04134 {
04135 int type, len;
04136 int ret;
04137 int needfree = 0;
04138 struct ast_channel *owner = NULL;
04139 struct ast_channel *bridge = NULL;
04140
04141
04142 unwrap_timestamp(fr);
04143
04144
04145 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04146 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04147 else {
04148 #if 0
04149 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04150 #endif
04151 fr->af.delivery = ast_tv(0,0);
04152 }
04153
04154 type = JB_TYPE_CONTROL;
04155 len = 0;
04156
04157 if(fr->af.frametype == AST_FRAME_VOICE) {
04158 type = JB_TYPE_VOICE;
04159 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04160 } else if(fr->af.frametype == AST_FRAME_CNG) {
04161 type = JB_TYPE_SILENCE;
04162 }
04163
04164 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04165 if (tsout)
04166 *tsout = fr->ts;
04167 __do_deliver(fr);
04168 return -1;
04169 }
04170
04171 iax2_lock_owner(fr->callno);
04172 if (!iaxs[fr->callno]) {
04173
04174 iax2_frame_free(fr);
04175 return -1;
04176 }
04177 if ((owner = iaxs[fr->callno]->owner))
04178 bridge = ast_bridged_channel(owner);
04179
04180
04181
04182 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04183 jb_frame frame;
04184
04185 ast_channel_unlock(owner);
04186
04187
04188 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04189 __do_deliver(frame.data);
04190
04191 if (!iaxs[fr->callno])
04192 return -1;
04193 }
04194
04195 jb_reset(iaxs[fr->callno]->jb);
04196
04197 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04198
04199
04200 if (tsout)
04201 *tsout = fr->ts;
04202 __do_deliver(fr);
04203 return -1;
04204 }
04205 if (owner) {
04206 ast_channel_unlock(owner);
04207 }
04208
04209
04210
04211 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04212 calc_rxstamp(iaxs[fr->callno],fr->ts));
04213 if (ret == JB_DROP) {
04214 needfree++;
04215 } else if (ret == JB_SCHED) {
04216 update_jbsched(iaxs[fr->callno]);
04217 }
04218 if (tsout)
04219 *tsout = fr->ts;
04220 if (needfree) {
04221
04222 iax2_frame_free(fr);
04223 return -1;
04224 }
04225 return 0;
04226 }
04227
04228 static int transmit_frame(void *data)
04229 {
04230 struct iax_frame *fr = data;
04231
04232 ast_mutex_lock(&iaxsl[fr->callno]);
04233
04234 fr->sentyet = 1;
04235
04236 if (iaxs[fr->callno]) {
04237 send_packet(fr);
04238 }
04239
04240 if (fr->retries < 0) {
04241 ast_mutex_unlock(&iaxsl[fr->callno]);
04242
04243 iax_frame_free(fr);
04244 } else {
04245
04246 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04247 fr->retries++;
04248 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04249 ast_mutex_unlock(&iaxsl[fr->callno]);
04250 }
04251
04252 return 0;
04253 }
04254
04255 static int iax2_transmit(struct iax_frame *fr)
04256 {
04257 fr->sentyet = 0;
04258
04259 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04260 }
04261
04262 static int iax2_digit_begin(struct ast_channel *c, char digit)
04263 {
04264 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04265 }
04266
04267 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04268 {
04269 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04270 }
04271
04272 static int iax2_sendtext(struct ast_channel *c, const char *text)
04273 {
04274
04275 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04276 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04277 }
04278
04279 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04280 {
04281 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04282 }
04283
04284 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04285 {
04286 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04287 }
04288
04289 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04290 {
04291 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04292 ast_mutex_lock(&iaxsl[callno]);
04293 if (iaxs[callno])
04294 iaxs[callno]->owner = newchan;
04295 else
04296 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04297 ast_mutex_unlock(&iaxsl[callno]);
04298 return 0;
04299 }
04300
04301
04302
04303
04304
04305 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04306 {
04307 struct ast_variable *var = NULL;
04308 struct ast_variable *tmp;
04309 struct iax2_peer *peer=NULL;
04310 time_t regseconds = 0, nowtime;
04311 int dynamic=0;
04312
04313 if (peername) {
04314 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04315 if (!var && sin)
04316 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04317 } else if (sin) {
04318 char porta[25];
04319 sprintf(porta, "%d", ntohs(sin->sin_port));
04320 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04321 if (var) {
04322
04323 for (tmp = var; tmp; tmp = tmp->next) {
04324 if (!strcasecmp(tmp->name, "name"))
04325 peername = tmp->value;
04326 }
04327 }
04328 }
04329 if (!var && peername) {
04330 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04331
04332
04333
04334
04335
04336
04337 if (var && sin) {
04338 for (tmp = var; tmp; tmp = tmp->next) {
04339 if (!strcasecmp(tmp->name, "host")) {
04340 struct ast_hostent ahp;
04341 struct hostent *hp;
04342 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04343
04344 ast_variables_destroy(var);
04345 var = NULL;
04346 }
04347 break;
04348 }
04349 }
04350 }
04351 }
04352 if (!var)
04353 return NULL;
04354
04355 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04356
04357 if (!peer) {
04358 ast_variables_destroy(var);
04359 return NULL;
04360 }
04361
04362 for (tmp = var; tmp; tmp = tmp->next) {
04363
04364 if (!strcasecmp(tmp->name, "type")) {
04365 if (strcasecmp(tmp->value, "friend") &&
04366 strcasecmp(tmp->value, "peer")) {
04367
04368 peer = peer_unref(peer);
04369 break;
04370 }
04371 } else if (!strcasecmp(tmp->name, "regseconds")) {
04372 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04373 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04374 ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE);
04375 } else if (!strcasecmp(tmp->name, "port")) {
04376 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04377 } else if (!strcasecmp(tmp->name, "host")) {
04378 if (!strcasecmp(tmp->value, "dynamic"))
04379 dynamic = 1;
04380 }
04381 }
04382
04383 ast_variables_destroy(var);
04384
04385 if (!peer)
04386 return NULL;
04387
04388 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04389 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04390 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04391 if (peer->expire > -1) {
04392 if (!ast_sched_thread_del(sched, peer->expire)) {
04393 peer->expire = -1;
04394 peer_unref(peer);
04395 }
04396 }
04397 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04398 if (peer->expire == -1)
04399 peer_unref(peer);
04400 }
04401 ao2_link(peers, peer);
04402 if (ast_test_flag64(peer, IAX_DYNAMIC))
04403 reg_source_db(peer);
04404 } else {
04405 ast_set_flag64(peer, IAX_TEMPONLY);
04406 }
04407
04408 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04409 time(&nowtime);
04410 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04411 memset(&peer->addr, 0, sizeof(peer->addr));
04412 realtime_update_peer(peer->name, &peer->addr, 0);
04413 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04414 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04415 }
04416 else {
04417 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04418 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04419 }
04420 }
04421
04422 return peer;
04423 }
04424
04425 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04426 {
04427 struct ast_variable *var;
04428 struct ast_variable *tmp;
04429 struct iax2_user *user=NULL;
04430
04431 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04432 if (!var)
04433 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04434 if (!var && sin) {
04435 char porta[6];
04436 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04437 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04438 if (!var)
04439 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04440 }
04441 if (!var) {
04442 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04443
04444
04445
04446
04447
04448
04449 if (var) {
04450 for (tmp = var; tmp; tmp = tmp->next) {
04451 if (!strcasecmp(tmp->name, "host")) {
04452 struct ast_hostent ahp;
04453 struct hostent *hp;
04454 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04455
04456 ast_variables_destroy(var);
04457 var = NULL;
04458 }
04459 break;
04460 }
04461 }
04462 }
04463 }
04464 if (!var)
04465 return NULL;
04466
04467 tmp = var;
04468 while(tmp) {
04469
04470 if (!strcasecmp(tmp->name, "type")) {
04471 if (strcasecmp(tmp->value, "friend") &&
04472 strcasecmp(tmp->value, "user")) {
04473 return NULL;
04474 }
04475 }
04476 tmp = tmp->next;
04477 }
04478
04479 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04480
04481 ast_variables_destroy(var);
04482
04483 if (!user)
04484 return NULL;
04485
04486 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04487 ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04488 ao2_link(users, user);
04489 } else {
04490 ast_set_flag64(user, IAX_TEMPONLY);
04491 }
04492
04493 return user;
04494 }
04495
04496 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
04497 {
04498 char port[10];
04499 char regseconds[20];
04500 const char *sysname = ast_config_AST_SYSTEM_NAME;
04501 char *syslabel = NULL;
04502
04503 if (ast_strlen_zero(sysname))
04504 sysname = NULL;
04505 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04506 syslabel = "regserver";
04507
04508 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04509 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04510 ast_update_realtime("iaxpeers", "name", peername,
04511 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port,
04512 "regseconds", regseconds, syslabel, sysname, SENTINEL);
04513 }
04514
04515 struct create_addr_info {
04516 format_t capability;
04517 uint64_t flags;
04518 int maxtime;
04519 int encmethods;
04520 int found;
04521 int sockfd;
04522 int adsi;
04523 char username[80];
04524 char secret[80];
04525 char outkey[80];
04526 char timezone[80];
04527 char prefs[32];
04528 char cid_num[80];
04529 char cid_name[80];
04530 char context[AST_MAX_CONTEXT];
04531 char peercontext[AST_MAX_CONTEXT];
04532 char mohinterpret[MAX_MUSICCLASS];
04533 char mohsuggest[MAX_MUSICCLASS];
04534 };
04535
04536 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04537 {
04538 struct iax2_peer *peer;
04539 int res = -1;
04540 struct ast_codec_pref ourprefs;
04541 struct sockaddr_in peer_addr;
04542
04543 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04544 cai->sockfd = defaultsockfd;
04545 cai->maxtime = 0;
04546 sin->sin_family = AF_INET;
04547
04548 if (!(peer = find_peer(peername, 1))) {
04549 struct ast_sockaddr sin_tmp;
04550
04551 cai->found = 0;
04552 sin_tmp.ss.ss_family = AF_INET;
04553 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04554 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04555 return -1;
04556 }
04557 ast_sockaddr_to_sin(&sin_tmp, sin);
04558 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04559
04560
04561 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04562 if (c)
04563 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04564 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04565 return 0;
04566 }
04567
04568 cai->found = 1;
04569
04570 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04571
04572
04573 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04574 goto return_unref;
04575 }
04576
04577
04578 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04579 goto return_unref;
04580
04581 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04582 cai->maxtime = peer->maxms;
04583 cai->capability = peer->capability;
04584 cai->encmethods = peer->encmethods;
04585 cai->sockfd = peer->sockfd;
04586 cai->adsi = peer->adsi;
04587 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04588
04589 if (c) {
04590 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04591 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04592 }
04593 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04594 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04595 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04596 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04597 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04598 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04599 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04600 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04601 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04602 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04603 if (ast_strlen_zero(peer->dbsecret)) {
04604 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04605 } else {
04606 char *family;
04607 char *key = NULL;
04608
04609 family = ast_strdupa(peer->dbsecret);
04610 key = strchr(family, '/');
04611 if (key)
04612 *key++ = '\0';
04613 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04614 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04615 goto return_unref;
04616 }
04617 }
04618
04619 if (peer_addr.sin_addr.s_addr) {
04620 sin->sin_addr = peer_addr.sin_addr;
04621 sin->sin_port = peer_addr.sin_port;
04622 } else {
04623 sin->sin_addr = peer->defaddr.sin_addr;
04624 sin->sin_port = peer->defaddr.sin_port;
04625 }
04626
04627 res = 0;
04628
04629 return_unref:
04630 peer_unref(peer);
04631
04632 return res;
04633 }
04634
04635 static void __auto_congest(const void *nothing)
04636 {
04637 int callno = PTR_TO_CALLNO(nothing);
04638 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04639 ast_mutex_lock(&iaxsl[callno]);
04640 if (iaxs[callno]) {
04641 iaxs[callno]->initid = -1;
04642 iax2_queue_frame(callno, &f);
04643 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04644 }
04645 ast_mutex_unlock(&iaxsl[callno]);
04646 }
04647
04648 static int auto_congest(const void *data)
04649 {
04650 #ifdef SCHED_MULTITHREADED
04651 if (schedule_action(__auto_congest, data))
04652 #endif
04653 __auto_congest(data);
04654 return 0;
04655 }
04656
04657 static unsigned int iax2_datetime(const char *tz)
04658 {
04659 struct timeval t = ast_tvnow();
04660 struct ast_tm tm;
04661 unsigned int tmp;
04662 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04663 tmp = (tm.tm_sec >> 1) & 0x1f;
04664 tmp |= (tm.tm_min & 0x3f) << 5;
04665 tmp |= (tm.tm_hour & 0x1f) << 11;
04666 tmp |= (tm.tm_mday & 0x1f) << 16;
04667 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04668 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04669 return tmp;
04670 }
04671
04672 struct parsed_dial_string {
04673 char *username;
04674 char *password;
04675 char *key;
04676 char *peer;
04677 char *port;
04678 char *exten;
04679 char *context;
04680 char *options;
04681 };
04682
04683 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04684 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04685 int sockfd, struct iax_ie_data *ied)
04686 {
04687 struct {
04688 struct ast_iax2_full_hdr f;
04689 struct iax_ie_data ied;
04690 } data;
04691 size_t size = sizeof(struct ast_iax2_full_hdr);
04692
04693 if (ied) {
04694 size += ied->pos;
04695 memcpy(&data.ied, ied->buf, ied->pos);
04696 }
04697
04698 data.f.scallno = htons(0x8000 | callno);
04699 data.f.dcallno = htons(dcallno);
04700 data.f.ts = htonl(ts);
04701 data.f.iseqno = seqno;
04702 data.f.oseqno = 0;
04703 data.f.type = AST_FRAME_IAX;
04704 data.f.csub = compress_subclass(command);
04705
04706 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04707 }
04708
04709 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04710 {
04711
04712 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04713 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04714 ied->buf[ied->pos++] = 0;
04715 pvt->calltoken_ie_len = 2;
04716 }
04717 }
04718
04719 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04720 {
04721 struct chan_iax2_pvt *pvt = iaxs[callno];
04722 int frametype = f->af.frametype;
04723 int subclass = f->af.subclass.integer;
04724 struct {
04725 struct ast_iax2_full_hdr fh;
04726 struct iax_ie_data ied;
04727 } data = {
04728 .ied.buf = { 0 },
04729 .ied.pos = 0,
04730 };
04731
04732 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04733
04734 if (!pvt) {
04735 return;
04736 }
04737
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04750 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04751 (f->datalen > sizeof(data))) {
04752
04753 return;
04754 }
04755
04756
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770 memcpy(&data, f->data, f->datalen);
04771 data.ied.pos = ie_data_pos;
04772
04773
04774
04775 data.ied.pos -= pvt->calltoken_ie_len;
04776 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04777
04778
04779 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04780
04781
04782 AST_LIST_REMOVE(&frame_queue[callno], f, list);
04783
04784
04785 iax2_frame_free(f);
04786
04787
04788 pvt->oseqno = 0;
04789 pvt->rseqno = 0;
04790 pvt->iseqno = 0;
04791 pvt->aseqno = 0;
04792 if (pvt->peercallno) {
04793 remove_by_peercallno(pvt);
04794 pvt->peercallno = 0;
04795 }
04796
04797
04798 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04799 }
04800
04801 static void requirecalltoken_mark_auto(const char *name, int subclass)
04802 {
04803 struct iax2_user *user = NULL;
04804 struct iax2_peer *peer = NULL;
04805
04806 if (ast_strlen_zero(name)) {
04807 return;
04808 }
04809
04810 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04811 user->calltoken_required = CALLTOKEN_YES;
04812 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04813 peer->calltoken_required = CALLTOKEN_YES;
04814 }
04815
04816 if (peer) {
04817 peer_unref(peer);
04818 }
04819 if (user) {
04820 user_unref(user);
04821 }
04822 }
04823
04824
04825
04826
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04842 struct sockaddr_in *sin, int fd)
04843 {
04844 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04845 #define CALLTOKEN_IE_FORMAT "%u?%s"
04846 struct ast_str *buf = ast_str_alloca(256);
04847 time_t t = time(NULL);
04848 char hash[41];
04849 int subclass = uncompress_subclass(fh->csub);
04850
04851
04852 if (ies->calltoken && !ies->calltokendata) {
04853 struct iax_ie_data ied = {
04854 .buf = { 0 },
04855 .pos = 0,
04856 };
04857
04858
04859 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04860 ast_sha1_hash(hash, ast_str_buffer(buf));
04861
04862 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04863 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04864 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04865
04866 return 1;
04867
04868
04869 } else if (ies->calltoken && ies->calltokendata) {
04870 char *rec_hash = NULL;
04871 char *rec_ts = NULL;
04872 unsigned int rec_time;
04873
04874
04875 rec_hash = strchr((char *) ies->calltokendata, '?');
04876 if (rec_hash) {
04877 *rec_hash++ = '\0';
04878 rec_ts = (char *) ies->calltokendata;
04879 }
04880
04881
04882 if (!rec_hash || !rec_ts) {
04883 goto reject;
04884 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04885 goto reject;
04886 }
04887
04888
04889 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04890 ast_sha1_hash(hash, ast_str_buffer(buf));
04891
04892
04893 if (strcmp(hash, rec_hash)) {
04894 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04895 goto reject;
04896 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04897 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04898 goto reject;
04899 }
04900
04901
04902
04903 requirecalltoken_mark_auto(ies->username, subclass);
04904 return 0;
04905
04906
04907 } else {
04908 if (calltoken_required(sin, ies->username, subclass)) {
04909 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"));
04910 goto reject;
04911 }
04912 return 0;
04913 }
04914
04915 reject:
04916
04917 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04918 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04919 } else {
04920 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04921 }
04922
04923 return 1;
04924 }
04925
04926
04927
04928
04929
04930
04931
04932
04933
04934
04935
04936
04937
04938
04939
04940
04941
04942
04943
04944 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04945 {
04946 if (ast_strlen_zero(data))
04947 return;
04948
04949 pds->peer = strsep(&data, "/");
04950 pds->exten = strsep(&data, "/");
04951 pds->options = data;
04952
04953 if (pds->exten) {
04954 data = pds->exten;
04955 pds->exten = strsep(&data, "@");
04956 pds->context = data;
04957 }
04958
04959 if (strchr(pds->peer, '@')) {
04960 data = pds->peer;
04961 pds->username = strsep(&data, "@");
04962 pds->peer = data;
04963 }
04964
04965 if (pds->username) {
04966 data = pds->username;
04967 pds->username = strsep(&data, ":");
04968 pds->password = data;
04969 }
04970
04971 data = pds->peer;
04972 pds->peer = strsep(&data, ":");
04973 pds->port = data;
04974
04975
04976
04977
04978 if (pds->password && (pds->password[0] == '[')) {
04979 pds->key = ast_strip_quoted(pds->password, "[", "]");
04980 pds->password = NULL;
04981 }
04982 }
04983
04984 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04985 {
04986 struct sockaddr_in sin;
04987 char *l=NULL, *n=NULL, *tmpstr;
04988 struct iax_ie_data ied;
04989 char *defaultrdest = "s";
04990 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04991 struct parsed_dial_string pds;
04992 struct create_addr_info cai;
04993 struct ast_var_t *var;
04994 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04995 const char* osp_token_ptr;
04996 unsigned int osp_token_length;
04997 unsigned char osp_block_index;
04998 unsigned int osp_block_length;
04999 unsigned char osp_buffer[256];
05000
05001 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
05002 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
05003 return -1;
05004 }
05005
05006 memset(&cai, 0, sizeof(cai));
05007 cai.encmethods = iax2_encryption;
05008
05009 memset(&pds, 0, sizeof(pds));
05010 tmpstr = ast_strdupa(dest);
05011 parse_dial_string(tmpstr, &pds);
05012
05013 if (ast_strlen_zero(pds.peer)) {
05014 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
05015 return -1;
05016 }
05017 if (!pds.exten) {
05018 pds.exten = defaultrdest;
05019 }
05020 if (create_addr(pds.peer, c, &sin, &cai)) {
05021 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
05022 return -1;
05023 }
05024 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
05025 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
05026 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05027 return -1;
05028 }
05029 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
05030 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
05031 return -1;
05032 }
05033 if (!pds.username && !ast_strlen_zero(cai.username))
05034 pds.username = cai.username;
05035 if (!pds.password && !ast_strlen_zero(cai.secret))
05036 pds.password = cai.secret;
05037 if (!pds.key && !ast_strlen_zero(cai.outkey))
05038 pds.key = cai.outkey;
05039 if (!pds.context && !ast_strlen_zero(cai.peercontext))
05040 pds.context = cai.peercontext;
05041
05042
05043 ast_copy_string(c->context, cai.context, sizeof(c->context));
05044
05045 if (pds.port)
05046 sin.sin_port = htons(atoi(pds.port));
05047
05048 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
05049 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
05050
05051
05052 memset(&ied, 0, sizeof(ied));
05053
05054
05055 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
05056 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
05057 if (pds.options && strchr(pds.options, 'a')) {
05058
05059 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
05060 }
05061
05062
05063 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
05064
05065 if (l) {
05066 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
05067 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05068 ast_party_id_presentation(&c->connected.id));
05069 } else if (n) {
05070 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05071 ast_party_id_presentation(&c->connected.id));
05072 } else {
05073 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
05074 }
05075
05076 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
05077 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
05078
05079 if (n)
05080 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
05081 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
05082 && c->connected.ani.number.valid
05083 && c->connected.ani.number.str) {
05084 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str);
05085 }
05086
05087 if (!ast_strlen_zero(c->language))
05088 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
05089 if (!ast_strlen_zero(c->dialed.number.str)) {
05090 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
05091 }
05092 if (c->redirecting.from.number.valid
05093 && !ast_strlen_zero(c->redirecting.from.number.str)) {
05094 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
05095 }
05096
05097 if (pds.context)
05098 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
05099
05100 if (pds.username)
05101 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
05102
05103 if (cai.encmethods)
05104 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
05105
05106 ast_mutex_lock(&iaxsl[callno]);
05107
05108 if (!ast_strlen_zero(c->context))
05109 ast_string_field_set(iaxs[callno], context, c->context);
05110
05111 if (pds.username)
05112 ast_string_field_set(iaxs[callno], username, pds.username);
05113
05114 iaxs[callno]->encmethods = cai.encmethods;
05115
05116 iaxs[callno]->adsi = cai.adsi;
05117
05118 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
05119 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
05120
05121 if (pds.key)
05122 ast_string_field_set(iaxs[callno], outkey, pds.key);
05123 if (pds.password)
05124 ast_string_field_set(iaxs[callno], secret, pds.password);
05125
05126 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
05127 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
05128 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
05129 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
05130 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
05131 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
05132
05133 if (iaxs[callno]->maxtime) {
05134
05135 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
05136 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
05137 } else if (autokill) {
05138 iaxs[callno]->pingtime = autokill / 2;
05139 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
05140 }
05141
05142
05143 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
05144 if (!ast_strlen_zero(osp_token_ptr)) {
05145 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
05146 osp_block_index = 0;
05147 while (osp_token_length > 0) {
05148 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
05149 osp_buffer[0] = osp_block_index;
05150 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
05151 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
05152 osp_block_index++;
05153 osp_token_ptr += osp_block_length;
05154 osp_token_length -= osp_block_length;
05155 }
05156 } else
05157 ast_log(LOG_WARNING, "OSP token is too long\n");
05158 } else if (iaxdebug)
05159 ast_debug(1, "OSP token is undefined\n");
05160
05161
05162 iaxs[callno]->sockfd = cai.sockfd;
05163
05164
05165 if (variablestore) {
05166 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
05167 ast_debug(1, "Found an IAX variable store on this channel\n");
05168 AST_LIST_LOCK(variablelist);
05169 AST_LIST_TRAVERSE(variablelist, var, entries) {
05170 char tmp[256];
05171 int i;
05172 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
05173
05174 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
05175 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
05176 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
05177 }
05178 }
05179 AST_LIST_UNLOCK(variablelist);
05180 }
05181
05182
05183 add_empty_calltoken_ie(iaxs[callno], &ied);
05184 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
05185
05186 ast_mutex_unlock(&iaxsl[callno]);
05187 ast_setstate(c, AST_STATE_RINGING);
05188
05189 return 0;
05190 }
05191
05192 static int iax2_hangup(struct ast_channel *c)
05193 {
05194 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05195 struct iax_ie_data ied;
05196 int alreadygone;
05197 memset(&ied, 0, sizeof(ied));
05198 ast_mutex_lock(&iaxsl[callno]);
05199 if (callno && iaxs[callno]) {
05200 ast_debug(1, "We're hanging up %s now...\n", c->name);
05201 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05202
05203 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05204 if (!iaxs[callno]->error && !alreadygone) {
05205 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05206 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05207 }
05208 if (!iaxs[callno]) {
05209 ast_mutex_unlock(&iaxsl[callno]);
05210 return 0;
05211 }
05212 }
05213
05214 iax2_predestroy(callno);
05215
05216 if (iaxs[callno] && alreadygone) {
05217 ast_debug(1, "Really destroying %s now...\n", c->name);
05218 iax2_destroy(callno);
05219 } else if (iaxs[callno]) {
05220 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05221 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05222 iax2_destroy(callno);
05223 }
05224 }
05225 } else if (c->tech_pvt) {
05226
05227
05228
05229
05230 c->tech_pvt = NULL;
05231 }
05232 ast_mutex_unlock(&iaxsl[callno]);
05233 ast_verb(3, "Hungup '%s'\n", c->name);
05234 return 0;
05235 }
05236
05237
05238
05239
05240 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05241 {
05242 unsigned short callno = pvt->callno;
05243
05244 if (!pvt->peercallno) {
05245
05246 int count = 10;
05247 while (count-- && pvt && !pvt->peercallno) {
05248 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05249 pvt = iaxs[callno];
05250 }
05251 if (!pvt->peercallno) {
05252 return -1;
05253 }
05254 }
05255
05256 return 0;
05257 }
05258
05259 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05260 {
05261 struct ast_option_header *h;
05262 int res;
05263
05264 switch (option) {
05265 case AST_OPTION_TXGAIN:
05266 case AST_OPTION_RXGAIN:
05267
05268 errno = ENOSYS;
05269 return -1;
05270 case AST_OPTION_FORMAT_READ:
05271 case AST_OPTION_FORMAT_WRITE:
05272 case AST_OPTION_MAKE_COMPATIBLE:
05273 return -1;
05274 case AST_OPTION_OPRMODE:
05275 errno = EINVAL;
05276 return -1;
05277 case AST_OPTION_SECURE_SIGNALING:
05278 case AST_OPTION_SECURE_MEDIA:
05279 {
05280 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05281 ast_mutex_lock(&iaxsl[callno]);
05282 if ((*(int *) data)) {
05283 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05284 } else {
05285 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05286 }
05287 ast_mutex_unlock(&iaxsl[callno]);
05288 return 0;
05289 }
05290 default:
05291 {
05292 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05293 struct chan_iax2_pvt *pvt;
05294
05295 ast_mutex_lock(&iaxsl[callno]);
05296 pvt = iaxs[callno];
05297
05298 if (wait_for_peercallno(pvt)) {
05299 ast_mutex_unlock(&iaxsl[callno]);
05300 return -1;
05301 }
05302
05303 ast_mutex_unlock(&iaxsl[callno]);
05304
05305 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05306 return -1;
05307 }
05308
05309 h->flag = AST_OPTION_FLAG_REQUEST;
05310 h->option = htons(option);
05311 memcpy(h->data, data, datalen);
05312 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05313 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05314 datalen + sizeof(*h), -1);
05315 ast_free(h);
05316 return res;
05317 }
05318 }
05319 }
05320
05321 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
05322 {
05323 switch (option) {
05324 case AST_OPTION_SECURE_SIGNALING:
05325 case AST_OPTION_SECURE_MEDIA:
05326 {
05327 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05328 ast_mutex_lock(&iaxsl[callno]);
05329 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05330 ast_mutex_unlock(&iaxsl[callno]);
05331 return 0;
05332 }
05333 default:
05334 return -1;
05335 }
05336 }
05337
05338 static struct ast_frame *iax2_read(struct ast_channel *c)
05339 {
05340 ast_log(LOG_NOTICE, "I should never be called!\n");
05341 return &ast_null_frame;
05342 }
05343
05344 static int iax2_key_rotate(const void *vpvt)
05345 {
05346 int res = 0;
05347 struct chan_iax2_pvt *pvt = (void *) vpvt;
05348 struct MD5Context md5;
05349 char key[17] = "";
05350 struct iax_ie_data ied = {
05351 .pos = 0,
05352 };
05353
05354 ast_mutex_lock(&iaxsl[pvt->callno]);
05355 pvt->keyrotateid =
05356 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05357
05358 snprintf(key, sizeof(key), "%lX", ast_random());
05359
05360 MD5Init(&md5);
05361 MD5Update(&md5, (unsigned char *) key, strlen(key));
05362 MD5Final((unsigned char *) key, &md5);
05363
05364 IAX_DEBUGDIGEST("Sending", key);
05365
05366 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05367
05368 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05369
05370 build_ecx_key((unsigned char *) key, pvt);
05371
05372 ast_mutex_unlock(&iaxsl[pvt->callno]);
05373
05374 return res;
05375 }
05376
05377 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05378 {
05379 int res;
05380 struct iax_ie_data ied0;
05381 struct iax_ie_data ied1;
05382 unsigned int transferid = (unsigned int)ast_random();
05383
05384 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05385 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05386 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05387 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05388 return 0;
05389 }
05390
05391 memset(&ied0, 0, sizeof(ied0));
05392 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05393 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05394 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05395
05396 memset(&ied1, 0, sizeof(ied1));
05397 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05398 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05399 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05400
05401 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05402 if (res)
05403 return -1;
05404 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05405 if (res)
05406 return -1;
05407 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05408 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05409 return 0;
05410 }
05411
05412 static void lock_both(unsigned short callno0, unsigned short callno1)
05413 {
05414 ast_mutex_lock(&iaxsl[callno0]);
05415 while (ast_mutex_trylock(&iaxsl[callno1])) {
05416 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05417 }
05418 }
05419
05420 static void unlock_both(unsigned short callno0, unsigned short callno1)
05421 {
05422 ast_mutex_unlock(&iaxsl[callno1]);
05423 ast_mutex_unlock(&iaxsl[callno0]);
05424 }
05425
05426 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)
05427 {
05428 struct ast_channel *cs[3];
05429 struct ast_channel *who, *other;
05430 int to = -1;
05431 int res = -1;
05432 int transferstarted=0;
05433 struct ast_frame *f;
05434 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05435 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05436 struct timeval waittimer = {0, 0};
05437
05438
05439 if (timeoutms > 0) {
05440 return AST_BRIDGE_FAILED;
05441 }
05442
05443 timeoutms = -1;
05444
05445 lock_both(callno0, callno1);
05446 if (!iaxs[callno0] || !iaxs[callno1]) {
05447 unlock_both(callno0, callno1);
05448 return AST_BRIDGE_FAILED;
05449 }
05450
05451 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05452 iaxs[callno0]->bridgecallno = callno1;
05453 iaxs[callno1]->bridgecallno = callno0;
05454 }
05455 unlock_both(callno0, callno1);
05456
05457
05458 cs[0] = c0;
05459 cs[1] = c1;
05460 for (;;) {
05461
05462 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05463 ast_verb(3, "Can't masquerade, we're different...\n");
05464
05465 if (c0->tech == &iax2_tech) {
05466 ast_mutex_lock(&iaxsl[callno0]);
05467 iaxs[callno0]->bridgecallno = 0;
05468 ast_mutex_unlock(&iaxsl[callno0]);
05469 }
05470 if (c1->tech == &iax2_tech) {
05471 ast_mutex_lock(&iaxsl[callno1]);
05472 iaxs[callno1]->bridgecallno = 0;
05473 ast_mutex_unlock(&iaxsl[callno1]);
05474 }
05475 return AST_BRIDGE_FAILED_NOWARN;
05476 }
05477 if (c0->nativeformats != c1->nativeformats) {
05478 char buf0[256];
05479 char buf1[256];
05480 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05481 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05482 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05483
05484 lock_both(callno0, callno1);
05485 if (iaxs[callno0])
05486 iaxs[callno0]->bridgecallno = 0;
05487 if (iaxs[callno1])
05488 iaxs[callno1]->bridgecallno = 0;
05489 unlock_both(callno0, callno1);
05490 return AST_BRIDGE_FAILED_NOWARN;
05491 }
05492
05493 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05494
05495 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05496 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05497 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05498 transferstarted = 1;
05499 }
05500 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05501
05502 struct timeval now = ast_tvnow();
05503 if (ast_tvzero(waittimer)) {
05504 waittimer = now;
05505 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05506 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05507 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05508 *fo = NULL;
05509 *rc = c0;
05510 res = AST_BRIDGE_COMPLETE;
05511 break;
05512 }
05513 }
05514 to = 1000;
05515 who = ast_waitfor_n(cs, 2, &to);
05516 if (timeoutms > -1) {
05517 timeoutms -= (1000 - to);
05518 if (timeoutms < 0)
05519 timeoutms = 0;
05520 }
05521 if (!who) {
05522 if (!timeoutms) {
05523 res = AST_BRIDGE_RETRY;
05524 break;
05525 }
05526 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05527 res = AST_BRIDGE_FAILED;
05528 break;
05529 }
05530 continue;
05531 }
05532 f = ast_read(who);
05533 if (!f) {
05534 *fo = NULL;
05535 *rc = who;
05536 res = AST_BRIDGE_COMPLETE;
05537 break;
05538 }
05539 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
05540 *fo = f;
05541 *rc = who;
05542 res = AST_BRIDGE_COMPLETE;
05543 break;
05544 }
05545 other = (who == c0) ? c1 : c0;
05546 if ((f->frametype == AST_FRAME_VOICE) ||
05547 (f->frametype == AST_FRAME_TEXT) ||
05548 (f->frametype == AST_FRAME_VIDEO) ||
05549 (f->frametype == AST_FRAME_IMAGE) ||
05550 (f->frametype == AST_FRAME_DTMF) ||
05551 (f->frametype == AST_FRAME_CONTROL)) {
05552
05553
05554
05555 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05556 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05557 *rc = who;
05558 *fo = f;
05559 res = AST_BRIDGE_COMPLETE;
05560
05561 break;
05562 }
05563
05564 ast_write(other, f);
05565 }
05566 ast_frfree(f);
05567
05568 cs[2] = cs[0];
05569 cs[0] = cs[1];
05570 cs[1] = cs[2];
05571 }
05572 lock_both(callno0, callno1);
05573 if(iaxs[callno0])
05574 iaxs[callno0]->bridgecallno = 0;
05575 if(iaxs[callno1])
05576 iaxs[callno1]->bridgecallno = 0;
05577 unlock_both(callno0, callno1);
05578 return res;
05579 }
05580
05581 static int iax2_answer(struct ast_channel *c)
05582 {
05583 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05584 ast_debug(1, "Answering IAX2 call\n");
05585 ast_mutex_lock(&iaxsl[callno]);
05586 if (iaxs[callno])
05587 iax2_ami_channelupdate(iaxs[callno]);
05588 ast_mutex_unlock(&iaxsl[callno]);
05589 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05590 }
05591
05592 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05593 {
05594 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05595 struct chan_iax2_pvt *pvt;
05596 int res = 0;
05597
05598 if (iaxdebug)
05599 ast_debug(1, "Indicating condition %d\n", condition);
05600
05601 ast_mutex_lock(&iaxsl[callno]);
05602 pvt = iaxs[callno];
05603
05604 if (wait_for_peercallno(pvt)) {
05605 res = -1;
05606 goto done;
05607 }
05608
05609 switch (condition) {
05610 case AST_CONTROL_HOLD:
05611 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05612 ast_moh_start(c, data, pvt->mohinterpret);
05613 goto done;
05614 }
05615 break;
05616 case AST_CONTROL_UNHOLD:
05617 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05618 ast_moh_stop(c);
05619 goto done;
05620 }
05621 break;
05622 case AST_CONTROL_CONNECTED_LINE:
05623 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05624 goto done;
05625 break;
05626 }
05627
05628 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05629
05630 done:
05631 ast_mutex_unlock(&iaxsl[callno]);
05632
05633 return res;
05634 }
05635
05636 static int iax2_transfer(struct ast_channel *c, const char *dest)
05637 {
05638 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05639 struct iax_ie_data ied = { "", };
05640 char tmp[256], *context;
05641 enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05642 ast_copy_string(tmp, dest, sizeof(tmp));
05643 context = strchr(tmp, '@');
05644 if (context) {
05645 *context = '\0';
05646 context++;
05647 }
05648 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05649 if (context)
05650 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05651 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05652 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05653 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05654 }
05655
05656 static int iax2_getpeertrunk(struct sockaddr_in sin)
05657 {
05658 struct iax2_peer *peer;
05659 int res = 0;
05660 struct ao2_iterator i;
05661
05662 i = ao2_iterator_init(peers, 0);
05663 while ((peer = ao2_iterator_next(&i))) {
05664 struct sockaddr_in peer_addr;
05665
05666 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05667
05668 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05669 (peer_addr.sin_port == sin.sin_port)) {
05670 res = ast_test_flag64(peer, IAX_TRUNK);
05671 peer_unref(peer);
05672 break;
05673 }
05674 peer_unref(peer);
05675 }
05676 ao2_iterator_destroy(&i);
05677
05678 return res;
05679 }
05680
05681
05682 static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
05683 {
05684 struct ast_channel *tmp;
05685 struct chan_iax2_pvt *i;
05686 struct ast_variable *v = NULL;
05687
05688 if (!(i = iaxs[callno])) {
05689 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05690 return NULL;
05691 }
05692
05693
05694 ast_mutex_unlock(&iaxsl[callno]);
05695 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);
05696 ast_mutex_lock(&iaxsl[callno]);
05697 if (i != iaxs[callno]) {
05698 if (tmp) {
05699
05700 ast_mutex_unlock(&iaxsl[callno]);
05701 tmp = ast_channel_release(tmp);
05702 ast_mutex_lock(&iaxsl[callno]);
05703 }
05704 return NULL;
05705 }
05706 iax2_ami_channelupdate(i);
05707 if (!tmp)
05708 return NULL;
05709 tmp->tech = &iax2_tech;
05710
05711 tmp->nativeformats = capability;
05712 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05713 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05714 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05715
05716 if (!ast_strlen_zero(i->parkinglot))
05717 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05718
05719
05720 if (!ast_strlen_zero(i->ani)) {
05721 tmp->caller.ani.number.valid = 1;
05722 tmp->caller.ani.number.str = ast_strdup(i->ani);
05723 } else if (!ast_strlen_zero(i->cid_num)) {
05724 tmp->caller.ani.number.valid = 1;
05725 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05726 }
05727 tmp->dialed.number.str = ast_strdup(i->dnid);
05728 tmp->redirecting.from.number.valid = 1;
05729 tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05730 tmp->caller.id.name.presentation = i->calling_pres;
05731 tmp->caller.id.number.presentation = i->calling_pres;
05732 tmp->caller.id.number.plan = i->calling_ton;
05733 tmp->dialed.transit_network_select = i->calling_tns;
05734 if (!ast_strlen_zero(i->language))
05735 ast_string_field_set(tmp, language, i->language);
05736 if (!ast_strlen_zero(i->accountcode))
05737 ast_string_field_set(tmp, accountcode, i->accountcode);
05738 if (i->amaflags)
05739 tmp->amaflags = i->amaflags;
05740 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05741 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05742 if (i->adsi)
05743 tmp->adsicpe = i->peeradsicpe;
05744 else
05745 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05746 i->owner = tmp;
05747 i->capability = capability;
05748
05749
05750 if (i->vars) {
05751 for (v = i->vars ; v ; v = v->next)
05752 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05753 }
05754 if (i->iaxvars) {
05755 struct ast_datastore *variablestore;
05756 struct ast_variable *var, *prev = NULL;
05757 AST_LIST_HEAD(, ast_var_t) *varlist;
05758 ast_debug(1, "Loading up the channel with IAXVARs\n");
05759 varlist = ast_calloc(1, sizeof(*varlist));
05760 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05761 if (variablestore && varlist) {
05762 variablestore->data = varlist;
05763 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05764 AST_LIST_HEAD_INIT(varlist);
05765 for (var = i->iaxvars; var; var = var->next) {
05766 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05767 if (prev)
05768 ast_free(prev);
05769 prev = var;
05770 if (!newvar) {
05771
05772 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05773 } else {
05774 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05775 }
05776 }
05777 if (prev)
05778 ast_free(prev);
05779 i->iaxvars = NULL;
05780 ast_channel_datastore_add(i->owner, variablestore);
05781 } else {
05782 if (variablestore) {
05783 ast_datastore_free(variablestore);
05784 }
05785 if (varlist) {
05786 ast_free(varlist);
05787 }
05788 }
05789 }
05790
05791 if (state != AST_STATE_DOWN) {
05792 if (ast_pbx_start(tmp)) {
05793 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05794 ast_hangup(tmp);
05795 i->owner = NULL;
05796 return NULL;
05797 }
05798 }
05799
05800 ast_module_ref(ast_module_info->self);
05801 return tmp;
05802 }
05803
05804 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05805 {
05806 unsigned long int mssincetx;
05807 long int ms, pred;
05808
05809 tpeer->trunkact = *now;
05810 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05811 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05812
05813 tpeer->txtrunktime = *now;
05814 tpeer->lastsent = 999999;
05815 }
05816
05817 tpeer->lasttxtime = *now;
05818
05819
05820 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05821
05822 pred = tpeer->lastsent + sampms;
05823 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05824 ms = pred;
05825
05826
05827 if (ms == tpeer->lastsent)
05828 ms = tpeer->lastsent + 1;
05829 tpeer->lastsent = ms;
05830 return ms;
05831 }
05832
05833 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05834 {
05835 long ms;
05836 if (ast_tvzero(iaxs[callno]->rxcore)) {
05837
05838 iaxs[callno]->rxcore = ast_tvnow();
05839
05840 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05841 }
05842
05843 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05844
05845 return ms + ts;
05846 }
05847
05848 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05849 {
05850 int ms;
05851 int voice = 0;
05852 int genuine = 0;
05853 int adjust;
05854 int rate = ast_format_rate(f->subclass.codec) / 1000;
05855 struct timeval *delivery = NULL;
05856
05857
05858
05859
05860
05861
05862
05863
05864 if (f) {
05865 if (f->frametype == AST_FRAME_VOICE) {
05866 voice = 1;
05867 delivery = &f->delivery;
05868 } else if (f->frametype == AST_FRAME_IAX) {
05869 genuine = 1;
05870 } else if (f->frametype == AST_FRAME_CNG) {
05871 p->notsilenttx = 0;
05872 }
05873 }
05874 if (ast_tvzero(p->offset)) {
05875 p->offset = ast_tvnow();
05876
05877 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05878 }
05879
05880 if (ts)
05881 return ts;
05882
05883 if (delivery && !ast_tvzero(*delivery)) {
05884 ms = ast_tvdiff_ms(*delivery, p->offset);
05885 if (ms < 0) {
05886 ms = 0;
05887 }
05888 if (iaxdebug)
05889 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05890 } else {
05891 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05892 if (ms < 0)
05893 ms = 0;
05894 if (voice) {
05895
05896 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05897
05898
05899
05900
05901
05902
05903
05904
05905
05906
05907
05908
05909
05910
05911
05912
05913
05914
05915 adjust = (ms - p->nextpred);
05916 if (adjust < 0)
05917 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05918 else if (adjust > 0)
05919 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05920
05921 if (!p->nextpred) {
05922 p->nextpred = ms;
05923 if (p->nextpred <= p->lastsent)
05924 p->nextpred = p->lastsent + 3;
05925 }
05926 ms = p->nextpred;
05927 } else {
05928
05929
05930
05931
05932
05933
05934
05935
05936
05937 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05938 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05939 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05940
05941 if (f->samples >= rate)
05942 {
05943 int diff = ms % (f->samples / rate);
05944 if (diff)
05945 ms += f->samples/rate - diff;
05946 }
05947
05948 p->nextpred = ms;
05949 p->notsilenttx = 1;
05950 }
05951 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05952
05953
05954
05955
05956
05957
05958
05959
05960 if ( (unsigned int)ms < p->lastsent )
05961 ms = p->lastsent;
05962 } else {
05963
05964
05965 if (genuine) {
05966
05967 if (ms <= p->lastsent)
05968 ms = p->lastsent + 3;
05969 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05970
05971 ms = p->lastsent + 3;
05972 }
05973 }
05974 }
05975 p->lastsent = ms;
05976 if (voice)
05977 p->nextpred = p->nextpred + f->samples / rate;
05978 return ms;
05979 }
05980
05981 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05982 {
05983
05984
05985 int ms;
05986 #ifdef IAXTESTS
05987 int jit;
05988 #endif
05989
05990 if (ast_tvzero(p->rxcore)) {
05991 p->rxcore = ast_tvnow();
05992 if (iaxdebug)
05993 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05994 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05995 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05996 #if 1
05997 if (iaxdebug)
05998 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05999 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06000 #endif
06001 }
06002
06003 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06004 #ifdef IAXTESTS
06005 if (test_jit) {
06006 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06007 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06008 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06009 jit = -jit;
06010 ms += jit;
06011 }
06012 }
06013 if (test_late) {
06014 ms += test_late;
06015 test_late = 0;
06016 }
06017 #endif
06018 return ms;
06019 }
06020
06021 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
06022 {
06023 struct iax2_trunk_peer *tpeer = NULL;
06024
06025
06026 AST_LIST_LOCK(&tpeers);
06027
06028 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06029 if (!inaddrcmp(&tpeer->addr, sin)) {
06030 ast_mutex_lock(&tpeer->lock);
06031 break;
06032 }
06033 }
06034
06035 if (!tpeer) {
06036 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06037 ast_mutex_init(&tpeer->lock);
06038 tpeer->lastsent = 9999;
06039 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06040 tpeer->trunkact = ast_tvnow();
06041 ast_mutex_lock(&tpeer->lock);
06042 tpeer->sockfd = fd;
06043 #ifdef SO_NO_CHECK
06044 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06045 #endif
06046 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06047 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06048 }
06049 }
06050
06051 AST_LIST_UNLOCK(&tpeers);
06052
06053 return tpeer;
06054 }
06055
06056 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
06057 {
06058 struct ast_frame *f;
06059 struct iax2_trunk_peer *tpeer;
06060 void *tmp, *ptr;
06061 struct timeval now;
06062 int res;
06063 struct ast_iax2_meta_trunk_entry *met;
06064 struct ast_iax2_meta_trunk_mini *mtm;
06065
06066 f = &fr->af;
06067 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06068 if (tpeer) {
06069 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06070
06071 if (tpeer->trunkdataalloc < trunkmaxsize) {
06072 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06073 ast_mutex_unlock(&tpeer->lock);
06074 return -1;
06075 }
06076
06077 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06078 tpeer->trunkdata = tmp;
06079 ast_debug(1, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
06080 } else {
06081 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));
06082 ast_mutex_unlock(&tpeer->lock);
06083 return -1;
06084 }
06085 }
06086
06087
06088 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06089 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06090 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06091 mtm->len = htons(f->datalen);
06092 mtm->mini.callno = htons(pvt->callno);
06093 mtm->mini.ts = htons(0xffff & fr->ts);
06094 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06095 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06096 } else {
06097 met = (struct ast_iax2_meta_trunk_entry *)ptr;
06098
06099 met->callno = htons(pvt->callno);
06100 met->len = htons(f->datalen);
06101
06102 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06103 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06104 }
06105
06106 memcpy(ptr, f->data.ptr, f->datalen);
06107 tpeer->trunkdatalen += f->datalen;
06108
06109 tpeer->calls++;
06110
06111
06112 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
06113 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
06114
06115
06116 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06117 now = ast_tvnow();
06118 res = send_trunk(tpeer, &now);
06119 trunk_untimed ++;
06120 }
06121
06122 ast_mutex_unlock(&tpeer->lock);
06123 }
06124 return 0;
06125 }
06126
06127
06128
06129 static void build_rand_pad(unsigned char *buf, ssize_t len)
06130 {
06131 long tmp;
06132 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06133 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06134 buf += sizeof(tmp);
06135 len -= sizeof(tmp);
06136 }
06137 }
06138
06139 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06140 {
06141 build_ecx_key(digest, pvt);
06142 ast_aes_set_decrypt_key(digest, &pvt->dcx);
06143 }
06144
06145 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06146 {
06147
06148
06149
06150 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06151 ast_aes_set_encrypt_key(digest, &pvt->ecx);
06152 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06153 }
06154
06155 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
06156 {
06157 #if 0
06158
06159 int x;
06160 if (len % 16)
06161 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06162 for (x=0;x<len;x++)
06163 dst[x] = src[x] ^ 0xff;
06164 #else
06165 unsigned char lastblock[16] = { 0 };
06166 int x;
06167 while(len > 0) {
06168 ast_aes_decrypt(src, dst, dcx);
06169 for (x=0;x<16;x++)
06170 dst[x] ^= lastblock[x];
06171 memcpy(lastblock, src, sizeof(lastblock));
06172 dst += 16;
06173 src += 16;
06174 len -= 16;
06175 }
06176 #endif
06177 }
06178
06179 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
06180 {
06181 #if 0
06182
06183 int x;
06184 if (len % 16)
06185 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06186 for (x=0;x<len;x++)
06187 dst[x] = src[x] ^ 0xff;
06188 #else
06189 unsigned char curblock[16] = { 0 };
06190 int x;
06191 while(len > 0) {
06192 for (x=0;x<16;x++)
06193 curblock[x] ^= src[x];
06194 ast_aes_encrypt(curblock, dst, ecx);
06195 memcpy(curblock, dst, sizeof(curblock));
06196 dst += 16;
06197 src += 16;
06198 len -= 16;
06199 }
06200 #endif
06201 }
06202
06203 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06204 {
06205 int padding;
06206 unsigned char *workspace;
06207
06208 workspace = alloca(*datalen);
06209 memset(f, 0, sizeof(*f));
06210 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06211 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06212 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06213 return -1;
06214
06215 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06216
06217 padding = 16 + (workspace[15] & 0x0f);
06218 if (iaxdebug)
06219 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06220 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06221 return -1;
06222
06223 *datalen -= padding;
06224 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06225 f->frametype = fh->type;
06226 if (f->frametype == AST_FRAME_VIDEO) {
06227 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06228 } else if (f->frametype == AST_FRAME_VOICE) {
06229 f->subclass.codec = uncompress_subclass(fh->csub);
06230 } else {
06231 f->subclass.integer = uncompress_subclass(fh->csub);
06232 }
06233 } else {
06234 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06235 if (iaxdebug)
06236 ast_debug(1, "Decoding mini with length %d\n", *datalen);
06237 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06238 return -1;
06239
06240 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06241 padding = 16 + (workspace[15] & 0x0f);
06242 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06243 return -1;
06244 *datalen -= padding;
06245 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06246 }
06247 return 0;
06248 }
06249
06250 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06251 {
06252 int padding;
06253 unsigned char *workspace;
06254 workspace = alloca(*datalen + 32);
06255 if (!workspace)
06256 return -1;
06257 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06258 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06259 if (iaxdebug)
06260 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06261 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06262 padding = 16 + (padding & 0xf);
06263 memcpy(workspace, poo, padding);
06264 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06265 workspace[15] &= 0xf0;
06266 workspace[15] |= (padding & 0xf);
06267 if (iaxdebug)
06268 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06269 *datalen += padding;
06270 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06271 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06272 memcpy(poo, workspace + *datalen - 32, 32);
06273 } else {
06274 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06275 if (iaxdebug)
06276 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06277 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06278 padding = 16 + (padding & 0xf);
06279 memcpy(workspace, poo, padding);
06280 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06281 workspace[15] &= 0xf0;
06282 workspace[15] |= (padding & 0x0f);
06283 *datalen += padding;
06284 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06285 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06286 memcpy(poo, workspace + *datalen - 32, 32);
06287 }
06288 return 0;
06289 }
06290
06291 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06292 {
06293 int res=-1;
06294 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06295
06296 struct MD5Context md5;
06297 unsigned char digest[16];
06298 char *tmppw, *stringp;
06299
06300 tmppw = ast_strdupa(iaxs[callno]->secret);
06301 stringp = tmppw;
06302 while ((tmppw = strsep(&stringp, ";"))) {
06303 MD5Init(&md5);
06304 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06305 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06306 MD5Final(digest, &md5);
06307 build_encryption_keys(digest, iaxs[callno]);
06308 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06309 if (!res) {
06310 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06311 break;
06312 }
06313 }
06314 } else
06315 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06316 return res;
06317 }
06318
06319 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06320 {
06321
06322
06323
06324 struct ast_iax2_full_hdr *fh;
06325 struct ast_iax2_mini_hdr *mh;
06326 struct ast_iax2_video_hdr *vh;
06327 struct {
06328 struct iax_frame fr2;
06329 unsigned char buffer[4096];
06330 } frb;
06331 struct iax_frame *fr;
06332 int res;
06333 int sendmini=0;
06334 unsigned int lastsent;
06335 unsigned int fts;
06336
06337 frb.fr2.afdatalen = sizeof(frb.buffer);
06338
06339 if (!pvt) {
06340 ast_log(LOG_WARNING, "No private structure for packet?\n");
06341 return -1;
06342 }
06343
06344 lastsent = pvt->lastsent;
06345
06346
06347 fts = calc_timestamp(pvt, ts, f);
06348
06349
06350
06351
06352 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06353 return 0;
06354 #if 0
06355 ast_log(LOG_NOTICE,
06356 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06357 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06358 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06359 pvt->keyrotateid != -1 ? "" : "no "
06360 );
06361 #endif
06362 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06363 iax2_key_rotate(pvt);
06364 }
06365
06366 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
06367 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06368 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06369 &&
06370 (f->frametype == AST_FRAME_VOICE)
06371 &&
06372 (f->subclass.codec == pvt->svoiceformat)
06373 ) {
06374
06375 now = 1;
06376
06377 sendmini = 1;
06378 }
06379 if ( f->frametype == AST_FRAME_VIDEO ) {
06380
06381
06382
06383
06384
06385 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06386 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
06387 ) {
06388 now = 1;
06389 sendmini = 1;
06390 } else {
06391 now = 0;
06392 sendmini = 0;
06393 }
06394 pvt->lastvsent = fts;
06395 }
06396 if (f->frametype == AST_FRAME_IAX) {
06397
06398 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06399 if (!pvt->first_iax_message) {
06400 pvt->first_iax_message = pvt->last_iax_message;
06401 }
06402 }
06403
06404 if (now) {
06405 fr = &frb.fr2;
06406 } else
06407 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));
06408 if (!fr) {
06409 ast_log(LOG_WARNING, "Out of memory\n");
06410 return -1;
06411 }
06412
06413 iax_frame_wrap(fr, f);
06414
06415 fr->ts = fts;
06416 fr->callno = pvt->callno;
06417 fr->transfer = transfer;
06418 fr->final = final;
06419 fr->encmethods = 0;
06420 if (!sendmini) {
06421
06422 if (seqno > -1)
06423 fr->oseqno = seqno;
06424 else
06425 fr->oseqno = pvt->oseqno++;
06426 fr->iseqno = pvt->iseqno;
06427 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06428 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06429 fh->ts = htonl(fr->ts);
06430 fh->oseqno = fr->oseqno;
06431 if (transfer) {
06432 fh->iseqno = 0;
06433 } else
06434 fh->iseqno = fr->iseqno;
06435
06436 if (!transfer)
06437 pvt->aseqno = fr->iseqno;
06438 fh->type = fr->af.frametype & 0xFF;
06439
06440 if (fr->af.frametype == AST_FRAME_VIDEO) {
06441 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
06442 } else if (fr->af.frametype == AST_FRAME_VOICE) {
06443 fh->csub = compress_subclass(fr->af.subclass.codec);
06444 } else {
06445 fh->csub = compress_subclass(fr->af.subclass.integer);
06446 }
06447
06448 if (transfer) {
06449 fr->dcallno = pvt->transfercallno;
06450 } else
06451 fr->dcallno = pvt->peercallno;
06452 fh->dcallno = htons(fr->dcallno);
06453 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06454 fr->data = fh;
06455 fr->retries = 0;
06456
06457 fr->retrytime = pvt->pingtime * 2;
06458 if (fr->retrytime < MIN_RETRY_TIME)
06459 fr->retrytime = MIN_RETRY_TIME;
06460 if (fr->retrytime > MAX_RETRY_TIME)
06461 fr->retrytime = MAX_RETRY_TIME;
06462
06463 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06464 fr->retries = -1;
06465 else if (f->frametype == AST_FRAME_VOICE)
06466 pvt->svoiceformat = f->subclass.codec;
06467 else if (f->frametype == AST_FRAME_VIDEO)
06468 pvt->svideoformat = f->subclass.codec & ~0x1LL;
06469 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06470 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06471 if (fr->transfer)
06472 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06473 else
06474 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06475 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06476 fr->encmethods = pvt->encmethods;
06477 fr->ecx = pvt->ecx;
06478 fr->mydcx = pvt->mydcx;
06479 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06480 } else
06481 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06482 }
06483
06484 if (now) {
06485 res = send_packet(fr);
06486 } else
06487 res = iax2_transmit(fr);
06488 } else {
06489 if (ast_test_flag64(pvt, IAX_TRUNK)) {
06490 iax2_trunk_queue(pvt, fr);
06491 res = 0;
06492 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06493
06494 fr->oseqno = -1;
06495 fr->iseqno = -1;
06496 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06497 vh->zeros = 0;
06498 vh->callno = htons(0x8000 | fr->callno);
06499 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
06500 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06501 fr->data = vh;
06502 fr->retries = -1;
06503 res = send_packet(fr);
06504 } else {
06505
06506 fr->oseqno = -1;
06507 fr->iseqno = -1;
06508
06509 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06510 mh->callno = htons(fr->callno);
06511 mh->ts = htons(fr->ts & 0xFFFF);
06512 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06513 fr->data = mh;
06514 fr->retries = -1;
06515 if (pvt->transferring == TRANSFER_MEDIAPASS)
06516 fr->transfer = 1;
06517 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06518 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06519 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06520 } else
06521 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06522 }
06523 res = send_packet(fr);
06524 }
06525 }
06526 return res;
06527 }
06528
06529 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06530 {
06531 regex_t regexbuf;
06532 int havepattern = 0;
06533
06534 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06535 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06536
06537 struct iax2_user *user = NULL;
06538 char auth[90];
06539 char *pstr = "";
06540 struct ao2_iterator i;
06541
06542 switch (cmd) {
06543 case CLI_INIT:
06544 e->command = "iax2 show users [like]";
06545 e->usage =
06546 "Usage: iax2 show users [like <pattern>]\n"
06547 " Lists all known IAX2 users.\n"
06548 " Optional regular expression pattern is used to filter the user list.\n";
06549 return NULL;
06550 case CLI_GENERATE:
06551 return NULL;
06552 }
06553
06554 switch (a->argc) {
06555 case 5:
06556 if (!strcasecmp(a->argv[3], "like")) {
06557 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06558 return CLI_SHOWUSAGE;
06559 havepattern = 1;
06560 } else
06561 return CLI_SHOWUSAGE;
06562 case 3:
06563 break;
06564 default:
06565 return CLI_SHOWUSAGE;
06566 }
06567
06568 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06569 i = ao2_iterator_init(users, 0);
06570 for (user = ao2_iterator_next(&i); user;
06571 user_unref(user), user = ao2_iterator_next(&i)) {
06572 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06573 continue;
06574
06575 if (!ast_strlen_zero(user->secret)) {
06576 ast_copy_string(auth,user->secret, sizeof(auth));
06577 } else if (!ast_strlen_zero(user->inkeys)) {
06578 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06579 } else
06580 ast_copy_string(auth, "-no secret-", sizeof(auth));
06581
06582 if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06583 pstr = "REQ Only";
06584 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06585 pstr = "Disabled";
06586 else
06587 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06588
06589 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06590 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06591 user->ha ? "Yes" : "No", pstr);
06592 }
06593 ao2_iterator_destroy(&i);
06594
06595 if (havepattern)
06596 regfree(®exbuf);
06597
06598 return CLI_SUCCESS;
06599 #undef FORMAT
06600 #undef FORMAT2
06601 }
06602
06603 static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char * const argv[])
06604 {
06605 regex_t regexbuf;
06606 int havepattern = 0;
06607 int total_peers = 0;
06608 int online_peers = 0;
06609 int offline_peers = 0;
06610 int unmonitored_peers = 0;
06611 struct ao2_iterator i;
06612
06613 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n"
06614 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n"
06615
06616 struct iax2_peer *peer = NULL;
06617 char name[256];
06618 struct ast_str *encmethods = ast_str_alloca(256);
06619 int registeredonly=0;
06620 char idtext[256] = "";
06621 switch (argc) {
06622 case 6:
06623 if (!strcasecmp(argv[3], "registered"))
06624 registeredonly = 1;
06625 else
06626 return RESULT_SHOWUSAGE;
06627 if (!strcasecmp(argv[4], "like")) {
06628 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06629 return RESULT_SHOWUSAGE;
06630 havepattern = 1;
06631 } else
06632 return RESULT_SHOWUSAGE;
06633 break;
06634 case 5:
06635 if (!strcasecmp(argv[3], "like")) {
06636 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06637 return RESULT_SHOWUSAGE;
06638 havepattern = 1;
06639 } else
06640 return RESULT_SHOWUSAGE;
06641 break;
06642 case 4:
06643 if (!strcasecmp(argv[3], "registered"))
06644 registeredonly = 1;
06645 else
06646 return RESULT_SHOWUSAGE;
06647 break;
06648 case 3:
06649 break;
06650 default:
06651 return RESULT_SHOWUSAGE;
06652 }
06653
06654
06655 if (!s)
06656 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status");
06657
06658 i = ao2_iterator_init(peers, 0);
06659 for (peer = ao2_iterator_next(&i); peer;
06660 peer_unref(peer), peer = ao2_iterator_next(&i)) {
06661 char nm[20];
06662 char status[20];
06663 int retstatus;
06664 struct sockaddr_in peer_addr;
06665
06666 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06667
06668 if (registeredonly && !peer_addr.sin_addr.s_addr) {
06669 continue;
06670 }
06671 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
06672 continue;
06673 }
06674
06675 if (!ast_strlen_zero(peer->username))
06676 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06677 else
06678 ast_copy_string(name, peer->name, sizeof(name));
06679
06680 encmethods_to_str(peer->encmethods, encmethods);
06681 retstatus = peer_status(peer, status, sizeof(status));
06682 if (retstatus > 0)
06683 online_peers++;
06684 else if (!retstatus)
06685 offline_peers++;
06686 else
06687 unmonitored_peers++;
06688
06689 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06690
06691 if (s) {
06692 astman_append(s,
06693 "Event: PeerEntry\r\n%s"
06694 "Channeltype: IAX2\r\n"
06695 "ObjectName: %s\r\n"
06696 "ChanObjectType: peer\r\n"
06697 "IPaddress: %s\r\n"
06698 "IPport: %d\r\n"
06699 "Dynamic: %s\r\n"
06700 "Trunk: %s\r\n"
06701 "Encryption: %s\r\n"
06702 "Status: %s\r\n\r\n",
06703 idtext,
06704 name,
06705 ast_sockaddr_stringify_addr(&peer->addr),
06706 ast_sockaddr_port(&peer->addr),
06707 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06708 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06709 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06710 status);
06711 } else {
06712 ast_cli(fd, FORMAT, name,
06713 ast_sockaddr_stringify_addr(&peer->addr),
06714 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06715 nm,
06716 ast_sockaddr_port(&peer->addr),
06717 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
06718 peer->encmethods ? "(E)" : " ",
06719 status);
06720 }
06721 total_peers++;
06722 }
06723 ao2_iterator_destroy(&i);
06724
06725 if (!s)
06726 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06727 total_peers, online_peers, offline_peers, unmonitored_peers);
06728
06729 if (havepattern)
06730 regfree(®exbuf);
06731
06732 if (total)
06733 *total = total_peers;
06734
06735 return RESULT_SUCCESS;
06736 #undef FORMAT
06737 #undef FORMAT2
06738 }
06739
06740 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06741 {
06742 struct iax2_thread *thread = NULL;
06743 time_t t;
06744 int threadcount = 0, dynamiccount = 0;
06745 char type;
06746
06747 switch (cmd) {
06748 case CLI_INIT:
06749 e->command = "iax2 show threads";
06750 e->usage =
06751 "Usage: iax2 show threads\n"
06752 " Lists status of IAX helper threads\n";
06753 return NULL;
06754 case CLI_GENERATE:
06755 return NULL;
06756 }
06757 if (a->argc != 3)
06758 return CLI_SHOWUSAGE;
06759
06760 ast_cli(a->fd, "IAX2 Thread Information\n");
06761 time(&t);
06762 ast_cli(a->fd, "Idle Threads:\n");
06763 AST_LIST_LOCK(&idle_list);
06764 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06765 #ifdef DEBUG_SCHED_MULTITHREAD
06766 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06767 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06768 #else
06769 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06770 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06771 #endif
06772 threadcount++;
06773 }
06774 AST_LIST_UNLOCK(&idle_list);
06775 ast_cli(a->fd, "Active Threads:\n");
06776 AST_LIST_LOCK(&active_list);
06777 AST_LIST_TRAVERSE(&active_list, thread, list) {
06778 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06779 type = 'D';
06780 else
06781 type = 'P';
06782 #ifdef DEBUG_SCHED_MULTITHREAD
06783 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06784 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06785 #else
06786 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06787 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06788 #endif
06789 threadcount++;
06790 }
06791 AST_LIST_UNLOCK(&active_list);
06792 ast_cli(a->fd, "Dynamic Threads:\n");
06793 AST_LIST_LOCK(&dynamic_list);
06794 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06795 #ifdef DEBUG_SCHED_MULTITHREAD
06796 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06797 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06798 #else
06799 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06800 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06801 #endif
06802 dynamiccount++;
06803 }
06804 AST_LIST_UNLOCK(&dynamic_list);
06805 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06806 return CLI_SUCCESS;
06807 }
06808
06809 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06810 {
06811 struct iax2_peer *p;
06812
06813 switch (cmd) {
06814 case CLI_INIT:
06815 e->command = "iax2 unregister";
06816 e->usage =
06817 "Usage: iax2 unregister <peername>\n"
06818 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06819 return NULL;
06820 case CLI_GENERATE:
06821 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06822 }
06823
06824 if (a->argc != 3)
06825 return CLI_SHOWUSAGE;
06826
06827 p = find_peer(a->argv[2], 1);
06828 if (p) {
06829 if (p->expire > 0) {
06830 struct iax2_peer tmp_peer = {
06831 .name = a->argv[2],
06832 };
06833 struct iax2_peer *peer;
06834
06835 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06836 if (peer) {
06837 expire_registry(peer_ref(peer));
06838 peer_unref(peer);
06839 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06840 } else {
06841 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06842 }
06843 } else {
06844 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06845 }
06846 } else {
06847 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06848 }
06849 return CLI_SUCCESS;
06850 }
06851
06852 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06853 {
06854 int which = 0;
06855 struct iax2_peer *p = NULL;
06856 char *res = NULL;
06857 int wordlen = strlen(word);
06858
06859
06860 if (pos == 2) {
06861 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06862 while ((p = ao2_iterator_next(&i))) {
06863 if (!strncasecmp(p->name, word, wordlen) &&
06864 ++which > state && p->expire > 0) {
06865 res = ast_strdup(p->name);
06866 peer_unref(p);
06867 break;
06868 }
06869 peer_unref(p);
06870 }
06871 ao2_iterator_destroy(&i);
06872 }
06873
06874 return res;
06875 }
06876
06877 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06878 {
06879 switch (cmd) {
06880 case CLI_INIT:
06881 e->command = "iax2 show peers";
06882 e->usage =
06883 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06884 " Lists all known IAX2 peers.\n"
06885 " Optional 'registered' argument lists only peers with known addresses.\n"
06886 " Optional regular expression pattern is used to filter the peer list.\n";
06887 return NULL;
06888 case CLI_GENERATE:
06889 return NULL;
06890 }
06891
06892 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06893 case RESULT_SHOWUSAGE:
06894 return CLI_SHOWUSAGE;
06895 case RESULT_FAILURE:
06896 return CLI_FAILURE;
06897 default:
06898 return CLI_SUCCESS;
06899 }
06900 }
06901
06902 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06903 {
06904 ast_cli_netstats(s, -1, 0);
06905 astman_append(s, "\r\n");
06906 return RESULT_SUCCESS;
06907 }
06908
06909 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06910 {
06911 struct iax_firmware *cur = NULL;
06912
06913 switch (cmd) {
06914 case CLI_INIT:
06915 e->command = "iax2 show firmware";
06916 e->usage =
06917 "Usage: iax2 show firmware\n"
06918 " Lists all known IAX firmware images.\n";
06919 return NULL;
06920 case CLI_GENERATE:
06921 return NULL;
06922 }
06923
06924 if (a->argc != 3 && a->argc != 4)
06925 return CLI_SHOWUSAGE;
06926
06927 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06928 AST_LIST_LOCK(&firmwares);
06929 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06930 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06931 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06932 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06933 }
06934 }
06935 AST_LIST_UNLOCK(&firmwares);
06936
06937 return CLI_SUCCESS;
06938 }
06939
06940
06941 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06942 {
06943 static const char * const a[] = { "iax2", "show", "peers" };
06944 const char *id = astman_get_header(m,"ActionID");
06945 char idtext[256] = "";
06946 int total = 0;
06947
06948 if (!ast_strlen_zero(id))
06949 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06950
06951 astman_send_listack(s, m, "Peer status list will follow", "start");
06952
06953 __iax2_show_peers(-1, &total, s, 3, a);
06954
06955 astman_append(s,
06956 "Event: PeerlistComplete\r\n"
06957 "EventList: Complete\r\n"
06958 "ListItems: %d\r\n"
06959 "%s"
06960 "\r\n", total, idtext);
06961 return 0;
06962 }
06963
06964
06965 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06966 {
06967 struct iax2_peer *peer = NULL;
06968 int peer_count = 0;
06969 char nm[20];
06970 char status[20];
06971 const char *id = astman_get_header(m,"ActionID");
06972 char idtext[256] = "";
06973 struct ast_str *encmethods = ast_str_alloca(256);
06974 struct ao2_iterator i;
06975
06976 if (!ast_strlen_zero(id))
06977 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06978
06979 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06980
06981
06982 i = ao2_iterator_init(peers, 0);
06983 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06984 encmethods_to_str(peer->encmethods, encmethods);
06985 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06986 if (!ast_strlen_zero(peer->username)) {
06987 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06988 } else {
06989 astman_append(s, "ObjectName: %s\r\n", peer->name);
06990 }
06991 astman_append(s, "ChanObjectType: peer\r\n");
06992 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
06993 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06994 astman_append(s, "Mask: %s\r\n", nm);
06995 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
06996 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
06997 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
06998 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
06999 peer_status(peer, status, sizeof(status));
07000 astman_append(s, "Status: %s\r\n\r\n", status);
07001 peer_count++;
07002 }
07003 ao2_iterator_destroy(&i);
07004
07005 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07006 return RESULT_SUCCESS;
07007 }
07008
07009
07010 static char *regstate2str(int regstate)
07011 {
07012 switch(regstate) {
07013 case REG_STATE_UNREGISTERED:
07014 return "Unregistered";
07015 case REG_STATE_REGSENT:
07016 return "Request Sent";
07017 case REG_STATE_AUTHSENT:
07018 return "Auth. Sent";
07019 case REG_STATE_REGISTERED:
07020 return "Registered";
07021 case REG_STATE_REJECTED:
07022 return "Rejected";
07023 case REG_STATE_TIMEOUT:
07024 return "Timeout";
07025 case REG_STATE_NOAUTH:
07026 return "No Authentication";
07027 default:
07028 return "Unknown";
07029 }
07030 }
07031
07032 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07033 {
07034 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
07035 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
07036 struct iax2_registry *reg = NULL;
07037 char host[80];
07038 char perceived[80];
07039 int counter = 0;
07040
07041 switch (cmd) {
07042 case CLI_INIT:
07043 e->command = "iax2 show registry";
07044 e->usage =
07045 "Usage: iax2 show registry\n"
07046 " Lists all registration requests and status.\n";
07047 return NULL;
07048 case CLI_GENERATE:
07049 return NULL;
07050 }
07051 if (a->argc != 3)
07052 return CLI_SHOWUSAGE;
07053 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07054 AST_LIST_LOCK(®istrations);
07055 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07056 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07057 if (reg->us.sin_addr.s_addr)
07058 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07059 else
07060 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07061 ast_cli(a->fd, FORMAT, host,
07062 (reg->dnsmgr) ? "Y" : "N",
07063 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07064 counter++;
07065 }
07066 AST_LIST_UNLOCK(®istrations);
07067 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07068 return CLI_SUCCESS;
07069 #undef FORMAT
07070 #undef FORMAT2
07071 }
07072
07073 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
07074 {
07075 const char *id = astman_get_header(m, "ActionID");
07076 struct iax2_registry *reg = NULL;
07077 char idtext[256] = "";
07078 char host[80] = "";
07079 char perceived[80] = "";
07080 int total = 0;
07081
07082 if (!ast_strlen_zero(id))
07083 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07084
07085 astman_send_listack(s, m, "Registrations will follow", "start");
07086
07087 AST_LIST_LOCK(®istrations);
07088 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07089 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07090
07091 if (reg->us.sin_addr.s_addr) {
07092 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07093 } else {
07094 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07095 }
07096
07097 astman_append(s,
07098 "Event: RegistryEntry\r\n"
07099 "%s"
07100 "Host: %s\r\n"
07101 "DNSmanager: %s\r\n"
07102 "Username: %s\r\n"
07103 "Perceived: %s\r\n"
07104 "Refresh: %d\r\n"
07105 "State: %s\r\n"
07106 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
07107 reg->refresh, regstate2str(reg->regstate));
07108
07109 total++;
07110 }
07111 AST_LIST_UNLOCK(®istrations);
07112
07113 astman_append(s,
07114 "Event: RegistrationsComplete\r\n"
07115 "EventList: Complete\r\n"
07116 "ListItems: %d\r\n"
07117 "%s"
07118 "\r\n", total, idtext);
07119
07120 return 0;
07121 }
07122
07123 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07124 {
07125 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
07126 #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"
07127 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
07128 int x;
07129 int numchans = 0;
07130 char first_message[10] = { 0, };
07131 char last_message[10] = { 0, };
07132
07133 switch (cmd) {
07134 case CLI_INIT:
07135 e->command = "iax2 show channels";
07136 e->usage =
07137 "Usage: iax2 show channels\n"
07138 " Lists all currently active IAX channels.\n";
07139 return NULL;
07140 case CLI_GENERATE:
07141 return NULL;
07142 }
07143
07144 if (a->argc != 3)
07145 return CLI_SHOWUSAGE;
07146 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07147 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07148 ast_mutex_lock(&iaxsl[x]);
07149 if (iaxs[x]) {
07150 int lag, jitter, localdelay;
07151 jb_info jbinfo;
07152 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07153 jb_getinfo(iaxs[x]->jb, &jbinfo);
07154 jitter = jbinfo.jitter;
07155 localdelay = jbinfo.current - jbinfo.min;
07156 } else {
07157 jitter = -1;
07158 localdelay = 0;
07159 }
07160
07161 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07162 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07163 lag = iaxs[x]->remote_rr.delay;
07164 ast_cli(a->fd, FORMAT,
07165 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07166 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07167 S_OR(iaxs[x]->username, "(None)"),
07168 iaxs[x]->callno, iaxs[x]->peercallno,
07169 iaxs[x]->oseqno, iaxs[x]->iseqno,
07170 lag,
07171 jitter,
07172 localdelay,
07173 ast_getformatname(iaxs[x]->voiceformat),
07174 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07175 first_message,
07176 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07177 last_message);
07178 numchans++;
07179 }
07180 ast_mutex_unlock(&iaxsl[x]);
07181 }
07182 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07183 return CLI_SUCCESS;
07184 #undef FORMAT
07185 #undef FORMAT2
07186 #undef FORMATB
07187 }
07188
07189 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
07190 {
07191 int x;
07192 int numchans = 0;
07193 char first_message[10] = { 0, };
07194 char last_message[10] = { 0, };
07195 #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
07196 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07197 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07198 ast_mutex_lock(&iaxsl[x]);
07199 if (iaxs[x]) {
07200 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07201 jb_info jbinfo;
07202 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07203 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07204
07205 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07206 jb_getinfo(iaxs[x]->jb, &jbinfo);
07207 localjitter = jbinfo.jitter;
07208 localdelay = jbinfo.current - jbinfo.min;
07209 locallost = jbinfo.frames_lost;
07210 locallosspct = jbinfo.losspct/1000;
07211 localdropped = jbinfo.frames_dropped;
07212 localooo = jbinfo.frames_ooo;
07213 } else {
07214 localjitter = -1;
07215 localdelay = 0;
07216 locallost = -1;
07217 locallosspct = -1;
07218 localdropped = 0;
07219 localooo = -1;
07220 }
07221 if (s)
07222 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07223 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07224 iaxs[x]->pingtime,
07225 localjitter,
07226 localdelay,
07227 locallost,
07228 locallosspct,
07229 localdropped,
07230 localooo,
07231 iaxs[x]->frames_received/1000,
07232 iaxs[x]->remote_rr.jitter,
07233 iaxs[x]->remote_rr.delay,
07234 iaxs[x]->remote_rr.losscnt,
07235 iaxs[x]->remote_rr.losspct,
07236 iaxs[x]->remote_rr.dropped,
07237 iaxs[x]->remote_rr.ooo,
07238 iaxs[x]->remote_rr.packets/1000,
07239 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07240 first_message,
07241 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07242 last_message);
07243 else
07244 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07245 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07246 iaxs[x]->pingtime,
07247 localjitter,
07248 localdelay,
07249 locallost,
07250 locallosspct,
07251 localdropped,
07252 localooo,
07253 iaxs[x]->frames_received/1000,
07254 iaxs[x]->remote_rr.jitter,
07255 iaxs[x]->remote_rr.delay,
07256 iaxs[x]->remote_rr.losscnt,
07257 iaxs[x]->remote_rr.losspct,
07258 iaxs[x]->remote_rr.dropped,
07259 iaxs[x]->remote_rr.ooo,
07260 iaxs[x]->remote_rr.packets/1000,
07261 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07262 first_message,
07263 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07264 last_message);
07265 numchans++;
07266 }
07267 ast_mutex_unlock(&iaxsl[x]);
07268 }
07269
07270 return numchans;
07271 }
07272
07273 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07274 {
07275 int numchans = 0;
07276
07277 switch (cmd) {
07278 case CLI_INIT:
07279 e->command = "iax2 show netstats";
07280 e->usage =
07281 "Usage: iax2 show netstats\n"
07282 " Lists network status for all currently active IAX channels.\n";
07283 return NULL;
07284 case CLI_GENERATE:
07285 return NULL;
07286 }
07287 if (a->argc != 3)
07288 return CLI_SHOWUSAGE;
07289 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07290 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07291 numchans = ast_cli_netstats(NULL, a->fd, 1);
07292 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07293 return CLI_SUCCESS;
07294 }
07295
07296 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07297 {
07298 switch (cmd) {
07299 case CLI_INIT:
07300 e->command = "iax2 set debug {on|off|peer}";
07301 e->usage =
07302 "Usage: iax2 set debug {on|off|peer peername}\n"
07303 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07304 return NULL;
07305 case CLI_GENERATE:
07306 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07307 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07308 return NULL;
07309 }
07310
07311 if (a->argc < e->args || a->argc > e->args + 1)
07312 return CLI_SHOWUSAGE;
07313
07314 if (!strcasecmp(a->argv[3], "peer")) {
07315 struct iax2_peer *peer;
07316 struct sockaddr_in peer_addr;
07317
07318
07319 if (a->argc != e->args + 1)
07320 return CLI_SHOWUSAGE;
07321
07322 peer = find_peer(a->argv[4], 1);
07323
07324 if (!peer) {
07325 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07326 return CLI_FAILURE;
07327 }
07328
07329 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07330
07331 debugaddr.sin_addr = peer_addr.sin_addr;
07332 debugaddr.sin_port = peer_addr.sin_port;
07333
07334 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07335 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07336
07337 ao2_ref(peer, -1);
07338 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07339 iaxdebug = 1;
07340 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07341 } else {
07342 iaxdebug = 0;
07343 memset(&debugaddr, 0, sizeof(debugaddr));
07344 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07345 }
07346 return CLI_SUCCESS;
07347 }
07348
07349 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07350 {
07351 switch (cmd) {
07352 case CLI_INIT:
07353 e->command = "iax2 set debug trunk {on|off}";
07354 e->usage =
07355 "Usage: iax2 set debug trunk {on|off}\n"
07356 " Enables/Disables debugging of IAX trunking\n";
07357 return NULL;
07358 case CLI_GENERATE:
07359 return NULL;
07360 }
07361
07362 if (a->argc != e->args)
07363 return CLI_SHOWUSAGE;
07364
07365 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07366 iaxtrunkdebug = 1;
07367 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07368 } else {
07369 iaxtrunkdebug = 0;
07370 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07371 }
07372 return CLI_SUCCESS;
07373 }
07374
07375 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07376 {
07377 switch (cmd) {
07378 case CLI_INIT:
07379 e->command = "iax2 set debug jb {on|off}";
07380 e->usage =
07381 "Usage: iax2 set debug jb {on|off}\n"
07382 " Enables/Disables jitterbuffer debugging information\n";
07383 return NULL;
07384 case CLI_GENERATE:
07385 return NULL;
07386 }
07387
07388 if (a->argc != e->args)
07389 return CLI_SHOWUSAGE;
07390
07391 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07392 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07393 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07394 } else {
07395 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07396 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07397 }
07398 return CLI_SUCCESS;
07399 }
07400
07401 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07402 {
07403 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07404 int res = -1;
07405 ast_mutex_lock(&iaxsl[callno]);
07406 if (iaxs[callno]) {
07407
07408 if (!iaxs[callno]->error) {
07409 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07410 res = 0;
07411
07412 else if (f->frametype == AST_FRAME_NULL)
07413 res = 0;
07414 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07415 res = 0;
07416 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07417 res = 0;
07418 else
07419
07420 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07421 } else {
07422 ast_debug(1, "Write error: %s\n", strerror(errno));
07423 }
07424 }
07425
07426 ast_mutex_unlock(&iaxsl[callno]);
07427 return res;
07428 }
07429
07430 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07431 int now, int transfer, int final)
07432 {
07433 struct ast_frame f = { 0, };
07434 int res = 0;
07435
07436 f.frametype = type;
07437 f.subclass.integer = command;
07438 f.datalen = datalen;
07439 f.src = __FUNCTION__;
07440 f.data.ptr = (void *) data;
07441
07442 if ((res = queue_signalling(i, &f)) <= 0) {
07443 return res;
07444 }
07445
07446 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07447 }
07448
07449 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07450 {
07451 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07452 }
07453
07454 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07455 {
07456 int res;
07457 ast_mutex_lock(&iaxsl[callno]);
07458 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07459 ast_mutex_unlock(&iaxsl[callno]);
07460 return res;
07461 }
07462
07463
07464
07465
07466
07467
07468 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)
07469 {
07470 int call_num = i->callno;
07471
07472 iax2_predestroy(i->callno);
07473 if (!iaxs[call_num])
07474 return -1;
07475 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07476 }
07477
07478 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)
07479 {
07480 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07481 }
07482
07483 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07484 {
07485 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07486 }
07487
07488 static int apply_context(struct iax2_context *con, const char *context)
07489 {
07490 while(con) {
07491 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07492 return -1;
07493 con = con->next;
07494 }
07495 return 0;
07496 }
07497
07498
07499 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07500 {
07501
07502 int res = -1;
07503 int version = 2;
07504 struct iax2_user *user = NULL, *best = NULL;
07505 int bestscore = 0;
07506 int gotcapability = 0;
07507 struct ast_variable *v = NULL, *tmpvar = NULL;
07508 struct ao2_iterator i;
07509 struct ast_sockaddr addr;
07510
07511 if (!iaxs[callno])
07512 return res;
07513 if (ies->called_number)
07514 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07515 if (ies->calling_number) {
07516 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07517 ast_shrink_phone_number(ies->calling_number);
07518 }
07519 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07520 }
07521 if (ies->calling_name)
07522 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07523 if (ies->calling_ani)
07524 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07525 if (ies->dnid)
07526 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07527 if (ies->rdnis)
07528 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07529 if (ies->called_context)
07530 ast_string_field_set(iaxs[callno], context, ies->called_context);
07531 if (ies->language)
07532 ast_string_field_set(iaxs[callno], language, ies->language);
07533 if (ies->username)
07534 ast_string_field_set(iaxs[callno], username, ies->username);
07535 if (ies->calling_ton > -1)
07536 iaxs[callno]->calling_ton = ies->calling_ton;
07537 if (ies->calling_tns > -1)
07538 iaxs[callno]->calling_tns = ies->calling_tns;
07539 if (ies->calling_pres > -1)
07540 iaxs[callno]->calling_pres = ies->calling_pres;
07541 if (ies->format)
07542 iaxs[callno]->peerformat = ies->format;
07543 if (ies->adsicpe)
07544 iaxs[callno]->peeradsicpe = ies->adsicpe;
07545 if (ies->capability) {
07546 gotcapability = 1;
07547 iaxs[callno]->peercapability = ies->capability;
07548 }
07549 if (ies->version)
07550 version = ies->version;
07551
07552
07553 if (ies->codec_prefs) {
07554 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07555 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07556 }
07557
07558 if (!gotcapability)
07559 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07560 if (version > IAX_PROTO_VERSION) {
07561 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07562 ast_inet_ntoa(sin->sin_addr), version);
07563 return res;
07564 }
07565
07566 i = ao2_iterator_init(users, 0);
07567 ast_sockaddr_from_sin(&addr, sin);
07568 while ((user = ao2_iterator_next(&i))) {
07569 if ((ast_strlen_zero(iaxs[callno]->username) ||
07570 !strcmp(iaxs[callno]->username, user->name))
07571 && ast_apply_ha(user->ha, &addr)
07572 && (ast_strlen_zero(iaxs[callno]->context) ||
07573 apply_context(user->contexts, iaxs[callno]->context))) {
07574 if (!ast_strlen_zero(iaxs[callno]->username)) {
07575
07576 if (best)
07577 user_unref(best);
07578 best = user;
07579 break;
07580 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07581
07582 if (user->ha) {
07583
07584 if (bestscore < 4) {
07585 bestscore = 4;
07586 if (best)
07587 user_unref(best);
07588 best = user;
07589 continue;
07590 }
07591 } else {
07592
07593 if (bestscore < 3) {
07594 bestscore = 3;
07595 if (best)
07596 user_unref(best);
07597 best = user;
07598 continue;
07599 }
07600 }
07601 } else {
07602 if (user->ha) {
07603
07604 if (bestscore < 2) {
07605 bestscore = 2;
07606 if (best)
07607 user_unref(best);
07608 best = user;
07609 continue;
07610 }
07611 } else {
07612
07613 if (bestscore < 1) {
07614 bestscore = 1;
07615 if (best)
07616 user_unref(best);
07617 best = user;
07618 continue;
07619 }
07620 }
07621 }
07622 }
07623 user_unref(user);
07624 }
07625 ao2_iterator_destroy(&i);
07626 user = best;
07627 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07628 user = realtime_user(iaxs[callno]->username, sin);
07629 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07630 !apply_context(user->contexts, iaxs[callno]->context)) {
07631 user = user_unref(user);
07632 }
07633 }
07634 if (user) {
07635
07636
07637 for (v = user->vars ; v ; v = v->next) {
07638 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07639 tmpvar->next = iaxs[callno]->vars;
07640 iaxs[callno]->vars = tmpvar;
07641 }
07642 }
07643
07644 if (user->maxauthreq > 0)
07645 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07646 iaxs[callno]->prefs = user->prefs;
07647 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07648 iaxs[callno]->encmethods = user->encmethods;
07649
07650 if (ast_strlen_zero(iaxs[callno]->username))
07651 ast_string_field_set(iaxs[callno], username, user->name);
07652
07653 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07654 iaxs[callno]->capability = user->capability;
07655
07656 if (ast_strlen_zero(iaxs[callno]->context)) {
07657 if (user->contexts)
07658 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07659 else
07660 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07661 }
07662
07663 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07664
07665 iaxs[callno]->authmethods = user->authmethods;
07666 iaxs[callno]->adsi = user->adsi;
07667
07668 if (ast_test_flag64(user, IAX_HASCALLERID)) {
07669 iaxs[callno]->calling_tns = 0;
07670 iaxs[callno]->calling_ton = 0;
07671 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07672 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07673 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07674 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07675 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07676 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07677 }
07678 if (!ast_strlen_zero(user->accountcode))
07679 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07680 if (!ast_strlen_zero(user->mohinterpret))
07681 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07682 if (!ast_strlen_zero(user->mohsuggest))
07683 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07684 if (!ast_strlen_zero(user->parkinglot))
07685 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07686 if (user->amaflags)
07687 iaxs[callno]->amaflags = user->amaflags;
07688 if (!ast_strlen_zero(user->language))
07689 ast_string_field_set(iaxs[callno], language, user->language);
07690 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
07691
07692 if (!ast_strlen_zero(user->dbsecret)) {
07693 char *family, *key=NULL;
07694 char buf[80];
07695 family = ast_strdupa(user->dbsecret);
07696 key = strchr(family, '/');
07697 if (key) {
07698 *key = '\0';
07699 key++;
07700 }
07701 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07702 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07703 else
07704 ast_string_field_set(iaxs[callno], secret, buf);
07705 } else
07706 ast_string_field_set(iaxs[callno], secret, user->secret);
07707 res = 0;
07708 user = user_unref(user);
07709 } else {
07710
07711
07712
07713
07714 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07715 ast_string_field_set(iaxs[callno], secret, "badsecret");
07716 iaxs[callno]->authrej = 1;
07717 if (!ast_strlen_zero(iaxs[callno]->username)) {
07718
07719 res = 0;
07720 }
07721 }
07722 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07723 return res;
07724 }
07725
07726 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07727 {
07728 struct ast_iax2_full_hdr fh;
07729 fh.scallno = htons(src | IAX_FLAG_FULL);
07730 fh.dcallno = htons(dst);
07731 fh.ts = 0;
07732 fh.oseqno = 0;
07733 fh.iseqno = 0;
07734 fh.type = AST_FRAME_IAX;
07735 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07736 iax_outputframe(NULL, &fh, 0, sin, 0);
07737 #if 0
07738 if (option_debug)
07739 #endif
07740 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07741 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07742 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07743 }
07744
07745 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07746 {
07747
07748 p->encmethods &= enc;
07749 if (p->encmethods) {
07750 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07751 p->keyrotateid = -2;
07752 }
07753 if (p->encmethods & IAX_ENCRYPT_AES128)
07754 p->encmethods = IAX_ENCRYPT_AES128;
07755 else
07756 p->encmethods = 0;
07757 }
07758 }
07759
07760
07761
07762
07763
07764
07765
07766 static int authenticate_request(int call_num)
07767 {
07768 struct iax_ie_data ied;
07769 int res = -1, authreq_restrict = 0;
07770 char challenge[10];
07771 struct chan_iax2_pvt *p = iaxs[call_num];
07772
07773 memset(&ied, 0, sizeof(ied));
07774
07775
07776 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07777 struct iax2_user *user, tmp_user = {
07778 .name = p->username,
07779 };
07780
07781 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07782 if (user) {
07783 if (user->curauthreq == user->maxauthreq)
07784 authreq_restrict = 1;
07785 else
07786 user->curauthreq++;
07787 user = user_unref(user);
07788 }
07789 }
07790
07791
07792 if (authreq_restrict) {
07793 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07794 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07795 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07796 return 0;
07797 }
07798
07799 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07800 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07801 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07802 ast_string_field_set(p, challenge, challenge);
07803
07804 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07805 }
07806 if (p->encmethods)
07807 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07808
07809 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07810
07811 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07812
07813 if (p->encmethods)
07814 ast_set_flag64(p, IAX_ENCRYPTED);
07815
07816 return res;
07817 }
07818
07819 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07820 {
07821 char requeststr[256];
07822 char md5secret[256] = "";
07823 char secret[256] = "";
07824 char rsasecret[256] = "";
07825 int res = -1;
07826 int x;
07827 struct iax2_user *user, tmp_user = {
07828 .name = p->username,
07829 };
07830
07831 if (p->authrej) {
07832 return res;
07833 }
07834 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07835 if (user) {
07836 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07837 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07838 ast_clear_flag64(p, IAX_MAXAUTHREQ);
07839 }
07840 ast_string_field_set(p, host, user->name);
07841 user = user_unref(user);
07842 }
07843 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07844 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07845 return res;
07846 }
07847 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07848 return res;
07849 if (ies->password)
07850 ast_copy_string(secret, ies->password, sizeof(secret));
07851 if (ies->md5_result)
07852 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07853 if (ies->rsa_result)
07854 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07855 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07856 struct ast_key *key;
07857 char *keyn;
07858 char tmpkey[256];
07859 char *stringp=NULL;
07860 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07861 stringp=tmpkey;
07862 keyn = strsep(&stringp, ":");
07863 while(keyn) {
07864 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07865 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07866 res = 0;
07867 break;
07868 } else if (!key)
07869 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07870 keyn = strsep(&stringp, ":");
07871 }
07872 } else if (p->authmethods & IAX_AUTH_MD5) {
07873 struct MD5Context md5;
07874 unsigned char digest[16];
07875 char *tmppw, *stringp;
07876
07877 tmppw = ast_strdupa(p->secret);
07878 stringp = tmppw;
07879 while((tmppw = strsep(&stringp, ";"))) {
07880 MD5Init(&md5);
07881 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07882 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07883 MD5Final(digest, &md5);
07884
07885 for (x=0;x<16;x++)
07886 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07887 if (!strcasecmp(requeststr, md5secret)) {
07888 res = 0;
07889 break;
07890 }
07891 }
07892 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07893 if (!strcmp(secret, p->secret))
07894 res = 0;
07895 }
07896 return res;
07897 }
07898
07899
07900 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07901 {
07902 char requeststr[256] = "";
07903 char peer[256] = "";
07904 char md5secret[256] = "";
07905 char rsasecret[256] = "";
07906 char secret[256] = "";
07907 struct iax2_peer *p = NULL;
07908 struct ast_key *key;
07909 char *keyn;
07910 int x;
07911 int expire = 0;
07912 int res = -1;
07913 struct ast_sockaddr addr;
07914
07915 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07916
07917 if (ies->username)
07918 ast_copy_string(peer, ies->username, sizeof(peer));
07919 if (ies->password)
07920 ast_copy_string(secret, ies->password, sizeof(secret));
07921 if (ies->md5_result)
07922 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07923 if (ies->rsa_result)
07924 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07925 if (ies->refresh)
07926 expire = ies->refresh;
07927
07928 if (ast_strlen_zero(peer)) {
07929 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07930 return -1;
07931 }
07932
07933
07934 ast_mutex_unlock(&iaxsl[callno]);
07935 p = find_peer(peer, 1);
07936 ast_mutex_lock(&iaxsl[callno]);
07937 if (!p || !iaxs[callno]) {
07938 if (iaxs[callno]) {
07939 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07940
07941 ast_string_field_set(iaxs[callno], secret, "badsecret");
07942
07943
07944
07945
07946
07947
07948
07949
07950
07951 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07952 !(!ast_strlen_zero(secret) && plaintext)) {
07953
07954 res = 0;
07955 }
07956 }
07957 if (authdebug && !p)
07958 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07959 goto return_unref;
07960 }
07961
07962 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
07963 if (authdebug)
07964 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07965 goto return_unref;
07966 }
07967
07968 ast_sockaddr_from_sin(&addr, sin);
07969 if (!ast_apply_ha(p->ha, &addr)) {
07970 if (authdebug)
07971 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07972 goto return_unref;
07973 }
07974 ast_string_field_set(iaxs[callno], secret, p->secret);
07975 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07976
07977 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07978 if (!ast_strlen_zero(p->inkeys)) {
07979 char tmpkeys[256];
07980 char *stringp=NULL;
07981 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07982 stringp=tmpkeys;
07983 keyn = strsep(&stringp, ":");
07984 while(keyn) {
07985 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07986 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07987 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07988 break;
07989 } else if (!key)
07990 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
07991 keyn = strsep(&stringp, ":");
07992 }
07993 if (!keyn) {
07994 if (authdebug)
07995 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
07996 goto return_unref;
07997 }
07998 } else {
07999 if (authdebug)
08000 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08001 goto return_unref;
08002 }
08003 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08004 struct MD5Context md5;
08005 unsigned char digest[16];
08006 char *tmppw, *stringp;
08007
08008 tmppw = ast_strdupa(p->secret);
08009 stringp = tmppw;
08010 while((tmppw = strsep(&stringp, ";"))) {
08011 MD5Init(&md5);
08012 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08013 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08014 MD5Final(digest, &md5);
08015 for (x=0;x<16;x++)
08016 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
08017 if (!strcasecmp(requeststr, md5secret))
08018 break;
08019 }
08020 if (tmppw) {
08021 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08022 } else {
08023 if (authdebug)
08024 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08025 goto return_unref;
08026 }
08027 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08028
08029 if (strcmp(secret, p->secret)) {
08030 if (authdebug)
08031 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08032 goto return_unref;
08033 } else
08034 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08035 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08036
08037 goto return_unref;
08038 }
08039 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08040
08041
08042 res = 0;
08043
08044 return_unref:
08045 if (iaxs[callno]) {
08046 ast_string_field_set(iaxs[callno], peer, peer);
08047
08048
08049 if (expire && (expire < iaxs[callno]->expiry)) {
08050 iaxs[callno]->expiry = expire;
08051 }
08052 }
08053
08054 if (p) {
08055 peer_unref(p);
08056 }
08057 return res;
08058 }
08059
08060 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)
08061 {
08062 int res = -1;
08063 int x;
08064 if (!ast_strlen_zero(keyn)) {
08065 if (!(authmethods & IAX_AUTH_RSA)) {
08066 if (ast_strlen_zero(secret))
08067 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));
08068 } else if (ast_strlen_zero(challenge)) {
08069 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08070 } else {
08071 char sig[256];
08072 struct ast_key *key;
08073 key = ast_key_get(keyn, AST_KEY_PRIVATE);
08074 if (!key) {
08075 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08076 } else {
08077 if (ast_sign(key, (char*)challenge, sig)) {
08078 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08079 res = -1;
08080 } else {
08081 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08082 res = 0;
08083 }
08084 }
08085 }
08086 }
08087
08088 if (res && !ast_strlen_zero(secret)) {
08089 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08090 struct MD5Context md5;
08091 unsigned char digest[16];
08092 char digres[128];
08093 MD5Init(&md5);
08094 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08095 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08096 MD5Final(digest, &md5);
08097
08098 for (x=0;x<16;x++)
08099 sprintf(digres + (x << 1), "%2.2x", digest[x]);
08100 if (pvt) {
08101 build_encryption_keys(digest, pvt);
08102 }
08103 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08104 res = 0;
08105 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08106 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08107 res = 0;
08108 } else
08109 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08110 }
08111 return res;
08112 }
08113
08114
08115
08116
08117
08118 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
08119 {
08120 struct iax2_peer *peer = NULL;
08121
08122 int res = -1;
08123 int authmethods = 0;
08124 struct iax_ie_data ied;
08125 uint16_t callno = p->callno;
08126
08127 memset(&ied, 0, sizeof(ied));
08128
08129 if (ies->username)
08130 ast_string_field_set(p, username, ies->username);
08131 if (ies->challenge)
08132 ast_string_field_set(p, challenge, ies->challenge);
08133 if (ies->authmethods)
08134 authmethods = ies->authmethods;
08135 if (authmethods & IAX_AUTH_MD5)
08136 merge_encryption(p, ies->encmethods);
08137 else
08138 p->encmethods = 0;
08139
08140
08141 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08142
08143 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08144 } else {
08145 struct ao2_iterator i = ao2_iterator_init(peers, 0);
08146 while ((peer = ao2_iterator_next(&i))) {
08147 struct sockaddr_in peer_addr;
08148
08149 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08150
08151 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08152
08153 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08154
08155 && (!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)))
08156
08157 ) {
08158 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08159 if (!res) {
08160 peer_unref(peer);
08161 break;
08162 }
08163 }
08164 peer_unref(peer);
08165 }
08166 ao2_iterator_destroy(&i);
08167 if (!peer) {
08168
08169
08170 const char *peer_name = ast_strdupa(p->peer);
08171 ast_mutex_unlock(&iaxsl[callno]);
08172 if ((peer = realtime_peer(peer_name, NULL))) {
08173 ast_mutex_lock(&iaxsl[callno]);
08174 if (!(p = iaxs[callno])) {
08175 peer_unref(peer);
08176 return -1;
08177 }
08178 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08179 peer_unref(peer);
08180 }
08181 if (!peer) {
08182 ast_mutex_lock(&iaxsl[callno]);
08183 if (!(p = iaxs[callno]))
08184 return -1;
08185 }
08186 }
08187 }
08188
08189 if (ies->encmethods) {
08190 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08191 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08192 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
08193 return -1;
08194 }
08195 if (!res) {
08196 struct ast_datastore *variablestore;
08197 struct ast_variable *var, *prev = NULL;
08198 AST_LIST_HEAD(, ast_var_t) *varlist;
08199 varlist = ast_calloc(1, sizeof(*varlist));
08200 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08201 if (variablestore && varlist && p->owner) {
08202 variablestore->data = varlist;
08203 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08204 AST_LIST_HEAD_INIT(varlist);
08205 for (var = ies->vars; var; var = var->next) {
08206 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08207 if (prev)
08208 ast_free(prev);
08209 prev = var;
08210 if (!newvar) {
08211
08212 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08213 } else {
08214 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08215 }
08216 }
08217 if (prev)
08218 ast_free(prev);
08219 ies->vars = NULL;
08220 ast_channel_datastore_add(p->owner, variablestore);
08221 } else {
08222 if (p->owner)
08223 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08224 if (variablestore)
08225 ast_datastore_free(variablestore);
08226 if (varlist)
08227 ast_free(varlist);
08228 }
08229 }
08230
08231 if (!res)
08232 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08233 return res;
08234 }
08235
08236 static int iax2_do_register(struct iax2_registry *reg);
08237
08238 static void __iax2_do_register_s(const void *data)
08239 {
08240 struct iax2_registry *reg = (struct iax2_registry *)data;
08241 reg->expire = -1;
08242 iax2_do_register(reg);
08243 }
08244
08245 static int iax2_do_register_s(const void *data)
08246 {
08247 #ifdef SCHED_MULTITHREADED
08248 if (schedule_action(__iax2_do_register_s, data))
08249 #endif
08250 __iax2_do_register_s(data);
08251 return 0;
08252 }
08253
08254 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08255 {
08256 int newcall = 0;
08257 char newip[256];
08258 struct iax_ie_data ied;
08259 struct sockaddr_in new;
08260
08261
08262 memset(&ied, 0, sizeof(ied));
08263 if (ies->apparent_addr)
08264 memmove(&new, ies->apparent_addr, sizeof(new));
08265 if (ies->callno)
08266 newcall = ies->callno;
08267 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08268 ast_log(LOG_WARNING, "Invalid transfer request\n");
08269 return -1;
08270 }
08271 pvt->transfercallno = newcall;
08272 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08273 inet_aton(newip, &pvt->transfer.sin_addr);
08274 pvt->transfer.sin_family = AF_INET;
08275 pvt->transferid = ies->transferid;
08276
08277
08278 if (pvt->transferring == TRANSFER_NONE) {
08279 store_by_transfercallno(pvt);
08280 }
08281 pvt->transferring = TRANSFER_BEGIN;
08282
08283 if (ies->transferid)
08284 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08285 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08286 return 0;
08287 }
08288
08289 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08290 {
08291 char exten[256] = "";
08292 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08293 struct iax2_dpcache *dp = NULL;
08294
08295 if (ies->called_number)
08296 ast_copy_string(exten, ies->called_number, sizeof(exten));
08297
08298 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08299 status = CACHE_FLAG_EXISTS;
08300 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08301 status = CACHE_FLAG_CANEXIST;
08302 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08303 status = CACHE_FLAG_NONEXISTENT;
08304
08305 if (ies->refresh)
08306 expiry = ies->refresh;
08307 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08308 matchmore = CACHE_FLAG_MATCHMORE;
08309
08310 AST_LIST_LOCK(&dpcache);
08311 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08312 if (strcmp(dp->exten, exten))
08313 continue;
08314 AST_LIST_REMOVE_CURRENT(peer_list);
08315 dp->callno = 0;
08316 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08317 if (dp->flags & CACHE_FLAG_PENDING) {
08318 dp->flags &= ~CACHE_FLAG_PENDING;
08319 dp->flags |= status;
08320 dp->flags |= matchmore;
08321 }
08322
08323 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08324 if (dp->waiters[x] > -1) {
08325 if (write(dp->waiters[x], "asdf", 4) < 0) {
08326 }
08327 }
08328 }
08329 }
08330 AST_LIST_TRAVERSE_SAFE_END;
08331 AST_LIST_UNLOCK(&dpcache);
08332
08333 return 0;
08334 }
08335
08336 static int complete_transfer(int callno, struct iax_ies *ies)
08337 {
08338 int peercallno = 0;
08339 struct chan_iax2_pvt *pvt = iaxs[callno];
08340 struct iax_frame *cur;
08341 jb_frame frame;
08342
08343 if (ies->callno)
08344 peercallno = ies->callno;
08345
08346 if (peercallno < 1) {
08347 ast_log(LOG_WARNING, "Invalid transfer request\n");
08348 return -1;
08349 }
08350 remove_by_transfercallno(pvt);
08351
08352
08353
08354 peercnt_remove_by_addr(&pvt->addr);
08355 peercnt_add(&pvt->transfer);
08356
08357 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08358 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08359
08360 pvt->oseqno = 0;
08361 pvt->rseqno = 0;
08362 pvt->iseqno = 0;
08363 pvt->aseqno = 0;
08364
08365 if (pvt->peercallno) {
08366 remove_by_peercallno(pvt);
08367 }
08368 pvt->peercallno = peercallno;
08369
08370 store_by_peercallno(pvt);
08371 pvt->transferring = TRANSFER_NONE;
08372 pvt->svoiceformat = -1;
08373 pvt->voiceformat = 0;
08374 pvt->svideoformat = -1;
08375 pvt->videoformat = 0;
08376 pvt->transfercallno = 0;
08377 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08378 memset(&pvt->offset, 0, sizeof(pvt->offset));
08379
08380 while(jb_getall(pvt->jb,&frame) == JB_OK)
08381 iax2_frame_free(frame.data);
08382 jb_reset(pvt->jb);
08383 pvt->lag = 0;
08384 pvt->last = 0;
08385 pvt->lastsent = 0;
08386 pvt->nextpred = 0;
08387 pvt->pingtime = DEFAULT_RETRY_TIME;
08388 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08389
08390
08391
08392 cur->retries = -1;
08393 }
08394 return 0;
08395 }
08396
08397
08398 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08399 {
08400 struct iax2_registry *reg;
08401
08402 char peer[256] = "";
08403 char msgstatus[60];
08404 int refresh = 60;
08405 char ourip[256] = "<Unspecified>";
08406 struct sockaddr_in oldus;
08407 struct sockaddr_in us;
08408 int oldmsgs;
08409 struct sockaddr_in reg_addr;
08410
08411 memset(&us, 0, sizeof(us));
08412 if (ies->apparent_addr)
08413 memmove(&us, ies->apparent_addr, sizeof(us));
08414 if (ies->username)
08415 ast_copy_string(peer, ies->username, sizeof(peer));
08416 if (ies->refresh)
08417 refresh = ies->refresh;
08418 if (ies->calling_number) {
08419
08420 }
08421 reg = iaxs[callno]->reg;
08422 if (!reg) {
08423 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08424 return -1;
08425 }
08426 memcpy(&oldus, ®->us, sizeof(oldus));
08427 oldmsgs = reg->messages;
08428 ast_sockaddr_to_sin(®->addr, ®_addr);
08429 if (inaddrcmp(®_addr, sin)) {
08430 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08431 return -1;
08432 }
08433 memcpy(®->us, &us, sizeof(reg->us));
08434 if (ies->msgcount >= 0)
08435 reg->messages = ies->msgcount & 0xffff;
08436
08437
08438
08439 reg->refresh = refresh;
08440 reg->expire = iax2_sched_replace(reg->expire, sched,
08441 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08442 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08443 if (reg->messages > 255)
08444 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08445 else if (reg->messages > 1)
08446 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
08447 else if (reg->messages > 0)
08448 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
08449 else
08450 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
08451 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08452 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08453 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08454 }
08455 reg->regstate = REG_STATE_REGISTERED;
08456 return 0;
08457 }
08458
08459 static int iax2_append_register(const char *hostname, const char *username,
08460 const char *secret, const char *porta)
08461 {
08462 struct iax2_registry *reg;
08463
08464 if (!(reg = ast_calloc(1, sizeof(*reg))))
08465 return -1;
08466
08467 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08468 ast_free(reg);
08469 return -1;
08470 }
08471
08472 ast_copy_string(reg->username, username, sizeof(reg->username));
08473
08474 if (secret)
08475 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08476
08477 reg->expire = -1;
08478 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08479 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08480
08481 AST_LIST_LOCK(®istrations);
08482 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08483 AST_LIST_UNLOCK(®istrations);
08484
08485 return 0;
08486 }
08487
08488 static int iax2_register(const char *value, int lineno)
08489 {
08490 char copy[256];
08491 char *username, *hostname, *secret;
08492 char *porta;
08493 char *stringp=NULL;
08494
08495 if (!value)
08496 return -1;
08497
08498 ast_copy_string(copy, value, sizeof(copy));
08499 stringp = copy;
08500 username = strsep(&stringp, "@");
08501 hostname = strsep(&stringp, "@");
08502
08503 if (!hostname) {
08504 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08505 return -1;
08506 }
08507
08508 stringp = username;
08509 username = strsep(&stringp, ":");
08510 secret = strsep(&stringp, ":");
08511 stringp = hostname;
08512 hostname = strsep(&stringp, ":");
08513 porta = strsep(&stringp, ":");
08514
08515 if (porta && !atoi(porta)) {
08516 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08517 return -1;
08518 }
08519
08520 return iax2_append_register(hostname, username, secret, porta);
08521 }
08522
08523
08524 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08525 {
08526 char multi[256];
08527 char *stringp, *ext;
08528 if (!ast_strlen_zero(regcontext)) {
08529 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08530 stringp = multi;
08531 while((ext = strsep(&stringp, "&"))) {
08532 if (onoff) {
08533 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08534 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08535 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08536 } else
08537 ast_context_remove_extension(regcontext, ext, 1, NULL);
08538 }
08539 }
08540 }
08541 static void prune_peers(void);
08542
08543 static void unlink_peer(struct iax2_peer *peer)
08544 {
08545 if (peer->expire > -1) {
08546 if (!ast_sched_thread_del(sched, peer->expire)) {
08547 peer->expire = -1;
08548 peer_unref(peer);
08549 }
08550 }
08551
08552 if (peer->pokeexpire > -1) {
08553 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08554 peer->pokeexpire = -1;
08555 peer_unref(peer);
08556 }
08557 }
08558
08559 ao2_unlink(peers, peer);
08560 }
08561
08562 static void __expire_registry(const void *data)
08563 {
08564 struct iax2_peer *peer = (struct iax2_peer *) data;
08565
08566 if (!peer)
08567 return;
08568
08569 peer->expire = -1;
08570
08571 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08572 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08573 realtime_update_peer(peer->name, &peer->addr, 0);
08574 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08575
08576 peercnt_modify(0, 0, &peer->addr);
08577
08578 memset(&peer->addr, 0, sizeof(peer->addr));
08579
08580 peer->expiry = min_reg_expire;
08581 if (!ast_test_flag64(peer, IAX_TEMPONLY))
08582 ast_db_del("IAX/Registry", peer->name);
08583 register_peer_exten(peer, 0);
08584 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08585 if (iax2_regfunk)
08586 iax2_regfunk(peer->name, 0);
08587
08588 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08589 unlink_peer(peer);
08590
08591 peer_unref(peer);
08592 }
08593
08594 static int expire_registry(const void *data)
08595 {
08596 #ifdef SCHED_MULTITHREADED
08597 if (schedule_action(__expire_registry, data))
08598 #endif
08599 __expire_registry(data);
08600 return 0;
08601 }
08602
08603 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08604
08605 static void reg_source_db(struct iax2_peer *p)
08606 {
08607 char data[80];
08608 char *expiry;
08609
08610 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08611 return;
08612 }
08613
08614 expiry = strrchr(data, ':');
08615 if (!expiry) {
08616 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08617 }
08618 *expiry++ = '\0';
08619
08620 if (ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08621 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08622 return;
08623 }
08624
08625 p->expiry = atoi(expiry);
08626
08627 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08628 ast_sockaddr_stringify(&p->addr), p->expiry);
08629
08630 iax2_poke_peer(p, 0);
08631 if (p->expire > -1) {
08632 if (!ast_sched_thread_del(sched, p->expire)) {
08633 p->expire = -1;
08634 peer_unref(p);
08635 }
08636 }
08637
08638 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08639
08640 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08641 if (p->expire == -1) {
08642 peer_unref(p);
08643 }
08644
08645 if (iax2_regfunk) {
08646 iax2_regfunk(p->name, 1);
08647 }
08648
08649 register_peer_exten(p, 1);
08650 }
08651
08652
08653
08654
08655
08656
08657
08658 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08659 {
08660
08661 struct iax_ie_data ied = {
08662 .pos = 0,
08663 };
08664 struct iax2_peer *p;
08665 int msgcount;
08666 char data[80];
08667 int version;
08668 const char *peer_name;
08669 int res = -1;
08670 struct ast_sockaddr sockaddr;
08671
08672 ast_sockaddr_from_sin(&sockaddr, sin);
08673
08674 peer_name = ast_strdupa(iaxs[callno]->peer);
08675
08676
08677 ast_mutex_unlock(&iaxsl[callno]);
08678 if (!(p = find_peer(peer_name, 1))) {
08679 ast_mutex_lock(&iaxsl[callno]);
08680 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08681 return -1;
08682 }
08683 ast_mutex_lock(&iaxsl[callno]);
08684 if (!iaxs[callno])
08685 goto return_unref;
08686
08687 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08688 if (sin->sin_addr.s_addr) {
08689 time_t nowtime;
08690 time(&nowtime);
08691 realtime_update_peer(peer_name, &sockaddr, nowtime);
08692 } else {
08693 realtime_update_peer(peer_name, &sockaddr, 0);
08694 }
08695 }
08696
08697 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08698 if (iax2_regfunk) {
08699 iax2_regfunk(p->name, 1);
08700 }
08701
08702
08703 peercnt_modify(0, 0, &p->addr);
08704
08705
08706 ast_sockaddr_from_sin(&p->addr, sin);
08707
08708 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08709 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08710 ast_db_put("IAX/Registry", p->name, data);
08711 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08712 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08713 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08714 register_peer_exten(p, 1);
08715 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08716 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08717 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08718 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08719 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08720 register_peer_exten(p, 0);
08721 ast_db_del("IAX/Registry", p->name);
08722 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08723 }
08724
08725
08726 iax2_poke_peer(p, callno);
08727 }
08728
08729
08730 if (p->maxcallno) {
08731 peercnt_modify(1, p->maxcallno, &p->addr);
08732 }
08733
08734
08735 if (!iaxs[callno]) {
08736 res = -1;
08737 goto return_unref;
08738 }
08739
08740
08741 p->sockfd = fd;
08742
08743 if (p->expire > -1) {
08744 if (!ast_sched_thread_del(sched, p->expire)) {
08745 p->expire = -1;
08746 peer_unref(p);
08747 }
08748 }
08749
08750 if (!refresh)
08751 refresh = min_reg_expire;
08752 if (refresh > max_reg_expire) {
08753 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08754 p->name, max_reg_expire, refresh);
08755 p->expiry = max_reg_expire;
08756 } else if (refresh < min_reg_expire) {
08757 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08758 p->name, min_reg_expire, refresh);
08759 p->expiry = min_reg_expire;
08760 } else {
08761 p->expiry = refresh;
08762 }
08763 if (p->expiry && sin->sin_addr.s_addr) {
08764 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08765 if (p->expire == -1)
08766 peer_unref(p);
08767 }
08768 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08769 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08770 if (sin->sin_addr.s_addr) {
08771 struct sockaddr_in peer_addr;
08772
08773 ast_sockaddr_to_sin(&p->addr, &peer_addr);
08774
08775 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08776 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08777 if (!ast_strlen_zero(p->mailbox)) {
08778 struct ast_event *event;
08779 int new, old;
08780 char *mailbox, *context;
08781
08782 context = mailbox = ast_strdupa(p->mailbox);
08783 strsep(&context, "@");
08784 if (ast_strlen_zero(context))
08785 context = "default";
08786
08787 event = ast_event_get_cached(AST_EVENT_MWI,
08788 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08789 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08790 AST_EVENT_IE_END);
08791 if (event) {
08792 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08793 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08794 ast_event_destroy(event);
08795 } else {
08796 ast_app_inboxcount(p->mailbox, &new, &old);
08797 }
08798
08799 if (new > 255) {
08800 new = 255;
08801 }
08802 if (old > 255) {
08803 old = 255;
08804 }
08805 msgcount = (old << 8) | new;
08806
08807 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08808 }
08809 if (ast_test_flag64(p, IAX_HASCALLERID)) {
08810 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08811 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08812 }
08813 }
08814 version = iax_check_version(devtype);
08815 if (version)
08816 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08817
08818 res = 0;
08819
08820 return_unref:
08821 peer_unref(p);
08822
08823 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08824 }
08825
08826 static int registry_authrequest(int callno)
08827 {
08828 struct iax_ie_data ied;
08829 struct iax2_peer *p;
08830 char challenge[10];
08831 const char *peer_name;
08832 int sentauthmethod;
08833
08834 peer_name = ast_strdupa(iaxs[callno]->peer);
08835
08836
08837 ast_mutex_unlock(&iaxsl[callno]);
08838 if ((p = find_peer(peer_name, 1))) {
08839 last_authmethod = p->authmethods;
08840 }
08841
08842 ast_mutex_lock(&iaxsl[callno]);
08843 if (!iaxs[callno])
08844 goto return_unref;
08845
08846 memset(&ied, 0, sizeof(ied));
08847
08848
08849
08850
08851
08852
08853 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08854 if (!p) {
08855 iaxs[callno]->authmethods = sentauthmethod;
08856 }
08857 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08858 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08859
08860 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08861 ast_string_field_set(iaxs[callno], challenge, challenge);
08862 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08863 }
08864 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08865
08866 return_unref:
08867 if (p) {
08868 peer_unref(p);
08869 }
08870
08871 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08872 }
08873
08874 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08875 {
08876 struct iax2_registry *reg;
08877
08878 struct iax_ie_data ied;
08879 char peer[256] = "";
08880 char challenge[256] = "";
08881 int res;
08882 int authmethods = 0;
08883 if (ies->authmethods)
08884 authmethods = ies->authmethods;
08885 if (ies->username)
08886 ast_copy_string(peer, ies->username, sizeof(peer));
08887 if (ies->challenge)
08888 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08889 memset(&ied, 0, sizeof(ied));
08890 reg = iaxs[callno]->reg;
08891 if (reg) {
08892 struct sockaddr_in reg_addr;
08893
08894 ast_sockaddr_to_sin(®->addr, ®_addr);
08895
08896 if (inaddrcmp(®_addr, sin)) {
08897 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08898 return -1;
08899 }
08900 if (ast_strlen_zero(reg->secret)) {
08901 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08902 reg->regstate = REG_STATE_NOAUTH;
08903 return -1;
08904 }
08905 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08906 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08907 if (reg->secret[0] == '[') {
08908 char tmpkey[256];
08909 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08910 tmpkey[strlen(tmpkey) - 1] = '\0';
08911 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08912 } else
08913 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08914 if (!res) {
08915 reg->regstate = REG_STATE_AUTHSENT;
08916 add_empty_calltoken_ie(iaxs[callno], &ied);
08917 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08918 } else
08919 return -1;
08920 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08921 } else
08922 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08923 return -1;
08924 }
08925
08926 static void stop_stuff(int callno)
08927 {
08928 iax2_destroy_helper(iaxs[callno]);
08929 }
08930
08931 static void __auth_reject(const void *nothing)
08932 {
08933
08934 int callno = (int)(long)(nothing);
08935 struct iax_ie_data ied;
08936 ast_mutex_lock(&iaxsl[callno]);
08937 if (iaxs[callno]) {
08938 memset(&ied, 0, sizeof(ied));
08939 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08940 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08941 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08942 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08943 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08944 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08945 }
08946 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08947 }
08948 ast_mutex_unlock(&iaxsl[callno]);
08949 }
08950
08951 static int auth_reject(const void *data)
08952 {
08953 int callno = (int)(long)(data);
08954 ast_mutex_lock(&iaxsl[callno]);
08955 if (iaxs[callno])
08956 iaxs[callno]->authid = -1;
08957 ast_mutex_unlock(&iaxsl[callno]);
08958 #ifdef SCHED_MULTITHREADED
08959 if (schedule_action(__auth_reject, data))
08960 #endif
08961 __auth_reject(data);
08962 return 0;
08963 }
08964
08965 static int auth_fail(int callno, int failcode)
08966 {
08967
08968
08969 if (iaxs[callno]) {
08970 iaxs[callno]->authfail = failcode;
08971 if (delayreject) {
08972 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08973 sched, 1000, auth_reject, (void *)(long)callno);
08974 } else
08975 auth_reject((void *)(long)callno);
08976 }
08977 return 0;
08978 }
08979
08980 static void __auto_hangup(const void *nothing)
08981 {
08982
08983 int callno = (int)(long)(nothing);
08984 struct iax_ie_data ied;
08985 ast_mutex_lock(&iaxsl[callno]);
08986 if (iaxs[callno]) {
08987 memset(&ied, 0, sizeof(ied));
08988 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08989 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
08990 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
08991 }
08992 ast_mutex_unlock(&iaxsl[callno]);
08993 }
08994
08995 static int auto_hangup(const void *data)
08996 {
08997 int callno = (int)(long)(data);
08998 ast_mutex_lock(&iaxsl[callno]);
08999 if (iaxs[callno]) {
09000 iaxs[callno]->autoid = -1;
09001 }
09002 ast_mutex_unlock(&iaxsl[callno]);
09003 #ifdef SCHED_MULTITHREADED
09004 if (schedule_action(__auto_hangup, data))
09005 #endif
09006 __auto_hangup(data);
09007 return 0;
09008 }
09009
09010 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
09011 {
09012 struct iax_ie_data ied;
09013
09014 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
09015 sched, 30000, auto_hangup, (void *)(long)callno);
09016 memset(&ied, 0, sizeof(ied));
09017 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09018 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09019 dp->flags |= CACHE_FLAG_TRANSMITTED;
09020 }
09021
09022 static int iax2_vnak(int callno)
09023 {
09024 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09025 }
09026
09027 static void vnak_retransmit(int callno, int last)
09028 {
09029 struct iax_frame *f;
09030
09031 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09032
09033 if (((unsigned char) (f->oseqno - last) < 128) &&
09034 (f->retries >= 0)) {
09035 send_packet(f);
09036 }
09037 }
09038 }
09039
09040 static void __iax2_poke_peer_s(const void *data)
09041 {
09042 struct iax2_peer *peer = (struct iax2_peer *)data;
09043 iax2_poke_peer(peer, 0);
09044 peer_unref(peer);
09045 }
09046
09047 static int iax2_poke_peer_s(const void *data)
09048 {
09049 struct iax2_peer *peer = (struct iax2_peer *)data;
09050 peer->pokeexpire = -1;
09051 #ifdef SCHED_MULTITHREADED
09052 if (schedule_action(__iax2_poke_peer_s, data))
09053 #endif
09054 __iax2_poke_peer_s(data);
09055 return 0;
09056 }
09057
09058 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
09059 {
09060 int res = 0;
09061 struct iax_frame *fr;
09062 struct ast_iax2_meta_hdr *meta;
09063 struct ast_iax2_meta_trunk_hdr *mth;
09064 int calls = 0;
09065
09066
09067 fr = (struct iax_frame *)tpeer->trunkdata;
09068
09069 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09070 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09071 if (tpeer->trunkdatalen) {
09072
09073 meta->zeros = 0;
09074 meta->metacmd = IAX_META_TRUNK;
09075 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09076 meta->cmddata = IAX_META_TRUNK_MINI;
09077 else
09078 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09079 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09080
09081 fr->direction = DIRECTION_OUTGRESS;
09082 fr->retrans = -1;
09083 fr->transfer = 0;
09084
09085 fr->data = fr->afdata;
09086 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09087 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09088 calls = tpeer->calls;
09089 #if 0
09090 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));
09091 #endif
09092
09093 tpeer->trunkdatalen = 0;
09094 tpeer->calls = 0;
09095 }
09096 if (res < 0)
09097 return res;
09098 return calls;
09099 }
09100
09101 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
09102 {
09103
09104 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
09105 return 1;
09106 return 0;
09107 }
09108
09109 static int timing_read(int *id, int fd, short events, void *cbdata)
09110 {
09111 int res, processed = 0, totalcalls = 0;
09112 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09113 struct timeval now = ast_tvnow();
09114
09115 if (iaxtrunkdebug)
09116 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09117
09118 if (timer) {
09119 ast_timer_ack(timer, 1);
09120 }
09121
09122
09123 AST_LIST_LOCK(&tpeers);
09124 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09125 processed++;
09126 res = 0;
09127 ast_mutex_lock(&tpeer->lock);
09128
09129
09130 if (!drop && iax2_trunk_expired(tpeer, &now)) {
09131
09132
09133 AST_LIST_REMOVE_CURRENT(list);
09134 drop = tpeer;
09135 } else {
09136 res = send_trunk(tpeer, &now);
09137 trunk_timed++;
09138 if (iaxtrunkdebug)
09139 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
09140 }
09141 totalcalls += res;
09142 res = 0;
09143 ast_mutex_unlock(&tpeer->lock);
09144 }
09145 AST_LIST_TRAVERSE_SAFE_END;
09146 AST_LIST_UNLOCK(&tpeers);
09147
09148 if (drop) {
09149 ast_mutex_lock(&drop->lock);
09150
09151
09152 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09153 if (drop->trunkdata) {
09154 ast_free(drop->trunkdata);
09155 drop->trunkdata = NULL;
09156 }
09157 ast_mutex_unlock(&drop->lock);
09158 ast_mutex_destroy(&drop->lock);
09159 ast_free(drop);
09160
09161 }
09162
09163 if (iaxtrunkdebug)
09164 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09165 iaxtrunkdebug = 0;
09166
09167 return 1;
09168 }
09169
09170 struct dpreq_data {
09171 int callno;
09172 char context[AST_MAX_EXTENSION];
09173 char callednum[AST_MAX_EXTENSION];
09174 char *callerid;
09175 };
09176
09177 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
09178 {
09179 unsigned short dpstatus = 0;
09180 struct iax_ie_data ied1;
09181 int mm;
09182
09183 memset(&ied1, 0, sizeof(ied1));
09184 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09185
09186 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09187 dpstatus = IAX_DPSTATUS_EXISTS;
09188 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09189 dpstatus = IAX_DPSTATUS_CANEXIST;
09190 } else {
09191 dpstatus = IAX_DPSTATUS_NONEXISTENT;
09192 }
09193 if (ast_ignore_pattern(context, callednum))
09194 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09195 if (mm)
09196 dpstatus |= IAX_DPSTATUS_MATCHMORE;
09197 if (!skiplock)
09198 ast_mutex_lock(&iaxsl[callno]);
09199 if (iaxs[callno]) {
09200 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09201 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09202 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09203 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09204 }
09205 if (!skiplock)
09206 ast_mutex_unlock(&iaxsl[callno]);
09207 }
09208
09209 static void *dp_lookup_thread(void *data)
09210 {
09211
09212 struct dpreq_data *dpr = data;
09213 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09214 if (dpr->callerid)
09215 ast_free(dpr->callerid);
09216 ast_free(dpr);
09217 return NULL;
09218 }
09219
09220 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
09221 {
09222 pthread_t newthread;
09223 struct dpreq_data *dpr;
09224
09225 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09226 return;
09227
09228 dpr->callno = callno;
09229 ast_copy_string(dpr->context, context, sizeof(dpr->context));
09230 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09231 if (callerid)
09232 dpr->callerid = ast_strdup(callerid);
09233 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09234 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09235 }
09236 }
09237
09238 struct iax_dual {
09239 struct ast_channel *chan1;
09240 struct ast_channel *chan2;
09241 const char *parkexten;
09242 };
09243
09244 static void *iax_park_thread(void *stuff)
09245 {
09246 struct ast_channel *chan1, *chan2;
09247 struct iax_dual *d;
09248 struct ast_frame *f;
09249 int ext;
09250 int res;
09251 d = stuff;
09252 chan1 = d->chan1;
09253 chan2 = d->chan2;
09254 ast_free(d);
09255 f = ast_read(chan1);
09256 if (f)
09257 ast_frfree(f);
09258 res = ast_park_call(chan1, chan2, 0, d->parkexten, &ext);
09259 ast_hangup(chan2);
09260 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09261 return NULL;
09262 }
09263
09264 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *parkexten)
09265 {
09266 struct iax_dual *d;
09267 struct ast_channel *chan1m, *chan2m;
09268 pthread_t th;
09269 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09270 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09271 if (chan2m && chan1m) {
09272
09273 chan1m->readformat = chan1->readformat;
09274 chan1m->writeformat = chan1->writeformat;
09275 ast_channel_masquerade(chan1m, chan1);
09276
09277 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09278 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09279 chan1m->priority = chan1->priority;
09280
09281
09282
09283
09284 chan2m->readformat = chan2->readformat;
09285 chan2m->writeformat = chan2->writeformat;
09286 ast_channel_masquerade(chan2m, chan2);
09287
09288 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09289 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09290 chan2m->priority = chan2->priority;
09291 if (ast_do_masquerade(chan2m)) {
09292 ast_log(LOG_WARNING, "Masquerade failed :(\n");
09293 ast_hangup(chan2m);
09294 return -1;
09295 }
09296 } else {
09297 if (chan1m)
09298 ast_hangup(chan1m);
09299 if (chan2m)
09300 ast_hangup(chan2m);
09301 return -1;
09302 }
09303 if ((d = ast_calloc(1, sizeof(*d)))) {
09304 d->chan1 = chan1m;
09305 d->chan2 = chan2m;
09306 d->parkexten = parkexten;
09307 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
09308 return 0;
09309 }
09310 ast_free(d);
09311 }
09312 return -1;
09313 }
09314
09315 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09316 {
09317 unsigned int ourver;
09318 char rsi[80];
09319 snprintf(rsi, sizeof(rsi), "si-%s", si);
09320 if (iax_provision_version(&ourver, rsi, 1))
09321 return 0;
09322 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09323 if (ourver != ver)
09324 iax2_provision(sin, sockfd, NULL, rsi, 1);
09325 return 0;
09326 }
09327
09328 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09329 {
09330 jb_info stats;
09331 jb_getinfo(pvt->jb, &stats);
09332
09333 memset(iep, 0, sizeof(*iep));
09334
09335 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09336 if(stats.frames_in == 0) stats.frames_in = 1;
09337 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09338 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09339 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09340 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09341 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09342 }
09343
09344 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09345 {
09346 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09347 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09348 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09349 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09350 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09351 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09352 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09353 }
09354
09355 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09356 {
09357 int i;
09358 unsigned int length, offset = 0;
09359 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09360
09361 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09362 length = ies->ospblocklength[i];
09363 if (length != 0) {
09364 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09365
09366 offset = 0;
09367 break;
09368 } else {
09369 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09370 offset += length;
09371 }
09372 } else {
09373 break;
09374 }
09375 }
09376 *(full_osptoken + offset) = '\0';
09377 if (strlen(full_osptoken) != offset) {
09378
09379 *full_osptoken = '\0';
09380 }
09381
09382 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09383 }
09384
09385 static void log_jitterstats(unsigned short callno)
09386 {
09387 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09388 jb_info jbinfo;
09389
09390 ast_mutex_lock(&iaxsl[callno]);
09391 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09392 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09393 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09394 localjitter = jbinfo.jitter;
09395 localdelay = jbinfo.current - jbinfo.min;
09396 locallost = jbinfo.frames_lost;
09397 locallosspct = jbinfo.losspct/1000;
09398 localdropped = jbinfo.frames_dropped;
09399 localooo = jbinfo.frames_ooo;
09400 localpackets = jbinfo.frames_in;
09401 }
09402 ast_debug(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n",
09403 iaxs[callno]->owner->name,
09404 iaxs[callno]->pingtime,
09405 localjitter,
09406 localdelay,
09407 locallost,
09408 locallosspct,
09409 localdropped,
09410 localooo,
09411 localpackets,
09412 iaxs[callno]->remote_rr.jitter,
09413 iaxs[callno]->remote_rr.delay,
09414 iaxs[callno]->remote_rr.losscnt,
09415 iaxs[callno]->remote_rr.losspct/1000,
09416 iaxs[callno]->remote_rr.dropped,
09417 iaxs[callno]->remote_rr.ooo,
09418 iaxs[callno]->remote_rr.packets);
09419 manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n",
09420 iaxs[callno]->owner->name,
09421 iaxs[callno]->pingtime,
09422 localjitter,
09423 localdelay,
09424 locallost,
09425 locallosspct,
09426 localdropped,
09427 localooo,
09428 localpackets,
09429 iaxs[callno]->remote_rr.jitter,
09430 iaxs[callno]->remote_rr.delay,
09431 iaxs[callno]->remote_rr.losscnt,
09432 iaxs[callno]->remote_rr.losspct/1000,
09433 iaxs[callno]->remote_rr.dropped,
09434 iaxs[callno]->remote_rr.ooo,
09435 iaxs[callno]->remote_rr.packets);
09436 }
09437 ast_mutex_unlock(&iaxsl[callno]);
09438 }
09439
09440 static int socket_process(struct iax2_thread *thread);
09441
09442
09443
09444
09445 static void handle_deferred_full_frames(struct iax2_thread *thread)
09446 {
09447 struct iax2_pkt_buf *pkt_buf;
09448
09449 ast_mutex_lock(&thread->lock);
09450
09451 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09452 ast_mutex_unlock(&thread->lock);
09453
09454 thread->buf = pkt_buf->buf;
09455 thread->buf_len = pkt_buf->len;
09456 thread->buf_size = pkt_buf->len + 1;
09457
09458 socket_process(thread);
09459
09460 thread->buf = NULL;
09461 ast_free(pkt_buf);
09462
09463 ast_mutex_lock(&thread->lock);
09464 }
09465
09466 ast_mutex_unlock(&thread->lock);
09467 }
09468
09469
09470
09471
09472
09473
09474
09475 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09476 {
09477 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09478 struct ast_iax2_full_hdr *fh, *cur_fh;
09479
09480 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09481 return;
09482
09483 pkt_buf->len = from_here->buf_len;
09484 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09485
09486 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09487 ast_mutex_lock(&to_here->lock);
09488 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09489 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09490 if (fh->oseqno < cur_fh->oseqno) {
09491 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09492 break;
09493 }
09494 }
09495 AST_LIST_TRAVERSE_SAFE_END
09496
09497 if (!cur_pkt_buf)
09498 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09499
09500 ast_mutex_unlock(&to_here->lock);
09501 }
09502
09503 static int socket_read(int *id, int fd, short events, void *cbdata)
09504 {
09505 struct iax2_thread *thread;
09506 socklen_t len;
09507 time_t t;
09508 static time_t last_errtime = 0;
09509 struct ast_iax2_full_hdr *fh;
09510
09511 if (!(thread = find_idle_thread())) {
09512 time(&t);
09513 if (t != last_errtime)
09514 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09515 last_errtime = t;
09516 usleep(1);
09517 return 1;
09518 }
09519
09520 len = sizeof(thread->iosin);
09521 thread->iofd = fd;
09522 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09523 thread->buf_size = sizeof(thread->readbuf);
09524 thread->buf = thread->readbuf;
09525 if (thread->buf_len < 0) {
09526 if (errno != ECONNREFUSED && errno != EAGAIN)
09527 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09528 handle_error();
09529 thread->iostate = IAX_IOSTATE_IDLE;
09530 signal_condition(&thread->lock, &thread->cond);
09531 return 1;
09532 }
09533 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09534 thread->iostate = IAX_IOSTATE_IDLE;
09535 signal_condition(&thread->lock, &thread->cond);
09536 return 1;
09537 }
09538
09539
09540
09541
09542 fh = (struct ast_iax2_full_hdr *) thread->buf;
09543 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09544 struct iax2_thread *cur = NULL;
09545 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09546
09547 AST_LIST_LOCK(&active_list);
09548 AST_LIST_TRAVERSE(&active_list, cur, list) {
09549 if ((cur->ffinfo.callno == callno) &&
09550 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09551 break;
09552 }
09553 if (cur) {
09554
09555
09556 defer_full_frame(thread, cur);
09557 AST_LIST_UNLOCK(&active_list);
09558 thread->iostate = IAX_IOSTATE_IDLE;
09559 signal_condition(&thread->lock, &thread->cond);
09560 return 1;
09561 } else {
09562
09563 thread->ffinfo.callno = callno;
09564 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09565 thread->ffinfo.type = fh->type;
09566 thread->ffinfo.csub = fh->csub;
09567 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09568 }
09569 AST_LIST_UNLOCK(&active_list);
09570 }
09571
09572
09573 thread->iostate = IAX_IOSTATE_READY;
09574 #ifdef DEBUG_SCHED_MULTITHREAD
09575 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09576 #endif
09577 signal_condition(&thread->lock, &thread->cond);
09578
09579 return 1;
09580 }
09581
09582 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09583 struct iax_frame *fr)
09584 {
09585 unsigned char metatype;
09586 struct ast_iax2_meta_trunk_mini *mtm;
09587 struct ast_iax2_meta_trunk_hdr *mth;
09588 struct ast_iax2_meta_trunk_entry *mte;
09589 struct iax2_trunk_peer *tpeer;
09590 unsigned int ts;
09591 void *ptr;
09592 struct timeval rxtrunktime;
09593 struct ast_frame f = { 0, };
09594
09595 if (packet_len < sizeof(*meta)) {
09596 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09597 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09598 return 1;
09599 }
09600
09601 if (meta->metacmd != IAX_META_TRUNK)
09602 return 1;
09603
09604 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09605 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09606 (int) (sizeof(*meta) + sizeof(*mth)));
09607 return 1;
09608 }
09609 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09610 ts = ntohl(mth->ts);
09611 metatype = meta->cmddata;
09612 packet_len -= (sizeof(*meta) + sizeof(*mth));
09613 ptr = mth->data;
09614 tpeer = find_tpeer(sin, sockfd);
09615 if (!tpeer) {
09616 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09617 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09618 return 1;
09619 }
09620 tpeer->trunkact = ast_tvnow();
09621 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09622 tpeer->rxtrunktime = tpeer->trunkact;
09623 rxtrunktime = tpeer->rxtrunktime;
09624 ast_mutex_unlock(&tpeer->lock);
09625 while (packet_len >= sizeof(*mte)) {
09626
09627 unsigned short callno, trunked_ts, len;
09628
09629 if (metatype == IAX_META_TRUNK_MINI) {
09630 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09631 ptr += sizeof(*mtm);
09632 packet_len -= sizeof(*mtm);
09633 len = ntohs(mtm->len);
09634 callno = ntohs(mtm->mini.callno);
09635 trunked_ts = ntohs(mtm->mini.ts);
09636 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09637 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09638 ptr += sizeof(*mte);
09639 packet_len -= sizeof(*mte);
09640 len = ntohs(mte->len);
09641 callno = ntohs(mte->callno);
09642 trunked_ts = 0;
09643 } else {
09644 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09645 break;
09646 }
09647
09648 if (len > packet_len)
09649 break;
09650 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09651 if (!fr->callno)
09652 continue;
09653
09654
09655
09656
09657 memset(&f, 0, sizeof(f));
09658 f.frametype = AST_FRAME_VOICE;
09659 if (!iaxs[fr->callno]) {
09660
09661 } else if (iaxs[fr->callno]->voiceformat == 0) {
09662 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09663 iax2_vnak(fr->callno);
09664 } else {
09665 f.subclass.codec = iaxs[fr->callno]->voiceformat;
09666 f.datalen = len;
09667 if (f.datalen >= 0) {
09668 if (f.datalen)
09669 f.data.ptr = ptr;
09670 else
09671 f.data.ptr = NULL;
09672 if (trunked_ts)
09673 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09674 else
09675 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09676
09677 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09678 struct iax_frame *duped_fr;
09679
09680
09681 f.src = "IAX2";
09682 f.mallocd = 0;
09683 f.offset = 0;
09684 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09685 f.samples = ast_codec_get_samples(&f);
09686 else
09687 f.samples = 0;
09688 fr->outoforder = 0;
09689 iax_frame_wrap(fr, &f);
09690 duped_fr = iaxfrdup2(fr);
09691 if (duped_fr)
09692 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09693 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09694 iaxs[fr->callno]->last = fr->ts;
09695 }
09696 } else {
09697 ast_log(LOG_WARNING, "Datalen < 0?\n");
09698 }
09699 }
09700 ast_mutex_unlock(&iaxsl[fr->callno]);
09701 ptr += len;
09702 packet_len -= len;
09703 }
09704
09705 return 1;
09706 }
09707
09708 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09709 {
09710 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09711 AST_LIST_HEAD(, ast_var_t) *varlist;
09712 struct ast_var_t *var;
09713
09714 if (!variablestore) {
09715 *buf = '\0';
09716 return 0;
09717 }
09718 varlist = variablestore->data;
09719
09720 AST_LIST_LOCK(varlist);
09721 AST_LIST_TRAVERSE(varlist, var, entries) {
09722 if (strcmp(var->name, data) == 0) {
09723 ast_copy_string(buf, var->value, len);
09724 break;
09725 }
09726 }
09727 AST_LIST_UNLOCK(varlist);
09728 return 0;
09729 }
09730
09731 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09732 {
09733 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09734 AST_LIST_HEAD(, ast_var_t) *varlist;
09735 struct ast_var_t *var;
09736
09737 if (!variablestore) {
09738 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09739 if (!variablestore) {
09740 ast_log(LOG_ERROR, "Memory allocation error\n");
09741 return -1;
09742 }
09743 varlist = ast_calloc(1, sizeof(*varlist));
09744 if (!varlist) {
09745 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09746 return -1;
09747 }
09748
09749 AST_LIST_HEAD_INIT(varlist);
09750 variablestore->data = varlist;
09751 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09752 ast_channel_datastore_add(chan, variablestore);
09753 } else
09754 varlist = variablestore->data;
09755
09756 AST_LIST_LOCK(varlist);
09757 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09758 if (strcmp(var->name, data) == 0) {
09759 AST_LIST_REMOVE_CURRENT(entries);
09760 ast_var_delete(var);
09761 break;
09762 }
09763 }
09764 AST_LIST_TRAVERSE_SAFE_END;
09765 var = ast_var_assign(data, value);
09766 if (var)
09767 AST_LIST_INSERT_TAIL(varlist, var, entries);
09768 else
09769 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09770 AST_LIST_UNLOCK(varlist);
09771 return 0;
09772 }
09773
09774 static struct ast_custom_function iaxvar_function = {
09775 .name = "IAXVAR",
09776 .read = acf_iaxvar_read,
09777 .write = acf_iaxvar_write,
09778 };
09779
09780 static void set_hangup_source_and_cause(int callno, unsigned char causecode)
09781 {
09782 iax2_lock_owner(callno);
09783 if (iaxs[callno] && iaxs[callno]->owner) {
09784 if (causecode) {
09785 iaxs[callno]->owner->hangupcause = causecode;
09786 }
09787 ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
09788 ast_channel_unlock(iaxs[callno]->owner);
09789 }
09790 }
09791
09792 static int socket_process(struct iax2_thread *thread)
09793 {
09794 struct sockaddr_in sin;
09795 int res;
09796 int updatehistory=1;
09797 int new = NEW_PREVENT;
09798 int dcallno = 0;
09799 char decrypted = 0;
09800 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09801 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09802 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09803 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09804 struct iax_frame *fr;
09805 struct iax_frame *cur;
09806 struct ast_frame f = { 0, };
09807 struct ast_channel *c = NULL;
09808 struct iax2_dpcache *dp;
09809 struct iax2_peer *peer;
09810 struct iax_ies ies;
09811 struct iax_ie_data ied0, ied1;
09812 format_t format;
09813 int fd;
09814 int exists;
09815 int minivid = 0;
09816 char empty[32]="";
09817 struct iax_frame *duped_fr;
09818 char host_pref_buf[128];
09819 char caller_pref_buf[128];
09820 struct ast_codec_pref pref;
09821 char *using_prefs = "mine";
09822
09823
09824 fr = alloca(sizeof(*fr) + 4096);
09825 memset(fr, 0, sizeof(*fr));
09826 fr->afdatalen = 4096;
09827
09828
09829 res = thread->buf_len;
09830 fd = thread->iofd;
09831 memcpy(&sin, &thread->iosin, sizeof(sin));
09832
09833 if (res < sizeof(*mh)) {
09834 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09835 return 1;
09836 }
09837 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09838 if (res < sizeof(*vh)) {
09839 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));
09840 return 1;
09841 }
09842
09843
09844 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09845 minivid = 1;
09846 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09847 return socket_process_meta(res, meta, &sin, fd, fr);
09848
09849 #ifdef DEBUG_SUPPORT
09850 if (res >= sizeof(*fh))
09851 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09852 #endif
09853 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09854 if (res < sizeof(*fh)) {
09855 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));
09856 return 1;
09857 }
09858
09859
09860 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09861
09862
09863
09864
09865
09866
09867 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09868 ast_mutex_lock(&iaxsl[fr->callno]);
09869 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
09870 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09871 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09872 ast_mutex_unlock(&iaxsl[fr->callno]);
09873 return 1;
09874 }
09875 decrypted = 1;
09876 }
09877 ast_mutex_unlock(&iaxsl[fr->callno]);
09878 }
09879
09880
09881 f.frametype = fh->type;
09882 if (f.frametype == AST_FRAME_VIDEO) {
09883 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09884 } else if (f.frametype == AST_FRAME_VOICE) {
09885 f.subclass.codec = uncompress_subclass(fh->csub);
09886 } else {
09887 f.subclass.integer = uncompress_subclass(fh->csub);
09888 }
09889
09890
09891 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
09892
09893 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09894 return 1;
09895 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
09896
09897 return 1;
09898 }
09899
09900 f.datalen = res - sizeof(*fh);
09901 if (f.datalen) {
09902 if (f.frametype == AST_FRAME_IAX) {
09903 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09904 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09905 ast_variables_destroy(ies.vars);
09906 return 1;
09907 }
09908 f.data.ptr = NULL;
09909 f.datalen = 0;
09910 } else {
09911 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09912 memset(&ies, 0, sizeof(ies));
09913 }
09914 } else {
09915 if (f.frametype == AST_FRAME_IAX)
09916 f.data.ptr = NULL;
09917 else
09918 f.data.ptr = empty;
09919 memset(&ies, 0, sizeof(ies));
09920 }
09921
09922 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
09923
09924 if (handle_call_token(fh, &ies, &sin, fd)) {
09925 ast_variables_destroy(ies.vars);
09926 return 1;
09927 }
09928
09929 if (ies.calltoken && ies.calltokendata) {
09930
09931
09932
09933
09934 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09935 } else {
09936 new = NEW_ALLOW;
09937 }
09938 }
09939 } else {
09940
09941 f.frametype = AST_FRAME_NULL;
09942 f.subclass.integer = 0;
09943 memset(&ies, 0, sizeof(ies));
09944 }
09945
09946 if (!fr->callno) {
09947 int check_dcallno = 0;
09948
09949
09950
09951
09952
09953
09954
09955
09956
09957 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
09958 check_dcallno = 1;
09959 }
09960
09961 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09962 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
09963 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09964 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
09965 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09966 }
09967 ast_variables_destroy(ies.vars);
09968 return 1;
09969 }
09970 }
09971
09972 if (fr->callno > 0)
09973 ast_mutex_lock(&iaxsl[fr->callno]);
09974
09975 if (!fr->callno || !iaxs[fr->callno]) {
09976
09977
09978 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09979
09980 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
09981 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
09982 (f.subclass.integer != IAX_COMMAND_TXACC) &&
09983 (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
09984 (f.frametype != AST_FRAME_IAX))
09985 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09986 fd);
09987 }
09988 if (fr->callno > 0)
09989 ast_mutex_unlock(&iaxsl[fr->callno]);
09990 ast_variables_destroy(ies.vars);
09991 return 1;
09992 }
09993 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
09994 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09995 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09996 ast_variables_destroy(ies.vars);
09997 ast_mutex_unlock(&iaxsl[fr->callno]);
09998 return 1;
09999 }
10000 decrypted = 1;
10001 }
10002
10003 #ifdef DEBUG_SUPPORT
10004 if (decrypted) {
10005 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10006 }
10007 #endif
10008
10009
10010
10011 iaxs[fr->callno]->frames_received++;
10012
10013 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10014 f.subclass.integer != IAX_COMMAND_TXCNT &&
10015 f.subclass.integer != IAX_COMMAND_TXACC) {
10016 unsigned short new_peercallno;
10017
10018 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10019 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10020 if (iaxs[fr->callno]->peercallno) {
10021 remove_by_peercallno(iaxs[fr->callno]);
10022 }
10023 iaxs[fr->callno]->peercallno = new_peercallno;
10024 store_by_peercallno(iaxs[fr->callno]);
10025 }
10026 }
10027 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10028 if (iaxdebug)
10029 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10030
10031 fr->oseqno = fh->oseqno;
10032 fr->iseqno = fh->iseqno;
10033 fr->ts = ntohl(fh->ts);
10034 #ifdef IAXTESTS
10035 if (test_resync) {
10036 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10037 fr->ts += test_resync;
10038 }
10039 #endif
10040 #if 0
10041 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10042 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10043 (f.subclass == IAX_COMMAND_NEW ||
10044 f.subclass == IAX_COMMAND_AUTHREQ ||
10045 f.subclass == IAX_COMMAND_ACCEPT ||
10046 f.subclass == IAX_COMMAND_REJECT)) ) )
10047 #endif
10048 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10049 updatehistory = 0;
10050 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10051 (iaxs[fr->callno]->iseqno ||
10052 ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10053 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10054 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10055 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10056 (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10057 (f.frametype != AST_FRAME_IAX))) {
10058 if (
10059 ((f.subclass.integer != IAX_COMMAND_ACK) &&
10060 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10061 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10062 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10063 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10064 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10065 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10066 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10067 (f.frametype != AST_FRAME_IAX)) {
10068
10069 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
10070 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10071
10072
10073 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10074
10075 if ((f.frametype != AST_FRAME_IAX) ||
10076 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10077 ast_debug(1, "Acking anyway\n");
10078
10079
10080 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10081 }
10082 } else {
10083
10084 iax2_vnak(fr->callno);
10085 }
10086 ast_variables_destroy(ies.vars);
10087 ast_mutex_unlock(&iaxsl[fr->callno]);
10088 return 1;
10089 }
10090 } else {
10091
10092 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10093 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10094 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10095 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10096 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10097 (f.frametype != AST_FRAME_IAX))
10098 iaxs[fr->callno]->iseqno++;
10099 }
10100
10101 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10102 if (res < thread->buf_size)
10103 thread->buf[res++] = '\0';
10104 else
10105 thread->buf[res - 1] = '\0';
10106 }
10107
10108
10109
10110 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10111 ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10112 (f.frametype != AST_FRAME_IAX))) {
10113 unsigned char x;
10114 int call_to_destroy;
10115
10116 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10117 x = fr->iseqno;
10118 else
10119 x = iaxs[fr->callno]->oseqno;
10120 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10121
10122
10123 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10124
10125 if (iaxdebug)
10126 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10127 call_to_destroy = 0;
10128 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10129
10130 if (x == cur->oseqno) {
10131 cur->retries = -1;
10132
10133 if (cur->final)
10134 call_to_destroy = fr->callno;
10135 }
10136 }
10137 if (call_to_destroy) {
10138 if (iaxdebug)
10139 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10140 ast_mutex_lock(&iaxsl[call_to_destroy]);
10141 iax2_destroy(call_to_destroy);
10142 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10143 }
10144 }
10145
10146 if (iaxs[fr->callno])
10147 iaxs[fr->callno]->rseqno = fr->iseqno;
10148 else {
10149
10150 ast_variables_destroy(ies.vars);
10151 ast_mutex_unlock(&iaxsl[fr->callno]);
10152 return 1;
10153 }
10154 } else {
10155 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10156 }
10157 }
10158 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10159 ((f.frametype != AST_FRAME_IAX) ||
10160 ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10161 (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10162
10163 ast_variables_destroy(ies.vars);
10164 ast_mutex_unlock(&iaxsl[fr->callno]);
10165 return 1;
10166 }
10167
10168
10169
10170
10171 if ((f.frametype == AST_FRAME_VOICE) ||
10172 (f.frametype == AST_FRAME_VIDEO) ||
10173 (f.frametype == AST_FRAME_IAX)) {
10174 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10175 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10176 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
10177 ast_variables_destroy(ies.vars);
10178 ast_mutex_unlock(&iaxsl[fr->callno]);
10179 return 1;
10180 }
10181 }
10182
10183 if (ies.vars) {
10184 struct ast_datastore *variablestore = NULL;
10185 struct ast_variable *var, *prev = NULL;
10186 AST_LIST_HEAD(, ast_var_t) *varlist;
10187
10188 iax2_lock_owner(fr->callno);
10189 if (!iaxs[fr->callno]) {
10190 ast_variables_destroy(ies.vars);
10191 ast_mutex_unlock(&iaxsl[fr->callno]);
10192 return 1;
10193 }
10194 if ((c = iaxs[fr->callno]->owner)) {
10195 varlist = ast_calloc(1, sizeof(*varlist));
10196 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10197
10198 if (variablestore && varlist) {
10199 variablestore->data = varlist;
10200 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10201 AST_LIST_HEAD_INIT(varlist);
10202 ast_debug(1, "I can haz IAX vars?\n");
10203 for (var = ies.vars; var; var = var->next) {
10204 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10205 if (prev) {
10206 ast_free(prev);
10207 }
10208 prev = var;
10209 if (!newvar) {
10210
10211 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10212 } else {
10213 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10214 }
10215 }
10216 if (prev) {
10217 ast_free(prev);
10218 }
10219 ies.vars = NULL;
10220 ast_channel_datastore_add(c, variablestore);
10221 } else {
10222 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10223 if (variablestore) {
10224 ast_datastore_free(variablestore);
10225 }
10226 if (varlist) {
10227 ast_free(varlist);
10228 }
10229 }
10230 ast_channel_unlock(c);
10231 } else {
10232
10233
10234 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10235 for (var = ies.vars; var && var->next; var = var->next);
10236 if (var) {
10237 var->next = iaxs[fr->callno]->iaxvars;
10238 iaxs[fr->callno]->iaxvars = ies.vars;
10239 ies.vars = NULL;
10240 }
10241 }
10242 }
10243
10244 if (ies.vars) {
10245 ast_debug(1, "I have IAX variables, but they were not processed\n");
10246 }
10247 }
10248
10249
10250
10251 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10252 send_signaling(iaxs[fr->callno]);
10253 }
10254
10255 if (f.frametype == AST_FRAME_VOICE) {
10256 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10257 iaxs[fr->callno]->voiceformat = f.subclass.codec;
10258 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10259 if (iaxs[fr->callno]->owner) {
10260 iax2_lock_owner(fr->callno);
10261 if (iaxs[fr->callno]) {
10262 if (iaxs[fr->callno]->owner) {
10263 format_t orignative;
10264
10265 orignative = iaxs[fr->callno]->owner->nativeformats;
10266 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10267 if (iaxs[fr->callno]->owner->readformat)
10268 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10269 iaxs[fr->callno]->owner->nativeformats = orignative;
10270 ast_channel_unlock(iaxs[fr->callno]->owner);
10271 }
10272 } else {
10273 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10274
10275 if (ies.vars) {
10276 ast_variables_destroy(ies.vars);
10277 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10278 ies.vars = NULL;
10279 }
10280 ast_mutex_unlock(&iaxsl[fr->callno]);
10281 return 1;
10282 }
10283 }
10284 }
10285 }
10286 if (f.frametype == AST_FRAME_VIDEO) {
10287 if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10288 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10289 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10290 }
10291 }
10292 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10293 if (f.subclass.integer == AST_CONTROL_BUSY) {
10294 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10295 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10296 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10297 }
10298 }
10299 if (f.frametype == AST_FRAME_IAX) {
10300 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10301
10302 if (iaxdebug)
10303 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10304
10305
10306 if (iaxs[fr->callno]->last < fr->ts &&
10307 f.subclass.integer != IAX_COMMAND_ACK &&
10308 f.subclass.integer != IAX_COMMAND_PONG &&
10309 f.subclass.integer != IAX_COMMAND_LAGRP) {
10310 iaxs[fr->callno]->last = fr->ts;
10311 if (iaxdebug)
10312 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10313 }
10314 iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10315 if (!iaxs[fr->callno]->first_iax_message) {
10316 iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10317 }
10318 switch(f.subclass.integer) {
10319 case IAX_COMMAND_ACK:
10320
10321 break;
10322 case IAX_COMMAND_QUELCH:
10323 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10324
10325 if (iaxs[fr->callno]->owner) {
10326 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10327 "Status: On\r\n"
10328 "Channel: %s\r\n"
10329 "Uniqueid: %s\r\n",
10330 iaxs[fr->callno]->owner->name,
10331 iaxs[fr->callno]->owner->uniqueid);
10332 }
10333
10334 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10335 if (ies.musiconhold) {
10336 iax2_lock_owner(fr->callno);
10337 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10338 break;
10339 }
10340 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10341 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10342
10343
10344
10345
10346
10347 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10348 S_OR(moh_suggest, NULL),
10349 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10350 }
10351 ast_channel_unlock(iaxs[fr->callno]->owner);
10352 }
10353 }
10354 break;
10355 case IAX_COMMAND_UNQUELCH:
10356 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10357 iax2_lock_owner(fr->callno);
10358 if (!iaxs[fr->callno]) {
10359 break;
10360 }
10361
10362 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10363 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10364 "Status: Off\r\n"
10365 "Channel: %s\r\n"
10366 "Uniqueid: %s\r\n",
10367 iaxs[fr->callno]->owner->name,
10368 iaxs[fr->callno]->owner->uniqueid);
10369 }
10370
10371 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10372 if (!iaxs[fr->callno]->owner) {
10373 break;
10374 }
10375 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10376
10377
10378
10379
10380 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10381 }
10382 ast_channel_unlock(iaxs[fr->callno]->owner);
10383 }
10384 break;
10385 case IAX_COMMAND_TXACC:
10386 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10387
10388 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10389
10390 if (cur->transfer) {
10391 cur->retries = -1;
10392 }
10393 }
10394 memset(&ied1, 0, sizeof(ied1));
10395 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10396 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10397 iaxs[fr->callno]->transferring = TRANSFER_READY;
10398 }
10399 break;
10400 case IAX_COMMAND_NEW:
10401
10402 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10403 break;
10404 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10405 ast_mutex_unlock(&iaxsl[fr->callno]);
10406 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10407 ast_mutex_lock(&iaxsl[fr->callno]);
10408 if (!iaxs[fr->callno]) {
10409 break;
10410 }
10411 }
10412
10413 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10414 int new_callno;
10415 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10416 fr->callno = new_callno;
10417 }
10418
10419 if (delayreject)
10420 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10421 if (check_access(fr->callno, &sin, &ies)) {
10422
10423 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10424 if (authdebug)
10425 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);
10426 break;
10427 }
10428 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10429 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10430 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10431 break;
10432 }
10433 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10434 const char *context, *exten, *cid_num;
10435
10436 context = ast_strdupa(iaxs[fr->callno]->context);
10437 exten = ast_strdupa(iaxs[fr->callno]->exten);
10438 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10439
10440
10441 ast_mutex_unlock(&iaxsl[fr->callno]);
10442 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10443 ast_mutex_lock(&iaxsl[fr->callno]);
10444
10445 if (!iaxs[fr->callno]) {
10446 break;
10447 }
10448 } else
10449 exists = 0;
10450
10451 save_osptoken(fr, &ies);
10452 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10453 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10454 memset(&ied0, 0, sizeof(ied0));
10455 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10456 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10457 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10458 if (!iaxs[fr->callno]) {
10459 break;
10460 }
10461 if (authdebug)
10462 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);
10463 } else {
10464
10465
10466 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10467 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10468 using_prefs = "reqonly";
10469 } else {
10470 using_prefs = "disabled";
10471 }
10472 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10473 memset(&pref, 0, sizeof(pref));
10474 strcpy(caller_pref_buf, "disabled");
10475 strcpy(host_pref_buf, "disabled");
10476 } else {
10477 using_prefs = "mine";
10478
10479 if (ies.codec_prefs)
10480 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10481 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10482
10483 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10484 pref = iaxs[fr->callno]->rprefs;
10485 using_prefs = "caller";
10486 } else {
10487 pref = iaxs[fr->callno]->prefs;
10488 }
10489 } else
10490 pref = iaxs[fr->callno]->prefs;
10491
10492 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10493 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10494 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10495 }
10496 if (!format) {
10497 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10498 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10499 if (!format) {
10500 memset(&ied0, 0, sizeof(ied0));
10501 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10502 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10503 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10504 if (!iaxs[fr->callno]) {
10505 break;
10506 }
10507 if (authdebug) {
10508 char tmp[256], tmp2[256], tmp3[256];
10509 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10510 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10511 ast_inet_ntoa(sin.sin_addr),
10512 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10513 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10514 } else {
10515 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10516 ast_inet_ntoa(sin.sin_addr),
10517 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10518 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10519 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10520 }
10521 }
10522 } else {
10523
10524 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10525 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10526 format = 0;
10527 } else {
10528 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10529 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10530 memset(&pref, 0, sizeof(pref));
10531 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10532 strcpy(caller_pref_buf,"disabled");
10533 strcpy(host_pref_buf,"disabled");
10534 } else {
10535 using_prefs = "mine";
10536 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10537
10538 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10539 pref = iaxs[fr->callno]->prefs;
10540 } else {
10541 pref = iaxs[fr->callno]->rprefs;
10542 using_prefs = "caller";
10543 }
10544 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10545 } else
10546 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10547 }
10548 }
10549
10550 if (!format) {
10551 char tmp[256], tmp2[256], tmp3[256];
10552 memset(&ied0, 0, sizeof(ied0));
10553 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10554 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10555 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10556 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10557 if (!iaxs[fr->callno]) {
10558 break;
10559 }
10560 if (authdebug) {
10561 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10562 ast_inet_ntoa(sin.sin_addr),
10563 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10564 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10565 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10566 }
10567 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10568 break;
10569 }
10570 }
10571 }
10572 if (format) {
10573
10574 memset(&ied1, 0, sizeof(ied1));
10575 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10576 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10577 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10578 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10579 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10580 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10581 "%srequested format = %s,\n"
10582 "%srequested prefs = %s,\n"
10583 "%sactual format = %s,\n"
10584 "%shost prefs = %s,\n"
10585 "%spriority = %s\n",
10586 ast_inet_ntoa(sin.sin_addr),
10587 VERBOSE_PREFIX_4,
10588 ast_getformatname(iaxs[fr->callno]->peerformat),
10589 VERBOSE_PREFIX_4,
10590 caller_pref_buf,
10591 VERBOSE_PREFIX_4,
10592 ast_getformatname(format),
10593 VERBOSE_PREFIX_4,
10594 host_pref_buf,
10595 VERBOSE_PREFIX_4,
10596 using_prefs);
10597
10598 iaxs[fr->callno]->chosenformat = format;
10599 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10600 } else {
10601 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10602
10603 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10604 }
10605 }
10606 }
10607 break;
10608 }
10609 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10610 merge_encryption(iaxs[fr->callno],ies.encmethods);
10611 else
10612 iaxs[fr->callno]->encmethods = 0;
10613 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10614 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10615 break;
10616 case IAX_COMMAND_DPREQ:
10617
10618 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10619 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10620 if (iaxcompat) {
10621
10622 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10623 } else {
10624
10625 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10626 }
10627 }
10628 break;
10629 case IAX_COMMAND_HANGUP:
10630 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10631 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10632
10633 if (iaxs[fr->callno]->owner) {
10634 set_hangup_source_and_cause(fr->callno, ies.causecode);
10635 if (!iaxs[fr->callno]) {
10636 break;
10637 }
10638 }
10639
10640
10641 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10642 iax2_destroy(fr->callno);
10643 break;
10644 case IAX_COMMAND_REJECT:
10645
10646 if (iaxs[fr->callno]->owner) {
10647 set_hangup_source_and_cause(fr->callno, ies.causecode);
10648 if (!iaxs[fr->callno]) {
10649 break;
10650 }
10651 }
10652
10653 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10654 if (iaxs[fr->callno]->owner && authdebug)
10655 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10656 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10657 ies.cause ? ies.cause : "<Unknown>");
10658 ast_debug(1, "Immediately destroying %d, having received reject\n",
10659 fr->callno);
10660 }
10661
10662 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10663 fr->ts, NULL, 0, fr->iseqno);
10664 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10665 iaxs[fr->callno]->error = EPERM;
10666 iax2_destroy(fr->callno);
10667 break;
10668 case IAX_COMMAND_TRANSFER:
10669 {
10670 struct ast_channel *bridged_chan;
10671 struct ast_channel *owner;
10672
10673 iax2_lock_owner(fr->callno);
10674 if (!iaxs[fr->callno]) {
10675
10676 break;
10677 }
10678 owner = iaxs[fr->callno]->owner;
10679 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10680 if (bridged_chan && ies.called_number) {
10681 ast_mutex_unlock(&iaxsl[fr->callno]);
10682
10683
10684 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10685 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10686
10687 if (ast_parking_ext_valid(ies.called_number, c, iaxs[fr->callno]->context)) {
10688 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10689 if (iax_park(bridged_chan, owner, ies.called_number)) {
10690 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10691 bridged_chan->name);
10692 }
10693 ast_mutex_lock(&iaxsl[fr->callno]);
10694 } else {
10695 ast_mutex_lock(&iaxsl[fr->callno]);
10696
10697 if (iaxs[fr->callno]) {
10698 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context,
10699 ies.called_number, 1)) {
10700 ast_log(LOG_WARNING,
10701 "Async goto of '%s' to '%s@%s' failed\n",
10702 bridged_chan->name, ies.called_number,
10703 iaxs[fr->callno]->context);
10704 } else {
10705 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10706 bridged_chan->name, ies.called_number,
10707 iaxs[fr->callno]->context);
10708 }
10709 } else {
10710
10711 }
10712 }
10713 } else {
10714 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10715 }
10716 if (owner) {
10717 ast_channel_unlock(owner);
10718 }
10719
10720 break;
10721 }
10722 case IAX_COMMAND_ACCEPT:
10723
10724 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10725 break;
10726 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10727
10728 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10729 iax2_destroy(fr->callno);
10730 break;
10731 }
10732 if (ies.format) {
10733 iaxs[fr->callno]->peerformat = ies.format;
10734 } else {
10735 if (iaxs[fr->callno]->owner)
10736 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10737 else
10738 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10739 }
10740 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));
10741 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10742 memset(&ied0, 0, sizeof(ied0));
10743 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10744 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10745 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10746 if (!iaxs[fr->callno]) {
10747 break;
10748 }
10749 if (authdebug) {
10750 char tmp1[256], tmp2[256];
10751 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10752 ast_inet_ntoa(sin.sin_addr),
10753 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10754 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10755 }
10756 } else {
10757 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10758 iax2_lock_owner(fr->callno);
10759 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10760
10761 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10762 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10763
10764
10765 if (iaxs[fr->callno]->owner->writeformat)
10766 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10767 if (iaxs[fr->callno]->owner->readformat)
10768 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10769 ast_channel_unlock(iaxs[fr->callno]->owner);
10770 }
10771 }
10772 if (iaxs[fr->callno]) {
10773 AST_LIST_LOCK(&dpcache);
10774 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10775 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10776 iax2_dprequest(dp, fr->callno);
10777 AST_LIST_UNLOCK(&dpcache);
10778 }
10779 break;
10780 case IAX_COMMAND_POKE:
10781
10782 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10783 break;
10784 case IAX_COMMAND_PING:
10785 {
10786 struct iax_ie_data pingied;
10787 construct_rr(iaxs[fr->callno], &pingied);
10788
10789 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10790 }
10791 break;
10792 case IAX_COMMAND_PONG:
10793
10794 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10795
10796 save_rr(fr, &ies);
10797
10798
10799 log_jitterstats(fr->callno);
10800
10801 if (iaxs[fr->callno]->peerpoke) {
10802 peer = iaxs[fr->callno]->peerpoke;
10803 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10804 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10805 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10806 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
10807 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10808 }
10809 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10810 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10811 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10812 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
10813 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10814 }
10815 }
10816 peer->lastms = iaxs[fr->callno]->pingtime;
10817 if (peer->smoothing && (peer->lastms > -1))
10818 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10819 else if (peer->smoothing && peer->lastms < 0)
10820 peer->historicms = (0 + peer->historicms) / 2;
10821 else
10822 peer->historicms = iaxs[fr->callno]->pingtime;
10823
10824
10825 if (peer->pokeexpire > -1) {
10826 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10827 peer_unref(peer);
10828 peer->pokeexpire = -1;
10829 }
10830 }
10831
10832 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10833 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10834 else
10835 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10836 if (peer->pokeexpire == -1)
10837 peer_unref(peer);
10838
10839 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10840
10841 iax2_destroy(fr->callno);
10842 peer->callno = 0;
10843 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10844 }
10845 break;
10846 case IAX_COMMAND_LAGRQ:
10847 case IAX_COMMAND_LAGRP:
10848 f.src = "LAGRQ";
10849 f.mallocd = 0;
10850 f.offset = 0;
10851 f.samples = 0;
10852 iax_frame_wrap(fr, &f);
10853 if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
10854
10855 fr->af.subclass.integer = IAX_COMMAND_LAGRP;
10856 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10857 } else {
10858
10859 unsigned int ts;
10860
10861 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10862 iaxs[fr->callno]->lag = ts - fr->ts;
10863 if (iaxdebug)
10864 ast_debug(1, "Peer %s lag measured as %dms\n",
10865 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10866 }
10867 break;
10868 case IAX_COMMAND_AUTHREQ:
10869 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10870 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>");
10871 break;
10872 }
10873 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10874 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10875 .subclass.integer = AST_CONTROL_HANGUP,
10876 };
10877 ast_log(LOG_WARNING,
10878 "I don't know how to authenticate %s to %s\n",
10879 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10880 iax2_queue_frame(fr->callno, &hangup_fr);
10881 }
10882 break;
10883 case IAX_COMMAND_AUTHREP:
10884
10885 if (delayreject)
10886 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10887
10888 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10889 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>");
10890 break;
10891 }
10892 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10893 if (authdebug)
10894 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);
10895 memset(&ied0, 0, sizeof(ied0));
10896 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10897 break;
10898 }
10899 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10900
10901 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10902 } else
10903 exists = 0;
10904 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10905 if (authdebug)
10906 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);
10907 memset(&ied0, 0, sizeof(ied0));
10908 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10909 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10910 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10911 if (!iaxs[fr->callno]) {
10912 break;
10913 }
10914 } else {
10915
10916 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10917 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10918 using_prefs = "reqonly";
10919 } else {
10920 using_prefs = "disabled";
10921 }
10922 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10923 memset(&pref, 0, sizeof(pref));
10924 strcpy(caller_pref_buf, "disabled");
10925 strcpy(host_pref_buf, "disabled");
10926 } else {
10927 using_prefs = "mine";
10928 if (ies.codec_prefs)
10929 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10930 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10931 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10932 pref = iaxs[fr->callno]->rprefs;
10933 using_prefs = "caller";
10934 } else {
10935 pref = iaxs[fr->callno]->prefs;
10936 }
10937 } else
10938 pref = iaxs[fr->callno]->prefs;
10939 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10940 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10941 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10942 }
10943 if (!format) {
10944 char tmp1[256], tmp2[256], tmp3[256];
10945 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10946 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
10947 ast_getformatname(iaxs[fr->callno]->peerformat),
10948 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
10949 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10950 }
10951 if (!format) {
10952 if (authdebug) {
10953 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10954 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
10955 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10956 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10957 } else {
10958 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10959 ast_inet_ntoa(sin.sin_addr),
10960 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10961 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10962 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10963 }
10964 }
10965 memset(&ied0, 0, sizeof(ied0));
10966 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10967 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10968 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10969 if (!iaxs[fr->callno]) {
10970 break;
10971 }
10972 } else {
10973
10974 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10975 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10976 format = 0;
10977 } else {
10978 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10979 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10980 memset(&pref, 0, sizeof(pref));
10981 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10982 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10983 strcpy(caller_pref_buf,"disabled");
10984 strcpy(host_pref_buf,"disabled");
10985 } else {
10986 using_prefs = "mine";
10987 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10988
10989 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10990 pref = iaxs[fr->callno]->prefs;
10991 } else {
10992 pref = iaxs[fr->callno]->rprefs;
10993 using_prefs = "caller";
10994 }
10995 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10996 } else
10997 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10998 }
10999 }
11000 if (!format) {
11001 char tmp1[256], tmp2[256], tmp3[256];
11002 ast_log(LOG_ERROR, "No best format in %s???\n",
11003 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11004 if (authdebug) {
11005 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11006 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%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 } else {
11011 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11012 ast_inet_ntoa(sin.sin_addr),
11013 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11014 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11015 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11016 }
11017 }
11018 memset(&ied0, 0, sizeof(ied0));
11019 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11020 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11021 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11022 if (!iaxs[fr->callno]) {
11023 break;
11024 }
11025 }
11026 }
11027 }
11028 if (format) {
11029
11030 memset(&ied1, 0, sizeof(ied1));
11031 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11032 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11033 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11034 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11035 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11036 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11037 "%srequested format = %s,\n"
11038 "%srequested prefs = %s,\n"
11039 "%sactual format = %s,\n"
11040 "%shost prefs = %s,\n"
11041 "%spriority = %s\n",
11042 ast_inet_ntoa(sin.sin_addr),
11043 VERBOSE_PREFIX_4,
11044 ast_getformatname(iaxs[fr->callno]->peerformat),
11045 VERBOSE_PREFIX_4,
11046 caller_pref_buf,
11047 VERBOSE_PREFIX_4,
11048 ast_getformatname(format),
11049 VERBOSE_PREFIX_4,
11050 host_pref_buf,
11051 VERBOSE_PREFIX_4,
11052 using_prefs);
11053
11054 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11055 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
11056 iax2_destroy(fr->callno);
11057 else if (ies.vars) {
11058 struct ast_datastore *variablestore;
11059 struct ast_variable *var, *prev = NULL;
11060 AST_LIST_HEAD(, ast_var_t) *varlist;
11061 varlist = ast_calloc(1, sizeof(*varlist));
11062 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11063 if (variablestore && varlist) {
11064 variablestore->data = varlist;
11065 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11066 AST_LIST_HEAD_INIT(varlist);
11067 ast_debug(1, "I can haz IAX vars? w00t\n");
11068 for (var = ies.vars; var; var = var->next) {
11069 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11070 if (prev)
11071 ast_free(prev);
11072 prev = var;
11073 if (!newvar) {
11074
11075 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11076 } else {
11077 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11078 }
11079 }
11080 if (prev)
11081 ast_free(prev);
11082 ies.vars = NULL;
11083 ast_channel_datastore_add(c, variablestore);
11084 } else {
11085 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11086 if (variablestore)
11087 ast_datastore_free(variablestore);
11088 if (varlist)
11089 ast_free(varlist);
11090 }
11091 }
11092 } else {
11093 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11094
11095 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11096 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11097 goto immediatedial;
11098 }
11099 }
11100 }
11101 }
11102 break;
11103 case IAX_COMMAND_DIAL:
11104 immediatedial:
11105 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11106 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11107 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11108 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11109 if (authdebug)
11110 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);
11111 memset(&ied0, 0, sizeof(ied0));
11112 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11113 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11114 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11115 if (!iaxs[fr->callno]) {
11116 break;
11117 }
11118 } else {
11119 char tmp[256];
11120 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11121 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11122 ast_inet_ntoa(sin.sin_addr),
11123 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11124 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11125 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11126 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
11127 iax2_destroy(fr->callno);
11128 else if (ies.vars) {
11129 struct ast_datastore *variablestore;
11130 struct ast_variable *var, *prev = NULL;
11131 AST_LIST_HEAD(, ast_var_t) *varlist;
11132 varlist = ast_calloc(1, sizeof(*varlist));
11133 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11134 ast_debug(1, "I can haz IAX vars? w00t\n");
11135 if (variablestore && varlist) {
11136 variablestore->data = varlist;
11137 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11138 AST_LIST_HEAD_INIT(varlist);
11139 for (var = ies.vars; var; var = var->next) {
11140 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11141 if (prev)
11142 ast_free(prev);
11143 prev = var;
11144 if (!newvar) {
11145
11146 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11147 } else {
11148 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11149 }
11150 }
11151 if (prev)
11152 ast_free(prev);
11153 ies.vars = NULL;
11154 ast_channel_datastore_add(c, variablestore);
11155 } else {
11156 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11157 if (variablestore)
11158 ast_datastore_free(variablestore);
11159 if (varlist)
11160 ast_free(varlist);
11161 }
11162 }
11163 }
11164 }
11165 break;
11166 case IAX_COMMAND_INVAL:
11167 iaxs[fr->callno]->error = ENOTCONN;
11168 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11169 iax2_destroy(fr->callno);
11170 ast_debug(1, "Destroying call %d\n", fr->callno);
11171 break;
11172 case IAX_COMMAND_VNAK:
11173 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11174
11175 vnak_retransmit(fr->callno, fr->iseqno);
11176 break;
11177 case IAX_COMMAND_REGREQ:
11178 case IAX_COMMAND_REGREL:
11179
11180 if (delayreject)
11181 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11182 if (register_verify(fr->callno, &sin, &ies)) {
11183 if (!iaxs[fr->callno]) {
11184 break;
11185 }
11186
11187 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11188 break;
11189 }
11190 if (!iaxs[fr->callno]) {
11191 break;
11192 }
11193 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11194 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11195
11196 if (f.subclass.integer == IAX_COMMAND_REGREL) {
11197 memset(&sin, 0, sizeof(sin));
11198 sin.sin_family = AF_INET;
11199 }
11200 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11201 ast_log(LOG_WARNING, "Registry error\n");
11202 }
11203 if (!iaxs[fr->callno]) {
11204 break;
11205 }
11206 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11207 ast_mutex_unlock(&iaxsl[fr->callno]);
11208 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11209 ast_mutex_lock(&iaxsl[fr->callno]);
11210 }
11211 break;
11212 }
11213 registry_authrequest(fr->callno);
11214 break;
11215 case IAX_COMMAND_REGACK:
11216 if (iax2_ack_registry(&ies, &sin, fr->callno))
11217 ast_log(LOG_WARNING, "Registration failure\n");
11218
11219 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11220 iax2_destroy(fr->callno);
11221 break;
11222 case IAX_COMMAND_REGREJ:
11223 if (iaxs[fr->callno]->reg) {
11224 if (authdebug) {
11225 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));
11226 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>");
11227 }
11228 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11229 }
11230
11231 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11232 iax2_destroy(fr->callno);
11233 break;
11234 case IAX_COMMAND_REGAUTH:
11235
11236 if (registry_rerequest(&ies, fr->callno, &sin)) {
11237 memset(&ied0, 0, sizeof(ied0));
11238 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11239 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11240 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11241 }
11242 break;
11243 case IAX_COMMAND_TXREJ:
11244 iaxs[fr->callno]->transferring = 0;
11245 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11246 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11247 if (iaxs[fr->callno]->bridgecallno) {
11248 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11249 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11250 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11251 }
11252 }
11253 break;
11254 case IAX_COMMAND_TXREADY:
11255 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11256 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11257 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11258 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11259 else
11260 iaxs[fr->callno]->transferring = TRANSFER_READY;
11261 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11262 if (iaxs[fr->callno]->bridgecallno) {
11263 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11264 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11265
11266 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11267 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11268 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11269
11270 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11271 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11272
11273 memset(&ied0, 0, sizeof(ied0));
11274 memset(&ied1, 0, sizeof(ied1));
11275 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11276 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11277 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11278 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11279 } else {
11280 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11281 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11282
11283 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11284 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11285 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11286 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11287
11288
11289 stop_stuff(fr->callno);
11290 stop_stuff(iaxs[fr->callno]->bridgecallno);
11291
11292 memset(&ied0, 0, sizeof(ied0));
11293 memset(&ied1, 0, sizeof(ied1));
11294 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11295 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11296 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11297 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11298 }
11299
11300 }
11301 }
11302 }
11303 break;
11304 case IAX_COMMAND_TXREQ:
11305 try_transfer(iaxs[fr->callno], &ies);
11306 break;
11307 case IAX_COMMAND_TXCNT:
11308 if (iaxs[fr->callno]->transferring)
11309 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11310 break;
11311 case IAX_COMMAND_TXREL:
11312
11313 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11314 complete_transfer(fr->callno, &ies);
11315 stop_stuff(fr->callno);
11316 break;
11317 case IAX_COMMAND_TXMEDIA:
11318 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11319 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11320
11321 if (cur->transfer) {
11322 cur->retries = -1;
11323 }
11324 }
11325
11326 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11327 }
11328 break;
11329 case IAX_COMMAND_RTKEY:
11330 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11331 ast_log(LOG_WARNING,
11332 "we've been told to rotate our encryption key, "
11333 "but this isn't an encrypted call. bad things will happen.\n"
11334 );
11335 break;
11336 }
11337
11338 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11339
11340 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11341 break;
11342 case IAX_COMMAND_DPREP:
11343 complete_dpreply(iaxs[fr->callno], &ies);
11344 break;
11345 case IAX_COMMAND_UNSUPPORT:
11346 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11347 break;
11348 case IAX_COMMAND_FWDOWNL:
11349
11350 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11351 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11352 break;
11353 }
11354 memset(&ied0, 0, sizeof(ied0));
11355 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11356 if (res < 0)
11357 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11358 else if (res > 0)
11359 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11360 else
11361 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11362 break;
11363 case IAX_COMMAND_CALLTOKEN:
11364 {
11365 struct iax_frame *cur;
11366
11367 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11368 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11369 }
11370 break;
11371 }
11372 default:
11373 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11374 memset(&ied0, 0, sizeof(ied0));
11375 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11376 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11377 }
11378
11379 if (ies.vars) {
11380 ast_variables_destroy(ies.vars);
11381 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11382 ies.vars = NULL;
11383 }
11384
11385
11386 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11387 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11388 (f.subclass.integer != IAX_COMMAND_TXACC) &&
11389 (f.subclass.integer != IAX_COMMAND_INVAL) &&
11390 (f.subclass.integer != IAX_COMMAND_VNAK)) {
11391 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11392 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11393 }
11394 ast_mutex_unlock(&iaxsl[fr->callno]);
11395 return 1;
11396 }
11397
11398 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11399 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11400 } else if (minivid) {
11401 f.frametype = AST_FRAME_VIDEO;
11402 if (iaxs[fr->callno]->videoformat > 0)
11403 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11404 else {
11405 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11406 iax2_vnak(fr->callno);
11407 ast_variables_destroy(ies.vars);
11408 ast_mutex_unlock(&iaxsl[fr->callno]);
11409 return 1;
11410 }
11411 f.datalen = res - sizeof(*vh);
11412 if (f.datalen)
11413 f.data.ptr = thread->buf + sizeof(*vh);
11414 else
11415 f.data.ptr = NULL;
11416 #ifdef IAXTESTS
11417 if (test_resync) {
11418 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11419 } else
11420 #endif
11421 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11422 } else {
11423
11424 f.frametype = AST_FRAME_VOICE;
11425 if (iaxs[fr->callno]->voiceformat > 0)
11426 f.subclass.codec = iaxs[fr->callno]->voiceformat;
11427 else {
11428 ast_debug(1, "Received mini frame before first full voice frame\n");
11429 iax2_vnak(fr->callno);
11430 ast_variables_destroy(ies.vars);
11431 ast_mutex_unlock(&iaxsl[fr->callno]);
11432 return 1;
11433 }
11434 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11435 if (f.datalen < 0) {
11436 ast_log(LOG_WARNING, "Datalen < 0?\n");
11437 ast_variables_destroy(ies.vars);
11438 ast_mutex_unlock(&iaxsl[fr->callno]);
11439 return 1;
11440 }
11441 if (f.datalen)
11442 f.data.ptr = thread->buf + sizeof(*mh);
11443 else
11444 f.data.ptr = NULL;
11445 #ifdef IAXTESTS
11446 if (test_resync) {
11447 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11448 } else
11449 #endif
11450 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11451
11452 }
11453
11454 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11455 ast_variables_destroy(ies.vars);
11456 ast_mutex_unlock(&iaxsl[fr->callno]);
11457 return 1;
11458 }
11459
11460 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11461 struct ast_party_connected_line connected;
11462
11463 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11464 ast_variables_destroy(ies.vars);
11465 ast_mutex_unlock(&iaxsl[fr->callno]);
11466 return 1;
11467 }
11468
11469
11470 ast_party_connected_line_init(&connected);
11471 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11472 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11473
11474 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11475 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11476 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11477 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11478
11479 if (iaxs[fr->callno]->owner) {
11480 ast_set_callerid(iaxs[fr->callno]->owner,
11481 S_COR(connected.id.number.valid, connected.id.number.str, ""),
11482 S_COR(connected.id.name.valid, connected.id.name.str, ""),
11483 NULL);
11484 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11485 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11486 }
11487 }
11488 ast_party_connected_line_free(&connected);
11489 }
11490
11491 f.src = "IAX2";
11492 f.mallocd = 0;
11493 f.offset = 0;
11494 f.len = 0;
11495 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11496 f.samples = ast_codec_get_samples(&f);
11497
11498 if (f.subclass.codec == AST_FORMAT_SLINEAR)
11499 ast_frame_byteswap_be(&f);
11500 } else
11501 f.samples = 0;
11502 iax_frame_wrap(fr, &f);
11503
11504
11505 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11506
11507 fr->outoforder = 0;
11508 } else {
11509 if (iaxdebug && iaxs[fr->callno])
11510 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last);
11511 fr->outoforder = -1;
11512 }
11513 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11514 duped_fr = iaxfrdup2(fr);
11515 if (duped_fr) {
11516 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11517 }
11518 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11519 iaxs[fr->callno]->last = fr->ts;
11520 #if 1
11521 if (iaxdebug)
11522 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11523 #endif
11524 }
11525
11526
11527 ast_variables_destroy(ies.vars);
11528 ast_mutex_unlock(&iaxsl[fr->callno]);
11529 return 1;
11530 }
11531
11532
11533 static void iax2_process_thread_cleanup(void *data)
11534 {
11535 struct iax2_thread *thread = data;
11536 ast_mutex_destroy(&thread->lock);
11537 ast_cond_destroy(&thread->cond);
11538 ast_mutex_destroy(&thread->init_lock);
11539 ast_cond_destroy(&thread->init_cond);
11540 ast_free(thread);
11541 ast_atomic_dec_and_test(&iaxactivethreadcount);
11542 }
11543
11544 static void *iax2_process_thread(void *data)
11545 {
11546 struct iax2_thread *thread = data;
11547 struct timeval wait;
11548 struct timespec ts;
11549 int put_into_idle = 0;
11550 int first_time = 1;
11551 int old_state;
11552
11553 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11554
11555 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11556 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11557
11558 for (;;) {
11559
11560 ast_mutex_lock(&thread->lock);
11561
11562 if (thread->stop) {
11563 ast_mutex_unlock(&thread->lock);
11564 break;
11565 }
11566
11567
11568 if (first_time) {
11569 signal_condition(&thread->init_lock, &thread->init_cond);
11570 first_time = 0;
11571 }
11572
11573
11574 if (put_into_idle) {
11575 insert_idle_thread(thread);
11576 }
11577
11578 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11579 struct iax2_thread *t = NULL;
11580
11581 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11582 ts.tv_sec = wait.tv_sec;
11583 ts.tv_nsec = wait.tv_usec * 1000;
11584 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11585
11586
11587 if (!put_into_idle || thread->stop) {
11588 ast_mutex_unlock(&thread->lock);
11589 break;
11590 }
11591 AST_LIST_LOCK(&dynamic_list);
11592
11593 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11594 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11595 AST_LIST_UNLOCK(&dynamic_list);
11596 if (t) {
11597
11598
11599
11600 ast_mutex_unlock(&thread->lock);
11601 break;
11602 }
11603
11604
11605
11606 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11607 ts.tv_sec = wait.tv_sec;
11608 ts.tv_nsec = wait.tv_usec * 1000;
11609 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11610 ast_mutex_unlock(&thread->lock);
11611 break;
11612 }
11613 }
11614 } else {
11615 ast_cond_wait(&thread->cond, &thread->lock);
11616 }
11617
11618
11619 put_into_idle = 1;
11620
11621 ast_mutex_unlock(&thread->lock);
11622
11623 if (thread->stop) {
11624 break;
11625 }
11626
11627 if (thread->iostate == IAX_IOSTATE_IDLE)
11628 continue;
11629
11630
11631 switch (thread->iostate) {
11632 case IAX_IOSTATE_READY:
11633 thread->actions++;
11634 thread->iostate = IAX_IOSTATE_PROCESSING;
11635 socket_process(thread);
11636 handle_deferred_full_frames(thread);
11637 break;
11638 case IAX_IOSTATE_SCHEDREADY:
11639 thread->actions++;
11640 thread->iostate = IAX_IOSTATE_PROCESSING;
11641 #ifdef SCHED_MULTITHREADED
11642 thread->schedfunc(thread->scheddata);
11643 #endif
11644 default:
11645 break;
11646 }
11647 time(&thread->checktime);
11648 thread->iostate = IAX_IOSTATE_IDLE;
11649 #ifdef DEBUG_SCHED_MULTITHREAD
11650 thread->curfunc[0]='\0';
11651 #endif
11652
11653
11654
11655
11656 AST_LIST_LOCK(&active_list);
11657 AST_LIST_REMOVE(&active_list, thread, list);
11658 AST_LIST_UNLOCK(&active_list);
11659
11660
11661 handle_deferred_full_frames(thread);
11662 }
11663
11664
11665
11666
11667
11668 AST_LIST_LOCK(&idle_list);
11669 AST_LIST_REMOVE(&idle_list, thread, list);
11670 AST_LIST_UNLOCK(&idle_list);
11671
11672 AST_LIST_LOCK(&dynamic_list);
11673 AST_LIST_REMOVE(&dynamic_list, thread, list);
11674 AST_LIST_UNLOCK(&dynamic_list);
11675
11676
11677
11678
11679 pthread_cleanup_pop(1);
11680 return NULL;
11681 }
11682
11683 static int iax2_do_register(struct iax2_registry *reg)
11684 {
11685 struct iax_ie_data ied;
11686 if (iaxdebug)
11687 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11688
11689 if (reg->dnsmgr &&
11690 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) {
11691
11692 ast_dnsmgr_refresh(reg->dnsmgr);
11693 }
11694
11695
11696
11697
11698
11699 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11700 int callno = reg->callno;
11701 ast_mutex_lock(&iaxsl[callno]);
11702 iax2_destroy(callno);
11703 ast_mutex_unlock(&iaxsl[callno]);
11704 reg->callno = 0;
11705 }
11706 if (!ast_sockaddr_ipv4(®->addr)) {
11707 if (iaxdebug)
11708 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11709
11710 reg->expire = iax2_sched_replace(reg->expire, sched,
11711 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11712 return -1;
11713 }
11714
11715 if (!reg->callno) {
11716 struct sockaddr_in reg_addr;
11717
11718 ast_debug(3, "Allocate call number\n");
11719
11720 ast_sockaddr_to_sin(®->addr, ®_addr);
11721
11722 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0);
11723 if (reg->callno < 1) {
11724 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11725 return -1;
11726 } else
11727 ast_debug(3, "Registration created on call %d\n", reg->callno);
11728 iaxs[reg->callno]->reg = reg;
11729 ast_mutex_unlock(&iaxsl[reg->callno]);
11730 }
11731
11732 reg->expire = iax2_sched_replace(reg->expire, sched,
11733 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11734
11735 memset(&ied, 0, sizeof(ied));
11736 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11737 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11738 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11739 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11740 reg->regstate = REG_STATE_REGSENT;
11741 return 0;
11742 }
11743
11744 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
11745 {
11746
11747
11748 struct iax_ie_data provdata;
11749 struct iax_ie_data ied;
11750 unsigned int sig;
11751 struct sockaddr_in sin;
11752 int callno;
11753 struct create_addr_info cai;
11754
11755 memset(&cai, 0, sizeof(cai));
11756
11757 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11758
11759 if (iax_provision_build(&provdata, &sig, template, force)) {
11760 ast_debug(1, "No provisioning found for template '%s'\n", template);
11761 return 0;
11762 }
11763
11764 if (end) {
11765 memcpy(&sin, end, sizeof(sin));
11766 cai.sockfd = sockfd;
11767 } else if (create_addr(dest, NULL, &sin, &cai))
11768 return -1;
11769
11770
11771 memset(&ied, 0, sizeof(ied));
11772 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11773
11774 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11775 if (!callno)
11776 return -1;
11777
11778 if (iaxs[callno]) {
11779
11780 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11781 sched, 15000, auto_hangup, (void *)(long)callno);
11782 ast_set_flag64(iaxs[callno], IAX_PROVISION);
11783
11784 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11785 }
11786 ast_mutex_unlock(&iaxsl[callno]);
11787
11788 return 1;
11789 }
11790
11791 static char *papp = "IAX2Provision";
11792
11793
11794
11795
11796 static int iax2_prov_app(struct ast_channel *chan, const char *data)
11797 {
11798 int res;
11799 char *sdata;
11800 char *opts;
11801 int force =0;
11802 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11803 if (ast_strlen_zero(data))
11804 data = "default";
11805 sdata = ast_strdupa(data);
11806 opts = strchr(sdata, '|');
11807 if (opts)
11808 *opts='\0';
11809
11810 if (chan->tech != &iax2_tech) {
11811 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11812 return -1;
11813 }
11814 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11815 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11816 return -1;
11817 }
11818 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11819 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11820 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11821 sdata, res);
11822 return res;
11823 }
11824
11825 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11826 {
11827 int force = 0;
11828 int res;
11829
11830 switch (cmd) {
11831 case CLI_INIT:
11832 e->command = "iax2 provision";
11833 e->usage =
11834 "Usage: iax2 provision <host> <template> [forced]\n"
11835 " Provisions the given peer or IP address using a template\n"
11836 " matching either 'template' or '*' if the template is not\n"
11837 " found. If 'forced' is specified, even empty provisioning\n"
11838 " fields will be provisioned as empty fields.\n";
11839 return NULL;
11840 case CLI_GENERATE:
11841 if (a->pos == 3)
11842 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11843 return NULL;
11844 }
11845
11846 if (a->argc < 4)
11847 return CLI_SHOWUSAGE;
11848 if (a->argc > 4) {
11849 if (!strcasecmp(a->argv[4], "forced"))
11850 force = 1;
11851 else
11852 return CLI_SHOWUSAGE;
11853 }
11854 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11855 if (res < 0)
11856 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11857 else if (res < 1)
11858 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11859 else
11860 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11861 return CLI_SUCCESS;
11862 }
11863
11864 static void __iax2_poke_noanswer(const void *data)
11865 {
11866 struct iax2_peer *peer = (struct iax2_peer *)data;
11867 int callno;
11868
11869 if (peer->lastms > -1) {
11870 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11871 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11872 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11873 }
11874 if ((callno = peer->callno) > 0) {
11875 ast_mutex_lock(&iaxsl[callno]);
11876 iax2_destroy(callno);
11877 ast_mutex_unlock(&iaxsl[callno]);
11878 }
11879 peer->callno = 0;
11880 peer->lastms = -1;
11881
11882 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11883 if (peer->pokeexpire == -1)
11884 peer_unref(peer);
11885 }
11886
11887 static int iax2_poke_noanswer(const void *data)
11888 {
11889 struct iax2_peer *peer = (struct iax2_peer *)data;
11890 peer->pokeexpire = -1;
11891 #ifdef SCHED_MULTITHREADED
11892 if (schedule_action(__iax2_poke_noanswer, data))
11893 #endif
11894 __iax2_poke_noanswer(data);
11895 peer_unref(peer);
11896 return 0;
11897 }
11898
11899 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11900 {
11901 struct iax2_peer *peer = obj;
11902
11903 iax2_poke_peer(peer, 0);
11904
11905 return 0;
11906 }
11907
11908 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11909 {
11910 int callno;
11911 struct sockaddr_in peer_addr;
11912
11913 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
11914
11915
11916 peer->lastms = 0;
11917 peer->historicms = 0;
11918 peer->pokeexpire = -1;
11919 peer->callno = 0;
11920 return 0;
11921 }
11922
11923 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
11924
11925
11926 if ((callno = peer->callno) > 0) {
11927 ast_log(LOG_NOTICE, "Still have a callno...\n");
11928 ast_mutex_lock(&iaxsl[callno]);
11929 iax2_destroy(callno);
11930 ast_mutex_unlock(&iaxsl[callno]);
11931 }
11932 if (heldcall)
11933 ast_mutex_unlock(&iaxsl[heldcall]);
11934 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
11935 if (heldcall)
11936 ast_mutex_lock(&iaxsl[heldcall]);
11937 if (peer->callno < 1) {
11938 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11939 return -1;
11940 }
11941
11942
11943 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11944 iaxs[peer->callno]->peerpoke = peer;
11945
11946 if (peer->pokeexpire > -1) {
11947 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
11948 peer->pokeexpire = -1;
11949 peer_unref(peer);
11950 }
11951 }
11952
11953
11954
11955 if (peer->lastms < 0)
11956 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11957 else
11958 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11959
11960 if (peer->pokeexpire == -1)
11961 peer_unref(peer);
11962
11963
11964 ast_mutex_lock(&iaxsl[callno]);
11965 if (iaxs[callno]) {
11966 struct iax_ie_data ied = {
11967 .buf = { 0 },
11968 .pos = 0,
11969 };
11970 add_empty_calltoken_ie(iaxs[callno], &ied);
11971 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11972 }
11973 ast_mutex_unlock(&iaxsl[callno]);
11974
11975 return 0;
11976 }
11977
11978 static void free_context(struct iax2_context *con)
11979 {
11980 struct iax2_context *conl;
11981 while(con) {
11982 conl = con;
11983 con = con->next;
11984 ast_free(conl);
11985 }
11986 }
11987
11988 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
11989 {
11990 int callno;
11991 int res;
11992 format_t fmt, native;
11993 struct sockaddr_in sin;
11994 struct ast_channel *c;
11995 struct parsed_dial_string pds;
11996 struct create_addr_info cai;
11997 char *tmpstr;
11998
11999 memset(&pds, 0, sizeof(pds));
12000 tmpstr = ast_strdupa(data);
12001 parse_dial_string(tmpstr, &pds);
12002
12003 if (ast_strlen_zero(pds.peer)) {
12004 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12005 return NULL;
12006 }
12007
12008 memset(&cai, 0, sizeof(cai));
12009 cai.capability = iax2_capability;
12010
12011 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12012
12013
12014 if (create_addr(pds.peer, NULL, &sin, &cai)) {
12015 *cause = AST_CAUSE_UNREGISTERED;
12016 return NULL;
12017 }
12018
12019 if (pds.port)
12020 sin.sin_port = htons(atoi(pds.port));
12021
12022 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12023 if (callno < 1) {
12024 ast_log(LOG_WARNING, "Unable to create call\n");
12025 *cause = AST_CAUSE_CONGESTION;
12026 return NULL;
12027 }
12028
12029
12030 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12031 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12032 int new_callno;
12033 if ((new_callno = make_trunk(callno, 1)) != -1)
12034 callno = new_callno;
12035 }
12036 iaxs[callno]->maxtime = cai.maxtime;
12037 if (cai.found)
12038 ast_string_field_set(iaxs[callno], host, pds.peer);
12039
12040 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
12041
12042 ast_mutex_unlock(&iaxsl[callno]);
12043
12044 if (c) {
12045
12046 if (c->nativeformats & format)
12047 c->nativeformats &= format;
12048 else {
12049 native = c->nativeformats;
12050 fmt = format;
12051 res = ast_translator_best_choice(&fmt, &native);
12052 if (res < 0) {
12053 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12054 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12055 ast_hangup(c);
12056 return NULL;
12057 }
12058 c->nativeformats = native;
12059 }
12060 c->readformat = ast_best_codec(c->nativeformats);
12061 c->writeformat = c->readformat;
12062 }
12063
12064 return c;
12065 }
12066
12067 static void *network_thread(void *ignore)
12068 {
12069 if (timer) {
12070 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12071 }
12072
12073 for (;;) {
12074 pthread_testcancel();
12075
12076
12077
12078 ast_io_wait(io, 1000);
12079 }
12080
12081 return NULL;
12082 }
12083
12084 static int start_network_thread(void)
12085 {
12086 struct iax2_thread *thread;
12087 int threadcount = 0;
12088 int x;
12089 for (x = 0; x < iaxthreadcount; x++) {
12090 thread = ast_calloc(1, sizeof(*thread));
12091 if (thread) {
12092 thread->type = IAX_THREAD_TYPE_POOL;
12093 thread->threadnum = ++threadcount;
12094 ast_mutex_init(&thread->lock);
12095 ast_cond_init(&thread->cond, NULL);
12096 ast_mutex_init(&thread->init_lock);
12097 ast_cond_init(&thread->init_cond, NULL);
12098 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12099 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12100 ast_mutex_destroy(&thread->lock);
12101 ast_cond_destroy(&thread->cond);
12102 ast_mutex_destroy(&thread->init_lock);
12103 ast_cond_destroy(&thread->init_cond);
12104 ast_free(thread);
12105 thread = NULL;
12106 continue;
12107 }
12108 AST_LIST_LOCK(&idle_list);
12109 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12110 AST_LIST_UNLOCK(&idle_list);
12111 }
12112 }
12113 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12114 ast_verb(2, "%d helper threads started\n", threadcount);
12115 return 0;
12116 }
12117
12118 static struct iax2_context *build_context(const char *context)
12119 {
12120 struct iax2_context *con;
12121
12122 if ((con = ast_calloc(1, sizeof(*con))))
12123 ast_copy_string(con->context, context, sizeof(con->context));
12124
12125 return con;
12126 }
12127
12128 static int get_auth_methods(const char *value)
12129 {
12130 int methods = 0;
12131 if (strstr(value, "rsa"))
12132 methods |= IAX_AUTH_RSA;
12133 if (strstr(value, "md5"))
12134 methods |= IAX_AUTH_MD5;
12135 if (strstr(value, "plaintext"))
12136 methods |= IAX_AUTH_PLAINTEXT;
12137 return methods;
12138 }
12139
12140
12141
12142
12143
12144 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
12145 {
12146 int sd;
12147 int res;
12148
12149 sd = socket(AF_INET, SOCK_DGRAM, 0);
12150 if (sd < 0) {
12151 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12152 return -1;
12153 }
12154
12155 res = bind(sd, sa, salen);
12156 if (res < 0) {
12157 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12158 close(sd);
12159 return 1;
12160 }
12161
12162 close(sd);
12163 return 0;
12164 }
12165
12166
12167
12168
12169 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12170 {
12171 struct sockaddr_in sin;
12172 struct ast_sockaddr sin_tmp;
12173 int nonlocal = 1;
12174 int port = IAX_DEFAULT_PORTNO;
12175 int sockfd = defaultsockfd;
12176 char *tmp;
12177 char *addr;
12178 char *portstr;
12179
12180 if (!(tmp = ast_strdupa(srcaddr)))
12181 return -1;
12182
12183 addr = strsep(&tmp, ":");
12184 portstr = tmp;
12185
12186 if (portstr) {
12187 port = atoi(portstr);
12188 if (port < 1)
12189 port = IAX_DEFAULT_PORTNO;
12190 }
12191
12192 if (!ast_get_ip(&sin_tmp, addr)) {
12193 struct ast_netsock *sock;
12194 int res;
12195
12196 ast_sockaddr_to_sin(&sin_tmp, &sin);
12197 sin.sin_port = 0;
12198 sin.sin_family = AF_INET;
12199 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12200 if (res == 0) {
12201
12202 sin.sin_port = htons(port);
12203 if (!(sock = ast_netsock_find(netsock, &sin)))
12204 sock = ast_netsock_find(outsock, &sin);
12205 if (sock) {
12206 sockfd = ast_netsock_sockfd(sock);
12207 nonlocal = 0;
12208 } else {
12209 unsigned int orig_saddr = sin.sin_addr.s_addr;
12210
12211 sin.sin_addr.s_addr = INADDR_ANY;
12212 if (ast_netsock_find(netsock, &sin)) {
12213 sin.sin_addr.s_addr = orig_saddr;
12214 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12215 if (sock) {
12216 sockfd = ast_netsock_sockfd(sock);
12217 ast_netsock_unref(sock);
12218 nonlocal = 0;
12219 } else {
12220 nonlocal = 2;
12221 }
12222 }
12223 }
12224 }
12225 }
12226
12227 peer->sockfd = sockfd;
12228
12229 if (nonlocal == 1) {
12230 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12231 srcaddr, peer->name);
12232 return -1;
12233 } else if (nonlocal == 2) {
12234 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12235 srcaddr, peer->name);
12236 return -1;
12237 } else {
12238 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12239 return 0;
12240 }
12241 }
12242
12243 static void peer_destructor(void *obj)
12244 {
12245 struct iax2_peer *peer = obj;
12246 int callno = peer->callno;
12247
12248 ast_free_ha(peer->ha);
12249
12250 if (callno > 0) {
12251 ast_mutex_lock(&iaxsl[callno]);
12252 iax2_destroy(callno);
12253 ast_mutex_unlock(&iaxsl[callno]);
12254 }
12255
12256 register_peer_exten(peer, 0);
12257
12258 if (peer->dnsmgr)
12259 ast_dnsmgr_release(peer->dnsmgr);
12260
12261 if (peer->mwi_event_sub)
12262 ast_event_unsubscribe(peer->mwi_event_sub);
12263
12264 ast_string_field_free_memory(peer);
12265 }
12266
12267
12268 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12269 {
12270 struct iax2_peer *peer = NULL;
12271 struct ast_ha *oldha = NULL;
12272 int maskfound = 0;
12273 int found = 0;
12274 int firstpass = 1;
12275 struct iax2_peer tmp_peer = {
12276 .name = name,
12277 };
12278
12279 if (!temponly) {
12280 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12281 if (peer && !ast_test_flag64(peer, IAX_DELME))
12282 firstpass = 0;
12283 }
12284
12285 if (peer) {
12286 found++;
12287 if (firstpass) {
12288 oldha = peer->ha;
12289 peer->ha = NULL;
12290 }
12291 unlink_peer(peer);
12292 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12293 peer->expire = -1;
12294 peer->pokeexpire = -1;
12295 peer->sockfd = defaultsockfd;
12296 if (ast_string_field_init(peer, 32))
12297 peer = peer_unref(peer);
12298 }
12299
12300 if (peer) {
12301 if (firstpass) {
12302 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12303 peer->encmethods = iax2_encryption;
12304 peer->adsi = adsi;
12305 ast_string_field_set(peer,secret,"");
12306 if (!found) {
12307 ast_string_field_set(peer, name, name);
12308 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12309 peer->expiry = min_reg_expire;
12310 }
12311 peer->prefs = prefs;
12312 peer->capability = iax2_capability;
12313 peer->smoothing = 0;
12314 peer->pokefreqok = DEFAULT_FREQ_OK;
12315 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12316 peer->maxcallno = 0;
12317 peercnt_modify(0, 0, &peer->addr);
12318 peer->calltoken_required = CALLTOKEN_DEFAULT;
12319 ast_string_field_set(peer,context,"");
12320 ast_string_field_set(peer,peercontext,"");
12321 ast_clear_flag64(peer, IAX_HASCALLERID);
12322 ast_string_field_set(peer, cid_name, "");
12323 ast_string_field_set(peer, cid_num, "");
12324 ast_string_field_set(peer, mohinterpret, mohinterpret);
12325 ast_string_field_set(peer, mohsuggest, mohsuggest);
12326 }
12327
12328 if (!v) {
12329 v = alt;
12330 alt = NULL;
12331 }
12332 while(v) {
12333 if (!strcasecmp(v->name, "secret")) {
12334 ast_string_field_set(peer, secret, v->value);
12335 } else if (!strcasecmp(v->name, "mailbox")) {
12336 ast_string_field_set(peer, mailbox, v->value);
12337 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12338 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12339 ast_string_field_set(peer, mailbox, name);
12340 }
12341 } else if (!strcasecmp(v->name, "mohinterpret")) {
12342 ast_string_field_set(peer, mohinterpret, v->value);
12343 } else if (!strcasecmp(v->name, "mohsuggest")) {
12344 ast_string_field_set(peer, mohsuggest, v->value);
12345 } else if (!strcasecmp(v->name, "dbsecret")) {
12346 ast_string_field_set(peer, dbsecret, v->value);
12347 } else if (!strcasecmp(v->name, "trunk")) {
12348 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12349 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12350 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12351 ast_clear_flag64(peer, IAX_TRUNK);
12352 }
12353 } else if (!strcasecmp(v->name, "auth")) {
12354 peer->authmethods = get_auth_methods(v->value);
12355 } else if (!strcasecmp(v->name, "encryption")) {
12356 peer->encmethods |= get_encrypt_methods(v->value);
12357 if (!peer->encmethods) {
12358 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12359 }
12360 } else if (!strcasecmp(v->name, "forceencryption")) {
12361 if (ast_false(v->value)) {
12362 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12363 } else {
12364 peer->encmethods |= get_encrypt_methods(v->value);
12365 if (peer->encmethods) {
12366 ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12367 }
12368 }
12369 } else if (!strcasecmp(v->name, "transfer")) {
12370 if (!strcasecmp(v->value, "mediaonly")) {
12371 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12372 } else if (ast_true(v->value)) {
12373 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12374 } else
12375 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12376 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12377 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12378 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12379 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12380 } else if (!strcasecmp(v->name, "host")) {
12381 if (!strcasecmp(v->value, "dynamic")) {
12382
12383 ast_set_flag64(peer, IAX_DYNAMIC);
12384 if (!found) {
12385
12386
12387 if (ast_sockaddr_port(&peer->addr)) {
12388 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12389 }
12390 ast_sockaddr_setnull(&peer->addr);
12391 }
12392 } else {
12393
12394 ast_sched_thread_del(sched, peer->expire);
12395 ast_clear_flag64(peer, IAX_DYNAMIC);
12396 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12397 return peer_unref(peer);
12398 if (!ast_sockaddr_port(&peer->addr)) {
12399 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12400 }
12401 }
12402 if (!maskfound)
12403 inet_aton("255.255.255.255", &peer->mask);
12404 } else if (!strcasecmp(v->name, "defaultip")) {
12405 struct ast_sockaddr peer_defaddr_tmp;
12406
12407 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12408 return peer_unref(peer);
12409 }
12410 ast_sockaddr_to_sin(&peer_defaddr_tmp,
12411 &peer->defaddr);
12412 } else if (!strcasecmp(v->name, "sourceaddress")) {
12413 peer_set_srcaddr(peer, v->value);
12414 } else if (!strcasecmp(v->name, "permit") ||
12415 !strcasecmp(v->name, "deny")) {
12416 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12417 } else if (!strcasecmp(v->name, "mask")) {
12418 maskfound++;
12419 inet_aton(v->value, &peer->mask);
12420 } else if (!strcasecmp(v->name, "context")) {
12421 ast_string_field_set(peer, context, v->value);
12422 } else if (!strcasecmp(v->name, "regexten")) {
12423 ast_string_field_set(peer, regexten, v->value);
12424 } else if (!strcasecmp(v->name, "peercontext")) {
12425 ast_string_field_set(peer, peercontext, v->value);
12426 } else if (!strcasecmp(v->name, "port")) {
12427 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12428 peer->defaddr.sin_port = htons(atoi(v->value));
12429 } else {
12430 ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12431 }
12432 } else if (!strcasecmp(v->name, "username")) {
12433 ast_string_field_set(peer, username, v->value);
12434 } else if (!strcasecmp(v->name, "allow")) {
12435 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12436 } else if (!strcasecmp(v->name, "disallow")) {
12437 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12438 } else if (!strcasecmp(v->name, "callerid")) {
12439 if (!ast_strlen_zero(v->value)) {
12440 char name2[80];
12441 char num2[80];
12442 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12443 ast_string_field_set(peer, cid_name, name2);
12444 ast_string_field_set(peer, cid_num, num2);
12445 } else {
12446 ast_string_field_set(peer, cid_name, "");
12447 ast_string_field_set(peer, cid_num, "");
12448 }
12449 ast_set_flag64(peer, IAX_HASCALLERID);
12450 } else if (!strcasecmp(v->name, "fullname")) {
12451 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12452 ast_set_flag64(peer, IAX_HASCALLERID);
12453 } else if (!strcasecmp(v->name, "cid_number")) {
12454 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12455 ast_set_flag64(peer, IAX_HASCALLERID);
12456 } else if (!strcasecmp(v->name, "sendani")) {
12457 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12458 } else if (!strcasecmp(v->name, "inkeys")) {
12459 ast_string_field_set(peer, inkeys, v->value);
12460 } else if (!strcasecmp(v->name, "outkey")) {
12461 ast_string_field_set(peer, outkey, v->value);
12462 } else if (!strcasecmp(v->name, "qualify")) {
12463 if (!strcasecmp(v->value, "no")) {
12464 peer->maxms = 0;
12465 } else if (!strcasecmp(v->value, "yes")) {
12466 peer->maxms = DEFAULT_MAXMS;
12467 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12468 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);
12469 peer->maxms = 0;
12470 }
12471 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12472 peer->smoothing = ast_true(v->value);
12473 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12474 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12475 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);
12476 }
12477 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12478 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12479 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);
12480 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12481 } else if (!strcasecmp(v->name, "timezone")) {
12482 ast_string_field_set(peer, zonetag, v->value);
12483 } else if (!strcasecmp(v->name, "adsi")) {
12484 peer->adsi = ast_true(v->value);
12485 } else if (!strcasecmp(v->name, "connectedline")) {
12486 if (ast_true(v->value)) {
12487 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12488 } else if (!strcasecmp(v->value, "send")) {
12489 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12490 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12491 } else if (!strcasecmp(v->value, "receive")) {
12492 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12493 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12494 } else {
12495 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12496 }
12497 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12498 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12499 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12500 } else {
12501 peercnt_modify(1, peer->maxcallno, &peer->addr);
12502 }
12503 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12504
12505 if (ast_false(v->value)) {
12506 peer->calltoken_required = CALLTOKEN_NO;
12507 } else if (!strcasecmp(v->value, "auto")) {
12508 peer->calltoken_required = CALLTOKEN_AUTO;
12509 } else if (ast_true(v->value)) {
12510 peer->calltoken_required = CALLTOKEN_YES;
12511 } else {
12512 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12513 }
12514 }
12515
12516 v = v->next;
12517 if (!v) {
12518 v = alt;
12519 alt = NULL;
12520 }
12521 }
12522 if (!peer->authmethods)
12523 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12524 ast_clear_flag64(peer, IAX_DELME);
12525 }
12526
12527 if (oldha)
12528 ast_free_ha(oldha);
12529
12530 if (!ast_strlen_zero(peer->mailbox)) {
12531 char *mailbox, *context;
12532 context = mailbox = ast_strdupa(peer->mailbox);
12533 strsep(&context, "@");
12534 if (ast_strlen_zero(context))
12535 context = "default";
12536 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12537 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12538 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12539 AST_EVENT_IE_END);
12540 }
12541
12542 return peer;
12543 }
12544
12545 static void user_destructor(void *obj)
12546 {
12547 struct iax2_user *user = obj;
12548
12549 ast_free_ha(user->ha);
12550 free_context(user->contexts);
12551 if(user->vars) {
12552 ast_variables_destroy(user->vars);
12553 user->vars = NULL;
12554 }
12555 ast_string_field_free_memory(user);
12556 }
12557
12558
12559 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12560 {
12561 struct iax2_user *user = NULL;
12562 struct iax2_context *con, *conl = NULL;
12563 struct ast_ha *oldha = NULL;
12564 struct iax2_context *oldcon = NULL;
12565 int format;
12566 int firstpass=1;
12567 int oldcurauthreq = 0;
12568 char *varname = NULL, *varval = NULL;
12569 struct ast_variable *tmpvar = NULL;
12570 struct iax2_user tmp_user = {
12571 .name = name,
12572 };
12573
12574 if (!temponly) {
12575 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12576 if (user && !ast_test_flag64(user, IAX_DELME))
12577 firstpass = 0;
12578 }
12579
12580 if (user) {
12581 if (firstpass) {
12582 oldcurauthreq = user->curauthreq;
12583 oldha = user->ha;
12584 oldcon = user->contexts;
12585 user->ha = NULL;
12586 user->contexts = NULL;
12587 }
12588
12589 ao2_unlink(users, user);
12590 } else {
12591 user = ao2_alloc(sizeof(*user), user_destructor);
12592 }
12593
12594 if (user) {
12595 if (firstpass) {
12596 ast_string_field_free_memory(user);
12597 memset(user, 0, sizeof(struct iax2_user));
12598 if (ast_string_field_init(user, 32)) {
12599 user = user_unref(user);
12600 goto cleanup;
12601 }
12602 user->maxauthreq = maxauthreq;
12603 user->curauthreq = oldcurauthreq;
12604 user->prefs = prefs;
12605 user->capability = iax2_capability;
12606 user->encmethods = iax2_encryption;
12607 user->adsi = adsi;
12608 user->calltoken_required = CALLTOKEN_DEFAULT;
12609 ast_string_field_set(user, name, name);
12610 ast_string_field_set(user, language, language);
12611 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);
12612 ast_clear_flag64(user, IAX_HASCALLERID);
12613 ast_string_field_set(user, cid_name, "");
12614 ast_string_field_set(user, cid_num, "");
12615 ast_string_field_set(user, accountcode, accountcode);
12616 ast_string_field_set(user, mohinterpret, mohinterpret);
12617 ast_string_field_set(user, mohsuggest, mohsuggest);
12618 }
12619 if (!v) {
12620 v = alt;
12621 alt = NULL;
12622 }
12623 while(v) {
12624 if (!strcasecmp(v->name, "context")) {
12625 con = build_context(v->value);
12626 if (con) {
12627 if (conl)
12628 conl->next = con;
12629 else
12630 user->contexts = con;
12631 conl = con;
12632 }
12633 } else if (!strcasecmp(v->name, "permit") ||
12634 !strcasecmp(v->name, "deny")) {
12635 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12636 } else if (!strcasecmp(v->name, "setvar")) {
12637 varname = ast_strdupa(v->value);
12638 if (varname && (varval = strchr(varname,'='))) {
12639 *varval = '\0';
12640 varval++;
12641 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12642 tmpvar->next = user->vars;
12643 user->vars = tmpvar;
12644 }
12645 }
12646 } else if (!strcasecmp(v->name, "allow")) {
12647 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12648 } else if (!strcasecmp(v->name, "disallow")) {
12649 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12650 } else if (!strcasecmp(v->name, "trunk")) {
12651 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
12652 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12653 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12654 ast_clear_flag64(user, IAX_TRUNK);
12655 }
12656 } else if (!strcasecmp(v->name, "auth")) {
12657 user->authmethods = get_auth_methods(v->value);
12658 } else if (!strcasecmp(v->name, "encryption")) {
12659 user->encmethods |= get_encrypt_methods(v->value);
12660 if (!user->encmethods) {
12661 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12662 }
12663 } else if (!strcasecmp(v->name, "forceencryption")) {
12664 if (ast_false(v->value)) {
12665 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12666 } else {
12667 user->encmethods |= get_encrypt_methods(v->value);
12668 if (user->encmethods) {
12669 ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12670 }
12671 }
12672 } else if (!strcasecmp(v->name, "transfer")) {
12673 if (!strcasecmp(v->value, "mediaonly")) {
12674 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12675 } else if (ast_true(v->value)) {
12676 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12677 } else
12678 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12679 } else if (!strcasecmp(v->name, "codecpriority")) {
12680 if(!strcasecmp(v->value, "caller"))
12681 ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12682 else if(!strcasecmp(v->value, "disabled"))
12683 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12684 else if(!strcasecmp(v->value, "reqonly")) {
12685 ast_set_flag64(user, IAX_CODEC_NOCAP);
12686 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12687 }
12688 } else if (!strcasecmp(v->name, "immediate")) {
12689 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12690 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12691 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12692 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12693 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12694 } else if (!strcasecmp(v->name, "dbsecret")) {
12695 ast_string_field_set(user, dbsecret, v->value);
12696 } else if (!strcasecmp(v->name, "secret")) {
12697 if (!ast_strlen_zero(user->secret)) {
12698 char *old = ast_strdupa(user->secret);
12699
12700 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12701 } else
12702 ast_string_field_set(user, secret, v->value);
12703 } else if (!strcasecmp(v->name, "callerid")) {
12704 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12705 char name2[80];
12706 char num2[80];
12707 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12708 ast_string_field_set(user, cid_name, name2);
12709 ast_string_field_set(user, cid_num, num2);
12710 ast_set_flag64(user, IAX_HASCALLERID);
12711 } else {
12712 ast_clear_flag64(user, IAX_HASCALLERID);
12713 ast_string_field_set(user, cid_name, "");
12714 ast_string_field_set(user, cid_num, "");
12715 }
12716 } else if (!strcasecmp(v->name, "fullname")) {
12717 if (!ast_strlen_zero(v->value)) {
12718 ast_string_field_set(user, cid_name, v->value);
12719 ast_set_flag64(user, IAX_HASCALLERID);
12720 } else {
12721 ast_string_field_set(user, cid_name, "");
12722 if (ast_strlen_zero(user->cid_num))
12723 ast_clear_flag64(user, IAX_HASCALLERID);
12724 }
12725 } else if (!strcasecmp(v->name, "cid_number")) {
12726 if (!ast_strlen_zero(v->value)) {
12727 ast_string_field_set(user, cid_num, v->value);
12728 ast_set_flag64(user, IAX_HASCALLERID);
12729 } else {
12730 ast_string_field_set(user, cid_num, "");
12731 if (ast_strlen_zero(user->cid_name))
12732 ast_clear_flag64(user, IAX_HASCALLERID);
12733 }
12734 } else if (!strcasecmp(v->name, "accountcode")) {
12735 ast_string_field_set(user, accountcode, v->value);
12736 } else if (!strcasecmp(v->name, "mohinterpret")) {
12737 ast_string_field_set(user, mohinterpret, v->value);
12738 } else if (!strcasecmp(v->name, "mohsuggest")) {
12739 ast_string_field_set(user, mohsuggest, v->value);
12740 } else if (!strcasecmp(v->name, "parkinglot")) {
12741 ast_string_field_set(user, parkinglot, v->value);
12742 } else if (!strcasecmp(v->name, "language")) {
12743 ast_string_field_set(user, language, v->value);
12744 } else if (!strcasecmp(v->name, "amaflags")) {
12745 format = ast_cdr_amaflags2int(v->value);
12746 if (format < 0) {
12747 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12748 } else {
12749 user->amaflags = format;
12750 }
12751 } else if (!strcasecmp(v->name, "inkeys")) {
12752 ast_string_field_set(user, inkeys, v->value);
12753 } else if (!strcasecmp(v->name, "maxauthreq")) {
12754 user->maxauthreq = atoi(v->value);
12755 if (user->maxauthreq < 0)
12756 user->maxauthreq = 0;
12757 } else if (!strcasecmp(v->name, "adsi")) {
12758 user->adsi = ast_true(v->value);
12759 } else if (!strcasecmp(v->name, "connectedline")) {
12760 if (ast_true(v->value)) {
12761 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12762 } else if (!strcasecmp(v->value, "send")) {
12763 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12764 ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12765 } else if (!strcasecmp(v->value, "receive")) {
12766 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12767 ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12768 } else {
12769 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12770 }
12771 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12772
12773 if (ast_false(v->value)) {
12774 user->calltoken_required = CALLTOKEN_NO;
12775 } else if (!strcasecmp(v->value, "auto")) {
12776 user->calltoken_required = CALLTOKEN_AUTO;
12777 } else if (ast_true(v->value)) {
12778 user->calltoken_required = CALLTOKEN_YES;
12779 } else {
12780 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12781 }
12782 }
12783
12784 v = v->next;
12785 if (!v) {
12786 v = alt;
12787 alt = NULL;
12788 }
12789 }
12790 if (!user->authmethods) {
12791 if (!ast_strlen_zero(user->secret)) {
12792 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12793 if (!ast_strlen_zero(user->inkeys))
12794 user->authmethods |= IAX_AUTH_RSA;
12795 } else if (!ast_strlen_zero(user->inkeys)) {
12796 user->authmethods = IAX_AUTH_RSA;
12797 } else {
12798 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12799 }
12800 }
12801 ast_clear_flag64(user, IAX_DELME);
12802 }
12803 cleanup:
12804 if (oldha)
12805 ast_free_ha(oldha);
12806 if (oldcon)
12807 free_context(oldcon);
12808 return user;
12809 }
12810
12811 static int peer_delme_cb(void *obj, void *arg, int flags)
12812 {
12813 struct iax2_peer *peer = obj;
12814
12815 ast_set_flag64(peer, IAX_DELME);
12816
12817 return 0;
12818 }
12819
12820 static int user_delme_cb(void *obj, void *arg, int flags)
12821 {
12822 struct iax2_user *user = obj;
12823
12824 ast_set_flag64(user, IAX_DELME);
12825
12826 return 0;
12827 }
12828
12829 static void delete_users(void)
12830 {
12831 struct iax2_registry *reg;
12832
12833 ao2_callback(users, 0, user_delme_cb, NULL);
12834
12835 AST_LIST_LOCK(®istrations);
12836 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12837 if (sched) {
12838 ast_sched_thread_del(sched, reg->expire);
12839 }
12840 if (reg->callno) {
12841 int callno = reg->callno;
12842 ast_mutex_lock(&iaxsl[callno]);
12843 if (iaxs[callno]) {
12844 iaxs[callno]->reg = NULL;
12845 iax2_destroy(callno);
12846 }
12847 ast_mutex_unlock(&iaxsl[callno]);
12848 }
12849 if (reg->dnsmgr)
12850 ast_dnsmgr_release(reg->dnsmgr);
12851 ast_free(reg);
12852 }
12853 AST_LIST_UNLOCK(®istrations);
12854
12855 ao2_callback(peers, 0, peer_delme_cb, NULL);
12856 }
12857
12858 static void prune_users(void)
12859 {
12860 struct iax2_user *user;
12861 struct ao2_iterator i;
12862
12863 i = ao2_iterator_init(users, 0);
12864 while ((user = ao2_iterator_next(&i))) {
12865 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
12866 ao2_unlink(users, user);
12867 }
12868 user_unref(user);
12869 }
12870 ao2_iterator_destroy(&i);
12871 }
12872
12873
12874 static void prune_peers(void)
12875 {
12876 struct iax2_peer *peer;
12877 struct ao2_iterator i;
12878
12879 i = ao2_iterator_init(peers, 0);
12880 while ((peer = ao2_iterator_next(&i))) {
12881 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
12882 unlink_peer(peer);
12883 }
12884 peer_unref(peer);
12885 }
12886 ao2_iterator_destroy(&i);
12887 }
12888
12889 static void set_config_destroy(void)
12890 {
12891 strcpy(accountcode, "");
12892 strcpy(language, "");
12893 strcpy(mohinterpret, "default");
12894 strcpy(mohsuggest, "");
12895 trunkmaxsize = MAX_TRUNKDATA;
12896 amaflags = 0;
12897 delayreject = 0;
12898 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF |
12899 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12900 delete_users();
12901 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12902 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12903 }
12904
12905
12906 static int set_config(const char *config_file, int reload)
12907 {
12908 struct ast_config *cfg, *ucfg;
12909 format_t capability = iax2_capability;
12910 struct ast_variable *v;
12911 char *cat;
12912 const char *utype;
12913 const char *tosval;
12914 int format;
12915 int portno = IAX_DEFAULT_PORTNO;
12916 int x;
12917 int mtuv;
12918 int subscribe_network_change = 1;
12919 struct iax2_user *user;
12920 struct iax2_peer *peer;
12921 struct ast_netsock *ns;
12922 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12923 #if 0
12924 static unsigned short int last_port=0;
12925 #endif
12926
12927 cfg = ast_config_load(config_file, config_flags);
12928
12929 if (!cfg) {
12930 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12931 return -1;
12932 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12933 ucfg = ast_config_load("users.conf", config_flags);
12934 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12935 return 0;
12936
12937 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12938 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
12939 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12940 ast_config_destroy(ucfg);
12941 return 0;
12942 }
12943 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
12944 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12945 return 0;
12946 } else {
12947 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12948 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
12949 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
12950 ast_config_destroy(cfg);
12951 return 0;
12952 }
12953 }
12954
12955 if (reload) {
12956 set_config_destroy();
12957 }
12958
12959
12960 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12961
12962
12963 memset(&globalflags, 0, sizeof(globalflags));
12964 ast_set_flag64(&globalflags, IAX_RTUPDATE);
12965 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
12966
12967 #ifdef SO_NO_CHECK
12968 nochecksums = 0;
12969 #endif
12970
12971 default_parkinglot[0] = '\0';
12972
12973 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12974 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12975 global_max_trunk_mtu = MAX_TRUNK_MTU;
12976 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12977 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12978
12979 maxauthreq = 3;
12980
12981 srvlookup = 0;
12982
12983 v = ast_variable_browse(cfg, "general");
12984
12985
12986 tosval = ast_variable_retrieve(cfg, "general", "tos");
12987 if (tosval) {
12988 if (ast_str2tos(tosval, &qos.tos))
12989 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
12990 }
12991
12992 tosval = ast_variable_retrieve(cfg, "general", "cos");
12993 if (tosval) {
12994 if (ast_str2cos(tosval, &qos.cos))
12995 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
12996 }
12997 while(v) {
12998 if (!strcasecmp(v->name, "bindport")){
12999 if (reload)
13000 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13001 else
13002 portno = atoi(v->value);
13003 } else if (!strcasecmp(v->name, "pingtime"))
13004 ping_time = atoi(v->value);
13005 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13006 if (reload) {
13007 if (atoi(v->value) != iaxthreadcount)
13008 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13009 } else {
13010 iaxthreadcount = atoi(v->value);
13011 if (iaxthreadcount < 1) {
13012 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13013 iaxthreadcount = 1;
13014 } else if (iaxthreadcount > 256) {
13015 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13016 iaxthreadcount = 256;
13017 }
13018 }
13019 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13020 if (reload) {
13021 AST_LIST_LOCK(&dynamic_list);
13022 iaxmaxthreadcount = atoi(v->value);
13023 AST_LIST_UNLOCK(&dynamic_list);
13024 } else {
13025 iaxmaxthreadcount = atoi(v->value);
13026 if (iaxmaxthreadcount < 0) {
13027 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13028 iaxmaxthreadcount = 0;
13029 } else if (iaxmaxthreadcount > 256) {
13030 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13031 iaxmaxthreadcount = 256;
13032 }
13033 }
13034 } else if (!strcasecmp(v->name, "nochecksums")) {
13035 #ifdef SO_NO_CHECK
13036 if (ast_true(v->value))
13037 nochecksums = 1;
13038 else
13039 nochecksums = 0;
13040 #else
13041 if (ast_true(v->value))
13042 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13043 #endif
13044 }
13045 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13046 maxjitterbuffer = atoi(v->value);
13047 else if (!strcasecmp(v->name, "resyncthreshold"))
13048 resyncthreshold = atoi(v->value);
13049 else if (!strcasecmp(v->name, "maxjitterinterps"))
13050 maxjitterinterps = atoi(v->value);
13051 else if (!strcasecmp(v->name, "jittertargetextra"))
13052 jittertargetextra = atoi(v->value);
13053 else if (!strcasecmp(v->name, "lagrqtime"))
13054 lagrq_time = atoi(v->value);
13055 else if (!strcasecmp(v->name, "maxregexpire"))
13056 max_reg_expire = atoi(v->value);
13057 else if (!strcasecmp(v->name, "minregexpire"))
13058 min_reg_expire = atoi(v->value);
13059 else if (!strcasecmp(v->name, "bindaddr")) {
13060 if (reload) {
13061 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13062 } else {
13063 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13064 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13065 } else {
13066 if (strchr(v->value, ':'))
13067 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13068 else
13069 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13070 if (defaultsockfd < 0)
13071 defaultsockfd = ast_netsock_sockfd(ns);
13072 ast_netsock_unref(ns);
13073 }
13074 }
13075 } else if (!strcasecmp(v->name, "authdebug")) {
13076 authdebug = ast_true(v->value);
13077 } else if (!strcasecmp(v->name, "encryption")) {
13078 iax2_encryption |= get_encrypt_methods(v->value);
13079 if (!iax2_encryption) {
13080 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13081 }
13082 } else if (!strcasecmp(v->name, "forceencryption")) {
13083 if (ast_false(v->value)) {
13084 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13085 } else {
13086 iax2_encryption |= get_encrypt_methods(v->value);
13087 if (iax2_encryption) {
13088 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13089 }
13090 }
13091 } else if (!strcasecmp(v->name, "transfer")) {
13092 if (!strcasecmp(v->value, "mediaonly")) {
13093 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13094 } else if (ast_true(v->value)) {
13095 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13096 } else
13097 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13098 } else if (!strcasecmp(v->name, "codecpriority")) {
13099 if(!strcasecmp(v->value, "caller"))
13100 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13101 else if(!strcasecmp(v->value, "disabled"))
13102 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13103 else if(!strcasecmp(v->value, "reqonly")) {
13104 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13105 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13106 }
13107 } else if (!strcasecmp(v->name, "jitterbuffer"))
13108 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13109 else if (!strcasecmp(v->name, "forcejitterbuffer"))
13110 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13111 else if (!strcasecmp(v->name, "delayreject"))
13112 delayreject = ast_true(v->value);
13113 else if (!strcasecmp(v->name, "allowfwdownload"))
13114 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13115 else if (!strcasecmp(v->name, "rtcachefriends"))
13116 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13117 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13118 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13119 else if (!strcasecmp(v->name, "rtupdate"))
13120 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13121 else if (!strcasecmp(v->name, "rtsavesysname"))
13122 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13123 else if (!strcasecmp(v->name, "trunktimestamps"))
13124 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13125 else if (!strcasecmp(v->name, "rtautoclear")) {
13126 int i = atoi(v->value);
13127 if(i > 0)
13128 global_rtautoclear = i;
13129 else
13130 i = 0;
13131 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13132 } else if (!strcasecmp(v->name, "trunkfreq")) {
13133 trunkfreq = atoi(v->value);
13134 if (trunkfreq < 10)
13135 trunkfreq = 10;
13136 } else if (!strcasecmp(v->name, "trunkmtu")) {
13137 mtuv = atoi(v->value);
13138 if (mtuv == 0 )
13139 global_max_trunk_mtu = 0;
13140 else if (mtuv >= 172 && mtuv < 4000)
13141 global_max_trunk_mtu = mtuv;
13142 else
13143 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13144 mtuv, v->lineno);
13145 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13146 trunkmaxsize = atoi(v->value);
13147 if (trunkmaxsize == 0)
13148 trunkmaxsize = MAX_TRUNKDATA;
13149 } else if (!strcasecmp(v->name, "autokill")) {
13150 if (sscanf(v->value, "%30d", &x) == 1) {
13151 if (x >= 0)
13152 autokill = x;
13153 else
13154 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13155 } else if (ast_true(v->value)) {
13156 autokill = DEFAULT_MAXMS;
13157 } else {
13158 autokill = 0;
13159 }
13160 } else if (!strcasecmp(v->name, "bandwidth")) {
13161 if (!strcasecmp(v->value, "low")) {
13162 capability = IAX_CAPABILITY_LOWBANDWIDTH;
13163 } else if (!strcasecmp(v->value, "medium")) {
13164 capability = IAX_CAPABILITY_MEDBANDWIDTH;
13165 } else if (!strcasecmp(v->value, "high")) {
13166 capability = IAX_CAPABILITY_FULLBANDWIDTH;
13167 } else
13168 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13169 } else if (!strcasecmp(v->name, "allow")) {
13170 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13171 } else if (!strcasecmp(v->name, "disallow")) {
13172 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13173 } else if (!strcasecmp(v->name, "register")) {
13174 iax2_register(v->value, v->lineno);
13175 } else if (!strcasecmp(v->name, "iaxcompat")) {
13176 iaxcompat = ast_true(v->value);
13177 } else if (!strcasecmp(v->name, "regcontext")) {
13178 ast_copy_string(regcontext, v->value, sizeof(regcontext));
13179
13180 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13181 } else if (!strcasecmp(v->name, "tos")) {
13182 if (ast_str2tos(v->value, &qos.tos))
13183 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13184 } else if (!strcasecmp(v->name, "cos")) {
13185 if (ast_str2cos(v->value, &qos.cos))
13186 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13187 } else if (!strcasecmp(v->name, "parkinglot")) {
13188 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13189 } else if (!strcasecmp(v->name, "accountcode")) {
13190 ast_copy_string(accountcode, v->value, sizeof(accountcode));
13191 } else if (!strcasecmp(v->name, "mohinterpret")) {
13192 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13193 } else if (!strcasecmp(v->name, "mohsuggest")) {
13194 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13195 } else if (!strcasecmp(v->name, "amaflags")) {
13196 format = ast_cdr_amaflags2int(v->value);
13197 if (format < 0) {
13198 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13199 } else {
13200 amaflags = format;
13201 }
13202 } else if (!strcasecmp(v->name, "language")) {
13203 ast_copy_string(language, v->value, sizeof(language));
13204 } else if (!strcasecmp(v->name, "maxauthreq")) {
13205 maxauthreq = atoi(v->value);
13206 if (maxauthreq < 0)
13207 maxauthreq = 0;
13208 } else if (!strcasecmp(v->name, "adsi")) {
13209 adsi = ast_true(v->value);
13210 } else if (!strcasecmp(v->name, "srvlookup")) {
13211 srvlookup = ast_true(v->value);
13212 } else if (!strcasecmp(v->name, "connectedline")) {
13213 if (ast_true(v->value)) {
13214 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13215 } else if (!strcasecmp(v->value, "send")) {
13216 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13217 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13218 } else if (!strcasecmp(v->value, "receive")) {
13219 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13220 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13221 } else {
13222 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13223 }
13224 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13225 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13226 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
13227 }
13228 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13229 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13230 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);
13231 }
13232 } else if (!strcasecmp(v->name, "calltokenoptional")) {
13233 if (add_calltoken_ignore(v->value)) {
13234 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13235 }
13236 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13237 if (ast_true(v->value)) {
13238 subscribe_network_change = 1;
13239 } else if (ast_false(v->value)) {
13240 subscribe_network_change = 0;
13241 } else {
13242 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13243 }
13244 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13245 if (ast_true(v->value)) {
13246 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13247 } else if (ast_false(v->value)) {
13248 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13249 } else {
13250 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13251 }
13252 }
13253
13254 v = v->next;
13255 }
13256
13257 if (subscribe_network_change) {
13258 network_change_event_subscribe();
13259 } else {
13260 network_change_event_unsubscribe();
13261 }
13262
13263 if (defaultsockfd < 0) {
13264 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13265 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13266 } else {
13267 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13268 defaultsockfd = ast_netsock_sockfd(ns);
13269 ast_netsock_unref(ns);
13270 }
13271 }
13272 if (reload) {
13273 ast_netsock_release(outsock);
13274 outsock = ast_netsock_list_alloc();
13275 if (!outsock) {
13276 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13277 return -1;
13278 }
13279 ast_netsock_init(outsock);
13280 }
13281
13282 if (min_reg_expire > max_reg_expire) {
13283 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13284 min_reg_expire, max_reg_expire, max_reg_expire);
13285 min_reg_expire = max_reg_expire;
13286 }
13287 iax2_capability = capability;
13288
13289 if (ucfg) {
13290 struct ast_variable *gen;
13291 int genhasiax;
13292 int genregisteriax;
13293 const char *hasiax, *registeriax;
13294
13295 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13296 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13297 gen = ast_variable_browse(ucfg, "general");
13298 cat = ast_category_browse(ucfg, NULL);
13299 while (cat) {
13300 if (strcasecmp(cat, "general")) {
13301 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13302 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13303 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13304
13305 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13306 if (user) {
13307 ao2_link(users, user);
13308 user = user_unref(user);
13309 }
13310 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13311 if (peer) {
13312 if (ast_test_flag64(peer, IAX_DYNAMIC))
13313 reg_source_db(peer);
13314 ao2_link(peers, peer);
13315 peer = peer_unref(peer);
13316 }
13317 }
13318 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13319 char tmp[256];
13320 const char *host = ast_variable_retrieve(ucfg, cat, "host");
13321 const char *username = ast_variable_retrieve(ucfg, cat, "username");
13322 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13323 if (!host)
13324 host = ast_variable_retrieve(ucfg, "general", "host");
13325 if (!username)
13326 username = ast_variable_retrieve(ucfg, "general", "username");
13327 if (!secret)
13328 secret = ast_variable_retrieve(ucfg, "general", "secret");
13329 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13330 if (!ast_strlen_zero(secret))
13331 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13332 else
13333 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13334 iax2_register(tmp, 0);
13335 }
13336 }
13337 }
13338 cat = ast_category_browse(ucfg, cat);
13339 }
13340 ast_config_destroy(ucfg);
13341 }
13342
13343 cat = ast_category_browse(cfg, NULL);
13344 while(cat) {
13345 if (strcasecmp(cat, "general")) {
13346 utype = ast_variable_retrieve(cfg, cat, "type");
13347 if (!strcasecmp(cat, "callnumberlimits")) {
13348 build_callno_limits(ast_variable_browse(cfg, cat));
13349 } else if (utype) {
13350 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13351 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13352 if (user) {
13353 ao2_link(users, user);
13354 user = user_unref(user);
13355 }
13356 }
13357 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13358 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13359 if (peer) {
13360 if (ast_test_flag64(peer, IAX_DYNAMIC))
13361 reg_source_db(peer);
13362 ao2_link(peers, peer);
13363 peer = peer_unref(peer);
13364 }
13365 } else if (strcasecmp(utype, "user")) {
13366 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13367 }
13368 } else
13369 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13370 }
13371 cat = ast_category_browse(cfg, cat);
13372 }
13373 ast_config_destroy(cfg);
13374 return 1;
13375 }
13376
13377 static void poke_all_peers(void)
13378 {
13379 struct ao2_iterator i;
13380 struct iax2_peer *peer;
13381
13382 i = ao2_iterator_init(peers, 0);
13383 while ((peer = ao2_iterator_next(&i))) {
13384 iax2_poke_peer(peer, 0);
13385 peer_unref(peer);
13386 }
13387 ao2_iterator_destroy(&i);
13388 }
13389 static int reload_config(void)
13390 {
13391 static const char config[] = "iax.conf";
13392 struct iax2_registry *reg;
13393
13394 if (set_config(config, 1) > 0) {
13395 prune_peers();
13396 prune_users();
13397 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13398 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13399 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13400 trunk_timed = trunk_untimed = 0;
13401 trunk_nmaxmtu = trunk_maxmtu = 0;
13402 memset(&debugaddr, '\0', sizeof(debugaddr));
13403
13404 AST_LIST_LOCK(®istrations);
13405 AST_LIST_TRAVERSE(®istrations, reg, entry)
13406 iax2_do_register(reg);
13407 AST_LIST_UNLOCK(®istrations);
13408
13409
13410 poke_all_peers();
13411 }
13412
13413 reload_firmware(0);
13414 iax_provision_reload(1);
13415 ast_unload_realtime("iaxpeers");
13416
13417 return 0;
13418 }
13419
13420 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13421 {
13422 switch (cmd) {
13423 case CLI_INIT:
13424 e->command = "iax2 reload";
13425 e->usage =
13426 "Usage: iax2 reload\n"
13427 " Reloads IAX configuration from iax.conf\n";
13428 return NULL;
13429 case CLI_GENERATE:
13430 return NULL;
13431 }
13432
13433 reload_config();
13434
13435 return CLI_SUCCESS;
13436 }
13437
13438 static int reload(void)
13439 {
13440 return reload_config();
13441 }
13442
13443 static int cache_get_callno_locked(const char *data)
13444 {
13445 struct sockaddr_in sin;
13446 int x;
13447 int callno;
13448 struct iax_ie_data ied;
13449 struct create_addr_info cai;
13450 struct parsed_dial_string pds;
13451 char *tmpstr;
13452
13453 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13454
13455
13456 if (!ast_mutex_trylock(&iaxsl[x])) {
13457 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13458 return x;
13459 ast_mutex_unlock(&iaxsl[x]);
13460 }
13461 }
13462
13463
13464
13465 memset(&cai, 0, sizeof(cai));
13466 memset(&ied, 0, sizeof(ied));
13467 memset(&pds, 0, sizeof(pds));
13468
13469 tmpstr = ast_strdupa(data);
13470 parse_dial_string(tmpstr, &pds);
13471
13472 if (ast_strlen_zero(pds.peer)) {
13473 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13474 return -1;
13475 }
13476
13477
13478 if (create_addr(pds.peer, NULL, &sin, &cai))
13479 return -1;
13480
13481 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13482 pds.peer, pds.username, pds.password, pds.context);
13483
13484 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13485 if (callno < 1) {
13486 ast_log(LOG_WARNING, "Unable to create call\n");
13487 return -1;
13488 }
13489
13490 ast_string_field_set(iaxs[callno], dproot, data);
13491 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13492
13493 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13494 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13495
13496
13497
13498 if (pds.exten)
13499 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13500 if (pds.username)
13501 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13502 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13503 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13504
13505 if (pds.password)
13506 ast_string_field_set(iaxs[callno], secret, pds.password);
13507 if (pds.key)
13508 ast_string_field_set(iaxs[callno], outkey, pds.key);
13509
13510 add_empty_calltoken_ie(iaxs[callno], &ied);
13511 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13512
13513 return callno;
13514 }
13515
13516 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13517 {
13518 struct iax2_dpcache *dp = NULL;
13519 struct timeval now = ast_tvnow();
13520 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13521 struct ast_channel *c = NULL;
13522 struct ast_frame *f = NULL;
13523
13524 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13525 if (ast_tvcmp(now, dp->expiry) > 0) {
13526 AST_LIST_REMOVE_CURRENT(cache_list);
13527 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13528 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13529 else
13530 ast_free(dp);
13531 continue;
13532 }
13533 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13534 break;
13535 }
13536 AST_LIST_TRAVERSE_SAFE_END;
13537
13538 if (!dp) {
13539
13540
13541 if ((callno = cache_get_callno_locked(data)) < 0) {
13542 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13543 return NULL;
13544 }
13545 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13546 ast_mutex_unlock(&iaxsl[callno]);
13547 return NULL;
13548 }
13549 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13550 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13551 dp->expiry = ast_tvnow();
13552 dp->orig = dp->expiry;
13553
13554 dp->expiry.tv_sec += iaxdefaultdpcache;
13555 dp->flags = CACHE_FLAG_PENDING;
13556 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13557 dp->waiters[x] = -1;
13558
13559 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13560 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13561
13562 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13563 iax2_dprequest(dp, callno);
13564 ast_mutex_unlock(&iaxsl[callno]);
13565 }
13566
13567
13568 if (dp->flags & CACHE_FLAG_PENDING) {
13569
13570
13571 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13572
13573 if (dp->waiters[x] < 0)
13574 break;
13575 }
13576 if (x >= ARRAY_LEN(dp->waiters)) {
13577 ast_log(LOG_WARNING, "No more waiter positions available\n");
13578 return NULL;
13579 }
13580 if (pipe(com)) {
13581 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13582 return NULL;
13583 }
13584 dp->waiters[x] = com[1];
13585
13586 timeout = iaxdefaulttimeout * 1000;
13587
13588 AST_LIST_UNLOCK(&dpcache);
13589
13590 if (chan)
13591 old = ast_channel_defer_dtmf(chan);
13592 doabort = 0;
13593 while(timeout) {
13594 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13595 if (outfd > -1)
13596 break;
13597 if (!c)
13598 continue;
13599 if (!(f = ast_read(c))) {
13600 doabort = 1;
13601 break;
13602 }
13603 ast_frfree(f);
13604 }
13605 if (!timeout) {
13606 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13607 }
13608 AST_LIST_LOCK(&dpcache);
13609 dp->waiters[x] = -1;
13610 close(com[1]);
13611 close(com[0]);
13612 if (doabort) {
13613
13614
13615 if (!old && chan)
13616 ast_channel_undefer_dtmf(chan);
13617 return NULL;
13618 }
13619 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13620
13621 if (dp->flags & CACHE_FLAG_PENDING) {
13622
13623
13624 dp->flags &= ~CACHE_FLAG_PENDING;
13625 dp->flags |= CACHE_FLAG_TIMEOUT;
13626
13627
13628 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13629 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13630 if (dp->waiters[x] > -1) {
13631 if (write(dp->waiters[x], "asdf", 4) < 0) {
13632 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13633 }
13634 }
13635 }
13636 }
13637 }
13638
13639 if (!old && chan)
13640 ast_channel_undefer_dtmf(chan);
13641 }
13642 return dp;
13643 }
13644
13645
13646 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13647 {
13648 int res = 0;
13649 struct iax2_dpcache *dp = NULL;
13650 #if 0
13651 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13652 #endif
13653 if ((priority != 1) && (priority != 2))
13654 return 0;
13655
13656 AST_LIST_LOCK(&dpcache);
13657 if ((dp = find_cache(chan, data, context, exten, priority))) {
13658 if (dp->flags & CACHE_FLAG_EXISTS)
13659 res = 1;
13660 } else {
13661 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13662 }
13663 AST_LIST_UNLOCK(&dpcache);
13664
13665 return res;
13666 }
13667
13668
13669 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13670 {
13671 int res = 0;
13672 struct iax2_dpcache *dp = NULL;
13673 #if 0
13674 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13675 #endif
13676 if ((priority != 1) && (priority != 2))
13677 return 0;
13678
13679 AST_LIST_LOCK(&dpcache);
13680 if ((dp = find_cache(chan, data, context, exten, priority))) {
13681 if (dp->flags & CACHE_FLAG_CANEXIST)
13682 res = 1;
13683 } else {
13684 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13685 }
13686 AST_LIST_UNLOCK(&dpcache);
13687
13688 return res;
13689 }
13690
13691
13692 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13693 {
13694 int res = 0;
13695 struct iax2_dpcache *dp = NULL;
13696 #if 0
13697 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13698 #endif
13699 if ((priority != 1) && (priority != 2))
13700 return 0;
13701
13702 AST_LIST_LOCK(&dpcache);
13703 if ((dp = find_cache(chan, data, context, exten, priority))) {
13704 if (dp->flags & CACHE_FLAG_MATCHMORE)
13705 res = 1;
13706 } else {
13707 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13708 }
13709 AST_LIST_UNLOCK(&dpcache);
13710
13711 return res;
13712 }
13713
13714
13715 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13716 {
13717 char odata[256];
13718 char req[256];
13719 char *ncontext;
13720 struct iax2_dpcache *dp = NULL;
13721 struct ast_app *dial = NULL;
13722 #if 0
13723 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);
13724 #endif
13725 if (priority == 2) {
13726
13727 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13728 if (dialstatus) {
13729 dial = pbx_findapp(dialstatus);
13730 if (dial)
13731 pbx_exec(chan, dial, "");
13732 }
13733 return -1;
13734 } else if (priority != 1)
13735 return -1;
13736
13737 AST_LIST_LOCK(&dpcache);
13738 if ((dp = find_cache(chan, data, context, exten, priority))) {
13739 if (dp->flags & CACHE_FLAG_EXISTS) {
13740 ast_copy_string(odata, data, sizeof(odata));
13741 ncontext = strchr(odata, '/');
13742 if (ncontext) {
13743 *ncontext = '\0';
13744 ncontext++;
13745 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13746 } else {
13747 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13748 }
13749 ast_verb(3, "Executing Dial('%s')\n", req);
13750 } else {
13751 AST_LIST_UNLOCK(&dpcache);
13752 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13753 return -1;
13754 }
13755 }
13756 AST_LIST_UNLOCK(&dpcache);
13757
13758 if ((dial = pbx_findapp("Dial")))
13759 return pbx_exec(chan, dial, req);
13760 else
13761 ast_log(LOG_WARNING, "No dial application registered\n");
13762
13763 return -1;
13764 }
13765
13766 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13767 {
13768 struct iax2_peer *peer;
13769 char *peername, *colname;
13770
13771 peername = ast_strdupa(data);
13772
13773
13774 if (!strcmp(peername,"CURRENTCHANNEL")) {
13775 unsigned short callno;
13776 if (chan->tech != &iax2_tech)
13777 return -1;
13778 callno = PTR_TO_CALLNO(chan->tech_pvt);
13779 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13780 return 0;
13781 }
13782
13783 if ((colname = strchr(peername, ',')))
13784 *colname++ = '\0';
13785 else
13786 colname = "ip";
13787
13788 if (!(peer = find_peer(peername, 1)))
13789 return -1;
13790
13791 if (!strcasecmp(colname, "ip")) {
13792 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13793 } else if (!strcasecmp(colname, "status")) {
13794 peer_status(peer, buf, len);
13795 } else if (!strcasecmp(colname, "mailbox")) {
13796 ast_copy_string(buf, peer->mailbox, len);
13797 } else if (!strcasecmp(colname, "context")) {
13798 ast_copy_string(buf, peer->context, len);
13799 } else if (!strcasecmp(colname, "expire")) {
13800 snprintf(buf, len, "%d", peer->expire);
13801 } else if (!strcasecmp(colname, "dynamic")) {
13802 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13803 } else if (!strcasecmp(colname, "callerid_name")) {
13804 ast_copy_string(buf, peer->cid_name, len);
13805 } else if (!strcasecmp(colname, "callerid_num")) {
13806 ast_copy_string(buf, peer->cid_num, len);
13807 } else if (!strcasecmp(colname, "codecs")) {
13808 ast_getformatname_multiple(buf, len -1, peer->capability);
13809 } else if (!strncasecmp(colname, "codec[", 6)) {
13810 char *codecnum, *ptr;
13811 int codec = 0;
13812
13813 codecnum = strchr(colname, '[');
13814 *codecnum = '\0';
13815 codecnum++;
13816 if ((ptr = strchr(codecnum, ']'))) {
13817 *ptr = '\0';
13818 }
13819 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13820 ast_copy_string(buf, ast_getformatname(codec), len);
13821 } else {
13822 buf[0] = '\0';
13823 }
13824 } else {
13825 buf[0] = '\0';
13826 }
13827
13828 peer_unref(peer);
13829
13830 return 0;
13831 }
13832
13833 static struct ast_custom_function iaxpeer_function = {
13834 .name = "IAXPEER",
13835 .read = function_iaxpeer,
13836 };
13837
13838 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13839 {
13840 struct chan_iax2_pvt *pvt;
13841 unsigned int callno;
13842 int res = 0;
13843
13844 if (!chan || chan->tech != &iax2_tech) {
13845 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13846 return -1;
13847 }
13848
13849 callno = PTR_TO_CALLNO(chan->tech_pvt);
13850 ast_mutex_lock(&iaxsl[callno]);
13851 if (!(pvt = iaxs[callno])) {
13852 ast_mutex_unlock(&iaxsl[callno]);
13853 return -1;
13854 }
13855
13856 if (!strcasecmp(args, "osptoken")) {
13857 ast_copy_string(buf, pvt->osptoken, buflen);
13858 } else if (!strcasecmp(args, "peerip")) {
13859 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13860 } else if (!strcasecmp(args, "peername")) {
13861 ast_copy_string(buf, pvt->username, buflen);
13862 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
13863 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
13864 } else {
13865 res = -1;
13866 }
13867
13868 ast_mutex_unlock(&iaxsl[callno]);
13869
13870 return res;
13871 }
13872
13873
13874 static int iax2_devicestate(void *data)
13875 {
13876 struct parsed_dial_string pds;
13877 char *tmp = ast_strdupa(data);
13878 struct iax2_peer *p;
13879 int res = AST_DEVICE_INVALID;
13880
13881 memset(&pds, 0, sizeof(pds));
13882 parse_dial_string(tmp, &pds);
13883
13884 if (ast_strlen_zero(pds.peer)) {
13885 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13886 return res;
13887 }
13888
13889 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13890
13891
13892 if (!(p = find_peer(pds.peer, 1)))
13893 return res;
13894
13895 res = AST_DEVICE_UNAVAILABLE;
13896 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13897 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13898
13899 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
13900 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13901
13902
13903 if (p->historicms == 0 || p->historicms <= p->maxms)
13904
13905 res = AST_DEVICE_UNKNOWN;
13906 }
13907
13908 peer_unref(p);
13909
13910 return res;
13911 }
13912
13913 static struct ast_switch iax2_switch =
13914 {
13915 name: "IAX2",
13916 description: "IAX Remote Dialplan Switch",
13917 exists: iax2_exists,
13918 canmatch: iax2_canmatch,
13919 exec: iax2_exec,
13920 matchmore: iax2_matchmore,
13921 };
13922
13923
13924
13925
13926
13927
13928
13929
13930
13931
13932
13933
13934
13935
13936
13937
13938
13939
13940
13941
13942
13943
13944
13945
13946
13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
13958
13959
13960
13961
13962
13963
13964
13965
13966
13967
13968
13969
13970
13971
13972
13973
13974
13975
13976
13977
13978
13979
13980
13981
13982
13983
13984
13985
13986
13987
13988
13989
13990
13991
13992
13993
13994
13995
13996
13997
13998
13999
14000
14001
14002
14003
14004
14005
14006
14007
14008
14009
14010
14011
14012
14013
14014
14015
14016
14017
14018
14019
14020
14021
14022
14023
14024
14025
14026
14027 static struct ast_cli_entry cli_iax2[] = {
14028 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14029 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14030 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14031 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14032 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14033 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14034 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14035 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14036 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14037 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14038 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14039 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14040 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14041 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14042 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14043 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14044 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14045 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14046 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14047 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14048 #ifdef IAXTESTS
14049 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14050 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14051 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14052 #endif
14053 };
14054
14055 #ifdef TEST_FRAMEWORK
14056 AST_TEST_DEFINE(test_iax2_peers_get)
14057 {
14058 struct ast_data_query query = {
14059 .path = "/asterisk/channel/iax2/peers",
14060 .search = "peers/peer/name=test_peer_data_provider"
14061 };
14062 struct ast_data *node;
14063 struct iax2_peer *peer;
14064
14065 switch (cmd) {
14066 case TEST_INIT:
14067 info->name = "iax2_peers_get_data_test";
14068 info->category = "/main/data/iax2/peers/";
14069 info->summary = "IAX2 peers data providers unit test";
14070 info->description =
14071 "Tests whether the IAX2 peers data provider implementation works as expected.";
14072 return AST_TEST_NOT_RUN;
14073 case TEST_EXECUTE:
14074 break;
14075 }
14076
14077
14078 peer = build_peer("test_peer_data_provider", NULL, NULL, 0);
14079 if (!peer) {
14080 return AST_TEST_FAIL;
14081 }
14082 peer->expiry= 1010;
14083 ao2_link(peers, peer);
14084
14085 node = ast_data_get(&query);
14086 if (!node) {
14087 ao2_unlink(peers, peer);
14088 peer_unref(peer);
14089 return AST_TEST_FAIL;
14090 }
14091
14092
14093 if (strcmp(ast_data_retrieve_string(node, "peer/name"), "test_peer_data_provider")) {
14094 ao2_unlink(peers, peer);
14095 peer_unref(peer);
14096 ast_data_free(node);
14097 return AST_TEST_FAIL;
14098 }
14099
14100 if (ast_data_retrieve_int(node, "peer/expiry") != 1010) {
14101 ao2_unlink(peers, peer);
14102 peer_unref(peer);
14103 ast_data_free(node);
14104 return AST_TEST_FAIL;
14105 }
14106
14107
14108 ast_data_free(node);
14109
14110 ao2_unlink(peers, peer);
14111 peer_unref(peer);
14112
14113 return AST_TEST_PASS;
14114 }
14115
14116 AST_TEST_DEFINE(test_iax2_users_get)
14117 {
14118 struct ast_data_query query = {
14119 .path = "/asterisk/channel/iax2/users",
14120 .search = "users/user/name=test_user_data_provider"
14121 };
14122 struct ast_data *node;
14123 struct iax2_user *user;
14124
14125 switch (cmd) {
14126 case TEST_INIT:
14127 info->name = "iax2_users_get_data_test";
14128 info->category = "/main/data/iax2/users/";
14129 info->summary = "IAX2 users data providers unit test";
14130 info->description =
14131 "Tests whether the IAX2 users data provider implementation works as expected.";
14132 return AST_TEST_NOT_RUN;
14133 case TEST_EXECUTE:
14134 break;
14135 }
14136
14137 user = build_user("test_user_data_provider", NULL, NULL, 0);
14138 if (!user) {
14139 ast_test_status_update(test, "Failed to build a test user\n");
14140 return AST_TEST_FAIL;
14141 }
14142 user->amaflags = 1010;
14143 ao2_link(users, user);
14144
14145 node = ast_data_get(&query);
14146 if (!node) {
14147 ast_test_status_update(test, "The data query to find our test user failed\n");
14148 ao2_unlink(users, user);
14149 user_unref(user);
14150 return AST_TEST_FAIL;
14151 }
14152
14153 if (strcmp(ast_data_retrieve_string(node, "user/name"), "test_user_data_provider")) {
14154 ast_test_status_update(test, "Our data results did not return the test user created in the previous step.\n");
14155 ao2_unlink(users, user);
14156 user_unref(user);
14157 ast_data_free(node);
14158 return AST_TEST_FAIL;
14159 }
14160
14161 if (ast_data_retrieve_int(node, "user/amaflags/value") != 1010) {
14162 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"));
14163 ao2_unlink(users, user);
14164 user_unref(user);
14165 ast_data_free(node);
14166 return AST_TEST_FAIL;
14167 }
14168
14169 ast_data_free(node);
14170
14171 ao2_unlink(users, user);
14172 user_unref(user);
14173
14174 return AST_TEST_PASS;
14175 }
14176 #endif
14177
14178 static void cleanup_thread_list(void *head)
14179 {
14180 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14181 struct iax2_thread_list *list_head = head;
14182 struct iax2_thread *thread;
14183
14184 AST_LIST_LOCK(list_head);
14185 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14186 pthread_t thread_id = thread->threadid;
14187
14188 thread->stop = 1;
14189 signal_condition(&thread->lock, &thread->cond);
14190
14191 AST_LIST_UNLOCK(list_head);
14192 pthread_join(thread_id, NULL);
14193 AST_LIST_LOCK(list_head);
14194 }
14195 AST_LIST_UNLOCK(list_head);
14196 }
14197
14198 static int __unload_module(void)
14199 {
14200 struct ast_context *con;
14201 int x;
14202
14203 network_change_event_unsubscribe();
14204
14205 ast_manager_unregister("IAXpeers");
14206 ast_manager_unregister("IAXpeerlist");
14207 ast_manager_unregister("IAXnetstats");
14208 ast_manager_unregister("IAXregistry");
14209 ast_unregister_application(papp);
14210 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14211 ast_unregister_switch(&iax2_switch);
14212 ast_channel_unregister(&iax2_tech);
14213
14214 if (netthreadid != AST_PTHREADT_NULL) {
14215 pthread_cancel(netthreadid);
14216 pthread_kill(netthreadid, SIGURG);
14217 pthread_join(netthreadid, NULL);
14218 }
14219
14220 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14221 if (iaxs[x]) {
14222 iax2_destroy(x);
14223 }
14224 }
14225
14226
14227 cleanup_thread_list(&idle_list);
14228 cleanup_thread_list(&active_list);
14229 cleanup_thread_list(&dynamic_list);
14230
14231 ast_netsock_release(netsock);
14232 ast_netsock_release(outsock);
14233 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14234 if (iaxs[x]) {
14235 iax2_destroy(x);
14236 }
14237 }
14238 ast_manager_unregister( "IAXpeers" );
14239 ast_manager_unregister( "IAXpeerlist" );
14240 ast_manager_unregister( "IAXnetstats" );
14241 ast_manager_unregister( "IAXregistry" );
14242 ast_unregister_application(papp);
14243 #ifdef TEST_FRAMEWORK
14244 AST_TEST_UNREGISTER(test_iax2_peers_get);
14245 AST_TEST_UNREGISTER(test_iax2_users_get);
14246 #endif
14247 ast_data_unregister(NULL);
14248 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14249 ast_unregister_switch(&iax2_switch);
14250 ast_channel_unregister(&iax2_tech);
14251 delete_users();
14252 iax_provision_unload();
14253 reload_firmware(1);
14254
14255 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14256 ast_mutex_destroy(&iaxsl[x]);
14257 }
14258
14259 ao2_ref(peers, -1);
14260 ao2_ref(users, -1);
14261 ao2_ref(iax_peercallno_pvts, -1);
14262 ao2_ref(iax_transfercallno_pvts, -1);
14263 ao2_ref(peercnts, -1);
14264 ao2_ref(callno_limits, -1);
14265 ao2_ref(calltoken_ignores, -1);
14266 ao2_ref(callno_pool, -1);
14267 ao2_ref(callno_pool_trunk, -1);
14268 if (timer) {
14269 ast_timer_close(timer);
14270 }
14271 transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14272 sched = ast_sched_thread_destroy(sched);
14273
14274 con = ast_context_find(regcontext);
14275 if (con)
14276 ast_context_destroy(con, "IAX2");
14277 ast_unload_realtime("iaxpeers");
14278 return 0;
14279 }
14280
14281 static int unload_module(void)
14282 {
14283 ast_custom_function_unregister(&iaxpeer_function);
14284 ast_custom_function_unregister(&iaxvar_function);
14285 return __unload_module();
14286 }
14287
14288 static int peer_set_sock_cb(void *obj, void *arg, int flags)
14289 {
14290 struct iax2_peer *peer = obj;
14291
14292 if (peer->sockfd < 0)
14293 peer->sockfd = defaultsockfd;
14294
14295 return 0;
14296 }
14297
14298 static int pvt_hash_cb(const void *obj, const int flags)
14299 {
14300 const struct chan_iax2_pvt *pvt = obj;
14301
14302 return pvt->peercallno;
14303 }
14304
14305 static int pvt_cmp_cb(void *obj, void *arg, int flags)
14306 {
14307 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14308
14309
14310
14311
14312 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14313 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14314 }
14315
14316 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14317 {
14318 const struct chan_iax2_pvt *pvt = obj;
14319
14320 return pvt->transfercallno;
14321 }
14322
14323 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14324 {
14325 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14326
14327
14328
14329
14330 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14331 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14332 }
14333
14334 static int load_objects(void)
14335 {
14336 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14337 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14338
14339 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14340 goto container_fail;
14341 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14342 goto container_fail;
14343 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14344 goto container_fail;
14345 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14346 goto container_fail;
14347 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14348 goto container_fail;
14349 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14350 goto container_fail;
14351 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14352 goto container_fail;
14353 } else if (create_callno_pools()) {
14354 goto container_fail;
14355 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14356 goto container_fail;
14357 }
14358
14359 return 0;
14360
14361 container_fail:
14362 if (peers) {
14363 ao2_ref(peers, -1);
14364 }
14365 if (users) {
14366 ao2_ref(users, -1);
14367 }
14368 if (iax_peercallno_pvts) {
14369 ao2_ref(iax_peercallno_pvts, -1);
14370 }
14371 if (iax_transfercallno_pvts) {
14372 ao2_ref(iax_transfercallno_pvts, -1);
14373 }
14374 if (peercnts) {
14375 ao2_ref(peercnts, -1);
14376 }
14377 if (callno_limits) {
14378 ao2_ref(callno_limits, -1);
14379 }
14380 if (calltoken_ignores) {
14381 ao2_ref(calltoken_ignores, -1);
14382 }
14383 if (callno_pool) {
14384 ao2_ref(callno_pool, -1);
14385 }
14386 if (callno_pool_trunk) {
14387 ao2_ref(callno_pool_trunk, -1);
14388 }
14389 return AST_MODULE_LOAD_FAILURE;
14390 }
14391
14392
14393 #define DATA_EXPORT_IAX2_PEER(MEMBER) \
14394 MEMBER(iax2_peer, name, AST_DATA_STRING) \
14395 MEMBER(iax2_peer, username, AST_DATA_STRING) \
14396 MEMBER(iax2_peer, secret, AST_DATA_PASSWORD) \
14397 MEMBER(iax2_peer, dbsecret, AST_DATA_PASSWORD) \
14398 MEMBER(iax2_peer, outkey, AST_DATA_STRING) \
14399 MEMBER(iax2_peer, regexten, AST_DATA_STRING) \
14400 MEMBER(iax2_peer, context, AST_DATA_STRING) \
14401 MEMBER(iax2_peer, peercontext, AST_DATA_STRING) \
14402 MEMBER(iax2_peer, mailbox, AST_DATA_STRING) \
14403 MEMBER(iax2_peer, mohinterpret, AST_DATA_STRING) \
14404 MEMBER(iax2_peer, mohsuggest, AST_DATA_STRING) \
14405 MEMBER(iax2_peer, inkeys, AST_DATA_STRING) \
14406 MEMBER(iax2_peer, cid_num, AST_DATA_STRING) \
14407 MEMBER(iax2_peer, cid_name, AST_DATA_STRING) \
14408 MEMBER(iax2_peer, zonetag, AST_DATA_STRING) \
14409 MEMBER(iax2_peer, parkinglot, AST_DATA_STRING) \
14410 MEMBER(iax2_peer, expiry, AST_DATA_SECONDS) \
14411 MEMBER(iax2_peer, callno, AST_DATA_INTEGER) \
14412 MEMBER(iax2_peer, lastms, AST_DATA_MILLISECONDS) \
14413 MEMBER(iax2_peer, maxms, AST_DATA_MILLISECONDS) \
14414 MEMBER(iax2_peer, pokefreqok, AST_DATA_MILLISECONDS) \
14415 MEMBER(iax2_peer, pokefreqnotok, AST_DATA_MILLISECONDS) \
14416 MEMBER(iax2_peer, historicms, AST_DATA_INTEGER) \
14417 MEMBER(iax2_peer, smoothing, AST_DATA_BOOLEAN) \
14418 MEMBER(iax2_peer, maxcallno, AST_DATA_INTEGER)
14419
14420 AST_DATA_STRUCTURE(iax2_peer, DATA_EXPORT_IAX2_PEER);
14421
14422 static int peers_data_provider_get(const struct ast_data_search *search,
14423 struct ast_data *data_root)
14424 {
14425 struct ast_data *data_peer;
14426 struct iax2_peer *peer;
14427 struct ao2_iterator i;
14428 char status[20];
14429 struct ast_str *encmethods = ast_str_alloca(256);
14430
14431 i = ao2_iterator_init(peers, 0);
14432 while ((peer = ao2_iterator_next(&i))) {
14433 data_peer = ast_data_add_node(data_root, "peer");
14434 if (!data_peer) {
14435 peer_unref(peer);
14436 continue;
14437 }
14438
14439 ast_data_add_structure(iax2_peer, data_peer, peer);
14440
14441 ast_data_add_codecs(data_peer, "codecs", peer->capability);
14442
14443 peer_status(peer, status, sizeof(status));
14444 ast_data_add_str(data_peer, "status", status);
14445
14446 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14447
14448 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14449
14450 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14451
14452 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14453
14454 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14455
14456 encmethods_to_str(peer->encmethods, encmethods);
14457 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14458
14459 peer_unref(peer);
14460
14461 if (!ast_data_search_match(search, data_peer)) {
14462 ast_data_remove_node(data_root, data_peer);
14463 }
14464 }
14465 ao2_iterator_destroy(&i);
14466
14467 return 0;
14468 }
14469
14470 #define DATA_EXPORT_IAX2_USER(MEMBER) \
14471 MEMBER(iax2_user, name, AST_DATA_STRING) \
14472 MEMBER(iax2_user, dbsecret, AST_DATA_PASSWORD) \
14473 MEMBER(iax2_user, accountcode, AST_DATA_STRING) \
14474 MEMBER(iax2_user, mohinterpret, AST_DATA_STRING) \
14475 MEMBER(iax2_user, mohsuggest, AST_DATA_STRING) \
14476 MEMBER(iax2_user, inkeys, AST_DATA_STRING) \
14477 MEMBER(iax2_user, language, AST_DATA_STRING) \
14478 MEMBER(iax2_user, cid_num, AST_DATA_STRING) \
14479 MEMBER(iax2_user, cid_name, AST_DATA_STRING) \
14480 MEMBER(iax2_user, parkinglot, AST_DATA_STRING) \
14481 MEMBER(iax2_user, maxauthreq, AST_DATA_INTEGER) \
14482 MEMBER(iax2_user, curauthreq, AST_DATA_INTEGER)
14483
14484 AST_DATA_STRUCTURE(iax2_user, DATA_EXPORT_IAX2_USER);
14485
14486 static int users_data_provider_get(const struct ast_data_search *search,
14487 struct ast_data *data_root)
14488 {
14489 struct ast_data *data_user, *data_authmethods, *data_enum_node;
14490 struct iax2_user *user;
14491 struct ao2_iterator i;
14492 char auth[90];
14493 char *pstr = "";
14494
14495 i = ao2_iterator_init(users, 0);
14496 while ((user = ao2_iterator_next(&i))) {
14497 data_user = ast_data_add_node(data_root, "user");
14498 if (!data_user) {
14499 user_unref(user);
14500 continue;
14501 }
14502
14503 ast_data_add_structure(iax2_user, data_user, user);
14504
14505 ast_data_add_codecs(data_user, "codecs", user->capability);
14506
14507 if (!ast_strlen_zero(user->secret)) {
14508 ast_copy_string(auth, user->secret, sizeof(auth));
14509 } else if (!ast_strlen_zero(user->inkeys)) {
14510 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14511 } else {
14512 ast_copy_string(auth, "no secret", sizeof(auth));
14513 }
14514 ast_data_add_password(data_user, "secret", auth);
14515
14516 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14517
14518
14519 data_authmethods = ast_data_add_node(data_user, "authmethods");
14520 if (!data_authmethods) {
14521 ast_data_remove_node(data_root, data_user);
14522 continue;
14523 }
14524 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14525 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14526 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14527
14528
14529 data_enum_node = ast_data_add_node(data_user, "amaflags");
14530 if (!data_enum_node) {
14531 ast_data_remove_node(data_root, data_user);
14532 continue;
14533 }
14534 ast_data_add_int(data_enum_node, "value", user->amaflags);
14535 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14536
14537 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14538
14539 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14540 pstr = "REQ only";
14541 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14542 pstr = "disabled";
14543 } else {
14544 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14545 }
14546 ast_data_add_str(data_user, "codec-preferences", pstr);
14547
14548 user_unref(user);
14549
14550 if (!ast_data_search_match(search, data_user)) {
14551 ast_data_remove_node(data_root, data_user);
14552 }
14553 }
14554 ao2_iterator_destroy(&i);
14555
14556 return 0;
14557 }
14558
14559 static const struct ast_data_handler peers_data_provider = {
14560 .version = AST_DATA_HANDLER_VERSION,
14561 .get = peers_data_provider_get
14562 };
14563
14564 static const struct ast_data_handler users_data_provider = {
14565 .version = AST_DATA_HANDLER_VERSION,
14566 .get = users_data_provider_get
14567 };
14568
14569 static const struct ast_data_entry iax2_data_providers[] = {
14570 AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
14571 AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
14572 };
14573
14574
14575 static int load_module(void)
14576 {
14577 static const char config[] = "iax.conf";
14578 int x = 0;
14579 struct iax2_registry *reg = NULL;
14580
14581 if (load_objects()) {
14582 return AST_MODULE_LOAD_FAILURE;
14583 }
14584
14585 memset(iaxs, 0, sizeof(iaxs));
14586
14587 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14588 ast_mutex_init(&iaxsl[x]);
14589 }
14590
14591 if (!(sched = ast_sched_thread_create())) {
14592 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14593 return AST_MODULE_LOAD_FAILURE;
14594 }
14595
14596 if (!(io = io_context_create())) {
14597 ast_log(LOG_ERROR, "Failed to create I/O context\n");
14598 sched = ast_sched_thread_destroy(sched);
14599 return AST_MODULE_LOAD_FAILURE;
14600 }
14601
14602 if (!(netsock = ast_netsock_list_alloc())) {
14603 ast_log(LOG_ERROR, "Failed to create netsock list\n");
14604 io_context_destroy(io);
14605 sched = ast_sched_thread_destroy(sched);
14606 return AST_MODULE_LOAD_FAILURE;
14607 }
14608 ast_netsock_init(netsock);
14609
14610 outsock = ast_netsock_list_alloc();
14611 if (!outsock) {
14612 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14613 io_context_destroy(io);
14614 sched = ast_sched_thread_destroy(sched);
14615 return AST_MODULE_LOAD_FAILURE;
14616 }
14617 ast_netsock_init(outsock);
14618
14619 randomcalltokendata = ast_random();
14620
14621 iax_set_output(iax_debug_output);
14622 iax_set_error(iax_error_output);
14623 jb_setoutput(jb_error_output, jb_warning_output, NULL);
14624
14625 if ((timer = ast_timer_open())) {
14626 ast_timer_set_rate(timer, trunkfreq);
14627 }
14628
14629 if (set_config(config, 0) == -1) {
14630 if (timer) {
14631 ast_timer_close(timer);
14632 }
14633 return AST_MODULE_LOAD_DECLINE;
14634 }
14635
14636 #ifdef TEST_FRAMEWORK
14637 AST_TEST_REGISTER(test_iax2_peers_get);
14638 AST_TEST_REGISTER(test_iax2_users_get);
14639 #endif
14640
14641
14642 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14643 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14644
14645 ast_register_application_xml(papp, iax2_prov_app);
14646
14647 ast_custom_function_register(&iaxpeer_function);
14648 ast_custom_function_register(&iaxvar_function);
14649
14650 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14651 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14652 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14653 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14654
14655 if (ast_channel_register(&iax2_tech)) {
14656 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14657 __unload_module();
14658 return AST_MODULE_LOAD_FAILURE;
14659 }
14660
14661 if (ast_register_switch(&iax2_switch)) {
14662 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14663 }
14664
14665 if (start_network_thread()) {
14666 ast_log(LOG_ERROR, "Unable to start network thread\n");
14667 __unload_module();
14668 return AST_MODULE_LOAD_FAILURE;
14669 } else {
14670 ast_verb(2, "IAX Ready and Listening\n");
14671 }
14672
14673 AST_LIST_LOCK(®istrations);
14674 AST_LIST_TRAVERSE(®istrations, reg, entry)
14675 iax2_do_register(reg);
14676 AST_LIST_UNLOCK(®istrations);
14677
14678 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14679 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14680
14681
14682 reload_firmware(0);
14683 iax_provision_reload(0);
14684
14685 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14686
14687 network_change_event_subscribe();
14688
14689 return AST_MODULE_LOAD_SUCCESS;
14690 }
14691
14692 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
14693 .load = load_module,
14694 .unload = unload_module,
14695 .reload = reload,
14696 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
14697 .nonoptreq = "res_crypto",
14698 );