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: 324704 $")
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_OPRMODE:
05271 errno = EINVAL;
05272 return -1;
05273 case AST_OPTION_SECURE_SIGNALING:
05274 case AST_OPTION_SECURE_MEDIA:
05275 {
05276 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05277 ast_mutex_lock(&iaxsl[callno]);
05278 if ((*(int *) data)) {
05279 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05280 } else {
05281 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05282 }
05283 ast_mutex_unlock(&iaxsl[callno]);
05284 return 0;
05285 }
05286
05287
05288
05289
05290 case AST_OPTION_TONE_VERIFY:
05291 case AST_OPTION_TDD:
05292 case AST_OPTION_RELAXDTMF:
05293 case AST_OPTION_AUDIO_MODE:
05294 case AST_OPTION_DIGIT_DETECT:
05295 case AST_OPTION_FAX_DETECT:
05296 {
05297 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05298 struct chan_iax2_pvt *pvt;
05299
05300 ast_mutex_lock(&iaxsl[callno]);
05301 pvt = iaxs[callno];
05302
05303 if (wait_for_peercallno(pvt)) {
05304 ast_mutex_unlock(&iaxsl[callno]);
05305 return -1;
05306 }
05307
05308 ast_mutex_unlock(&iaxsl[callno]);
05309
05310 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05311 return -1;
05312 }
05313
05314 h->flag = AST_OPTION_FLAG_REQUEST;
05315 h->option = htons(option);
05316 memcpy(h->data, data, datalen);
05317 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05318 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05319 datalen + sizeof(*h), -1);
05320 ast_free(h);
05321 return res;
05322 }
05323 default:
05324 return -1;
05325 }
05326
05327
05328 return -1;
05329 }
05330
05331 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
05332 {
05333 switch (option) {
05334 case AST_OPTION_SECURE_SIGNALING:
05335 case AST_OPTION_SECURE_MEDIA:
05336 {
05337 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05338 ast_mutex_lock(&iaxsl[callno]);
05339 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05340 ast_mutex_unlock(&iaxsl[callno]);
05341 return 0;
05342 }
05343 default:
05344 return -1;
05345 }
05346 }
05347
05348 static struct ast_frame *iax2_read(struct ast_channel *c)
05349 {
05350 ast_log(LOG_NOTICE, "I should never be called!\n");
05351 return &ast_null_frame;
05352 }
05353
05354 static int iax2_key_rotate(const void *vpvt)
05355 {
05356 int res = 0;
05357 struct chan_iax2_pvt *pvt = (void *) vpvt;
05358 struct MD5Context md5;
05359 char key[17] = "";
05360 struct iax_ie_data ied = {
05361 .pos = 0,
05362 };
05363
05364 ast_mutex_lock(&iaxsl[pvt->callno]);
05365 pvt->keyrotateid =
05366 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05367
05368 snprintf(key, sizeof(key), "%lX", ast_random());
05369
05370 MD5Init(&md5);
05371 MD5Update(&md5, (unsigned char *) key, strlen(key));
05372 MD5Final((unsigned char *) key, &md5);
05373
05374 IAX_DEBUGDIGEST("Sending", key);
05375
05376 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05377
05378 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05379
05380 build_ecx_key((unsigned char *) key, pvt);
05381
05382 ast_mutex_unlock(&iaxsl[pvt->callno]);
05383
05384 return res;
05385 }
05386
05387 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05388 {
05389 int res;
05390 struct iax_ie_data ied0;
05391 struct iax_ie_data ied1;
05392 unsigned int transferid = (unsigned int)ast_random();
05393
05394 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05395 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05396 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05397 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05398 return 0;
05399 }
05400
05401 memset(&ied0, 0, sizeof(ied0));
05402 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05403 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05404 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05405
05406 memset(&ied1, 0, sizeof(ied1));
05407 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05408 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05409 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05410
05411 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05412 if (res)
05413 return -1;
05414 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05415 if (res)
05416 return -1;
05417 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05418 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05419 return 0;
05420 }
05421
05422 static void lock_both(unsigned short callno0, unsigned short callno1)
05423 {
05424 ast_mutex_lock(&iaxsl[callno0]);
05425 while (ast_mutex_trylock(&iaxsl[callno1])) {
05426 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05427 }
05428 }
05429
05430 static void unlock_both(unsigned short callno0, unsigned short callno1)
05431 {
05432 ast_mutex_unlock(&iaxsl[callno1]);
05433 ast_mutex_unlock(&iaxsl[callno0]);
05434 }
05435
05436 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)
05437 {
05438 struct ast_channel *cs[3];
05439 struct ast_channel *who, *other;
05440 int to = -1;
05441 int res = -1;
05442 int transferstarted=0;
05443 struct ast_frame *f;
05444 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05445 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05446 struct timeval waittimer = {0, 0};
05447
05448
05449 if (timeoutms > 0) {
05450 return AST_BRIDGE_FAILED;
05451 }
05452
05453 timeoutms = -1;
05454
05455 lock_both(callno0, callno1);
05456 if (!iaxs[callno0] || !iaxs[callno1]) {
05457 unlock_both(callno0, callno1);
05458 return AST_BRIDGE_FAILED;
05459 }
05460
05461 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05462 iaxs[callno0]->bridgecallno = callno1;
05463 iaxs[callno1]->bridgecallno = callno0;
05464 }
05465 unlock_both(callno0, callno1);
05466
05467
05468 cs[0] = c0;
05469 cs[1] = c1;
05470 for (;;) {
05471
05472 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05473 ast_verb(3, "Can't masquerade, we're different...\n");
05474
05475 if (c0->tech == &iax2_tech) {
05476 ast_mutex_lock(&iaxsl[callno0]);
05477 iaxs[callno0]->bridgecallno = 0;
05478 ast_mutex_unlock(&iaxsl[callno0]);
05479 }
05480 if (c1->tech == &iax2_tech) {
05481 ast_mutex_lock(&iaxsl[callno1]);
05482 iaxs[callno1]->bridgecallno = 0;
05483 ast_mutex_unlock(&iaxsl[callno1]);
05484 }
05485 return AST_BRIDGE_FAILED_NOWARN;
05486 }
05487 if (c0->nativeformats != c1->nativeformats) {
05488 char buf0[256];
05489 char buf1[256];
05490 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05491 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05492 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05493
05494 lock_both(callno0, callno1);
05495 if (iaxs[callno0])
05496 iaxs[callno0]->bridgecallno = 0;
05497 if (iaxs[callno1])
05498 iaxs[callno1]->bridgecallno = 0;
05499 unlock_both(callno0, callno1);
05500 return AST_BRIDGE_FAILED_NOWARN;
05501 }
05502
05503 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05504
05505 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05506 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05507 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05508 transferstarted = 1;
05509 }
05510 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05511
05512 struct timeval now = ast_tvnow();
05513 if (ast_tvzero(waittimer)) {
05514 waittimer = now;
05515 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05516 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05517 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05518 *fo = NULL;
05519 *rc = c0;
05520 res = AST_BRIDGE_COMPLETE;
05521 break;
05522 }
05523 }
05524 to = 1000;
05525 who = ast_waitfor_n(cs, 2, &to);
05526 if (timeoutms > -1) {
05527 timeoutms -= (1000 - to);
05528 if (timeoutms < 0)
05529 timeoutms = 0;
05530 }
05531 if (!who) {
05532 if (!timeoutms) {
05533 res = AST_BRIDGE_RETRY;
05534 break;
05535 }
05536 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05537 res = AST_BRIDGE_FAILED;
05538 break;
05539 }
05540 continue;
05541 }
05542 f = ast_read(who);
05543 if (!f) {
05544 *fo = NULL;
05545 *rc = who;
05546 res = AST_BRIDGE_COMPLETE;
05547 break;
05548 }
05549 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
05550 *fo = f;
05551 *rc = who;
05552 res = AST_BRIDGE_COMPLETE;
05553 break;
05554 }
05555 other = (who == c0) ? c1 : c0;
05556 if ((f->frametype == AST_FRAME_VOICE) ||
05557 (f->frametype == AST_FRAME_TEXT) ||
05558 (f->frametype == AST_FRAME_VIDEO) ||
05559 (f->frametype == AST_FRAME_IMAGE) ||
05560 (f->frametype == AST_FRAME_DTMF) ||
05561 (f->frametype == AST_FRAME_CONTROL)) {
05562
05563
05564
05565 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05566 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05567 *rc = who;
05568 *fo = f;
05569 res = AST_BRIDGE_COMPLETE;
05570
05571 break;
05572 }
05573
05574 ast_write(other, f);
05575 }
05576 ast_frfree(f);
05577
05578 cs[2] = cs[0];
05579 cs[0] = cs[1];
05580 cs[1] = cs[2];
05581 }
05582 lock_both(callno0, callno1);
05583 if(iaxs[callno0])
05584 iaxs[callno0]->bridgecallno = 0;
05585 if(iaxs[callno1])
05586 iaxs[callno1]->bridgecallno = 0;
05587 unlock_both(callno0, callno1);
05588 return res;
05589 }
05590
05591 static int iax2_answer(struct ast_channel *c)
05592 {
05593 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05594 ast_debug(1, "Answering IAX2 call\n");
05595 ast_mutex_lock(&iaxsl[callno]);
05596 if (iaxs[callno])
05597 iax2_ami_channelupdate(iaxs[callno]);
05598 ast_mutex_unlock(&iaxsl[callno]);
05599 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05600 }
05601
05602 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05603 {
05604 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05605 struct chan_iax2_pvt *pvt;
05606 int res = 0;
05607
05608 if (iaxdebug)
05609 ast_debug(1, "Indicating condition %d\n", condition);
05610
05611 ast_mutex_lock(&iaxsl[callno]);
05612 pvt = iaxs[callno];
05613
05614 if (wait_for_peercallno(pvt)) {
05615 res = -1;
05616 goto done;
05617 }
05618
05619 switch (condition) {
05620 case AST_CONTROL_HOLD:
05621 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05622 ast_moh_start(c, data, pvt->mohinterpret);
05623 goto done;
05624 }
05625 break;
05626 case AST_CONTROL_UNHOLD:
05627 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05628 ast_moh_stop(c);
05629 goto done;
05630 }
05631 break;
05632 case AST_CONTROL_CONNECTED_LINE:
05633 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05634 goto done;
05635 break;
05636 }
05637
05638 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05639
05640 done:
05641 ast_mutex_unlock(&iaxsl[callno]);
05642
05643 return res;
05644 }
05645
05646 static int iax2_transfer(struct ast_channel *c, const char *dest)
05647 {
05648 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05649 struct iax_ie_data ied = { "", };
05650 char tmp[256], *context;
05651 enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05652 ast_copy_string(tmp, dest, sizeof(tmp));
05653 context = strchr(tmp, '@');
05654 if (context) {
05655 *context = '\0';
05656 context++;
05657 }
05658 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05659 if (context)
05660 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05661 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05662 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05663 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05664 }
05665
05666 static int iax2_getpeertrunk(struct sockaddr_in sin)
05667 {
05668 struct iax2_peer *peer;
05669 int res = 0;
05670 struct ao2_iterator i;
05671
05672 i = ao2_iterator_init(peers, 0);
05673 while ((peer = ao2_iterator_next(&i))) {
05674 struct sockaddr_in peer_addr;
05675
05676 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05677
05678 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05679 (peer_addr.sin_port == sin.sin_port)) {
05680 res = ast_test_flag64(peer, IAX_TRUNK);
05681 peer_unref(peer);
05682 break;
05683 }
05684 peer_unref(peer);
05685 }
05686 ao2_iterator_destroy(&i);
05687
05688 return res;
05689 }
05690
05691
05692 static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
05693 {
05694 struct ast_channel *tmp;
05695 struct chan_iax2_pvt *i;
05696 struct ast_variable *v = NULL;
05697
05698 if (!(i = iaxs[callno])) {
05699 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05700 return NULL;
05701 }
05702
05703
05704 ast_mutex_unlock(&iaxsl[callno]);
05705 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);
05706 ast_mutex_lock(&iaxsl[callno]);
05707 if (i != iaxs[callno]) {
05708 if (tmp) {
05709
05710 ast_mutex_unlock(&iaxsl[callno]);
05711 tmp = ast_channel_release(tmp);
05712 ast_mutex_lock(&iaxsl[callno]);
05713 }
05714 return NULL;
05715 }
05716 iax2_ami_channelupdate(i);
05717 if (!tmp)
05718 return NULL;
05719 tmp->tech = &iax2_tech;
05720
05721 tmp->nativeformats = capability;
05722 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05723 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05724 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05725
05726 if (!ast_strlen_zero(i->parkinglot))
05727 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05728
05729
05730 if (!ast_strlen_zero(i->ani)) {
05731 tmp->caller.ani.number.valid = 1;
05732 tmp->caller.ani.number.str = ast_strdup(i->ani);
05733 } else if (!ast_strlen_zero(i->cid_num)) {
05734 tmp->caller.ani.number.valid = 1;
05735 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05736 }
05737 tmp->dialed.number.str = ast_strdup(i->dnid);
05738 tmp->redirecting.from.number.valid = 1;
05739 tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05740 tmp->caller.id.name.presentation = i->calling_pres;
05741 tmp->caller.id.number.presentation = i->calling_pres;
05742 tmp->caller.id.number.plan = i->calling_ton;
05743 tmp->dialed.transit_network_select = i->calling_tns;
05744 if (!ast_strlen_zero(i->language))
05745 ast_string_field_set(tmp, language, i->language);
05746 if (!ast_strlen_zero(i->accountcode))
05747 ast_string_field_set(tmp, accountcode, i->accountcode);
05748 if (i->amaflags)
05749 tmp->amaflags = i->amaflags;
05750 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05751 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05752 if (i->adsi)
05753 tmp->adsicpe = i->peeradsicpe;
05754 else
05755 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05756 i->owner = tmp;
05757 i->capability = capability;
05758
05759
05760 if (i->vars) {
05761 for (v = i->vars ; v ; v = v->next)
05762 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05763 }
05764 if (i->iaxvars) {
05765 struct ast_datastore *variablestore;
05766 struct ast_variable *var, *prev = NULL;
05767 AST_LIST_HEAD(, ast_var_t) *varlist;
05768 ast_debug(1, "Loading up the channel with IAXVARs\n");
05769 varlist = ast_calloc(1, sizeof(*varlist));
05770 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05771 if (variablestore && varlist) {
05772 variablestore->data = varlist;
05773 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05774 AST_LIST_HEAD_INIT(varlist);
05775 for (var = i->iaxvars; var; var = var->next) {
05776 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05777 if (prev)
05778 ast_free(prev);
05779 prev = var;
05780 if (!newvar) {
05781
05782 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05783 } else {
05784 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05785 }
05786 }
05787 if (prev)
05788 ast_free(prev);
05789 i->iaxvars = NULL;
05790 ast_channel_datastore_add(i->owner, variablestore);
05791 } else {
05792 if (variablestore) {
05793 ast_datastore_free(variablestore);
05794 }
05795 if (varlist) {
05796 ast_free(varlist);
05797 }
05798 }
05799 }
05800
05801 if (state != AST_STATE_DOWN) {
05802 if (ast_pbx_start(tmp)) {
05803 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05804 ast_hangup(tmp);
05805 i->owner = NULL;
05806 return NULL;
05807 }
05808 }
05809
05810 ast_module_ref(ast_module_info->self);
05811 return tmp;
05812 }
05813
05814 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05815 {
05816 unsigned long int mssincetx;
05817 long int ms, pred;
05818
05819 tpeer->trunkact = *now;
05820 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05821 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05822
05823 tpeer->txtrunktime = *now;
05824 tpeer->lastsent = 999999;
05825 }
05826
05827 tpeer->lasttxtime = *now;
05828
05829
05830 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05831
05832 pred = tpeer->lastsent + sampms;
05833 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05834 ms = pred;
05835
05836
05837 if (ms == tpeer->lastsent)
05838 ms = tpeer->lastsent + 1;
05839 tpeer->lastsent = ms;
05840 return ms;
05841 }
05842
05843 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05844 {
05845 long ms;
05846 if (ast_tvzero(iaxs[callno]->rxcore)) {
05847
05848 iaxs[callno]->rxcore = ast_tvnow();
05849
05850 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05851 }
05852
05853 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05854
05855 return ms + ts;
05856 }
05857
05858 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05859 {
05860 int ms;
05861 int voice = 0;
05862 int genuine = 0;
05863 int adjust;
05864 int rate = ast_format_rate(f->subclass.codec) / 1000;
05865 struct timeval *delivery = NULL;
05866
05867
05868
05869
05870
05871
05872
05873
05874 if (f) {
05875 if (f->frametype == AST_FRAME_VOICE) {
05876 voice = 1;
05877 delivery = &f->delivery;
05878 } else if (f->frametype == AST_FRAME_IAX) {
05879 genuine = 1;
05880 } else if (f->frametype == AST_FRAME_CNG) {
05881 p->notsilenttx = 0;
05882 }
05883 }
05884 if (ast_tvzero(p->offset)) {
05885 p->offset = ast_tvnow();
05886
05887 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05888 }
05889
05890 if (ts)
05891 return ts;
05892
05893 if (delivery && !ast_tvzero(*delivery)) {
05894 ms = ast_tvdiff_ms(*delivery, p->offset);
05895 if (ms < 0) {
05896 ms = 0;
05897 }
05898 if (iaxdebug)
05899 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05900 } else {
05901 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05902 if (ms < 0)
05903 ms = 0;
05904 if (voice) {
05905
05906 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05907
05908
05909
05910
05911
05912
05913
05914
05915
05916
05917
05918
05919
05920
05921
05922
05923
05924
05925 adjust = (ms - p->nextpred);
05926 if (adjust < 0)
05927 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05928 else if (adjust > 0)
05929 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05930
05931 if (!p->nextpred) {
05932 p->nextpred = ms;
05933 if (p->nextpred <= p->lastsent)
05934 p->nextpred = p->lastsent + 3;
05935 }
05936 ms = p->nextpred;
05937 } else {
05938
05939
05940
05941
05942
05943
05944
05945
05946
05947 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05948 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05949 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05950
05951 if (f->samples >= rate)
05952 {
05953 int diff = ms % (f->samples / rate);
05954 if (diff)
05955 ms += f->samples/rate - diff;
05956 }
05957
05958 p->nextpred = ms;
05959 p->notsilenttx = 1;
05960 }
05961 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05962
05963
05964
05965
05966
05967
05968
05969
05970 if ( (unsigned int)ms < p->lastsent )
05971 ms = p->lastsent;
05972 } else {
05973
05974
05975 if (genuine) {
05976
05977 if (ms <= p->lastsent)
05978 ms = p->lastsent + 3;
05979 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05980
05981 ms = p->lastsent + 3;
05982 }
05983 }
05984 }
05985 p->lastsent = ms;
05986 if (voice)
05987 p->nextpred = p->nextpred + f->samples / rate;
05988 return ms;
05989 }
05990
05991 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05992 {
05993
05994
05995 int ms;
05996 #ifdef IAXTESTS
05997 int jit;
05998 #endif
05999
06000 if (ast_tvzero(p->rxcore)) {
06001 p->rxcore = ast_tvnow();
06002 if (iaxdebug)
06003 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06004 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06005 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06006 #if 1
06007 if (iaxdebug)
06008 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06009 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06010 #endif
06011 }
06012
06013 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06014 #ifdef IAXTESTS
06015 if (test_jit) {
06016 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06017 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06018 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06019 jit = -jit;
06020 ms += jit;
06021 }
06022 }
06023 if (test_late) {
06024 ms += test_late;
06025 test_late = 0;
06026 }
06027 #endif
06028 return ms;
06029 }
06030
06031 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
06032 {
06033 struct iax2_trunk_peer *tpeer = NULL;
06034
06035
06036 AST_LIST_LOCK(&tpeers);
06037
06038 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06039 if (!inaddrcmp(&tpeer->addr, sin)) {
06040 ast_mutex_lock(&tpeer->lock);
06041 break;
06042 }
06043 }
06044
06045 if (!tpeer) {
06046 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06047 ast_mutex_init(&tpeer->lock);
06048 tpeer->lastsent = 9999;
06049 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06050 tpeer->trunkact = ast_tvnow();
06051 ast_mutex_lock(&tpeer->lock);
06052 tpeer->sockfd = fd;
06053 #ifdef SO_NO_CHECK
06054 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06055 #endif
06056 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06057 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06058 }
06059 }
06060
06061 AST_LIST_UNLOCK(&tpeers);
06062
06063 return tpeer;
06064 }
06065
06066 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
06067 {
06068 struct ast_frame *f;
06069 struct iax2_trunk_peer *tpeer;
06070 void *tmp, *ptr;
06071 struct timeval now;
06072 int res;
06073 struct ast_iax2_meta_trunk_entry *met;
06074 struct ast_iax2_meta_trunk_mini *mtm;
06075
06076 f = &fr->af;
06077 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06078 if (tpeer) {
06079 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06080
06081 if (tpeer->trunkdataalloc < trunkmaxsize) {
06082 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06083 ast_mutex_unlock(&tpeer->lock);
06084 return -1;
06085 }
06086
06087 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06088 tpeer->trunkdata = tmp;
06089 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);
06090 } else {
06091 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));
06092 ast_mutex_unlock(&tpeer->lock);
06093 return -1;
06094 }
06095 }
06096
06097
06098 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06099 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06100 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06101 mtm->len = htons(f->datalen);
06102 mtm->mini.callno = htons(pvt->callno);
06103 mtm->mini.ts = htons(0xffff & fr->ts);
06104 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06105 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06106 } else {
06107 met = (struct ast_iax2_meta_trunk_entry *)ptr;
06108
06109 met->callno = htons(pvt->callno);
06110 met->len = htons(f->datalen);
06111
06112 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06113 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06114 }
06115
06116 memcpy(ptr, f->data.ptr, f->datalen);
06117 tpeer->trunkdatalen += f->datalen;
06118
06119 tpeer->calls++;
06120
06121
06122 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
06123 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
06124
06125
06126 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06127 now = ast_tvnow();
06128 res = send_trunk(tpeer, &now);
06129 trunk_untimed ++;
06130 }
06131
06132 ast_mutex_unlock(&tpeer->lock);
06133 }
06134 return 0;
06135 }
06136
06137
06138
06139 static void build_rand_pad(unsigned char *buf, ssize_t len)
06140 {
06141 long tmp;
06142 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06143 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06144 buf += sizeof(tmp);
06145 len -= sizeof(tmp);
06146 }
06147 }
06148
06149 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06150 {
06151 build_ecx_key(digest, pvt);
06152 ast_aes_set_decrypt_key(digest, &pvt->dcx);
06153 }
06154
06155 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06156 {
06157
06158
06159
06160 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06161 ast_aes_set_encrypt_key(digest, &pvt->ecx);
06162 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06163 }
06164
06165 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
06166 {
06167 #if 0
06168
06169 int x;
06170 if (len % 16)
06171 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06172 for (x=0;x<len;x++)
06173 dst[x] = src[x] ^ 0xff;
06174 #else
06175 unsigned char lastblock[16] = { 0 };
06176 int x;
06177 while(len > 0) {
06178 ast_aes_decrypt(src, dst, dcx);
06179 for (x=0;x<16;x++)
06180 dst[x] ^= lastblock[x];
06181 memcpy(lastblock, src, sizeof(lastblock));
06182 dst += 16;
06183 src += 16;
06184 len -= 16;
06185 }
06186 #endif
06187 }
06188
06189 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
06190 {
06191 #if 0
06192
06193 int x;
06194 if (len % 16)
06195 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06196 for (x=0;x<len;x++)
06197 dst[x] = src[x] ^ 0xff;
06198 #else
06199 unsigned char curblock[16] = { 0 };
06200 int x;
06201 while(len > 0) {
06202 for (x=0;x<16;x++)
06203 curblock[x] ^= src[x];
06204 ast_aes_encrypt(curblock, dst, ecx);
06205 memcpy(curblock, dst, sizeof(curblock));
06206 dst += 16;
06207 src += 16;
06208 len -= 16;
06209 }
06210 #endif
06211 }
06212
06213 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06214 {
06215 int padding;
06216 unsigned char *workspace;
06217
06218 workspace = alloca(*datalen);
06219 memset(f, 0, sizeof(*f));
06220 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06221 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06222 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06223 return -1;
06224
06225 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06226
06227 padding = 16 + (workspace[15] & 0x0f);
06228 if (iaxdebug)
06229 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06230 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06231 return -1;
06232
06233 *datalen -= padding;
06234 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06235 f->frametype = fh->type;
06236 if (f->frametype == AST_FRAME_VIDEO) {
06237 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06238 } else if (f->frametype == AST_FRAME_VOICE) {
06239 f->subclass.codec = uncompress_subclass(fh->csub);
06240 } else {
06241 f->subclass.integer = uncompress_subclass(fh->csub);
06242 }
06243 } else {
06244 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06245 if (iaxdebug)
06246 ast_debug(1, "Decoding mini with length %d\n", *datalen);
06247 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06248 return -1;
06249
06250 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06251 padding = 16 + (workspace[15] & 0x0f);
06252 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06253 return -1;
06254 *datalen -= padding;
06255 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06256 }
06257 return 0;
06258 }
06259
06260 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06261 {
06262 int padding;
06263 unsigned char *workspace;
06264 workspace = alloca(*datalen + 32);
06265 if (!workspace)
06266 return -1;
06267 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06268 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06269 if (iaxdebug)
06270 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06271 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06272 padding = 16 + (padding & 0xf);
06273 memcpy(workspace, poo, padding);
06274 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06275 workspace[15] &= 0xf0;
06276 workspace[15] |= (padding & 0xf);
06277 if (iaxdebug)
06278 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06279 *datalen += padding;
06280 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06281 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06282 memcpy(poo, workspace + *datalen - 32, 32);
06283 } else {
06284 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06285 if (iaxdebug)
06286 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06287 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06288 padding = 16 + (padding & 0xf);
06289 memcpy(workspace, poo, padding);
06290 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06291 workspace[15] &= 0xf0;
06292 workspace[15] |= (padding & 0x0f);
06293 *datalen += padding;
06294 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06295 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06296 memcpy(poo, workspace + *datalen - 32, 32);
06297 }
06298 return 0;
06299 }
06300
06301 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06302 {
06303 int res=-1;
06304 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06305
06306 struct MD5Context md5;
06307 unsigned char digest[16];
06308 char *tmppw, *stringp;
06309
06310 tmppw = ast_strdupa(iaxs[callno]->secret);
06311 stringp = tmppw;
06312 while ((tmppw = strsep(&stringp, ";"))) {
06313 MD5Init(&md5);
06314 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06315 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06316 MD5Final(digest, &md5);
06317 build_encryption_keys(digest, iaxs[callno]);
06318 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06319 if (!res) {
06320 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06321 break;
06322 }
06323 }
06324 } else
06325 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06326 return res;
06327 }
06328
06329 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06330 {
06331
06332
06333
06334 struct ast_iax2_full_hdr *fh;
06335 struct ast_iax2_mini_hdr *mh;
06336 struct ast_iax2_video_hdr *vh;
06337 struct {
06338 struct iax_frame fr2;
06339 unsigned char buffer[4096];
06340 } frb;
06341 struct iax_frame *fr;
06342 int res;
06343 int sendmini=0;
06344 unsigned int lastsent;
06345 unsigned int fts;
06346
06347 frb.fr2.afdatalen = sizeof(frb.buffer);
06348
06349 if (!pvt) {
06350 ast_log(LOG_WARNING, "No private structure for packet?\n");
06351 return -1;
06352 }
06353
06354 lastsent = pvt->lastsent;
06355
06356
06357 fts = calc_timestamp(pvt, ts, f);
06358
06359
06360
06361
06362 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06363 return 0;
06364 #if 0
06365 ast_log(LOG_NOTICE,
06366 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06367 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06368 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06369 pvt->keyrotateid != -1 ? "" : "no "
06370 );
06371 #endif
06372 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06373 iax2_key_rotate(pvt);
06374 }
06375
06376 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
06377 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06378 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06379 &&
06380 (f->frametype == AST_FRAME_VOICE)
06381 &&
06382 (f->subclass.codec == pvt->svoiceformat)
06383 ) {
06384
06385 now = 1;
06386
06387 sendmini = 1;
06388 }
06389 if ( f->frametype == AST_FRAME_VIDEO ) {
06390
06391
06392
06393
06394
06395 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06396 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
06397 ) {
06398 now = 1;
06399 sendmini = 1;
06400 } else {
06401 now = 0;
06402 sendmini = 0;
06403 }
06404 pvt->lastvsent = fts;
06405 }
06406 if (f->frametype == AST_FRAME_IAX) {
06407
06408 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06409 if (!pvt->first_iax_message) {
06410 pvt->first_iax_message = pvt->last_iax_message;
06411 }
06412 }
06413
06414 if (now) {
06415 fr = &frb.fr2;
06416 } else
06417 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));
06418 if (!fr) {
06419 ast_log(LOG_WARNING, "Out of memory\n");
06420 return -1;
06421 }
06422
06423 iax_frame_wrap(fr, f);
06424
06425 fr->ts = fts;
06426 fr->callno = pvt->callno;
06427 fr->transfer = transfer;
06428 fr->final = final;
06429 fr->encmethods = 0;
06430 if (!sendmini) {
06431
06432 if (seqno > -1)
06433 fr->oseqno = seqno;
06434 else
06435 fr->oseqno = pvt->oseqno++;
06436 fr->iseqno = pvt->iseqno;
06437 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06438 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06439 fh->ts = htonl(fr->ts);
06440 fh->oseqno = fr->oseqno;
06441 if (transfer) {
06442 fh->iseqno = 0;
06443 } else
06444 fh->iseqno = fr->iseqno;
06445
06446 if (!transfer)
06447 pvt->aseqno = fr->iseqno;
06448 fh->type = fr->af.frametype & 0xFF;
06449
06450 if (fr->af.frametype == AST_FRAME_VIDEO) {
06451 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
06452 } else if (fr->af.frametype == AST_FRAME_VOICE) {
06453 fh->csub = compress_subclass(fr->af.subclass.codec);
06454 } else {
06455 fh->csub = compress_subclass(fr->af.subclass.integer);
06456 }
06457
06458 if (transfer) {
06459 fr->dcallno = pvt->transfercallno;
06460 } else
06461 fr->dcallno = pvt->peercallno;
06462 fh->dcallno = htons(fr->dcallno);
06463 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06464 fr->data = fh;
06465 fr->retries = 0;
06466
06467 fr->retrytime = pvt->pingtime * 2;
06468 if (fr->retrytime < MIN_RETRY_TIME)
06469 fr->retrytime = MIN_RETRY_TIME;
06470 if (fr->retrytime > MAX_RETRY_TIME)
06471 fr->retrytime = MAX_RETRY_TIME;
06472
06473 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06474 fr->retries = -1;
06475 else if (f->frametype == AST_FRAME_VOICE)
06476 pvt->svoiceformat = f->subclass.codec;
06477 else if (f->frametype == AST_FRAME_VIDEO)
06478 pvt->svideoformat = f->subclass.codec & ~0x1LL;
06479 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06480 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06481 if (fr->transfer)
06482 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06483 else
06484 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06485 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06486 fr->encmethods = pvt->encmethods;
06487 fr->ecx = pvt->ecx;
06488 fr->mydcx = pvt->mydcx;
06489 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06490 } else
06491 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06492 }
06493
06494 if (now) {
06495 res = send_packet(fr);
06496 } else
06497 res = iax2_transmit(fr);
06498 } else {
06499 if (ast_test_flag64(pvt, IAX_TRUNK)) {
06500 iax2_trunk_queue(pvt, fr);
06501 res = 0;
06502 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06503
06504 fr->oseqno = -1;
06505 fr->iseqno = -1;
06506 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06507 vh->zeros = 0;
06508 vh->callno = htons(0x8000 | fr->callno);
06509 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
06510 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06511 fr->data = vh;
06512 fr->retries = -1;
06513 res = send_packet(fr);
06514 } else {
06515
06516 fr->oseqno = -1;
06517 fr->iseqno = -1;
06518
06519 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06520 mh->callno = htons(fr->callno);
06521 mh->ts = htons(fr->ts & 0xFFFF);
06522 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06523 fr->data = mh;
06524 fr->retries = -1;
06525 if (pvt->transferring == TRANSFER_MEDIAPASS)
06526 fr->transfer = 1;
06527 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06528 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06529 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06530 } else
06531 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06532 }
06533 res = send_packet(fr);
06534 }
06535 }
06536 return res;
06537 }
06538
06539 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06540 {
06541 regex_t regexbuf;
06542 int havepattern = 0;
06543
06544 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06545 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06546
06547 struct iax2_user *user = NULL;
06548 char auth[90];
06549 char *pstr = "";
06550 struct ao2_iterator i;
06551
06552 switch (cmd) {
06553 case CLI_INIT:
06554 e->command = "iax2 show users [like]";
06555 e->usage =
06556 "Usage: iax2 show users [like <pattern>]\n"
06557 " Lists all known IAX2 users.\n"
06558 " Optional regular expression pattern is used to filter the user list.\n";
06559 return NULL;
06560 case CLI_GENERATE:
06561 return NULL;
06562 }
06563
06564 switch (a->argc) {
06565 case 5:
06566 if (!strcasecmp(a->argv[3], "like")) {
06567 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06568 return CLI_SHOWUSAGE;
06569 havepattern = 1;
06570 } else
06571 return CLI_SHOWUSAGE;
06572 case 3:
06573 break;
06574 default:
06575 return CLI_SHOWUSAGE;
06576 }
06577
06578 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06579 i = ao2_iterator_init(users, 0);
06580 for (user = ao2_iterator_next(&i); user;
06581 user_unref(user), user = ao2_iterator_next(&i)) {
06582 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06583 continue;
06584
06585 if (!ast_strlen_zero(user->secret)) {
06586 ast_copy_string(auth,user->secret, sizeof(auth));
06587 } else if (!ast_strlen_zero(user->inkeys)) {
06588 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06589 } else
06590 ast_copy_string(auth, "-no secret-", sizeof(auth));
06591
06592 if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06593 pstr = "REQ Only";
06594 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06595 pstr = "Disabled";
06596 else
06597 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06598
06599 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06600 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06601 user->ha ? "Yes" : "No", pstr);
06602 }
06603 ao2_iterator_destroy(&i);
06604
06605 if (havepattern)
06606 regfree(®exbuf);
06607
06608 return CLI_SUCCESS;
06609 #undef FORMAT
06610 #undef FORMAT2
06611 }
06612
06613 static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char * const argv[])
06614 {
06615 regex_t regexbuf;
06616 int havepattern = 0;
06617 int total_peers = 0;
06618 int online_peers = 0;
06619 int offline_peers = 0;
06620 int unmonitored_peers = 0;
06621 struct ao2_iterator i;
06622
06623 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n"
06624 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n"
06625
06626 struct iax2_peer *peer = NULL;
06627 char name[256];
06628 struct ast_str *encmethods = ast_str_alloca(256);
06629 int registeredonly=0;
06630 char idtext[256] = "";
06631 switch (argc) {
06632 case 6:
06633 if (!strcasecmp(argv[3], "registered"))
06634 registeredonly = 1;
06635 else
06636 return RESULT_SHOWUSAGE;
06637 if (!strcasecmp(argv[4], "like")) {
06638 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06639 return RESULT_SHOWUSAGE;
06640 havepattern = 1;
06641 } else
06642 return RESULT_SHOWUSAGE;
06643 break;
06644 case 5:
06645 if (!strcasecmp(argv[3], "like")) {
06646 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06647 return RESULT_SHOWUSAGE;
06648 havepattern = 1;
06649 } else
06650 return RESULT_SHOWUSAGE;
06651 break;
06652 case 4:
06653 if (!strcasecmp(argv[3], "registered"))
06654 registeredonly = 1;
06655 else
06656 return RESULT_SHOWUSAGE;
06657 break;
06658 case 3:
06659 break;
06660 default:
06661 return RESULT_SHOWUSAGE;
06662 }
06663
06664
06665 if (!s)
06666 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status");
06667
06668 i = ao2_iterator_init(peers, 0);
06669 for (peer = ao2_iterator_next(&i); peer;
06670 peer_unref(peer), peer = ao2_iterator_next(&i)) {
06671 char nm[20];
06672 char status[20];
06673 int retstatus;
06674 struct sockaddr_in peer_addr;
06675
06676 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06677
06678 if (registeredonly && !peer_addr.sin_addr.s_addr) {
06679 continue;
06680 }
06681 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
06682 continue;
06683 }
06684
06685 if (!ast_strlen_zero(peer->username))
06686 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06687 else
06688 ast_copy_string(name, peer->name, sizeof(name));
06689
06690 encmethods_to_str(peer->encmethods, encmethods);
06691 retstatus = peer_status(peer, status, sizeof(status));
06692 if (retstatus > 0)
06693 online_peers++;
06694 else if (!retstatus)
06695 offline_peers++;
06696 else
06697 unmonitored_peers++;
06698
06699 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06700
06701 if (s) {
06702 astman_append(s,
06703 "Event: PeerEntry\r\n%s"
06704 "Channeltype: IAX2\r\n"
06705 "ObjectName: %s\r\n"
06706 "ChanObjectType: peer\r\n"
06707 "IPaddress: %s\r\n"
06708 "IPport: %d\r\n"
06709 "Dynamic: %s\r\n"
06710 "Trunk: %s\r\n"
06711 "Encryption: %s\r\n"
06712 "Status: %s\r\n\r\n",
06713 idtext,
06714 name,
06715 ast_sockaddr_stringify_addr(&peer->addr),
06716 ast_sockaddr_port(&peer->addr),
06717 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06718 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06719 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06720 status);
06721 } else {
06722 ast_cli(fd, FORMAT, name,
06723 ast_sockaddr_stringify_addr(&peer->addr),
06724 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06725 nm,
06726 ast_sockaddr_port(&peer->addr),
06727 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
06728 peer->encmethods ? "(E)" : " ",
06729 status);
06730 }
06731 total_peers++;
06732 }
06733 ao2_iterator_destroy(&i);
06734
06735 if (!s)
06736 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06737 total_peers, online_peers, offline_peers, unmonitored_peers);
06738
06739 if (havepattern)
06740 regfree(®exbuf);
06741
06742 if (total)
06743 *total = total_peers;
06744
06745 return RESULT_SUCCESS;
06746 #undef FORMAT
06747 #undef FORMAT2
06748 }
06749
06750 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06751 {
06752 struct iax2_thread *thread = NULL;
06753 time_t t;
06754 int threadcount = 0, dynamiccount = 0;
06755 char type;
06756
06757 switch (cmd) {
06758 case CLI_INIT:
06759 e->command = "iax2 show threads";
06760 e->usage =
06761 "Usage: iax2 show threads\n"
06762 " Lists status of IAX helper threads\n";
06763 return NULL;
06764 case CLI_GENERATE:
06765 return NULL;
06766 }
06767 if (a->argc != 3)
06768 return CLI_SHOWUSAGE;
06769
06770 ast_cli(a->fd, "IAX2 Thread Information\n");
06771 time(&t);
06772 ast_cli(a->fd, "Idle Threads:\n");
06773 AST_LIST_LOCK(&idle_list);
06774 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06775 #ifdef DEBUG_SCHED_MULTITHREAD
06776 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06777 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06778 #else
06779 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06780 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06781 #endif
06782 threadcount++;
06783 }
06784 AST_LIST_UNLOCK(&idle_list);
06785 ast_cli(a->fd, "Active Threads:\n");
06786 AST_LIST_LOCK(&active_list);
06787 AST_LIST_TRAVERSE(&active_list, thread, list) {
06788 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06789 type = 'D';
06790 else
06791 type = 'P';
06792 #ifdef DEBUG_SCHED_MULTITHREAD
06793 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06794 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06795 #else
06796 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06797 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06798 #endif
06799 threadcount++;
06800 }
06801 AST_LIST_UNLOCK(&active_list);
06802 ast_cli(a->fd, "Dynamic Threads:\n");
06803 AST_LIST_LOCK(&dynamic_list);
06804 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06805 #ifdef DEBUG_SCHED_MULTITHREAD
06806 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06807 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06808 #else
06809 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06810 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06811 #endif
06812 dynamiccount++;
06813 }
06814 AST_LIST_UNLOCK(&dynamic_list);
06815 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06816 return CLI_SUCCESS;
06817 }
06818
06819 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06820 {
06821 struct iax2_peer *p;
06822
06823 switch (cmd) {
06824 case CLI_INIT:
06825 e->command = "iax2 unregister";
06826 e->usage =
06827 "Usage: iax2 unregister <peername>\n"
06828 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06829 return NULL;
06830 case CLI_GENERATE:
06831 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06832 }
06833
06834 if (a->argc != 3)
06835 return CLI_SHOWUSAGE;
06836
06837 p = find_peer(a->argv[2], 1);
06838 if (p) {
06839 if (p->expire > 0) {
06840 struct iax2_peer tmp_peer = {
06841 .name = a->argv[2],
06842 };
06843 struct iax2_peer *peer;
06844
06845 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06846 if (peer) {
06847 expire_registry(peer_ref(peer));
06848 peer_unref(peer);
06849 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06850 } else {
06851 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06852 }
06853 } else {
06854 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06855 }
06856 } else {
06857 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06858 }
06859 return CLI_SUCCESS;
06860 }
06861
06862 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06863 {
06864 int which = 0;
06865 struct iax2_peer *p = NULL;
06866 char *res = NULL;
06867 int wordlen = strlen(word);
06868
06869
06870 if (pos == 2) {
06871 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06872 while ((p = ao2_iterator_next(&i))) {
06873 if (!strncasecmp(p->name, word, wordlen) &&
06874 ++which > state && p->expire > 0) {
06875 res = ast_strdup(p->name);
06876 peer_unref(p);
06877 break;
06878 }
06879 peer_unref(p);
06880 }
06881 ao2_iterator_destroy(&i);
06882 }
06883
06884 return res;
06885 }
06886
06887 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06888 {
06889 switch (cmd) {
06890 case CLI_INIT:
06891 e->command = "iax2 show peers";
06892 e->usage =
06893 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06894 " Lists all known IAX2 peers.\n"
06895 " Optional 'registered' argument lists only peers with known addresses.\n"
06896 " Optional regular expression pattern is used to filter the peer list.\n";
06897 return NULL;
06898 case CLI_GENERATE:
06899 return NULL;
06900 }
06901
06902 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06903 case RESULT_SHOWUSAGE:
06904 return CLI_SHOWUSAGE;
06905 case RESULT_FAILURE:
06906 return CLI_FAILURE;
06907 default:
06908 return CLI_SUCCESS;
06909 }
06910 }
06911
06912 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06913 {
06914 ast_cli_netstats(s, -1, 0);
06915 astman_append(s, "\r\n");
06916 return RESULT_SUCCESS;
06917 }
06918
06919 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06920 {
06921 struct iax_firmware *cur = NULL;
06922
06923 switch (cmd) {
06924 case CLI_INIT:
06925 e->command = "iax2 show firmware";
06926 e->usage =
06927 "Usage: iax2 show firmware\n"
06928 " Lists all known IAX firmware images.\n";
06929 return NULL;
06930 case CLI_GENERATE:
06931 return NULL;
06932 }
06933
06934 if (a->argc != 3 && a->argc != 4)
06935 return CLI_SHOWUSAGE;
06936
06937 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06938 AST_LIST_LOCK(&firmwares);
06939 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06940 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06941 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06942 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06943 }
06944 }
06945 AST_LIST_UNLOCK(&firmwares);
06946
06947 return CLI_SUCCESS;
06948 }
06949
06950
06951 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06952 {
06953 static const char * const a[] = { "iax2", "show", "peers" };
06954 const char *id = astman_get_header(m,"ActionID");
06955 char idtext[256] = "";
06956 int total = 0;
06957
06958 if (!ast_strlen_zero(id))
06959 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06960
06961 astman_send_listack(s, m, "Peer status list will follow", "start");
06962
06963 __iax2_show_peers(-1, &total, s, 3, a);
06964
06965 astman_append(s,
06966 "Event: PeerlistComplete\r\n"
06967 "EventList: Complete\r\n"
06968 "ListItems: %d\r\n"
06969 "%s"
06970 "\r\n", total, idtext);
06971 return 0;
06972 }
06973
06974
06975 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06976 {
06977 struct iax2_peer *peer = NULL;
06978 int peer_count = 0;
06979 char nm[20];
06980 char status[20];
06981 const char *id = astman_get_header(m,"ActionID");
06982 char idtext[256] = "";
06983 struct ast_str *encmethods = ast_str_alloca(256);
06984 struct ao2_iterator i;
06985
06986 if (!ast_strlen_zero(id))
06987 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06988
06989 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06990
06991
06992 i = ao2_iterator_init(peers, 0);
06993 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06994 encmethods_to_str(peer->encmethods, encmethods);
06995 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06996 if (!ast_strlen_zero(peer->username)) {
06997 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06998 } else {
06999 astman_append(s, "ObjectName: %s\r\n", peer->name);
07000 }
07001 astman_append(s, "ChanObjectType: peer\r\n");
07002 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07003 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07004 astman_append(s, "Mask: %s\r\n", nm);
07005 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07006 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07007 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07008 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07009 peer_status(peer, status, sizeof(status));
07010 astman_append(s, "Status: %s\r\n\r\n", status);
07011 peer_count++;
07012 }
07013 ao2_iterator_destroy(&i);
07014
07015 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07016 return RESULT_SUCCESS;
07017 }
07018
07019
07020 static char *regstate2str(int regstate)
07021 {
07022 switch(regstate) {
07023 case REG_STATE_UNREGISTERED:
07024 return "Unregistered";
07025 case REG_STATE_REGSENT:
07026 return "Request Sent";
07027 case REG_STATE_AUTHSENT:
07028 return "Auth. Sent";
07029 case REG_STATE_REGISTERED:
07030 return "Registered";
07031 case REG_STATE_REJECTED:
07032 return "Rejected";
07033 case REG_STATE_TIMEOUT:
07034 return "Timeout";
07035 case REG_STATE_NOAUTH:
07036 return "No Authentication";
07037 default:
07038 return "Unknown";
07039 }
07040 }
07041
07042 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07043 {
07044 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
07045 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
07046 struct iax2_registry *reg = NULL;
07047 char host[80];
07048 char perceived[80];
07049 int counter = 0;
07050
07051 switch (cmd) {
07052 case CLI_INIT:
07053 e->command = "iax2 show registry";
07054 e->usage =
07055 "Usage: iax2 show registry\n"
07056 " Lists all registration requests and status.\n";
07057 return NULL;
07058 case CLI_GENERATE:
07059 return NULL;
07060 }
07061 if (a->argc != 3)
07062 return CLI_SHOWUSAGE;
07063 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07064 AST_LIST_LOCK(®istrations);
07065 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07066 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07067 if (reg->us.sin_addr.s_addr)
07068 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07069 else
07070 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07071 ast_cli(a->fd, FORMAT, host,
07072 (reg->dnsmgr) ? "Y" : "N",
07073 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07074 counter++;
07075 }
07076 AST_LIST_UNLOCK(®istrations);
07077 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07078 return CLI_SUCCESS;
07079 #undef FORMAT
07080 #undef FORMAT2
07081 }
07082
07083 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
07084 {
07085 const char *id = astman_get_header(m, "ActionID");
07086 struct iax2_registry *reg = NULL;
07087 char idtext[256] = "";
07088 char host[80] = "";
07089 char perceived[80] = "";
07090 int total = 0;
07091
07092 if (!ast_strlen_zero(id))
07093 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07094
07095 astman_send_listack(s, m, "Registrations will follow", "start");
07096
07097 AST_LIST_LOCK(®istrations);
07098 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07099 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07100
07101 if (reg->us.sin_addr.s_addr) {
07102 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07103 } else {
07104 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07105 }
07106
07107 astman_append(s,
07108 "Event: RegistryEntry\r\n"
07109 "%s"
07110 "Host: %s\r\n"
07111 "DNSmanager: %s\r\n"
07112 "Username: %s\r\n"
07113 "Perceived: %s\r\n"
07114 "Refresh: %d\r\n"
07115 "State: %s\r\n"
07116 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
07117 reg->refresh, regstate2str(reg->regstate));
07118
07119 total++;
07120 }
07121 AST_LIST_UNLOCK(®istrations);
07122
07123 astman_append(s,
07124 "Event: RegistrationsComplete\r\n"
07125 "EventList: Complete\r\n"
07126 "ListItems: %d\r\n"
07127 "%s"
07128 "\r\n", total, idtext);
07129
07130 return 0;
07131 }
07132
07133 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07134 {
07135 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
07136 #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"
07137 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
07138 int x;
07139 int numchans = 0;
07140 char first_message[10] = { 0, };
07141 char last_message[10] = { 0, };
07142
07143 switch (cmd) {
07144 case CLI_INIT:
07145 e->command = "iax2 show channels";
07146 e->usage =
07147 "Usage: iax2 show channels\n"
07148 " Lists all currently active IAX channels.\n";
07149 return NULL;
07150 case CLI_GENERATE:
07151 return NULL;
07152 }
07153
07154 if (a->argc != 3)
07155 return CLI_SHOWUSAGE;
07156 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07157 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07158 ast_mutex_lock(&iaxsl[x]);
07159 if (iaxs[x]) {
07160 int lag, jitter, localdelay;
07161 jb_info jbinfo;
07162 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07163 jb_getinfo(iaxs[x]->jb, &jbinfo);
07164 jitter = jbinfo.jitter;
07165 localdelay = jbinfo.current - jbinfo.min;
07166 } else {
07167 jitter = -1;
07168 localdelay = 0;
07169 }
07170
07171 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07172 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07173 lag = iaxs[x]->remote_rr.delay;
07174 ast_cli(a->fd, FORMAT,
07175 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07176 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07177 S_OR(iaxs[x]->username, "(None)"),
07178 iaxs[x]->callno, iaxs[x]->peercallno,
07179 iaxs[x]->oseqno, iaxs[x]->iseqno,
07180 lag,
07181 jitter,
07182 localdelay,
07183 ast_getformatname(iaxs[x]->voiceformat),
07184 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07185 first_message,
07186 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07187 last_message);
07188 numchans++;
07189 }
07190 ast_mutex_unlock(&iaxsl[x]);
07191 }
07192 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07193 return CLI_SUCCESS;
07194 #undef FORMAT
07195 #undef FORMAT2
07196 #undef FORMATB
07197 }
07198
07199 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
07200 {
07201 int x;
07202 int numchans = 0;
07203 char first_message[10] = { 0, };
07204 char last_message[10] = { 0, };
07205 #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"
07206 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07207 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07208 ast_mutex_lock(&iaxsl[x]);
07209 if (iaxs[x]) {
07210 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07211 jb_info jbinfo;
07212 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07213 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07214
07215 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07216 jb_getinfo(iaxs[x]->jb, &jbinfo);
07217 localjitter = jbinfo.jitter;
07218 localdelay = jbinfo.current - jbinfo.min;
07219 locallost = jbinfo.frames_lost;
07220 locallosspct = jbinfo.losspct/1000;
07221 localdropped = jbinfo.frames_dropped;
07222 localooo = jbinfo.frames_ooo;
07223 } else {
07224 localjitter = -1;
07225 localdelay = 0;
07226 locallost = -1;
07227 locallosspct = -1;
07228 localdropped = 0;
07229 localooo = -1;
07230 }
07231 if (s)
07232 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07233 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07234 iaxs[x]->pingtime,
07235 localjitter,
07236 localdelay,
07237 locallost,
07238 locallosspct,
07239 localdropped,
07240 localooo,
07241 iaxs[x]->frames_received/1000,
07242 iaxs[x]->remote_rr.jitter,
07243 iaxs[x]->remote_rr.delay,
07244 iaxs[x]->remote_rr.losscnt,
07245 iaxs[x]->remote_rr.losspct,
07246 iaxs[x]->remote_rr.dropped,
07247 iaxs[x]->remote_rr.ooo,
07248 iaxs[x]->remote_rr.packets/1000,
07249 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07250 first_message,
07251 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07252 last_message);
07253 else
07254 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07255 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07256 iaxs[x]->pingtime,
07257 localjitter,
07258 localdelay,
07259 locallost,
07260 locallosspct,
07261 localdropped,
07262 localooo,
07263 iaxs[x]->frames_received/1000,
07264 iaxs[x]->remote_rr.jitter,
07265 iaxs[x]->remote_rr.delay,
07266 iaxs[x]->remote_rr.losscnt,
07267 iaxs[x]->remote_rr.losspct,
07268 iaxs[x]->remote_rr.dropped,
07269 iaxs[x]->remote_rr.ooo,
07270 iaxs[x]->remote_rr.packets/1000,
07271 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07272 first_message,
07273 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07274 last_message);
07275 numchans++;
07276 }
07277 ast_mutex_unlock(&iaxsl[x]);
07278 }
07279
07280 return numchans;
07281 }
07282
07283 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07284 {
07285 int numchans = 0;
07286
07287 switch (cmd) {
07288 case CLI_INIT:
07289 e->command = "iax2 show netstats";
07290 e->usage =
07291 "Usage: iax2 show netstats\n"
07292 " Lists network status for all currently active IAX channels.\n";
07293 return NULL;
07294 case CLI_GENERATE:
07295 return NULL;
07296 }
07297 if (a->argc != 3)
07298 return CLI_SHOWUSAGE;
07299 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07300 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07301 numchans = ast_cli_netstats(NULL, a->fd, 1);
07302 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07303 return CLI_SUCCESS;
07304 }
07305
07306 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07307 {
07308 switch (cmd) {
07309 case CLI_INIT:
07310 e->command = "iax2 set debug {on|off|peer}";
07311 e->usage =
07312 "Usage: iax2 set debug {on|off|peer peername}\n"
07313 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07314 return NULL;
07315 case CLI_GENERATE:
07316 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07317 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07318 return NULL;
07319 }
07320
07321 if (a->argc < e->args || a->argc > e->args + 1)
07322 return CLI_SHOWUSAGE;
07323
07324 if (!strcasecmp(a->argv[3], "peer")) {
07325 struct iax2_peer *peer;
07326 struct sockaddr_in peer_addr;
07327
07328
07329 if (a->argc != e->args + 1)
07330 return CLI_SHOWUSAGE;
07331
07332 peer = find_peer(a->argv[4], 1);
07333
07334 if (!peer) {
07335 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07336 return CLI_FAILURE;
07337 }
07338
07339 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07340
07341 debugaddr.sin_addr = peer_addr.sin_addr;
07342 debugaddr.sin_port = peer_addr.sin_port;
07343
07344 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07345 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07346
07347 ao2_ref(peer, -1);
07348 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07349 iaxdebug = 1;
07350 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07351 } else {
07352 iaxdebug = 0;
07353 memset(&debugaddr, 0, sizeof(debugaddr));
07354 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07355 }
07356 return CLI_SUCCESS;
07357 }
07358
07359 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07360 {
07361 switch (cmd) {
07362 case CLI_INIT:
07363 e->command = "iax2 set debug trunk {on|off}";
07364 e->usage =
07365 "Usage: iax2 set debug trunk {on|off}\n"
07366 " Enables/Disables debugging of IAX trunking\n";
07367 return NULL;
07368 case CLI_GENERATE:
07369 return NULL;
07370 }
07371
07372 if (a->argc != e->args)
07373 return CLI_SHOWUSAGE;
07374
07375 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07376 iaxtrunkdebug = 1;
07377 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07378 } else {
07379 iaxtrunkdebug = 0;
07380 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07381 }
07382 return CLI_SUCCESS;
07383 }
07384
07385 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07386 {
07387 switch (cmd) {
07388 case CLI_INIT:
07389 e->command = "iax2 set debug jb {on|off}";
07390 e->usage =
07391 "Usage: iax2 set debug jb {on|off}\n"
07392 " Enables/Disables jitterbuffer debugging information\n";
07393 return NULL;
07394 case CLI_GENERATE:
07395 return NULL;
07396 }
07397
07398 if (a->argc != e->args)
07399 return CLI_SHOWUSAGE;
07400
07401 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07402 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07403 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07404 } else {
07405 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07406 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07407 }
07408 return CLI_SUCCESS;
07409 }
07410
07411 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07412 {
07413 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07414 int res = -1;
07415 ast_mutex_lock(&iaxsl[callno]);
07416 if (iaxs[callno]) {
07417
07418 if (!iaxs[callno]->error) {
07419 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07420 res = 0;
07421
07422 else if (f->frametype == AST_FRAME_NULL)
07423 res = 0;
07424 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07425 res = 0;
07426 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07427 res = 0;
07428 else
07429
07430 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07431 } else {
07432 ast_debug(1, "Write error: %s\n", strerror(errno));
07433 }
07434 }
07435
07436 ast_mutex_unlock(&iaxsl[callno]);
07437 return res;
07438 }
07439
07440 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07441 int now, int transfer, int final)
07442 {
07443 struct ast_frame f = { 0, };
07444 int res = 0;
07445
07446 f.frametype = type;
07447 f.subclass.integer = command;
07448 f.datalen = datalen;
07449 f.src = __FUNCTION__;
07450 f.data.ptr = (void *) data;
07451
07452 if ((res = queue_signalling(i, &f)) <= 0) {
07453 return res;
07454 }
07455
07456 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07457 }
07458
07459 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07460 {
07461 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07462 }
07463
07464 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07465 {
07466 int res;
07467 ast_mutex_lock(&iaxsl[callno]);
07468 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07469 ast_mutex_unlock(&iaxsl[callno]);
07470 return res;
07471 }
07472
07473
07474
07475
07476
07477
07478 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)
07479 {
07480 int call_num = i->callno;
07481
07482 iax2_predestroy(i->callno);
07483 if (!iaxs[call_num])
07484 return -1;
07485 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07486 }
07487
07488 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)
07489 {
07490 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07491 }
07492
07493 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07494 {
07495 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07496 }
07497
07498 static int apply_context(struct iax2_context *con, const char *context)
07499 {
07500 while(con) {
07501 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07502 return -1;
07503 con = con->next;
07504 }
07505 return 0;
07506 }
07507
07508
07509 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07510 {
07511
07512 int res = -1;
07513 int version = 2;
07514 struct iax2_user *user = NULL, *best = NULL;
07515 int bestscore = 0;
07516 int gotcapability = 0;
07517 struct ast_variable *v = NULL, *tmpvar = NULL;
07518 struct ao2_iterator i;
07519 struct ast_sockaddr addr;
07520
07521 if (!iaxs[callno])
07522 return res;
07523 if (ies->called_number)
07524 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07525 if (ies->calling_number) {
07526 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07527 ast_shrink_phone_number(ies->calling_number);
07528 }
07529 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07530 }
07531 if (ies->calling_name)
07532 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07533 if (ies->calling_ani)
07534 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07535 if (ies->dnid)
07536 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07537 if (ies->rdnis)
07538 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07539 if (ies->called_context)
07540 ast_string_field_set(iaxs[callno], context, ies->called_context);
07541 if (ies->language)
07542 ast_string_field_set(iaxs[callno], language, ies->language);
07543 if (ies->username)
07544 ast_string_field_set(iaxs[callno], username, ies->username);
07545 if (ies->calling_ton > -1)
07546 iaxs[callno]->calling_ton = ies->calling_ton;
07547 if (ies->calling_tns > -1)
07548 iaxs[callno]->calling_tns = ies->calling_tns;
07549 if (ies->calling_pres > -1)
07550 iaxs[callno]->calling_pres = ies->calling_pres;
07551 if (ies->format)
07552 iaxs[callno]->peerformat = ies->format;
07553 if (ies->adsicpe)
07554 iaxs[callno]->peeradsicpe = ies->adsicpe;
07555 if (ies->capability) {
07556 gotcapability = 1;
07557 iaxs[callno]->peercapability = ies->capability;
07558 }
07559 if (ies->version)
07560 version = ies->version;
07561
07562
07563 if (ies->codec_prefs) {
07564 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07565 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07566 }
07567
07568 if (!gotcapability)
07569 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07570 if (version > IAX_PROTO_VERSION) {
07571 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07572 ast_inet_ntoa(sin->sin_addr), version);
07573 return res;
07574 }
07575
07576 i = ao2_iterator_init(users, 0);
07577 ast_sockaddr_from_sin(&addr, sin);
07578 while ((user = ao2_iterator_next(&i))) {
07579 if ((ast_strlen_zero(iaxs[callno]->username) ||
07580 !strcmp(iaxs[callno]->username, user->name))
07581 && ast_apply_ha(user->ha, &addr)
07582 && (ast_strlen_zero(iaxs[callno]->context) ||
07583 apply_context(user->contexts, iaxs[callno]->context))) {
07584 if (!ast_strlen_zero(iaxs[callno]->username)) {
07585
07586 if (best)
07587 user_unref(best);
07588 best = user;
07589 break;
07590 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07591
07592 if (user->ha) {
07593
07594 if (bestscore < 4) {
07595 bestscore = 4;
07596 if (best)
07597 user_unref(best);
07598 best = user;
07599 continue;
07600 }
07601 } else {
07602
07603 if (bestscore < 3) {
07604 bestscore = 3;
07605 if (best)
07606 user_unref(best);
07607 best = user;
07608 continue;
07609 }
07610 }
07611 } else {
07612 if (user->ha) {
07613
07614 if (bestscore < 2) {
07615 bestscore = 2;
07616 if (best)
07617 user_unref(best);
07618 best = user;
07619 continue;
07620 }
07621 } else {
07622
07623 if (bestscore < 1) {
07624 bestscore = 1;
07625 if (best)
07626 user_unref(best);
07627 best = user;
07628 continue;
07629 }
07630 }
07631 }
07632 }
07633 user_unref(user);
07634 }
07635 ao2_iterator_destroy(&i);
07636 user = best;
07637 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07638 user = realtime_user(iaxs[callno]->username, sin);
07639 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07640 !apply_context(user->contexts, iaxs[callno]->context)) {
07641 user = user_unref(user);
07642 }
07643 }
07644 if (user) {
07645
07646
07647 for (v = user->vars ; v ; v = v->next) {
07648 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07649 tmpvar->next = iaxs[callno]->vars;
07650 iaxs[callno]->vars = tmpvar;
07651 }
07652 }
07653
07654 if (user->maxauthreq > 0)
07655 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07656 iaxs[callno]->prefs = user->prefs;
07657 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07658 iaxs[callno]->encmethods = user->encmethods;
07659
07660 if (ast_strlen_zero(iaxs[callno]->username))
07661 ast_string_field_set(iaxs[callno], username, user->name);
07662
07663 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07664 iaxs[callno]->capability = user->capability;
07665
07666 if (ast_strlen_zero(iaxs[callno]->context)) {
07667 if (user->contexts)
07668 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07669 else
07670 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07671 }
07672
07673 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07674
07675 iaxs[callno]->authmethods = user->authmethods;
07676 iaxs[callno]->adsi = user->adsi;
07677
07678 if (ast_test_flag64(user, IAX_HASCALLERID)) {
07679 iaxs[callno]->calling_tns = 0;
07680 iaxs[callno]->calling_ton = 0;
07681 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07682 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07683 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07684 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07685 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07686 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07687 }
07688 if (!ast_strlen_zero(user->accountcode))
07689 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07690 if (!ast_strlen_zero(user->mohinterpret))
07691 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07692 if (!ast_strlen_zero(user->mohsuggest))
07693 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07694 if (!ast_strlen_zero(user->parkinglot))
07695 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07696 if (user->amaflags)
07697 iaxs[callno]->amaflags = user->amaflags;
07698 if (!ast_strlen_zero(user->language))
07699 ast_string_field_set(iaxs[callno], language, user->language);
07700 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
07701
07702 if (!ast_strlen_zero(user->dbsecret)) {
07703 char *family, *key=NULL;
07704 char buf[80];
07705 family = ast_strdupa(user->dbsecret);
07706 key = strchr(family, '/');
07707 if (key) {
07708 *key = '\0';
07709 key++;
07710 }
07711 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07712 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07713 else
07714 ast_string_field_set(iaxs[callno], secret, buf);
07715 } else
07716 ast_string_field_set(iaxs[callno], secret, user->secret);
07717 res = 0;
07718 user = user_unref(user);
07719 } else {
07720
07721
07722
07723
07724 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07725 ast_string_field_set(iaxs[callno], secret, "badsecret");
07726 iaxs[callno]->authrej = 1;
07727 if (!ast_strlen_zero(iaxs[callno]->username)) {
07728
07729 res = 0;
07730 }
07731 }
07732 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07733 return res;
07734 }
07735
07736 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07737 {
07738 struct ast_iax2_full_hdr fh;
07739 fh.scallno = htons(src | IAX_FLAG_FULL);
07740 fh.dcallno = htons(dst);
07741 fh.ts = 0;
07742 fh.oseqno = 0;
07743 fh.iseqno = 0;
07744 fh.type = AST_FRAME_IAX;
07745 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07746 iax_outputframe(NULL, &fh, 0, sin, 0);
07747 #if 0
07748 if (option_debug)
07749 #endif
07750 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07751 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07752 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07753 }
07754
07755 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07756 {
07757
07758 p->encmethods &= enc;
07759 if (p->encmethods) {
07760 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07761 p->keyrotateid = -2;
07762 }
07763 if (p->encmethods & IAX_ENCRYPT_AES128)
07764 p->encmethods = IAX_ENCRYPT_AES128;
07765 else
07766 p->encmethods = 0;
07767 }
07768 }
07769
07770
07771
07772
07773
07774
07775
07776 static int authenticate_request(int call_num)
07777 {
07778 struct iax_ie_data ied;
07779 int res = -1, authreq_restrict = 0;
07780 char challenge[10];
07781 struct chan_iax2_pvt *p = iaxs[call_num];
07782
07783 memset(&ied, 0, sizeof(ied));
07784
07785
07786 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07787 struct iax2_user *user, tmp_user = {
07788 .name = p->username,
07789 };
07790
07791 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07792 if (user) {
07793 if (user->curauthreq == user->maxauthreq)
07794 authreq_restrict = 1;
07795 else
07796 user->curauthreq++;
07797 user = user_unref(user);
07798 }
07799 }
07800
07801
07802 if (authreq_restrict) {
07803 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07804 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07805 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07806 return 0;
07807 }
07808
07809 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07810 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07811 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07812 ast_string_field_set(p, challenge, challenge);
07813
07814 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07815 }
07816 if (p->encmethods)
07817 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07818
07819 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07820
07821 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07822
07823 if (p->encmethods)
07824 ast_set_flag64(p, IAX_ENCRYPTED);
07825
07826 return res;
07827 }
07828
07829 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07830 {
07831 char requeststr[256];
07832 char md5secret[256] = "";
07833 char secret[256] = "";
07834 char rsasecret[256] = "";
07835 int res = -1;
07836 int x;
07837 struct iax2_user *user, tmp_user = {
07838 .name = p->username,
07839 };
07840
07841 if (p->authrej) {
07842 return res;
07843 }
07844 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07845 if (user) {
07846 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07847 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07848 ast_clear_flag64(p, IAX_MAXAUTHREQ);
07849 }
07850 ast_string_field_set(p, host, user->name);
07851 user = user_unref(user);
07852 }
07853 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07854 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07855 return res;
07856 }
07857 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07858 return res;
07859 if (ies->password)
07860 ast_copy_string(secret, ies->password, sizeof(secret));
07861 if (ies->md5_result)
07862 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07863 if (ies->rsa_result)
07864 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07865 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07866 struct ast_key *key;
07867 char *keyn;
07868 char tmpkey[256];
07869 char *stringp=NULL;
07870 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07871 stringp=tmpkey;
07872 keyn = strsep(&stringp, ":");
07873 while(keyn) {
07874 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07875 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07876 res = 0;
07877 break;
07878 } else if (!key)
07879 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07880 keyn = strsep(&stringp, ":");
07881 }
07882 } else if (p->authmethods & IAX_AUTH_MD5) {
07883 struct MD5Context md5;
07884 unsigned char digest[16];
07885 char *tmppw, *stringp;
07886
07887 tmppw = ast_strdupa(p->secret);
07888 stringp = tmppw;
07889 while((tmppw = strsep(&stringp, ";"))) {
07890 MD5Init(&md5);
07891 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07892 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07893 MD5Final(digest, &md5);
07894
07895 for (x=0;x<16;x++)
07896 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07897 if (!strcasecmp(requeststr, md5secret)) {
07898 res = 0;
07899 break;
07900 }
07901 }
07902 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07903 if (!strcmp(secret, p->secret))
07904 res = 0;
07905 }
07906 return res;
07907 }
07908
07909
07910 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07911 {
07912 char requeststr[256] = "";
07913 char peer[256] = "";
07914 char md5secret[256] = "";
07915 char rsasecret[256] = "";
07916 char secret[256] = "";
07917 struct iax2_peer *p = NULL;
07918 struct ast_key *key;
07919 char *keyn;
07920 int x;
07921 int expire = 0;
07922 int res = -1;
07923 struct ast_sockaddr addr;
07924
07925 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07926
07927 if (ies->username)
07928 ast_copy_string(peer, ies->username, sizeof(peer));
07929 if (ies->password)
07930 ast_copy_string(secret, ies->password, sizeof(secret));
07931 if (ies->md5_result)
07932 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07933 if (ies->rsa_result)
07934 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07935 if (ies->refresh)
07936 expire = ies->refresh;
07937
07938 if (ast_strlen_zero(peer)) {
07939 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07940 return -1;
07941 }
07942
07943
07944 ast_mutex_unlock(&iaxsl[callno]);
07945 p = find_peer(peer, 1);
07946 ast_mutex_lock(&iaxsl[callno]);
07947 if (!p || !iaxs[callno]) {
07948 if (iaxs[callno]) {
07949 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07950
07951 ast_string_field_set(iaxs[callno], secret, "badsecret");
07952
07953
07954
07955
07956
07957
07958
07959
07960
07961 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07962 !(!ast_strlen_zero(secret) && plaintext)) {
07963
07964 res = 0;
07965 }
07966 }
07967 if (authdebug && !p)
07968 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07969 goto return_unref;
07970 }
07971
07972 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
07973 if (authdebug)
07974 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07975 goto return_unref;
07976 }
07977
07978 ast_sockaddr_from_sin(&addr, sin);
07979 if (!ast_apply_ha(p->ha, &addr)) {
07980 if (authdebug)
07981 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07982 goto return_unref;
07983 }
07984 ast_string_field_set(iaxs[callno], secret, p->secret);
07985 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07986
07987 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07988 if (!ast_strlen_zero(p->inkeys)) {
07989 char tmpkeys[256];
07990 char *stringp=NULL;
07991 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07992 stringp=tmpkeys;
07993 keyn = strsep(&stringp, ":");
07994 while(keyn) {
07995 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07996 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07997 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07998 break;
07999 } else if (!key)
08000 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08001 keyn = strsep(&stringp, ":");
08002 }
08003 if (!keyn) {
08004 if (authdebug)
08005 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08006 goto return_unref;
08007 }
08008 } else {
08009 if (authdebug)
08010 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08011 goto return_unref;
08012 }
08013 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08014 struct MD5Context md5;
08015 unsigned char digest[16];
08016 char *tmppw, *stringp;
08017
08018 tmppw = ast_strdupa(p->secret);
08019 stringp = tmppw;
08020 while((tmppw = strsep(&stringp, ";"))) {
08021 MD5Init(&md5);
08022 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08023 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08024 MD5Final(digest, &md5);
08025 for (x=0;x<16;x++)
08026 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
08027 if (!strcasecmp(requeststr, md5secret))
08028 break;
08029 }
08030 if (tmppw) {
08031 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08032 } else {
08033 if (authdebug)
08034 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08035 goto return_unref;
08036 }
08037 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08038
08039 if (strcmp(secret, p->secret)) {
08040 if (authdebug)
08041 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08042 goto return_unref;
08043 } else
08044 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08045 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08046
08047 goto return_unref;
08048 }
08049 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08050
08051
08052 res = 0;
08053
08054 return_unref:
08055 if (iaxs[callno]) {
08056 ast_string_field_set(iaxs[callno], peer, peer);
08057
08058
08059 if (expire && (expire < iaxs[callno]->expiry)) {
08060 iaxs[callno]->expiry = expire;
08061 }
08062 }
08063
08064 if (p) {
08065 peer_unref(p);
08066 }
08067 return res;
08068 }
08069
08070 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)
08071 {
08072 int res = -1;
08073 int x;
08074 if (!ast_strlen_zero(keyn)) {
08075 if (!(authmethods & IAX_AUTH_RSA)) {
08076 if (ast_strlen_zero(secret))
08077 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));
08078 } else if (ast_strlen_zero(challenge)) {
08079 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08080 } else {
08081 char sig[256];
08082 struct ast_key *key;
08083 key = ast_key_get(keyn, AST_KEY_PRIVATE);
08084 if (!key) {
08085 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08086 } else {
08087 if (ast_sign(key, (char*)challenge, sig)) {
08088 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08089 res = -1;
08090 } else {
08091 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08092 res = 0;
08093 }
08094 }
08095 }
08096 }
08097
08098 if (res && !ast_strlen_zero(secret)) {
08099 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08100 struct MD5Context md5;
08101 unsigned char digest[16];
08102 char digres[128];
08103 MD5Init(&md5);
08104 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08105 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08106 MD5Final(digest, &md5);
08107
08108 for (x=0;x<16;x++)
08109 sprintf(digres + (x << 1), "%2.2x", digest[x]);
08110 if (pvt) {
08111 build_encryption_keys(digest, pvt);
08112 }
08113 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08114 res = 0;
08115 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08116 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08117 res = 0;
08118 } else
08119 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08120 }
08121 return res;
08122 }
08123
08124
08125
08126
08127
08128 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
08129 {
08130 struct iax2_peer *peer = NULL;
08131
08132 int res = -1;
08133 int authmethods = 0;
08134 struct iax_ie_data ied;
08135 uint16_t callno = p->callno;
08136
08137 memset(&ied, 0, sizeof(ied));
08138
08139 if (ies->username)
08140 ast_string_field_set(p, username, ies->username);
08141 if (ies->challenge)
08142 ast_string_field_set(p, challenge, ies->challenge);
08143 if (ies->authmethods)
08144 authmethods = ies->authmethods;
08145 if (authmethods & IAX_AUTH_MD5)
08146 merge_encryption(p, ies->encmethods);
08147 else
08148 p->encmethods = 0;
08149
08150
08151 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08152
08153 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08154 } else {
08155 struct ao2_iterator i = ao2_iterator_init(peers, 0);
08156 while ((peer = ao2_iterator_next(&i))) {
08157 struct sockaddr_in peer_addr;
08158
08159 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08160
08161 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08162
08163 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08164
08165 && (!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)))
08166
08167 ) {
08168 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08169 if (!res) {
08170 peer_unref(peer);
08171 break;
08172 }
08173 }
08174 peer_unref(peer);
08175 }
08176 ao2_iterator_destroy(&i);
08177 if (!peer) {
08178
08179
08180 const char *peer_name = ast_strdupa(p->peer);
08181 ast_mutex_unlock(&iaxsl[callno]);
08182 if ((peer = realtime_peer(peer_name, NULL))) {
08183 ast_mutex_lock(&iaxsl[callno]);
08184 if (!(p = iaxs[callno])) {
08185 peer_unref(peer);
08186 return -1;
08187 }
08188 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08189 peer_unref(peer);
08190 }
08191 if (!peer) {
08192 ast_mutex_lock(&iaxsl[callno]);
08193 if (!(p = iaxs[callno]))
08194 return -1;
08195 }
08196 }
08197 }
08198
08199 if (ies->encmethods) {
08200 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08201 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08202 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
08203 return -1;
08204 }
08205 if (!res) {
08206 struct ast_datastore *variablestore;
08207 struct ast_variable *var, *prev = NULL;
08208 AST_LIST_HEAD(, ast_var_t) *varlist;
08209 varlist = ast_calloc(1, sizeof(*varlist));
08210 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08211 if (variablestore && varlist && p->owner) {
08212 variablestore->data = varlist;
08213 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08214 AST_LIST_HEAD_INIT(varlist);
08215 for (var = ies->vars; var; var = var->next) {
08216 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08217 if (prev)
08218 ast_free(prev);
08219 prev = var;
08220 if (!newvar) {
08221
08222 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08223 } else {
08224 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08225 }
08226 }
08227 if (prev)
08228 ast_free(prev);
08229 ies->vars = NULL;
08230 ast_channel_datastore_add(p->owner, variablestore);
08231 } else {
08232 if (p->owner)
08233 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08234 if (variablestore)
08235 ast_datastore_free(variablestore);
08236 if (varlist)
08237 ast_free(varlist);
08238 }
08239 }
08240
08241 if (!res)
08242 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08243 return res;
08244 }
08245
08246 static int iax2_do_register(struct iax2_registry *reg);
08247
08248 static void __iax2_do_register_s(const void *data)
08249 {
08250 struct iax2_registry *reg = (struct iax2_registry *)data;
08251 reg->expire = -1;
08252 iax2_do_register(reg);
08253 }
08254
08255 static int iax2_do_register_s(const void *data)
08256 {
08257 #ifdef SCHED_MULTITHREADED
08258 if (schedule_action(__iax2_do_register_s, data))
08259 #endif
08260 __iax2_do_register_s(data);
08261 return 0;
08262 }
08263
08264 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08265 {
08266 int newcall = 0;
08267 char newip[256];
08268 struct iax_ie_data ied;
08269 struct sockaddr_in new;
08270
08271
08272 memset(&ied, 0, sizeof(ied));
08273 if (ies->apparent_addr)
08274 memmove(&new, ies->apparent_addr, sizeof(new));
08275 if (ies->callno)
08276 newcall = ies->callno;
08277 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08278 ast_log(LOG_WARNING, "Invalid transfer request\n");
08279 return -1;
08280 }
08281 pvt->transfercallno = newcall;
08282 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08283 inet_aton(newip, &pvt->transfer.sin_addr);
08284 pvt->transfer.sin_family = AF_INET;
08285 pvt->transferid = ies->transferid;
08286
08287
08288 if (pvt->transferring == TRANSFER_NONE) {
08289 store_by_transfercallno(pvt);
08290 }
08291 pvt->transferring = TRANSFER_BEGIN;
08292
08293 if (ies->transferid)
08294 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08295 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08296 return 0;
08297 }
08298
08299 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08300 {
08301 char exten[256] = "";
08302 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08303 struct iax2_dpcache *dp = NULL;
08304
08305 if (ies->called_number)
08306 ast_copy_string(exten, ies->called_number, sizeof(exten));
08307
08308 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08309 status = CACHE_FLAG_EXISTS;
08310 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08311 status = CACHE_FLAG_CANEXIST;
08312 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08313 status = CACHE_FLAG_NONEXISTENT;
08314
08315 if (ies->refresh)
08316 expiry = ies->refresh;
08317 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08318 matchmore = CACHE_FLAG_MATCHMORE;
08319
08320 AST_LIST_LOCK(&dpcache);
08321 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08322 if (strcmp(dp->exten, exten))
08323 continue;
08324 AST_LIST_REMOVE_CURRENT(peer_list);
08325 dp->callno = 0;
08326 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08327 if (dp->flags & CACHE_FLAG_PENDING) {
08328 dp->flags &= ~CACHE_FLAG_PENDING;
08329 dp->flags |= status;
08330 dp->flags |= matchmore;
08331 }
08332
08333 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08334 if (dp->waiters[x] > -1) {
08335 if (write(dp->waiters[x], "asdf", 4) < 0) {
08336 }
08337 }
08338 }
08339 }
08340 AST_LIST_TRAVERSE_SAFE_END;
08341 AST_LIST_UNLOCK(&dpcache);
08342
08343 return 0;
08344 }
08345
08346 static int complete_transfer(int callno, struct iax_ies *ies)
08347 {
08348 int peercallno = 0;
08349 struct chan_iax2_pvt *pvt = iaxs[callno];
08350 struct iax_frame *cur;
08351 jb_frame frame;
08352
08353 if (ies->callno)
08354 peercallno = ies->callno;
08355
08356 if (peercallno < 1) {
08357 ast_log(LOG_WARNING, "Invalid transfer request\n");
08358 return -1;
08359 }
08360 remove_by_transfercallno(pvt);
08361
08362
08363
08364 peercnt_remove_by_addr(&pvt->addr);
08365 peercnt_add(&pvt->transfer);
08366
08367 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08368 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08369
08370 pvt->oseqno = 0;
08371 pvt->rseqno = 0;
08372 pvt->iseqno = 0;
08373 pvt->aseqno = 0;
08374
08375 if (pvt->peercallno) {
08376 remove_by_peercallno(pvt);
08377 }
08378 pvt->peercallno = peercallno;
08379
08380 store_by_peercallno(pvt);
08381 pvt->transferring = TRANSFER_NONE;
08382 pvt->svoiceformat = -1;
08383 pvt->voiceformat = 0;
08384 pvt->svideoformat = -1;
08385 pvt->videoformat = 0;
08386 pvt->transfercallno = 0;
08387 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08388 memset(&pvt->offset, 0, sizeof(pvt->offset));
08389
08390 while(jb_getall(pvt->jb,&frame) == JB_OK)
08391 iax2_frame_free(frame.data);
08392 jb_reset(pvt->jb);
08393 pvt->lag = 0;
08394 pvt->last = 0;
08395 pvt->lastsent = 0;
08396 pvt->nextpred = 0;
08397 pvt->pingtime = DEFAULT_RETRY_TIME;
08398 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08399
08400
08401
08402 cur->retries = -1;
08403 }
08404 return 0;
08405 }
08406
08407
08408 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08409 {
08410 struct iax2_registry *reg;
08411
08412 char peer[256] = "";
08413 char msgstatus[60];
08414 int refresh = 60;
08415 char ourip[256] = "<Unspecified>";
08416 struct sockaddr_in oldus;
08417 struct sockaddr_in us;
08418 int oldmsgs;
08419 struct sockaddr_in reg_addr;
08420
08421 memset(&us, 0, sizeof(us));
08422 if (ies->apparent_addr)
08423 memmove(&us, ies->apparent_addr, sizeof(us));
08424 if (ies->username)
08425 ast_copy_string(peer, ies->username, sizeof(peer));
08426 if (ies->refresh)
08427 refresh = ies->refresh;
08428 if (ies->calling_number) {
08429
08430 }
08431 reg = iaxs[callno]->reg;
08432 if (!reg) {
08433 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08434 return -1;
08435 }
08436 memcpy(&oldus, ®->us, sizeof(oldus));
08437 oldmsgs = reg->messages;
08438 ast_sockaddr_to_sin(®->addr, ®_addr);
08439 if (inaddrcmp(®_addr, sin)) {
08440 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08441 return -1;
08442 }
08443 memcpy(®->us, &us, sizeof(reg->us));
08444 if (ies->msgcount >= 0)
08445 reg->messages = ies->msgcount & 0xffff;
08446
08447
08448
08449 reg->refresh = refresh;
08450 reg->expire = iax2_sched_replace(reg->expire, sched,
08451 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08452 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08453 if (reg->messages > 255)
08454 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08455 else if (reg->messages > 1)
08456 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
08457 else if (reg->messages > 0)
08458 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
08459 else
08460 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
08461 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08462 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08463 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08464 }
08465 reg->regstate = REG_STATE_REGISTERED;
08466 return 0;
08467 }
08468
08469 static int iax2_append_register(const char *hostname, const char *username,
08470 const char *secret, const char *porta)
08471 {
08472 struct iax2_registry *reg;
08473
08474 if (!(reg = ast_calloc(1, sizeof(*reg))))
08475 return -1;
08476
08477 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08478 ast_free(reg);
08479 return -1;
08480 }
08481
08482 ast_copy_string(reg->username, username, sizeof(reg->username));
08483
08484 if (secret)
08485 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08486
08487 reg->expire = -1;
08488 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08489 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08490
08491 AST_LIST_LOCK(®istrations);
08492 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08493 AST_LIST_UNLOCK(®istrations);
08494
08495 return 0;
08496 }
08497
08498 static int iax2_register(const char *value, int lineno)
08499 {
08500 char copy[256];
08501 char *username, *hostname, *secret;
08502 char *porta;
08503 char *stringp=NULL;
08504
08505 if (!value)
08506 return -1;
08507
08508 ast_copy_string(copy, value, sizeof(copy));
08509 stringp = copy;
08510 username = strsep(&stringp, "@");
08511 hostname = strsep(&stringp, "@");
08512
08513 if (!hostname) {
08514 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08515 return -1;
08516 }
08517
08518 stringp = username;
08519 username = strsep(&stringp, ":");
08520 secret = strsep(&stringp, ":");
08521 stringp = hostname;
08522 hostname = strsep(&stringp, ":");
08523 porta = strsep(&stringp, ":");
08524
08525 if (porta && !atoi(porta)) {
08526 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08527 return -1;
08528 }
08529
08530 return iax2_append_register(hostname, username, secret, porta);
08531 }
08532
08533
08534 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08535 {
08536 char multi[256];
08537 char *stringp, *ext;
08538 if (!ast_strlen_zero(regcontext)) {
08539 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08540 stringp = multi;
08541 while((ext = strsep(&stringp, "&"))) {
08542 if (onoff) {
08543 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08544 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08545 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08546 } else
08547 ast_context_remove_extension(regcontext, ext, 1, NULL);
08548 }
08549 }
08550 }
08551 static void prune_peers(void);
08552
08553 static void unlink_peer(struct iax2_peer *peer)
08554 {
08555 if (peer->expire > -1) {
08556 if (!ast_sched_thread_del(sched, peer->expire)) {
08557 peer->expire = -1;
08558 peer_unref(peer);
08559 }
08560 }
08561
08562 if (peer->pokeexpire > -1) {
08563 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08564 peer->pokeexpire = -1;
08565 peer_unref(peer);
08566 }
08567 }
08568
08569 ao2_unlink(peers, peer);
08570 }
08571
08572 static void __expire_registry(const void *data)
08573 {
08574 struct iax2_peer *peer = (struct iax2_peer *) data;
08575
08576 if (!peer)
08577 return;
08578
08579 peer->expire = -1;
08580
08581 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08582 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08583 realtime_update_peer(peer->name, &peer->addr, 0);
08584 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08585
08586 peercnt_modify(0, 0, &peer->addr);
08587
08588 memset(&peer->addr, 0, sizeof(peer->addr));
08589
08590 peer->expiry = min_reg_expire;
08591 if (!ast_test_flag64(peer, IAX_TEMPONLY))
08592 ast_db_del("IAX/Registry", peer->name);
08593 register_peer_exten(peer, 0);
08594 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08595 if (iax2_regfunk)
08596 iax2_regfunk(peer->name, 0);
08597
08598 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08599 unlink_peer(peer);
08600
08601 peer_unref(peer);
08602 }
08603
08604 static int expire_registry(const void *data)
08605 {
08606 #ifdef SCHED_MULTITHREADED
08607 if (schedule_action(__expire_registry, data))
08608 #endif
08609 __expire_registry(data);
08610 return 0;
08611 }
08612
08613 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08614
08615 static void reg_source_db(struct iax2_peer *p)
08616 {
08617 char data[80];
08618 char *expiry;
08619
08620 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08621 return;
08622 }
08623
08624 expiry = strrchr(data, ':');
08625 if (!expiry) {
08626 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08627 }
08628 *expiry++ = '\0';
08629
08630 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08631 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08632 return;
08633 }
08634
08635 p->expiry = atoi(expiry);
08636
08637 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08638 ast_sockaddr_stringify(&p->addr), p->expiry);
08639
08640 iax2_poke_peer(p, 0);
08641 if (p->expire > -1) {
08642 if (!ast_sched_thread_del(sched, p->expire)) {
08643 p->expire = -1;
08644 peer_unref(p);
08645 }
08646 }
08647
08648 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08649
08650 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08651 if (p->expire == -1) {
08652 peer_unref(p);
08653 }
08654
08655 if (iax2_regfunk) {
08656 iax2_regfunk(p->name, 1);
08657 }
08658
08659 register_peer_exten(p, 1);
08660 }
08661
08662
08663
08664
08665
08666
08667
08668 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08669 {
08670
08671 struct iax_ie_data ied = {
08672 .pos = 0,
08673 };
08674 struct iax2_peer *p;
08675 int msgcount;
08676 char data[80];
08677 int version;
08678 const char *peer_name;
08679 int res = -1;
08680 struct ast_sockaddr sockaddr;
08681
08682 ast_sockaddr_from_sin(&sockaddr, sin);
08683
08684 peer_name = ast_strdupa(iaxs[callno]->peer);
08685
08686
08687 ast_mutex_unlock(&iaxsl[callno]);
08688 if (!(p = find_peer(peer_name, 1))) {
08689 ast_mutex_lock(&iaxsl[callno]);
08690 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08691 return -1;
08692 }
08693 ast_mutex_lock(&iaxsl[callno]);
08694 if (!iaxs[callno])
08695 goto return_unref;
08696
08697 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08698 if (sin->sin_addr.s_addr) {
08699 time_t nowtime;
08700 time(&nowtime);
08701 realtime_update_peer(peer_name, &sockaddr, nowtime);
08702 } else {
08703 realtime_update_peer(peer_name, &sockaddr, 0);
08704 }
08705 }
08706
08707 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08708 if (iax2_regfunk) {
08709 iax2_regfunk(p->name, 1);
08710 }
08711
08712
08713 peercnt_modify(0, 0, &p->addr);
08714
08715
08716 ast_sockaddr_from_sin(&p->addr, sin);
08717
08718 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08719 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08720 ast_db_put("IAX/Registry", p->name, data);
08721 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08722 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08723 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08724 register_peer_exten(p, 1);
08725 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08726 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08727 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08728 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08729 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08730 register_peer_exten(p, 0);
08731 ast_db_del("IAX/Registry", p->name);
08732 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08733 }
08734
08735
08736 iax2_poke_peer(p, callno);
08737 }
08738
08739
08740 if (p->maxcallno) {
08741 peercnt_modify(1, p->maxcallno, &p->addr);
08742 }
08743
08744
08745 if (!iaxs[callno]) {
08746 res = -1;
08747 goto return_unref;
08748 }
08749
08750
08751 p->sockfd = fd;
08752
08753 if (p->expire > -1) {
08754 if (!ast_sched_thread_del(sched, p->expire)) {
08755 p->expire = -1;
08756 peer_unref(p);
08757 }
08758 }
08759
08760 if (!refresh)
08761 refresh = min_reg_expire;
08762 if (refresh > max_reg_expire) {
08763 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08764 p->name, max_reg_expire, refresh);
08765 p->expiry = max_reg_expire;
08766 } else if (refresh < min_reg_expire) {
08767 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08768 p->name, min_reg_expire, refresh);
08769 p->expiry = min_reg_expire;
08770 } else {
08771 p->expiry = refresh;
08772 }
08773 if (p->expiry && sin->sin_addr.s_addr) {
08774 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08775 if (p->expire == -1)
08776 peer_unref(p);
08777 }
08778 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08779 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08780 if (sin->sin_addr.s_addr) {
08781 struct sockaddr_in peer_addr;
08782
08783 ast_sockaddr_to_sin(&p->addr, &peer_addr);
08784
08785 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08786 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08787 if (!ast_strlen_zero(p->mailbox)) {
08788 struct ast_event *event;
08789 int new, old;
08790 char *mailbox, *context;
08791
08792 context = mailbox = ast_strdupa(p->mailbox);
08793 strsep(&context, "@");
08794 if (ast_strlen_zero(context))
08795 context = "default";
08796
08797 event = ast_event_get_cached(AST_EVENT_MWI,
08798 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08799 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08800 AST_EVENT_IE_END);
08801 if (event) {
08802 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08803 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08804 ast_event_destroy(event);
08805 } else {
08806 ast_app_inboxcount(p->mailbox, &new, &old);
08807 }
08808
08809 if (new > 255) {
08810 new = 255;
08811 }
08812 if (old > 255) {
08813 old = 255;
08814 }
08815 msgcount = (old << 8) | new;
08816
08817 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08818 }
08819 if (ast_test_flag64(p, IAX_HASCALLERID)) {
08820 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08821 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08822 }
08823 }
08824 version = iax_check_version(devtype);
08825 if (version)
08826 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08827
08828 res = 0;
08829
08830 return_unref:
08831 peer_unref(p);
08832
08833 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08834 }
08835
08836 static int registry_authrequest(int callno)
08837 {
08838 struct iax_ie_data ied;
08839 struct iax2_peer *p;
08840 char challenge[10];
08841 const char *peer_name;
08842 int sentauthmethod;
08843
08844 peer_name = ast_strdupa(iaxs[callno]->peer);
08845
08846
08847 ast_mutex_unlock(&iaxsl[callno]);
08848 if ((p = find_peer(peer_name, 1))) {
08849 last_authmethod = p->authmethods;
08850 }
08851
08852 ast_mutex_lock(&iaxsl[callno]);
08853 if (!iaxs[callno])
08854 goto return_unref;
08855
08856 memset(&ied, 0, sizeof(ied));
08857
08858
08859
08860
08861
08862
08863 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08864 if (!p) {
08865 iaxs[callno]->authmethods = sentauthmethod;
08866 }
08867 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08868 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08869
08870 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08871 ast_string_field_set(iaxs[callno], challenge, challenge);
08872 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08873 }
08874 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08875
08876 return_unref:
08877 if (p) {
08878 peer_unref(p);
08879 }
08880
08881 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08882 }
08883
08884 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08885 {
08886 struct iax2_registry *reg;
08887
08888 struct iax_ie_data ied;
08889 char peer[256] = "";
08890 char challenge[256] = "";
08891 int res;
08892 int authmethods = 0;
08893 if (ies->authmethods)
08894 authmethods = ies->authmethods;
08895 if (ies->username)
08896 ast_copy_string(peer, ies->username, sizeof(peer));
08897 if (ies->challenge)
08898 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08899 memset(&ied, 0, sizeof(ied));
08900 reg = iaxs[callno]->reg;
08901 if (reg) {
08902 struct sockaddr_in reg_addr;
08903
08904 ast_sockaddr_to_sin(®->addr, ®_addr);
08905
08906 if (inaddrcmp(®_addr, sin)) {
08907 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08908 return -1;
08909 }
08910 if (ast_strlen_zero(reg->secret)) {
08911 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08912 reg->regstate = REG_STATE_NOAUTH;
08913 return -1;
08914 }
08915 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08916 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08917 if (reg->secret[0] == '[') {
08918 char tmpkey[256];
08919 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08920 tmpkey[strlen(tmpkey) - 1] = '\0';
08921 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08922 } else
08923 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08924 if (!res) {
08925 reg->regstate = REG_STATE_AUTHSENT;
08926 add_empty_calltoken_ie(iaxs[callno], &ied);
08927 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08928 } else
08929 return -1;
08930 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08931 } else
08932 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08933 return -1;
08934 }
08935
08936 static void stop_stuff(int callno)
08937 {
08938 iax2_destroy_helper(iaxs[callno]);
08939 }
08940
08941 static void __auth_reject(const void *nothing)
08942 {
08943
08944 int callno = (int)(long)(nothing);
08945 struct iax_ie_data ied;
08946 ast_mutex_lock(&iaxsl[callno]);
08947 if (iaxs[callno]) {
08948 memset(&ied, 0, sizeof(ied));
08949 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08950 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08951 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08952 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08953 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08954 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08955 }
08956 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08957 }
08958 ast_mutex_unlock(&iaxsl[callno]);
08959 }
08960
08961 static int auth_reject(const void *data)
08962 {
08963 int callno = (int)(long)(data);
08964 ast_mutex_lock(&iaxsl[callno]);
08965 if (iaxs[callno])
08966 iaxs[callno]->authid = -1;
08967 ast_mutex_unlock(&iaxsl[callno]);
08968 #ifdef SCHED_MULTITHREADED
08969 if (schedule_action(__auth_reject, data))
08970 #endif
08971 __auth_reject(data);
08972 return 0;
08973 }
08974
08975 static int auth_fail(int callno, int failcode)
08976 {
08977
08978
08979 if (iaxs[callno]) {
08980 iaxs[callno]->authfail = failcode;
08981 if (delayreject) {
08982 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08983 sched, 1000, auth_reject, (void *)(long)callno);
08984 } else
08985 auth_reject((void *)(long)callno);
08986 }
08987 return 0;
08988 }
08989
08990 static void __auto_hangup(const void *nothing)
08991 {
08992
08993 int callno = (int)(long)(nothing);
08994 struct iax_ie_data ied;
08995 ast_mutex_lock(&iaxsl[callno]);
08996 if (iaxs[callno]) {
08997 memset(&ied, 0, sizeof(ied));
08998 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
08999 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09000 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09001 }
09002 ast_mutex_unlock(&iaxsl[callno]);
09003 }
09004
09005 static int auto_hangup(const void *data)
09006 {
09007 int callno = (int)(long)(data);
09008 ast_mutex_lock(&iaxsl[callno]);
09009 if (iaxs[callno]) {
09010 iaxs[callno]->autoid = -1;
09011 }
09012 ast_mutex_unlock(&iaxsl[callno]);
09013 #ifdef SCHED_MULTITHREADED
09014 if (schedule_action(__auto_hangup, data))
09015 #endif
09016 __auto_hangup(data);
09017 return 0;
09018 }
09019
09020 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
09021 {
09022 struct iax_ie_data ied;
09023
09024 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
09025 sched, 30000, auto_hangup, (void *)(long)callno);
09026 memset(&ied, 0, sizeof(ied));
09027 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09028 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09029 dp->flags |= CACHE_FLAG_TRANSMITTED;
09030 }
09031
09032 static int iax2_vnak(int callno)
09033 {
09034 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09035 }
09036
09037 static void vnak_retransmit(int callno, int last)
09038 {
09039 struct iax_frame *f;
09040
09041 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09042
09043 if (((unsigned char) (f->oseqno - last) < 128) &&
09044 (f->retries >= 0)) {
09045 send_packet(f);
09046 }
09047 }
09048 }
09049
09050 static void __iax2_poke_peer_s(const void *data)
09051 {
09052 struct iax2_peer *peer = (struct iax2_peer *)data;
09053 iax2_poke_peer(peer, 0);
09054 peer_unref(peer);
09055 }
09056
09057 static int iax2_poke_peer_s(const void *data)
09058 {
09059 struct iax2_peer *peer = (struct iax2_peer *)data;
09060 peer->pokeexpire = -1;
09061 #ifdef SCHED_MULTITHREADED
09062 if (schedule_action(__iax2_poke_peer_s, data))
09063 #endif
09064 __iax2_poke_peer_s(data);
09065 return 0;
09066 }
09067
09068 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
09069 {
09070 int res = 0;
09071 struct iax_frame *fr;
09072 struct ast_iax2_meta_hdr *meta;
09073 struct ast_iax2_meta_trunk_hdr *mth;
09074 int calls = 0;
09075
09076
09077 fr = (struct iax_frame *)tpeer->trunkdata;
09078
09079 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09080 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09081 if (tpeer->trunkdatalen) {
09082
09083 meta->zeros = 0;
09084 meta->metacmd = IAX_META_TRUNK;
09085 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09086 meta->cmddata = IAX_META_TRUNK_MINI;
09087 else
09088 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09089 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09090
09091 fr->direction = DIRECTION_OUTGRESS;
09092 fr->retrans = -1;
09093 fr->transfer = 0;
09094
09095 fr->data = fr->afdata;
09096 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09097 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09098 calls = tpeer->calls;
09099 #if 0
09100 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));
09101 #endif
09102
09103 tpeer->trunkdatalen = 0;
09104 tpeer->calls = 0;
09105 }
09106 if (res < 0)
09107 return res;
09108 return calls;
09109 }
09110
09111 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
09112 {
09113
09114 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
09115 return 1;
09116 return 0;
09117 }
09118
09119 static int timing_read(int *id, int fd, short events, void *cbdata)
09120 {
09121 int res, processed = 0, totalcalls = 0;
09122 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09123 struct timeval now = ast_tvnow();
09124
09125 if (iaxtrunkdebug)
09126 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09127
09128 if (timer) {
09129 ast_timer_ack(timer, 1);
09130 }
09131
09132
09133 AST_LIST_LOCK(&tpeers);
09134 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09135 processed++;
09136 res = 0;
09137 ast_mutex_lock(&tpeer->lock);
09138
09139
09140 if (!drop && iax2_trunk_expired(tpeer, &now)) {
09141
09142
09143 AST_LIST_REMOVE_CURRENT(list);
09144 drop = tpeer;
09145 } else {
09146 res = send_trunk(tpeer, &now);
09147 trunk_timed++;
09148 if (iaxtrunkdebug)
09149 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);
09150 }
09151 totalcalls += res;
09152 res = 0;
09153 ast_mutex_unlock(&tpeer->lock);
09154 }
09155 AST_LIST_TRAVERSE_SAFE_END;
09156 AST_LIST_UNLOCK(&tpeers);
09157
09158 if (drop) {
09159 ast_mutex_lock(&drop->lock);
09160
09161
09162 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09163 if (drop->trunkdata) {
09164 ast_free(drop->trunkdata);
09165 drop->trunkdata = NULL;
09166 }
09167 ast_mutex_unlock(&drop->lock);
09168 ast_mutex_destroy(&drop->lock);
09169 ast_free(drop);
09170
09171 }
09172
09173 if (iaxtrunkdebug)
09174 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09175 iaxtrunkdebug = 0;
09176
09177 return 1;
09178 }
09179
09180 struct dpreq_data {
09181 int callno;
09182 char context[AST_MAX_EXTENSION];
09183 char callednum[AST_MAX_EXTENSION];
09184 char *callerid;
09185 };
09186
09187 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
09188 {
09189 unsigned short dpstatus = 0;
09190 struct iax_ie_data ied1;
09191 int mm;
09192
09193 memset(&ied1, 0, sizeof(ied1));
09194 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09195
09196 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09197 dpstatus = IAX_DPSTATUS_EXISTS;
09198 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09199 dpstatus = IAX_DPSTATUS_CANEXIST;
09200 } else {
09201 dpstatus = IAX_DPSTATUS_NONEXISTENT;
09202 }
09203 if (ast_ignore_pattern(context, callednum))
09204 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09205 if (mm)
09206 dpstatus |= IAX_DPSTATUS_MATCHMORE;
09207 if (!skiplock)
09208 ast_mutex_lock(&iaxsl[callno]);
09209 if (iaxs[callno]) {
09210 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09211 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09212 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09213 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09214 }
09215 if (!skiplock)
09216 ast_mutex_unlock(&iaxsl[callno]);
09217 }
09218
09219 static void *dp_lookup_thread(void *data)
09220 {
09221
09222 struct dpreq_data *dpr = data;
09223 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09224 if (dpr->callerid)
09225 ast_free(dpr->callerid);
09226 ast_free(dpr);
09227 return NULL;
09228 }
09229
09230 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
09231 {
09232 pthread_t newthread;
09233 struct dpreq_data *dpr;
09234
09235 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09236 return;
09237
09238 dpr->callno = callno;
09239 ast_copy_string(dpr->context, context, sizeof(dpr->context));
09240 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09241 if (callerid)
09242 dpr->callerid = ast_strdup(callerid);
09243 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09244 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09245 }
09246 }
09247
09248 struct iax_dual {
09249 struct ast_channel *chan1;
09250 struct ast_channel *chan2;
09251 const char *parkexten;
09252 };
09253
09254 static void *iax_park_thread(void *stuff)
09255 {
09256 struct ast_channel *chan1, *chan2;
09257 struct iax_dual *d;
09258 struct ast_frame *f;
09259 int ext;
09260 int res;
09261 d = stuff;
09262 chan1 = d->chan1;
09263 chan2 = d->chan2;
09264 ast_free(d);
09265 f = ast_read(chan1);
09266 if (f)
09267 ast_frfree(f);
09268 res = ast_park_call(chan1, chan2, 0, d->parkexten, &ext);
09269 ast_hangup(chan2);
09270 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09271 return NULL;
09272 }
09273
09274 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *parkexten)
09275 {
09276 struct iax_dual *d;
09277 struct ast_channel *chan1m, *chan2m;
09278 pthread_t th;
09279 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09280 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09281 if (chan2m && chan1m) {
09282
09283 chan1m->readformat = chan1->readformat;
09284 chan1m->writeformat = chan1->writeformat;
09285 ast_channel_masquerade(chan1m, chan1);
09286
09287 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09288 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09289 chan1m->priority = chan1->priority;
09290
09291
09292
09293
09294 chan2m->readformat = chan2->readformat;
09295 chan2m->writeformat = chan2->writeformat;
09296 ast_channel_masquerade(chan2m, chan2);
09297
09298 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09299 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09300 chan2m->priority = chan2->priority;
09301 if (ast_do_masquerade(chan2m)) {
09302 ast_log(LOG_WARNING, "Masquerade failed :(\n");
09303 ast_hangup(chan2m);
09304 return -1;
09305 }
09306 } else {
09307 if (chan1m)
09308 ast_hangup(chan1m);
09309 if (chan2m)
09310 ast_hangup(chan2m);
09311 return -1;
09312 }
09313 if ((d = ast_calloc(1, sizeof(*d)))) {
09314 d->chan1 = chan1m;
09315 d->chan2 = chan2m;
09316 d->parkexten = parkexten;
09317 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
09318 return 0;
09319 }
09320 ast_free(d);
09321 }
09322 return -1;
09323 }
09324
09325 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09326 {
09327 unsigned int ourver;
09328 char rsi[80];
09329 snprintf(rsi, sizeof(rsi), "si-%s", si);
09330 if (iax_provision_version(&ourver, rsi, 1))
09331 return 0;
09332 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09333 if (ourver != ver)
09334 iax2_provision(sin, sockfd, NULL, rsi, 1);
09335 return 0;
09336 }
09337
09338 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09339 {
09340 jb_info stats;
09341 jb_getinfo(pvt->jb, &stats);
09342
09343 memset(iep, 0, sizeof(*iep));
09344
09345 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09346 if(stats.frames_in == 0) stats.frames_in = 1;
09347 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09348 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09349 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09350 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09351 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09352 }
09353
09354 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09355 {
09356 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09357 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09358 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09359 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09360 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09361 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09362 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09363 }
09364
09365 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09366 {
09367 int i;
09368 unsigned int length, offset = 0;
09369 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09370
09371 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09372 length = ies->ospblocklength[i];
09373 if (length != 0) {
09374 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09375
09376 offset = 0;
09377 break;
09378 } else {
09379 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09380 offset += length;
09381 }
09382 } else {
09383 break;
09384 }
09385 }
09386 *(full_osptoken + offset) = '\0';
09387 if (strlen(full_osptoken) != offset) {
09388
09389 *full_osptoken = '\0';
09390 }
09391
09392 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09393 }
09394
09395 static void log_jitterstats(unsigned short callno)
09396 {
09397 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09398 jb_info jbinfo;
09399
09400 ast_mutex_lock(&iaxsl[callno]);
09401 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09402 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09403 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09404 localjitter = jbinfo.jitter;
09405 localdelay = jbinfo.current - jbinfo.min;
09406 locallost = jbinfo.frames_lost;
09407 locallosspct = jbinfo.losspct/1000;
09408 localdropped = jbinfo.frames_dropped;
09409 localooo = jbinfo.frames_ooo;
09410 localpackets = jbinfo.frames_in;
09411 }
09412 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",
09413 iaxs[callno]->owner->name,
09414 iaxs[callno]->pingtime,
09415 localjitter,
09416 localdelay,
09417 locallost,
09418 locallosspct,
09419 localdropped,
09420 localooo,
09421 localpackets,
09422 iaxs[callno]->remote_rr.jitter,
09423 iaxs[callno]->remote_rr.delay,
09424 iaxs[callno]->remote_rr.losscnt,
09425 iaxs[callno]->remote_rr.losspct/1000,
09426 iaxs[callno]->remote_rr.dropped,
09427 iaxs[callno]->remote_rr.ooo,
09428 iaxs[callno]->remote_rr.packets);
09429 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",
09430 iaxs[callno]->owner->name,
09431 iaxs[callno]->pingtime,
09432 localjitter,
09433 localdelay,
09434 locallost,
09435 locallosspct,
09436 localdropped,
09437 localooo,
09438 localpackets,
09439 iaxs[callno]->remote_rr.jitter,
09440 iaxs[callno]->remote_rr.delay,
09441 iaxs[callno]->remote_rr.losscnt,
09442 iaxs[callno]->remote_rr.losspct/1000,
09443 iaxs[callno]->remote_rr.dropped,
09444 iaxs[callno]->remote_rr.ooo,
09445 iaxs[callno]->remote_rr.packets);
09446 }
09447 ast_mutex_unlock(&iaxsl[callno]);
09448 }
09449
09450 static int socket_process(struct iax2_thread *thread);
09451
09452
09453
09454
09455 static void handle_deferred_full_frames(struct iax2_thread *thread)
09456 {
09457 struct iax2_pkt_buf *pkt_buf;
09458
09459 ast_mutex_lock(&thread->lock);
09460
09461 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09462 ast_mutex_unlock(&thread->lock);
09463
09464 thread->buf = pkt_buf->buf;
09465 thread->buf_len = pkt_buf->len;
09466 thread->buf_size = pkt_buf->len + 1;
09467
09468 socket_process(thread);
09469
09470 thread->buf = NULL;
09471 ast_free(pkt_buf);
09472
09473 ast_mutex_lock(&thread->lock);
09474 }
09475
09476 ast_mutex_unlock(&thread->lock);
09477 }
09478
09479
09480
09481
09482
09483
09484
09485 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09486 {
09487 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09488 struct ast_iax2_full_hdr *fh, *cur_fh;
09489
09490 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09491 return;
09492
09493 pkt_buf->len = from_here->buf_len;
09494 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09495
09496 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09497 ast_mutex_lock(&to_here->lock);
09498 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09499 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09500 if (fh->oseqno < cur_fh->oseqno) {
09501 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09502 break;
09503 }
09504 }
09505 AST_LIST_TRAVERSE_SAFE_END
09506
09507 if (!cur_pkt_buf)
09508 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09509
09510 ast_mutex_unlock(&to_here->lock);
09511 }
09512
09513 static int socket_read(int *id, int fd, short events, void *cbdata)
09514 {
09515 struct iax2_thread *thread;
09516 socklen_t len;
09517 time_t t;
09518 static time_t last_errtime = 0;
09519 struct ast_iax2_full_hdr *fh;
09520
09521 if (!(thread = find_idle_thread())) {
09522 time(&t);
09523 if (t != last_errtime)
09524 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09525 last_errtime = t;
09526 usleep(1);
09527 return 1;
09528 }
09529
09530 len = sizeof(thread->iosin);
09531 thread->iofd = fd;
09532 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09533 thread->buf_size = sizeof(thread->readbuf);
09534 thread->buf = thread->readbuf;
09535 if (thread->buf_len < 0) {
09536 if (errno != ECONNREFUSED && errno != EAGAIN)
09537 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09538 handle_error();
09539 thread->iostate = IAX_IOSTATE_IDLE;
09540 signal_condition(&thread->lock, &thread->cond);
09541 return 1;
09542 }
09543 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09544 thread->iostate = IAX_IOSTATE_IDLE;
09545 signal_condition(&thread->lock, &thread->cond);
09546 return 1;
09547 }
09548
09549
09550
09551
09552 fh = (struct ast_iax2_full_hdr *) thread->buf;
09553 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09554 struct iax2_thread *cur = NULL;
09555 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09556
09557 AST_LIST_LOCK(&active_list);
09558 AST_LIST_TRAVERSE(&active_list, cur, list) {
09559 if ((cur->ffinfo.callno == callno) &&
09560 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09561 break;
09562 }
09563 if (cur) {
09564
09565
09566 defer_full_frame(thread, cur);
09567 AST_LIST_UNLOCK(&active_list);
09568 thread->iostate = IAX_IOSTATE_IDLE;
09569 signal_condition(&thread->lock, &thread->cond);
09570 return 1;
09571 } else {
09572
09573 thread->ffinfo.callno = callno;
09574 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09575 thread->ffinfo.type = fh->type;
09576 thread->ffinfo.csub = fh->csub;
09577 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09578 }
09579 AST_LIST_UNLOCK(&active_list);
09580 }
09581
09582
09583 thread->iostate = IAX_IOSTATE_READY;
09584 #ifdef DEBUG_SCHED_MULTITHREAD
09585 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09586 #endif
09587 signal_condition(&thread->lock, &thread->cond);
09588
09589 return 1;
09590 }
09591
09592 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09593 struct iax_frame *fr)
09594 {
09595 unsigned char metatype;
09596 struct ast_iax2_meta_trunk_mini *mtm;
09597 struct ast_iax2_meta_trunk_hdr *mth;
09598 struct ast_iax2_meta_trunk_entry *mte;
09599 struct iax2_trunk_peer *tpeer;
09600 unsigned int ts;
09601 void *ptr;
09602 struct timeval rxtrunktime;
09603 struct ast_frame f = { 0, };
09604
09605 if (packet_len < sizeof(*meta)) {
09606 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09607 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09608 return 1;
09609 }
09610
09611 if (meta->metacmd != IAX_META_TRUNK)
09612 return 1;
09613
09614 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09615 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09616 (int) (sizeof(*meta) + sizeof(*mth)));
09617 return 1;
09618 }
09619 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09620 ts = ntohl(mth->ts);
09621 metatype = meta->cmddata;
09622 packet_len -= (sizeof(*meta) + sizeof(*mth));
09623 ptr = mth->data;
09624 tpeer = find_tpeer(sin, sockfd);
09625 if (!tpeer) {
09626 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09627 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09628 return 1;
09629 }
09630 tpeer->trunkact = ast_tvnow();
09631 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09632 tpeer->rxtrunktime = tpeer->trunkact;
09633 rxtrunktime = tpeer->rxtrunktime;
09634 ast_mutex_unlock(&tpeer->lock);
09635 while (packet_len >= sizeof(*mte)) {
09636
09637 unsigned short callno, trunked_ts, len;
09638
09639 if (metatype == IAX_META_TRUNK_MINI) {
09640 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09641 ptr += sizeof(*mtm);
09642 packet_len -= sizeof(*mtm);
09643 len = ntohs(mtm->len);
09644 callno = ntohs(mtm->mini.callno);
09645 trunked_ts = ntohs(mtm->mini.ts);
09646 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09647 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09648 ptr += sizeof(*mte);
09649 packet_len -= sizeof(*mte);
09650 len = ntohs(mte->len);
09651 callno = ntohs(mte->callno);
09652 trunked_ts = 0;
09653 } else {
09654 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09655 break;
09656 }
09657
09658 if (len > packet_len)
09659 break;
09660 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09661 if (!fr->callno)
09662 continue;
09663
09664
09665
09666
09667 memset(&f, 0, sizeof(f));
09668 f.frametype = AST_FRAME_VOICE;
09669 if (!iaxs[fr->callno]) {
09670
09671 } else if (iaxs[fr->callno]->voiceformat == 0) {
09672 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09673 iax2_vnak(fr->callno);
09674 } else {
09675 f.subclass.codec = iaxs[fr->callno]->voiceformat;
09676 f.datalen = len;
09677 if (f.datalen >= 0) {
09678 if (f.datalen)
09679 f.data.ptr = ptr;
09680 else
09681 f.data.ptr = NULL;
09682 if (trunked_ts)
09683 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09684 else
09685 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09686
09687 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09688 struct iax_frame *duped_fr;
09689
09690
09691 f.src = "IAX2";
09692 f.mallocd = 0;
09693 f.offset = 0;
09694 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09695 f.samples = ast_codec_get_samples(&f);
09696 else
09697 f.samples = 0;
09698 fr->outoforder = 0;
09699 iax_frame_wrap(fr, &f);
09700 duped_fr = iaxfrdup2(fr);
09701 if (duped_fr)
09702 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09703 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09704 iaxs[fr->callno]->last = fr->ts;
09705 }
09706 } else {
09707 ast_log(LOG_WARNING, "Datalen < 0?\n");
09708 }
09709 }
09710 ast_mutex_unlock(&iaxsl[fr->callno]);
09711 ptr += len;
09712 packet_len -= len;
09713 }
09714
09715 return 1;
09716 }
09717
09718 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09719 {
09720 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09721 AST_LIST_HEAD(, ast_var_t) *varlist;
09722 struct ast_var_t *var;
09723
09724 if (!variablestore) {
09725 *buf = '\0';
09726 return 0;
09727 }
09728 varlist = variablestore->data;
09729
09730 AST_LIST_LOCK(varlist);
09731 AST_LIST_TRAVERSE(varlist, var, entries) {
09732 if (strcmp(var->name, data) == 0) {
09733 ast_copy_string(buf, var->value, len);
09734 break;
09735 }
09736 }
09737 AST_LIST_UNLOCK(varlist);
09738 return 0;
09739 }
09740
09741 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09742 {
09743 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09744 AST_LIST_HEAD(, ast_var_t) *varlist;
09745 struct ast_var_t *var;
09746
09747 if (!variablestore) {
09748 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09749 if (!variablestore) {
09750 ast_log(LOG_ERROR, "Memory allocation error\n");
09751 return -1;
09752 }
09753 varlist = ast_calloc(1, sizeof(*varlist));
09754 if (!varlist) {
09755 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09756 return -1;
09757 }
09758
09759 AST_LIST_HEAD_INIT(varlist);
09760 variablestore->data = varlist;
09761 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09762 ast_channel_datastore_add(chan, variablestore);
09763 } else
09764 varlist = variablestore->data;
09765
09766 AST_LIST_LOCK(varlist);
09767 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09768 if (strcmp(var->name, data) == 0) {
09769 AST_LIST_REMOVE_CURRENT(entries);
09770 ast_var_delete(var);
09771 break;
09772 }
09773 }
09774 AST_LIST_TRAVERSE_SAFE_END;
09775 var = ast_var_assign(data, value);
09776 if (var)
09777 AST_LIST_INSERT_TAIL(varlist, var, entries);
09778 else
09779 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09780 AST_LIST_UNLOCK(varlist);
09781 return 0;
09782 }
09783
09784 static struct ast_custom_function iaxvar_function = {
09785 .name = "IAXVAR",
09786 .read = acf_iaxvar_read,
09787 .write = acf_iaxvar_write,
09788 };
09789
09790 static void set_hangup_source_and_cause(int callno, unsigned char causecode)
09791 {
09792 iax2_lock_owner(callno);
09793 if (iaxs[callno] && iaxs[callno]->owner) {
09794 if (causecode) {
09795 iaxs[callno]->owner->hangupcause = causecode;
09796 }
09797 ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
09798 ast_channel_unlock(iaxs[callno]->owner);
09799 }
09800 }
09801
09802 static int socket_process(struct iax2_thread *thread)
09803 {
09804 struct sockaddr_in sin;
09805 int res;
09806 int updatehistory=1;
09807 int new = NEW_PREVENT;
09808 int dcallno = 0;
09809 char decrypted = 0;
09810 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09811 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09812 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09813 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09814 struct iax_frame *fr;
09815 struct iax_frame *cur;
09816 struct ast_frame f = { 0, };
09817 struct ast_channel *c = NULL;
09818 struct iax2_dpcache *dp;
09819 struct iax2_peer *peer;
09820 struct iax_ies ies;
09821 struct iax_ie_data ied0, ied1;
09822 format_t format;
09823 int fd;
09824 int exists;
09825 int minivid = 0;
09826 char empty[32]="";
09827 struct iax_frame *duped_fr;
09828 char host_pref_buf[128];
09829 char caller_pref_buf[128];
09830 struct ast_codec_pref pref;
09831 char *using_prefs = "mine";
09832
09833
09834 fr = alloca(sizeof(*fr) + 4096);
09835 memset(fr, 0, sizeof(*fr));
09836 fr->afdatalen = 4096;
09837
09838
09839 res = thread->buf_len;
09840 fd = thread->iofd;
09841 memcpy(&sin, &thread->iosin, sizeof(sin));
09842
09843 if (res < sizeof(*mh)) {
09844 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09845 return 1;
09846 }
09847 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09848 if (res < sizeof(*vh)) {
09849 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));
09850 return 1;
09851 }
09852
09853
09854 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09855 minivid = 1;
09856 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09857 return socket_process_meta(res, meta, &sin, fd, fr);
09858
09859 #ifdef DEBUG_SUPPORT
09860 if (res >= sizeof(*fh))
09861 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09862 #endif
09863 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09864 if (res < sizeof(*fh)) {
09865 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));
09866 return 1;
09867 }
09868
09869
09870 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09871
09872
09873
09874
09875
09876
09877 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09878 ast_mutex_lock(&iaxsl[fr->callno]);
09879 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
09880 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09881 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09882 ast_mutex_unlock(&iaxsl[fr->callno]);
09883 return 1;
09884 }
09885 decrypted = 1;
09886 }
09887 ast_mutex_unlock(&iaxsl[fr->callno]);
09888 }
09889
09890
09891 f.frametype = fh->type;
09892 if (f.frametype == AST_FRAME_VIDEO) {
09893 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09894 } else if (f.frametype == AST_FRAME_VOICE) {
09895 f.subclass.codec = uncompress_subclass(fh->csub);
09896 } else {
09897 f.subclass.integer = uncompress_subclass(fh->csub);
09898 }
09899
09900
09901 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
09902
09903 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09904 return 1;
09905 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
09906
09907 return 1;
09908 }
09909
09910 f.datalen = res - sizeof(*fh);
09911 if (f.datalen) {
09912 if (f.frametype == AST_FRAME_IAX) {
09913 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09914 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09915 ast_variables_destroy(ies.vars);
09916 return 1;
09917 }
09918 f.data.ptr = NULL;
09919 f.datalen = 0;
09920 } else {
09921 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09922 memset(&ies, 0, sizeof(ies));
09923 }
09924 } else {
09925 if (f.frametype == AST_FRAME_IAX)
09926 f.data.ptr = NULL;
09927 else
09928 f.data.ptr = empty;
09929 memset(&ies, 0, sizeof(ies));
09930 }
09931
09932 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
09933
09934 if (handle_call_token(fh, &ies, &sin, fd)) {
09935 ast_variables_destroy(ies.vars);
09936 return 1;
09937 }
09938
09939 if (ies.calltoken && ies.calltokendata) {
09940
09941
09942
09943
09944 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09945 } else {
09946 new = NEW_ALLOW;
09947 }
09948 }
09949 } else {
09950
09951 f.frametype = AST_FRAME_NULL;
09952 f.subclass.integer = 0;
09953 memset(&ies, 0, sizeof(ies));
09954 }
09955
09956 if (!fr->callno) {
09957 int check_dcallno = 0;
09958
09959
09960
09961
09962
09963
09964
09965
09966
09967 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
09968 check_dcallno = 1;
09969 }
09970
09971 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09972 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
09973 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09974 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
09975 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09976 }
09977 ast_variables_destroy(ies.vars);
09978 return 1;
09979 }
09980 }
09981
09982 if (fr->callno > 0)
09983 ast_mutex_lock(&iaxsl[fr->callno]);
09984
09985 if (!fr->callno || !iaxs[fr->callno]) {
09986
09987
09988 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09989
09990 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
09991 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
09992 (f.subclass.integer != IAX_COMMAND_TXACC) &&
09993 (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
09994 (f.frametype != AST_FRAME_IAX))
09995 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09996 fd);
09997 }
09998 if (fr->callno > 0)
09999 ast_mutex_unlock(&iaxsl[fr->callno]);
10000 ast_variables_destroy(ies.vars);
10001 return 1;
10002 }
10003 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10004 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10005 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10006 ast_variables_destroy(ies.vars);
10007 ast_mutex_unlock(&iaxsl[fr->callno]);
10008 return 1;
10009 }
10010 decrypted = 1;
10011 }
10012
10013 #ifdef DEBUG_SUPPORT
10014 if (decrypted) {
10015 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10016 }
10017 #endif
10018
10019
10020
10021 iaxs[fr->callno]->frames_received++;
10022
10023 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10024 f.subclass.integer != IAX_COMMAND_TXCNT &&
10025 f.subclass.integer != IAX_COMMAND_TXACC) {
10026 unsigned short new_peercallno;
10027
10028 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10029 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10030 if (iaxs[fr->callno]->peercallno) {
10031 remove_by_peercallno(iaxs[fr->callno]);
10032 }
10033 iaxs[fr->callno]->peercallno = new_peercallno;
10034 store_by_peercallno(iaxs[fr->callno]);
10035 }
10036 }
10037 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10038 if (iaxdebug)
10039 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10040
10041 fr->oseqno = fh->oseqno;
10042 fr->iseqno = fh->iseqno;
10043 fr->ts = ntohl(fh->ts);
10044 #ifdef IAXTESTS
10045 if (test_resync) {
10046 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10047 fr->ts += test_resync;
10048 }
10049 #endif
10050 #if 0
10051 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10052 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10053 (f.subclass == IAX_COMMAND_NEW ||
10054 f.subclass == IAX_COMMAND_AUTHREQ ||
10055 f.subclass == IAX_COMMAND_ACCEPT ||
10056 f.subclass == IAX_COMMAND_REJECT)) ) )
10057 #endif
10058 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10059 updatehistory = 0;
10060 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10061 (iaxs[fr->callno]->iseqno ||
10062 ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10063 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10064 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10065 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10066 (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10067 (f.frametype != AST_FRAME_IAX))) {
10068 if (
10069 ((f.subclass.integer != IAX_COMMAND_ACK) &&
10070 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10071 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10072 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10073 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10074 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10075 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10076 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10077 (f.frametype != AST_FRAME_IAX)) {
10078
10079 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
10080 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10081
10082
10083 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10084
10085 if ((f.frametype != AST_FRAME_IAX) ||
10086 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10087 ast_debug(1, "Acking anyway\n");
10088
10089
10090 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10091 }
10092 } else {
10093
10094 iax2_vnak(fr->callno);
10095 }
10096 ast_variables_destroy(ies.vars);
10097 ast_mutex_unlock(&iaxsl[fr->callno]);
10098 return 1;
10099 }
10100 } else {
10101
10102 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10103 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10104 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10105 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10106 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10107 (f.frametype != AST_FRAME_IAX))
10108 iaxs[fr->callno]->iseqno++;
10109 }
10110
10111 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10112 if (res < thread->buf_size)
10113 thread->buf[res++] = '\0';
10114 else
10115 thread->buf[res - 1] = '\0';
10116 }
10117
10118
10119
10120 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10121 ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10122 (f.frametype != AST_FRAME_IAX))) {
10123 unsigned char x;
10124 int call_to_destroy;
10125
10126 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10127 x = fr->iseqno;
10128 else
10129 x = iaxs[fr->callno]->oseqno;
10130 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10131
10132
10133 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10134
10135 if (iaxdebug)
10136 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10137 call_to_destroy = 0;
10138 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10139
10140 if (x == cur->oseqno) {
10141 cur->retries = -1;
10142
10143 if (cur->final)
10144 call_to_destroy = fr->callno;
10145 }
10146 }
10147 if (call_to_destroy) {
10148 if (iaxdebug)
10149 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10150 ast_mutex_lock(&iaxsl[call_to_destroy]);
10151 iax2_destroy(call_to_destroy);
10152 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10153 }
10154 }
10155
10156 if (iaxs[fr->callno])
10157 iaxs[fr->callno]->rseqno = fr->iseqno;
10158 else {
10159
10160 ast_variables_destroy(ies.vars);
10161 ast_mutex_unlock(&iaxsl[fr->callno]);
10162 return 1;
10163 }
10164 } else {
10165 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10166 }
10167 }
10168 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10169 ((f.frametype != AST_FRAME_IAX) ||
10170 ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10171 (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10172
10173 ast_variables_destroy(ies.vars);
10174 ast_mutex_unlock(&iaxsl[fr->callno]);
10175 return 1;
10176 }
10177
10178
10179
10180
10181 if ((f.frametype == AST_FRAME_VOICE) ||
10182 (f.frametype == AST_FRAME_VIDEO) ||
10183 (f.frametype == AST_FRAME_IAX)) {
10184 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10185 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10186 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
10187 ast_variables_destroy(ies.vars);
10188 ast_mutex_unlock(&iaxsl[fr->callno]);
10189 return 1;
10190 }
10191 }
10192
10193 if (ies.vars) {
10194 struct ast_datastore *variablestore = NULL;
10195 struct ast_variable *var, *prev = NULL;
10196 AST_LIST_HEAD(, ast_var_t) *varlist;
10197
10198 iax2_lock_owner(fr->callno);
10199 if (!iaxs[fr->callno]) {
10200 ast_variables_destroy(ies.vars);
10201 ast_mutex_unlock(&iaxsl[fr->callno]);
10202 return 1;
10203 }
10204 if ((c = iaxs[fr->callno]->owner)) {
10205 varlist = ast_calloc(1, sizeof(*varlist));
10206 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10207
10208 if (variablestore && varlist) {
10209 variablestore->data = varlist;
10210 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10211 AST_LIST_HEAD_INIT(varlist);
10212 ast_debug(1, "I can haz IAX vars?\n");
10213 for (var = ies.vars; var; var = var->next) {
10214 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10215 if (prev) {
10216 ast_free(prev);
10217 }
10218 prev = var;
10219 if (!newvar) {
10220
10221 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10222 } else {
10223 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10224 }
10225 }
10226 if (prev) {
10227 ast_free(prev);
10228 }
10229 ies.vars = NULL;
10230 ast_channel_datastore_add(c, variablestore);
10231 } else {
10232 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10233 if (variablestore) {
10234 ast_datastore_free(variablestore);
10235 }
10236 if (varlist) {
10237 ast_free(varlist);
10238 }
10239 }
10240 ast_channel_unlock(c);
10241 } else {
10242
10243
10244 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10245 for (var = ies.vars; var && var->next; var = var->next);
10246 if (var) {
10247 var->next = iaxs[fr->callno]->iaxvars;
10248 iaxs[fr->callno]->iaxvars = ies.vars;
10249 ies.vars = NULL;
10250 }
10251 }
10252 }
10253
10254 if (ies.vars) {
10255 ast_debug(1, "I have IAX variables, but they were not processed\n");
10256 }
10257 }
10258
10259
10260
10261 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10262 send_signaling(iaxs[fr->callno]);
10263 }
10264
10265 if (f.frametype == AST_FRAME_VOICE) {
10266 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10267 iaxs[fr->callno]->voiceformat = f.subclass.codec;
10268 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10269 if (iaxs[fr->callno]->owner) {
10270 iax2_lock_owner(fr->callno);
10271 if (iaxs[fr->callno]) {
10272 if (iaxs[fr->callno]->owner) {
10273 format_t orignative;
10274
10275 orignative = iaxs[fr->callno]->owner->nativeformats;
10276 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10277 if (iaxs[fr->callno]->owner->readformat)
10278 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10279 iaxs[fr->callno]->owner->nativeformats = orignative;
10280 ast_channel_unlock(iaxs[fr->callno]->owner);
10281 }
10282 } else {
10283 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10284
10285 if (ies.vars) {
10286 ast_variables_destroy(ies.vars);
10287 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10288 ies.vars = NULL;
10289 }
10290 ast_mutex_unlock(&iaxsl[fr->callno]);
10291 return 1;
10292 }
10293 }
10294 }
10295 }
10296 if (f.frametype == AST_FRAME_VIDEO) {
10297 if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10298 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10299 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10300 }
10301 }
10302 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10303 if (f.subclass.integer == AST_CONTROL_BUSY) {
10304 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10305 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10306 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10307 }
10308 }
10309 if (f.frametype == AST_FRAME_IAX) {
10310 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10311
10312 if (iaxdebug)
10313 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10314
10315
10316 if (iaxs[fr->callno]->last < fr->ts &&
10317 f.subclass.integer != IAX_COMMAND_ACK &&
10318 f.subclass.integer != IAX_COMMAND_PONG &&
10319 f.subclass.integer != IAX_COMMAND_LAGRP) {
10320 iaxs[fr->callno]->last = fr->ts;
10321 if (iaxdebug)
10322 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10323 }
10324 iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10325 if (!iaxs[fr->callno]->first_iax_message) {
10326 iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10327 }
10328 switch(f.subclass.integer) {
10329 case IAX_COMMAND_ACK:
10330
10331 break;
10332 case IAX_COMMAND_QUELCH:
10333 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10334
10335 if (iaxs[fr->callno]->owner) {
10336 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10337 "Status: On\r\n"
10338 "Channel: %s\r\n"
10339 "Uniqueid: %s\r\n",
10340 iaxs[fr->callno]->owner->name,
10341 iaxs[fr->callno]->owner->uniqueid);
10342 }
10343
10344 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10345 if (ies.musiconhold) {
10346 iax2_lock_owner(fr->callno);
10347 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10348 break;
10349 }
10350 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10351 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10352
10353
10354
10355
10356
10357 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10358 S_OR(moh_suggest, NULL),
10359 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10360 }
10361 ast_channel_unlock(iaxs[fr->callno]->owner);
10362 }
10363 }
10364 break;
10365 case IAX_COMMAND_UNQUELCH:
10366 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10367 iax2_lock_owner(fr->callno);
10368 if (!iaxs[fr->callno]) {
10369 break;
10370 }
10371
10372 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10373 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10374 "Status: Off\r\n"
10375 "Channel: %s\r\n"
10376 "Uniqueid: %s\r\n",
10377 iaxs[fr->callno]->owner->name,
10378 iaxs[fr->callno]->owner->uniqueid);
10379 }
10380
10381 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10382 if (!iaxs[fr->callno]->owner) {
10383 break;
10384 }
10385 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10386
10387
10388
10389
10390 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10391 }
10392 ast_channel_unlock(iaxs[fr->callno]->owner);
10393 }
10394 break;
10395 case IAX_COMMAND_TXACC:
10396 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10397
10398 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10399
10400 if (cur->transfer) {
10401 cur->retries = -1;
10402 }
10403 }
10404 memset(&ied1, 0, sizeof(ied1));
10405 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10406 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10407 iaxs[fr->callno]->transferring = TRANSFER_READY;
10408 }
10409 break;
10410 case IAX_COMMAND_NEW:
10411
10412 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10413 break;
10414 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10415 ast_mutex_unlock(&iaxsl[fr->callno]);
10416 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10417 ast_mutex_lock(&iaxsl[fr->callno]);
10418 if (!iaxs[fr->callno]) {
10419 break;
10420 }
10421 }
10422
10423 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10424 int new_callno;
10425 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10426 fr->callno = new_callno;
10427 }
10428
10429 if (delayreject)
10430 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10431 if (check_access(fr->callno, &sin, &ies)) {
10432
10433 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10434 if (authdebug)
10435 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);
10436 break;
10437 }
10438 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10439 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10440 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10441 break;
10442 }
10443 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10444 const char *context, *exten, *cid_num;
10445
10446 context = ast_strdupa(iaxs[fr->callno]->context);
10447 exten = ast_strdupa(iaxs[fr->callno]->exten);
10448 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10449
10450
10451 ast_mutex_unlock(&iaxsl[fr->callno]);
10452 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10453 ast_mutex_lock(&iaxsl[fr->callno]);
10454
10455 if (!iaxs[fr->callno]) {
10456 break;
10457 }
10458 } else
10459 exists = 0;
10460
10461 save_osptoken(fr, &ies);
10462 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10463 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10464 memset(&ied0, 0, sizeof(ied0));
10465 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10466 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10467 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10468 if (!iaxs[fr->callno]) {
10469 break;
10470 }
10471 if (authdebug)
10472 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);
10473 } else {
10474
10475
10476 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10477 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10478 using_prefs = "reqonly";
10479 } else {
10480 using_prefs = "disabled";
10481 }
10482 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10483 memset(&pref, 0, sizeof(pref));
10484 strcpy(caller_pref_buf, "disabled");
10485 strcpy(host_pref_buf, "disabled");
10486 } else {
10487 using_prefs = "mine";
10488
10489 if (ies.codec_prefs)
10490 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10491 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10492
10493 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10494 pref = iaxs[fr->callno]->rprefs;
10495 using_prefs = "caller";
10496 } else {
10497 pref = iaxs[fr->callno]->prefs;
10498 }
10499 } else
10500 pref = iaxs[fr->callno]->prefs;
10501
10502 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10503 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10504 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10505 }
10506 if (!format) {
10507 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10508 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10509 if (!format) {
10510 memset(&ied0, 0, sizeof(ied0));
10511 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10512 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10513 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10514 if (!iaxs[fr->callno]) {
10515 break;
10516 }
10517 if (authdebug) {
10518 char tmp[256], tmp2[256], tmp3[256];
10519 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10520 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10521 ast_inet_ntoa(sin.sin_addr),
10522 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10523 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10524 } else {
10525 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10526 ast_inet_ntoa(sin.sin_addr),
10527 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10528 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10529 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10530 }
10531 }
10532 } else {
10533
10534 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10535 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10536 format = 0;
10537 } else {
10538 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10539 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10540 memset(&pref, 0, sizeof(pref));
10541 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10542 strcpy(caller_pref_buf,"disabled");
10543 strcpy(host_pref_buf,"disabled");
10544 } else {
10545 using_prefs = "mine";
10546 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10547
10548 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10549 pref = iaxs[fr->callno]->prefs;
10550 } else {
10551 pref = iaxs[fr->callno]->rprefs;
10552 using_prefs = "caller";
10553 }
10554 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10555 } else
10556 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10557 }
10558 }
10559
10560 if (!format) {
10561 char tmp[256], tmp2[256], tmp3[256];
10562 memset(&ied0, 0, sizeof(ied0));
10563 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10564 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10565 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10566 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10567 if (!iaxs[fr->callno]) {
10568 break;
10569 }
10570 if (authdebug) {
10571 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10572 ast_inet_ntoa(sin.sin_addr),
10573 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10574 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10575 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10576 }
10577 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10578 break;
10579 }
10580 }
10581 }
10582 if (format) {
10583
10584 memset(&ied1, 0, sizeof(ied1));
10585 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10586 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10587 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10588 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10589 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10590 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10591 "%srequested format = %s,\n"
10592 "%srequested prefs = %s,\n"
10593 "%sactual format = %s,\n"
10594 "%shost prefs = %s,\n"
10595 "%spriority = %s\n",
10596 ast_inet_ntoa(sin.sin_addr),
10597 VERBOSE_PREFIX_4,
10598 ast_getformatname(iaxs[fr->callno]->peerformat),
10599 VERBOSE_PREFIX_4,
10600 caller_pref_buf,
10601 VERBOSE_PREFIX_4,
10602 ast_getformatname(format),
10603 VERBOSE_PREFIX_4,
10604 host_pref_buf,
10605 VERBOSE_PREFIX_4,
10606 using_prefs);
10607
10608 iaxs[fr->callno]->chosenformat = format;
10609 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10610 } else {
10611 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10612
10613 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10614 }
10615 }
10616 }
10617 break;
10618 }
10619 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10620 merge_encryption(iaxs[fr->callno],ies.encmethods);
10621 else
10622 iaxs[fr->callno]->encmethods = 0;
10623 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10624 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10625 break;
10626 case IAX_COMMAND_DPREQ:
10627
10628 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10629 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10630 if (iaxcompat) {
10631
10632 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10633 } else {
10634
10635 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10636 }
10637 }
10638 break;
10639 case IAX_COMMAND_HANGUP:
10640 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10641 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10642
10643 if (iaxs[fr->callno]->owner) {
10644 set_hangup_source_and_cause(fr->callno, ies.causecode);
10645 if (!iaxs[fr->callno]) {
10646 break;
10647 }
10648 }
10649
10650
10651 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10652 iax2_destroy(fr->callno);
10653 break;
10654 case IAX_COMMAND_REJECT:
10655
10656 if (iaxs[fr->callno]->owner) {
10657 set_hangup_source_and_cause(fr->callno, ies.causecode);
10658 if (!iaxs[fr->callno]) {
10659 break;
10660 }
10661 }
10662
10663 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10664 if (iaxs[fr->callno]->owner && authdebug)
10665 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10666 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10667 ies.cause ? ies.cause : "<Unknown>");
10668 ast_debug(1, "Immediately destroying %d, having received reject\n",
10669 fr->callno);
10670 }
10671
10672 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10673 fr->ts, NULL, 0, fr->iseqno);
10674 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10675 iaxs[fr->callno]->error = EPERM;
10676 iax2_destroy(fr->callno);
10677 break;
10678 case IAX_COMMAND_TRANSFER:
10679 {
10680 struct ast_channel *bridged_chan;
10681 struct ast_channel *owner;
10682
10683 iax2_lock_owner(fr->callno);
10684 if (!iaxs[fr->callno]) {
10685
10686 break;
10687 }
10688 owner = iaxs[fr->callno]->owner;
10689 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10690 if (bridged_chan && ies.called_number) {
10691 ast_mutex_unlock(&iaxsl[fr->callno]);
10692
10693
10694 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10695 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10696
10697 if (ast_parking_ext_valid(ies.called_number, c, iaxs[fr->callno]->context)) {
10698 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10699 if (iax_park(bridged_chan, owner, ies.called_number)) {
10700 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10701 bridged_chan->name);
10702 }
10703 ast_mutex_lock(&iaxsl[fr->callno]);
10704 } else {
10705 ast_mutex_lock(&iaxsl[fr->callno]);
10706
10707 if (iaxs[fr->callno]) {
10708 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context,
10709 ies.called_number, 1)) {
10710 ast_log(LOG_WARNING,
10711 "Async goto of '%s' to '%s@%s' failed\n",
10712 bridged_chan->name, ies.called_number,
10713 iaxs[fr->callno]->context);
10714 } else {
10715 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10716 bridged_chan->name, ies.called_number,
10717 iaxs[fr->callno]->context);
10718 }
10719 } else {
10720
10721 }
10722 }
10723 } else {
10724 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10725 }
10726 if (owner) {
10727 ast_channel_unlock(owner);
10728 }
10729
10730 break;
10731 }
10732 case IAX_COMMAND_ACCEPT:
10733
10734 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10735 break;
10736 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10737
10738 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10739 iax2_destroy(fr->callno);
10740 break;
10741 }
10742 if (ies.format) {
10743 iaxs[fr->callno]->peerformat = ies.format;
10744 } else {
10745 if (iaxs[fr->callno]->owner)
10746 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10747 else
10748 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10749 }
10750 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));
10751 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10752 memset(&ied0, 0, sizeof(ied0));
10753 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10754 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10755 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10756 if (!iaxs[fr->callno]) {
10757 break;
10758 }
10759 if (authdebug) {
10760 char tmp1[256], tmp2[256];
10761 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10762 ast_inet_ntoa(sin.sin_addr),
10763 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10764 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10765 }
10766 } else {
10767 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10768 iax2_lock_owner(fr->callno);
10769 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10770
10771 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10772 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10773
10774
10775 if (iaxs[fr->callno]->owner->writeformat)
10776 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10777 if (iaxs[fr->callno]->owner->readformat)
10778 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10779 ast_channel_unlock(iaxs[fr->callno]->owner);
10780 }
10781 }
10782 if (iaxs[fr->callno]) {
10783 AST_LIST_LOCK(&dpcache);
10784 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10785 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10786 iax2_dprequest(dp, fr->callno);
10787 AST_LIST_UNLOCK(&dpcache);
10788 }
10789 break;
10790 case IAX_COMMAND_POKE:
10791
10792 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10793 break;
10794 case IAX_COMMAND_PING:
10795 {
10796 struct iax_ie_data pingied;
10797 construct_rr(iaxs[fr->callno], &pingied);
10798
10799 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10800 }
10801 break;
10802 case IAX_COMMAND_PONG:
10803
10804 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10805
10806 save_rr(fr, &ies);
10807
10808
10809 log_jitterstats(fr->callno);
10810
10811 if (iaxs[fr->callno]->peerpoke) {
10812 peer = iaxs[fr->callno]->peerpoke;
10813 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10814 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10815 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10816 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);
10817 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10818 }
10819 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10820 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10821 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10822 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);
10823 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10824 }
10825 }
10826 peer->lastms = iaxs[fr->callno]->pingtime;
10827 if (peer->smoothing && (peer->lastms > -1))
10828 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10829 else if (peer->smoothing && peer->lastms < 0)
10830 peer->historicms = (0 + peer->historicms) / 2;
10831 else
10832 peer->historicms = iaxs[fr->callno]->pingtime;
10833
10834
10835 if (peer->pokeexpire > -1) {
10836 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10837 peer_unref(peer);
10838 peer->pokeexpire = -1;
10839 }
10840 }
10841
10842 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10843 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10844 else
10845 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10846 if (peer->pokeexpire == -1)
10847 peer_unref(peer);
10848
10849 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10850
10851 iax2_destroy(fr->callno);
10852 peer->callno = 0;
10853 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10854 }
10855 break;
10856 case IAX_COMMAND_LAGRQ:
10857 case IAX_COMMAND_LAGRP:
10858 f.src = "LAGRQ";
10859 f.mallocd = 0;
10860 f.offset = 0;
10861 f.samples = 0;
10862 iax_frame_wrap(fr, &f);
10863 if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
10864
10865 fr->af.subclass.integer = IAX_COMMAND_LAGRP;
10866 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10867 } else {
10868
10869 unsigned int ts;
10870
10871 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10872 iaxs[fr->callno]->lag = ts - fr->ts;
10873 if (iaxdebug)
10874 ast_debug(1, "Peer %s lag measured as %dms\n",
10875 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10876 }
10877 break;
10878 case IAX_COMMAND_AUTHREQ:
10879 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10880 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>");
10881 break;
10882 }
10883 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10884 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10885 .subclass.integer = AST_CONTROL_HANGUP,
10886 };
10887 ast_log(LOG_WARNING,
10888 "I don't know how to authenticate %s to %s\n",
10889 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10890 iax2_queue_frame(fr->callno, &hangup_fr);
10891 }
10892 break;
10893 case IAX_COMMAND_AUTHREP:
10894
10895 if (delayreject)
10896 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10897
10898 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10899 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>");
10900 break;
10901 }
10902 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10903 if (authdebug)
10904 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);
10905 memset(&ied0, 0, sizeof(ied0));
10906 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10907 break;
10908 }
10909 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10910
10911 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10912 } else
10913 exists = 0;
10914 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10915 if (authdebug)
10916 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);
10917 memset(&ied0, 0, sizeof(ied0));
10918 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10919 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10920 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10921 if (!iaxs[fr->callno]) {
10922 break;
10923 }
10924 } else {
10925
10926 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10927 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10928 using_prefs = "reqonly";
10929 } else {
10930 using_prefs = "disabled";
10931 }
10932 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10933 memset(&pref, 0, sizeof(pref));
10934 strcpy(caller_pref_buf, "disabled");
10935 strcpy(host_pref_buf, "disabled");
10936 } else {
10937 using_prefs = "mine";
10938 if (ies.codec_prefs)
10939 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10940 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10941 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10942 pref = iaxs[fr->callno]->rprefs;
10943 using_prefs = "caller";
10944 } else {
10945 pref = iaxs[fr->callno]->prefs;
10946 }
10947 } else
10948 pref = iaxs[fr->callno]->prefs;
10949 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10950 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10951 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10952 }
10953 if (!format) {
10954 char tmp1[256], tmp2[256], tmp3[256];
10955 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10956 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
10957 ast_getformatname(iaxs[fr->callno]->peerformat),
10958 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
10959 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10960 }
10961 if (!format) {
10962 if (authdebug) {
10963 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10964 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
10965 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10966 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10967 } else {
10968 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10969 ast_inet_ntoa(sin.sin_addr),
10970 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10971 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10972 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10973 }
10974 }
10975 memset(&ied0, 0, sizeof(ied0));
10976 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10977 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10978 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10979 if (!iaxs[fr->callno]) {
10980 break;
10981 }
10982 } else {
10983
10984 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10985 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10986 format = 0;
10987 } else {
10988 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10989 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10990 memset(&pref, 0, sizeof(pref));
10991 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10992 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10993 strcpy(caller_pref_buf,"disabled");
10994 strcpy(host_pref_buf,"disabled");
10995 } else {
10996 using_prefs = "mine";
10997 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10998
10999 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11000 pref = iaxs[fr->callno]->prefs;
11001 } else {
11002 pref = iaxs[fr->callno]->rprefs;
11003 using_prefs = "caller";
11004 }
11005 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11006 } else
11007 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11008 }
11009 }
11010 if (!format) {
11011 char tmp1[256], tmp2[256], tmp3[256];
11012 ast_log(LOG_ERROR, "No best format in %s???\n",
11013 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11014 if (authdebug) {
11015 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11016 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11017 ast_inet_ntoa(sin.sin_addr),
11018 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11019 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11020 } else {
11021 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11022 ast_inet_ntoa(sin.sin_addr),
11023 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11024 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11025 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11026 }
11027 }
11028 memset(&ied0, 0, sizeof(ied0));
11029 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11030 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11031 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11032 if (!iaxs[fr->callno]) {
11033 break;
11034 }
11035 }
11036 }
11037 }
11038 if (format) {
11039
11040 memset(&ied1, 0, sizeof(ied1));
11041 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11042 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11043 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11044 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11045 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11046 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11047 "%srequested format = %s,\n"
11048 "%srequested prefs = %s,\n"
11049 "%sactual format = %s,\n"
11050 "%shost prefs = %s,\n"
11051 "%spriority = %s\n",
11052 ast_inet_ntoa(sin.sin_addr),
11053 VERBOSE_PREFIX_4,
11054 ast_getformatname(iaxs[fr->callno]->peerformat),
11055 VERBOSE_PREFIX_4,
11056 caller_pref_buf,
11057 VERBOSE_PREFIX_4,
11058 ast_getformatname(format),
11059 VERBOSE_PREFIX_4,
11060 host_pref_buf,
11061 VERBOSE_PREFIX_4,
11062 using_prefs);
11063
11064 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11065 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
11066 iax2_destroy(fr->callno);
11067 else if (ies.vars) {
11068 struct ast_datastore *variablestore;
11069 struct ast_variable *var, *prev = NULL;
11070 AST_LIST_HEAD(, ast_var_t) *varlist;
11071 varlist = ast_calloc(1, sizeof(*varlist));
11072 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11073 if (variablestore && varlist) {
11074 variablestore->data = varlist;
11075 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11076 AST_LIST_HEAD_INIT(varlist);
11077 ast_debug(1, "I can haz IAX vars? w00t\n");
11078 for (var = ies.vars; var; var = var->next) {
11079 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11080 if (prev)
11081 ast_free(prev);
11082 prev = var;
11083 if (!newvar) {
11084
11085 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11086 } else {
11087 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11088 }
11089 }
11090 if (prev)
11091 ast_free(prev);
11092 ies.vars = NULL;
11093 ast_channel_datastore_add(c, variablestore);
11094 } else {
11095 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11096 if (variablestore)
11097 ast_datastore_free(variablestore);
11098 if (varlist)
11099 ast_free(varlist);
11100 }
11101 }
11102 } else {
11103 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11104
11105 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11106 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11107 goto immediatedial;
11108 }
11109 }
11110 }
11111 }
11112 break;
11113 case IAX_COMMAND_DIAL:
11114 immediatedial:
11115 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11116 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11117 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11118 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11119 if (authdebug)
11120 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);
11121 memset(&ied0, 0, sizeof(ied0));
11122 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11123 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11124 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11125 if (!iaxs[fr->callno]) {
11126 break;
11127 }
11128 } else {
11129 char tmp[256];
11130 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11131 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11132 ast_inet_ntoa(sin.sin_addr),
11133 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11134 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11135 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11136 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
11137 iax2_destroy(fr->callno);
11138 else if (ies.vars) {
11139 struct ast_datastore *variablestore;
11140 struct ast_variable *var, *prev = NULL;
11141 AST_LIST_HEAD(, ast_var_t) *varlist;
11142 varlist = ast_calloc(1, sizeof(*varlist));
11143 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11144 ast_debug(1, "I can haz IAX vars? w00t\n");
11145 if (variablestore && varlist) {
11146 variablestore->data = varlist;
11147 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11148 AST_LIST_HEAD_INIT(varlist);
11149 for (var = ies.vars; var; var = var->next) {
11150 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11151 if (prev)
11152 ast_free(prev);
11153 prev = var;
11154 if (!newvar) {
11155
11156 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11157 } else {
11158 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11159 }
11160 }
11161 if (prev)
11162 ast_free(prev);
11163 ies.vars = NULL;
11164 ast_channel_datastore_add(c, variablestore);
11165 } else {
11166 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11167 if (variablestore)
11168 ast_datastore_free(variablestore);
11169 if (varlist)
11170 ast_free(varlist);
11171 }
11172 }
11173 }
11174 }
11175 break;
11176 case IAX_COMMAND_INVAL:
11177 iaxs[fr->callno]->error = ENOTCONN;
11178 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11179 iax2_destroy(fr->callno);
11180 ast_debug(1, "Destroying call %d\n", fr->callno);
11181 break;
11182 case IAX_COMMAND_VNAK:
11183 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11184
11185 vnak_retransmit(fr->callno, fr->iseqno);
11186 break;
11187 case IAX_COMMAND_REGREQ:
11188 case IAX_COMMAND_REGREL:
11189
11190 if (delayreject)
11191 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11192 if (register_verify(fr->callno, &sin, &ies)) {
11193 if (!iaxs[fr->callno]) {
11194 break;
11195 }
11196
11197 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11198 break;
11199 }
11200 if (!iaxs[fr->callno]) {
11201 break;
11202 }
11203 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11204 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11205
11206 if (f.subclass.integer == IAX_COMMAND_REGREL) {
11207 memset(&sin, 0, sizeof(sin));
11208 sin.sin_family = AF_INET;
11209 }
11210 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11211 ast_log(LOG_WARNING, "Registry error\n");
11212 }
11213 if (!iaxs[fr->callno]) {
11214 break;
11215 }
11216 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11217 ast_mutex_unlock(&iaxsl[fr->callno]);
11218 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11219 ast_mutex_lock(&iaxsl[fr->callno]);
11220 }
11221 break;
11222 }
11223 registry_authrequest(fr->callno);
11224 break;
11225 case IAX_COMMAND_REGACK:
11226 if (iax2_ack_registry(&ies, &sin, fr->callno))
11227 ast_log(LOG_WARNING, "Registration failure\n");
11228
11229 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11230 iax2_destroy(fr->callno);
11231 break;
11232 case IAX_COMMAND_REGREJ:
11233 if (iaxs[fr->callno]->reg) {
11234 if (authdebug) {
11235 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));
11236 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>");
11237 }
11238 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11239 }
11240
11241 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11242 iax2_destroy(fr->callno);
11243 break;
11244 case IAX_COMMAND_REGAUTH:
11245
11246 if (registry_rerequest(&ies, fr->callno, &sin)) {
11247 memset(&ied0, 0, sizeof(ied0));
11248 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11249 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11250 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11251 }
11252 break;
11253 case IAX_COMMAND_TXREJ:
11254 iaxs[fr->callno]->transferring = 0;
11255 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11256 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11257 if (iaxs[fr->callno]->bridgecallno) {
11258 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11259 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11260 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11261 }
11262 }
11263 break;
11264 case IAX_COMMAND_TXREADY:
11265 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11266 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11267 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11268 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11269 else
11270 iaxs[fr->callno]->transferring = TRANSFER_READY;
11271 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11272 if (iaxs[fr->callno]->bridgecallno) {
11273 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11274 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11275
11276 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11277 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11278 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11279
11280 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11281 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11282
11283 memset(&ied0, 0, sizeof(ied0));
11284 memset(&ied1, 0, sizeof(ied1));
11285 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11286 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11287 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11288 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11289 } else {
11290 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11291 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11292
11293 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11294 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11295 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11296 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11297
11298
11299 stop_stuff(fr->callno);
11300 stop_stuff(iaxs[fr->callno]->bridgecallno);
11301
11302 memset(&ied0, 0, sizeof(ied0));
11303 memset(&ied1, 0, sizeof(ied1));
11304 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11305 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11306 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11307 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11308 }
11309
11310 }
11311 }
11312 }
11313 break;
11314 case IAX_COMMAND_TXREQ:
11315 try_transfer(iaxs[fr->callno], &ies);
11316 break;
11317 case IAX_COMMAND_TXCNT:
11318 if (iaxs[fr->callno]->transferring)
11319 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11320 break;
11321 case IAX_COMMAND_TXREL:
11322
11323 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11324 complete_transfer(fr->callno, &ies);
11325 stop_stuff(fr->callno);
11326 break;
11327 case IAX_COMMAND_TXMEDIA:
11328 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11329 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11330
11331 if (cur->transfer) {
11332 cur->retries = -1;
11333 }
11334 }
11335
11336 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11337 }
11338 break;
11339 case IAX_COMMAND_RTKEY:
11340 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11341 ast_log(LOG_WARNING,
11342 "we've been told to rotate our encryption key, "
11343 "but this isn't an encrypted call. bad things will happen.\n"
11344 );
11345 break;
11346 }
11347
11348 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11349
11350 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11351 break;
11352 case IAX_COMMAND_DPREP:
11353 complete_dpreply(iaxs[fr->callno], &ies);
11354 break;
11355 case IAX_COMMAND_UNSUPPORT:
11356 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11357 break;
11358 case IAX_COMMAND_FWDOWNL:
11359
11360 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11361 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11362 break;
11363 }
11364 memset(&ied0, 0, sizeof(ied0));
11365 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11366 if (res < 0)
11367 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11368 else if (res > 0)
11369 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11370 else
11371 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11372 break;
11373 case IAX_COMMAND_CALLTOKEN:
11374 {
11375 struct iax_frame *cur;
11376
11377 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11378 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11379 }
11380 break;
11381 }
11382 default:
11383 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11384 memset(&ied0, 0, sizeof(ied0));
11385 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11386 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11387 }
11388
11389 if (ies.vars) {
11390 ast_variables_destroy(ies.vars);
11391 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11392 ies.vars = NULL;
11393 }
11394
11395
11396 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11397 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11398 (f.subclass.integer != IAX_COMMAND_TXACC) &&
11399 (f.subclass.integer != IAX_COMMAND_INVAL) &&
11400 (f.subclass.integer != IAX_COMMAND_VNAK)) {
11401 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11402 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11403 }
11404 ast_mutex_unlock(&iaxsl[fr->callno]);
11405 return 1;
11406 }
11407
11408 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11409 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11410 } else if (minivid) {
11411 f.frametype = AST_FRAME_VIDEO;
11412 if (iaxs[fr->callno]->videoformat > 0)
11413 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11414 else {
11415 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11416 iax2_vnak(fr->callno);
11417 ast_variables_destroy(ies.vars);
11418 ast_mutex_unlock(&iaxsl[fr->callno]);
11419 return 1;
11420 }
11421 f.datalen = res - sizeof(*vh);
11422 if (f.datalen)
11423 f.data.ptr = thread->buf + sizeof(*vh);
11424 else
11425 f.data.ptr = NULL;
11426 #ifdef IAXTESTS
11427 if (test_resync) {
11428 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11429 } else
11430 #endif
11431 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11432 } else {
11433
11434 f.frametype = AST_FRAME_VOICE;
11435 if (iaxs[fr->callno]->voiceformat > 0)
11436 f.subclass.codec = iaxs[fr->callno]->voiceformat;
11437 else {
11438 ast_debug(1, "Received mini frame before first full voice frame\n");
11439 iax2_vnak(fr->callno);
11440 ast_variables_destroy(ies.vars);
11441 ast_mutex_unlock(&iaxsl[fr->callno]);
11442 return 1;
11443 }
11444 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11445 if (f.datalen < 0) {
11446 ast_log(LOG_WARNING, "Datalen < 0?\n");
11447 ast_variables_destroy(ies.vars);
11448 ast_mutex_unlock(&iaxsl[fr->callno]);
11449 return 1;
11450 }
11451 if (f.datalen)
11452 f.data.ptr = thread->buf + sizeof(*mh);
11453 else
11454 f.data.ptr = NULL;
11455 #ifdef IAXTESTS
11456 if (test_resync) {
11457 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11458 } else
11459 #endif
11460 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11461
11462 }
11463
11464 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11465 ast_variables_destroy(ies.vars);
11466 ast_mutex_unlock(&iaxsl[fr->callno]);
11467 return 1;
11468 }
11469
11470 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11471 struct ast_party_connected_line connected;
11472
11473 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11474 ast_variables_destroy(ies.vars);
11475 ast_mutex_unlock(&iaxsl[fr->callno]);
11476 return 1;
11477 }
11478
11479
11480 ast_party_connected_line_init(&connected);
11481 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11482 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11483
11484 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11485 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11486 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11487 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11488
11489 if (iaxs[fr->callno]->owner) {
11490 ast_set_callerid(iaxs[fr->callno]->owner,
11491 S_COR(connected.id.number.valid, connected.id.number.str, ""),
11492 S_COR(connected.id.name.valid, connected.id.name.str, ""),
11493 NULL);
11494 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11495 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11496 }
11497 }
11498 ast_party_connected_line_free(&connected);
11499 }
11500
11501 f.src = "IAX2";
11502 f.mallocd = 0;
11503 f.offset = 0;
11504 f.len = 0;
11505 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11506 f.samples = ast_codec_get_samples(&f);
11507
11508 if (f.subclass.codec == AST_FORMAT_SLINEAR)
11509 ast_frame_byteswap_be(&f);
11510 } else
11511 f.samples = 0;
11512 iax_frame_wrap(fr, &f);
11513
11514
11515 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11516
11517 fr->outoforder = 0;
11518 } else {
11519 if (iaxdebug && iaxs[fr->callno])
11520 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);
11521 fr->outoforder = -1;
11522 }
11523 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11524 duped_fr = iaxfrdup2(fr);
11525 if (duped_fr) {
11526 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11527 }
11528 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11529 iaxs[fr->callno]->last = fr->ts;
11530 #if 1
11531 if (iaxdebug)
11532 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11533 #endif
11534 }
11535
11536
11537 ast_variables_destroy(ies.vars);
11538 ast_mutex_unlock(&iaxsl[fr->callno]);
11539 return 1;
11540 }
11541
11542
11543 static void iax2_process_thread_cleanup(void *data)
11544 {
11545 struct iax2_thread *thread = data;
11546 ast_mutex_destroy(&thread->lock);
11547 ast_cond_destroy(&thread->cond);
11548 ast_mutex_destroy(&thread->init_lock);
11549 ast_cond_destroy(&thread->init_cond);
11550 ast_free(thread);
11551 ast_atomic_dec_and_test(&iaxactivethreadcount);
11552 }
11553
11554 static void *iax2_process_thread(void *data)
11555 {
11556 struct iax2_thread *thread = data;
11557 struct timeval wait;
11558 struct timespec ts;
11559 int put_into_idle = 0;
11560 int first_time = 1;
11561 int old_state;
11562
11563 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11564
11565 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11566 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11567
11568 for (;;) {
11569
11570 ast_mutex_lock(&thread->lock);
11571
11572 if (thread->stop) {
11573 ast_mutex_unlock(&thread->lock);
11574 break;
11575 }
11576
11577
11578 if (first_time) {
11579 signal_condition(&thread->init_lock, &thread->init_cond);
11580 first_time = 0;
11581 }
11582
11583
11584 if (put_into_idle) {
11585 insert_idle_thread(thread);
11586 }
11587
11588 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11589 struct iax2_thread *t = NULL;
11590
11591 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11592 ts.tv_sec = wait.tv_sec;
11593 ts.tv_nsec = wait.tv_usec * 1000;
11594 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11595
11596
11597 if (!put_into_idle || thread->stop) {
11598 ast_mutex_unlock(&thread->lock);
11599 break;
11600 }
11601 AST_LIST_LOCK(&dynamic_list);
11602
11603 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11604 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11605 AST_LIST_UNLOCK(&dynamic_list);
11606 if (t) {
11607
11608
11609
11610 ast_mutex_unlock(&thread->lock);
11611 break;
11612 }
11613
11614
11615
11616 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11617 ts.tv_sec = wait.tv_sec;
11618 ts.tv_nsec = wait.tv_usec * 1000;
11619 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11620 ast_mutex_unlock(&thread->lock);
11621 break;
11622 }
11623 }
11624 } else {
11625 ast_cond_wait(&thread->cond, &thread->lock);
11626 }
11627
11628
11629 put_into_idle = 1;
11630
11631 ast_mutex_unlock(&thread->lock);
11632
11633 if (thread->stop) {
11634 break;
11635 }
11636
11637 if (thread->iostate == IAX_IOSTATE_IDLE)
11638 continue;
11639
11640
11641 switch (thread->iostate) {
11642 case IAX_IOSTATE_READY:
11643 thread->actions++;
11644 thread->iostate = IAX_IOSTATE_PROCESSING;
11645 socket_process(thread);
11646 handle_deferred_full_frames(thread);
11647 break;
11648 case IAX_IOSTATE_SCHEDREADY:
11649 thread->actions++;
11650 thread->iostate = IAX_IOSTATE_PROCESSING;
11651 #ifdef SCHED_MULTITHREADED
11652 thread->schedfunc(thread->scheddata);
11653 #endif
11654 default:
11655 break;
11656 }
11657 time(&thread->checktime);
11658 thread->iostate = IAX_IOSTATE_IDLE;
11659 #ifdef DEBUG_SCHED_MULTITHREAD
11660 thread->curfunc[0]='\0';
11661 #endif
11662
11663
11664
11665
11666 AST_LIST_LOCK(&active_list);
11667 AST_LIST_REMOVE(&active_list, thread, list);
11668 AST_LIST_UNLOCK(&active_list);
11669
11670
11671 handle_deferred_full_frames(thread);
11672 }
11673
11674
11675
11676
11677
11678 AST_LIST_LOCK(&idle_list);
11679 AST_LIST_REMOVE(&idle_list, thread, list);
11680 AST_LIST_UNLOCK(&idle_list);
11681
11682 AST_LIST_LOCK(&dynamic_list);
11683 AST_LIST_REMOVE(&dynamic_list, thread, list);
11684 AST_LIST_UNLOCK(&dynamic_list);
11685
11686
11687
11688
11689 pthread_cleanup_pop(1);
11690 return NULL;
11691 }
11692
11693 static int iax2_do_register(struct iax2_registry *reg)
11694 {
11695 struct iax_ie_data ied;
11696 if (iaxdebug)
11697 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11698
11699 if (reg->dnsmgr &&
11700 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) {
11701
11702 ast_dnsmgr_refresh(reg->dnsmgr);
11703 }
11704
11705
11706
11707
11708
11709 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11710 int callno = reg->callno;
11711 ast_mutex_lock(&iaxsl[callno]);
11712 iax2_destroy(callno);
11713 ast_mutex_unlock(&iaxsl[callno]);
11714 reg->callno = 0;
11715 }
11716 if (!ast_sockaddr_ipv4(®->addr)) {
11717 if (iaxdebug)
11718 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11719
11720 reg->expire = iax2_sched_replace(reg->expire, sched,
11721 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11722 return -1;
11723 }
11724
11725 if (!reg->callno) {
11726 struct sockaddr_in reg_addr;
11727
11728 ast_debug(3, "Allocate call number\n");
11729
11730 ast_sockaddr_to_sin(®->addr, ®_addr);
11731
11732 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0);
11733 if (reg->callno < 1) {
11734 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11735 return -1;
11736 } else
11737 ast_debug(3, "Registration created on call %d\n", reg->callno);
11738 iaxs[reg->callno]->reg = reg;
11739 ast_mutex_unlock(&iaxsl[reg->callno]);
11740 }
11741
11742 reg->expire = iax2_sched_replace(reg->expire, sched,
11743 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11744
11745 memset(&ied, 0, sizeof(ied));
11746 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11747 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11748 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11749 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11750 reg->regstate = REG_STATE_REGSENT;
11751 return 0;
11752 }
11753
11754 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
11755 {
11756
11757
11758 struct iax_ie_data provdata;
11759 struct iax_ie_data ied;
11760 unsigned int sig;
11761 struct sockaddr_in sin;
11762 int callno;
11763 struct create_addr_info cai;
11764
11765 memset(&cai, 0, sizeof(cai));
11766
11767 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11768
11769 if (iax_provision_build(&provdata, &sig, template, force)) {
11770 ast_debug(1, "No provisioning found for template '%s'\n", template);
11771 return 0;
11772 }
11773
11774 if (end) {
11775 memcpy(&sin, end, sizeof(sin));
11776 cai.sockfd = sockfd;
11777 } else if (create_addr(dest, NULL, &sin, &cai))
11778 return -1;
11779
11780
11781 memset(&ied, 0, sizeof(ied));
11782 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11783
11784 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11785 if (!callno)
11786 return -1;
11787
11788 if (iaxs[callno]) {
11789
11790 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11791 sched, 15000, auto_hangup, (void *)(long)callno);
11792 ast_set_flag64(iaxs[callno], IAX_PROVISION);
11793
11794 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11795 }
11796 ast_mutex_unlock(&iaxsl[callno]);
11797
11798 return 1;
11799 }
11800
11801 static char *papp = "IAX2Provision";
11802
11803
11804
11805
11806 static int iax2_prov_app(struct ast_channel *chan, const char *data)
11807 {
11808 int res;
11809 char *sdata;
11810 char *opts;
11811 int force =0;
11812 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11813 if (ast_strlen_zero(data))
11814 data = "default";
11815 sdata = ast_strdupa(data);
11816 opts = strchr(sdata, '|');
11817 if (opts)
11818 *opts='\0';
11819
11820 if (chan->tech != &iax2_tech) {
11821 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11822 return -1;
11823 }
11824 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11825 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11826 return -1;
11827 }
11828 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11829 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11830 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11831 sdata, res);
11832 return res;
11833 }
11834
11835 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11836 {
11837 int force = 0;
11838 int res;
11839
11840 switch (cmd) {
11841 case CLI_INIT:
11842 e->command = "iax2 provision";
11843 e->usage =
11844 "Usage: iax2 provision <host> <template> [forced]\n"
11845 " Provisions the given peer or IP address using a template\n"
11846 " matching either 'template' or '*' if the template is not\n"
11847 " found. If 'forced' is specified, even empty provisioning\n"
11848 " fields will be provisioned as empty fields.\n";
11849 return NULL;
11850 case CLI_GENERATE:
11851 if (a->pos == 3)
11852 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11853 return NULL;
11854 }
11855
11856 if (a->argc < 4)
11857 return CLI_SHOWUSAGE;
11858 if (a->argc > 4) {
11859 if (!strcasecmp(a->argv[4], "forced"))
11860 force = 1;
11861 else
11862 return CLI_SHOWUSAGE;
11863 }
11864 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11865 if (res < 0)
11866 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11867 else if (res < 1)
11868 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11869 else
11870 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11871 return CLI_SUCCESS;
11872 }
11873
11874 static void __iax2_poke_noanswer(const void *data)
11875 {
11876 struct iax2_peer *peer = (struct iax2_peer *)data;
11877 int callno;
11878
11879 if (peer->lastms > -1) {
11880 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11881 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11882 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11883 }
11884 if ((callno = peer->callno) > 0) {
11885 ast_mutex_lock(&iaxsl[callno]);
11886 iax2_destroy(callno);
11887 ast_mutex_unlock(&iaxsl[callno]);
11888 }
11889 peer->callno = 0;
11890 peer->lastms = -1;
11891
11892 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11893 if (peer->pokeexpire == -1)
11894 peer_unref(peer);
11895 }
11896
11897 static int iax2_poke_noanswer(const void *data)
11898 {
11899 struct iax2_peer *peer = (struct iax2_peer *)data;
11900 peer->pokeexpire = -1;
11901 #ifdef SCHED_MULTITHREADED
11902 if (schedule_action(__iax2_poke_noanswer, data))
11903 #endif
11904 __iax2_poke_noanswer(data);
11905 peer_unref(peer);
11906 return 0;
11907 }
11908
11909 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11910 {
11911 struct iax2_peer *peer = obj;
11912
11913 iax2_poke_peer(peer, 0);
11914
11915 return 0;
11916 }
11917
11918 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11919 {
11920 int callno;
11921 struct sockaddr_in peer_addr;
11922
11923 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
11924
11925
11926 peer->lastms = 0;
11927 peer->historicms = 0;
11928 peer->pokeexpire = -1;
11929 peer->callno = 0;
11930 return 0;
11931 }
11932
11933 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
11934
11935
11936 if ((callno = peer->callno) > 0) {
11937 ast_log(LOG_NOTICE, "Still have a callno...\n");
11938 ast_mutex_lock(&iaxsl[callno]);
11939 iax2_destroy(callno);
11940 ast_mutex_unlock(&iaxsl[callno]);
11941 }
11942 if (heldcall)
11943 ast_mutex_unlock(&iaxsl[heldcall]);
11944 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
11945 if (heldcall)
11946 ast_mutex_lock(&iaxsl[heldcall]);
11947 if (peer->callno < 1) {
11948 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11949 return -1;
11950 }
11951
11952
11953 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11954 iaxs[peer->callno]->peerpoke = peer;
11955
11956 if (peer->pokeexpire > -1) {
11957 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
11958 peer->pokeexpire = -1;
11959 peer_unref(peer);
11960 }
11961 }
11962
11963
11964
11965 if (peer->lastms < 0)
11966 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11967 else
11968 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11969
11970 if (peer->pokeexpire == -1)
11971 peer_unref(peer);
11972
11973
11974 ast_mutex_lock(&iaxsl[callno]);
11975 if (iaxs[callno]) {
11976 struct iax_ie_data ied = {
11977 .buf = { 0 },
11978 .pos = 0,
11979 };
11980 add_empty_calltoken_ie(iaxs[callno], &ied);
11981 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11982 }
11983 ast_mutex_unlock(&iaxsl[callno]);
11984
11985 return 0;
11986 }
11987
11988 static void free_context(struct iax2_context *con)
11989 {
11990 struct iax2_context *conl;
11991 while(con) {
11992 conl = con;
11993 con = con->next;
11994 ast_free(conl);
11995 }
11996 }
11997
11998 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
11999 {
12000 int callno;
12001 int res;
12002 format_t fmt, native;
12003 struct sockaddr_in sin;
12004 struct ast_channel *c;
12005 struct parsed_dial_string pds;
12006 struct create_addr_info cai;
12007 char *tmpstr;
12008
12009 memset(&pds, 0, sizeof(pds));
12010 tmpstr = ast_strdupa(data);
12011 parse_dial_string(tmpstr, &pds);
12012
12013 if (ast_strlen_zero(pds.peer)) {
12014 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12015 return NULL;
12016 }
12017
12018 memset(&cai, 0, sizeof(cai));
12019 cai.capability = iax2_capability;
12020
12021 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12022
12023
12024 if (create_addr(pds.peer, NULL, &sin, &cai)) {
12025 *cause = AST_CAUSE_UNREGISTERED;
12026 return NULL;
12027 }
12028
12029 if (pds.port)
12030 sin.sin_port = htons(atoi(pds.port));
12031
12032 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12033 if (callno < 1) {
12034 ast_log(LOG_WARNING, "Unable to create call\n");
12035 *cause = AST_CAUSE_CONGESTION;
12036 return NULL;
12037 }
12038
12039
12040 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12041 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12042 int new_callno;
12043 if ((new_callno = make_trunk(callno, 1)) != -1)
12044 callno = new_callno;
12045 }
12046 iaxs[callno]->maxtime = cai.maxtime;
12047 if (cai.found)
12048 ast_string_field_set(iaxs[callno], host, pds.peer);
12049
12050 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
12051
12052 ast_mutex_unlock(&iaxsl[callno]);
12053
12054 if (c) {
12055
12056 if (c->nativeformats & format)
12057 c->nativeformats &= format;
12058 else {
12059 native = c->nativeformats;
12060 fmt = format;
12061 res = ast_translator_best_choice(&fmt, &native);
12062 if (res < 0) {
12063 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12064 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12065 ast_hangup(c);
12066 return NULL;
12067 }
12068 c->nativeformats = native;
12069 }
12070 c->readformat = ast_best_codec(c->nativeformats);
12071 c->writeformat = c->readformat;
12072 }
12073
12074 return c;
12075 }
12076
12077 static void *network_thread(void *ignore)
12078 {
12079 if (timer) {
12080 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12081 }
12082
12083 for (;;) {
12084 pthread_testcancel();
12085
12086
12087
12088 ast_io_wait(io, 1000);
12089 }
12090
12091 return NULL;
12092 }
12093
12094 static int start_network_thread(void)
12095 {
12096 struct iax2_thread *thread;
12097 int threadcount = 0;
12098 int x;
12099 for (x = 0; x < iaxthreadcount; x++) {
12100 thread = ast_calloc(1, sizeof(*thread));
12101 if (thread) {
12102 thread->type = IAX_THREAD_TYPE_POOL;
12103 thread->threadnum = ++threadcount;
12104 ast_mutex_init(&thread->lock);
12105 ast_cond_init(&thread->cond, NULL);
12106 ast_mutex_init(&thread->init_lock);
12107 ast_cond_init(&thread->init_cond, NULL);
12108 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12109 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12110 ast_mutex_destroy(&thread->lock);
12111 ast_cond_destroy(&thread->cond);
12112 ast_mutex_destroy(&thread->init_lock);
12113 ast_cond_destroy(&thread->init_cond);
12114 ast_free(thread);
12115 thread = NULL;
12116 continue;
12117 }
12118 AST_LIST_LOCK(&idle_list);
12119 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12120 AST_LIST_UNLOCK(&idle_list);
12121 }
12122 }
12123 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12124 ast_verb(2, "%d helper threads started\n", threadcount);
12125 return 0;
12126 }
12127
12128 static struct iax2_context *build_context(const char *context)
12129 {
12130 struct iax2_context *con;
12131
12132 if ((con = ast_calloc(1, sizeof(*con))))
12133 ast_copy_string(con->context, context, sizeof(con->context));
12134
12135 return con;
12136 }
12137
12138 static int get_auth_methods(const char *value)
12139 {
12140 int methods = 0;
12141 if (strstr(value, "rsa"))
12142 methods |= IAX_AUTH_RSA;
12143 if (strstr(value, "md5"))
12144 methods |= IAX_AUTH_MD5;
12145 if (strstr(value, "plaintext"))
12146 methods |= IAX_AUTH_PLAINTEXT;
12147 return methods;
12148 }
12149
12150
12151
12152
12153
12154 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
12155 {
12156 int sd;
12157 int res;
12158
12159 sd = socket(AF_INET, SOCK_DGRAM, 0);
12160 if (sd < 0) {
12161 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12162 return -1;
12163 }
12164
12165 res = bind(sd, sa, salen);
12166 if (res < 0) {
12167 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12168 close(sd);
12169 return 1;
12170 }
12171
12172 close(sd);
12173 return 0;
12174 }
12175
12176
12177
12178
12179 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12180 {
12181 struct sockaddr_in sin;
12182 struct ast_sockaddr sin_tmp;
12183 int nonlocal = 1;
12184 int port = IAX_DEFAULT_PORTNO;
12185 int sockfd = defaultsockfd;
12186 char *tmp;
12187 char *addr;
12188 char *portstr;
12189
12190 if (!(tmp = ast_strdupa(srcaddr)))
12191 return -1;
12192
12193 addr = strsep(&tmp, ":");
12194 portstr = tmp;
12195
12196 if (portstr) {
12197 port = atoi(portstr);
12198 if (port < 1)
12199 port = IAX_DEFAULT_PORTNO;
12200 }
12201
12202 if (!ast_get_ip(&sin_tmp, addr)) {
12203 struct ast_netsock *sock;
12204 int res;
12205
12206 ast_sockaddr_to_sin(&sin_tmp, &sin);
12207 sin.sin_port = 0;
12208 sin.sin_family = AF_INET;
12209 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12210 if (res == 0) {
12211
12212 sin.sin_port = htons(port);
12213 if (!(sock = ast_netsock_find(netsock, &sin)))
12214 sock = ast_netsock_find(outsock, &sin);
12215 if (sock) {
12216 sockfd = ast_netsock_sockfd(sock);
12217 nonlocal = 0;
12218 } else {
12219 unsigned int orig_saddr = sin.sin_addr.s_addr;
12220
12221 sin.sin_addr.s_addr = INADDR_ANY;
12222 if (ast_netsock_find(netsock, &sin)) {
12223 sin.sin_addr.s_addr = orig_saddr;
12224 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12225 if (sock) {
12226 sockfd = ast_netsock_sockfd(sock);
12227 ast_netsock_unref(sock);
12228 nonlocal = 0;
12229 } else {
12230 nonlocal = 2;
12231 }
12232 }
12233 }
12234 }
12235 }
12236
12237 peer->sockfd = sockfd;
12238
12239 if (nonlocal == 1) {
12240 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12241 srcaddr, peer->name);
12242 return -1;
12243 } else if (nonlocal == 2) {
12244 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12245 srcaddr, peer->name);
12246 return -1;
12247 } else {
12248 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12249 return 0;
12250 }
12251 }
12252
12253 static void peer_destructor(void *obj)
12254 {
12255 struct iax2_peer *peer = obj;
12256 int callno = peer->callno;
12257
12258 ast_free_ha(peer->ha);
12259
12260 if (callno > 0) {
12261 ast_mutex_lock(&iaxsl[callno]);
12262 iax2_destroy(callno);
12263 ast_mutex_unlock(&iaxsl[callno]);
12264 }
12265
12266 register_peer_exten(peer, 0);
12267
12268 if (peer->dnsmgr)
12269 ast_dnsmgr_release(peer->dnsmgr);
12270
12271 if (peer->mwi_event_sub)
12272 ast_event_unsubscribe(peer->mwi_event_sub);
12273
12274 ast_string_field_free_memory(peer);
12275 }
12276
12277
12278 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12279 {
12280 struct iax2_peer *peer = NULL;
12281 struct ast_ha *oldha = NULL;
12282 int maskfound = 0;
12283 int found = 0;
12284 int firstpass = 1;
12285 struct iax2_peer tmp_peer = {
12286 .name = name,
12287 };
12288
12289 if (!temponly) {
12290 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12291 if (peer && !ast_test_flag64(peer, IAX_DELME))
12292 firstpass = 0;
12293 }
12294
12295 if (peer) {
12296 found++;
12297 if (firstpass) {
12298 oldha = peer->ha;
12299 peer->ha = NULL;
12300 }
12301 unlink_peer(peer);
12302 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12303 peer->expire = -1;
12304 peer->pokeexpire = -1;
12305 peer->sockfd = defaultsockfd;
12306 if (ast_string_field_init(peer, 32))
12307 peer = peer_unref(peer);
12308 }
12309
12310 if (peer) {
12311 if (firstpass) {
12312 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12313 peer->encmethods = iax2_encryption;
12314 peer->adsi = adsi;
12315 ast_string_field_set(peer,secret,"");
12316 if (!found) {
12317 ast_string_field_set(peer, name, name);
12318 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12319 peer->expiry = min_reg_expire;
12320 }
12321 peer->prefs = prefs;
12322 peer->capability = iax2_capability;
12323 peer->smoothing = 0;
12324 peer->pokefreqok = DEFAULT_FREQ_OK;
12325 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12326 peer->maxcallno = 0;
12327 peercnt_modify(0, 0, &peer->addr);
12328 peer->calltoken_required = CALLTOKEN_DEFAULT;
12329 ast_string_field_set(peer,context,"");
12330 ast_string_field_set(peer,peercontext,"");
12331 ast_clear_flag64(peer, IAX_HASCALLERID);
12332 ast_string_field_set(peer, cid_name, "");
12333 ast_string_field_set(peer, cid_num, "");
12334 ast_string_field_set(peer, mohinterpret, mohinterpret);
12335 ast_string_field_set(peer, mohsuggest, mohsuggest);
12336 }
12337
12338 if (!v) {
12339 v = alt;
12340 alt = NULL;
12341 }
12342 while(v) {
12343 if (!strcasecmp(v->name, "secret")) {
12344 ast_string_field_set(peer, secret, v->value);
12345 } else if (!strcasecmp(v->name, "mailbox")) {
12346 ast_string_field_set(peer, mailbox, v->value);
12347 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12348 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12349 ast_string_field_set(peer, mailbox, name);
12350 }
12351 } else if (!strcasecmp(v->name, "mohinterpret")) {
12352 ast_string_field_set(peer, mohinterpret, v->value);
12353 } else if (!strcasecmp(v->name, "mohsuggest")) {
12354 ast_string_field_set(peer, mohsuggest, v->value);
12355 } else if (!strcasecmp(v->name, "dbsecret")) {
12356 ast_string_field_set(peer, dbsecret, v->value);
12357 } else if (!strcasecmp(v->name, "trunk")) {
12358 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12359 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12360 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12361 ast_clear_flag64(peer, IAX_TRUNK);
12362 }
12363 } else if (!strcasecmp(v->name, "auth")) {
12364 peer->authmethods = get_auth_methods(v->value);
12365 } else if (!strcasecmp(v->name, "encryption")) {
12366 peer->encmethods |= get_encrypt_methods(v->value);
12367 if (!peer->encmethods) {
12368 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12369 }
12370 } else if (!strcasecmp(v->name, "forceencryption")) {
12371 if (ast_false(v->value)) {
12372 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12373 } else {
12374 peer->encmethods |= get_encrypt_methods(v->value);
12375 if (peer->encmethods) {
12376 ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12377 }
12378 }
12379 } else if (!strcasecmp(v->name, "transfer")) {
12380 if (!strcasecmp(v->value, "mediaonly")) {
12381 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12382 } else if (ast_true(v->value)) {
12383 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12384 } else
12385 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12386 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12387 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12388 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12389 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12390 } else if (!strcasecmp(v->name, "host")) {
12391 if (!strcasecmp(v->value, "dynamic")) {
12392
12393 ast_set_flag64(peer, IAX_DYNAMIC);
12394 if (!found) {
12395
12396
12397 if (ast_sockaddr_port(&peer->addr)) {
12398 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12399 }
12400 ast_sockaddr_setnull(&peer->addr);
12401 }
12402 } else {
12403
12404 ast_sched_thread_del(sched, peer->expire);
12405 ast_clear_flag64(peer, IAX_DYNAMIC);
12406 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12407 return peer_unref(peer);
12408 if (!ast_sockaddr_port(&peer->addr)) {
12409 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12410 }
12411 }
12412 if (!maskfound)
12413 inet_aton("255.255.255.255", &peer->mask);
12414 } else if (!strcasecmp(v->name, "defaultip")) {
12415 struct ast_sockaddr peer_defaddr_tmp;
12416
12417 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12418 return peer_unref(peer);
12419 }
12420 ast_sockaddr_to_sin(&peer_defaddr_tmp,
12421 &peer->defaddr);
12422 } else if (!strcasecmp(v->name, "sourceaddress")) {
12423 peer_set_srcaddr(peer, v->value);
12424 } else if (!strcasecmp(v->name, "permit") ||
12425 !strcasecmp(v->name, "deny")) {
12426 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12427 } else if (!strcasecmp(v->name, "mask")) {
12428 maskfound++;
12429 inet_aton(v->value, &peer->mask);
12430 } else if (!strcasecmp(v->name, "context")) {
12431 ast_string_field_set(peer, context, v->value);
12432 } else if (!strcasecmp(v->name, "regexten")) {
12433 ast_string_field_set(peer, regexten, v->value);
12434 } else if (!strcasecmp(v->name, "peercontext")) {
12435 ast_string_field_set(peer, peercontext, v->value);
12436 } else if (!strcasecmp(v->name, "port")) {
12437 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12438 peer->defaddr.sin_port = htons(atoi(v->value));
12439 } else {
12440 ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12441 }
12442 } else if (!strcasecmp(v->name, "username")) {
12443 ast_string_field_set(peer, username, v->value);
12444 } else if (!strcasecmp(v->name, "allow")) {
12445 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12446 } else if (!strcasecmp(v->name, "disallow")) {
12447 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12448 } else if (!strcasecmp(v->name, "callerid")) {
12449 if (!ast_strlen_zero(v->value)) {
12450 char name2[80];
12451 char num2[80];
12452 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12453 ast_string_field_set(peer, cid_name, name2);
12454 ast_string_field_set(peer, cid_num, num2);
12455 } else {
12456 ast_string_field_set(peer, cid_name, "");
12457 ast_string_field_set(peer, cid_num, "");
12458 }
12459 ast_set_flag64(peer, IAX_HASCALLERID);
12460 } else if (!strcasecmp(v->name, "fullname")) {
12461 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12462 ast_set_flag64(peer, IAX_HASCALLERID);
12463 } else if (!strcasecmp(v->name, "cid_number")) {
12464 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12465 ast_set_flag64(peer, IAX_HASCALLERID);
12466 } else if (!strcasecmp(v->name, "sendani")) {
12467 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12468 } else if (!strcasecmp(v->name, "inkeys")) {
12469 ast_string_field_set(peer, inkeys, v->value);
12470 } else if (!strcasecmp(v->name, "outkey")) {
12471 ast_string_field_set(peer, outkey, v->value);
12472 } else if (!strcasecmp(v->name, "qualify")) {
12473 if (!strcasecmp(v->value, "no")) {
12474 peer->maxms = 0;
12475 } else if (!strcasecmp(v->value, "yes")) {
12476 peer->maxms = DEFAULT_MAXMS;
12477 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12478 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);
12479 peer->maxms = 0;
12480 }
12481 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12482 peer->smoothing = ast_true(v->value);
12483 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12484 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12485 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);
12486 }
12487 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12488 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12489 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);
12490 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12491 } else if (!strcasecmp(v->name, "timezone")) {
12492 ast_string_field_set(peer, zonetag, v->value);
12493 } else if (!strcasecmp(v->name, "adsi")) {
12494 peer->adsi = ast_true(v->value);
12495 } else if (!strcasecmp(v->name, "connectedline")) {
12496 if (ast_true(v->value)) {
12497 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12498 } else if (!strcasecmp(v->value, "send")) {
12499 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12500 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12501 } else if (!strcasecmp(v->value, "receive")) {
12502 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12503 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12504 } else {
12505 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12506 }
12507 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12508 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12509 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12510 } else {
12511 peercnt_modify(1, peer->maxcallno, &peer->addr);
12512 }
12513 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12514
12515 if (ast_false(v->value)) {
12516 peer->calltoken_required = CALLTOKEN_NO;
12517 } else if (!strcasecmp(v->value, "auto")) {
12518 peer->calltoken_required = CALLTOKEN_AUTO;
12519 } else if (ast_true(v->value)) {
12520 peer->calltoken_required = CALLTOKEN_YES;
12521 } else {
12522 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12523 }
12524 }
12525
12526 v = v->next;
12527 if (!v) {
12528 v = alt;
12529 alt = NULL;
12530 }
12531 }
12532 if (!peer->authmethods)
12533 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12534 ast_clear_flag64(peer, IAX_DELME);
12535 }
12536
12537 if (oldha)
12538 ast_free_ha(oldha);
12539
12540 if (!ast_strlen_zero(peer->mailbox)) {
12541 char *mailbox, *context;
12542 context = mailbox = ast_strdupa(peer->mailbox);
12543 strsep(&context, "@");
12544 if (ast_strlen_zero(context))
12545 context = "default";
12546 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12547 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12548 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12549 AST_EVENT_IE_END);
12550 }
12551
12552 return peer;
12553 }
12554
12555 static void user_destructor(void *obj)
12556 {
12557 struct iax2_user *user = obj;
12558
12559 ast_free_ha(user->ha);
12560 free_context(user->contexts);
12561 if(user->vars) {
12562 ast_variables_destroy(user->vars);
12563 user->vars = NULL;
12564 }
12565 ast_string_field_free_memory(user);
12566 }
12567
12568
12569 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12570 {
12571 struct iax2_user *user = NULL;
12572 struct iax2_context *con, *conl = NULL;
12573 struct ast_ha *oldha = NULL;
12574 struct iax2_context *oldcon = NULL;
12575 int format;
12576 int firstpass=1;
12577 int oldcurauthreq = 0;
12578 char *varname = NULL, *varval = NULL;
12579 struct ast_variable *tmpvar = NULL;
12580 struct iax2_user tmp_user = {
12581 .name = name,
12582 };
12583
12584 if (!temponly) {
12585 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12586 if (user && !ast_test_flag64(user, IAX_DELME))
12587 firstpass = 0;
12588 }
12589
12590 if (user) {
12591 if (firstpass) {
12592 oldcurauthreq = user->curauthreq;
12593 oldha = user->ha;
12594 oldcon = user->contexts;
12595 user->ha = NULL;
12596 user->contexts = NULL;
12597 }
12598
12599 ao2_unlink(users, user);
12600 } else {
12601 user = ao2_alloc(sizeof(*user), user_destructor);
12602 }
12603
12604 if (user) {
12605 if (firstpass) {
12606 ast_string_field_free_memory(user);
12607 memset(user, 0, sizeof(struct iax2_user));
12608 if (ast_string_field_init(user, 32)) {
12609 user = user_unref(user);
12610 goto cleanup;
12611 }
12612 user->maxauthreq = maxauthreq;
12613 user->curauthreq = oldcurauthreq;
12614 user->prefs = prefs;
12615 user->capability = iax2_capability;
12616 user->encmethods = iax2_encryption;
12617 user->adsi = adsi;
12618 user->calltoken_required = CALLTOKEN_DEFAULT;
12619 ast_string_field_set(user, name, name);
12620 ast_string_field_set(user, language, language);
12621 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);
12622 ast_clear_flag64(user, IAX_HASCALLERID);
12623 ast_string_field_set(user, cid_name, "");
12624 ast_string_field_set(user, cid_num, "");
12625 ast_string_field_set(user, accountcode, accountcode);
12626 ast_string_field_set(user, mohinterpret, mohinterpret);
12627 ast_string_field_set(user, mohsuggest, mohsuggest);
12628 }
12629 if (!v) {
12630 v = alt;
12631 alt = NULL;
12632 }
12633 while(v) {
12634 if (!strcasecmp(v->name, "context")) {
12635 con = build_context(v->value);
12636 if (con) {
12637 if (conl)
12638 conl->next = con;
12639 else
12640 user->contexts = con;
12641 conl = con;
12642 }
12643 } else if (!strcasecmp(v->name, "permit") ||
12644 !strcasecmp(v->name, "deny")) {
12645 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12646 } else if (!strcasecmp(v->name, "setvar")) {
12647 varname = ast_strdupa(v->value);
12648 if (varname && (varval = strchr(varname,'='))) {
12649 *varval = '\0';
12650 varval++;
12651 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12652 tmpvar->next = user->vars;
12653 user->vars = tmpvar;
12654 }
12655 }
12656 } else if (!strcasecmp(v->name, "allow")) {
12657 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12658 } else if (!strcasecmp(v->name, "disallow")) {
12659 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12660 } else if (!strcasecmp(v->name, "trunk")) {
12661 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
12662 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12663 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12664 ast_clear_flag64(user, IAX_TRUNK);
12665 }
12666 } else if (!strcasecmp(v->name, "auth")) {
12667 user->authmethods = get_auth_methods(v->value);
12668 } else if (!strcasecmp(v->name, "encryption")) {
12669 user->encmethods |= get_encrypt_methods(v->value);
12670 if (!user->encmethods) {
12671 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12672 }
12673 } else if (!strcasecmp(v->name, "forceencryption")) {
12674 if (ast_false(v->value)) {
12675 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12676 } else {
12677 user->encmethods |= get_encrypt_methods(v->value);
12678 if (user->encmethods) {
12679 ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12680 }
12681 }
12682 } else if (!strcasecmp(v->name, "transfer")) {
12683 if (!strcasecmp(v->value, "mediaonly")) {
12684 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12685 } else if (ast_true(v->value)) {
12686 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12687 } else
12688 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12689 } else if (!strcasecmp(v->name, "codecpriority")) {
12690 if(!strcasecmp(v->value, "caller"))
12691 ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12692 else if(!strcasecmp(v->value, "disabled"))
12693 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12694 else if(!strcasecmp(v->value, "reqonly")) {
12695 ast_set_flag64(user, IAX_CODEC_NOCAP);
12696 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12697 }
12698 } else if (!strcasecmp(v->name, "immediate")) {
12699 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12700 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12701 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12702 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12703 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12704 } else if (!strcasecmp(v->name, "dbsecret")) {
12705 ast_string_field_set(user, dbsecret, v->value);
12706 } else if (!strcasecmp(v->name, "secret")) {
12707 if (!ast_strlen_zero(user->secret)) {
12708 char *old = ast_strdupa(user->secret);
12709
12710 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12711 } else
12712 ast_string_field_set(user, secret, v->value);
12713 } else if (!strcasecmp(v->name, "callerid")) {
12714 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12715 char name2[80];
12716 char num2[80];
12717 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12718 ast_string_field_set(user, cid_name, name2);
12719 ast_string_field_set(user, cid_num, num2);
12720 ast_set_flag64(user, IAX_HASCALLERID);
12721 } else {
12722 ast_clear_flag64(user, IAX_HASCALLERID);
12723 ast_string_field_set(user, cid_name, "");
12724 ast_string_field_set(user, cid_num, "");
12725 }
12726 } else if (!strcasecmp(v->name, "fullname")) {
12727 if (!ast_strlen_zero(v->value)) {
12728 ast_string_field_set(user, cid_name, v->value);
12729 ast_set_flag64(user, IAX_HASCALLERID);
12730 } else {
12731 ast_string_field_set(user, cid_name, "");
12732 if (ast_strlen_zero(user->cid_num))
12733 ast_clear_flag64(user, IAX_HASCALLERID);
12734 }
12735 } else if (!strcasecmp(v->name, "cid_number")) {
12736 if (!ast_strlen_zero(v->value)) {
12737 ast_string_field_set(user, cid_num, v->value);
12738 ast_set_flag64(user, IAX_HASCALLERID);
12739 } else {
12740 ast_string_field_set(user, cid_num, "");
12741 if (ast_strlen_zero(user->cid_name))
12742 ast_clear_flag64(user, IAX_HASCALLERID);
12743 }
12744 } else if (!strcasecmp(v->name, "accountcode")) {
12745 ast_string_field_set(user, accountcode, v->value);
12746 } else if (!strcasecmp(v->name, "mohinterpret")) {
12747 ast_string_field_set(user, mohinterpret, v->value);
12748 } else if (!strcasecmp(v->name, "mohsuggest")) {
12749 ast_string_field_set(user, mohsuggest, v->value);
12750 } else if (!strcasecmp(v->name, "parkinglot")) {
12751 ast_string_field_set(user, parkinglot, v->value);
12752 } else if (!strcasecmp(v->name, "language")) {
12753 ast_string_field_set(user, language, v->value);
12754 } else if (!strcasecmp(v->name, "amaflags")) {
12755 format = ast_cdr_amaflags2int(v->value);
12756 if (format < 0) {
12757 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12758 } else {
12759 user->amaflags = format;
12760 }
12761 } else if (!strcasecmp(v->name, "inkeys")) {
12762 ast_string_field_set(user, inkeys, v->value);
12763 } else if (!strcasecmp(v->name, "maxauthreq")) {
12764 user->maxauthreq = atoi(v->value);
12765 if (user->maxauthreq < 0)
12766 user->maxauthreq = 0;
12767 } else if (!strcasecmp(v->name, "adsi")) {
12768 user->adsi = ast_true(v->value);
12769 } else if (!strcasecmp(v->name, "connectedline")) {
12770 if (ast_true(v->value)) {
12771 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12772 } else if (!strcasecmp(v->value, "send")) {
12773 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12774 ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12775 } else if (!strcasecmp(v->value, "receive")) {
12776 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12777 ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12778 } else {
12779 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12780 }
12781 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12782
12783 if (ast_false(v->value)) {
12784 user->calltoken_required = CALLTOKEN_NO;
12785 } else if (!strcasecmp(v->value, "auto")) {
12786 user->calltoken_required = CALLTOKEN_AUTO;
12787 } else if (ast_true(v->value)) {
12788 user->calltoken_required = CALLTOKEN_YES;
12789 } else {
12790 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12791 }
12792 }
12793
12794 v = v->next;
12795 if (!v) {
12796 v = alt;
12797 alt = NULL;
12798 }
12799 }
12800 if (!user->authmethods) {
12801 if (!ast_strlen_zero(user->secret)) {
12802 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12803 if (!ast_strlen_zero(user->inkeys))
12804 user->authmethods |= IAX_AUTH_RSA;
12805 } else if (!ast_strlen_zero(user->inkeys)) {
12806 user->authmethods = IAX_AUTH_RSA;
12807 } else {
12808 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12809 }
12810 }
12811 ast_clear_flag64(user, IAX_DELME);
12812 }
12813 cleanup:
12814 if (oldha)
12815 ast_free_ha(oldha);
12816 if (oldcon)
12817 free_context(oldcon);
12818 return user;
12819 }
12820
12821 static int peer_delme_cb(void *obj, void *arg, int flags)
12822 {
12823 struct iax2_peer *peer = obj;
12824
12825 ast_set_flag64(peer, IAX_DELME);
12826
12827 return 0;
12828 }
12829
12830 static int user_delme_cb(void *obj, void *arg, int flags)
12831 {
12832 struct iax2_user *user = obj;
12833
12834 ast_set_flag64(user, IAX_DELME);
12835
12836 return 0;
12837 }
12838
12839 static void delete_users(void)
12840 {
12841 struct iax2_registry *reg;
12842
12843 ao2_callback(users, 0, user_delme_cb, NULL);
12844
12845 AST_LIST_LOCK(®istrations);
12846 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12847 if (sched) {
12848 ast_sched_thread_del(sched, reg->expire);
12849 }
12850 if (reg->callno) {
12851 int callno = reg->callno;
12852 ast_mutex_lock(&iaxsl[callno]);
12853 if (iaxs[callno]) {
12854 iaxs[callno]->reg = NULL;
12855 iax2_destroy(callno);
12856 }
12857 ast_mutex_unlock(&iaxsl[callno]);
12858 }
12859 if (reg->dnsmgr)
12860 ast_dnsmgr_release(reg->dnsmgr);
12861 ast_free(reg);
12862 }
12863 AST_LIST_UNLOCK(®istrations);
12864
12865 ao2_callback(peers, 0, peer_delme_cb, NULL);
12866 }
12867
12868 static void prune_users(void)
12869 {
12870 struct iax2_user *user;
12871 struct ao2_iterator i;
12872
12873 i = ao2_iterator_init(users, 0);
12874 while ((user = ao2_iterator_next(&i))) {
12875 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
12876 ao2_unlink(users, user);
12877 }
12878 user_unref(user);
12879 }
12880 ao2_iterator_destroy(&i);
12881 }
12882
12883
12884 static void prune_peers(void)
12885 {
12886 struct iax2_peer *peer;
12887 struct ao2_iterator i;
12888
12889 i = ao2_iterator_init(peers, 0);
12890 while ((peer = ao2_iterator_next(&i))) {
12891 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
12892 unlink_peer(peer);
12893 }
12894 peer_unref(peer);
12895 }
12896 ao2_iterator_destroy(&i);
12897 }
12898
12899 static void set_config_destroy(void)
12900 {
12901 strcpy(accountcode, "");
12902 strcpy(language, "");
12903 strcpy(mohinterpret, "default");
12904 strcpy(mohsuggest, "");
12905 trunkmaxsize = MAX_TRUNKDATA;
12906 amaflags = 0;
12907 delayreject = 0;
12908 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF |
12909 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12910 delete_users();
12911 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12912 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12913 }
12914
12915
12916 static int set_config(const char *config_file, int reload)
12917 {
12918 struct ast_config *cfg, *ucfg;
12919 format_t capability = iax2_capability;
12920 struct ast_variable *v;
12921 char *cat;
12922 const char *utype;
12923 const char *tosval;
12924 int format;
12925 int portno = IAX_DEFAULT_PORTNO;
12926 int x;
12927 int mtuv;
12928 int subscribe_network_change = 1;
12929 struct iax2_user *user;
12930 struct iax2_peer *peer;
12931 struct ast_netsock *ns;
12932 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12933 #if 0
12934 static unsigned short int last_port=0;
12935 #endif
12936
12937 cfg = ast_config_load(config_file, config_flags);
12938
12939 if (!cfg) {
12940 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12941 return -1;
12942 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12943 ucfg = ast_config_load("users.conf", config_flags);
12944 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12945 return 0;
12946
12947 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12948 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
12949 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12950 ast_config_destroy(ucfg);
12951 return 0;
12952 }
12953 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
12954 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12955 return 0;
12956 } else {
12957 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12958 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
12959 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
12960 ast_config_destroy(cfg);
12961 return 0;
12962 }
12963 }
12964
12965 if (reload) {
12966 set_config_destroy();
12967 }
12968
12969
12970 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12971
12972
12973 memset(&globalflags, 0, sizeof(globalflags));
12974 ast_set_flag64(&globalflags, IAX_RTUPDATE);
12975 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
12976
12977 #ifdef SO_NO_CHECK
12978 nochecksums = 0;
12979 #endif
12980
12981 default_parkinglot[0] = '\0';
12982
12983 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12984 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12985 global_max_trunk_mtu = MAX_TRUNK_MTU;
12986 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12987 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12988
12989 maxauthreq = 3;
12990
12991 srvlookup = 0;
12992
12993 v = ast_variable_browse(cfg, "general");
12994
12995
12996 tosval = ast_variable_retrieve(cfg, "general", "tos");
12997 if (tosval) {
12998 if (ast_str2tos(tosval, &qos.tos))
12999 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13000 }
13001
13002 tosval = ast_variable_retrieve(cfg, "general", "cos");
13003 if (tosval) {
13004 if (ast_str2cos(tosval, &qos.cos))
13005 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13006 }
13007 while(v) {
13008 if (!strcasecmp(v->name, "bindport")){
13009 if (reload)
13010 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13011 else
13012 portno = atoi(v->value);
13013 } else if (!strcasecmp(v->name, "pingtime"))
13014 ping_time = atoi(v->value);
13015 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13016 if (reload) {
13017 if (atoi(v->value) != iaxthreadcount)
13018 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13019 } else {
13020 iaxthreadcount = atoi(v->value);
13021 if (iaxthreadcount < 1) {
13022 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13023 iaxthreadcount = 1;
13024 } else if (iaxthreadcount > 256) {
13025 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13026 iaxthreadcount = 256;
13027 }
13028 }
13029 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13030 if (reload) {
13031 AST_LIST_LOCK(&dynamic_list);
13032 iaxmaxthreadcount = atoi(v->value);
13033 AST_LIST_UNLOCK(&dynamic_list);
13034 } else {
13035 iaxmaxthreadcount = atoi(v->value);
13036 if (iaxmaxthreadcount < 0) {
13037 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13038 iaxmaxthreadcount = 0;
13039 } else if (iaxmaxthreadcount > 256) {
13040 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13041 iaxmaxthreadcount = 256;
13042 }
13043 }
13044 } else if (!strcasecmp(v->name, "nochecksums")) {
13045 #ifdef SO_NO_CHECK
13046 if (ast_true(v->value))
13047 nochecksums = 1;
13048 else
13049 nochecksums = 0;
13050 #else
13051 if (ast_true(v->value))
13052 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13053 #endif
13054 }
13055 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13056 maxjitterbuffer = atoi(v->value);
13057 else if (!strcasecmp(v->name, "resyncthreshold"))
13058 resyncthreshold = atoi(v->value);
13059 else if (!strcasecmp(v->name, "maxjitterinterps"))
13060 maxjitterinterps = atoi(v->value);
13061 else if (!strcasecmp(v->name, "jittertargetextra"))
13062 jittertargetextra = atoi(v->value);
13063 else if (!strcasecmp(v->name, "lagrqtime"))
13064 lagrq_time = atoi(v->value);
13065 else if (!strcasecmp(v->name, "maxregexpire"))
13066 max_reg_expire = atoi(v->value);
13067 else if (!strcasecmp(v->name, "minregexpire"))
13068 min_reg_expire = atoi(v->value);
13069 else if (!strcasecmp(v->name, "bindaddr")) {
13070 if (reload) {
13071 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13072 } else {
13073 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13074 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13075 } else {
13076 if (strchr(v->value, ':'))
13077 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13078 else
13079 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13080 if (defaultsockfd < 0)
13081 defaultsockfd = ast_netsock_sockfd(ns);
13082 ast_netsock_unref(ns);
13083 }
13084 }
13085 } else if (!strcasecmp(v->name, "authdebug")) {
13086 authdebug = ast_true(v->value);
13087 } else if (!strcasecmp(v->name, "encryption")) {
13088 iax2_encryption |= get_encrypt_methods(v->value);
13089 if (!iax2_encryption) {
13090 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13091 }
13092 } else if (!strcasecmp(v->name, "forceencryption")) {
13093 if (ast_false(v->value)) {
13094 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13095 } else {
13096 iax2_encryption |= get_encrypt_methods(v->value);
13097 if (iax2_encryption) {
13098 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13099 }
13100 }
13101 } else if (!strcasecmp(v->name, "transfer")) {
13102 if (!strcasecmp(v->value, "mediaonly")) {
13103 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13104 } else if (ast_true(v->value)) {
13105 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13106 } else
13107 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13108 } else if (!strcasecmp(v->name, "codecpriority")) {
13109 if(!strcasecmp(v->value, "caller"))
13110 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13111 else if(!strcasecmp(v->value, "disabled"))
13112 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13113 else if(!strcasecmp(v->value, "reqonly")) {
13114 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13115 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13116 }
13117 } else if (!strcasecmp(v->name, "jitterbuffer"))
13118 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13119 else if (!strcasecmp(v->name, "forcejitterbuffer"))
13120 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13121 else if (!strcasecmp(v->name, "delayreject"))
13122 delayreject = ast_true(v->value);
13123 else if (!strcasecmp(v->name, "allowfwdownload"))
13124 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13125 else if (!strcasecmp(v->name, "rtcachefriends"))
13126 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13127 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13128 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13129 else if (!strcasecmp(v->name, "rtupdate"))
13130 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13131 else if (!strcasecmp(v->name, "rtsavesysname"))
13132 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13133 else if (!strcasecmp(v->name, "trunktimestamps"))
13134 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13135 else if (!strcasecmp(v->name, "rtautoclear")) {
13136 int i = atoi(v->value);
13137 if(i > 0)
13138 global_rtautoclear = i;
13139 else
13140 i = 0;
13141 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13142 } else if (!strcasecmp(v->name, "trunkfreq")) {
13143 trunkfreq = atoi(v->value);
13144 if (trunkfreq < 10)
13145 trunkfreq = 10;
13146 } else if (!strcasecmp(v->name, "trunkmtu")) {
13147 mtuv = atoi(v->value);
13148 if (mtuv == 0 )
13149 global_max_trunk_mtu = 0;
13150 else if (mtuv >= 172 && mtuv < 4000)
13151 global_max_trunk_mtu = mtuv;
13152 else
13153 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13154 mtuv, v->lineno);
13155 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13156 trunkmaxsize = atoi(v->value);
13157 if (trunkmaxsize == 0)
13158 trunkmaxsize = MAX_TRUNKDATA;
13159 } else if (!strcasecmp(v->name, "autokill")) {
13160 if (sscanf(v->value, "%30d", &x) == 1) {
13161 if (x >= 0)
13162 autokill = x;
13163 else
13164 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13165 } else if (ast_true(v->value)) {
13166 autokill = DEFAULT_MAXMS;
13167 } else {
13168 autokill = 0;
13169 }
13170 } else if (!strcasecmp(v->name, "bandwidth")) {
13171 if (!strcasecmp(v->value, "low")) {
13172 capability = IAX_CAPABILITY_LOWBANDWIDTH;
13173 } else if (!strcasecmp(v->value, "medium")) {
13174 capability = IAX_CAPABILITY_MEDBANDWIDTH;
13175 } else if (!strcasecmp(v->value, "high")) {
13176 capability = IAX_CAPABILITY_FULLBANDWIDTH;
13177 } else
13178 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13179 } else if (!strcasecmp(v->name, "allow")) {
13180 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13181 } else if (!strcasecmp(v->name, "disallow")) {
13182 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13183 } else if (!strcasecmp(v->name, "register")) {
13184 iax2_register(v->value, v->lineno);
13185 } else if (!strcasecmp(v->name, "iaxcompat")) {
13186 iaxcompat = ast_true(v->value);
13187 } else if (!strcasecmp(v->name, "regcontext")) {
13188 ast_copy_string(regcontext, v->value, sizeof(regcontext));
13189
13190 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13191 } else if (!strcasecmp(v->name, "tos")) {
13192 if (ast_str2tos(v->value, &qos.tos))
13193 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13194 } else if (!strcasecmp(v->name, "cos")) {
13195 if (ast_str2cos(v->value, &qos.cos))
13196 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13197 } else if (!strcasecmp(v->name, "parkinglot")) {
13198 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13199 } else if (!strcasecmp(v->name, "accountcode")) {
13200 ast_copy_string(accountcode, v->value, sizeof(accountcode));
13201 } else if (!strcasecmp(v->name, "mohinterpret")) {
13202 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13203 } else if (!strcasecmp(v->name, "mohsuggest")) {
13204 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13205 } else if (!strcasecmp(v->name, "amaflags")) {
13206 format = ast_cdr_amaflags2int(v->value);
13207 if (format < 0) {
13208 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13209 } else {
13210 amaflags = format;
13211 }
13212 } else if (!strcasecmp(v->name, "language")) {
13213 ast_copy_string(language, v->value, sizeof(language));
13214 } else if (!strcasecmp(v->name, "maxauthreq")) {
13215 maxauthreq = atoi(v->value);
13216 if (maxauthreq < 0)
13217 maxauthreq = 0;
13218 } else if (!strcasecmp(v->name, "adsi")) {
13219 adsi = ast_true(v->value);
13220 } else if (!strcasecmp(v->name, "srvlookup")) {
13221 srvlookup = ast_true(v->value);
13222 } else if (!strcasecmp(v->name, "connectedline")) {
13223 if (ast_true(v->value)) {
13224 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13225 } else if (!strcasecmp(v->value, "send")) {
13226 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13227 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13228 } else if (!strcasecmp(v->value, "receive")) {
13229 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13230 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13231 } else {
13232 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13233 }
13234 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13235 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13236 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
13237 }
13238 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13239 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13240 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);
13241 }
13242 } else if (!strcasecmp(v->name, "calltokenoptional")) {
13243 if (add_calltoken_ignore(v->value)) {
13244 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13245 }
13246 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13247 if (ast_true(v->value)) {
13248 subscribe_network_change = 1;
13249 } else if (ast_false(v->value)) {
13250 subscribe_network_change = 0;
13251 } else {
13252 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13253 }
13254 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13255 if (ast_true(v->value)) {
13256 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13257 } else if (ast_false(v->value)) {
13258 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13259 } else {
13260 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13261 }
13262 }
13263
13264 v = v->next;
13265 }
13266
13267 if (subscribe_network_change) {
13268 network_change_event_subscribe();
13269 } else {
13270 network_change_event_unsubscribe();
13271 }
13272
13273 if (defaultsockfd < 0) {
13274 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13275 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13276 } else {
13277 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13278 defaultsockfd = ast_netsock_sockfd(ns);
13279 ast_netsock_unref(ns);
13280 }
13281 }
13282 if (reload) {
13283 ast_netsock_release(outsock);
13284 outsock = ast_netsock_list_alloc();
13285 if (!outsock) {
13286 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13287 return -1;
13288 }
13289 ast_netsock_init(outsock);
13290 }
13291
13292 if (min_reg_expire > max_reg_expire) {
13293 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13294 min_reg_expire, max_reg_expire, max_reg_expire);
13295 min_reg_expire = max_reg_expire;
13296 }
13297 iax2_capability = capability;
13298
13299 if (ucfg) {
13300 struct ast_variable *gen;
13301 int genhasiax;
13302 int genregisteriax;
13303 const char *hasiax, *registeriax;
13304
13305 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13306 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13307 gen = ast_variable_browse(ucfg, "general");
13308 cat = ast_category_browse(ucfg, NULL);
13309 while (cat) {
13310 if (strcasecmp(cat, "general")) {
13311 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13312 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13313 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13314
13315 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13316 if (user) {
13317 ao2_link(users, user);
13318 user = user_unref(user);
13319 }
13320 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13321 if (peer) {
13322 if (ast_test_flag64(peer, IAX_DYNAMIC))
13323 reg_source_db(peer);
13324 ao2_link(peers, peer);
13325 peer = peer_unref(peer);
13326 }
13327 }
13328 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13329 char tmp[256];
13330 const char *host = ast_variable_retrieve(ucfg, cat, "host");
13331 const char *username = ast_variable_retrieve(ucfg, cat, "username");
13332 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13333 if (!host)
13334 host = ast_variable_retrieve(ucfg, "general", "host");
13335 if (!username)
13336 username = ast_variable_retrieve(ucfg, "general", "username");
13337 if (!secret)
13338 secret = ast_variable_retrieve(ucfg, "general", "secret");
13339 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13340 if (!ast_strlen_zero(secret))
13341 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13342 else
13343 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13344 iax2_register(tmp, 0);
13345 }
13346 }
13347 }
13348 cat = ast_category_browse(ucfg, cat);
13349 }
13350 ast_config_destroy(ucfg);
13351 }
13352
13353 cat = ast_category_browse(cfg, NULL);
13354 while(cat) {
13355 if (strcasecmp(cat, "general")) {
13356 utype = ast_variable_retrieve(cfg, cat, "type");
13357 if (!strcasecmp(cat, "callnumberlimits")) {
13358 build_callno_limits(ast_variable_browse(cfg, cat));
13359 } else if (utype) {
13360 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13361 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13362 if (user) {
13363 ao2_link(users, user);
13364 user = user_unref(user);
13365 }
13366 }
13367 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13368 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13369 if (peer) {
13370 if (ast_test_flag64(peer, IAX_DYNAMIC))
13371 reg_source_db(peer);
13372 ao2_link(peers, peer);
13373 peer = peer_unref(peer);
13374 }
13375 } else if (strcasecmp(utype, "user")) {
13376 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13377 }
13378 } else
13379 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13380 }
13381 cat = ast_category_browse(cfg, cat);
13382 }
13383 ast_config_destroy(cfg);
13384 return 1;
13385 }
13386
13387 static void poke_all_peers(void)
13388 {
13389 struct ao2_iterator i;
13390 struct iax2_peer *peer;
13391
13392 i = ao2_iterator_init(peers, 0);
13393 while ((peer = ao2_iterator_next(&i))) {
13394 iax2_poke_peer(peer, 0);
13395 peer_unref(peer);
13396 }
13397 ao2_iterator_destroy(&i);
13398 }
13399 static int reload_config(void)
13400 {
13401 static const char config[] = "iax.conf";
13402 struct iax2_registry *reg;
13403
13404 if (set_config(config, 1) > 0) {
13405 prune_peers();
13406 prune_users();
13407 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13408 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13409 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13410 trunk_timed = trunk_untimed = 0;
13411 trunk_nmaxmtu = trunk_maxmtu = 0;
13412 memset(&debugaddr, '\0', sizeof(debugaddr));
13413
13414 AST_LIST_LOCK(®istrations);
13415 AST_LIST_TRAVERSE(®istrations, reg, entry)
13416 iax2_do_register(reg);
13417 AST_LIST_UNLOCK(®istrations);
13418
13419
13420 poke_all_peers();
13421 }
13422
13423 reload_firmware(0);
13424 iax_provision_reload(1);
13425 ast_unload_realtime("iaxpeers");
13426
13427 return 0;
13428 }
13429
13430 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13431 {
13432 switch (cmd) {
13433 case CLI_INIT:
13434 e->command = "iax2 reload";
13435 e->usage =
13436 "Usage: iax2 reload\n"
13437 " Reloads IAX configuration from iax.conf\n";
13438 return NULL;
13439 case CLI_GENERATE:
13440 return NULL;
13441 }
13442
13443 reload_config();
13444
13445 return CLI_SUCCESS;
13446 }
13447
13448 static int reload(void)
13449 {
13450 return reload_config();
13451 }
13452
13453 static int cache_get_callno_locked(const char *data)
13454 {
13455 struct sockaddr_in sin;
13456 int x;
13457 int callno;
13458 struct iax_ie_data ied;
13459 struct create_addr_info cai;
13460 struct parsed_dial_string pds;
13461 char *tmpstr;
13462
13463 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13464
13465
13466 if (!ast_mutex_trylock(&iaxsl[x])) {
13467 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13468 return x;
13469 ast_mutex_unlock(&iaxsl[x]);
13470 }
13471 }
13472
13473
13474
13475 memset(&cai, 0, sizeof(cai));
13476 memset(&ied, 0, sizeof(ied));
13477 memset(&pds, 0, sizeof(pds));
13478
13479 tmpstr = ast_strdupa(data);
13480 parse_dial_string(tmpstr, &pds);
13481
13482 if (ast_strlen_zero(pds.peer)) {
13483 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13484 return -1;
13485 }
13486
13487
13488 if (create_addr(pds.peer, NULL, &sin, &cai))
13489 return -1;
13490
13491 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13492 pds.peer, pds.username, pds.password, pds.context);
13493
13494 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13495 if (callno < 1) {
13496 ast_log(LOG_WARNING, "Unable to create call\n");
13497 return -1;
13498 }
13499
13500 ast_string_field_set(iaxs[callno], dproot, data);
13501 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13502
13503 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13504 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13505
13506
13507
13508 if (pds.exten)
13509 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13510 if (pds.username)
13511 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13512 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13513 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13514
13515 if (pds.password)
13516 ast_string_field_set(iaxs[callno], secret, pds.password);
13517 if (pds.key)
13518 ast_string_field_set(iaxs[callno], outkey, pds.key);
13519
13520 add_empty_calltoken_ie(iaxs[callno], &ied);
13521 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13522
13523 return callno;
13524 }
13525
13526 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13527 {
13528 struct iax2_dpcache *dp = NULL;
13529 struct timeval now = ast_tvnow();
13530 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13531 struct ast_channel *c = NULL;
13532 struct ast_frame *f = NULL;
13533
13534 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13535 if (ast_tvcmp(now, dp->expiry) > 0) {
13536 AST_LIST_REMOVE_CURRENT(cache_list);
13537 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13538 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13539 else
13540 ast_free(dp);
13541 continue;
13542 }
13543 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13544 break;
13545 }
13546 AST_LIST_TRAVERSE_SAFE_END;
13547
13548 if (!dp) {
13549
13550
13551 if ((callno = cache_get_callno_locked(data)) < 0) {
13552 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13553 return NULL;
13554 }
13555 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13556 ast_mutex_unlock(&iaxsl[callno]);
13557 return NULL;
13558 }
13559 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13560 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13561 dp->expiry = ast_tvnow();
13562 dp->orig = dp->expiry;
13563
13564 dp->expiry.tv_sec += iaxdefaultdpcache;
13565 dp->flags = CACHE_FLAG_PENDING;
13566 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13567 dp->waiters[x] = -1;
13568
13569 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13570 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13571
13572 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13573 iax2_dprequest(dp, callno);
13574 ast_mutex_unlock(&iaxsl[callno]);
13575 }
13576
13577
13578 if (dp->flags & CACHE_FLAG_PENDING) {
13579
13580
13581 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13582
13583 if (dp->waiters[x] < 0)
13584 break;
13585 }
13586 if (x >= ARRAY_LEN(dp->waiters)) {
13587 ast_log(LOG_WARNING, "No more waiter positions available\n");
13588 return NULL;
13589 }
13590 if (pipe(com)) {
13591 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13592 return NULL;
13593 }
13594 dp->waiters[x] = com[1];
13595
13596 timeout = iaxdefaulttimeout * 1000;
13597
13598 AST_LIST_UNLOCK(&dpcache);
13599
13600 if (chan)
13601 old = ast_channel_defer_dtmf(chan);
13602 doabort = 0;
13603 while(timeout) {
13604 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13605 if (outfd > -1)
13606 break;
13607 if (!c)
13608 continue;
13609 if (!(f = ast_read(c))) {
13610 doabort = 1;
13611 break;
13612 }
13613 ast_frfree(f);
13614 }
13615 if (!timeout) {
13616 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13617 }
13618 AST_LIST_LOCK(&dpcache);
13619 dp->waiters[x] = -1;
13620 close(com[1]);
13621 close(com[0]);
13622 if (doabort) {
13623
13624
13625 if (!old && chan)
13626 ast_channel_undefer_dtmf(chan);
13627 return NULL;
13628 }
13629 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13630
13631 if (dp->flags & CACHE_FLAG_PENDING) {
13632
13633
13634 dp->flags &= ~CACHE_FLAG_PENDING;
13635 dp->flags |= CACHE_FLAG_TIMEOUT;
13636
13637
13638 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13639 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13640 if (dp->waiters[x] > -1) {
13641 if (write(dp->waiters[x], "asdf", 4) < 0) {
13642 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13643 }
13644 }
13645 }
13646 }
13647 }
13648
13649 if (!old && chan)
13650 ast_channel_undefer_dtmf(chan);
13651 }
13652 return dp;
13653 }
13654
13655
13656 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13657 {
13658 int res = 0;
13659 struct iax2_dpcache *dp = NULL;
13660 #if 0
13661 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13662 #endif
13663 if ((priority != 1) && (priority != 2))
13664 return 0;
13665
13666 AST_LIST_LOCK(&dpcache);
13667 if ((dp = find_cache(chan, data, context, exten, priority))) {
13668 if (dp->flags & CACHE_FLAG_EXISTS)
13669 res = 1;
13670 } else {
13671 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13672 }
13673 AST_LIST_UNLOCK(&dpcache);
13674
13675 return res;
13676 }
13677
13678
13679 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13680 {
13681 int res = 0;
13682 struct iax2_dpcache *dp = NULL;
13683 #if 0
13684 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13685 #endif
13686 if ((priority != 1) && (priority != 2))
13687 return 0;
13688
13689 AST_LIST_LOCK(&dpcache);
13690 if ((dp = find_cache(chan, data, context, exten, priority))) {
13691 if (dp->flags & CACHE_FLAG_CANEXIST)
13692 res = 1;
13693 } else {
13694 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13695 }
13696 AST_LIST_UNLOCK(&dpcache);
13697
13698 return res;
13699 }
13700
13701
13702 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13703 {
13704 int res = 0;
13705 struct iax2_dpcache *dp = NULL;
13706 #if 0
13707 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13708 #endif
13709 if ((priority != 1) && (priority != 2))
13710 return 0;
13711
13712 AST_LIST_LOCK(&dpcache);
13713 if ((dp = find_cache(chan, data, context, exten, priority))) {
13714 if (dp->flags & CACHE_FLAG_MATCHMORE)
13715 res = 1;
13716 } else {
13717 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13718 }
13719 AST_LIST_UNLOCK(&dpcache);
13720
13721 return res;
13722 }
13723
13724
13725 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13726 {
13727 char odata[256];
13728 char req[256];
13729 char *ncontext;
13730 struct iax2_dpcache *dp = NULL;
13731 struct ast_app *dial = NULL;
13732 #if 0
13733 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);
13734 #endif
13735 if (priority == 2) {
13736
13737 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13738 if (dialstatus) {
13739 dial = pbx_findapp(dialstatus);
13740 if (dial)
13741 pbx_exec(chan, dial, "");
13742 }
13743 return -1;
13744 } else if (priority != 1)
13745 return -1;
13746
13747 AST_LIST_LOCK(&dpcache);
13748 if ((dp = find_cache(chan, data, context, exten, priority))) {
13749 if (dp->flags & CACHE_FLAG_EXISTS) {
13750 ast_copy_string(odata, data, sizeof(odata));
13751 ncontext = strchr(odata, '/');
13752 if (ncontext) {
13753 *ncontext = '\0';
13754 ncontext++;
13755 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13756 } else {
13757 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13758 }
13759 ast_verb(3, "Executing Dial('%s')\n", req);
13760 } else {
13761 AST_LIST_UNLOCK(&dpcache);
13762 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13763 return -1;
13764 }
13765 }
13766 AST_LIST_UNLOCK(&dpcache);
13767
13768 if ((dial = pbx_findapp("Dial")))
13769 return pbx_exec(chan, dial, req);
13770 else
13771 ast_log(LOG_WARNING, "No dial application registered\n");
13772
13773 return -1;
13774 }
13775
13776 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13777 {
13778 struct iax2_peer *peer;
13779 char *peername, *colname;
13780
13781 peername = ast_strdupa(data);
13782
13783
13784 if (!strcmp(peername,"CURRENTCHANNEL")) {
13785 unsigned short callno;
13786 if (chan->tech != &iax2_tech)
13787 return -1;
13788 callno = PTR_TO_CALLNO(chan->tech_pvt);
13789 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13790 return 0;
13791 }
13792
13793 if ((colname = strchr(peername, ',')))
13794 *colname++ = '\0';
13795 else
13796 colname = "ip";
13797
13798 if (!(peer = find_peer(peername, 1)))
13799 return -1;
13800
13801 if (!strcasecmp(colname, "ip")) {
13802 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13803 } else if (!strcasecmp(colname, "status")) {
13804 peer_status(peer, buf, len);
13805 } else if (!strcasecmp(colname, "mailbox")) {
13806 ast_copy_string(buf, peer->mailbox, len);
13807 } else if (!strcasecmp(colname, "context")) {
13808 ast_copy_string(buf, peer->context, len);
13809 } else if (!strcasecmp(colname, "expire")) {
13810 snprintf(buf, len, "%d", peer->expire);
13811 } else if (!strcasecmp(colname, "dynamic")) {
13812 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13813 } else if (!strcasecmp(colname, "callerid_name")) {
13814 ast_copy_string(buf, peer->cid_name, len);
13815 } else if (!strcasecmp(colname, "callerid_num")) {
13816 ast_copy_string(buf, peer->cid_num, len);
13817 } else if (!strcasecmp(colname, "codecs")) {
13818 ast_getformatname_multiple(buf, len -1, peer->capability);
13819 } else if (!strncasecmp(colname, "codec[", 6)) {
13820 char *codecnum, *ptr;
13821 int codec = 0;
13822
13823 codecnum = strchr(colname, '[');
13824 *codecnum = '\0';
13825 codecnum++;
13826 if ((ptr = strchr(codecnum, ']'))) {
13827 *ptr = '\0';
13828 }
13829 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13830 ast_copy_string(buf, ast_getformatname(codec), len);
13831 } else {
13832 buf[0] = '\0';
13833 }
13834 } else {
13835 buf[0] = '\0';
13836 }
13837
13838 peer_unref(peer);
13839
13840 return 0;
13841 }
13842
13843 static struct ast_custom_function iaxpeer_function = {
13844 .name = "IAXPEER",
13845 .read = function_iaxpeer,
13846 };
13847
13848 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13849 {
13850 struct chan_iax2_pvt *pvt;
13851 unsigned int callno;
13852 int res = 0;
13853
13854 if (!chan || chan->tech != &iax2_tech) {
13855 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13856 return -1;
13857 }
13858
13859 callno = PTR_TO_CALLNO(chan->tech_pvt);
13860 ast_mutex_lock(&iaxsl[callno]);
13861 if (!(pvt = iaxs[callno])) {
13862 ast_mutex_unlock(&iaxsl[callno]);
13863 return -1;
13864 }
13865
13866 if (!strcasecmp(args, "osptoken")) {
13867 ast_copy_string(buf, pvt->osptoken, buflen);
13868 } else if (!strcasecmp(args, "peerip")) {
13869 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13870 } else if (!strcasecmp(args, "peername")) {
13871 ast_copy_string(buf, pvt->username, buflen);
13872 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
13873 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
13874 } else {
13875 res = -1;
13876 }
13877
13878 ast_mutex_unlock(&iaxsl[callno]);
13879
13880 return res;
13881 }
13882
13883
13884 static int iax2_devicestate(void *data)
13885 {
13886 struct parsed_dial_string pds;
13887 char *tmp = ast_strdupa(data);
13888 struct iax2_peer *p;
13889 int res = AST_DEVICE_INVALID;
13890
13891 memset(&pds, 0, sizeof(pds));
13892 parse_dial_string(tmp, &pds);
13893
13894 if (ast_strlen_zero(pds.peer)) {
13895 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13896 return res;
13897 }
13898
13899 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13900
13901
13902 if (!(p = find_peer(pds.peer, 1)))
13903 return res;
13904
13905 res = AST_DEVICE_UNAVAILABLE;
13906 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13907 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13908
13909 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
13910 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13911
13912
13913 if (p->historicms == 0 || p->historicms <= p->maxms)
13914
13915 res = AST_DEVICE_UNKNOWN;
13916 }
13917
13918 peer_unref(p);
13919
13920 return res;
13921 }
13922
13923 static struct ast_switch iax2_switch =
13924 {
13925 name: "IAX2",
13926 description: "IAX Remote Dialplan Switch",
13927 exists: iax2_exists,
13928 canmatch: iax2_canmatch,
13929 exec: iax2_exec,
13930 matchmore: iax2_matchmore,
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
14028
14029
14030
14031
14032
14033
14034
14035
14036
14037 static struct ast_cli_entry cli_iax2[] = {
14038 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14039 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14040 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14041 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14042 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14043 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14044 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14045 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14046 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14047 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14048 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14049 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14050 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14051 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14052 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14053 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14054 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14055 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14056 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14057 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14058 #ifdef IAXTESTS
14059 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14060 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14061 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14062 #endif
14063 };
14064
14065 #ifdef TEST_FRAMEWORK
14066 AST_TEST_DEFINE(test_iax2_peers_get)
14067 {
14068 struct ast_data_query query = {
14069 .path = "/asterisk/channel/iax2/peers",
14070 .search = "peers/peer/name=test_peer_data_provider"
14071 };
14072 struct ast_data *node;
14073 struct iax2_peer *peer;
14074
14075 switch (cmd) {
14076 case TEST_INIT:
14077 info->name = "iax2_peers_get_data_test";
14078 info->category = "/main/data/iax2/peers/";
14079 info->summary = "IAX2 peers data providers unit test";
14080 info->description =
14081 "Tests whether the IAX2 peers data provider implementation works as expected.";
14082 return AST_TEST_NOT_RUN;
14083 case TEST_EXECUTE:
14084 break;
14085 }
14086
14087
14088 peer = build_peer("test_peer_data_provider", NULL, NULL, 0);
14089 if (!peer) {
14090 return AST_TEST_FAIL;
14091 }
14092 peer->expiry= 1010;
14093 ao2_link(peers, peer);
14094
14095 node = ast_data_get(&query);
14096 if (!node) {
14097 ao2_unlink(peers, peer);
14098 peer_unref(peer);
14099 return AST_TEST_FAIL;
14100 }
14101
14102
14103 if (strcmp(ast_data_retrieve_string(node, "peer/name"), "test_peer_data_provider")) {
14104 ao2_unlink(peers, peer);
14105 peer_unref(peer);
14106 ast_data_free(node);
14107 return AST_TEST_FAIL;
14108 }
14109
14110 if (ast_data_retrieve_int(node, "peer/expiry") != 1010) {
14111 ao2_unlink(peers, peer);
14112 peer_unref(peer);
14113 ast_data_free(node);
14114 return AST_TEST_FAIL;
14115 }
14116
14117
14118 ast_data_free(node);
14119
14120 ao2_unlink(peers, peer);
14121 peer_unref(peer);
14122
14123 return AST_TEST_PASS;
14124 }
14125
14126 AST_TEST_DEFINE(test_iax2_users_get)
14127 {
14128 struct ast_data_query query = {
14129 .path = "/asterisk/channel/iax2/users",
14130 .search = "users/user/name=test_user_data_provider"
14131 };
14132 struct ast_data *node;
14133 struct iax2_user *user;
14134
14135 switch (cmd) {
14136 case TEST_INIT:
14137 info->name = "iax2_users_get_data_test";
14138 info->category = "/main/data/iax2/users/";
14139 info->summary = "IAX2 users data providers unit test";
14140 info->description =
14141 "Tests whether the IAX2 users data provider implementation works as expected.";
14142 return AST_TEST_NOT_RUN;
14143 case TEST_EXECUTE:
14144 break;
14145 }
14146
14147 user = build_user("test_user_data_provider", NULL, NULL, 0);
14148 if (!user) {
14149 ast_test_status_update(test, "Failed to build a test user\n");
14150 return AST_TEST_FAIL;
14151 }
14152 user->amaflags = 1010;
14153 ao2_link(users, user);
14154
14155 node = ast_data_get(&query);
14156 if (!node) {
14157 ast_test_status_update(test, "The data query to find our test user failed\n");
14158 ao2_unlink(users, user);
14159 user_unref(user);
14160 return AST_TEST_FAIL;
14161 }
14162
14163 if (strcmp(ast_data_retrieve_string(node, "user/name"), "test_user_data_provider")) {
14164 ast_test_status_update(test, "Our data results did not return the test user created in the previous step.\n");
14165 ao2_unlink(users, user);
14166 user_unref(user);
14167 ast_data_free(node);
14168 return AST_TEST_FAIL;
14169 }
14170
14171 if (ast_data_retrieve_int(node, "user/amaflags/value") != 1010) {
14172 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"));
14173 ao2_unlink(users, user);
14174 user_unref(user);
14175 ast_data_free(node);
14176 return AST_TEST_FAIL;
14177 }
14178
14179 ast_data_free(node);
14180
14181 ao2_unlink(users, user);
14182 user_unref(user);
14183
14184 return AST_TEST_PASS;
14185 }
14186 #endif
14187
14188 static void cleanup_thread_list(void *head)
14189 {
14190 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14191 struct iax2_thread_list *list_head = head;
14192 struct iax2_thread *thread;
14193
14194 AST_LIST_LOCK(list_head);
14195 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14196 pthread_t thread_id = thread->threadid;
14197
14198 thread->stop = 1;
14199 signal_condition(&thread->lock, &thread->cond);
14200
14201 AST_LIST_UNLOCK(list_head);
14202 pthread_join(thread_id, NULL);
14203 AST_LIST_LOCK(list_head);
14204 }
14205 AST_LIST_UNLOCK(list_head);
14206 }
14207
14208 static int __unload_module(void)
14209 {
14210 struct ast_context *con;
14211 int x;
14212
14213 network_change_event_unsubscribe();
14214
14215 ast_manager_unregister("IAXpeers");
14216 ast_manager_unregister("IAXpeerlist");
14217 ast_manager_unregister("IAXnetstats");
14218 ast_manager_unregister("IAXregistry");
14219 ast_unregister_application(papp);
14220 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14221 ast_unregister_switch(&iax2_switch);
14222 ast_channel_unregister(&iax2_tech);
14223
14224 if (netthreadid != AST_PTHREADT_NULL) {
14225 pthread_cancel(netthreadid);
14226 pthread_kill(netthreadid, SIGURG);
14227 pthread_join(netthreadid, NULL);
14228 }
14229
14230 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14231 if (iaxs[x]) {
14232 iax2_destroy(x);
14233 }
14234 }
14235
14236
14237 cleanup_thread_list(&idle_list);
14238 cleanup_thread_list(&active_list);
14239 cleanup_thread_list(&dynamic_list);
14240
14241 ast_netsock_release(netsock);
14242 ast_netsock_release(outsock);
14243 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14244 if (iaxs[x]) {
14245 iax2_destroy(x);
14246 }
14247 }
14248 ast_manager_unregister( "IAXpeers" );
14249 ast_manager_unregister( "IAXpeerlist" );
14250 ast_manager_unregister( "IAXnetstats" );
14251 ast_manager_unregister( "IAXregistry" );
14252 ast_unregister_application(papp);
14253 #ifdef TEST_FRAMEWORK
14254 AST_TEST_UNREGISTER(test_iax2_peers_get);
14255 AST_TEST_UNREGISTER(test_iax2_users_get);
14256 #endif
14257 ast_data_unregister(NULL);
14258 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14259 ast_unregister_switch(&iax2_switch);
14260 ast_channel_unregister(&iax2_tech);
14261 delete_users();
14262 iax_provision_unload();
14263 reload_firmware(1);
14264
14265 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14266 ast_mutex_destroy(&iaxsl[x]);
14267 }
14268
14269 ao2_ref(peers, -1);
14270 ao2_ref(users, -1);
14271 ao2_ref(iax_peercallno_pvts, -1);
14272 ao2_ref(iax_transfercallno_pvts, -1);
14273 ao2_ref(peercnts, -1);
14274 ao2_ref(callno_limits, -1);
14275 ao2_ref(calltoken_ignores, -1);
14276 ao2_ref(callno_pool, -1);
14277 ao2_ref(callno_pool_trunk, -1);
14278 if (timer) {
14279 ast_timer_close(timer);
14280 }
14281 transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14282 sched = ast_sched_thread_destroy(sched);
14283
14284 con = ast_context_find(regcontext);
14285 if (con)
14286 ast_context_destroy(con, "IAX2");
14287 ast_unload_realtime("iaxpeers");
14288 return 0;
14289 }
14290
14291 static int unload_module(void)
14292 {
14293 ast_custom_function_unregister(&iaxpeer_function);
14294 ast_custom_function_unregister(&iaxvar_function);
14295 return __unload_module();
14296 }
14297
14298 static int peer_set_sock_cb(void *obj, void *arg, int flags)
14299 {
14300 struct iax2_peer *peer = obj;
14301
14302 if (peer->sockfd < 0)
14303 peer->sockfd = defaultsockfd;
14304
14305 return 0;
14306 }
14307
14308 static int pvt_hash_cb(const void *obj, const int flags)
14309 {
14310 const struct chan_iax2_pvt *pvt = obj;
14311
14312 return pvt->peercallno;
14313 }
14314
14315 static int pvt_cmp_cb(void *obj, void *arg, int flags)
14316 {
14317 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14318
14319
14320
14321
14322 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14323 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14324 }
14325
14326 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14327 {
14328 const struct chan_iax2_pvt *pvt = obj;
14329
14330 return pvt->transfercallno;
14331 }
14332
14333 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14334 {
14335 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14336
14337
14338
14339
14340 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14341 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14342 }
14343
14344 static int load_objects(void)
14345 {
14346 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14347 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14348
14349 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14350 goto container_fail;
14351 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14352 goto container_fail;
14353 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14354 goto container_fail;
14355 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14356 goto container_fail;
14357 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14358 goto container_fail;
14359 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14360 goto container_fail;
14361 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14362 goto container_fail;
14363 } else if (create_callno_pools()) {
14364 goto container_fail;
14365 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14366 goto container_fail;
14367 }
14368
14369 return 0;
14370
14371 container_fail:
14372 if (peers) {
14373 ao2_ref(peers, -1);
14374 }
14375 if (users) {
14376 ao2_ref(users, -1);
14377 }
14378 if (iax_peercallno_pvts) {
14379 ao2_ref(iax_peercallno_pvts, -1);
14380 }
14381 if (iax_transfercallno_pvts) {
14382 ao2_ref(iax_transfercallno_pvts, -1);
14383 }
14384 if (peercnts) {
14385 ao2_ref(peercnts, -1);
14386 }
14387 if (callno_limits) {
14388 ao2_ref(callno_limits, -1);
14389 }
14390 if (calltoken_ignores) {
14391 ao2_ref(calltoken_ignores, -1);
14392 }
14393 if (callno_pool) {
14394 ao2_ref(callno_pool, -1);
14395 }
14396 if (callno_pool_trunk) {
14397 ao2_ref(callno_pool_trunk, -1);
14398 }
14399 return AST_MODULE_LOAD_FAILURE;
14400 }
14401
14402
14403 #define DATA_EXPORT_IAX2_PEER(MEMBER) \
14404 MEMBER(iax2_peer, name, AST_DATA_STRING) \
14405 MEMBER(iax2_peer, username, AST_DATA_STRING) \
14406 MEMBER(iax2_peer, secret, AST_DATA_PASSWORD) \
14407 MEMBER(iax2_peer, dbsecret, AST_DATA_PASSWORD) \
14408 MEMBER(iax2_peer, outkey, AST_DATA_STRING) \
14409 MEMBER(iax2_peer, regexten, AST_DATA_STRING) \
14410 MEMBER(iax2_peer, context, AST_DATA_STRING) \
14411 MEMBER(iax2_peer, peercontext, AST_DATA_STRING) \
14412 MEMBER(iax2_peer, mailbox, AST_DATA_STRING) \
14413 MEMBER(iax2_peer, mohinterpret, AST_DATA_STRING) \
14414 MEMBER(iax2_peer, mohsuggest, AST_DATA_STRING) \
14415 MEMBER(iax2_peer, inkeys, AST_DATA_STRING) \
14416 MEMBER(iax2_peer, cid_num, AST_DATA_STRING) \
14417 MEMBER(iax2_peer, cid_name, AST_DATA_STRING) \
14418 MEMBER(iax2_peer, zonetag, AST_DATA_STRING) \
14419 MEMBER(iax2_peer, parkinglot, AST_DATA_STRING) \
14420 MEMBER(iax2_peer, expiry, AST_DATA_SECONDS) \
14421 MEMBER(iax2_peer, callno, AST_DATA_INTEGER) \
14422 MEMBER(iax2_peer, lastms, AST_DATA_MILLISECONDS) \
14423 MEMBER(iax2_peer, maxms, AST_DATA_MILLISECONDS) \
14424 MEMBER(iax2_peer, pokefreqok, AST_DATA_MILLISECONDS) \
14425 MEMBER(iax2_peer, pokefreqnotok, AST_DATA_MILLISECONDS) \
14426 MEMBER(iax2_peer, historicms, AST_DATA_INTEGER) \
14427 MEMBER(iax2_peer, smoothing, AST_DATA_BOOLEAN) \
14428 MEMBER(iax2_peer, maxcallno, AST_DATA_INTEGER)
14429
14430 AST_DATA_STRUCTURE(iax2_peer, DATA_EXPORT_IAX2_PEER);
14431
14432 static int peers_data_provider_get(const struct ast_data_search *search,
14433 struct ast_data *data_root)
14434 {
14435 struct ast_data *data_peer;
14436 struct iax2_peer *peer;
14437 struct ao2_iterator i;
14438 char status[20];
14439 struct ast_str *encmethods = ast_str_alloca(256);
14440
14441 i = ao2_iterator_init(peers, 0);
14442 while ((peer = ao2_iterator_next(&i))) {
14443 data_peer = ast_data_add_node(data_root, "peer");
14444 if (!data_peer) {
14445 peer_unref(peer);
14446 continue;
14447 }
14448
14449 ast_data_add_structure(iax2_peer, data_peer, peer);
14450
14451 ast_data_add_codecs(data_peer, "codecs", peer->capability);
14452
14453 peer_status(peer, status, sizeof(status));
14454 ast_data_add_str(data_peer, "status", status);
14455
14456 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14457
14458 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14459
14460 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14461
14462 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14463
14464 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14465
14466 encmethods_to_str(peer->encmethods, encmethods);
14467 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14468
14469 peer_unref(peer);
14470
14471 if (!ast_data_search_match(search, data_peer)) {
14472 ast_data_remove_node(data_root, data_peer);
14473 }
14474 }
14475 ao2_iterator_destroy(&i);
14476
14477 return 0;
14478 }
14479
14480 #define DATA_EXPORT_IAX2_USER(MEMBER) \
14481 MEMBER(iax2_user, name, AST_DATA_STRING) \
14482 MEMBER(iax2_user, dbsecret, AST_DATA_PASSWORD) \
14483 MEMBER(iax2_user, accountcode, AST_DATA_STRING) \
14484 MEMBER(iax2_user, mohinterpret, AST_DATA_STRING) \
14485 MEMBER(iax2_user, mohsuggest, AST_DATA_STRING) \
14486 MEMBER(iax2_user, inkeys, AST_DATA_STRING) \
14487 MEMBER(iax2_user, language, AST_DATA_STRING) \
14488 MEMBER(iax2_user, cid_num, AST_DATA_STRING) \
14489 MEMBER(iax2_user, cid_name, AST_DATA_STRING) \
14490 MEMBER(iax2_user, parkinglot, AST_DATA_STRING) \
14491 MEMBER(iax2_user, maxauthreq, AST_DATA_INTEGER) \
14492 MEMBER(iax2_user, curauthreq, AST_DATA_INTEGER)
14493
14494 AST_DATA_STRUCTURE(iax2_user, DATA_EXPORT_IAX2_USER);
14495
14496 static int users_data_provider_get(const struct ast_data_search *search,
14497 struct ast_data *data_root)
14498 {
14499 struct ast_data *data_user, *data_authmethods, *data_enum_node;
14500 struct iax2_user *user;
14501 struct ao2_iterator i;
14502 char auth[90];
14503 char *pstr = "";
14504
14505 i = ao2_iterator_init(users, 0);
14506 while ((user = ao2_iterator_next(&i))) {
14507 data_user = ast_data_add_node(data_root, "user");
14508 if (!data_user) {
14509 user_unref(user);
14510 continue;
14511 }
14512
14513 ast_data_add_structure(iax2_user, data_user, user);
14514
14515 ast_data_add_codecs(data_user, "codecs", user->capability);
14516
14517 if (!ast_strlen_zero(user->secret)) {
14518 ast_copy_string(auth, user->secret, sizeof(auth));
14519 } else if (!ast_strlen_zero(user->inkeys)) {
14520 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14521 } else {
14522 ast_copy_string(auth, "no secret", sizeof(auth));
14523 }
14524 ast_data_add_password(data_user, "secret", auth);
14525
14526 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14527
14528
14529 data_authmethods = ast_data_add_node(data_user, "authmethods");
14530 if (!data_authmethods) {
14531 ast_data_remove_node(data_root, data_user);
14532 continue;
14533 }
14534 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14535 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14536 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14537
14538
14539 data_enum_node = ast_data_add_node(data_user, "amaflags");
14540 if (!data_enum_node) {
14541 ast_data_remove_node(data_root, data_user);
14542 continue;
14543 }
14544 ast_data_add_int(data_enum_node, "value", user->amaflags);
14545 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14546
14547 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14548
14549 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14550 pstr = "REQ only";
14551 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14552 pstr = "disabled";
14553 } else {
14554 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14555 }
14556 ast_data_add_str(data_user, "codec-preferences", pstr);
14557
14558 user_unref(user);
14559
14560 if (!ast_data_search_match(search, data_user)) {
14561 ast_data_remove_node(data_root, data_user);
14562 }
14563 }
14564 ao2_iterator_destroy(&i);
14565
14566 return 0;
14567 }
14568
14569 static const struct ast_data_handler peers_data_provider = {
14570 .version = AST_DATA_HANDLER_VERSION,
14571 .get = peers_data_provider_get
14572 };
14573
14574 static const struct ast_data_handler users_data_provider = {
14575 .version = AST_DATA_HANDLER_VERSION,
14576 .get = users_data_provider_get
14577 };
14578
14579 static const struct ast_data_entry iax2_data_providers[] = {
14580 AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
14581 AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
14582 };
14583
14584
14585 static int load_module(void)
14586 {
14587 static const char config[] = "iax.conf";
14588 int x = 0;
14589 struct iax2_registry *reg = NULL;
14590
14591 if (load_objects()) {
14592 return AST_MODULE_LOAD_FAILURE;
14593 }
14594
14595 memset(iaxs, 0, sizeof(iaxs));
14596
14597 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14598 ast_mutex_init(&iaxsl[x]);
14599 }
14600
14601 if (!(sched = ast_sched_thread_create())) {
14602 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14603 return AST_MODULE_LOAD_FAILURE;
14604 }
14605
14606 if (!(io = io_context_create())) {
14607 ast_log(LOG_ERROR, "Failed to create I/O context\n");
14608 sched = ast_sched_thread_destroy(sched);
14609 return AST_MODULE_LOAD_FAILURE;
14610 }
14611
14612 if (!(netsock = ast_netsock_list_alloc())) {
14613 ast_log(LOG_ERROR, "Failed to create netsock list\n");
14614 io_context_destroy(io);
14615 sched = ast_sched_thread_destroy(sched);
14616 return AST_MODULE_LOAD_FAILURE;
14617 }
14618 ast_netsock_init(netsock);
14619
14620 outsock = ast_netsock_list_alloc();
14621 if (!outsock) {
14622 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14623 io_context_destroy(io);
14624 sched = ast_sched_thread_destroy(sched);
14625 return AST_MODULE_LOAD_FAILURE;
14626 }
14627 ast_netsock_init(outsock);
14628
14629 randomcalltokendata = ast_random();
14630
14631 iax_set_output(iax_debug_output);
14632 iax_set_error(iax_error_output);
14633 jb_setoutput(jb_error_output, jb_warning_output, NULL);
14634
14635 if ((timer = ast_timer_open())) {
14636 ast_timer_set_rate(timer, trunkfreq);
14637 }
14638
14639 if (set_config(config, 0) == -1) {
14640 if (timer) {
14641 ast_timer_close(timer);
14642 }
14643 return AST_MODULE_LOAD_DECLINE;
14644 }
14645
14646 #ifdef TEST_FRAMEWORK
14647 AST_TEST_REGISTER(test_iax2_peers_get);
14648 AST_TEST_REGISTER(test_iax2_users_get);
14649 #endif
14650
14651
14652 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14653 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14654
14655 ast_register_application_xml(papp, iax2_prov_app);
14656
14657 ast_custom_function_register(&iaxpeer_function);
14658 ast_custom_function_register(&iaxvar_function);
14659
14660 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14661 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14662 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14663 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14664
14665 if (ast_channel_register(&iax2_tech)) {
14666 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14667 __unload_module();
14668 return AST_MODULE_LOAD_FAILURE;
14669 }
14670
14671 if (ast_register_switch(&iax2_switch)) {
14672 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14673 }
14674
14675 if (start_network_thread()) {
14676 ast_log(LOG_ERROR, "Unable to start network thread\n");
14677 __unload_module();
14678 return AST_MODULE_LOAD_FAILURE;
14679 } else {
14680 ast_verb(2, "IAX Ready and Listening\n");
14681 }
14682
14683 AST_LIST_LOCK(®istrations);
14684 AST_LIST_TRAVERSE(®istrations, reg, entry)
14685 iax2_do_register(reg);
14686 AST_LIST_UNLOCK(®istrations);
14687
14688 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14689 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14690
14691
14692 reload_firmware(0);
14693 iax_provision_reload(0);
14694
14695 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14696
14697 network_change_event_subscribe();
14698
14699 return AST_MODULE_LOAD_SUCCESS;
14700 }
14701
14702 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
14703 .load = load_module,
14704 .unload = unload_module,
14705 .reload = reload,
14706 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
14707 .nonoptreq = "res_crypto",
14708 );