00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "asterisk.h"
00040
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 367850 $")
00042
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <strings.h>
00054 #include <netdb.h>
00055 #include <fcntl.h>
00056 #include <sys/stat.h>
00057 #include <regex.h>
00058
00059 #include "asterisk/paths.h"
00060
00061 #include "asterisk/lock.h"
00062 #include "asterisk/frame.h"
00063 #include "asterisk/channel.h"
00064 #include "asterisk/module.h"
00065 #include "asterisk/pbx.h"
00066 #include "asterisk/sched.h"
00067 #include "asterisk/io.h"
00068 #include "asterisk/config.h"
00069 #include "asterisk/cli.h"
00070 #include "asterisk/translate.h"
00071 #include "asterisk/md5.h"
00072 #include "asterisk/cdr.h"
00073 #include "asterisk/crypto.h"
00074 #include "asterisk/acl.h"
00075 #include "asterisk/manager.h"
00076 #include "asterisk/callerid.h"
00077 #include "asterisk/app.h"
00078 #include "asterisk/astdb.h"
00079 #include "asterisk/musiconhold.h"
00080 #include "asterisk/features.h"
00081 #include "asterisk/utils.h"
00082 #include "asterisk/causes.h"
00083 #include "asterisk/localtime.h"
00084 #include "asterisk/dnsmgr.h"
00085 #include "asterisk/devicestate.h"
00086 #include "asterisk/netsock.h"
00087 #include "asterisk/stringfields.h"
00088 #include "asterisk/linkedlists.h"
00089 #include "asterisk/event.h"
00090 #include "asterisk/astobj2.h"
00091 #include "asterisk/timing.h"
00092 #include "asterisk/taskprocessor.h"
00093 #include "asterisk/test.h"
00094 #include "asterisk/data.h"
00095 #include "asterisk/netsock2.h"
00096
00097 #include "iax2.h"
00098 #include "iax2-parser.h"
00099 #include "iax2-provision.h"
00100 #include "jitterbuf.h"
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 #define SCHED_MULTITHREADED
00232
00233
00234
00235 #define DEBUG_SCHED_MULTITHREAD
00236
00237
00238 #ifdef SO_NO_CHECK
00239 static int nochecksums = 0;
00240 #endif
00241
00242 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00243 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00244
00245 #define DEFAULT_THREAD_COUNT 10
00246 #define DEFAULT_MAX_THREAD_COUNT 100
00247 #define DEFAULT_RETRY_TIME 1000
00248 #define MEMORY_SIZE 100
00249 #define DEFAULT_DROP 3
00250
00251 #define DEBUG_SUPPORT
00252
00253 #define MIN_REUSE_TIME 60
00254
00255
00256 #define GAMMA (0.01)
00257
00258 static struct ast_codec_pref prefs;
00259
00260 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00261
00262
00263
00264
00265 #define MAX_TRUNK_MTU 1240
00266
00267 static int global_max_trunk_mtu;
00268 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00269
00270 #define DEFAULT_CONTEXT "default"
00271
00272 static char default_parkinglot[AST_MAX_CONTEXT];
00273
00274 static char language[MAX_LANGUAGE] = "";
00275 static char regcontext[AST_MAX_CONTEXT] = "";
00276
00277 static struct ast_event_sub *network_change_event_subscription;
00278 static int network_change_event_sched_id = -1;
00279
00280 static int maxauthreq = 3;
00281 static int max_retries = 4;
00282 static int ping_time = 21;
00283 static int lagrq_time = 10;
00284 static int maxjitterbuffer=1000;
00285 static int resyncthreshold=1000;
00286 static int maxjitterinterps=10;
00287 static int jittertargetextra = 40;
00288
00289 #define MAX_TRUNKDATA 640 * 200
00290
00291 static int trunkfreq = 20;
00292 static int trunkmaxsize = MAX_TRUNKDATA;
00293
00294 static int authdebug = 1;
00295 static int autokill = 0;
00296 static int iaxcompat = 0;
00297 static int last_authmethod = 0;
00298
00299 static int iaxdefaultdpcache=10 * 60;
00300
00301 static int iaxdefaulttimeout = 5;
00302
00303 static struct {
00304 unsigned int tos;
00305 unsigned int cos;
00306 } qos = { 0, 0 };
00307
00308 static int min_reg_expire;
00309 static int max_reg_expire;
00310
00311 static int srvlookup = 0;
00312
00313 static struct ast_timer *timer;
00314
00315 static struct ast_netsock_list *netsock;
00316 static struct ast_netsock_list *outsock;
00317 static int defaultsockfd = -1;
00318
00319 static int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00320
00321
00322 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00323
00324 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00325 ~AST_FORMAT_SLINEAR & \
00326 ~AST_FORMAT_SLINEAR16 & \
00327 ~AST_FORMAT_SIREN7 & \
00328 ~AST_FORMAT_SIREN14 & \
00329 ~AST_FORMAT_G719 & \
00330 ~AST_FORMAT_ULAW & \
00331 ~AST_FORMAT_ALAW & \
00332 ~AST_FORMAT_G722)
00333
00334 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00335 ~AST_FORMAT_G726 & \
00336 ~AST_FORMAT_G726_AAL2 & \
00337 ~AST_FORMAT_ADPCM)
00338
00339 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00340 ~AST_FORMAT_G723_1)
00341
00342
00343 #define DEFAULT_MAXMS 2000
00344 #define DEFAULT_FREQ_OK 60 * 1000
00345 #define DEFAULT_FREQ_NOTOK 10 * 1000
00346
00347
00348 #define IAX_CALLENCRYPTED(pvt) \
00349 (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))
00350
00351 #define IAX_DEBUGDIGEST(msg, key) do { \
00352 int idx; \
00353 char digest[33] = ""; \
00354 \
00355 if (!iaxdebug) \
00356 break; \
00357 \
00358 for (idx = 0; idx < 16; idx++) \
00359 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00360 \
00361 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00362 } while(0)
00363
00364 static struct io_context *io;
00365 static struct ast_sched_thread *sched;
00366
00367 #define DONT_RESCHEDULE -2
00368
00369 static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00370
00371 static int iaxdebug = 0;
00372
00373 static int iaxtrunkdebug = 0;
00374
00375 static int test_losspct = 0;
00376 #ifdef IAXTESTS
00377 static int test_late = 0;
00378 static int test_resync = 0;
00379 static int test_jit = 0;
00380 static int test_jitpct = 0;
00381 #endif
00382
00383 static char accountcode[AST_MAX_ACCOUNT_CODE];
00384 static char mohinterpret[MAX_MUSICCLASS];
00385 static char mohsuggest[MAX_MUSICCLASS];
00386 static int amaflags = 0;
00387 static int adsi = 0;
00388 static int delayreject = 0;
00389 static int iax2_encryption = 0;
00390
00391 static struct ast_flags64 globalflags = { 0 };
00392
00393 static pthread_t netthreadid = AST_PTHREADT_NULL;
00394
00395 enum iax2_state {
00396 IAX_STATE_STARTED = (1 << 0),
00397 IAX_STATE_AUTHENTICATED = (1 << 1),
00398 IAX_STATE_TBD = (1 << 2),
00399 };
00400
00401 struct iax2_context {
00402 char context[AST_MAX_CONTEXT];
00403 struct iax2_context *next;
00404 };
00405
00406
00407 #define IAX_HASCALLERID (uint64_t)(1 << 0)
00408 #define IAX_DELME (uint64_t)(1 << 1)
00409 #define IAX_TEMPONLY (uint64_t)(1 << 2)
00410 #define IAX_TRUNK (uint64_t)(1 << 3)
00411 #define IAX_NOTRANSFER (uint64_t)(1 << 4)
00412 #define IAX_USEJITTERBUF (uint64_t)(1 << 5)
00413 #define IAX_DYNAMIC (uint64_t)(1 << 6)
00414 #define IAX_SENDANI (uint64_t)(1 << 7)
00415 #define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8)
00416 #define IAX_ALREADYGONE (uint64_t)(1 << 9)
00417 #define IAX_PROVISION (uint64_t)(1 << 10)
00418 #define IAX_QUELCH (uint64_t)(1 << 11)
00419 #define IAX_ENCRYPTED (uint64_t)(1 << 12)
00420 #define IAX_KEYPOPULATED (uint64_t)(1 << 13)
00421 #define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14)
00422 #define IAX_CODEC_NOPREFS (uint64_t)(1 << 15)
00423 #define IAX_CODEC_NOCAP (uint64_t)(1 << 16)
00424 #define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17)
00425 #define IAX_RTUPDATE (uint64_t)(1 << 18)
00426 #define IAX_RTAUTOCLEAR (uint64_t)(1 << 19)
00427 #define IAX_FORCEJITTERBUF (uint64_t)(1 << 20)
00428 #define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21)
00429 #define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22)
00430 #define IAX_TRANSFERMEDIA (uint64_t)(1 << 23)
00431 #define IAX_MAXAUTHREQ (uint64_t)(1 << 24)
00432 #define IAX_DELAYPBXSTART (uint64_t)(1 << 25)
00433 #define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26)
00434 #define IAX_IMMEDIATE (uint64_t)(1 << 27)
00435 #define IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28)
00436 #define IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29)
00437 #define IAX_FORCE_ENCRYPT (uint64_t)(1 << 30)
00438 #define IAX_SHRINKCALLERID (uint64_t)(1 << 31)
00439 static int global_rtautoclear = 120;
00440
00441 static int reload_config(void);
00442
00443
00444
00445
00446 enum calltoken_peer_enum {
00447
00448 CALLTOKEN_DEFAULT = 0,
00449
00450 CALLTOKEN_YES = 1,
00451
00452
00453 CALLTOKEN_AUTO = 2,
00454
00455 CALLTOKEN_NO = 3,
00456 };
00457
00458 struct iax2_user {
00459 AST_DECLARE_STRING_FIELDS(
00460 AST_STRING_FIELD(name);
00461 AST_STRING_FIELD(secret);
00462 AST_STRING_FIELD(dbsecret);
00463 AST_STRING_FIELD(accountcode);
00464 AST_STRING_FIELD(mohinterpret);
00465 AST_STRING_FIELD(mohsuggest);
00466 AST_STRING_FIELD(inkeys);
00467 AST_STRING_FIELD(language);
00468 AST_STRING_FIELD(cid_num);
00469 AST_STRING_FIELD(cid_name);
00470 AST_STRING_FIELD(parkinglot);
00471 );
00472
00473 int authmethods;
00474 int encmethods;
00475 int amaflags;
00476 int adsi;
00477 uint64_t flags;
00478 format_t capability;
00479 int maxauthreq;
00480 int curauthreq;
00481 struct ast_codec_pref prefs;
00482 struct ast_ha *ha;
00483 struct iax2_context *contexts;
00484 struct ast_variable *vars;
00485 enum calltoken_peer_enum calltoken_required;
00486 };
00487
00488 struct iax2_peer {
00489 AST_DECLARE_STRING_FIELDS(
00490 AST_STRING_FIELD(name);
00491 AST_STRING_FIELD(username);
00492 AST_STRING_FIELD(secret);
00493 AST_STRING_FIELD(dbsecret);
00494 AST_STRING_FIELD(outkey);
00495
00496 AST_STRING_FIELD(regexten);
00497 AST_STRING_FIELD(context);
00498 AST_STRING_FIELD(peercontext);
00499 AST_STRING_FIELD(mailbox);
00500 AST_STRING_FIELD(mohinterpret);
00501 AST_STRING_FIELD(mohsuggest);
00502 AST_STRING_FIELD(inkeys);
00503
00504 AST_STRING_FIELD(cid_num);
00505 AST_STRING_FIELD(cid_name);
00506 AST_STRING_FIELD(zonetag);
00507 AST_STRING_FIELD(parkinglot);
00508 );
00509 struct ast_codec_pref prefs;
00510 struct ast_dnsmgr_entry *dnsmgr;
00511 struct ast_sockaddr addr;
00512 int formats;
00513 int sockfd;
00514 struct in_addr mask;
00515 int adsi;
00516 uint64_t flags;
00517
00518
00519 struct sockaddr_in defaddr;
00520 int authmethods;
00521 int encmethods;
00522
00523 int expire;
00524 int expiry;
00525 format_t capability;
00526
00527
00528 int callno;
00529 int pokeexpire;
00530 int lastms;
00531 int maxms;
00532
00533 int pokefreqok;
00534 int pokefreqnotok;
00535 int historicms;
00536 int smoothing;
00537 uint16_t maxcallno;
00538
00539 struct ast_event_sub *mwi_event_sub;
00540
00541 struct ast_ha *ha;
00542 enum calltoken_peer_enum calltoken_required;
00543 };
00544
00545 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00546
00547 struct iax2_trunk_peer {
00548 ast_mutex_t lock;
00549 int sockfd;
00550 struct sockaddr_in addr;
00551 struct timeval txtrunktime;
00552 struct timeval rxtrunktime;
00553 struct timeval lasttxtime;
00554 struct timeval trunkact;
00555 unsigned int lastsent;
00556
00557 unsigned char *trunkdata;
00558 unsigned int trunkdatalen;
00559 unsigned int trunkdataalloc;
00560 int trunkmaxmtu;
00561 int trunkerror;
00562 int calls;
00563 AST_LIST_ENTRY(iax2_trunk_peer) list;
00564 };
00565
00566 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00567
00568 struct iax_firmware {
00569 AST_LIST_ENTRY(iax_firmware) list;
00570 int fd;
00571 int mmaplen;
00572 int dead;
00573 struct ast_iax2_firmware_header *fwh;
00574 unsigned char *buf;
00575 };
00576
00577 enum iax_reg_state {
00578 REG_STATE_UNREGISTERED = 0,
00579 REG_STATE_REGSENT,
00580 REG_STATE_AUTHSENT,
00581 REG_STATE_REGISTERED,
00582 REG_STATE_REJECTED,
00583 REG_STATE_TIMEOUT,
00584 REG_STATE_NOAUTH
00585 };
00586
00587 enum iax_transfer_state {
00588 TRANSFER_NONE = 0,
00589 TRANSFER_BEGIN,
00590 TRANSFER_READY,
00591 TRANSFER_RELEASED,
00592 TRANSFER_PASSTHROUGH,
00593 TRANSFER_MBEGIN,
00594 TRANSFER_MREADY,
00595 TRANSFER_MRELEASED,
00596 TRANSFER_MPASSTHROUGH,
00597 TRANSFER_MEDIA,
00598 TRANSFER_MEDIAPASS
00599 };
00600
00601 struct iax2_registry {
00602 struct ast_sockaddr addr;
00603 char username[80];
00604 char secret[80];
00605 int expire;
00606 int refresh;
00607 enum iax_reg_state regstate;
00608 int messages;
00609 int callno;
00610 struct sockaddr_in us;
00611 struct ast_dnsmgr_entry *dnsmgr;
00612 AST_LIST_ENTRY(iax2_registry) entry;
00613 };
00614
00615 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00616
00617
00618 #define MIN_RETRY_TIME 100
00619 #define MAX_RETRY_TIME 10000
00620
00621 #define MAX_JITTER_BUFFER 50
00622 #define MIN_JITTER_BUFFER 10
00623
00624 #define DEFAULT_TRUNKDATA 640 * 10
00625
00626 #define MAX_TIMESTAMP_SKEW 160
00627
00628
00629 #define TS_GAP_FOR_JB_RESYNC 5000
00630
00631
00632 #define MARK_IAX_SUBCLASS_TX 0x8000
00633
00634 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00635 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00636 static int iaxdynamicthreadcount = 0;
00637 static int iaxdynamicthreadnum = 0;
00638 static int iaxactivethreadcount = 0;
00639
00640 struct iax_rr {
00641 int jitter;
00642 int losspct;
00643 int losscnt;
00644 int packets;
00645 int delay;
00646 int dropped;
00647 int ooo;
00648 };
00649
00650 struct iax2_pvt_ref;
00651
00652 struct chan_iax2_pvt {
00653
00654 int sockfd;
00655
00656 format_t voiceformat;
00657
00658 format_t videoformat;
00659
00660 format_t svoiceformat;
00661
00662 format_t svideoformat;
00663
00664 format_t capability;
00665
00666 unsigned int last;
00667
00668 unsigned int lastsent;
00669
00670 unsigned int lastvsent;
00671
00672 unsigned int nextpred;
00673
00674 int first_iax_message;
00675
00676 int last_iax_message;
00677
00678 unsigned int notsilenttx:1;
00679
00680 unsigned int pingtime;
00681
00682 int maxtime;
00683
00684 struct sockaddr_in addr;
00685
00686 struct ast_codec_pref prefs;
00687
00688 struct ast_codec_pref rprefs;
00689
00690 unsigned short callno;
00691
00692 struct callno_entry *callno_entry;
00693
00694 unsigned short peercallno;
00695
00696
00697
00698 format_t chosenformat;
00699
00700 format_t peerformat;
00701
00702 format_t peercapability;
00703
00704 struct timeval offset;
00705
00706 struct timeval rxcore;
00707
00708 jitterbuf *jb;
00709
00710 int jbid;
00711
00712 int lag;
00713
00714 int error;
00715
00716 struct ast_channel *owner;
00717
00718 struct ast_flags state;
00719
00720 int expiry;
00721
00722 unsigned char oseqno;
00723
00724 unsigned char rseqno;
00725
00726 unsigned char iseqno;
00727
00728 unsigned char aseqno;
00729
00730 AST_DECLARE_STRING_FIELDS(
00731
00732 AST_STRING_FIELD(peer);
00733
00734 AST_STRING_FIELD(context);
00735
00736 AST_STRING_FIELD(cid_num);
00737 AST_STRING_FIELD(cid_name);
00738
00739 AST_STRING_FIELD(ani);
00740
00741 AST_STRING_FIELD(dnid);
00742
00743 AST_STRING_FIELD(rdnis);
00744
00745 AST_STRING_FIELD(exten);
00746
00747 AST_STRING_FIELD(username);
00748
00749 AST_STRING_FIELD(secret);
00750
00751 AST_STRING_FIELD(challenge);
00752
00753 AST_STRING_FIELD(inkeys);
00754
00755 AST_STRING_FIELD(outkey);
00756
00757 AST_STRING_FIELD(language);
00758
00759 AST_STRING_FIELD(host);
00760
00761 AST_STRING_FIELD(dproot);
00762 AST_STRING_FIELD(accountcode);
00763 AST_STRING_FIELD(mohinterpret);
00764 AST_STRING_FIELD(mohsuggest);
00765
00766 AST_STRING_FIELD(osptoken);
00767
00768 AST_STRING_FIELD(parkinglot);
00769 );
00770
00771 int authrej;
00772
00773 int authmethods;
00774
00775 int encmethods;
00776
00777 ast_aes_encrypt_key ecx;
00778
00779 ast_aes_decrypt_key mydcx;
00780
00781 ast_aes_decrypt_key dcx;
00782
00783
00784 int keyrotateid;
00785
00786 unsigned char semirand[32];
00787
00788 struct iax2_registry *reg;
00789
00790 struct iax2_peer *peerpoke;
00791
00792 uint64_t flags;
00793 int adsi;
00794
00795
00796 enum iax_transfer_state transferring;
00797
00798 int transferid;
00799
00800 struct sockaddr_in transfer;
00801
00802 unsigned short transfercallno;
00803
00804 ast_aes_encrypt_key tdcx;
00805
00806
00807 int peeradsicpe;
00808
00809
00810 unsigned short bridgecallno;
00811
00812 int pingid;
00813 int lagid;
00814 int autoid;
00815 int authid;
00816 int authfail;
00817 int initid;
00818 int calling_ton;
00819 int calling_tns;
00820 int calling_pres;
00821 int amaflags;
00822 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00823
00824 struct ast_variable *vars;
00825
00826 struct ast_variable *iaxvars;
00827
00828 struct iax_rr remote_rr;
00829
00830 int min;
00831
00832 int frames_dropped;
00833
00834 int frames_received;
00835
00836 unsigned char calltoken_ie_len;
00837
00838 char hold_signaling;
00839
00840 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00841 };
00842
00843 struct signaling_queue_entry {
00844 struct ast_frame f;
00845 AST_LIST_ENTRY(signaling_queue_entry) next;
00846 };
00847
00848
00849 static struct ao2_container *callno_pool;
00850
00851
00852 static struct ao2_container *callno_pool_trunk;
00853
00854 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 static AST_LIST_HEAD_NOLOCK(, iax_frame) frame_queue[IAX_MAX_CALLS + 1];
00866
00867 static struct ast_taskprocessor *transmit_processor;
00868
00869 static int randomcalltokendata;
00870
00871 static const time_t MAX_CALLTOKEN_DELAY = 10;
00872
00873
00874
00875
00876
00877
00878
00879
00880 #ifdef LOW_MEMORY
00881 #define MAX_PEER_BUCKETS 17
00882 #else
00883 #define MAX_PEER_BUCKETS 563
00884 #endif
00885 static struct ao2_container *peers;
00886
00887 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00888 static struct ao2_container *users;
00889
00890
00891 static struct ao2_container *peercnts;
00892
00893
00894 static struct ao2_container *callno_limits;
00895
00896
00897 static struct ao2_container *calltoken_ignores;
00898
00899 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00900
00901 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00902
00903 static uint16_t global_maxcallno;
00904
00905
00906 static uint16_t global_maxcallno_nonval;
00907
00908 static uint16_t total_nonval_callno_used = 0;
00909
00910
00911
00912 struct peercnt {
00913
00914 unsigned long addr;
00915
00916 uint16_t cur;
00917
00918 uint16_t limit;
00919
00920
00921 unsigned char reg;
00922 };
00923
00924
00925 struct addr_range {
00926
00927 struct ast_ha ha;
00928
00929 uint16_t limit;
00930
00931 unsigned char delme;
00932 };
00933
00934 struct callno_entry {
00935
00936 uint16_t callno;
00937
00938 unsigned char validated;
00939 };
00940
00941 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00942
00943 enum {
00944
00945 CACHE_FLAG_EXISTS = (1 << 0),
00946
00947 CACHE_FLAG_NONEXISTENT = (1 << 1),
00948
00949 CACHE_FLAG_CANEXIST = (1 << 2),
00950
00951 CACHE_FLAG_PENDING = (1 << 3),
00952
00953 CACHE_FLAG_TIMEOUT = (1 << 4),
00954
00955 CACHE_FLAG_TRANSMITTED = (1 << 5),
00956
00957 CACHE_FLAG_UNKNOWN = (1 << 6),
00958
00959 CACHE_FLAG_MATCHMORE = (1 << 7),
00960 };
00961
00962 struct iax2_dpcache {
00963 char peercontext[AST_MAX_CONTEXT];
00964 char exten[AST_MAX_EXTENSION];
00965 struct timeval orig;
00966 struct timeval expiry;
00967 int flags;
00968 unsigned short callno;
00969 int waiters[256];
00970 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00971 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00972 };
00973
00974 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00975
00976 static void reg_source_db(struct iax2_peer *p);
00977 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00978 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00979
00980 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00981 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags);
00982 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00983
00984 enum iax2_thread_iostate {
00985 IAX_IOSTATE_IDLE,
00986 IAX_IOSTATE_READY,
00987 IAX_IOSTATE_PROCESSING,
00988 IAX_IOSTATE_SCHEDREADY,
00989 };
00990
00991 enum iax2_thread_type {
00992 IAX_THREAD_TYPE_POOL,
00993 IAX_THREAD_TYPE_DYNAMIC,
00994 };
00995
00996 struct iax2_pkt_buf {
00997 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00998 size_t len;
00999 unsigned char buf[1];
01000 };
01001
01002 struct iax2_thread {
01003 AST_LIST_ENTRY(iax2_thread) list;
01004 enum iax2_thread_type type;
01005 enum iax2_thread_iostate iostate;
01006 #ifdef SCHED_MULTITHREADED
01007 void (*schedfunc)(const void *);
01008 const void *scheddata;
01009 #endif
01010 #ifdef DEBUG_SCHED_MULTITHREAD
01011 char curfunc[80];
01012 #endif
01013 int actions;
01014 pthread_t threadid;
01015 int threadnum;
01016 struct sockaddr_in iosin;
01017 unsigned char readbuf[4096];
01018 unsigned char *buf;
01019 ssize_t buf_len;
01020 size_t buf_size;
01021 int iofd;
01022 time_t checktime;
01023 ast_mutex_t lock;
01024 ast_cond_t cond;
01025 ast_mutex_t init_lock;
01026 ast_cond_t init_cond;
01027
01028
01029
01030
01031 struct {
01032 unsigned short callno;
01033 struct sockaddr_in sin;
01034 unsigned char type;
01035 unsigned char csub;
01036 } ffinfo;
01037
01038
01039
01040 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
01041 unsigned char stop;
01042 };
01043
01044
01045 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
01046 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
01047 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
01048
01049 static void *iax2_process_thread(void *data);
01050 static void iax2_destroy(int callno);
01051
01052 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
01053 {
01054 ast_mutex_lock(lock);
01055 ast_cond_signal(cond);
01056 ast_mutex_unlock(lock);
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS + 1];
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 static struct ao2_container *iax_peercallno_pvts;
01079
01080
01081
01082
01083
01084
01085
01086
01087 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
01088
01089
01090
01091
01092
01093
01094 static struct ao2_container *iax_transfercallno_pvts;
01095
01096
01097
01098 #define TRUNK_CALL_START IAX_MAX_CALLS / 2
01099
01100
01101 static struct sockaddr_in debugaddr;
01102
01103 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
01104 {
01105 if (iaxdebug ||
01106 (sin && debugaddr.sin_addr.s_addr &&
01107 (!ntohs(debugaddr.sin_port) ||
01108 debugaddr.sin_port == sin->sin_port) &&
01109 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01110 if (iaxdebug) {
01111 iax_showframe(f, fhi, rx, sin, datalen);
01112 } else {
01113 iaxdebug = 1;
01114 iax_showframe(f, fhi, rx, sin, datalen);
01115 iaxdebug = 0;
01116 }
01117 }
01118 }
01119
01120 static void iax_debug_output(const char *data)
01121 {
01122 if (iaxdebug)
01123 ast_verbose("%s", data);
01124 }
01125
01126 static void iax_error_output(const char *data)
01127 {
01128 ast_log(LOG_WARNING, "%s", data);
01129 }
01130
01131 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
01132 {
01133 va_list args;
01134 char buf[1024];
01135
01136 va_start(args, fmt);
01137 vsnprintf(buf, sizeof(buf), fmt, args);
01138 va_end(args);
01139
01140 ast_log(LOG_ERROR, "%s", buf);
01141 }
01142
01143 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01144 {
01145 va_list args;
01146 char buf[1024];
01147
01148 va_start(args, fmt);
01149 vsnprintf(buf, sizeof(buf), fmt, args);
01150 va_end(args);
01151
01152 ast_log(LOG_WARNING, "%s", buf);
01153 }
01154
01155 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01156 {
01157 va_list args;
01158 char buf[1024];
01159
01160 va_start(args, fmt);
01161 vsnprintf(buf, sizeof(buf), fmt, args);
01162 va_end(args);
01163
01164 ast_verbose("%s", buf);
01165 }
01166
01167 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
01168 static int expire_registry(const void *data);
01169 static int iax2_answer(struct ast_channel *c);
01170 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01171 static int iax2_devicestate(void *data);
01172 static int iax2_digit_begin(struct ast_channel *c, char digit);
01173 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01174 static int iax2_do_register(struct iax2_registry *reg);
01175 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01176 static int iax2_hangup(struct ast_channel *c);
01177 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01178 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01179 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force);
01180 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01181 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01182 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01183 static int iax2_sendtext(struct ast_channel *c, const char *text);
01184 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01185 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen);
01186 static int iax2_transfer(struct ast_channel *c, const char *dest);
01187 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01188 static int iax2_sched_add(struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data);
01189
01190 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01191 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01192 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01193 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01194 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01195 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01196 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
01197 static struct ast_frame *iax2_read(struct ast_channel *c);
01198 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01199 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01200 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime);
01201 static void *iax2_dup_variable_datastore(void *);
01202 static void prune_peers(void);
01203 static void prune_users(void);
01204 static void iax2_free_variable_datastore(void *);
01205
01206 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01207 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01208 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01209 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01210 static void build_rand_pad(unsigned char *buf, ssize_t len);
01211 static struct callno_entry *get_unused_callno(int trunk, int validated);
01212 static int replace_callno(const void *obj);
01213 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01214 static void network_change_event_cb(const struct ast_event *, void *);
01215
01216 static const struct ast_channel_tech iax2_tech = {
01217 .type = "IAX2",
01218 .description = tdesc,
01219 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01220 .properties = AST_CHAN_TP_WANTSJITTER,
01221 .requester = iax2_request,
01222 .devicestate = iax2_devicestate,
01223 .send_digit_begin = iax2_digit_begin,
01224 .send_digit_end = iax2_digit_end,
01225 .send_text = iax2_sendtext,
01226 .send_image = iax2_sendimage,
01227 .send_html = iax2_sendhtml,
01228 .call = iax2_call,
01229 .hangup = iax2_hangup,
01230 .answer = iax2_answer,
01231 .read = iax2_read,
01232 .write = iax2_write,
01233 .write_video = iax2_write,
01234 .indicate = iax2_indicate,
01235 .setoption = iax2_setoption,
01236 .queryoption = iax2_queryoption,
01237 .bridge = iax2_bridge,
01238 .transfer = iax2_transfer,
01239 .fixup = iax2_fixup,
01240 .func_channel_read = acf_channel_read,
01241 };
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 static void iax2_lock_owner(int callno)
01261 {
01262 for (;;) {
01263 if (!iaxs[callno] || !iaxs[callno]->owner) {
01264
01265 break;
01266 }
01267 if (!ast_channel_trylock(iaxs[callno]->owner)) {
01268
01269 break;
01270 }
01271
01272 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01273 }
01274 }
01275
01276 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01277 {
01278
01279
01280
01281 }
01282
01283 static void network_change_event_subscribe(void)
01284 {
01285 if (!network_change_event_subscription) {
01286 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE,
01287 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END);
01288 }
01289 }
01290
01291 static void network_change_event_unsubscribe(void)
01292 {
01293 if (network_change_event_subscription) {
01294 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription);
01295 }
01296 }
01297
01298 static int network_change_event_sched_cb(const void *data)
01299 {
01300 struct iax2_registry *reg;
01301 network_change_event_sched_id = -1;
01302 AST_LIST_LOCK(®istrations);
01303 AST_LIST_TRAVERSE(®istrations, reg, entry) {
01304 iax2_do_register(reg);
01305 }
01306 AST_LIST_UNLOCK(®istrations);
01307
01308 return 0;
01309 }
01310
01311 static void network_change_event_cb(const struct ast_event *event, void *userdata)
01312 {
01313 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n");
01314 if (network_change_event_sched_id == -1) {
01315 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
01316 }
01317
01318 }
01319
01320
01321
01322
01323 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01324 {
01325 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01326 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01327 pvt->owner ? pvt->owner->name : "",
01328 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01329 }
01330
01331 static struct ast_datastore_info iax2_variable_datastore_info = {
01332 .type = "IAX2_VARIABLE",
01333 .duplicate = iax2_dup_variable_datastore,
01334 .destroy = iax2_free_variable_datastore,
01335 };
01336
01337 static void *iax2_dup_variable_datastore(void *old)
01338 {
01339 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01340 struct ast_var_t *oldvar, *newvar;
01341
01342 newlist = ast_calloc(sizeof(*newlist), 1);
01343 if (!newlist) {
01344 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01345 return NULL;
01346 }
01347
01348 AST_LIST_HEAD_INIT(newlist);
01349 AST_LIST_LOCK(oldlist);
01350 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01351 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01352 if (newvar)
01353 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01354 else
01355 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01356 }
01357 AST_LIST_UNLOCK(oldlist);
01358 return newlist;
01359 }
01360
01361 static void iax2_free_variable_datastore(void *old)
01362 {
01363 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01364 struct ast_var_t *oldvar;
01365
01366 AST_LIST_LOCK(oldlist);
01367 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01368 ast_free(oldvar);
01369 }
01370 AST_LIST_UNLOCK(oldlist);
01371 AST_LIST_HEAD_DESTROY(oldlist);
01372 ast_free(oldlist);
01373 }
01374
01375
01376
01377
01378
01379 static void insert_idle_thread(struct iax2_thread *thread)
01380 {
01381 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01382 AST_LIST_LOCK(&dynamic_list);
01383 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01384 AST_LIST_UNLOCK(&dynamic_list);
01385 } else {
01386 AST_LIST_LOCK(&idle_list);
01387 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01388 AST_LIST_UNLOCK(&idle_list);
01389 }
01390
01391 return;
01392 }
01393
01394 static struct iax2_thread *find_idle_thread(void)
01395 {
01396 struct iax2_thread *thread = NULL;
01397
01398
01399 AST_LIST_LOCK(&idle_list);
01400 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01401 AST_LIST_UNLOCK(&idle_list);
01402
01403
01404 if (thread) {
01405 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01406 return thread;
01407 }
01408
01409
01410 AST_LIST_LOCK(&dynamic_list);
01411 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01412 AST_LIST_UNLOCK(&dynamic_list);
01413
01414
01415 if (thread) {
01416 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01417 return thread;
01418 }
01419
01420
01421 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01422 return NULL;
01423
01424
01425 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01426 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01427 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01428
01429
01430 ast_mutex_init(&thread->lock);
01431 ast_cond_init(&thread->cond, NULL);
01432 ast_mutex_init(&thread->init_lock);
01433 ast_cond_init(&thread->init_cond, NULL);
01434 ast_mutex_lock(&thread->init_lock);
01435
01436
01437 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01438 ast_cond_destroy(&thread->cond);
01439 ast_mutex_destroy(&thread->lock);
01440 ast_mutex_unlock(&thread->init_lock);
01441 ast_cond_destroy(&thread->init_cond);
01442 ast_mutex_destroy(&thread->init_lock);
01443 ast_free(thread);
01444 return NULL;
01445 }
01446
01447
01448
01449 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01450
01451
01452 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01453
01454
01455 ast_mutex_unlock(&thread->init_lock);
01456
01457 return thread;
01458 }
01459
01460 #ifdef SCHED_MULTITHREADED
01461 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01462 {
01463 struct iax2_thread *thread = NULL;
01464 static time_t lasterror;
01465 static time_t t;
01466
01467 thread = find_idle_thread();
01468
01469 if (thread != NULL) {
01470 thread->schedfunc = func;
01471 thread->scheddata = data;
01472 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01473 #ifdef DEBUG_SCHED_MULTITHREAD
01474 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01475 #endif
01476 signal_condition(&thread->lock, &thread->cond);
01477 return 0;
01478 }
01479 time(&t);
01480 if (t != lasterror)
01481 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01482 lasterror = t;
01483
01484 return -1;
01485 }
01486 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01487 #endif
01488
01489 static int iax2_sched_replace(int id, struct ast_sched_thread *st, int when,
01490 ast_sched_cb callback, const void *data)
01491 {
01492 ast_sched_thread_del(st, id);
01493
01494 return ast_sched_thread_add(st, when, callback, data);
01495 }
01496
01497 static int iax2_sched_add(struct ast_sched_thread *st, int when,
01498 ast_sched_cb callback, const void *data)
01499 {
01500 return ast_sched_thread_add(st, when, callback, data);
01501 }
01502
01503 static int send_ping(const void *data);
01504
01505 static void __send_ping(const void *data)
01506 {
01507 int callno = (long) data;
01508
01509 ast_mutex_lock(&iaxsl[callno]);
01510
01511 if (iaxs[callno]) {
01512 if (iaxs[callno]->peercallno) {
01513 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01514 if (iaxs[callno]->pingid != DONT_RESCHEDULE) {
01515 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01516 }
01517 }
01518 } else {
01519 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01520 }
01521
01522 ast_mutex_unlock(&iaxsl[callno]);
01523 }
01524
01525 static int send_ping(const void *data)
01526 {
01527 int callno = (long) data;
01528 ast_mutex_lock(&iaxsl[callno]);
01529 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) {
01530 iaxs[callno]->pingid = -1;
01531 }
01532 ast_mutex_unlock(&iaxsl[callno]);
01533
01534 #ifdef SCHED_MULTITHREADED
01535 if (schedule_action(__send_ping, data))
01536 #endif
01537 __send_ping(data);
01538
01539 return 0;
01540 }
01541
01542 static void encmethods_to_str(int e, struct ast_str *buf)
01543 {
01544 ast_str_set(&buf, 0, "(");
01545 if (e & IAX_ENCRYPT_AES128) {
01546 ast_str_append(&buf, 0, "aes128");
01547 }
01548 if (e & IAX_ENCRYPT_KEYROTATE) {
01549 ast_str_append(&buf, 0, ",keyrotate");
01550 }
01551 if (ast_str_strlen(buf) > 1) {
01552 ast_str_append(&buf, 0, ")");
01553 } else {
01554 ast_str_set(&buf, 0, "No");
01555 }
01556 }
01557
01558 static int get_encrypt_methods(const char *s)
01559 {
01560 int e;
01561 if (!strcasecmp(s, "aes128"))
01562 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01563 else if (ast_true(s))
01564 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01565 else
01566 e = 0;
01567 return e;
01568 }
01569
01570 static int send_lagrq(const void *data);
01571
01572 static void __send_lagrq(const void *data)
01573 {
01574 int callno = (long) data;
01575
01576 ast_mutex_lock(&iaxsl[callno]);
01577
01578 if (iaxs[callno]) {
01579 if (iaxs[callno]->peercallno) {
01580 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01581 if (iaxs[callno]->lagid != DONT_RESCHEDULE) {
01582 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01583 }
01584 }
01585 } else {
01586 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01587 }
01588
01589 ast_mutex_unlock(&iaxsl[callno]);
01590 }
01591
01592 static int send_lagrq(const void *data)
01593 {
01594 int callno = (long) data;
01595 ast_mutex_lock(&iaxsl[callno]);
01596 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) {
01597 iaxs[callno]->lagid = -1;
01598 }
01599 ast_mutex_unlock(&iaxsl[callno]);
01600
01601 #ifdef SCHED_MULTITHREADED
01602 if (schedule_action(__send_lagrq, data))
01603 #endif
01604 __send_lagrq(data);
01605 return 0;
01606 }
01607
01608 static unsigned char compress_subclass(format_t subclass)
01609 {
01610 int x;
01611 int power=-1;
01612
01613 if (subclass < IAX_FLAG_SC_LOG)
01614 return subclass;
01615
01616 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01617 if (subclass & (1LL << x)) {
01618 if (power > -1) {
01619 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
01620 return 0;
01621 } else
01622 power = x;
01623 }
01624 }
01625 return power | IAX_FLAG_SC_LOG;
01626 }
01627
01628 static format_t uncompress_subclass(unsigned char csub)
01629 {
01630
01631 if (csub & IAX_FLAG_SC_LOG) {
01632
01633 if (csub == 0xff)
01634 return -1;
01635 else
01636 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01637 }
01638 else
01639 return csub;
01640 }
01641
01642
01643
01644
01645 static int peer_hash_cb(const void *obj, const int flags)
01646 {
01647 const struct iax2_peer *peer = obj;
01648
01649 return ast_str_hash(peer->name);
01650 }
01651
01652
01653
01654
01655 static int peer_cmp_cb(void *obj, void *arg, int flags)
01656 {
01657 struct iax2_peer *peer = obj, *peer2 = arg;
01658
01659 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01660 }
01661
01662
01663
01664
01665 static int user_hash_cb(const void *obj, const int flags)
01666 {
01667 const struct iax2_user *user = obj;
01668
01669 return ast_str_hash(user->name);
01670 }
01671
01672
01673
01674
01675 static int user_cmp_cb(void *obj, void *arg, int flags)
01676 {
01677 struct iax2_user *user = obj, *user2 = arg;
01678
01679 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01680 }
01681
01682
01683
01684
01685
01686 static struct iax2_peer *find_peer(const char *name, int realtime)
01687 {
01688 struct iax2_peer *peer = NULL;
01689 struct iax2_peer tmp_peer = {
01690 .name = name,
01691 };
01692
01693 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01694
01695
01696 if(!peer && realtime)
01697 peer = realtime_peer(name, NULL);
01698
01699 return peer;
01700 }
01701
01702 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01703 {
01704 ao2_ref(peer, +1);
01705 return peer;
01706 }
01707
01708 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01709 {
01710 ao2_ref(peer, -1);
01711 return NULL;
01712 }
01713
01714 static struct iax2_user *find_user(const char *name)
01715 {
01716 struct iax2_user tmp_user = {
01717 .name = name,
01718 };
01719
01720 return ao2_find(users, &tmp_user, OBJ_POINTER);
01721 }
01722 static inline struct iax2_user *user_ref(struct iax2_user *user)
01723 {
01724 ao2_ref(user, +1);
01725 return user;
01726 }
01727
01728 static inline struct iax2_user *user_unref(struct iax2_user *user)
01729 {
01730 ao2_ref(user, -1);
01731 return NULL;
01732 }
01733
01734 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01735 {
01736 struct iax2_peer *peer = NULL;
01737 int res = 0;
01738 struct ao2_iterator i;
01739
01740 i = ao2_iterator_init(peers, 0);
01741 while ((peer = ao2_iterator_next(&i))) {
01742 struct sockaddr_in peer_addr;
01743
01744 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
01745
01746 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01747 (peer_addr.sin_port == sin.sin_port)) {
01748 ast_copy_string(host, peer->name, len);
01749 peer_unref(peer);
01750 res = 1;
01751 break;
01752 }
01753 peer_unref(peer);
01754 }
01755 ao2_iterator_destroy(&i);
01756
01757 if (!peer) {
01758 peer = realtime_peer(NULL, &sin);
01759 if (peer) {
01760 ast_copy_string(host, peer->name, len);
01761 peer_unref(peer);
01762 res = 1;
01763 }
01764 }
01765
01766 return res;
01767 }
01768
01769
01770
01771 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01772 {
01773
01774 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
01775 struct iax2_user *user;
01776 struct iax2_user tmp_user = {
01777 .name = pvt->username,
01778 };
01779
01780 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01781 if (user) {
01782 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01783 user_unref(user);
01784 }
01785
01786 ast_clear_flag64(pvt, IAX_MAXAUTHREQ);
01787 }
01788
01789 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01790 pvt->pingid = DONT_RESCHEDULE;
01791 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01792 pvt->lagid = DONT_RESCHEDULE;
01793 ast_sched_thread_del(sched, pvt->autoid);
01794 ast_sched_thread_del(sched, pvt->authid);
01795 ast_sched_thread_del(sched, pvt->initid);
01796 ast_sched_thread_del(sched, pvt->jbid);
01797 ast_sched_thread_del(sched, pvt->keyrotateid);
01798 }
01799
01800 static void iax2_frame_free(struct iax_frame *fr)
01801 {
01802 ast_sched_thread_del(sched, fr->retrans);
01803 iax_frame_free(fr);
01804 }
01805
01806 static int scheduled_destroy(const void *vid)
01807 {
01808 unsigned short callno = PTR_TO_CALLNO(vid);
01809 ast_mutex_lock(&iaxsl[callno]);
01810 if (iaxs[callno]) {
01811 if (option_debug) {
01812 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01813 }
01814 iax2_destroy(callno);
01815 }
01816 ast_mutex_unlock(&iaxsl[callno]);
01817 return 0;
01818 }
01819
01820 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01821 {
01822 if (s->f.datalen) {
01823 ast_free(s->f.data.ptr);
01824 }
01825 ast_free(s);
01826 }
01827
01828
01829
01830 static void send_signaling(struct chan_iax2_pvt *pvt)
01831 {
01832 struct signaling_queue_entry *s = NULL;
01833
01834 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01835 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01836 free_signaling_queue_entry(s);
01837 }
01838 pvt->hold_signaling = 0;
01839 }
01840
01841
01842
01843 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01844 {
01845 struct signaling_queue_entry *qe;
01846
01847 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01848 return 1;
01849 } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01850 return -1;
01851 }
01852
01853
01854 qe->f = *f;
01855 if (qe->f.datalen) {
01856
01857 if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) {
01858 free_signaling_queue_entry(qe);
01859 return -1;
01860 }
01861 memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen);
01862 }
01863 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, qe, next);
01864
01865 return 0;
01866 }
01867
01868 static void pvt_destructor(void *obj)
01869 {
01870 struct chan_iax2_pvt *pvt = obj;
01871 struct iax_frame *cur = NULL;
01872 struct signaling_queue_entry *s = NULL;
01873
01874 ast_mutex_lock(&iaxsl[pvt->callno]);
01875
01876 iax2_destroy_helper(pvt);
01877
01878 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01879 pvt->callno_entry = NULL;
01880
01881
01882 ast_set_flag64(pvt, IAX_ALREADYGONE);
01883
01884 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
01885
01886 cur->retries = -1;
01887 }
01888
01889 ast_mutex_unlock(&iaxsl[pvt->callno]);
01890
01891 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01892 free_signaling_queue_entry(s);
01893 }
01894
01895 if (pvt->reg) {
01896 pvt->reg->callno = 0;
01897 }
01898
01899 if (!pvt->owner) {
01900 jb_frame frame;
01901 if (pvt->vars) {
01902 ast_variables_destroy(pvt->vars);
01903 pvt->vars = NULL;
01904 }
01905
01906 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01907 iax2_frame_free(frame.data);
01908 }
01909
01910 jb_destroy(pvt->jb);
01911 ast_string_field_free_memory(pvt);
01912 }
01913 }
01914
01915 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01916 {
01917 struct chan_iax2_pvt *tmp;
01918 jb_conf jbconf;
01919
01920 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01921 return NULL;
01922 }
01923
01924 if (ast_string_field_init(tmp, 32)) {
01925 ao2_ref(tmp, -1);
01926 tmp = NULL;
01927 return NULL;
01928 }
01929
01930 tmp->prefs = prefs;
01931 tmp->pingid = -1;
01932 tmp->lagid = -1;
01933 tmp->autoid = -1;
01934 tmp->authid = -1;
01935 tmp->initid = -1;
01936 tmp->keyrotateid = -1;
01937
01938 ast_string_field_set(tmp,exten, "s");
01939 ast_string_field_set(tmp,host, host);
01940
01941 tmp->jb = jb_new();
01942 tmp->jbid = -1;
01943 jbconf.max_jitterbuf = maxjitterbuffer;
01944 jbconf.resync_threshold = resyncthreshold;
01945 jbconf.max_contig_interp = maxjitterinterps;
01946 jbconf.target_extra = jittertargetextra;
01947 jb_setconf(tmp->jb,&jbconf);
01948
01949 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01950
01951 tmp->hold_signaling = 1;
01952 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01953
01954 return tmp;
01955 }
01956
01957 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01958 {
01959 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01960 if (new) {
01961 size_t afdatalen = new->afdatalen;
01962 memcpy(new, fr, sizeof(*new));
01963 iax_frame_wrap(new, &fr->af);
01964 new->afdatalen = afdatalen;
01965 new->data = NULL;
01966 new->datalen = 0;
01967 new->direction = DIRECTION_INGRESS;
01968 new->retrans = -1;
01969 }
01970 return new;
01971 }
01972
01973
01974 enum {
01975
01976 NEW_PREVENT = 0,
01977
01978 NEW_ALLOW = 1,
01979
01980 NEW_FORCE = 2,
01981
01982
01983 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01984 };
01985
01986 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01987 {
01988 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01989 (cur->addr.sin_port == sin->sin_port)) {
01990
01991 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01992 (check_dcallno ? dcallno == cur->callno : 1) ) {
01993
01994 return 1;
01995 }
01996 }
01997 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01998 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01999
02000 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
02001 return 1;
02002 }
02003 return 0;
02004 }
02005
02006 #ifdef IAX_OLD_FIND
02007
02008 static int maxtrunkcall = TRUNK_CALL_START;
02009 static int maxnontrunkcall = 1;
02010
02011 #define update_max_trunk() __update_max_trunk()
02012 #define update_max_nontrunk() __update_max_nontrunk()
02013
02014 static void __update_max_trunk(void)
02015 {
02016 int max = TRUNK_CALL_START;
02017 int x;
02018
02019
02020 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
02021 if (iaxs[x]) {
02022 max = x + 1;
02023 }
02024 }
02025
02026 maxtrunkcall = max;
02027 if (iaxdebug)
02028 ast_debug(1, "New max trunk callno is %d\n", max);
02029 }
02030
02031 static void __update_max_nontrunk(void)
02032 {
02033 int max = 1;
02034 int x;
02035
02036 for (x=1;x<TRUNK_CALL_START - 1; x++) {
02037 if (iaxs[x])
02038 max = x + 1;
02039 }
02040 maxnontrunkcall = max;
02041 if (iaxdebug)
02042 ast_debug(1, "New max nontrunk callno is %d\n", max);
02043 }
02044
02045 #else
02046
02047 #define update_max_trunk() do { } while (0)
02048 #define update_max_nontrunk() do { } while (0)
02049
02050 #endif
02051
02052 static int make_trunk(unsigned short callno, int locked)
02053 {
02054 int x;
02055 int res= 0;
02056 struct callno_entry *callno_entry;
02057 if (iaxs[callno]->oseqno) {
02058 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
02059 return -1;
02060 }
02061 if (callno & TRUNK_CALL_START) {
02062 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
02063 return -1;
02064 }
02065
02066 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
02067 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
02068 return -1;
02069 }
02070
02071 x = callno_entry->callno;
02072 ast_mutex_lock(&iaxsl[x]);
02073
02074
02075
02076
02077
02078 ast_sched_thread_del(sched, iaxs[callno]->pingid);
02079 ast_sched_thread_del(sched, iaxs[callno]->lagid);
02080 iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
02081 iaxs[x] = iaxs[callno];
02082 iaxs[x]->callno = x;
02083
02084
02085
02086 if (iaxs[x]->callno_entry) {
02087 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
02088 }
02089 iaxs[x]->callno_entry = callno_entry;
02090
02091 iaxs[callno] = NULL;
02092
02093 iaxs[x]->pingid = iax2_sched_add(sched,
02094 ping_time * 1000, send_ping, (void *)(long)x);
02095 iaxs[x]->lagid = iax2_sched_add(sched,
02096 lagrq_time * 1000, send_lagrq, (void *)(long)x);
02097
02098 if (locked)
02099 ast_mutex_unlock(&iaxsl[callno]);
02100 res = x;
02101 if (!locked)
02102 ast_mutex_unlock(&iaxsl[x]);
02103
02104 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
02105
02106 update_max_trunk();
02107 update_max_nontrunk();
02108 return res;
02109 }
02110
02111 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
02112 {
02113 if (!pvt->transfercallno) {
02114 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02115 return;
02116 }
02117
02118 ao2_link(iax_transfercallno_pvts, pvt);
02119 }
02120
02121 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
02122 {
02123 if (!pvt->transfercallno) {
02124 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02125 return;
02126 }
02127
02128 ao2_unlink(iax_transfercallno_pvts, pvt);
02129 }
02130 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
02131 {
02132 if (!pvt->peercallno) {
02133 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02134 return;
02135 }
02136
02137 ao2_link(iax_peercallno_pvts, pvt);
02138 }
02139
02140 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
02141 {
02142 if (!pvt->peercallno) {
02143 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02144 return;
02145 }
02146
02147 ao2_unlink(iax_peercallno_pvts, pvt);
02148 }
02149
02150 static int addr_range_delme_cb(void *obj, void *arg, int flags)
02151 {
02152 struct addr_range *lim = obj;
02153 lim->delme = 1;
02154 return 0;
02155 }
02156
02157 static int addr_range_hash_cb(const void *obj, const int flags)
02158 {
02159 const struct addr_range *lim = obj;
02160 struct sockaddr_in sin;
02161 ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02162 return abs((int) sin.sin_addr.s_addr);
02163 }
02164
02165 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
02166 {
02167 struct addr_range *lim1 = obj, *lim2 = arg;
02168 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02169 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02170 CMP_MATCH | CMP_STOP : 0;
02171 }
02172
02173 static int peercnt_hash_cb(const void *obj, const int flags)
02174 {
02175 const struct peercnt *peercnt = obj;
02176 return abs((int) peercnt->addr);
02177 }
02178
02179 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
02180 {
02181 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02182 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02183 }
02184
02185 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
02186 {
02187 struct addr_range *addr_range = obj;
02188 struct sockaddr_in *sin = arg;
02189 struct sockaddr_in ha_netmask_sin;
02190 struct sockaddr_in ha_addr_sin;
02191
02192 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02193 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02194
02195 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02196 return CMP_MATCH | CMP_STOP;
02197 }
02198 return 0;
02199 }
02200
02201
02202
02203
02204
02205
02206 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
02207 {
02208 struct addr_range *addr_range;
02209 struct iax2_peer *peer = NULL;
02210 struct iax2_user *user = NULL;
02211
02212 const char *find = S_OR(name, "guest");
02213 int res = 1;
02214 int optional = 0;
02215 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02216
02217
02218
02219
02220
02221
02222
02223 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02224 ao2_ref(addr_range, -1);
02225 optional = 1;
02226 }
02227
02228
02229 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02230 calltoken_required = user->calltoken_required;
02231 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02232 calltoken_required = user->calltoken_required;
02233 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02234 calltoken_required = peer->calltoken_required;
02235 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02236 calltoken_required = peer->calltoken_required;
02237 }
02238
02239 if (peer) {
02240 peer_unref(peer);
02241 }
02242 if (user) {
02243 user_unref(user);
02244 }
02245
02246 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);
02247 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02248 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02249 res = 0;
02250 }
02251
02252 return res;
02253 }
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265 static void set_peercnt_limit(struct peercnt *peercnt)
02266 {
02267 uint16_t limit = global_maxcallno;
02268 struct addr_range *addr_range;
02269 struct sockaddr_in sin = {
02270 .sin_addr.s_addr = peercnt->addr,
02271 };
02272
02273
02274 if (peercnt->reg && peercnt->limit) {
02275 return;
02276 }
02277
02278 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02279 limit = addr_range->limit;
02280 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02281 ao2_ref(addr_range, -1);
02282 }
02283
02284 peercnt->limit = limit;
02285 }
02286
02287
02288
02289
02290
02291 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02292 {
02293 struct peercnt *peercnt = obj;
02294
02295 set_peercnt_limit(peercnt);
02296 ast_debug(1, "Reset limits for peercnts table\n");
02297
02298 return 0;
02299 }
02300
02301
02302
02303
02304
02305 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02306 {
02307 struct addr_range *addr_range = obj;
02308
02309 return addr_range->delme ? CMP_MATCH : 0;
02310 }
02311
02312
02313
02314
02315
02316 static void peercnt_modify(unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
02317 {
02318
02319 struct peercnt *peercnt;
02320 struct peercnt tmp = {
02321 .addr = 0,
02322 };
02323 struct sockaddr_in sin;
02324
02325 ast_sockaddr_to_sin(sockaddr, &sin);
02326
02327 tmp.addr = sin.sin_addr.s_addr;
02328
02329 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02330 peercnt->reg = reg;
02331 if (limit) {
02332 peercnt->limit = limit;
02333 } else {
02334 set_peercnt_limit(peercnt);
02335 }
02336 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02337 ao2_ref(peercnt, -1);
02338 }
02339 }
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349 static int peercnt_add(struct sockaddr_in *sin)
02350 {
02351 struct peercnt *peercnt;
02352 unsigned long addr = sin->sin_addr.s_addr;
02353 int res = 0;
02354 struct peercnt tmp = {
02355 .addr = addr,
02356 };
02357
02358
02359
02360
02361
02362
02363
02364 ao2_lock(peercnts);
02365 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02366 ao2_lock(peercnt);
02367 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02368 ao2_lock(peercnt);
02369
02370 peercnt->addr = addr;
02371 set_peercnt_limit(peercnt);
02372
02373
02374 ao2_link(peercnts, peercnt);
02375 } else {
02376 ao2_unlock(peercnts);
02377 return -1;
02378 }
02379
02380
02381 if (peercnt->limit > peercnt->cur) {
02382 peercnt->cur++;
02383 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02384 } else {
02385 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02386 res = -1;
02387 }
02388
02389
02390 ao2_unlock(peercnt);
02391 ao2_unlock(peercnts);
02392 ao2_ref(peercnt, -1);
02393
02394 return res;
02395 }
02396
02397
02398
02399
02400
02401 static void peercnt_remove(struct peercnt *peercnt)
02402 {
02403 struct sockaddr_in sin = {
02404 .sin_addr.s_addr = peercnt->addr,
02405 };
02406
02407 if (peercnt) {
02408
02409
02410
02411 ao2_lock(peercnts);
02412 peercnt->cur--;
02413 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02414
02415 if (peercnt->cur == 0) {
02416 ao2_unlink(peercnts, peercnt);
02417 }
02418 ao2_unlock(peercnts);
02419 }
02420 }
02421
02422
02423
02424
02425
02426 static int peercnt_remove_cb(const void *obj)
02427 {
02428 struct peercnt *peercnt = (struct peercnt *) obj;
02429
02430 peercnt_remove(peercnt);
02431 ao2_ref(peercnt, -1);
02432
02433 return 0;
02434 }
02435
02436
02437
02438
02439
02440 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02441 {
02442 struct peercnt *peercnt;
02443 struct peercnt tmp = {
02444 .addr = sin->sin_addr.s_addr,
02445 };
02446
02447 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02448 peercnt_remove(peercnt);
02449 ao2_ref(peercnt, -1);
02450 }
02451 return 0;
02452 }
02453
02454
02455
02456
02457
02458 static void build_callno_limits(struct ast_variable *v)
02459 {
02460 struct addr_range *addr_range = NULL;
02461 struct addr_range tmp;
02462 struct ast_ha *ha;
02463 int limit;
02464 int error;
02465 int found;
02466
02467 for (; v; v = v->next) {
02468 limit = -1;
02469 error = 0;
02470 found = 0;
02471 ha = ast_append_ha("permit", v->name, NULL, &error);
02472
02473
02474 if (error) {
02475 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02476 continue;
02477 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02478 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02479 ast_free_ha(ha);
02480 continue;
02481 }
02482
02483 ast_copy_ha(ha, &tmp.ha);
02484
02485 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02486 ao2_lock(addr_range);
02487 found = 1;
02488 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02489 ast_free_ha(ha);
02490 return;
02491 }
02492
02493
02494 ast_copy_ha(ha, &addr_range->ha);
02495 ast_free_ha(ha);
02496 addr_range->limit = limit;
02497 addr_range->delme = 0;
02498
02499
02500 if (found) {
02501 ao2_unlock(addr_range);
02502 } else {
02503 ao2_link(callno_limits, addr_range);
02504 }
02505 ao2_ref(addr_range, -1);
02506 }
02507 }
02508
02509
02510
02511
02512
02513 static int add_calltoken_ignore(const char *addr)
02514 {
02515 struct addr_range tmp;
02516 struct addr_range *addr_range = NULL;
02517 struct ast_ha *ha = NULL;
02518 int error = 0;
02519
02520 if (ast_strlen_zero(addr)) {
02521 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02522 return -1;
02523 }
02524
02525 ha = ast_append_ha("permit", addr, NULL, &error);
02526
02527
02528 if (error) {
02529 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02530 return -1;
02531 }
02532
02533 ast_copy_ha(ha, &tmp.ha);
02534
02535 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02536 ao2_lock(addr_range);
02537 addr_range->delme = 0;
02538 ao2_unlock(addr_range);
02539 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02540
02541 ast_copy_ha(ha, &addr_range->ha);
02542 ao2_link(calltoken_ignores, addr_range);
02543 } else {
02544 ast_free_ha(ha);
02545 return -1;
02546 }
02547
02548 ast_free_ha(ha);
02549 ao2_ref(addr_range, -1);
02550
02551 return 0;
02552 }
02553
02554 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02555 {
02556 struct ao2_iterator i;
02557 struct peercnt *peercnt;
02558 struct sockaddr_in sin;
02559 int found = 0;
02560
02561 switch (cmd) {
02562 case CLI_INIT:
02563 e->command = "iax2 show callnumber usage";
02564 e->usage =
02565 "Usage: iax2 show callnumber usage [IP address]\n"
02566 " Shows current IP addresses which are consuming iax2 call numbers\n";
02567 return NULL;
02568 case CLI_GENERATE:
02569 return NULL;
02570 case CLI_HANDLER:
02571 if (a->argc < 4 || a->argc > 5)
02572 return CLI_SHOWUSAGE;
02573
02574 if (a->argc == 4) {
02575 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02576 }
02577
02578 i = ao2_iterator_init(peercnts, 0);
02579 while ((peercnt = ao2_iterator_next(&i))) {
02580 sin.sin_addr.s_addr = peercnt->addr;
02581 if (a->argc == 5) {
02582 if (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr))) {
02583 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02584 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02585 ao2_ref(peercnt, -1);
02586 found = 1;
02587 break;
02588 }
02589 } else {
02590 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02591 }
02592 ao2_ref(peercnt, -1);
02593 }
02594 ao2_iterator_destroy(&i);
02595
02596 if (a->argc == 4) {
02597 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02598 "Non-CallToken Validated Callno Used: %d\n",
02599 global_maxcallno_nonval,
02600 total_nonval_callno_used);
02601
02602 ast_cli(a->fd, "Total Available Callno: %d\n"
02603 "Regular Callno Available: %d\n"
02604 "Trunk Callno Available: %d\n",
02605 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02606 ao2_container_count(callno_pool),
02607 ao2_container_count(callno_pool_trunk));
02608 } else if (a->argc == 5 && !found) {
02609 ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] );
02610 }
02611
02612
02613 return CLI_SUCCESS;
02614 default:
02615 return NULL;
02616 }
02617 }
02618
02619 static struct callno_entry *get_unused_callno(int trunk, int validated)
02620 {
02621 struct callno_entry *callno_entry = NULL;
02622 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02623 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02624
02625 return NULL;
02626 }
02627
02628
02629
02630 ao2_lock(callno_pool);
02631
02632
02633
02634
02635 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02636 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02637 ao2_unlock(callno_pool);
02638 return NULL;
02639 }
02640
02641
02642
02643 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02644
02645 if (callno_entry) {
02646 callno_entry->validated = validated;
02647 if (!validated) {
02648 total_nonval_callno_used++;
02649 }
02650 }
02651
02652 ao2_unlock(callno_pool);
02653 return callno_entry;
02654 }
02655
02656 static int replace_callno(const void *obj)
02657 {
02658 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02659
02660
02661
02662 ao2_lock(callno_pool);
02663
02664 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02665 total_nonval_callno_used--;
02666 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02667 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02668 }
02669
02670 if (callno_entry->callno < TRUNK_CALL_START) {
02671 ao2_link(callno_pool, callno_entry);
02672 } else {
02673 ao2_link(callno_pool_trunk, callno_entry);
02674 }
02675 ao2_ref(callno_entry, -1);
02676
02677 ao2_unlock(callno_pool);
02678 return 0;
02679 }
02680
02681 static int callno_hash(const void *obj, const int flags)
02682 {
02683 return abs(ast_random());
02684 }
02685
02686 static int create_callno_pools(void)
02687 {
02688 uint16_t i;
02689
02690 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02691 return -1;
02692 }
02693
02694 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02695 return -1;
02696 }
02697
02698
02699 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02700 struct callno_entry *callno_entry;
02701
02702 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02703 return -1;
02704 }
02705
02706 callno_entry->callno = i;
02707
02708 if (i < TRUNK_CALL_START) {
02709 ao2_link(callno_pool, callno_entry);
02710 } else {
02711 ao2_link(callno_pool_trunk, callno_entry);
02712 }
02713
02714 ao2_ref(callno_entry, -1);
02715 }
02716
02717 return 0;
02718 }
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02729 {
02730 int i;
02731 struct peercnt *peercnt;
02732 struct peercnt tmp = {
02733 .addr = sin->sin_addr.s_addr,
02734 };
02735
02736 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02737
02738 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02739 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02740 if (i == -1) {
02741 ao2_ref(peercnt, -1);
02742 }
02743 }
02744
02745 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02746 }
02747
02748
02749
02750
02751
02752
02753
02754
02755 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02756 {
02757 if (frametype != AST_FRAME_IAX) {
02758 return 0;
02759 }
02760 switch (subclass) {
02761 case IAX_COMMAND_NEW:
02762 case IAX_COMMAND_REGREQ:
02763 case IAX_COMMAND_FWDOWNL:
02764 case IAX_COMMAND_REGREL:
02765 return 1;
02766 case IAX_COMMAND_POKE:
02767 if (!inbound) {
02768 return 1;
02769 }
02770 break;
02771 }
02772 return 0;
02773 }
02774
02775
02776
02777
02778 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02779 {
02780 int res = 0;
02781 int x;
02782
02783
02784 int validated = (new > NEW_ALLOW) ? 1 : 0;
02785 char host[80];
02786
02787 if (new <= NEW_ALLOW) {
02788 if (callno) {
02789 struct chan_iax2_pvt *pvt;
02790 struct chan_iax2_pvt tmp_pvt = {
02791 .callno = dcallno,
02792 .peercallno = callno,
02793 .transfercallno = callno,
02794
02795 .frames_received = check_dcallno,
02796 };
02797
02798 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02799
02800 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02801 if (return_locked) {
02802 ast_mutex_lock(&iaxsl[pvt->callno]);
02803 }
02804 res = pvt->callno;
02805 ao2_ref(pvt, -1);
02806 pvt = NULL;
02807 return res;
02808 }
02809
02810 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02811 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02812 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02813 if (return_locked) {
02814 ast_mutex_lock(&iaxsl[pvt->callno]);
02815 }
02816 res = pvt->callno;
02817 ao2_ref(pvt, -1);
02818 pvt = NULL;
02819 return res;
02820 }
02821 }
02822
02823
02824 if (dcallno) {
02825 ast_mutex_lock(&iaxsl[dcallno]);
02826 }
02827 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02828 iaxs[dcallno]->peercallno = callno;
02829 res = dcallno;
02830 store_by_peercallno(iaxs[dcallno]);
02831 if (!res || !return_locked) {
02832 ast_mutex_unlock(&iaxsl[dcallno]);
02833 }
02834 return res;
02835 }
02836 if (dcallno) {
02837 ast_mutex_unlock(&iaxsl[dcallno]);
02838 }
02839 #ifdef IAX_OLD_FIND
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851 for (x = 1; !res && x < maxnontrunkcall; x++) {
02852 ast_mutex_lock(&iaxsl[x]);
02853 if (iaxs[x]) {
02854
02855 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02856 res = x;
02857 }
02858 }
02859 if (!res || !return_locked)
02860 ast_mutex_unlock(&iaxsl[x]);
02861 }
02862 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02863 ast_mutex_lock(&iaxsl[x]);
02864 if (iaxs[x]) {
02865
02866 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02867 res = x;
02868 }
02869 }
02870 if (!res || !return_locked)
02871 ast_mutex_unlock(&iaxsl[x]);
02872 }
02873 #endif
02874 }
02875 if (!res && (new >= NEW_ALLOW)) {
02876 struct callno_entry *callno_entry;
02877
02878
02879
02880
02881
02882
02883 if (!iax2_getpeername(*sin, host, sizeof(host)))
02884 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02885
02886 if (peercnt_add(sin)) {
02887
02888
02889 return 0;
02890 }
02891
02892 if (!(callno_entry = get_unused_callno(0, validated))) {
02893
02894
02895 peercnt_remove_by_addr(sin);
02896 ast_log(LOG_WARNING, "No more space\n");
02897 return 0;
02898 }
02899 x = callno_entry->callno;
02900 ast_mutex_lock(&iaxsl[x]);
02901
02902 iaxs[x] = new_iax(sin, host);
02903 update_max_nontrunk();
02904 if (iaxs[x]) {
02905 if (iaxdebug)
02906 ast_debug(1, "Creating new call structure %d\n", x);
02907 iaxs[x]->callno_entry = callno_entry;
02908 iaxs[x]->sockfd = sockfd;
02909 iaxs[x]->addr.sin_port = sin->sin_port;
02910 iaxs[x]->addr.sin_family = sin->sin_family;
02911 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02912 iaxs[x]->peercallno = callno;
02913 iaxs[x]->callno = x;
02914 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02915 iaxs[x]->expiry = min_reg_expire;
02916 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02917 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02918 iaxs[x]->amaflags = amaflags;
02919 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
02920 ast_string_field_set(iaxs[x], accountcode, accountcode);
02921 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02922 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02923 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02924
02925 if (iaxs[x]->peercallno) {
02926 store_by_peercallno(iaxs[x]);
02927 }
02928 } else {
02929 ast_log(LOG_WARNING, "Out of resources\n");
02930 ast_mutex_unlock(&iaxsl[x]);
02931 replace_callno(callno_entry);
02932 return 0;
02933 }
02934 if (!return_locked)
02935 ast_mutex_unlock(&iaxsl[x]);
02936 res = x;
02937 }
02938 return res;
02939 }
02940
02941 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02942 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02943 }
02944
02945 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02946
02947 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02948 }
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960 static int iax2_queue_frame(int callno, struct ast_frame *f)
02961 {
02962 iax2_lock_owner(callno);
02963 if (iaxs[callno] && iaxs[callno]->owner) {
02964 ast_queue_frame(iaxs[callno]->owner, f);
02965 ast_channel_unlock(iaxs[callno]->owner);
02966 }
02967 return 0;
02968 }
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983 static int iax2_queue_hangup(int callno)
02984 {
02985 iax2_lock_owner(callno);
02986 if (iaxs[callno] && iaxs[callno]->owner) {
02987 ast_queue_hangup(iaxs[callno]->owner);
02988 ast_channel_unlock(iaxs[callno]->owner);
02989 }
02990 return 0;
02991 }
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006 static int iax2_queue_control_data(int callno,
03007 enum ast_control_frame_type control, const void *data, size_t datalen)
03008 {
03009 iax2_lock_owner(callno);
03010 if (iaxs[callno] && iaxs[callno]->owner) {
03011 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
03012 ast_channel_unlock(iaxs[callno]->owner);
03013 }
03014 return 0;
03015 }
03016 static void destroy_firmware(struct iax_firmware *cur)
03017 {
03018
03019 if (cur->fwh) {
03020 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
03021 }
03022 close(cur->fd);
03023 ast_free(cur);
03024 }
03025
03026 static int try_firmware(char *s)
03027 {
03028 struct stat stbuf;
03029 struct iax_firmware *cur = NULL;
03030 int ifd, fd, res, len, chunk;
03031 struct ast_iax2_firmware_header *fwh, fwh2;
03032 struct MD5Context md5;
03033 unsigned char sum[16], buf[1024];
03034 char *s2, *last;
03035
03036 if (!(s2 = alloca(strlen(s) + 100))) {
03037 ast_log(LOG_WARNING, "Alloca failed!\n");
03038 return -1;
03039 }
03040
03041 last = strrchr(s, '/');
03042 if (last)
03043 last++;
03044 else
03045 last = s;
03046
03047 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03048
03049 if ((res = stat(s, &stbuf) < 0)) {
03050 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03051 return -1;
03052 }
03053
03054
03055 if (S_ISDIR(stbuf.st_mode))
03056 return -1;
03057 ifd = open(s, O_RDONLY);
03058 if (ifd < 0) {
03059 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03060 return -1;
03061 }
03062 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03063 if (fd < 0) {
03064 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03065 close(ifd);
03066 return -1;
03067 }
03068
03069 unlink(s2);
03070
03071
03072 len = stbuf.st_size;
03073 while(len) {
03074 chunk = len;
03075 if (chunk > sizeof(buf))
03076 chunk = sizeof(buf);
03077 res = read(ifd, buf, chunk);
03078 if (res != chunk) {
03079 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03080 close(ifd);
03081 close(fd);
03082 return -1;
03083 }
03084 res = write(fd, buf, chunk);
03085 if (res != chunk) {
03086 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03087 close(ifd);
03088 close(fd);
03089 return -1;
03090 }
03091 len -= chunk;
03092 }
03093 close(ifd);
03094
03095 lseek(fd, 0, SEEK_SET);
03096 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03097 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03098 close(fd);
03099 return -1;
03100 }
03101 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03102 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03103 close(fd);
03104 return -1;
03105 }
03106 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03107 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03108 close(fd);
03109 return -1;
03110 }
03111 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03112 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03113 close(fd);
03114 return -1;
03115 }
03116 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
03117 if (fwh == MAP_FAILED) {
03118 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03119 close(fd);
03120 return -1;
03121 }
03122 MD5Init(&md5);
03123 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03124 MD5Final(sum, &md5);
03125 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03126 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03127 munmap((void*)fwh, stbuf.st_size);
03128 close(fd);
03129 return -1;
03130 }
03131
03132 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03133 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03134
03135 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03136
03137 break;
03138
03139
03140 munmap((void*)fwh, stbuf.st_size);
03141 close(fd);
03142 return 0;
03143 }
03144 }
03145
03146 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03147 cur->fd = -1;
03148 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03149 }
03150
03151 if (cur) {
03152 if (cur->fwh)
03153 munmap((void*)cur->fwh, cur->mmaplen);
03154 if (cur->fd > -1)
03155 close(cur->fd);
03156 cur->fwh = fwh;
03157 cur->fd = fd;
03158 cur->mmaplen = stbuf.st_size;
03159 cur->dead = 0;
03160 }
03161
03162 return 0;
03163 }
03164
03165 static int iax_check_version(char *dev)
03166 {
03167 int res = 0;
03168 struct iax_firmware *cur = NULL;
03169
03170 if (ast_strlen_zero(dev))
03171 return 0;
03172
03173 AST_LIST_LOCK(&firmwares);
03174 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03175 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03176 res = ntohs(cur->fwh->version);
03177 break;
03178 }
03179 }
03180 AST_LIST_UNLOCK(&firmwares);
03181
03182 return res;
03183 }
03184
03185 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03186 {
03187 int res = -1;
03188 unsigned int bs = desc & 0xff;
03189 unsigned int start = (desc >> 8) & 0xffffff;
03190 unsigned int bytes;
03191 struct iax_firmware *cur;
03192
03193 if (ast_strlen_zero((char *)dev) || !bs)
03194 return -1;
03195
03196 start *= bs;
03197
03198 AST_LIST_LOCK(&firmwares);
03199 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03200 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03201 continue;
03202 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03203 if (start < ntohl(cur->fwh->datalen)) {
03204 bytes = ntohl(cur->fwh->datalen) - start;
03205 if (bytes > bs)
03206 bytes = bs;
03207 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03208 } else {
03209 bytes = 0;
03210 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03211 }
03212 if (bytes == bs)
03213 res = 0;
03214 else
03215 res = 1;
03216 break;
03217 }
03218 AST_LIST_UNLOCK(&firmwares);
03219
03220 return res;
03221 }
03222
03223
03224 static void reload_firmware(int unload)
03225 {
03226 struct iax_firmware *cur = NULL;
03227 DIR *fwd;
03228 struct dirent *de;
03229 char dir[256], fn[256];
03230
03231 AST_LIST_LOCK(&firmwares);
03232
03233
03234 AST_LIST_TRAVERSE(&firmwares, cur, list)
03235 cur->dead = 1;
03236
03237
03238 if (!unload) {
03239 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03240 fwd = opendir(dir);
03241 if (fwd) {
03242 while((de = readdir(fwd))) {
03243 if (de->d_name[0] != '.') {
03244 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03245 if (!try_firmware(fn)) {
03246 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03247 }
03248 }
03249 }
03250 closedir(fwd);
03251 } else
03252 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03253 }
03254
03255
03256 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03257 if (!cur->dead)
03258 continue;
03259 AST_LIST_REMOVE_CURRENT(list);
03260 destroy_firmware(cur);
03261 }
03262 AST_LIST_TRAVERSE_SAFE_END;
03263
03264 AST_LIST_UNLOCK(&firmwares);
03265 }
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275 static int __do_deliver(void *data)
03276 {
03277
03278
03279 struct iax_frame *fr = data;
03280 fr->retrans = -1;
03281 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03282 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03283 iax2_queue_frame(fr->callno, &fr->af);
03284
03285 iax2_frame_free(fr);
03286
03287 return 0;
03288 }
03289
03290 static int handle_error(void)
03291 {
03292
03293
03294
03295 #if 0
03296 struct sockaddr_in *sin;
03297 int res;
03298 struct msghdr m;
03299 struct sock_extended_err e;
03300 m.msg_name = NULL;
03301 m.msg_namelen = 0;
03302 m.msg_iov = NULL;
03303 m.msg_control = &e;
03304 m.msg_controllen = sizeof(e);
03305 m.msg_flags = 0;
03306 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03307 if (res < 0)
03308 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03309 else {
03310 if (m.msg_controllen) {
03311 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03312 if (sin)
03313 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03314 else
03315 ast_log(LOG_WARNING, "No address detected??\n");
03316 } else {
03317 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03318 }
03319 }
03320 #endif
03321 return 0;
03322 }
03323
03324 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03325 {
03326 int res;
03327 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03328 sizeof(*sin));
03329 if (res < 0) {
03330 ast_debug(1, "Received error: %s\n", strerror(errno));
03331 handle_error();
03332 } else
03333 res = 0;
03334 return res;
03335 }
03336
03337 static int send_packet(struct iax_frame *f)
03338 {
03339 int res;
03340 int callno = f->callno;
03341
03342
03343 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03344 return -1;
03345
03346
03347 if (iaxdebug)
03348 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));
03349
03350 if (f->transfer) {
03351 if (iaxdebug)
03352 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03353 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03354 } else {
03355 if (iaxdebug)
03356 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03357 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03358 }
03359 if (res < 0) {
03360 if (iaxdebug)
03361 ast_debug(1, "Received error: %s\n", strerror(errno));
03362 handle_error();
03363 } else
03364 res = 0;
03365
03366 return res;
03367 }
03368
03369
03370
03371
03372
03373 static int iax2_predestroy(int callno)
03374 {
03375 struct ast_channel *c = NULL;
03376 struct chan_iax2_pvt *pvt = iaxs[callno];
03377
03378 if (!pvt)
03379 return -1;
03380
03381 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03382 iax2_destroy_helper(pvt);
03383 ast_set_flag64(pvt, IAX_ALREADYGONE);
03384 }
03385
03386 if ((c = pvt->owner)) {
03387 c->tech_pvt = NULL;
03388 iax2_queue_hangup(callno);
03389 pvt->owner = NULL;
03390 ast_module_unref(ast_module_info->self);
03391 }
03392
03393 return 0;
03394 }
03395
03396 static void iax2_destroy(int callno)
03397 {
03398 struct chan_iax2_pvt *pvt = NULL;
03399 struct ast_channel *owner = NULL;
03400
03401 retry:
03402 if ((pvt = iaxs[callno])) {
03403 #if 0
03404
03405
03406
03407
03408
03409
03410
03411 iax2_destroy_helper(pvt);
03412 #endif
03413 }
03414
03415 owner = pvt ? pvt->owner : NULL;
03416
03417 if (owner) {
03418 if (ast_channel_trylock(owner)) {
03419 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03420 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03421 goto retry;
03422 }
03423 }
03424
03425 if (!owner) {
03426 iaxs[callno] = NULL;
03427 }
03428
03429 if (pvt) {
03430 if (!owner) {
03431 pvt->owner = NULL;
03432 } else {
03433
03434
03435
03436 ast_queue_hangup(owner);
03437 }
03438
03439 if (pvt->peercallno) {
03440 remove_by_peercallno(pvt);
03441 }
03442
03443 if (pvt->transfercallno) {
03444 remove_by_transfercallno(pvt);
03445 }
03446
03447 if (!owner) {
03448 ao2_ref(pvt, -1);
03449 pvt = NULL;
03450 }
03451 }
03452
03453 if (owner) {
03454 ast_channel_unlock(owner);
03455 }
03456
03457 if (callno & TRUNK_CALL_START) {
03458 update_max_trunk();
03459 }
03460 }
03461
03462 static int update_packet(struct iax_frame *f)
03463 {
03464
03465 struct ast_iax2_full_hdr *fh = f->data;
03466 struct ast_frame af;
03467
03468
03469 if (f->encmethods) {
03470 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03471 }
03472
03473 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03474
03475 f->iseqno = iaxs[f->callno]->iseqno;
03476 fh->iseqno = f->iseqno;
03477
03478
03479 if (f->encmethods) {
03480
03481
03482 build_rand_pad(f->semirand, sizeof(f->semirand));
03483 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03484 }
03485 return 0;
03486 }
03487
03488 static int attempt_transmit(const void *data);
03489 static void __attempt_transmit(const void *data)
03490 {
03491
03492
03493 struct iax_frame *f = (struct iax_frame *)data;
03494 int freeme = 0;
03495 int callno = f->callno;
03496
03497 if (callno)
03498 ast_mutex_lock(&iaxsl[callno]);
03499 if (callno && iaxs[callno]) {
03500 if ((f->retries < 0) ||
03501 (f->retries >= max_retries) ) {
03502
03503 if (f->retries >= max_retries) {
03504 if (f->transfer) {
03505
03506 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03507 } else if (f->final) {
03508 iax2_destroy(callno);
03509 } else {
03510 if (iaxs[callno]->owner)
03511 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);
03512 iaxs[callno]->error = ETIMEDOUT;
03513 if (iaxs[callno]->owner) {
03514 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03515
03516 iax2_queue_frame(callno, &fr);
03517
03518 if (iaxs[callno] && iaxs[callno]->owner)
03519 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03520 } else {
03521 if (iaxs[callno]->reg) {
03522 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03523 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03524 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03525 }
03526 iax2_destroy(callno);
03527 }
03528 }
03529
03530 }
03531 freeme = 1;
03532 } else {
03533
03534 update_packet(f);
03535
03536 send_packet(f);
03537 f->retries++;
03538
03539 f->retrytime *= 10;
03540 if (f->retrytime > MAX_RETRY_TIME)
03541 f->retrytime = MAX_RETRY_TIME;
03542
03543 if (f->transfer && (f->retrytime > 1000))
03544 f->retrytime = 1000;
03545 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03546 }
03547 } else {
03548
03549 f->retries = -1;
03550 freeme = 1;
03551 }
03552
03553 if (freeme) {
03554
03555 AST_LIST_REMOVE(&frame_queue[callno], f, list);
03556 ast_mutex_unlock(&iaxsl[callno]);
03557 f->retrans = -1;
03558
03559 iax2_frame_free(f);
03560 } else if (callno) {
03561 ast_mutex_unlock(&iaxsl[callno]);
03562 }
03563 }
03564
03565 static int attempt_transmit(const void *data)
03566 {
03567 #ifdef SCHED_MULTITHREADED
03568 if (schedule_action(__attempt_transmit, data))
03569 #endif
03570 __attempt_transmit(data);
03571 return 0;
03572 }
03573
03574 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03575 {
03576 struct iax2_peer *peer = NULL;
03577 struct iax2_user *user = NULL;
03578 static const char * const choices[] = { "all", NULL };
03579 char *cmplt;
03580
03581 switch (cmd) {
03582 case CLI_INIT:
03583 e->command = "iax2 prune realtime";
03584 e->usage =
03585 "Usage: iax2 prune realtime [<peername>|all]\n"
03586 " Prunes object(s) from the cache\n";
03587 return NULL;
03588 case CLI_GENERATE:
03589 if (a->pos == 3) {
03590 cmplt = ast_cli_complete(a->word, choices, a->n);
03591 if (!cmplt)
03592 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03593 return cmplt;
03594 }
03595 return NULL;
03596 }
03597 if (a->argc != 4)
03598 return CLI_SHOWUSAGE;
03599 if (!strcmp(a->argv[3], "all")) {
03600 prune_users();
03601 prune_peers();
03602 ast_cli(a->fd, "Cache flushed successfully.\n");
03603 return CLI_SUCCESS;
03604 }
03605 peer = find_peer(a->argv[3], 0);
03606 user = find_user(a->argv[3]);
03607 if (peer || user) {
03608 if (peer) {
03609 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03610 ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03611 expire_registry(peer_ref(peer));
03612 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03613 } else {
03614 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03615 }
03616 peer_unref(peer);
03617 }
03618 if (user) {
03619 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03620 ast_set_flag64(user, IAX_RTAUTOCLEAR);
03621 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03622 } else {
03623 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03624 }
03625 ao2_unlink(users,user);
03626 user_unref(user);
03627 }
03628 } else {
03629 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03630 }
03631
03632 return CLI_SUCCESS;
03633 }
03634
03635 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03636 {
03637 switch (cmd) {
03638 case CLI_INIT:
03639 e->command = "iax2 test losspct";
03640 e->usage =
03641 "Usage: iax2 test losspct <percentage>\n"
03642 " For testing, throws away <percentage> percent of incoming packets\n";
03643 return NULL;
03644 case CLI_GENERATE:
03645 return NULL;
03646 }
03647 if (a->argc != 4)
03648 return CLI_SHOWUSAGE;
03649
03650 test_losspct = atoi(a->argv[3]);
03651
03652 return CLI_SUCCESS;
03653 }
03654
03655 #ifdef IAXTESTS
03656 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03657 {
03658 switch (cmd) {
03659 case CLI_INIT:
03660 e->command = "iax2 test late";
03661 e->usage =
03662 "Usage: iax2 test late <ms>\n"
03663 " For testing, count the next frame as <ms> ms late\n";
03664 return NULL;
03665 case CLI_GENERATE:
03666 return NULL;
03667 }
03668
03669 if (a->argc != 4)
03670 return CLI_SHOWUSAGE;
03671
03672 test_late = atoi(a->argv[3]);
03673
03674 return CLI_SUCCESS;
03675 }
03676
03677 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03678 {
03679 switch (cmd) {
03680 case CLI_INIT:
03681 e->command = "iax2 test resync";
03682 e->usage =
03683 "Usage: iax2 test resync <ms>\n"
03684 " For testing, adjust all future frames by <ms> ms\n";
03685 return NULL;
03686 case CLI_GENERATE:
03687 return NULL;
03688 }
03689
03690 if (a->argc != 4)
03691 return CLI_SHOWUSAGE;
03692
03693 test_resync = atoi(a->argv[3]);
03694
03695 return CLI_SUCCESS;
03696 }
03697
03698 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03699 {
03700 switch (cmd) {
03701 case CLI_INIT:
03702 e->command = "iax2 test jitter";
03703 e->usage =
03704 "Usage: iax2 test jitter <ms> <pct>\n"
03705 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03706 " percentage of packets. If <pct> is not specified, adds\n"
03707 " jitter to all packets.\n";
03708 return NULL;
03709 case CLI_GENERATE:
03710 return NULL;
03711 }
03712
03713 if (a->argc < 4 || a->argc > 5)
03714 return CLI_SHOWUSAGE;
03715
03716 test_jit = atoi(a->argv[3]);
03717 if (a->argc == 5)
03718 test_jitpct = atoi(a->argv[4]);
03719
03720 return CLI_SUCCESS;
03721 }
03722 #endif
03723
03724
03725
03726 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03727 {
03728 int res = 0;
03729 if (peer->maxms) {
03730 if (peer->lastms < 0) {
03731 ast_copy_string(status, "UNREACHABLE", statuslen);
03732 } else if (peer->lastms > peer->maxms) {
03733 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03734 res = 1;
03735 } else if (peer->lastms) {
03736 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03737 res = 1;
03738 } else {
03739 ast_copy_string(status, "UNKNOWN", statuslen);
03740 }
03741 } else {
03742 ast_copy_string(status, "Unmonitored", statuslen);
03743 res = -1;
03744 }
03745 return res;
03746 }
03747
03748
03749 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03750 {
03751 char status[30];
03752 char cbuf[256];
03753 struct iax2_peer *peer;
03754 char codec_buf[512];
03755 struct ast_str *encmethods = ast_str_alloca(256);
03756 int x = 0, codec = 0, load_realtime = 0;
03757
03758 switch (cmd) {
03759 case CLI_INIT:
03760 e->command = "iax2 show peer";
03761 e->usage =
03762 "Usage: iax2 show peer <name>\n"
03763 " Display details on specific IAX peer\n";
03764 return NULL;
03765 case CLI_GENERATE:
03766 if (a->pos == 3)
03767 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03768 return NULL;
03769 }
03770
03771 if (a->argc < 4)
03772 return CLI_SHOWUSAGE;
03773
03774 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03775
03776 peer = find_peer(a->argv[3], load_realtime);
03777 if (peer) {
03778 struct sockaddr_in peer_addr;
03779
03780 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03781
03782 encmethods_to_str(peer->encmethods, encmethods);
03783 ast_cli(a->fd, "\n\n");
03784 ast_cli(a->fd, " * Name : %s\n", peer->name);
03785 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03786 ast_cli(a->fd, " Context : %s\n", peer->context);
03787 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03788 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03789 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03790 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03791 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03792 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03793 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03794 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03795 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03796 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03797 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));
03798 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03799 ast_cli(a->fd, " Username : %s\n", peer->username);
03800 ast_cli(a->fd, " Codecs : ");
03801 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03802 ast_cli(a->fd, "%s\n", codec_buf);
03803
03804 ast_cli(a->fd, " Codec Order : (");
03805 for(x = 0; x < 32 ; x++) {
03806 codec = ast_codec_pref_index(&peer->prefs,x);
03807 if(!codec)
03808 break;
03809 ast_cli(a->fd, "%s", ast_getformatname(codec));
03810 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03811 ast_cli(a->fd, "|");
03812 }
03813
03814 if (!x)
03815 ast_cli(a->fd, "none");
03816 ast_cli(a->fd, ")\n");
03817
03818 ast_cli(a->fd, " Status : ");
03819 peer_status(peer, status, sizeof(status));
03820 ast_cli(a->fd, "%s\n",status);
03821 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");
03822 ast_cli(a->fd, "\n");
03823 peer_unref(peer);
03824 } else {
03825 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03826 ast_cli(a->fd, "\n");
03827 }
03828
03829 return CLI_SUCCESS;
03830 }
03831
03832 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
03833 {
03834 int which = 0;
03835 struct iax2_peer *peer;
03836 char *res = NULL;
03837 int wordlen = strlen(word);
03838 struct ao2_iterator i;
03839
03840 i = ao2_iterator_init(peers, 0);
03841 while ((peer = ao2_iterator_next(&i))) {
03842 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03843 && (!flags || ast_test_flag64(peer, flags))) {
03844 res = ast_strdup(peer->name);
03845 peer_unref(peer);
03846 break;
03847 }
03848 peer_unref(peer);
03849 }
03850 ao2_iterator_destroy(&i);
03851
03852 return res;
03853 }
03854
03855 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03856 {
03857 struct iax_frame *cur;
03858 int cnt = 0, dead = 0, final = 0, i = 0;
03859
03860 switch (cmd) {
03861 case CLI_INIT:
03862 e->command = "iax2 show stats";
03863 e->usage =
03864 "Usage: iax2 show stats\n"
03865 " Display statistics on IAX channel driver.\n";
03866 return NULL;
03867 case CLI_GENERATE:
03868 return NULL;
03869 }
03870
03871 if (a->argc != 3)
03872 return CLI_SHOWUSAGE;
03873
03874 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03875 ast_mutex_lock(&iaxsl[i]);
03876 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03877 if (cur->retries < 0)
03878 dead++;
03879 if (cur->final)
03880 final++;
03881 cnt++;
03882 }
03883 ast_mutex_unlock(&iaxsl[i]);
03884 }
03885
03886 ast_cli(a->fd, " IAX Statistics\n");
03887 ast_cli(a->fd, "---------------------\n");
03888 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03889 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03890 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03891 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03892
03893 trunk_timed = trunk_untimed = 0;
03894 if (trunk_maxmtu > trunk_nmaxmtu)
03895 trunk_nmaxmtu = trunk_maxmtu;
03896
03897 return CLI_SUCCESS;
03898 }
03899
03900
03901 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03902 {
03903 int mtuv;
03904
03905 switch (cmd) {
03906 case CLI_INIT:
03907 e->command = "iax2 set mtu";
03908 e->usage =
03909 "Usage: iax2 set mtu <value>\n"
03910 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03911 " zero to disable. Disabling means that the operating system\n"
03912 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03913 " packet exceeds the UDP payload size. This is substantially\n"
03914 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03915 " greater for G.711 samples.\n";
03916 return NULL;
03917 case CLI_GENERATE:
03918 return NULL;
03919 }
03920
03921 if (a->argc != 4)
03922 return CLI_SHOWUSAGE;
03923 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03924 mtuv = MAX_TRUNK_MTU;
03925 else
03926 mtuv = atoi(a->argv[3]);
03927
03928 if (mtuv == 0) {
03929 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03930 global_max_trunk_mtu = 0;
03931 return CLI_SUCCESS;
03932 }
03933 if (mtuv < 172 || mtuv > 4000) {
03934 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03935 return CLI_SHOWUSAGE;
03936 }
03937 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03938 global_max_trunk_mtu = mtuv;
03939 return CLI_SUCCESS;
03940 }
03941
03942 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03943 {
03944 struct iax2_dpcache *dp = NULL;
03945 char tmp[1024], *pc = NULL;
03946 int s, x, y;
03947 struct timeval now = ast_tvnow();
03948
03949 switch (cmd) {
03950 case CLI_INIT:
03951 e->command = "iax2 show cache";
03952 e->usage =
03953 "Usage: iax2 show cache\n"
03954 " Display currently cached IAX Dialplan results.\n";
03955 return NULL;
03956 case CLI_GENERATE:
03957 return NULL;
03958 }
03959
03960 AST_LIST_LOCK(&dpcache);
03961
03962 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03963
03964 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03965 s = dp->expiry.tv_sec - now.tv_sec;
03966 tmp[0] = '\0';
03967 if (dp->flags & CACHE_FLAG_EXISTS)
03968 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03969 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03970 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03971 if (dp->flags & CACHE_FLAG_CANEXIST)
03972 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03973 if (dp->flags & CACHE_FLAG_PENDING)
03974 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03975 if (dp->flags & CACHE_FLAG_TIMEOUT)
03976 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03977 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03978 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03979 if (dp->flags & CACHE_FLAG_MATCHMORE)
03980 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03981 if (dp->flags & CACHE_FLAG_UNKNOWN)
03982 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03983
03984 if (!ast_strlen_zero(tmp)) {
03985 tmp[strlen(tmp) - 1] = '\0';
03986 } else {
03987 ast_copy_string(tmp, "(none)", sizeof(tmp));
03988 }
03989 y = 0;
03990 pc = strchr(dp->peercontext, '@');
03991 if (!pc) {
03992 pc = dp->peercontext;
03993 } else {
03994 pc++;
03995 }
03996 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03997 if (dp->waiters[x] > -1)
03998 y++;
03999 }
04000 if (s > 0) {
04001 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
04002 } else {
04003 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
04004 }
04005 }
04006
04007 AST_LIST_UNLOCK(&dpcache);
04008
04009 return CLI_SUCCESS;
04010 }
04011
04012 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
04013
04014 static void unwrap_timestamp(struct iax_frame *fr)
04015 {
04016
04017
04018 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
04019 const int lower_mask = (1 << ts_shift) - 1;
04020 const int upper_mask = ~lower_mask;
04021 const int last_upper = iaxs[fr->callno]->last & upper_mask;
04022
04023 if ( (fr->ts & upper_mask) == last_upper ) {
04024 const int x = fr->ts - iaxs[fr->callno]->last;
04025 const int threshold = (ts_shift == 15) ? 25000 : 50000;
04026
04027 if (x < -threshold) {
04028
04029
04030
04031
04032 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04033 if (iaxdebug)
04034 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04035 } else if (x > threshold) {
04036
04037
04038
04039
04040 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04041 if (iaxdebug)
04042 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04043 }
04044 }
04045 }
04046
04047 static int get_from_jb(const void *p);
04048
04049 static void update_jbsched(struct chan_iax2_pvt *pvt)
04050 {
04051 int when;
04052
04053 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04054
04055 when = jb_next(pvt->jb) - when;
04056
04057 if (when <= 0) {
04058
04059 when = 1;
04060 }
04061
04062 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
04063 CALLNO_TO_PTR(pvt->callno));
04064 }
04065
04066 static void __get_from_jb(const void *p)
04067 {
04068 int callno = PTR_TO_CALLNO(p);
04069 struct chan_iax2_pvt *pvt = NULL;
04070 struct iax_frame *fr;
04071 jb_frame frame;
04072 int ret;
04073 long ms;
04074 long next;
04075 struct timeval now = ast_tvnow();
04076
04077
04078 ast_mutex_lock(&iaxsl[callno]);
04079 pvt = iaxs[callno];
04080 if (!pvt) {
04081
04082 ast_mutex_unlock(&iaxsl[callno]);
04083 return;
04084 }
04085
04086 pvt->jbid = -1;
04087
04088
04089
04090
04091 now.tv_usec += 1000;
04092
04093 ms = ast_tvdiff_ms(now, pvt->rxcore);
04094
04095 if(ms >= (next = jb_next(pvt->jb))) {
04096 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
04097 switch(ret) {
04098 case JB_OK:
04099 fr = frame.data;
04100 __do_deliver(fr);
04101
04102 pvt = iaxs[callno];
04103 break;
04104 case JB_INTERP:
04105 {
04106 struct ast_frame af = { 0, };
04107
04108
04109 af.frametype = AST_FRAME_VOICE;
04110 af.subclass.codec = pvt->voiceformat;
04111 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
04112 af.src = "IAX2 JB interpolation";
04113 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04114 af.offset = AST_FRIENDLY_OFFSET;
04115
04116
04117
04118 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04119 iax2_queue_frame(callno, &af);
04120
04121 pvt = iaxs[callno];
04122 }
04123 }
04124 break;
04125 case JB_DROP:
04126 iax2_frame_free(frame.data);
04127 break;
04128 case JB_NOFRAME:
04129 case JB_EMPTY:
04130
04131 break;
04132 default:
04133
04134 break;
04135 }
04136 }
04137 if (pvt)
04138 update_jbsched(pvt);
04139 ast_mutex_unlock(&iaxsl[callno]);
04140 }
04141
04142 static int get_from_jb(const void *data)
04143 {
04144 #ifdef SCHED_MULTITHREADED
04145 if (schedule_action(__get_from_jb, data))
04146 #endif
04147 __get_from_jb(data);
04148 return 0;
04149 }
04150
04151
04152
04153
04154
04155
04156
04157 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
04158 {
04159 int type, len;
04160 int ret;
04161 int needfree = 0;
04162 struct ast_channel *owner = NULL;
04163 struct ast_channel *bridge = NULL;
04164
04165
04166
04167
04168
04169
04170 if (!fr->af.datalen) {
04171 memset(&fr->af.data, 0, sizeof(fr->af.data));
04172 }
04173
04174
04175 unwrap_timestamp(fr);
04176
04177
04178 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04179 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04180 else {
04181 #if 0
04182 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04183 #endif
04184 fr->af.delivery = ast_tv(0,0);
04185 }
04186
04187 type = JB_TYPE_CONTROL;
04188 len = 0;
04189
04190 if(fr->af.frametype == AST_FRAME_VOICE) {
04191 type = JB_TYPE_VOICE;
04192 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04193 } else if(fr->af.frametype == AST_FRAME_CNG) {
04194 type = JB_TYPE_SILENCE;
04195 }
04196
04197 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04198 if (tsout)
04199 *tsout = fr->ts;
04200 __do_deliver(fr);
04201 return -1;
04202 }
04203
04204 iax2_lock_owner(fr->callno);
04205 if (!iaxs[fr->callno]) {
04206
04207 iax2_frame_free(fr);
04208 return -1;
04209 }
04210 if ((owner = iaxs[fr->callno]->owner))
04211 bridge = ast_bridged_channel(owner);
04212
04213
04214
04215 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04216 jb_frame frame;
04217
04218 ast_channel_unlock(owner);
04219
04220
04221 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04222 __do_deliver(frame.data);
04223
04224 if (!iaxs[fr->callno])
04225 return -1;
04226 }
04227
04228 jb_reset(iaxs[fr->callno]->jb);
04229
04230 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04231
04232
04233 if (tsout)
04234 *tsout = fr->ts;
04235 __do_deliver(fr);
04236 return -1;
04237 }
04238 if (owner) {
04239 ast_channel_unlock(owner);
04240 }
04241
04242
04243
04244 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04245 calc_rxstamp(iaxs[fr->callno],fr->ts));
04246 if (ret == JB_DROP) {
04247 needfree++;
04248 } else if (ret == JB_SCHED) {
04249 update_jbsched(iaxs[fr->callno]);
04250 }
04251 if (tsout)
04252 *tsout = fr->ts;
04253 if (needfree) {
04254
04255 iax2_frame_free(fr);
04256 return -1;
04257 }
04258 return 0;
04259 }
04260
04261 static int transmit_frame(void *data)
04262 {
04263 struct iax_frame *fr = data;
04264
04265 ast_mutex_lock(&iaxsl[fr->callno]);
04266
04267 fr->sentyet = 1;
04268
04269 if (iaxs[fr->callno]) {
04270 send_packet(fr);
04271 }
04272
04273 if (fr->retries < 0) {
04274 ast_mutex_unlock(&iaxsl[fr->callno]);
04275
04276 iax_frame_free(fr);
04277 } else {
04278
04279 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04280 fr->retries++;
04281 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04282 ast_mutex_unlock(&iaxsl[fr->callno]);
04283 }
04284
04285 return 0;
04286 }
04287
04288 static int iax2_transmit(struct iax_frame *fr)
04289 {
04290 fr->sentyet = 0;
04291
04292 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04293 }
04294
04295 static int iax2_digit_begin(struct ast_channel *c, char digit)
04296 {
04297 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04298 }
04299
04300 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04301 {
04302 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04303 }
04304
04305 static int iax2_sendtext(struct ast_channel *c, const char *text)
04306 {
04307
04308 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04309 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04310 }
04311
04312 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04313 {
04314 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04315 }
04316
04317 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04318 {
04319 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04320 }
04321
04322 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04323 {
04324 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04325 ast_mutex_lock(&iaxsl[callno]);
04326 if (iaxs[callno])
04327 iaxs[callno]->owner = newchan;
04328 else
04329 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04330 ast_mutex_unlock(&iaxsl[callno]);
04331 return 0;
04332 }
04333
04334
04335
04336
04337
04338 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04339 {
04340 struct ast_variable *var = NULL;
04341 struct ast_variable *tmp;
04342 struct iax2_peer *peer=NULL;
04343 time_t regseconds = 0, nowtime;
04344 int dynamic=0;
04345
04346 if (peername) {
04347 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04348 if (!var && sin)
04349 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04350 } else if (sin) {
04351 char porta[25];
04352 sprintf(porta, "%d", ntohs(sin->sin_port));
04353 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04354 if (var) {
04355
04356 for (tmp = var; tmp; tmp = tmp->next) {
04357 if (!strcasecmp(tmp->name, "name"))
04358 peername = tmp->value;
04359 }
04360 }
04361 }
04362 if (!var && peername) {
04363 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04364
04365
04366
04367
04368
04369
04370 if (var && sin) {
04371 for (tmp = var; tmp; tmp = tmp->next) {
04372 if (!strcasecmp(tmp->name, "host")) {
04373 struct ast_hostent ahp;
04374 struct hostent *hp;
04375 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
04376
04377 ast_variables_destroy(var);
04378 var = NULL;
04379 }
04380 break;
04381 }
04382 }
04383 }
04384 }
04385 if (!var)
04386 return NULL;
04387
04388 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04389
04390 if (!peer) {
04391 ast_variables_destroy(var);
04392 return NULL;
04393 }
04394
04395 for (tmp = var; tmp; tmp = tmp->next) {
04396
04397 if (!strcasecmp(tmp->name, "type")) {
04398 if (strcasecmp(tmp->value, "friend") &&
04399 strcasecmp(tmp->value, "peer")) {
04400
04401 peer = peer_unref(peer);
04402 break;
04403 }
04404 } else if (!strcasecmp(tmp->name, "regseconds")) {
04405 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04406 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04407 ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE);
04408 } else if (!strcasecmp(tmp->name, "port")) {
04409 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04410 } else if (!strcasecmp(tmp->name, "host")) {
04411 if (!strcasecmp(tmp->value, "dynamic"))
04412 dynamic = 1;
04413 }
04414 }
04415
04416 ast_variables_destroy(var);
04417
04418 if (!peer)
04419 return NULL;
04420
04421 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04422 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04423 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04424 if (peer->expire > -1) {
04425 if (!ast_sched_thread_del(sched, peer->expire)) {
04426 peer->expire = -1;
04427 peer_unref(peer);
04428 }
04429 }
04430 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04431 if (peer->expire == -1)
04432 peer_unref(peer);
04433 }
04434 ao2_link(peers, peer);
04435 if (ast_test_flag64(peer, IAX_DYNAMIC))
04436 reg_source_db(peer);
04437 } else {
04438 ast_set_flag64(peer, IAX_TEMPONLY);
04439 }
04440
04441 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04442 time(&nowtime);
04443 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04444 memset(&peer->addr, 0, sizeof(peer->addr));
04445 realtime_update_peer(peer->name, &peer->addr, 0);
04446 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04447 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04448 }
04449 else {
04450 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04451 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04452 }
04453 }
04454
04455 return peer;
04456 }
04457
04458 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04459 {
04460 struct ast_variable *var;
04461 struct ast_variable *tmp;
04462 struct iax2_user *user=NULL;
04463
04464 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04465 if (!var)
04466 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04467 if (!var && sin) {
04468 char porta[6];
04469 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04470 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04471 if (!var)
04472 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04473 }
04474 if (!var) {
04475 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04476
04477
04478
04479
04480
04481
04482 if (var) {
04483 for (tmp = var; tmp; tmp = tmp->next) {
04484 if (!strcasecmp(tmp->name, "host")) {
04485 struct ast_hostent ahp;
04486 struct hostent *hp;
04487 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
04488
04489 ast_variables_destroy(var);
04490 var = NULL;
04491 }
04492 break;
04493 }
04494 }
04495 }
04496 }
04497 if (!var)
04498 return NULL;
04499
04500 tmp = var;
04501 while(tmp) {
04502
04503 if (!strcasecmp(tmp->name, "type")) {
04504 if (strcasecmp(tmp->value, "friend") &&
04505 strcasecmp(tmp->value, "user")) {
04506 return NULL;
04507 }
04508 }
04509 tmp = tmp->next;
04510 }
04511
04512 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04513
04514 ast_variables_destroy(var);
04515
04516 if (!user)
04517 return NULL;
04518
04519 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04520 ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04521 ao2_link(users, user);
04522 } else {
04523 ast_set_flag64(user, IAX_TEMPONLY);
04524 }
04525
04526 return user;
04527 }
04528
04529 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
04530 {
04531 char port[10];
04532 char regseconds[20];
04533 const char *sysname = ast_config_AST_SYSTEM_NAME;
04534 char *syslabel = NULL;
04535
04536 if (ast_strlen_zero(sysname))
04537 sysname = NULL;
04538 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04539 syslabel = "regserver";
04540
04541 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04542 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04543 ast_update_realtime("iaxpeers", "name", peername,
04544 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port,
04545 "regseconds", regseconds, syslabel, sysname, SENTINEL);
04546 }
04547
04548 struct create_addr_info {
04549 format_t capability;
04550 uint64_t flags;
04551 int maxtime;
04552 int encmethods;
04553 int found;
04554 int sockfd;
04555 int adsi;
04556 char username[80];
04557 char secret[80];
04558 char outkey[80];
04559 char timezone[80];
04560 char prefs[32];
04561 char cid_num[80];
04562 char cid_name[80];
04563 char context[AST_MAX_CONTEXT];
04564 char peercontext[AST_MAX_CONTEXT];
04565 char mohinterpret[MAX_MUSICCLASS];
04566 char mohsuggest[MAX_MUSICCLASS];
04567 };
04568
04569 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04570 {
04571 struct iax2_peer *peer;
04572 int res = -1;
04573 struct ast_codec_pref ourprefs;
04574 struct sockaddr_in peer_addr;
04575
04576 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04577 cai->sockfd = defaultsockfd;
04578 cai->maxtime = 0;
04579 sin->sin_family = AF_INET;
04580
04581 if (!(peer = find_peer(peername, 1))) {
04582 struct ast_sockaddr sin_tmp;
04583
04584 cai->found = 0;
04585 sin_tmp.ss.ss_family = AF_INET;
04586 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04587 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04588 return -1;
04589 }
04590 ast_sockaddr_to_sin(&sin_tmp, sin);
04591 if (sin->sin_port == 0) {
04592 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04593 }
04594
04595
04596 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04597 if (c)
04598 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04599 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04600 return 0;
04601 }
04602
04603 cai->found = 1;
04604
04605 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04606
04607
04608 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04609 goto return_unref;
04610 }
04611
04612
04613 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04614 goto return_unref;
04615
04616 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04617 cai->maxtime = peer->maxms;
04618 cai->capability = peer->capability;
04619 cai->encmethods = peer->encmethods;
04620 cai->sockfd = peer->sockfd;
04621 cai->adsi = peer->adsi;
04622 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04623
04624 if (c) {
04625 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04626 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04627 }
04628 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04629 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04630 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04631 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04632 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04633 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04634 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04635 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04636 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04637 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04638 if (ast_strlen_zero(peer->dbsecret)) {
04639 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04640 } else {
04641 char *family;
04642 char *key = NULL;
04643
04644 family = ast_strdupa(peer->dbsecret);
04645 key = strchr(family, '/');
04646 if (key)
04647 *key++ = '\0';
04648 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04649 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04650 goto return_unref;
04651 }
04652 }
04653
04654 if (peer_addr.sin_addr.s_addr) {
04655 sin->sin_addr = peer_addr.sin_addr;
04656 sin->sin_port = peer_addr.sin_port;
04657 } else {
04658 sin->sin_addr = peer->defaddr.sin_addr;
04659 sin->sin_port = peer->defaddr.sin_port;
04660 }
04661
04662 res = 0;
04663
04664 return_unref:
04665 peer_unref(peer);
04666
04667 return res;
04668 }
04669
04670 static void __auto_congest(const void *nothing)
04671 {
04672 int callno = PTR_TO_CALLNO(nothing);
04673 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04674 ast_mutex_lock(&iaxsl[callno]);
04675 if (iaxs[callno]) {
04676 iaxs[callno]->initid = -1;
04677 iax2_queue_frame(callno, &f);
04678 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04679 }
04680 ast_mutex_unlock(&iaxsl[callno]);
04681 }
04682
04683 static int auto_congest(const void *data)
04684 {
04685 #ifdef SCHED_MULTITHREADED
04686 if (schedule_action(__auto_congest, data))
04687 #endif
04688 __auto_congest(data);
04689 return 0;
04690 }
04691
04692 static unsigned int iax2_datetime(const char *tz)
04693 {
04694 struct timeval t = ast_tvnow();
04695 struct ast_tm tm;
04696 unsigned int tmp;
04697 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04698 tmp = (tm.tm_sec >> 1) & 0x1f;
04699 tmp |= (tm.tm_min & 0x3f) << 5;
04700 tmp |= (tm.tm_hour & 0x1f) << 11;
04701 tmp |= (tm.tm_mday & 0x1f) << 16;
04702 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04703 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04704 return tmp;
04705 }
04706
04707 struct parsed_dial_string {
04708 char *username;
04709 char *password;
04710 char *key;
04711 char *peer;
04712 char *port;
04713 char *exten;
04714 char *context;
04715 char *options;
04716 };
04717
04718 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04719 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04720 int sockfd, struct iax_ie_data *ied)
04721 {
04722 struct {
04723 struct ast_iax2_full_hdr f;
04724 struct iax_ie_data ied;
04725 } data;
04726 size_t size = sizeof(struct ast_iax2_full_hdr);
04727
04728 if (ied) {
04729 size += ied->pos;
04730 memcpy(&data.ied, ied->buf, ied->pos);
04731 }
04732
04733 data.f.scallno = htons(0x8000 | callno);
04734 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS);
04735 data.f.ts = htonl(ts);
04736 data.f.iseqno = seqno;
04737 data.f.oseqno = 0;
04738 data.f.type = AST_FRAME_IAX;
04739 data.f.csub = compress_subclass(command);
04740
04741 if (iaxdebug) {
04742 iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr));
04743 }
04744
04745 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04746 }
04747
04748 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04749 {
04750
04751 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04752 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04753 ied->buf[ied->pos++] = 0;
04754 pvt->calltoken_ie_len = 2;
04755 }
04756 }
04757
04758 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04759 {
04760 struct chan_iax2_pvt *pvt = iaxs[callno];
04761 int frametype = f->af.frametype;
04762 int subclass = f->af.subclass.integer;
04763 struct {
04764 struct ast_iax2_full_hdr fh;
04765 struct iax_ie_data ied;
04766 } data = {
04767 .ied.buf = { 0 },
04768 .ied.pos = 0,
04769 };
04770
04771 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04772
04773 if (!pvt) {
04774 return;
04775 }
04776
04777
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04789 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04790 (f->datalen > sizeof(data))) {
04791
04792 return;
04793 }
04794
04795
04796
04797
04798
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808
04809 memcpy(&data, f->data, f->datalen);
04810 data.ied.pos = ie_data_pos;
04811
04812
04813
04814 data.ied.pos -= pvt->calltoken_ie_len;
04815 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04816
04817
04818 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04819
04820
04821 AST_LIST_REMOVE(&frame_queue[callno], f, list);
04822
04823
04824 iax2_frame_free(f);
04825
04826
04827 pvt->oseqno = 0;
04828 pvt->rseqno = 0;
04829 pvt->iseqno = 0;
04830 pvt->aseqno = 0;
04831 if (pvt->peercallno) {
04832 remove_by_peercallno(pvt);
04833 pvt->peercallno = 0;
04834 }
04835
04836
04837 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04838 }
04839
04840 static void requirecalltoken_mark_auto(const char *name, int subclass)
04841 {
04842 struct iax2_user *user = NULL;
04843 struct iax2_peer *peer = NULL;
04844
04845 if (ast_strlen_zero(name)) {
04846 return;
04847 }
04848
04849 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04850 user->calltoken_required = CALLTOKEN_YES;
04851 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04852 peer->calltoken_required = CALLTOKEN_YES;
04853 }
04854
04855 if (peer) {
04856 peer_unref(peer);
04857 }
04858 if (user) {
04859 user_unref(user);
04860 }
04861 }
04862
04863
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04881 struct sockaddr_in *sin, int fd)
04882 {
04883 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04884 #define CALLTOKEN_IE_FORMAT "%u?%s"
04885 struct ast_str *buf = ast_str_alloca(256);
04886 time_t t = time(NULL);
04887 char hash[41];
04888 int subclass = uncompress_subclass(fh->csub);
04889
04890
04891 if (ies->calltoken && !ies->calltokendata) {
04892 struct iax_ie_data ied = {
04893 .buf = { 0 },
04894 .pos = 0,
04895 };
04896
04897
04898 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04899 ast_sha1_hash(hash, ast_str_buffer(buf));
04900
04901 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04902 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04903 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04904
04905 return 1;
04906
04907
04908 } else if (ies->calltoken && ies->calltokendata) {
04909 char *rec_hash = NULL;
04910 char *rec_ts = NULL;
04911 unsigned int rec_time;
04912
04913
04914 rec_hash = strchr((char *) ies->calltokendata, '?');
04915 if (rec_hash) {
04916 *rec_hash++ = '\0';
04917 rec_ts = (char *) ies->calltokendata;
04918 }
04919
04920
04921 if (!rec_hash || !rec_ts) {
04922 goto reject;
04923 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04924 goto reject;
04925 }
04926
04927
04928 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04929 ast_sha1_hash(hash, ast_str_buffer(buf));
04930
04931
04932 if (strcmp(hash, rec_hash)) {
04933 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04934 goto reject;
04935 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04936 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04937 goto reject;
04938 }
04939
04940
04941
04942 requirecalltoken_mark_auto(ies->username, subclass);
04943 return 0;
04944
04945
04946 } else {
04947 if (calltoken_required(sin, ies->username, subclass)) {
04948 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"));
04949 goto reject;
04950 }
04951 return 0;
04952 }
04953
04954 reject:
04955
04956 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04957 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04958 } else {
04959 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04960 }
04961
04962 return 1;
04963 }
04964
04965
04966
04967
04968
04969
04970
04971
04972
04973
04974
04975
04976
04977
04978
04979
04980
04981
04982
04983 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04984 {
04985 if (ast_strlen_zero(data))
04986 return;
04987
04988 pds->peer = strsep(&data, "/");
04989 pds->exten = strsep(&data, "/");
04990 pds->options = data;
04991
04992 if (pds->exten) {
04993 data = pds->exten;
04994 pds->exten = strsep(&data, "@");
04995 pds->context = data;
04996 }
04997
04998 if (strchr(pds->peer, '@')) {
04999 data = pds->peer;
05000 pds->username = strsep(&data, "@");
05001 pds->peer = data;
05002 }
05003
05004 if (pds->username) {
05005 data = pds->username;
05006 pds->username = strsep(&data, ":");
05007 pds->password = data;
05008 }
05009
05010 data = pds->peer;
05011 pds->peer = strsep(&data, ":");
05012 pds->port = data;
05013
05014
05015
05016
05017 if (pds->password && (pds->password[0] == '[')) {
05018 pds->key = ast_strip_quoted(pds->password, "[", "]");
05019 pds->password = NULL;
05020 }
05021 }
05022
05023 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
05024 {
05025 struct sockaddr_in sin;
05026 char *l=NULL, *n=NULL, *tmpstr;
05027 struct iax_ie_data ied;
05028 char *defaultrdest = "s";
05029 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05030 struct parsed_dial_string pds;
05031 struct create_addr_info cai;
05032 struct ast_var_t *var;
05033 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
05034 const char* osp_token_ptr;
05035 unsigned int osp_token_length;
05036 unsigned char osp_block_index;
05037 unsigned int osp_block_length;
05038 unsigned char osp_buffer[256];
05039
05040 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
05041 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
05042 return -1;
05043 }
05044
05045 memset(&cai, 0, sizeof(cai));
05046 cai.encmethods = iax2_encryption;
05047
05048 memset(&pds, 0, sizeof(pds));
05049 tmpstr = ast_strdupa(dest);
05050 parse_dial_string(tmpstr, &pds);
05051
05052 if (ast_strlen_zero(pds.peer)) {
05053 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
05054 return -1;
05055 }
05056 if (!pds.exten) {
05057 pds.exten = defaultrdest;
05058 }
05059 if (create_addr(pds.peer, c, &sin, &cai)) {
05060 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
05061 return -1;
05062 }
05063 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
05064 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
05065 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05066 return -1;
05067 }
05068 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
05069 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
05070 return -1;
05071 }
05072 if (!pds.username && !ast_strlen_zero(cai.username))
05073 pds.username = cai.username;
05074 if (!pds.password && !ast_strlen_zero(cai.secret))
05075 pds.password = cai.secret;
05076 if (!pds.key && !ast_strlen_zero(cai.outkey))
05077 pds.key = cai.outkey;
05078 if (!pds.context && !ast_strlen_zero(cai.peercontext))
05079 pds.context = cai.peercontext;
05080
05081
05082 ast_copy_string(c->context, cai.context, sizeof(c->context));
05083
05084 if (pds.port)
05085 sin.sin_port = htons(atoi(pds.port));
05086
05087 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
05088 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
05089
05090
05091 memset(&ied, 0, sizeof(ied));
05092
05093
05094 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
05095 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
05096 if (pds.options && strchr(pds.options, 'a')) {
05097
05098 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
05099 }
05100
05101
05102 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
05103
05104 if (l) {
05105 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
05106 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05107 ast_party_id_presentation(&c->connected.id));
05108 } else if (n) {
05109 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05110 ast_party_id_presentation(&c->connected.id));
05111 } else {
05112 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
05113 }
05114
05115 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
05116 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
05117
05118 if (n)
05119 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
05120 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
05121 && c->connected.ani.number.valid
05122 && c->connected.ani.number.str) {
05123 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str);
05124 }
05125
05126 if (!ast_strlen_zero(c->language))
05127 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
05128 if (!ast_strlen_zero(c->dialed.number.str)) {
05129 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
05130 }
05131 if (c->redirecting.from.number.valid
05132 && !ast_strlen_zero(c->redirecting.from.number.str)) {
05133 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
05134 }
05135
05136 if (pds.context)
05137 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
05138
05139 if (pds.username)
05140 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
05141
05142 if (cai.encmethods)
05143 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
05144
05145 ast_mutex_lock(&iaxsl[callno]);
05146
05147 if (!ast_strlen_zero(c->context))
05148 ast_string_field_set(iaxs[callno], context, c->context);
05149
05150 if (pds.username)
05151 ast_string_field_set(iaxs[callno], username, pds.username);
05152
05153 iaxs[callno]->encmethods = cai.encmethods;
05154
05155 iaxs[callno]->adsi = cai.adsi;
05156
05157 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
05158 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
05159
05160 if (pds.key)
05161 ast_string_field_set(iaxs[callno], outkey, pds.key);
05162 if (pds.password)
05163 ast_string_field_set(iaxs[callno], secret, pds.password);
05164
05165 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
05166 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
05167 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
05168 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
05169 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
05170 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
05171
05172 if (iaxs[callno]->maxtime) {
05173
05174 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
05175 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
05176 } else if (autokill) {
05177 iaxs[callno]->pingtime = autokill / 2;
05178 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
05179 }
05180
05181
05182 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
05183 if (!ast_strlen_zero(osp_token_ptr)) {
05184 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
05185 osp_block_index = 0;
05186 while (osp_token_length > 0) {
05187 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
05188 osp_buffer[0] = osp_block_index;
05189 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
05190 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
05191 osp_block_index++;
05192 osp_token_ptr += osp_block_length;
05193 osp_token_length -= osp_block_length;
05194 }
05195 } else
05196 ast_log(LOG_WARNING, "OSP token is too long\n");
05197 } else if (iaxdebug)
05198 ast_debug(1, "OSP token is undefined\n");
05199
05200
05201 iaxs[callno]->sockfd = cai.sockfd;
05202
05203
05204 if (variablestore) {
05205 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
05206 ast_debug(1, "Found an IAX variable store on this channel\n");
05207 AST_LIST_LOCK(variablelist);
05208 AST_LIST_TRAVERSE(variablelist, var, entries) {
05209 char tmp[256];
05210 int i;
05211 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
05212
05213 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
05214 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
05215 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
05216 }
05217 }
05218 AST_LIST_UNLOCK(variablelist);
05219 }
05220
05221
05222 add_empty_calltoken_ie(iaxs[callno], &ied);
05223 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
05224
05225 ast_mutex_unlock(&iaxsl[callno]);
05226 ast_setstate(c, AST_STATE_RINGING);
05227
05228 return 0;
05229 }
05230
05231 static int iax2_hangup(struct ast_channel *c)
05232 {
05233 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05234 struct iax_ie_data ied;
05235 int alreadygone;
05236 memset(&ied, 0, sizeof(ied));
05237 ast_mutex_lock(&iaxsl[callno]);
05238 if (callno && iaxs[callno]) {
05239 ast_debug(1, "We're hanging up %s now...\n", c->name);
05240 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05241
05242 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05243 if (!iaxs[callno]->error && !alreadygone) {
05244 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05245 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05246 }
05247 if (!iaxs[callno]) {
05248 ast_mutex_unlock(&iaxsl[callno]);
05249 return 0;
05250 }
05251 }
05252
05253 iax2_predestroy(callno);
05254
05255 if (iaxs[callno] && alreadygone) {
05256 ast_debug(1, "Really destroying %s now...\n", c->name);
05257 iax2_destroy(callno);
05258 } else if (iaxs[callno]) {
05259 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05260 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05261 iax2_destroy(callno);
05262 }
05263 }
05264 } else if (c->tech_pvt) {
05265
05266
05267
05268
05269 c->tech_pvt = NULL;
05270 }
05271 ast_mutex_unlock(&iaxsl[callno]);
05272 ast_verb(3, "Hungup '%s'\n", c->name);
05273 return 0;
05274 }
05275
05276
05277
05278
05279 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05280 {
05281 unsigned short callno = pvt->callno;
05282
05283 if (!pvt->peercallno) {
05284
05285 int count = 10;
05286 while (count-- && pvt && !pvt->peercallno) {
05287 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05288 pvt = iaxs[callno];
05289 }
05290 if (!pvt->peercallno) {
05291 return -1;
05292 }
05293 }
05294
05295 return 0;
05296 }
05297
05298 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05299 {
05300 struct ast_option_header *h;
05301 int res;
05302
05303 switch (option) {
05304 case AST_OPTION_TXGAIN:
05305 case AST_OPTION_RXGAIN:
05306
05307 errno = ENOSYS;
05308 return -1;
05309 case AST_OPTION_OPRMODE:
05310 errno = EINVAL;
05311 return -1;
05312 case AST_OPTION_SECURE_SIGNALING:
05313 case AST_OPTION_SECURE_MEDIA:
05314 {
05315 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05316 ast_mutex_lock(&iaxsl[callno]);
05317 if ((*(int *) data)) {
05318 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05319 } else {
05320 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05321 }
05322 ast_mutex_unlock(&iaxsl[callno]);
05323 return 0;
05324 }
05325
05326
05327
05328
05329 case AST_OPTION_TONE_VERIFY:
05330 case AST_OPTION_TDD:
05331 case AST_OPTION_RELAXDTMF:
05332 case AST_OPTION_AUDIO_MODE:
05333 case AST_OPTION_DIGIT_DETECT:
05334 case AST_OPTION_FAX_DETECT:
05335 {
05336 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05337 struct chan_iax2_pvt *pvt;
05338
05339 ast_mutex_lock(&iaxsl[callno]);
05340 pvt = iaxs[callno];
05341
05342 if (wait_for_peercallno(pvt)) {
05343 ast_mutex_unlock(&iaxsl[callno]);
05344 return -1;
05345 }
05346
05347 ast_mutex_unlock(&iaxsl[callno]);
05348
05349 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05350 return -1;
05351 }
05352
05353 h->flag = AST_OPTION_FLAG_REQUEST;
05354 h->option = htons(option);
05355 memcpy(h->data, data, datalen);
05356 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05357 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05358 datalen + sizeof(*h), -1);
05359 ast_free(h);
05360 return res;
05361 }
05362 default:
05363 return -1;
05364 }
05365
05366
05367 return -1;
05368 }
05369
05370 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
05371 {
05372 switch (option) {
05373 case AST_OPTION_SECURE_SIGNALING:
05374 case AST_OPTION_SECURE_MEDIA:
05375 {
05376 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05377 ast_mutex_lock(&iaxsl[callno]);
05378 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05379 ast_mutex_unlock(&iaxsl[callno]);
05380 return 0;
05381 }
05382 default:
05383 return -1;
05384 }
05385 }
05386
05387 static struct ast_frame *iax2_read(struct ast_channel *c)
05388 {
05389 ast_debug(1, "I should never be called!\n");
05390 return &ast_null_frame;
05391 }
05392
05393 static int iax2_key_rotate(const void *vpvt)
05394 {
05395 int res = 0;
05396 struct chan_iax2_pvt *pvt = (void *) vpvt;
05397 struct MD5Context md5;
05398 char key[17] = "";
05399 struct iax_ie_data ied = {
05400 .pos = 0,
05401 };
05402
05403 ast_mutex_lock(&iaxsl[pvt->callno]);
05404 pvt->keyrotateid =
05405 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05406
05407 snprintf(key, sizeof(key), "%lX", ast_random());
05408
05409 MD5Init(&md5);
05410 MD5Update(&md5, (unsigned char *) key, strlen(key));
05411 MD5Final((unsigned char *) key, &md5);
05412
05413 IAX_DEBUGDIGEST("Sending", key);
05414
05415 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05416
05417 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05418
05419 build_ecx_key((unsigned char *) key, pvt);
05420
05421 ast_mutex_unlock(&iaxsl[pvt->callno]);
05422
05423 return res;
05424 }
05425
05426 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05427 {
05428 int res;
05429 struct iax_ie_data ied0;
05430 struct iax_ie_data ied1;
05431 unsigned int transferid = (unsigned int)ast_random();
05432
05433 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05434 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05435 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05436 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05437 return 0;
05438 }
05439
05440 memset(&ied0, 0, sizeof(ied0));
05441 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05442 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05443 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05444
05445 memset(&ied1, 0, sizeof(ied1));
05446 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05447 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05448 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05449
05450 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05451 if (res)
05452 return -1;
05453 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05454 if (res)
05455 return -1;
05456 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05457 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05458 return 0;
05459 }
05460
05461 static void lock_both(unsigned short callno0, unsigned short callno1)
05462 {
05463 ast_mutex_lock(&iaxsl[callno0]);
05464 while (ast_mutex_trylock(&iaxsl[callno1])) {
05465 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05466 }
05467 }
05468
05469 static void unlock_both(unsigned short callno0, unsigned short callno1)
05470 {
05471 ast_mutex_unlock(&iaxsl[callno1]);
05472 ast_mutex_unlock(&iaxsl[callno0]);
05473 }
05474
05475 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)
05476 {
05477 struct ast_channel *cs[3];
05478 struct ast_channel *who, *other;
05479 int to = -1;
05480 int res = -1;
05481 int transferstarted=0;
05482 struct ast_frame *f;
05483 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05484 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05485 struct timeval waittimer = {0, 0};
05486
05487
05488 if (timeoutms > 0) {
05489 return AST_BRIDGE_FAILED;
05490 }
05491
05492 timeoutms = -1;
05493
05494 lock_both(callno0, callno1);
05495 if (!iaxs[callno0] || !iaxs[callno1]) {
05496 unlock_both(callno0, callno1);
05497 return AST_BRIDGE_FAILED;
05498 }
05499
05500 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05501 iaxs[callno0]->bridgecallno = callno1;
05502 iaxs[callno1]->bridgecallno = callno0;
05503 }
05504 unlock_both(callno0, callno1);
05505
05506
05507 cs[0] = c0;
05508 cs[1] = c1;
05509 for (;;) {
05510
05511 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05512 ast_verb(3, "Can't masquerade, we're different...\n");
05513
05514 if (c0->tech == &iax2_tech) {
05515 ast_mutex_lock(&iaxsl[callno0]);
05516 iaxs[callno0]->bridgecallno = 0;
05517 ast_mutex_unlock(&iaxsl[callno0]);
05518 }
05519 if (c1->tech == &iax2_tech) {
05520 ast_mutex_lock(&iaxsl[callno1]);
05521 iaxs[callno1]->bridgecallno = 0;
05522 ast_mutex_unlock(&iaxsl[callno1]);
05523 }
05524 return AST_BRIDGE_FAILED_NOWARN;
05525 }
05526 if (c0->nativeformats != c1->nativeformats) {
05527 char buf0[256];
05528 char buf1[256];
05529 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05530 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05531 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05532
05533 lock_both(callno0, callno1);
05534 if (iaxs[callno0])
05535 iaxs[callno0]->bridgecallno = 0;
05536 if (iaxs[callno1])
05537 iaxs[callno1]->bridgecallno = 0;
05538 unlock_both(callno0, callno1);
05539 return AST_BRIDGE_FAILED_NOWARN;
05540 }
05541
05542 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05543
05544 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05545 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05546 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05547 transferstarted = 1;
05548 }
05549 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05550
05551 struct timeval now = ast_tvnow();
05552 if (ast_tvzero(waittimer)) {
05553 waittimer = now;
05554 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05555 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05556 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05557 *fo = NULL;
05558 *rc = c0;
05559 res = AST_BRIDGE_COMPLETE;
05560 break;
05561 }
05562 }
05563 to = 1000;
05564 who = ast_waitfor_n(cs, 2, &to);
05565 if (timeoutms > -1) {
05566 timeoutms -= (1000 - to);
05567 if (timeoutms < 0)
05568 timeoutms = 0;
05569 }
05570 if (!who) {
05571 if (!timeoutms) {
05572 res = AST_BRIDGE_RETRY;
05573 break;
05574 }
05575 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05576 res = AST_BRIDGE_FAILED;
05577 break;
05578 }
05579 continue;
05580 }
05581 f = ast_read(who);
05582 if (!f) {
05583 *fo = NULL;
05584 *rc = who;
05585 res = AST_BRIDGE_COMPLETE;
05586 break;
05587 }
05588 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
05589 *fo = f;
05590 *rc = who;
05591 res = AST_BRIDGE_COMPLETE;
05592 break;
05593 }
05594 other = (who == c0) ? c1 : c0;
05595 if ((f->frametype == AST_FRAME_VOICE) ||
05596 (f->frametype == AST_FRAME_TEXT) ||
05597 (f->frametype == AST_FRAME_VIDEO) ||
05598 (f->frametype == AST_FRAME_IMAGE) ||
05599 (f->frametype == AST_FRAME_DTMF) ||
05600 (f->frametype == AST_FRAME_CONTROL)) {
05601
05602
05603
05604 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05605 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05606 *rc = who;
05607 *fo = f;
05608 res = AST_BRIDGE_COMPLETE;
05609
05610 break;
05611 }
05612
05613 ast_write(other, f);
05614 }
05615 ast_frfree(f);
05616
05617 cs[2] = cs[0];
05618 cs[0] = cs[1];
05619 cs[1] = cs[2];
05620 }
05621 lock_both(callno0, callno1);
05622 if(iaxs[callno0])
05623 iaxs[callno0]->bridgecallno = 0;
05624 if(iaxs[callno1])
05625 iaxs[callno1]->bridgecallno = 0;
05626 unlock_both(callno0, callno1);
05627 return res;
05628 }
05629
05630 static int iax2_answer(struct ast_channel *c)
05631 {
05632 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05633 ast_debug(1, "Answering IAX2 call\n");
05634 ast_mutex_lock(&iaxsl[callno]);
05635 if (iaxs[callno])
05636 iax2_ami_channelupdate(iaxs[callno]);
05637 ast_mutex_unlock(&iaxsl[callno]);
05638 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05639 }
05640
05641 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05642 {
05643 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05644 struct chan_iax2_pvt *pvt;
05645 int res = 0;
05646
05647 if (iaxdebug)
05648 ast_debug(1, "Indicating condition %d\n", condition);
05649
05650 ast_mutex_lock(&iaxsl[callno]);
05651 pvt = iaxs[callno];
05652
05653 if (wait_for_peercallno(pvt)) {
05654 res = -1;
05655 goto done;
05656 }
05657
05658 switch (condition) {
05659 case AST_CONTROL_HOLD:
05660 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05661 ast_moh_start(c, data, pvt->mohinterpret);
05662 goto done;
05663 }
05664 break;
05665 case AST_CONTROL_UNHOLD:
05666 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05667 ast_moh_stop(c);
05668 goto done;
05669 }
05670 break;
05671 case AST_CONTROL_CONNECTED_LINE:
05672 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05673 goto done;
05674 break;
05675 }
05676
05677 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05678
05679 done:
05680 ast_mutex_unlock(&iaxsl[callno]);
05681
05682 return res;
05683 }
05684
05685 static int iax2_transfer(struct ast_channel *c, const char *dest)
05686 {
05687 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05688 struct iax_ie_data ied = { "", };
05689 char tmp[256], *context;
05690 enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05691 ast_copy_string(tmp, dest, sizeof(tmp));
05692 context = strchr(tmp, '@');
05693 if (context) {
05694 *context = '\0';
05695 context++;
05696 }
05697 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05698 if (context)
05699 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05700 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05701 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05702 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05703 }
05704
05705 static int iax2_getpeertrunk(struct sockaddr_in sin)
05706 {
05707 struct iax2_peer *peer;
05708 int res = 0;
05709 struct ao2_iterator i;
05710
05711 i = ao2_iterator_init(peers, 0);
05712 while ((peer = ao2_iterator_next(&i))) {
05713 struct sockaddr_in peer_addr;
05714
05715 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05716
05717 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05718 (peer_addr.sin_port == sin.sin_port)) {
05719 res = ast_test_flag64(peer, IAX_TRUNK);
05720 peer_unref(peer);
05721 break;
05722 }
05723 peer_unref(peer);
05724 }
05725 ao2_iterator_destroy(&i);
05726
05727 return res;
05728 }
05729
05730
05731 static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
05732 {
05733 struct ast_channel *tmp;
05734 struct chan_iax2_pvt *i;
05735 struct ast_variable *v = NULL;
05736
05737 if (!(i = iaxs[callno])) {
05738 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05739 return NULL;
05740 }
05741
05742
05743 ast_mutex_unlock(&iaxsl[callno]);
05744 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);
05745 ast_mutex_lock(&iaxsl[callno]);
05746 if (i != iaxs[callno]) {
05747 if (tmp) {
05748
05749 ast_mutex_unlock(&iaxsl[callno]);
05750 tmp = ast_channel_release(tmp);
05751 ast_mutex_lock(&iaxsl[callno]);
05752 }
05753 return NULL;
05754 }
05755 iax2_ami_channelupdate(i);
05756 if (!tmp)
05757 return NULL;
05758 tmp->tech = &iax2_tech;
05759
05760 tmp->nativeformats = capability;
05761 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05762 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05763 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05764
05765 if (!ast_strlen_zero(i->parkinglot))
05766 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05767
05768
05769 if (!ast_strlen_zero(i->ani)) {
05770 tmp->caller.ani.number.valid = 1;
05771 tmp->caller.ani.number.str = ast_strdup(i->ani);
05772 } else if (!ast_strlen_zero(i->cid_num)) {
05773 tmp->caller.ani.number.valid = 1;
05774 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05775 }
05776 tmp->dialed.number.str = ast_strdup(i->dnid);
05777 if (!ast_strlen_zero(i->rdnis)) {
05778 tmp->redirecting.from.number.valid = 1;
05779 tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05780 }
05781 tmp->caller.id.name.presentation = i->calling_pres;
05782 tmp->caller.id.number.presentation = i->calling_pres;
05783 tmp->caller.id.number.plan = i->calling_ton;
05784 tmp->dialed.transit_network_select = i->calling_tns;
05785 if (!ast_strlen_zero(i->language))
05786 ast_string_field_set(tmp, language, i->language);
05787 if (!ast_strlen_zero(i->accountcode))
05788 ast_string_field_set(tmp, accountcode, i->accountcode);
05789 if (i->amaflags)
05790 tmp->amaflags = i->amaflags;
05791 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05792 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05793 if (i->adsi)
05794 tmp->adsicpe = i->peeradsicpe;
05795 else
05796 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05797 i->owner = tmp;
05798 i->capability = capability;
05799
05800
05801 if (i->vars) {
05802 for (v = i->vars ; v ; v = v->next)
05803 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05804 }
05805 if (i->iaxvars) {
05806 struct ast_datastore *variablestore;
05807 struct ast_variable *var, *prev = NULL;
05808 AST_LIST_HEAD(, ast_var_t) *varlist;
05809 ast_debug(1, "Loading up the channel with IAXVARs\n");
05810 varlist = ast_calloc(1, sizeof(*varlist));
05811 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05812 if (variablestore && varlist) {
05813 variablestore->data = varlist;
05814 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05815 AST_LIST_HEAD_INIT(varlist);
05816 for (var = i->iaxvars; var; var = var->next) {
05817 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05818 if (prev)
05819 ast_free(prev);
05820 prev = var;
05821 if (!newvar) {
05822
05823 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05824 } else {
05825 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05826 }
05827 }
05828 if (prev)
05829 ast_free(prev);
05830 i->iaxvars = NULL;
05831 ast_channel_datastore_add(i->owner, variablestore);
05832 } else {
05833 if (variablestore) {
05834 ast_datastore_free(variablestore);
05835 }
05836 if (varlist) {
05837 ast_free(varlist);
05838 }
05839 }
05840 }
05841
05842 if (state != AST_STATE_DOWN) {
05843 if (ast_pbx_start(tmp)) {
05844 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05845 ast_hangup(tmp);
05846 i->owner = NULL;
05847 return NULL;
05848 }
05849 }
05850
05851 ast_module_ref(ast_module_info->self);
05852 return tmp;
05853 }
05854
05855 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05856 {
05857 unsigned long int mssincetx;
05858 long int ms, pred;
05859
05860 tpeer->trunkact = *now;
05861 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05862 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05863
05864 tpeer->txtrunktime = *now;
05865 tpeer->lastsent = 999999;
05866 }
05867
05868 tpeer->lasttxtime = *now;
05869
05870
05871 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05872
05873 pred = tpeer->lastsent + sampms;
05874 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05875 ms = pred;
05876
05877
05878 if (ms == tpeer->lastsent)
05879 ms = tpeer->lastsent + 1;
05880 tpeer->lastsent = ms;
05881 return ms;
05882 }
05883
05884 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05885 {
05886 long ms;
05887 if (ast_tvzero(iaxs[callno]->rxcore)) {
05888
05889 iaxs[callno]->rxcore = ast_tvnow();
05890
05891 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05892 }
05893
05894 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05895
05896 return ms + ts;
05897 }
05898
05899 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05900 {
05901 int ms;
05902 int voice = 0;
05903 int genuine = 0;
05904 int adjust;
05905 int rate = ast_format_rate(f->subclass.codec) / 1000;
05906 struct timeval *delivery = NULL;
05907
05908
05909
05910
05911
05912
05913
05914
05915 if (f) {
05916 if (f->frametype == AST_FRAME_VOICE) {
05917 voice = 1;
05918 delivery = &f->delivery;
05919 } else if (f->frametype == AST_FRAME_IAX) {
05920 genuine = 1;
05921 } else if (f->frametype == AST_FRAME_CNG) {
05922 p->notsilenttx = 0;
05923 }
05924 }
05925 if (ast_tvzero(p->offset)) {
05926 p->offset = ast_tvnow();
05927
05928 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05929 }
05930
05931 if (ts)
05932 return ts;
05933
05934 if (delivery && !ast_tvzero(*delivery)) {
05935 ms = ast_tvdiff_ms(*delivery, p->offset);
05936 if (ms < 0) {
05937 ms = 0;
05938 }
05939 if (iaxdebug)
05940 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05941 } else {
05942 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05943 if (ms < 0)
05944 ms = 0;
05945 if (voice) {
05946
05947 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05948
05949
05950
05951
05952
05953
05954
05955
05956
05957
05958
05959
05960
05961
05962
05963
05964
05965
05966 adjust = (ms - p->nextpred);
05967 if (adjust < 0)
05968 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05969 else if (adjust > 0)
05970 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05971
05972 if (!p->nextpred) {
05973 p->nextpred = ms;
05974 if (p->nextpred <= p->lastsent)
05975 p->nextpred = p->lastsent + 3;
05976 }
05977 ms = p->nextpred;
05978 } else {
05979
05980
05981
05982
05983
05984
05985
05986
05987
05988 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05989 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05990 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05991
05992 if (f->samples >= rate)
05993 {
05994 int diff = ms % (f->samples / rate);
05995 if (diff)
05996 ms += f->samples/rate - diff;
05997 }
05998
05999 p->nextpred = ms;
06000 p->notsilenttx = 1;
06001 }
06002 } else if ( f->frametype == AST_FRAME_VIDEO ) {
06003
06004
06005
06006
06007
06008
06009
06010
06011 if ( (unsigned int)ms < p->lastsent )
06012 ms = p->lastsent;
06013 } else {
06014
06015
06016 if (genuine) {
06017
06018 if (ms <= p->lastsent)
06019 ms = p->lastsent + 3;
06020 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
06021
06022 ms = p->lastsent + 3;
06023 }
06024 }
06025 }
06026 p->lastsent = ms;
06027 if (voice)
06028 p->nextpred = p->nextpred + f->samples / rate;
06029 return ms;
06030 }
06031
06032 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
06033 {
06034
06035
06036 int ms;
06037 #ifdef IAXTESTS
06038 int jit;
06039 #endif
06040
06041 if (ast_tvzero(p->rxcore)) {
06042 p->rxcore = ast_tvnow();
06043 if (iaxdebug)
06044 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06045 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06046 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06047 #if 1
06048 if (iaxdebug)
06049 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06050 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06051 #endif
06052 }
06053
06054 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06055 #ifdef IAXTESTS
06056 if (test_jit) {
06057 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06058 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06059 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06060 jit = -jit;
06061 ms += jit;
06062 }
06063 }
06064 if (test_late) {
06065 ms += test_late;
06066 test_late = 0;
06067 }
06068 #endif
06069 return ms;
06070 }
06071
06072 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
06073 {
06074 struct iax2_trunk_peer *tpeer = NULL;
06075
06076
06077 AST_LIST_LOCK(&tpeers);
06078
06079 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06080 if (!inaddrcmp(&tpeer->addr, sin)) {
06081 ast_mutex_lock(&tpeer->lock);
06082 break;
06083 }
06084 }
06085
06086 if (!tpeer) {
06087 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06088 ast_mutex_init(&tpeer->lock);
06089 tpeer->lastsent = 9999;
06090 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06091 tpeer->trunkact = ast_tvnow();
06092 ast_mutex_lock(&tpeer->lock);
06093 tpeer->sockfd = fd;
06094 #ifdef SO_NO_CHECK
06095 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06096 #endif
06097 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06098 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06099 }
06100 }
06101
06102 AST_LIST_UNLOCK(&tpeers);
06103
06104 return tpeer;
06105 }
06106
06107 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
06108 {
06109 struct ast_frame *f;
06110 struct iax2_trunk_peer *tpeer;
06111 void *tmp, *ptr;
06112 struct timeval now;
06113 struct ast_iax2_meta_trunk_entry *met;
06114 struct ast_iax2_meta_trunk_mini *mtm;
06115
06116 f = &fr->af;
06117 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06118 if (tpeer) {
06119 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06120
06121 if (tpeer->trunkdataalloc < trunkmaxsize) {
06122 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06123 ast_mutex_unlock(&tpeer->lock);
06124 return -1;
06125 }
06126
06127 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06128 tpeer->trunkdata = tmp;
06129 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);
06130 } else {
06131 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));
06132 ast_mutex_unlock(&tpeer->lock);
06133 return -1;
06134 }
06135 }
06136
06137
06138 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06139 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06140 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06141 mtm->len = htons(f->datalen);
06142 mtm->mini.callno = htons(pvt->callno);
06143 mtm->mini.ts = htons(0xffff & fr->ts);
06144 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06145 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06146 } else {
06147 met = (struct ast_iax2_meta_trunk_entry *)ptr;
06148
06149 met->callno = htons(pvt->callno);
06150 met->len = htons(f->datalen);
06151
06152 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06153 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06154 }
06155
06156 memcpy(ptr, f->data.ptr, f->datalen);
06157 tpeer->trunkdatalen += f->datalen;
06158
06159 tpeer->calls++;
06160
06161
06162 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
06163 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
06164
06165
06166 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06167 now = ast_tvnow();
06168 send_trunk(tpeer, &now);
06169 trunk_untimed ++;
06170 }
06171
06172 ast_mutex_unlock(&tpeer->lock);
06173 }
06174 return 0;
06175 }
06176
06177
06178
06179 static void build_rand_pad(unsigned char *buf, ssize_t len)
06180 {
06181 long tmp;
06182 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06183 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06184 buf += sizeof(tmp);
06185 len -= sizeof(tmp);
06186 }
06187 }
06188
06189 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06190 {
06191 build_ecx_key(digest, pvt);
06192 ast_aes_set_decrypt_key(digest, &pvt->dcx);
06193 }
06194
06195 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06196 {
06197
06198
06199
06200 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06201 ast_aes_set_encrypt_key(digest, &pvt->ecx);
06202 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06203 }
06204
06205 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
06206 {
06207 #if 0
06208
06209 int x;
06210 if (len % 16)
06211 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06212 for (x=0;x<len;x++)
06213 dst[x] = src[x] ^ 0xff;
06214 #else
06215 unsigned char lastblock[16] = { 0 };
06216 int x;
06217 while(len > 0) {
06218 ast_aes_decrypt(src, dst, dcx);
06219 for (x=0;x<16;x++)
06220 dst[x] ^= lastblock[x];
06221 memcpy(lastblock, src, sizeof(lastblock));
06222 dst += 16;
06223 src += 16;
06224 len -= 16;
06225 }
06226 #endif
06227 }
06228
06229 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
06230 {
06231 #if 0
06232
06233 int x;
06234 if (len % 16)
06235 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06236 for (x=0;x<len;x++)
06237 dst[x] = src[x] ^ 0xff;
06238 #else
06239 unsigned char curblock[16] = { 0 };
06240 int x;
06241 while(len > 0) {
06242 for (x=0;x<16;x++)
06243 curblock[x] ^= src[x];
06244 ast_aes_encrypt(curblock, dst, ecx);
06245 memcpy(curblock, dst, sizeof(curblock));
06246 dst += 16;
06247 src += 16;
06248 len -= 16;
06249 }
06250 #endif
06251 }
06252
06253 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06254 {
06255 int padding;
06256 unsigned char *workspace;
06257
06258 workspace = alloca(*datalen);
06259 memset(f, 0, sizeof(*f));
06260 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06261 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06262 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06263 return -1;
06264
06265 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06266
06267 padding = 16 + (workspace[15] & 0x0f);
06268 if (iaxdebug)
06269 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06270 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06271 return -1;
06272
06273 *datalen -= padding;
06274 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06275 f->frametype = fh->type;
06276 if (f->frametype == AST_FRAME_VIDEO) {
06277 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06278 } else if (f->frametype == AST_FRAME_VOICE) {
06279 f->subclass.codec = uncompress_subclass(fh->csub);
06280 } else {
06281 f->subclass.integer = uncompress_subclass(fh->csub);
06282 }
06283 } else {
06284 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06285 if (iaxdebug)
06286 ast_debug(1, "Decoding mini with length %d\n", *datalen);
06287 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06288 return -1;
06289
06290 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06291 padding = 16 + (workspace[15] & 0x0f);
06292 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06293 return -1;
06294 *datalen -= padding;
06295 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06296 }
06297 return 0;
06298 }
06299
06300 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06301 {
06302 int padding;
06303 unsigned char *workspace;
06304 workspace = alloca(*datalen + 32);
06305 if (!workspace)
06306 return -1;
06307 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06308 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06309 if (iaxdebug)
06310 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06311 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06312 padding = 16 + (padding & 0xf);
06313 memcpy(workspace, poo, padding);
06314 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06315 workspace[15] &= 0xf0;
06316 workspace[15] |= (padding & 0xf);
06317 if (iaxdebug)
06318 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06319 *datalen += padding;
06320 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06321 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06322 memcpy(poo, workspace + *datalen - 32, 32);
06323 } else {
06324 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06325 if (iaxdebug)
06326 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06327 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06328 padding = 16 + (padding & 0xf);
06329 memcpy(workspace, poo, padding);
06330 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06331 workspace[15] &= 0xf0;
06332 workspace[15] |= (padding & 0x0f);
06333 *datalen += padding;
06334 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06335 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06336 memcpy(poo, workspace + *datalen - 32, 32);
06337 }
06338 return 0;
06339 }
06340
06341 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06342 {
06343 int res=-1;
06344 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06345
06346 struct MD5Context md5;
06347 unsigned char digest[16];
06348 char *tmppw, *stringp;
06349
06350 tmppw = ast_strdupa(iaxs[callno]->secret);
06351 stringp = tmppw;
06352 while ((tmppw = strsep(&stringp, ";"))) {
06353 MD5Init(&md5);
06354 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06355 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06356 MD5Final(digest, &md5);
06357 build_encryption_keys(digest, iaxs[callno]);
06358 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06359 if (!res) {
06360 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06361 break;
06362 }
06363 }
06364 } else
06365 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06366 return res;
06367 }
06368
06369 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06370 {
06371
06372
06373
06374 struct ast_iax2_full_hdr *fh;
06375 struct ast_iax2_mini_hdr *mh;
06376 struct ast_iax2_video_hdr *vh;
06377 struct {
06378 struct iax_frame fr2;
06379 unsigned char buffer[4096];
06380 } frb;
06381 struct iax_frame *fr;
06382 int res;
06383 int sendmini=0;
06384 unsigned int lastsent;
06385 unsigned int fts;
06386
06387 frb.fr2.afdatalen = sizeof(frb.buffer);
06388
06389 if (!pvt) {
06390 ast_log(LOG_WARNING, "No private structure for packet?\n");
06391 return -1;
06392 }
06393
06394 lastsent = pvt->lastsent;
06395
06396
06397 fts = calc_timestamp(pvt, ts, f);
06398
06399
06400
06401
06402 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06403 return 0;
06404 #if 0
06405 ast_log(LOG_NOTICE,
06406 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06407 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06408 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06409 pvt->keyrotateid != -1 ? "" : "no "
06410 );
06411 #endif
06412 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06413 iax2_key_rotate(pvt);
06414 }
06415
06416 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
06417 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06418 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06419 &&
06420 (f->frametype == AST_FRAME_VOICE)
06421 &&
06422 (f->subclass.codec == pvt->svoiceformat)
06423 ) {
06424
06425 now = 1;
06426
06427 sendmini = 1;
06428 }
06429 if ( f->frametype == AST_FRAME_VIDEO ) {
06430
06431
06432
06433
06434
06435 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06436 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
06437 ) {
06438 now = 1;
06439 sendmini = 1;
06440 } else {
06441 now = 0;
06442 sendmini = 0;
06443 }
06444 pvt->lastvsent = fts;
06445 }
06446 if (f->frametype == AST_FRAME_IAX) {
06447
06448 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06449 if (!pvt->first_iax_message) {
06450 pvt->first_iax_message = pvt->last_iax_message;
06451 }
06452 }
06453
06454 if (now) {
06455 fr = &frb.fr2;
06456 } else
06457 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));
06458 if (!fr) {
06459 ast_log(LOG_WARNING, "Out of memory\n");
06460 return -1;
06461 }
06462
06463 iax_frame_wrap(fr, f);
06464
06465 fr->ts = fts;
06466 fr->callno = pvt->callno;
06467 fr->transfer = transfer;
06468 fr->final = final;
06469 fr->encmethods = 0;
06470 if (!sendmini) {
06471
06472 if (seqno > -1)
06473 fr->oseqno = seqno;
06474 else
06475 fr->oseqno = pvt->oseqno++;
06476 fr->iseqno = pvt->iseqno;
06477 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06478 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06479 fh->ts = htonl(fr->ts);
06480 fh->oseqno = fr->oseqno;
06481 if (transfer) {
06482 fh->iseqno = 0;
06483 } else
06484 fh->iseqno = fr->iseqno;
06485
06486 if (!transfer)
06487 pvt->aseqno = fr->iseqno;
06488 fh->type = fr->af.frametype & 0xFF;
06489
06490 if (fr->af.frametype == AST_FRAME_VIDEO) {
06491 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
06492 } else if (fr->af.frametype == AST_FRAME_VOICE) {
06493 fh->csub = compress_subclass(fr->af.subclass.codec);
06494 } else {
06495 fh->csub = compress_subclass(fr->af.subclass.integer);
06496 }
06497
06498 if (transfer) {
06499 fr->dcallno = pvt->transfercallno;
06500 } else
06501 fr->dcallno = pvt->peercallno;
06502 fh->dcallno = htons(fr->dcallno);
06503 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06504 fr->data = fh;
06505 fr->retries = 0;
06506
06507 fr->retrytime = pvt->pingtime * 2;
06508 if (fr->retrytime < MIN_RETRY_TIME)
06509 fr->retrytime = MIN_RETRY_TIME;
06510 if (fr->retrytime > MAX_RETRY_TIME)
06511 fr->retrytime = MAX_RETRY_TIME;
06512
06513 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06514 fr->retries = -1;
06515 else if (f->frametype == AST_FRAME_VOICE)
06516 pvt->svoiceformat = f->subclass.codec;
06517 else if (f->frametype == AST_FRAME_VIDEO)
06518 pvt->svideoformat = f->subclass.codec & ~0x1LL;
06519 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06520 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06521 if (fr->transfer)
06522 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06523 else
06524 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06525 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06526 fr->encmethods = pvt->encmethods;
06527 fr->ecx = pvt->ecx;
06528 fr->mydcx = pvt->mydcx;
06529 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06530 } else
06531 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06532 }
06533
06534 if (now) {
06535 res = send_packet(fr);
06536 } else
06537 res = iax2_transmit(fr);
06538 } else {
06539 if (ast_test_flag64(pvt, IAX_TRUNK)) {
06540 iax2_trunk_queue(pvt, fr);
06541 res = 0;
06542 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06543
06544 fr->oseqno = -1;
06545 fr->iseqno = -1;
06546 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06547 vh->zeros = 0;
06548 vh->callno = htons(0x8000 | fr->callno);
06549 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
06550 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06551 fr->data = vh;
06552 fr->retries = -1;
06553 res = send_packet(fr);
06554 } else {
06555
06556 fr->oseqno = -1;
06557 fr->iseqno = -1;
06558
06559 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06560 mh->callno = htons(fr->callno);
06561 mh->ts = htons(fr->ts & 0xFFFF);
06562 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06563 fr->data = mh;
06564 fr->retries = -1;
06565 if (pvt->transferring == TRANSFER_MEDIAPASS)
06566 fr->transfer = 1;
06567 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06568 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06569 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06570 } else
06571 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06572 }
06573 res = send_packet(fr);
06574 }
06575 }
06576 return res;
06577 }
06578
06579 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06580 {
06581 regex_t regexbuf;
06582 int havepattern = 0;
06583
06584 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06585 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06586
06587 struct iax2_user *user = NULL;
06588 char auth[90];
06589 char *pstr = "";
06590 struct ao2_iterator i;
06591
06592 switch (cmd) {
06593 case CLI_INIT:
06594 e->command = "iax2 show users [like]";
06595 e->usage =
06596 "Usage: iax2 show users [like <pattern>]\n"
06597 " Lists all known IAX2 users.\n"
06598 " Optional regular expression pattern is used to filter the user list.\n";
06599 return NULL;
06600 case CLI_GENERATE:
06601 return NULL;
06602 }
06603
06604 switch (a->argc) {
06605 case 5:
06606 if (!strcasecmp(a->argv[3], "like")) {
06607 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06608 return CLI_SHOWUSAGE;
06609 havepattern = 1;
06610 } else
06611 return CLI_SHOWUSAGE;
06612 case 3:
06613 break;
06614 default:
06615 return CLI_SHOWUSAGE;
06616 }
06617
06618 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06619 i = ao2_iterator_init(users, 0);
06620 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
06621 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06622 continue;
06623
06624 if (!ast_strlen_zero(user->secret)) {
06625 ast_copy_string(auth,user->secret, sizeof(auth));
06626 } else if (!ast_strlen_zero(user->inkeys)) {
06627 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06628 } else
06629 ast_copy_string(auth, "-no secret-", sizeof(auth));
06630
06631 if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06632 pstr = "REQ Only";
06633 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06634 pstr = "Disabled";
06635 else
06636 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06637
06638 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06639 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06640 user->ha ? "Yes" : "No", pstr);
06641 }
06642 ao2_iterator_destroy(&i);
06643
06644 if (havepattern)
06645 regfree(®exbuf);
06646
06647 return CLI_SUCCESS;
06648 #undef FORMAT
06649 #undef FORMAT2
06650 }
06651
06652 static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char * const argv[])
06653 {
06654 regex_t regexbuf;
06655 int havepattern = 0;
06656 int total_peers = 0;
06657 int online_peers = 0;
06658 int offline_peers = 0;
06659 int unmonitored_peers = 0;
06660 struct ao2_iterator i;
06661
06662 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n"
06663 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n"
06664
06665 struct iax2_peer *peer = NULL;
06666 char name[256];
06667 struct ast_str *encmethods = ast_str_alloca(256);
06668 int registeredonly=0;
06669 char idtext[256] = "";
06670 switch (argc) {
06671 case 6:
06672 if (!strcasecmp(argv[3], "registered"))
06673 registeredonly = 1;
06674 else
06675 return RESULT_SHOWUSAGE;
06676 if (!strcasecmp(argv[4], "like")) {
06677 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06678 return RESULT_SHOWUSAGE;
06679 havepattern = 1;
06680 } else
06681 return RESULT_SHOWUSAGE;
06682 break;
06683 case 5:
06684 if (!strcasecmp(argv[3], "like")) {
06685 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06686 return RESULT_SHOWUSAGE;
06687 havepattern = 1;
06688 } else
06689 return RESULT_SHOWUSAGE;
06690 break;
06691 case 4:
06692 if (!strcasecmp(argv[3], "registered"))
06693 registeredonly = 1;
06694 else
06695 return RESULT_SHOWUSAGE;
06696 break;
06697 case 3:
06698 break;
06699 default:
06700 return RESULT_SHOWUSAGE;
06701 }
06702
06703
06704 if (!s)
06705 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status");
06706
06707 i = ao2_iterator_init(peers, 0);
06708 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06709 char nm[20];
06710 char status[20];
06711 int retstatus;
06712 struct sockaddr_in peer_addr;
06713
06714 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06715
06716 if (registeredonly && !peer_addr.sin_addr.s_addr) {
06717 continue;
06718 }
06719 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
06720 continue;
06721 }
06722
06723 if (!ast_strlen_zero(peer->username))
06724 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06725 else
06726 ast_copy_string(name, peer->name, sizeof(name));
06727
06728 encmethods_to_str(peer->encmethods, encmethods);
06729 retstatus = peer_status(peer, status, sizeof(status));
06730 if (retstatus > 0)
06731 online_peers++;
06732 else if (!retstatus)
06733 offline_peers++;
06734 else
06735 unmonitored_peers++;
06736
06737 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06738
06739 if (s) {
06740 astman_append(s,
06741 "Event: PeerEntry\r\n%s"
06742 "Channeltype: IAX2\r\n"
06743 "ObjectName: %s\r\n"
06744 "ChanObjectType: peer\r\n"
06745 "IPaddress: %s\r\n"
06746 "IPport: %d\r\n"
06747 "Dynamic: %s\r\n"
06748 "Trunk: %s\r\n"
06749 "Encryption: %s\r\n"
06750 "Status: %s\r\n\r\n",
06751 idtext,
06752 name,
06753 ast_sockaddr_stringify_addr(&peer->addr),
06754 ast_sockaddr_port(&peer->addr),
06755 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06756 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06757 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06758 status);
06759 } else {
06760 ast_cli(fd, FORMAT, name,
06761 ast_sockaddr_stringify_addr(&peer->addr),
06762 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06763 nm,
06764 ast_sockaddr_port(&peer->addr),
06765 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
06766 peer->encmethods ? "(E)" : " ",
06767 status);
06768 }
06769 total_peers++;
06770 }
06771 ao2_iterator_destroy(&i);
06772
06773 if (!s)
06774 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06775 total_peers, online_peers, offline_peers, unmonitored_peers);
06776
06777 if (havepattern)
06778 regfree(®exbuf);
06779
06780 if (total)
06781 *total = total_peers;
06782
06783 return RESULT_SUCCESS;
06784 #undef FORMAT
06785 #undef FORMAT2
06786 }
06787
06788 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06789 {
06790 struct iax2_thread *thread = NULL;
06791 time_t t;
06792 int threadcount = 0, dynamiccount = 0;
06793 char type;
06794
06795 switch (cmd) {
06796 case CLI_INIT:
06797 e->command = "iax2 show threads";
06798 e->usage =
06799 "Usage: iax2 show threads\n"
06800 " Lists status of IAX helper threads\n";
06801 return NULL;
06802 case CLI_GENERATE:
06803 return NULL;
06804 }
06805 if (a->argc != 3)
06806 return CLI_SHOWUSAGE;
06807
06808 ast_cli(a->fd, "IAX2 Thread Information\n");
06809 time(&t);
06810 ast_cli(a->fd, "Idle Threads:\n");
06811 AST_LIST_LOCK(&idle_list);
06812 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06813 #ifdef DEBUG_SCHED_MULTITHREAD
06814 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06815 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06816 #else
06817 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06818 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06819 #endif
06820 threadcount++;
06821 }
06822 AST_LIST_UNLOCK(&idle_list);
06823 ast_cli(a->fd, "Active Threads:\n");
06824 AST_LIST_LOCK(&active_list);
06825 AST_LIST_TRAVERSE(&active_list, thread, list) {
06826 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06827 type = 'D';
06828 else
06829 type = 'P';
06830 #ifdef DEBUG_SCHED_MULTITHREAD
06831 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06832 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06833 #else
06834 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06835 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06836 #endif
06837 threadcount++;
06838 }
06839 AST_LIST_UNLOCK(&active_list);
06840 ast_cli(a->fd, "Dynamic Threads:\n");
06841 AST_LIST_LOCK(&dynamic_list);
06842 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06843 #ifdef DEBUG_SCHED_MULTITHREAD
06844 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06845 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06846 #else
06847 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06848 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06849 #endif
06850 dynamiccount++;
06851 }
06852 AST_LIST_UNLOCK(&dynamic_list);
06853 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06854 return CLI_SUCCESS;
06855 }
06856
06857 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06858 {
06859 struct iax2_peer *p;
06860
06861 switch (cmd) {
06862 case CLI_INIT:
06863 e->command = "iax2 unregister";
06864 e->usage =
06865 "Usage: iax2 unregister <peername>\n"
06866 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06867 return NULL;
06868 case CLI_GENERATE:
06869 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06870 }
06871
06872 if (a->argc != 3)
06873 return CLI_SHOWUSAGE;
06874
06875 p = find_peer(a->argv[2], 1);
06876 if (p) {
06877 if (p->expire > 0) {
06878 struct iax2_peer tmp_peer = {
06879 .name = a->argv[2],
06880 };
06881 struct iax2_peer *peer;
06882
06883 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06884 if (peer) {
06885 expire_registry(peer_ref(peer));
06886 peer_unref(peer);
06887 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06888 } else {
06889 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06890 }
06891 } else {
06892 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06893 }
06894 } else {
06895 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06896 }
06897 return CLI_SUCCESS;
06898 }
06899
06900 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06901 {
06902 int which = 0;
06903 struct iax2_peer *p = NULL;
06904 char *res = NULL;
06905 int wordlen = strlen(word);
06906
06907
06908 if (pos == 2) {
06909 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06910 while ((p = ao2_iterator_next(&i))) {
06911 if (!strncasecmp(p->name, word, wordlen) &&
06912 ++which > state && p->expire > 0) {
06913 res = ast_strdup(p->name);
06914 peer_unref(p);
06915 break;
06916 }
06917 peer_unref(p);
06918 }
06919 ao2_iterator_destroy(&i);
06920 }
06921
06922 return res;
06923 }
06924
06925 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06926 {
06927 switch (cmd) {
06928 case CLI_INIT:
06929 e->command = "iax2 show peers";
06930 e->usage =
06931 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06932 " Lists all known IAX2 peers.\n"
06933 " Optional 'registered' argument lists only peers with known addresses.\n"
06934 " Optional regular expression pattern is used to filter the peer list.\n";
06935 return NULL;
06936 case CLI_GENERATE:
06937 return NULL;
06938 }
06939
06940 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06941 case RESULT_SHOWUSAGE:
06942 return CLI_SHOWUSAGE;
06943 case RESULT_FAILURE:
06944 return CLI_FAILURE;
06945 default:
06946 return CLI_SUCCESS;
06947 }
06948 }
06949
06950 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06951 {
06952 ast_cli_netstats(s, -1, 0);
06953 astman_append(s, "\r\n");
06954 return RESULT_SUCCESS;
06955 }
06956
06957 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06958 {
06959 struct iax_firmware *cur = NULL;
06960
06961 switch (cmd) {
06962 case CLI_INIT:
06963 e->command = "iax2 show firmware";
06964 e->usage =
06965 "Usage: iax2 show firmware\n"
06966 " Lists all known IAX firmware images.\n";
06967 return NULL;
06968 case CLI_GENERATE:
06969 return NULL;
06970 }
06971
06972 if (a->argc != 3 && a->argc != 4)
06973 return CLI_SHOWUSAGE;
06974
06975 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06976 AST_LIST_LOCK(&firmwares);
06977 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06978 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06979 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06980 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06981 }
06982 }
06983 AST_LIST_UNLOCK(&firmwares);
06984
06985 return CLI_SUCCESS;
06986 }
06987
06988
06989 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06990 {
06991 static const char * const a[] = { "iax2", "show", "peers" };
06992 const char *id = astman_get_header(m,"ActionID");
06993 char idtext[256] = "";
06994 int total = 0;
06995
06996 if (!ast_strlen_zero(id))
06997 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06998
06999 astman_send_listack(s, m, "Peer status list will follow", "start");
07000
07001 __iax2_show_peers(-1, &total, s, 3, a);
07002
07003 astman_append(s,
07004 "Event: PeerlistComplete\r\n"
07005 "EventList: Complete\r\n"
07006 "ListItems: %d\r\n"
07007 "%s"
07008 "\r\n", total, idtext);
07009 return 0;
07010 }
07011
07012
07013 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
07014 {
07015 struct iax2_peer *peer = NULL;
07016 int peer_count = 0;
07017 char nm[20];
07018 char status[20];
07019 const char *id = astman_get_header(m,"ActionID");
07020 char idtext[256] = "";
07021 struct ast_str *encmethods = ast_str_alloca(256);
07022 struct ao2_iterator i;
07023
07024 if (!ast_strlen_zero(id))
07025 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07026
07027 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
07028
07029
07030 i = ao2_iterator_init(peers, 0);
07031 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
07032 encmethods_to_str(peer->encmethods, encmethods);
07033 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
07034 if (!ast_strlen_zero(peer->username)) {
07035 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07036 } else {
07037 astman_append(s, "ObjectName: %s\r\n", peer->name);
07038 }
07039 astman_append(s, "ChanObjectType: peer\r\n");
07040 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07041 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07042 astman_append(s, "Mask: %s\r\n", nm);
07043 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07044 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07045 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07046 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07047 peer_status(peer, status, sizeof(status));
07048 astman_append(s, "Status: %s\r\n\r\n", status);
07049 peer_count++;
07050 }
07051 ao2_iterator_destroy(&i);
07052
07053 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07054 return RESULT_SUCCESS;
07055 }
07056
07057
07058 static char *regstate2str(int regstate)
07059 {
07060 switch(regstate) {
07061 case REG_STATE_UNREGISTERED:
07062 return "Unregistered";
07063 case REG_STATE_REGSENT:
07064 return "Request Sent";
07065 case REG_STATE_AUTHSENT:
07066 return "Auth. Sent";
07067 case REG_STATE_REGISTERED:
07068 return "Registered";
07069 case REG_STATE_REJECTED:
07070 return "Rejected";
07071 case REG_STATE_TIMEOUT:
07072 return "Timeout";
07073 case REG_STATE_NOAUTH:
07074 return "No Authentication";
07075 default:
07076 return "Unknown";
07077 }
07078 }
07079
07080 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07081 {
07082 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
07083 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
07084 struct iax2_registry *reg = NULL;
07085 char host[80];
07086 char perceived[80];
07087 int counter = 0;
07088
07089 switch (cmd) {
07090 case CLI_INIT:
07091 e->command = "iax2 show registry";
07092 e->usage =
07093 "Usage: iax2 show registry\n"
07094 " Lists all registration requests and status.\n";
07095 return NULL;
07096 case CLI_GENERATE:
07097 return NULL;
07098 }
07099 if (a->argc != 3)
07100 return CLI_SHOWUSAGE;
07101 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07102 AST_LIST_LOCK(®istrations);
07103 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07104 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07105 if (reg->us.sin_addr.s_addr)
07106 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07107 else
07108 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07109 ast_cli(a->fd, FORMAT, host,
07110 (reg->dnsmgr) ? "Y" : "N",
07111 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07112 counter++;
07113 }
07114 AST_LIST_UNLOCK(®istrations);
07115 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07116 return CLI_SUCCESS;
07117 #undef FORMAT
07118 #undef FORMAT2
07119 }
07120
07121 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
07122 {
07123 const char *id = astman_get_header(m, "ActionID");
07124 struct iax2_registry *reg = NULL;
07125 char idtext[256] = "";
07126 char host[80] = "";
07127 char perceived[80] = "";
07128 int total = 0;
07129
07130 if (!ast_strlen_zero(id))
07131 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07132
07133 astman_send_listack(s, m, "Registrations will follow", "start");
07134
07135 AST_LIST_LOCK(®istrations);
07136 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07137 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07138
07139 if (reg->us.sin_addr.s_addr) {
07140 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07141 } else {
07142 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07143 }
07144
07145 astman_append(s,
07146 "Event: RegistryEntry\r\n"
07147 "%s"
07148 "Host: %s\r\n"
07149 "DNSmanager: %s\r\n"
07150 "Username: %s\r\n"
07151 "Perceived: %s\r\n"
07152 "Refresh: %d\r\n"
07153 "State: %s\r\n"
07154 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
07155 reg->refresh, regstate2str(reg->regstate));
07156
07157 total++;
07158 }
07159 AST_LIST_UNLOCK(®istrations);
07160
07161 astman_append(s,
07162 "Event: RegistrationsComplete\r\n"
07163 "EventList: Complete\r\n"
07164 "ListItems: %d\r\n"
07165 "%s"
07166 "\r\n", total, idtext);
07167
07168 return 0;
07169 }
07170
07171 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07172 {
07173 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
07174 #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"
07175 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
07176 int x;
07177 int numchans = 0;
07178 char first_message[10] = { 0, };
07179 char last_message[10] = { 0, };
07180
07181 switch (cmd) {
07182 case CLI_INIT:
07183 e->command = "iax2 show channels";
07184 e->usage =
07185 "Usage: iax2 show channels\n"
07186 " Lists all currently active IAX channels.\n";
07187 return NULL;
07188 case CLI_GENERATE:
07189 return NULL;
07190 }
07191
07192 if (a->argc != 3)
07193 return CLI_SHOWUSAGE;
07194 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07195 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07196 ast_mutex_lock(&iaxsl[x]);
07197 if (iaxs[x]) {
07198 int lag, jitter, localdelay;
07199 jb_info jbinfo;
07200 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07201 jb_getinfo(iaxs[x]->jb, &jbinfo);
07202 jitter = jbinfo.jitter;
07203 localdelay = jbinfo.current - jbinfo.min;
07204 } else {
07205 jitter = -1;
07206 localdelay = 0;
07207 }
07208
07209 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07210 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07211 lag = iaxs[x]->remote_rr.delay;
07212 ast_cli(a->fd, FORMAT,
07213 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07214 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07215 S_OR(iaxs[x]->username, "(None)"),
07216 iaxs[x]->callno, iaxs[x]->peercallno,
07217 iaxs[x]->oseqno, iaxs[x]->iseqno,
07218 lag,
07219 jitter,
07220 localdelay,
07221 ast_getformatname(iaxs[x]->voiceformat),
07222 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07223 first_message,
07224 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07225 last_message);
07226 numchans++;
07227 }
07228 ast_mutex_unlock(&iaxsl[x]);
07229 }
07230 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07231 return CLI_SUCCESS;
07232 #undef FORMAT
07233 #undef FORMAT2
07234 #undef FORMATB
07235 }
07236
07237 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
07238 {
07239 int x;
07240 int numchans = 0;
07241 char first_message[10] = { 0, };
07242 char last_message[10] = { 0, };
07243 #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"
07244 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07245 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07246 ast_mutex_lock(&iaxsl[x]);
07247 if (iaxs[x]) {
07248 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07249 jb_info jbinfo;
07250 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07251 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07252
07253 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07254 jb_getinfo(iaxs[x]->jb, &jbinfo);
07255 localjitter = jbinfo.jitter;
07256 localdelay = jbinfo.current - jbinfo.min;
07257 locallost = jbinfo.frames_lost;
07258 locallosspct = jbinfo.losspct/1000;
07259 localdropped = jbinfo.frames_dropped;
07260 localooo = jbinfo.frames_ooo;
07261 } else {
07262 localjitter = -1;
07263 localdelay = 0;
07264 locallost = -1;
07265 locallosspct = -1;
07266 localdropped = 0;
07267 localooo = -1;
07268 }
07269 if (s)
07270 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07271 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07272 iaxs[x]->pingtime,
07273 localjitter,
07274 localdelay,
07275 locallost,
07276 locallosspct,
07277 localdropped,
07278 localooo,
07279 iaxs[x]->frames_received/1000,
07280 iaxs[x]->remote_rr.jitter,
07281 iaxs[x]->remote_rr.delay,
07282 iaxs[x]->remote_rr.losscnt,
07283 iaxs[x]->remote_rr.losspct,
07284 iaxs[x]->remote_rr.dropped,
07285 iaxs[x]->remote_rr.ooo,
07286 iaxs[x]->remote_rr.packets/1000,
07287 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07288 first_message,
07289 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07290 last_message);
07291 else
07292 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07293 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07294 iaxs[x]->pingtime,
07295 localjitter,
07296 localdelay,
07297 locallost,
07298 locallosspct,
07299 localdropped,
07300 localooo,
07301 iaxs[x]->frames_received/1000,
07302 iaxs[x]->remote_rr.jitter,
07303 iaxs[x]->remote_rr.delay,
07304 iaxs[x]->remote_rr.losscnt,
07305 iaxs[x]->remote_rr.losspct,
07306 iaxs[x]->remote_rr.dropped,
07307 iaxs[x]->remote_rr.ooo,
07308 iaxs[x]->remote_rr.packets/1000,
07309 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07310 first_message,
07311 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07312 last_message);
07313 numchans++;
07314 }
07315 ast_mutex_unlock(&iaxsl[x]);
07316 }
07317
07318 return numchans;
07319 }
07320
07321 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07322 {
07323 int numchans = 0;
07324
07325 switch (cmd) {
07326 case CLI_INIT:
07327 e->command = "iax2 show netstats";
07328 e->usage =
07329 "Usage: iax2 show netstats\n"
07330 " Lists network status for all currently active IAX channels.\n";
07331 return NULL;
07332 case CLI_GENERATE:
07333 return NULL;
07334 }
07335 if (a->argc != 3)
07336 return CLI_SHOWUSAGE;
07337 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07338 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07339 numchans = ast_cli_netstats(NULL, a->fd, 1);
07340 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07341 return CLI_SUCCESS;
07342 }
07343
07344 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07345 {
07346 switch (cmd) {
07347 case CLI_INIT:
07348 e->command = "iax2 set debug {on|off|peer}";
07349 e->usage =
07350 "Usage: iax2 set debug {on|off|peer peername}\n"
07351 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07352 return NULL;
07353 case CLI_GENERATE:
07354 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07355 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07356 return NULL;
07357 }
07358
07359 if (a->argc < e->args || a->argc > e->args + 1)
07360 return CLI_SHOWUSAGE;
07361
07362 if (!strcasecmp(a->argv[3], "peer")) {
07363 struct iax2_peer *peer;
07364 struct sockaddr_in peer_addr;
07365
07366
07367 if (a->argc != e->args + 1)
07368 return CLI_SHOWUSAGE;
07369
07370 peer = find_peer(a->argv[4], 1);
07371
07372 if (!peer) {
07373 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07374 return CLI_FAILURE;
07375 }
07376
07377 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07378
07379 debugaddr.sin_addr = peer_addr.sin_addr;
07380 debugaddr.sin_port = peer_addr.sin_port;
07381
07382 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07383 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07384
07385 ao2_ref(peer, -1);
07386 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07387 iaxdebug = 1;
07388 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07389 } else {
07390 iaxdebug = 0;
07391 memset(&debugaddr, 0, sizeof(debugaddr));
07392 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07393 }
07394 return CLI_SUCCESS;
07395 }
07396
07397 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07398 {
07399 switch (cmd) {
07400 case CLI_INIT:
07401 e->command = "iax2 set debug trunk {on|off}";
07402 e->usage =
07403 "Usage: iax2 set debug trunk {on|off}\n"
07404 " Enables/Disables debugging of IAX trunking\n";
07405 return NULL;
07406 case CLI_GENERATE:
07407 return NULL;
07408 }
07409
07410 if (a->argc != e->args)
07411 return CLI_SHOWUSAGE;
07412
07413 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07414 iaxtrunkdebug = 1;
07415 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07416 } else {
07417 iaxtrunkdebug = 0;
07418 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07419 }
07420 return CLI_SUCCESS;
07421 }
07422
07423 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07424 {
07425 switch (cmd) {
07426 case CLI_INIT:
07427 e->command = "iax2 set debug jb {on|off}";
07428 e->usage =
07429 "Usage: iax2 set debug jb {on|off}\n"
07430 " Enables/Disables jitterbuffer debugging information\n";
07431 return NULL;
07432 case CLI_GENERATE:
07433 return NULL;
07434 }
07435
07436 if (a->argc != e->args)
07437 return CLI_SHOWUSAGE;
07438
07439 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07440 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07441 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07442 } else {
07443 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07444 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07445 }
07446 return CLI_SUCCESS;
07447 }
07448
07449 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07450 {
07451 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07452 int res = -1;
07453 ast_mutex_lock(&iaxsl[callno]);
07454 if (iaxs[callno]) {
07455
07456 if (!iaxs[callno]->error) {
07457 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07458 res = 0;
07459
07460 else if (f->frametype == AST_FRAME_NULL)
07461 res = 0;
07462 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07463 res = 0;
07464 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07465 res = 0;
07466 else
07467
07468 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07469 } else {
07470 ast_debug(1, "Write error: %s\n", strerror(errno));
07471 }
07472 }
07473
07474 ast_mutex_unlock(&iaxsl[callno]);
07475 return res;
07476 }
07477
07478 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07479 int now, int transfer, int final)
07480 {
07481 struct ast_frame f = { 0, };
07482 int res = 0;
07483
07484 f.frametype = type;
07485 f.subclass.integer = command;
07486 f.datalen = datalen;
07487 f.src = __FUNCTION__;
07488 f.data.ptr = (void *) data;
07489
07490 if ((res = queue_signalling(i, &f)) <= 0) {
07491 return res;
07492 }
07493
07494 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07495 }
07496
07497 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07498 {
07499 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07500 }
07501
07502 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07503 {
07504 int res;
07505 ast_mutex_lock(&iaxsl[callno]);
07506 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07507 ast_mutex_unlock(&iaxsl[callno]);
07508 return res;
07509 }
07510
07511
07512
07513
07514
07515
07516 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)
07517 {
07518 int call_num = i->callno;
07519
07520 iax2_predestroy(i->callno);
07521 if (!iaxs[call_num])
07522 return -1;
07523 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07524 }
07525
07526 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)
07527 {
07528 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07529 }
07530
07531 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07532 {
07533 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07534 }
07535
07536 static int apply_context(struct iax2_context *con, const char *context)
07537 {
07538 while(con) {
07539 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07540 return -1;
07541 con = con->next;
07542 }
07543 return 0;
07544 }
07545
07546
07547 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07548 {
07549
07550 int res = -1;
07551 int version = 2;
07552 struct iax2_user *user = NULL, *best = NULL;
07553 int bestscore = 0;
07554 int gotcapability = 0;
07555 struct ast_variable *v = NULL, *tmpvar = NULL;
07556 struct ao2_iterator i;
07557 struct ast_sockaddr addr;
07558
07559 if (!iaxs[callno])
07560 return res;
07561 if (ies->called_number)
07562 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07563 if (ies->calling_number) {
07564 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07565 ast_shrink_phone_number(ies->calling_number);
07566 }
07567 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07568 }
07569 if (ies->calling_name)
07570 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07571 if (ies->calling_ani)
07572 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07573 if (ies->dnid)
07574 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07575 if (ies->rdnis)
07576 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07577 if (ies->called_context)
07578 ast_string_field_set(iaxs[callno], context, ies->called_context);
07579 if (ies->language)
07580 ast_string_field_set(iaxs[callno], language, ies->language);
07581 if (ies->username)
07582 ast_string_field_set(iaxs[callno], username, ies->username);
07583 if (ies->calling_ton > -1)
07584 iaxs[callno]->calling_ton = ies->calling_ton;
07585 if (ies->calling_tns > -1)
07586 iaxs[callno]->calling_tns = ies->calling_tns;
07587 if (ies->calling_pres > -1)
07588 iaxs[callno]->calling_pres = ies->calling_pres;
07589 if (ies->format)
07590 iaxs[callno]->peerformat = ies->format;
07591 if (ies->adsicpe)
07592 iaxs[callno]->peeradsicpe = ies->adsicpe;
07593 if (ies->capability) {
07594 gotcapability = 1;
07595 iaxs[callno]->peercapability = ies->capability;
07596 }
07597 if (ies->version)
07598 version = ies->version;
07599
07600
07601 if (ies->codec_prefs) {
07602 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07603 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07604 }
07605
07606 if (!gotcapability)
07607 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07608 if (version > IAX_PROTO_VERSION) {
07609 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07610 ast_inet_ntoa(sin->sin_addr), version);
07611 return res;
07612 }
07613
07614 ast_sockaddr_from_sin(&addr, sin);
07615 i = ao2_iterator_init(users, 0);
07616 while ((user = ao2_iterator_next(&i))) {
07617 if ((ast_strlen_zero(iaxs[callno]->username) ||
07618 !strcmp(iaxs[callno]->username, user->name))
07619 && ast_apply_ha(user->ha, &addr)
07620 && (ast_strlen_zero(iaxs[callno]->context) ||
07621 apply_context(user->contexts, iaxs[callno]->context))) {
07622 if (!ast_strlen_zero(iaxs[callno]->username)) {
07623
07624 if (best)
07625 user_unref(best);
07626 best = user;
07627 break;
07628 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07629
07630 if (user->ha) {
07631
07632 if (bestscore < 4) {
07633 bestscore = 4;
07634 if (best)
07635 user_unref(best);
07636 best = user;
07637 continue;
07638 }
07639 } else {
07640
07641 if (bestscore < 3) {
07642 bestscore = 3;
07643 if (best)
07644 user_unref(best);
07645 best = user;
07646 continue;
07647 }
07648 }
07649 } else {
07650 if (user->ha) {
07651
07652 if (bestscore < 2) {
07653 bestscore = 2;
07654 if (best)
07655 user_unref(best);
07656 best = user;
07657 continue;
07658 }
07659 } else {
07660
07661 if (bestscore < 1) {
07662 bestscore = 1;
07663 if (best)
07664 user_unref(best);
07665 best = user;
07666 continue;
07667 }
07668 }
07669 }
07670 }
07671 user_unref(user);
07672 }
07673 ao2_iterator_destroy(&i);
07674 user = best;
07675 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07676 user = realtime_user(iaxs[callno]->username, sin);
07677 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07678 !apply_context(user->contexts, iaxs[callno]->context)) {
07679 user = user_unref(user);
07680 }
07681 }
07682 if (user) {
07683
07684
07685 for (v = user->vars ; v ; v = v->next) {
07686 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07687 tmpvar->next = iaxs[callno]->vars;
07688 iaxs[callno]->vars = tmpvar;
07689 }
07690 }
07691
07692 if (user->maxauthreq > 0)
07693 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07694 iaxs[callno]->prefs = user->prefs;
07695 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07696 iaxs[callno]->encmethods = user->encmethods;
07697
07698 if (ast_strlen_zero(iaxs[callno]->username))
07699 ast_string_field_set(iaxs[callno], username, user->name);
07700
07701 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07702 iaxs[callno]->capability = user->capability;
07703
07704 if (ast_strlen_zero(iaxs[callno]->context)) {
07705 if (user->contexts)
07706 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07707 else
07708 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07709 }
07710
07711 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07712
07713 iaxs[callno]->authmethods = user->authmethods;
07714 iaxs[callno]->adsi = user->adsi;
07715
07716 if (ast_test_flag64(user, IAX_HASCALLERID)) {
07717 iaxs[callno]->calling_tns = 0;
07718 iaxs[callno]->calling_ton = 0;
07719 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07720 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07721 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07722 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07723 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07724 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07725 }
07726 if (!ast_strlen_zero(user->accountcode))
07727 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07728 if (!ast_strlen_zero(user->mohinterpret))
07729 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07730 if (!ast_strlen_zero(user->mohsuggest))
07731 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07732 if (!ast_strlen_zero(user->parkinglot))
07733 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07734 if (user->amaflags)
07735 iaxs[callno]->amaflags = user->amaflags;
07736 if (!ast_strlen_zero(user->language))
07737 ast_string_field_set(iaxs[callno], language, user->language);
07738 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
07739
07740 if (!ast_strlen_zero(user->dbsecret)) {
07741 char *family, *key=NULL;
07742 char buf[80];
07743 family = ast_strdupa(user->dbsecret);
07744 key = strchr(family, '/');
07745 if (key) {
07746 *key = '\0';
07747 key++;
07748 }
07749 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07750 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07751 else
07752 ast_string_field_set(iaxs[callno], secret, buf);
07753 } else
07754 ast_string_field_set(iaxs[callno], secret, user->secret);
07755 res = 0;
07756 user = user_unref(user);
07757 } else {
07758
07759
07760
07761
07762 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07763 ast_string_field_set(iaxs[callno], secret, "badsecret");
07764 iaxs[callno]->authrej = 1;
07765 if (!ast_strlen_zero(iaxs[callno]->username)) {
07766
07767 res = 0;
07768 }
07769 }
07770 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07771 return res;
07772 }
07773
07774 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07775 {
07776 struct ast_iax2_full_hdr fh;
07777 fh.scallno = htons(src | IAX_FLAG_FULL);
07778 fh.dcallno = htons(dst);
07779 fh.ts = 0;
07780 fh.oseqno = 0;
07781 fh.iseqno = 0;
07782 fh.type = AST_FRAME_IAX;
07783 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07784 iax_outputframe(NULL, &fh, 0, sin, 0);
07785 #if 0
07786 if (option_debug)
07787 #endif
07788 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07789 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07790 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07791 }
07792
07793 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07794 {
07795
07796 p->encmethods &= enc;
07797 if (p->encmethods) {
07798 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07799 p->keyrotateid = -2;
07800 }
07801 if (p->encmethods & IAX_ENCRYPT_AES128)
07802 p->encmethods = IAX_ENCRYPT_AES128;
07803 else
07804 p->encmethods = 0;
07805 }
07806 }
07807
07808
07809
07810
07811
07812
07813
07814 static int authenticate_request(int call_num)
07815 {
07816 struct iax_ie_data ied;
07817 int res = -1, authreq_restrict = 0;
07818 char challenge[10];
07819 struct chan_iax2_pvt *p = iaxs[call_num];
07820
07821 memset(&ied, 0, sizeof(ied));
07822
07823
07824 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07825 struct iax2_user *user, tmp_user = {
07826 .name = p->username,
07827 };
07828
07829 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07830 if (user) {
07831 if (user->curauthreq == user->maxauthreq)
07832 authreq_restrict = 1;
07833 else
07834 user->curauthreq++;
07835 user = user_unref(user);
07836 }
07837 }
07838
07839
07840 if (authreq_restrict) {
07841 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07842 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07843 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07844 return 0;
07845 }
07846
07847 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07848 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07849 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07850 ast_string_field_set(p, challenge, challenge);
07851
07852 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07853 }
07854 if (p->encmethods)
07855 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07856
07857 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07858
07859 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07860
07861 if (p->encmethods)
07862 ast_set_flag64(p, IAX_ENCRYPTED);
07863
07864 return res;
07865 }
07866
07867 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07868 {
07869 char requeststr[256];
07870 char md5secret[256] = "";
07871 char secret[256] = "";
07872 char rsasecret[256] = "";
07873 int res = -1;
07874 int x;
07875 struct iax2_user *user, tmp_user = {
07876 .name = p->username,
07877 };
07878
07879 if (p->authrej) {
07880 return res;
07881 }
07882 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07883 if (user) {
07884 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07885 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07886 ast_clear_flag64(p, IAX_MAXAUTHREQ);
07887 }
07888 ast_string_field_set(p, host, user->name);
07889 user = user_unref(user);
07890 }
07891 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07892 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07893 return res;
07894 }
07895 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07896 return res;
07897 if (ies->password)
07898 ast_copy_string(secret, ies->password, sizeof(secret));
07899 if (ies->md5_result)
07900 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07901 if (ies->rsa_result)
07902 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07903 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07904 struct ast_key *key;
07905 char *keyn;
07906 char tmpkey[256];
07907 char *stringp=NULL;
07908 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07909 stringp=tmpkey;
07910 keyn = strsep(&stringp, ":");
07911 while(keyn) {
07912 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07913 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07914 res = 0;
07915 break;
07916 } else if (!key)
07917 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07918 keyn = strsep(&stringp, ":");
07919 }
07920 } else if (p->authmethods & IAX_AUTH_MD5) {
07921 struct MD5Context md5;
07922 unsigned char digest[16];
07923 char *tmppw, *stringp;
07924
07925 tmppw = ast_strdupa(p->secret);
07926 stringp = tmppw;
07927 while((tmppw = strsep(&stringp, ";"))) {
07928 MD5Init(&md5);
07929 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07930 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07931 MD5Final(digest, &md5);
07932
07933 for (x=0;x<16;x++)
07934 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07935 if (!strcasecmp(requeststr, md5secret)) {
07936 res = 0;
07937 break;
07938 }
07939 }
07940 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07941 if (!strcmp(secret, p->secret))
07942 res = 0;
07943 }
07944 return res;
07945 }
07946
07947
07948 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07949 {
07950 char requeststr[256] = "";
07951 char peer[256] = "";
07952 char md5secret[256] = "";
07953 char rsasecret[256] = "";
07954 char secret[256] = "";
07955 struct iax2_peer *p = NULL;
07956 struct ast_key *key;
07957 char *keyn;
07958 int x;
07959 int expire = 0;
07960 int res = -1;
07961 struct ast_sockaddr addr;
07962
07963 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07964
07965 if (ies->username)
07966 ast_copy_string(peer, ies->username, sizeof(peer));
07967 if (ies->password)
07968 ast_copy_string(secret, ies->password, sizeof(secret));
07969 if (ies->md5_result)
07970 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07971 if (ies->rsa_result)
07972 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07973 if (ies->refresh)
07974 expire = ies->refresh;
07975
07976 if (ast_strlen_zero(peer)) {
07977 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07978 return -1;
07979 }
07980
07981
07982 ast_mutex_unlock(&iaxsl[callno]);
07983 p = find_peer(peer, 1);
07984 ast_mutex_lock(&iaxsl[callno]);
07985 if (!p || !iaxs[callno]) {
07986 if (iaxs[callno]) {
07987 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07988
07989 ast_string_field_set(iaxs[callno], secret, "badsecret");
07990
07991
07992
07993
07994
07995
07996
07997
07998
07999 if (ast_strlen_zero(iaxs[callno]->challenge) &&
08000 !(!ast_strlen_zero(secret) && plaintext)) {
08001
08002 res = 0;
08003 }
08004 }
08005 if (authdebug && !p)
08006 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08007 goto return_unref;
08008 }
08009
08010 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
08011 if (authdebug)
08012 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08013 goto return_unref;
08014 }
08015
08016 ast_sockaddr_from_sin(&addr, sin);
08017 if (!ast_apply_ha(p->ha, &addr)) {
08018 if (authdebug)
08019 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08020 goto return_unref;
08021 }
08022 ast_string_field_set(iaxs[callno], secret, p->secret);
08023 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
08024
08025 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08026 if (!ast_strlen_zero(p->inkeys)) {
08027 char tmpkeys[256];
08028 char *stringp=NULL;
08029 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
08030 stringp=tmpkeys;
08031 keyn = strsep(&stringp, ":");
08032 while(keyn) {
08033 key = ast_key_get(keyn, AST_KEY_PUBLIC);
08034 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
08035 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08036 break;
08037 } else if (!key)
08038 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08039 keyn = strsep(&stringp, ":");
08040 }
08041 if (!keyn) {
08042 if (authdebug)
08043 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08044 goto return_unref;
08045 }
08046 } else {
08047 if (authdebug)
08048 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08049 goto return_unref;
08050 }
08051 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08052 struct MD5Context md5;
08053 unsigned char digest[16];
08054 char *tmppw, *stringp;
08055
08056 tmppw = ast_strdupa(p->secret);
08057 stringp = tmppw;
08058 while((tmppw = strsep(&stringp, ";"))) {
08059 MD5Init(&md5);
08060 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08061 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08062 MD5Final(digest, &md5);
08063 for (x=0;x<16;x++)
08064 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
08065 if (!strcasecmp(requeststr, md5secret))
08066 break;
08067 }
08068 if (tmppw) {
08069 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08070 } else {
08071 if (authdebug)
08072 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08073 goto return_unref;
08074 }
08075 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08076
08077 if (strcmp(secret, p->secret)) {
08078 if (authdebug)
08079 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08080 goto return_unref;
08081 } else
08082 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08083 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08084
08085 goto return_unref;
08086 }
08087 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08088
08089
08090 res = 0;
08091
08092 return_unref:
08093 if (iaxs[callno]) {
08094 ast_string_field_set(iaxs[callno], peer, peer);
08095
08096
08097 if (expire && (expire < iaxs[callno]->expiry)) {
08098 iaxs[callno]->expiry = expire;
08099 }
08100 }
08101
08102 if (p) {
08103 peer_unref(p);
08104 }
08105 return res;
08106 }
08107
08108 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)
08109 {
08110 int res = -1;
08111 int x;
08112 if (!ast_strlen_zero(keyn)) {
08113 if (!(authmethods & IAX_AUTH_RSA)) {
08114 if (ast_strlen_zero(secret))
08115 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));
08116 } else if (ast_strlen_zero(challenge)) {
08117 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08118 } else {
08119 char sig[256];
08120 struct ast_key *key;
08121 key = ast_key_get(keyn, AST_KEY_PRIVATE);
08122 if (!key) {
08123 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08124 } else {
08125 if (ast_sign(key, (char*)challenge, sig)) {
08126 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08127 res = -1;
08128 } else {
08129 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08130 res = 0;
08131 }
08132 }
08133 }
08134 }
08135
08136 if (res && !ast_strlen_zero(secret)) {
08137 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08138 struct MD5Context md5;
08139 unsigned char digest[16];
08140 char digres[128];
08141 MD5Init(&md5);
08142 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08143 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08144 MD5Final(digest, &md5);
08145
08146 for (x=0;x<16;x++)
08147 sprintf(digres + (x << 1), "%2.2x", digest[x]);
08148 if (pvt) {
08149 build_encryption_keys(digest, pvt);
08150 }
08151 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08152 res = 0;
08153 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08154 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08155 res = 0;
08156 } else
08157 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08158 }
08159 return res;
08160 }
08161
08162
08163
08164
08165
08166 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
08167 {
08168 struct iax2_peer *peer = NULL;
08169
08170 int res = -1;
08171 int authmethods = 0;
08172 struct iax_ie_data ied;
08173 uint16_t callno = p->callno;
08174
08175 memset(&ied, 0, sizeof(ied));
08176
08177 if (ies->username)
08178 ast_string_field_set(p, username, ies->username);
08179 if (ies->challenge)
08180 ast_string_field_set(p, challenge, ies->challenge);
08181 if (ies->authmethods)
08182 authmethods = ies->authmethods;
08183 if (authmethods & IAX_AUTH_MD5)
08184 merge_encryption(p, ies->encmethods);
08185 else
08186 p->encmethods = 0;
08187
08188
08189 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08190
08191 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08192 } else {
08193 struct ao2_iterator i = ao2_iterator_init(peers, 0);
08194 while ((peer = ao2_iterator_next(&i))) {
08195 struct sockaddr_in peer_addr;
08196
08197 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08198
08199 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08200
08201 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08202
08203 && (!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)))
08204
08205 ) {
08206 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08207 if (!res) {
08208 peer_unref(peer);
08209 break;
08210 }
08211 }
08212 peer_unref(peer);
08213 }
08214 ao2_iterator_destroy(&i);
08215 if (!peer) {
08216
08217
08218 const char *peer_name = ast_strdupa(p->peer);
08219 ast_mutex_unlock(&iaxsl[callno]);
08220 if ((peer = realtime_peer(peer_name, NULL))) {
08221 ast_mutex_lock(&iaxsl[callno]);
08222 if (!(p = iaxs[callno])) {
08223 peer_unref(peer);
08224 return -1;
08225 }
08226 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08227 peer_unref(peer);
08228 }
08229 if (!peer) {
08230 ast_mutex_lock(&iaxsl[callno]);
08231 if (!(p = iaxs[callno]))
08232 return -1;
08233 }
08234 }
08235 }
08236
08237 if (ies->encmethods) {
08238 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08239 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08240 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
08241 return -1;
08242 }
08243 if (!res) {
08244 struct ast_datastore *variablestore;
08245 struct ast_variable *var, *prev = NULL;
08246 AST_LIST_HEAD(, ast_var_t) *varlist;
08247 varlist = ast_calloc(1, sizeof(*varlist));
08248 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08249 if (variablestore && varlist && p->owner) {
08250 variablestore->data = varlist;
08251 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08252 AST_LIST_HEAD_INIT(varlist);
08253 for (var = ies->vars; var; var = var->next) {
08254 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08255 if (prev)
08256 ast_free(prev);
08257 prev = var;
08258 if (!newvar) {
08259
08260 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08261 } else {
08262 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08263 }
08264 }
08265 if (prev)
08266 ast_free(prev);
08267 ies->vars = NULL;
08268 ast_channel_datastore_add(p->owner, variablestore);
08269 } else {
08270 if (p->owner)
08271 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08272 if (variablestore)
08273 ast_datastore_free(variablestore);
08274 if (varlist)
08275 ast_free(varlist);
08276 }
08277 }
08278
08279 if (!res)
08280 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08281 return res;
08282 }
08283
08284 static int iax2_do_register(struct iax2_registry *reg);
08285
08286 static void __iax2_do_register_s(const void *data)
08287 {
08288 struct iax2_registry *reg = (struct iax2_registry *)data;
08289 reg->expire = -1;
08290 iax2_do_register(reg);
08291 }
08292
08293 static int iax2_do_register_s(const void *data)
08294 {
08295 #ifdef SCHED_MULTITHREADED
08296 if (schedule_action(__iax2_do_register_s, data))
08297 #endif
08298 __iax2_do_register_s(data);
08299 return 0;
08300 }
08301
08302 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08303 {
08304 int newcall = 0;
08305 char newip[256];
08306 struct iax_ie_data ied;
08307 struct sockaddr_in new = { 0, };
08308
08309 memset(&ied, 0, sizeof(ied));
08310 if (ies->apparent_addr)
08311 memmove(&new, ies->apparent_addr, sizeof(new));
08312 if (ies->callno)
08313 newcall = ies->callno;
08314 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08315 ast_log(LOG_WARNING, "Invalid transfer request\n");
08316 return -1;
08317 }
08318 pvt->transfercallno = newcall;
08319 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08320 inet_aton(newip, &pvt->transfer.sin_addr);
08321 pvt->transfer.sin_family = AF_INET;
08322 pvt->transferid = ies->transferid;
08323
08324
08325 if (pvt->transferring == TRANSFER_NONE) {
08326 store_by_transfercallno(pvt);
08327 }
08328 pvt->transferring = TRANSFER_BEGIN;
08329
08330 if (ies->transferid)
08331 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08332 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08333 return 0;
08334 }
08335
08336 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08337 {
08338 char exten[256] = "";
08339 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08340 struct iax2_dpcache *dp = NULL;
08341
08342 if (ies->called_number)
08343 ast_copy_string(exten, ies->called_number, sizeof(exten));
08344
08345 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08346 status = CACHE_FLAG_EXISTS;
08347 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08348 status = CACHE_FLAG_CANEXIST;
08349 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08350 status = CACHE_FLAG_NONEXISTENT;
08351
08352 if (ies->refresh)
08353 expiry = ies->refresh;
08354 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08355 matchmore = CACHE_FLAG_MATCHMORE;
08356
08357 AST_LIST_LOCK(&dpcache);
08358 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08359 if (strcmp(dp->exten, exten))
08360 continue;
08361 AST_LIST_REMOVE_CURRENT(peer_list);
08362 dp->callno = 0;
08363 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08364 if (dp->flags & CACHE_FLAG_PENDING) {
08365 dp->flags &= ~CACHE_FLAG_PENDING;
08366 dp->flags |= status;
08367 dp->flags |= matchmore;
08368 }
08369
08370 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08371 if (dp->waiters[x] > -1) {
08372 if (write(dp->waiters[x], "asdf", 4) < 0) {
08373 }
08374 }
08375 }
08376 }
08377 AST_LIST_TRAVERSE_SAFE_END;
08378 AST_LIST_UNLOCK(&dpcache);
08379
08380 return 0;
08381 }
08382
08383 static int complete_transfer(int callno, struct iax_ies *ies)
08384 {
08385 int peercallno = 0;
08386 struct chan_iax2_pvt *pvt = iaxs[callno];
08387 struct iax_frame *cur;
08388 jb_frame frame;
08389
08390 if (ies->callno)
08391 peercallno = ies->callno;
08392
08393 if (peercallno < 1) {
08394 ast_log(LOG_WARNING, "Invalid transfer request\n");
08395 return -1;
08396 }
08397 remove_by_transfercallno(pvt);
08398
08399
08400
08401 peercnt_remove_by_addr(&pvt->addr);
08402 peercnt_add(&pvt->transfer);
08403
08404 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08405 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08406
08407 pvt->oseqno = 0;
08408 pvt->rseqno = 0;
08409 pvt->iseqno = 0;
08410 pvt->aseqno = 0;
08411
08412 if (pvt->peercallno) {
08413 remove_by_peercallno(pvt);
08414 }
08415 pvt->peercallno = peercallno;
08416
08417 store_by_peercallno(pvt);
08418 pvt->transferring = TRANSFER_NONE;
08419 pvt->svoiceformat = -1;
08420 pvt->voiceformat = 0;
08421 pvt->svideoformat = -1;
08422 pvt->videoformat = 0;
08423 pvt->transfercallno = 0;
08424 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08425 memset(&pvt->offset, 0, sizeof(pvt->offset));
08426
08427 while(jb_getall(pvt->jb,&frame) == JB_OK)
08428 iax2_frame_free(frame.data);
08429 jb_reset(pvt->jb);
08430 pvt->lag = 0;
08431 pvt->last = 0;
08432 pvt->lastsent = 0;
08433 pvt->nextpred = 0;
08434 pvt->pingtime = DEFAULT_RETRY_TIME;
08435 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08436
08437
08438
08439 cur->retries = -1;
08440 }
08441 return 0;
08442 }
08443
08444
08445 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08446 {
08447 struct iax2_registry *reg;
08448
08449 char peer[256] = "";
08450 char msgstatus[60];
08451 int refresh = 60;
08452 char ourip[256] = "<Unspecified>";
08453 struct sockaddr_in oldus;
08454 struct sockaddr_in us;
08455 int oldmsgs;
08456 struct sockaddr_in reg_addr;
08457
08458 memset(&us, 0, sizeof(us));
08459 if (ies->apparent_addr) {
08460 memmove(&us, ies->apparent_addr, sizeof(us));
08461 }
08462 if (ies->username) {
08463 ast_copy_string(peer, ies->username, sizeof(peer));
08464 }
08465 if (ies->refresh) {
08466 refresh = ies->refresh;
08467 }
08468 if (ies->calling_number) {
08469
08470 }
08471 reg = iaxs[callno]->reg;
08472 if (!reg) {
08473 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08474 return -1;
08475 }
08476 memcpy(&oldus, ®->us, sizeof(oldus));
08477 oldmsgs = reg->messages;
08478 ast_sockaddr_to_sin(®->addr, ®_addr);
08479 if (inaddrcmp(®_addr, sin)) {
08480 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08481 return -1;
08482 }
08483 memcpy(®->us, &us, sizeof(reg->us));
08484 if (ies->msgcount >= 0) {
08485 reg->messages = ies->msgcount & 0xffff;
08486 }
08487
08488
08489
08490 reg->refresh = refresh;
08491 reg->expire = iax2_sched_replace(reg->expire, sched,
08492 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08493 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08494 if (reg->messages > 255) {
08495 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08496 } else if (reg->messages > 1) {
08497 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08498 } else if (reg->messages > 0) {
08499 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08500 } else {
08501 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08502 }
08503 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08504 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08505 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08506 }
08507 reg->regstate = REG_STATE_REGISTERED;
08508 return 0;
08509 }
08510
08511 static int iax2_append_register(const char *hostname, const char *username,
08512 const char *secret, const char *porta)
08513 {
08514 struct iax2_registry *reg;
08515
08516 if (!(reg = ast_calloc(1, sizeof(*reg))))
08517 return -1;
08518
08519 reg->addr.ss.ss_family = AF_INET;
08520 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08521 ast_free(reg);
08522 return -1;
08523 }
08524
08525 ast_copy_string(reg->username, username, sizeof(reg->username));
08526
08527 if (secret)
08528 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08529
08530 reg->expire = -1;
08531 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08532 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08533
08534 AST_LIST_LOCK(®istrations);
08535 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08536 AST_LIST_UNLOCK(®istrations);
08537
08538 return 0;
08539 }
08540
08541 static int iax2_register(const char *value, int lineno)
08542 {
08543 char copy[256];
08544 char *username, *hostname, *secret;
08545 char *porta;
08546 char *stringp=NULL;
08547
08548 if (!value)
08549 return -1;
08550
08551 ast_copy_string(copy, value, sizeof(copy));
08552 stringp = copy;
08553 username = strsep(&stringp, "@");
08554 hostname = strsep(&stringp, "@");
08555
08556 if (!hostname) {
08557 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08558 return -1;
08559 }
08560
08561 stringp = username;
08562 username = strsep(&stringp, ":");
08563 secret = strsep(&stringp, ":");
08564 stringp = hostname;
08565 hostname = strsep(&stringp, ":");
08566 porta = strsep(&stringp, ":");
08567
08568 if (porta && !atoi(porta)) {
08569 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08570 return -1;
08571 }
08572
08573 return iax2_append_register(hostname, username, secret, porta);
08574 }
08575
08576
08577 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08578 {
08579 char multi[256];
08580 char *stringp, *ext;
08581 if (!ast_strlen_zero(regcontext)) {
08582 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08583 stringp = multi;
08584 while((ext = strsep(&stringp, "&"))) {
08585 if (onoff) {
08586 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08587 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08588 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08589 } else
08590 ast_context_remove_extension(regcontext, ext, 1, NULL);
08591 }
08592 }
08593 }
08594 static void prune_peers(void);
08595
08596 static void unlink_peer(struct iax2_peer *peer)
08597 {
08598 if (peer->expire > -1) {
08599 if (!ast_sched_thread_del(sched, peer->expire)) {
08600 peer->expire = -1;
08601 peer_unref(peer);
08602 }
08603 }
08604
08605 if (peer->pokeexpire > -1) {
08606 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08607 peer->pokeexpire = -1;
08608 peer_unref(peer);
08609 }
08610 }
08611
08612 ao2_unlink(peers, peer);
08613 }
08614
08615 static void __expire_registry(const void *data)
08616 {
08617 struct iax2_peer *peer = (struct iax2_peer *) data;
08618
08619 if (!peer)
08620 return;
08621 if (peer->expire == -1) {
08622
08623 return;
08624 }
08625
08626 peer->expire = -1;
08627
08628 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08629 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08630 realtime_update_peer(peer->name, &peer->addr, 0);
08631 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08632
08633 peercnt_modify(0, 0, &peer->addr);
08634
08635 memset(&peer->addr, 0, sizeof(peer->addr));
08636
08637 peer->expiry = min_reg_expire;
08638 if (!ast_test_flag64(peer, IAX_TEMPONLY))
08639 ast_db_del("IAX/Registry", peer->name);
08640 register_peer_exten(peer, 0);
08641 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08642 if (iax2_regfunk)
08643 iax2_regfunk(peer->name, 0);
08644
08645 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08646 unlink_peer(peer);
08647
08648 peer_unref(peer);
08649 }
08650
08651 static int expire_registry(const void *data)
08652 {
08653 #ifdef SCHED_MULTITHREADED
08654 if (schedule_action(__expire_registry, data))
08655 #endif
08656 __expire_registry(data);
08657 return 0;
08658 }
08659
08660 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08661
08662 static void reg_source_db(struct iax2_peer *p)
08663 {
08664 char data[80];
08665 char *expiry;
08666
08667 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08668 return;
08669 }
08670
08671 expiry = strrchr(data, ':');
08672 if (!expiry) {
08673 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08674 }
08675 *expiry++ = '\0';
08676
08677 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08678 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08679 return;
08680 }
08681
08682 p->expiry = atoi(expiry);
08683
08684 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08685 ast_sockaddr_stringify(&p->addr), p->expiry);
08686
08687 iax2_poke_peer(p, 0);
08688 if (p->expire > -1) {
08689 if (!ast_sched_thread_del(sched, p->expire)) {
08690 p->expire = -1;
08691 peer_unref(p);
08692 }
08693 }
08694
08695 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08696
08697 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08698 if (p->expire == -1) {
08699 peer_unref(p);
08700 }
08701
08702 if (iax2_regfunk) {
08703 iax2_regfunk(p->name, 1);
08704 }
08705
08706 register_peer_exten(p, 1);
08707 }
08708
08709
08710
08711
08712
08713
08714
08715 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08716 {
08717
08718 struct iax_ie_data ied = {
08719 .pos = 0,
08720 };
08721 struct iax2_peer *p;
08722 int msgcount;
08723 char data[80];
08724 int version;
08725 const char *peer_name;
08726 int res = -1;
08727 struct ast_sockaddr sockaddr;
08728
08729 ast_sockaddr_from_sin(&sockaddr, sin);
08730
08731 peer_name = ast_strdupa(iaxs[callno]->peer);
08732
08733
08734 ast_mutex_unlock(&iaxsl[callno]);
08735 if (!(p = find_peer(peer_name, 1))) {
08736 ast_mutex_lock(&iaxsl[callno]);
08737 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08738 return -1;
08739 }
08740 ast_mutex_lock(&iaxsl[callno]);
08741 if (!iaxs[callno])
08742 goto return_unref;
08743
08744 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08745 if (sin->sin_addr.s_addr) {
08746 time_t nowtime;
08747 time(&nowtime);
08748 realtime_update_peer(peer_name, &sockaddr, nowtime);
08749 } else {
08750 realtime_update_peer(peer_name, &sockaddr, 0);
08751 }
08752 }
08753
08754 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08755 if (iax2_regfunk) {
08756 iax2_regfunk(p->name, 1);
08757 }
08758
08759
08760 peercnt_modify(0, 0, &p->addr);
08761
08762
08763 ast_sockaddr_from_sin(&p->addr, sin);
08764
08765 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08766 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08767 ast_db_put("IAX/Registry", p->name, data);
08768 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08769 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08770 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08771 register_peer_exten(p, 1);
08772 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08773 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08774 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08775 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08776 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08777 register_peer_exten(p, 0);
08778 ast_db_del("IAX/Registry", p->name);
08779 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08780 }
08781
08782
08783 iax2_poke_peer(p, callno);
08784 }
08785
08786
08787 if (p->maxcallno) {
08788 peercnt_modify(1, p->maxcallno, &p->addr);
08789 }
08790
08791
08792 if (!iaxs[callno]) {
08793 res = -1;
08794 goto return_unref;
08795 }
08796
08797
08798 p->sockfd = fd;
08799
08800 if (p->expire > -1) {
08801 if (!ast_sched_thread_del(sched, p->expire)) {
08802 p->expire = -1;
08803 peer_unref(p);
08804 }
08805 }
08806
08807 if (!refresh)
08808 refresh = min_reg_expire;
08809 if (refresh > max_reg_expire) {
08810 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08811 p->name, max_reg_expire, refresh);
08812 p->expiry = max_reg_expire;
08813 } else if (refresh < min_reg_expire) {
08814 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08815 p->name, min_reg_expire, refresh);
08816 p->expiry = min_reg_expire;
08817 } else {
08818 p->expiry = refresh;
08819 }
08820 if (p->expiry && sin->sin_addr.s_addr) {
08821 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08822 if (p->expire == -1)
08823 peer_unref(p);
08824 }
08825 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08826 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08827 if (sin->sin_addr.s_addr) {
08828 struct sockaddr_in peer_addr;
08829
08830 ast_sockaddr_to_sin(&p->addr, &peer_addr);
08831
08832 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08833 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08834 if (!ast_strlen_zero(p->mailbox)) {
08835 struct ast_event *event;
08836 int new, old;
08837 char *mailbox, *context;
08838
08839 context = mailbox = ast_strdupa(p->mailbox);
08840 strsep(&context, "@");
08841 if (ast_strlen_zero(context))
08842 context = "default";
08843
08844 event = ast_event_get_cached(AST_EVENT_MWI,
08845 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08846 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08847 AST_EVENT_IE_END);
08848 if (event) {
08849 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08850 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08851 ast_event_destroy(event);
08852 } else {
08853 ast_app_inboxcount(p->mailbox, &new, &old);
08854 }
08855
08856 if (new > 255) {
08857 new = 255;
08858 }
08859 if (old > 255) {
08860 old = 255;
08861 }
08862 msgcount = (old << 8) | new;
08863
08864 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08865 }
08866 if (ast_test_flag64(p, IAX_HASCALLERID)) {
08867 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08868 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08869 }
08870 }
08871 version = iax_check_version(devtype);
08872 if (version)
08873 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08874
08875 res = 0;
08876
08877 return_unref:
08878 peer_unref(p);
08879
08880 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08881 }
08882
08883 static int registry_authrequest(int callno)
08884 {
08885 struct iax_ie_data ied;
08886 struct iax2_peer *p;
08887 char challenge[10];
08888 const char *peer_name;
08889 int sentauthmethod;
08890
08891 peer_name = ast_strdupa(iaxs[callno]->peer);
08892
08893
08894 ast_mutex_unlock(&iaxsl[callno]);
08895 if ((p = find_peer(peer_name, 1))) {
08896 last_authmethod = p->authmethods;
08897 }
08898
08899 ast_mutex_lock(&iaxsl[callno]);
08900 if (!iaxs[callno])
08901 goto return_unref;
08902
08903 memset(&ied, 0, sizeof(ied));
08904
08905
08906
08907
08908
08909
08910 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08911 if (!p) {
08912 iaxs[callno]->authmethods = sentauthmethod;
08913 }
08914 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08915 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08916
08917 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08918 ast_string_field_set(iaxs[callno], challenge, challenge);
08919 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08920 }
08921 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08922
08923 return_unref:
08924 if (p) {
08925 peer_unref(p);
08926 }
08927
08928 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08929 }
08930
08931 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08932 {
08933 struct iax2_registry *reg;
08934
08935 struct iax_ie_data ied;
08936 char peer[256] = "";
08937 char challenge[256] = "";
08938 int res;
08939 int authmethods = 0;
08940 if (ies->authmethods)
08941 authmethods = ies->authmethods;
08942 if (ies->username)
08943 ast_copy_string(peer, ies->username, sizeof(peer));
08944 if (ies->challenge)
08945 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08946 memset(&ied, 0, sizeof(ied));
08947 reg = iaxs[callno]->reg;
08948 if (reg) {
08949 struct sockaddr_in reg_addr;
08950
08951 ast_sockaddr_to_sin(®->addr, ®_addr);
08952
08953 if (inaddrcmp(®_addr, sin)) {
08954 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08955 return -1;
08956 }
08957 if (ast_strlen_zero(reg->secret)) {
08958 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08959 reg->regstate = REG_STATE_NOAUTH;
08960 return -1;
08961 }
08962 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08963 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08964 if (reg->secret[0] == '[') {
08965 char tmpkey[256];
08966 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08967 tmpkey[strlen(tmpkey) - 1] = '\0';
08968 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08969 } else
08970 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08971 if (!res) {
08972 reg->regstate = REG_STATE_AUTHSENT;
08973 add_empty_calltoken_ie(iaxs[callno], &ied);
08974 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08975 } else
08976 return -1;
08977 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08978 } else
08979 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08980 return -1;
08981 }
08982
08983 static void stop_stuff(int callno)
08984 {
08985 iax2_destroy_helper(iaxs[callno]);
08986 }
08987
08988 static void __auth_reject(const void *nothing)
08989 {
08990
08991 int callno = (int)(long)(nothing);
08992 struct iax_ie_data ied;
08993 ast_mutex_lock(&iaxsl[callno]);
08994 if (iaxs[callno]) {
08995 memset(&ied, 0, sizeof(ied));
08996 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08997 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08998 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08999 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
09000 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
09001 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09002 }
09003 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
09004 }
09005 ast_mutex_unlock(&iaxsl[callno]);
09006 }
09007
09008 static int auth_reject(const void *data)
09009 {
09010 int callno = (int)(long)(data);
09011 ast_mutex_lock(&iaxsl[callno]);
09012 if (iaxs[callno])
09013 iaxs[callno]->authid = -1;
09014 ast_mutex_unlock(&iaxsl[callno]);
09015 #ifdef SCHED_MULTITHREADED
09016 if (schedule_action(__auth_reject, data))
09017 #endif
09018 __auth_reject(data);
09019 return 0;
09020 }
09021
09022 static int auth_fail(int callno, int failcode)
09023 {
09024
09025
09026 if (iaxs[callno]) {
09027 iaxs[callno]->authfail = failcode;
09028 if (delayreject) {
09029 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
09030 sched, 1000, auth_reject, (void *)(long)callno);
09031 } else
09032 auth_reject((void *)(long)callno);
09033 }
09034 return 0;
09035 }
09036
09037 static void __auto_hangup(const void *nothing)
09038 {
09039
09040 int callno = (int)(long)(nothing);
09041 struct iax_ie_data ied;
09042 ast_mutex_lock(&iaxsl[callno]);
09043 if (iaxs[callno]) {
09044 memset(&ied, 0, sizeof(ied));
09045 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09046 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09047 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09048 }
09049 ast_mutex_unlock(&iaxsl[callno]);
09050 }
09051
09052 static int auto_hangup(const void *data)
09053 {
09054 int callno = (int)(long)(data);
09055 ast_mutex_lock(&iaxsl[callno]);
09056 if (iaxs[callno]) {
09057 iaxs[callno]->autoid = -1;
09058 }
09059 ast_mutex_unlock(&iaxsl[callno]);
09060 #ifdef SCHED_MULTITHREADED
09061 if (schedule_action(__auto_hangup, data))
09062 #endif
09063 __auto_hangup(data);
09064 return 0;
09065 }
09066
09067 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
09068 {
09069 struct iax_ie_data ied;
09070
09071 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
09072 sched, 30000, auto_hangup, (void *)(long)callno);
09073 memset(&ied, 0, sizeof(ied));
09074 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09075 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09076 dp->flags |= CACHE_FLAG_TRANSMITTED;
09077 }
09078
09079 static int iax2_vnak(int callno)
09080 {
09081 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09082 }
09083
09084 static void vnak_retransmit(int callno, int last)
09085 {
09086 struct iax_frame *f;
09087
09088 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09089
09090 if (((unsigned char) (f->oseqno - last) < 128) &&
09091 (f->retries >= 0)) {
09092 send_packet(f);
09093 }
09094 }
09095 }
09096
09097 static void __iax2_poke_peer_s(const void *data)
09098 {
09099 struct iax2_peer *peer = (struct iax2_peer *)data;
09100 iax2_poke_peer(peer, 0);
09101 peer_unref(peer);
09102 }
09103
09104 static int iax2_poke_peer_s(const void *data)
09105 {
09106 struct iax2_peer *peer = (struct iax2_peer *)data;
09107 peer->pokeexpire = -1;
09108 #ifdef SCHED_MULTITHREADED
09109 if (schedule_action(__iax2_poke_peer_s, data))
09110 #endif
09111 __iax2_poke_peer_s(data);
09112 return 0;
09113 }
09114
09115 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
09116 {
09117 int res = 0;
09118 struct iax_frame *fr;
09119 struct ast_iax2_meta_hdr *meta;
09120 struct ast_iax2_meta_trunk_hdr *mth;
09121 int calls = 0;
09122
09123
09124 fr = (struct iax_frame *)tpeer->trunkdata;
09125
09126 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09127 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09128 if (tpeer->trunkdatalen) {
09129
09130 meta->zeros = 0;
09131 meta->metacmd = IAX_META_TRUNK;
09132 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09133 meta->cmddata = IAX_META_TRUNK_MINI;
09134 else
09135 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09136 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09137
09138 fr->direction = DIRECTION_OUTGRESS;
09139 fr->retrans = -1;
09140 fr->transfer = 0;
09141
09142 fr->data = fr->afdata;
09143 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09144 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09145 calls = tpeer->calls;
09146 #if 0
09147 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));
09148 #endif
09149
09150 tpeer->trunkdatalen = 0;
09151 tpeer->calls = 0;
09152 }
09153 if (res < 0)
09154 return res;
09155 return calls;
09156 }
09157
09158 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
09159 {
09160
09161 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
09162 return 1;
09163 return 0;
09164 }
09165
09166 static int timing_read(int *id, int fd, short events, void *cbdata)
09167 {
09168 int res, processed = 0, totalcalls = 0;
09169 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09170 struct timeval now = ast_tvnow();
09171
09172 if (iaxtrunkdebug)
09173 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09174
09175 if (timer) {
09176 ast_timer_ack(timer, 1);
09177 }
09178
09179
09180 AST_LIST_LOCK(&tpeers);
09181 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09182 processed++;
09183 res = 0;
09184 ast_mutex_lock(&tpeer->lock);
09185
09186
09187 if (!drop && iax2_trunk_expired(tpeer, &now)) {
09188
09189
09190 AST_LIST_REMOVE_CURRENT(list);
09191 drop = tpeer;
09192 } else {
09193 res = send_trunk(tpeer, &now);
09194 trunk_timed++;
09195 if (iaxtrunkdebug)
09196 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);
09197 }
09198 totalcalls += res;
09199 res = 0;
09200 ast_mutex_unlock(&tpeer->lock);
09201 }
09202 AST_LIST_TRAVERSE_SAFE_END;
09203 AST_LIST_UNLOCK(&tpeers);
09204
09205 if (drop) {
09206 ast_mutex_lock(&drop->lock);
09207
09208
09209 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09210 if (drop->trunkdata) {
09211 ast_free(drop->trunkdata);
09212 drop->trunkdata = NULL;
09213 }
09214 ast_mutex_unlock(&drop->lock);
09215 ast_mutex_destroy(&drop->lock);
09216 ast_free(drop);
09217
09218 }
09219
09220 if (iaxtrunkdebug)
09221 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09222 iaxtrunkdebug = 0;
09223
09224 return 1;
09225 }
09226
09227 struct dpreq_data {
09228 int callno;
09229 char context[AST_MAX_EXTENSION];
09230 char callednum[AST_MAX_EXTENSION];
09231 char *callerid;
09232 };
09233
09234 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
09235 {
09236 unsigned short dpstatus = 0;
09237 struct iax_ie_data ied1;
09238 int mm;
09239
09240 memset(&ied1, 0, sizeof(ied1));
09241 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09242
09243 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09244 dpstatus = IAX_DPSTATUS_EXISTS;
09245 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09246 dpstatus = IAX_DPSTATUS_CANEXIST;
09247 } else {
09248 dpstatus = IAX_DPSTATUS_NONEXISTENT;
09249 }
09250 if (ast_ignore_pattern(context, callednum))
09251 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09252 if (mm)
09253 dpstatus |= IAX_DPSTATUS_MATCHMORE;
09254 if (!skiplock)
09255 ast_mutex_lock(&iaxsl[callno]);
09256 if (iaxs[callno]) {
09257 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09258 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09259 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09260 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09261 }
09262 if (!skiplock)
09263 ast_mutex_unlock(&iaxsl[callno]);
09264 }
09265
09266 static void *dp_lookup_thread(void *data)
09267 {
09268
09269 struct dpreq_data *dpr = data;
09270 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09271 if (dpr->callerid)
09272 ast_free(dpr->callerid);
09273 ast_free(dpr);
09274 return NULL;
09275 }
09276
09277 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
09278 {
09279 pthread_t newthread;
09280 struct dpreq_data *dpr;
09281
09282 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09283 return;
09284
09285 dpr->callno = callno;
09286 ast_copy_string(dpr->context, context, sizeof(dpr->context));
09287 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09288 if (callerid)
09289 dpr->callerid = ast_strdup(callerid);
09290 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09291 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09292 }
09293 }
09294
09295 struct iax_dual {
09296 struct ast_channel *chan1;
09297 struct ast_channel *chan2;
09298 char *park_exten;
09299 char *park_context;
09300 };
09301
09302 static void *iax_park_thread(void *stuff)
09303 {
09304 struct iax_dual *d;
09305 int res;
09306 int ext = 0;
09307
09308 d = stuff;
09309
09310 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09311 d->chan2->name, d->chan1->name);
09312
09313 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09314 if (res) {
09315
09316 ast_hangup(d->chan1);
09317 } else {
09318 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09319 }
09320 ast_hangup(d->chan2);
09321
09322 ast_free(d->park_exten);
09323 ast_free(d->park_context);
09324 ast_free(d);
09325 return NULL;
09326 }
09327
09328
09329 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
09330 {
09331 struct iax_dual *d;
09332 struct ast_channel *chan1m, *chan2m;
09333 pthread_t th;
09334
09335 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09336 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09337 d = ast_calloc(1, sizeof(*d));
09338 if (!chan1m || !chan2m || !d) {
09339 if (chan1m) {
09340 ast_hangup(chan1m);
09341 }
09342 if (chan2m) {
09343 ast_hangup(chan2m);
09344 }
09345 ast_free(d);
09346 return -1;
09347 }
09348 d->park_exten = ast_strdup(park_exten);
09349 d->park_context = ast_strdup(park_context);
09350 if (!d->park_exten || !d->park_context) {
09351 ast_hangup(chan1m);
09352 ast_hangup(chan2m);
09353 ast_free(d->park_exten);
09354 ast_free(d->park_context);
09355 ast_free(d);
09356 return -1;
09357 }
09358
09359
09360 chan1m->readformat = chan1->readformat;
09361 chan1m->writeformat = chan1->writeformat;
09362
09363
09364 if (ast_channel_masquerade(chan1m, chan1)) {
09365 ast_hangup(chan1m);
09366 ast_hangup(chan2m);
09367 ast_free(d->park_exten);
09368 ast_free(d->park_context);
09369 ast_free(d);
09370 return -1;
09371 }
09372
09373
09374 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09375 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09376 chan1m->priority = chan1->priority;
09377
09378 ast_do_masquerade(chan1m);
09379
09380
09381
09382
09383
09384 chan2m->readformat = chan2->readformat;
09385 chan2m->writeformat = chan2->writeformat;
09386 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot);
09387
09388
09389 if (ast_channel_masquerade(chan2m, chan2)) {
09390 ast_hangup(chan1m);
09391 ast_hangup(chan2m);
09392 ast_free(d->park_exten);
09393 ast_free(d->park_context);
09394 ast_free(d);
09395 return -1;
09396 }
09397
09398
09399 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09400 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09401 chan2m->priority = chan2->priority;
09402
09403 ast_do_masquerade(chan2m);
09404
09405 d->chan1 = chan1m;
09406 d->chan2 = chan2m;
09407 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09408
09409 ast_hangup(chan1m);
09410 ast_hangup(chan2m);
09411 ast_free(d->park_exten);
09412 ast_free(d->park_context);
09413 ast_free(d);
09414 return -1;
09415 }
09416 return 0;
09417 }
09418
09419 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09420 {
09421 unsigned int ourver;
09422 char rsi[80];
09423 snprintf(rsi, sizeof(rsi), "si-%s", si);
09424 if (iax_provision_version(&ourver, rsi, 1))
09425 return 0;
09426 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09427 if (ourver != ver)
09428 iax2_provision(sin, sockfd, NULL, rsi, 1);
09429 return 0;
09430 }
09431
09432 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09433 {
09434 jb_info stats;
09435 jb_getinfo(pvt->jb, &stats);
09436
09437 memset(iep, 0, sizeof(*iep));
09438
09439 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09440 if(stats.frames_in == 0) stats.frames_in = 1;
09441 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09442 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09443 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09444 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09445 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09446 }
09447
09448 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09449 {
09450 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09451 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09452 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09453 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09454 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09455 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09456 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09457 }
09458
09459 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09460 {
09461 int i;
09462 unsigned int length, offset = 0;
09463 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09464
09465 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09466 length = ies->ospblocklength[i];
09467 if (length != 0) {
09468 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09469
09470 offset = 0;
09471 break;
09472 } else {
09473 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09474 offset += length;
09475 }
09476 } else {
09477 break;
09478 }
09479 }
09480 *(full_osptoken + offset) = '\0';
09481 if (strlen(full_osptoken) != offset) {
09482
09483 *full_osptoken = '\0';
09484 }
09485
09486 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09487 }
09488
09489 static void log_jitterstats(unsigned short callno)
09490 {
09491 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09492 jb_info jbinfo;
09493
09494 ast_mutex_lock(&iaxsl[callno]);
09495 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09496 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09497 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09498 localjitter = jbinfo.jitter;
09499 localdelay = jbinfo.current - jbinfo.min;
09500 locallost = jbinfo.frames_lost;
09501 locallosspct = jbinfo.losspct/1000;
09502 localdropped = jbinfo.frames_dropped;
09503 localooo = jbinfo.frames_ooo;
09504 localpackets = jbinfo.frames_in;
09505 }
09506 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",
09507 iaxs[callno]->owner->name,
09508 iaxs[callno]->pingtime,
09509 localjitter,
09510 localdelay,
09511 locallost,
09512 locallosspct,
09513 localdropped,
09514 localooo,
09515 localpackets,
09516 iaxs[callno]->remote_rr.jitter,
09517 iaxs[callno]->remote_rr.delay,
09518 iaxs[callno]->remote_rr.losscnt,
09519 iaxs[callno]->remote_rr.losspct/1000,
09520 iaxs[callno]->remote_rr.dropped,
09521 iaxs[callno]->remote_rr.ooo,
09522 iaxs[callno]->remote_rr.packets);
09523 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",
09524 iaxs[callno]->owner->name,
09525 iaxs[callno]->pingtime,
09526 localjitter,
09527 localdelay,
09528 locallost,
09529 locallosspct,
09530 localdropped,
09531 localooo,
09532 localpackets,
09533 iaxs[callno]->remote_rr.jitter,
09534 iaxs[callno]->remote_rr.delay,
09535 iaxs[callno]->remote_rr.losscnt,
09536 iaxs[callno]->remote_rr.losspct/1000,
09537 iaxs[callno]->remote_rr.dropped,
09538 iaxs[callno]->remote_rr.ooo,
09539 iaxs[callno]->remote_rr.packets);
09540 }
09541 ast_mutex_unlock(&iaxsl[callno]);
09542 }
09543
09544 static int socket_process(struct iax2_thread *thread);
09545
09546
09547
09548
09549 static void handle_deferred_full_frames(struct iax2_thread *thread)
09550 {
09551 struct iax2_pkt_buf *pkt_buf;
09552
09553 ast_mutex_lock(&thread->lock);
09554
09555 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09556 ast_mutex_unlock(&thread->lock);
09557
09558 thread->buf = pkt_buf->buf;
09559 thread->buf_len = pkt_buf->len;
09560 thread->buf_size = pkt_buf->len + 1;
09561
09562 socket_process(thread);
09563
09564 thread->buf = NULL;
09565 ast_free(pkt_buf);
09566
09567 ast_mutex_lock(&thread->lock);
09568 }
09569
09570 ast_mutex_unlock(&thread->lock);
09571 }
09572
09573
09574
09575
09576
09577
09578
09579 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09580 {
09581 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09582 struct ast_iax2_full_hdr *fh, *cur_fh;
09583
09584 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09585 return;
09586
09587 pkt_buf->len = from_here->buf_len;
09588 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09589
09590 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09591 ast_mutex_lock(&to_here->lock);
09592 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09593 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09594 if (fh->oseqno < cur_fh->oseqno) {
09595 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09596 break;
09597 }
09598 }
09599 AST_LIST_TRAVERSE_SAFE_END
09600
09601 if (!cur_pkt_buf)
09602 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09603
09604 ast_mutex_unlock(&to_here->lock);
09605 }
09606
09607 static int socket_read(int *id, int fd, short events, void *cbdata)
09608 {
09609 struct iax2_thread *thread;
09610 socklen_t len;
09611 time_t t;
09612 static time_t last_errtime = 0;
09613 struct ast_iax2_full_hdr *fh;
09614
09615 if (!(thread = find_idle_thread())) {
09616 time(&t);
09617 if (t != last_errtime)
09618 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09619 last_errtime = t;
09620 usleep(1);
09621 return 1;
09622 }
09623
09624 len = sizeof(thread->iosin);
09625 thread->iofd = fd;
09626 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09627 thread->buf_size = sizeof(thread->readbuf);
09628 thread->buf = thread->readbuf;
09629 if (thread->buf_len < 0) {
09630 if (errno != ECONNREFUSED && errno != EAGAIN)
09631 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09632 handle_error();
09633 thread->iostate = IAX_IOSTATE_IDLE;
09634 signal_condition(&thread->lock, &thread->cond);
09635 return 1;
09636 }
09637 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09638 thread->iostate = IAX_IOSTATE_IDLE;
09639 signal_condition(&thread->lock, &thread->cond);
09640 return 1;
09641 }
09642
09643
09644
09645
09646 fh = (struct ast_iax2_full_hdr *) thread->buf;
09647 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09648 struct iax2_thread *cur = NULL;
09649 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09650
09651 AST_LIST_LOCK(&active_list);
09652 AST_LIST_TRAVERSE(&active_list, cur, list) {
09653 if ((cur->ffinfo.callno == callno) &&
09654 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09655 break;
09656 }
09657 if (cur) {
09658
09659
09660 defer_full_frame(thread, cur);
09661 AST_LIST_UNLOCK(&active_list);
09662 thread->iostate = IAX_IOSTATE_IDLE;
09663 signal_condition(&thread->lock, &thread->cond);
09664 return 1;
09665 } else {
09666
09667 thread->ffinfo.callno = callno;
09668 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09669 thread->ffinfo.type = fh->type;
09670 thread->ffinfo.csub = fh->csub;
09671 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09672 }
09673 AST_LIST_UNLOCK(&active_list);
09674 }
09675
09676
09677 thread->iostate = IAX_IOSTATE_READY;
09678 #ifdef DEBUG_SCHED_MULTITHREAD
09679 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09680 #endif
09681 signal_condition(&thread->lock, &thread->cond);
09682
09683 return 1;
09684 }
09685
09686 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09687 struct iax_frame *fr)
09688 {
09689 unsigned char metatype;
09690 struct ast_iax2_meta_trunk_mini *mtm;
09691 struct ast_iax2_meta_trunk_hdr *mth;
09692 struct ast_iax2_meta_trunk_entry *mte;
09693 struct iax2_trunk_peer *tpeer;
09694 unsigned int ts;
09695 void *ptr;
09696 struct timeval rxtrunktime;
09697 struct ast_frame f = { 0, };
09698
09699 if (packet_len < sizeof(*meta)) {
09700 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09701 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09702 return 1;
09703 }
09704
09705 if (meta->metacmd != IAX_META_TRUNK)
09706 return 1;
09707
09708 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09709 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09710 (int) (sizeof(*meta) + sizeof(*mth)));
09711 return 1;
09712 }
09713 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09714 ts = ntohl(mth->ts);
09715 metatype = meta->cmddata;
09716 packet_len -= (sizeof(*meta) + sizeof(*mth));
09717 ptr = mth->data;
09718 tpeer = find_tpeer(sin, sockfd);
09719 if (!tpeer) {
09720 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09721 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09722 return 1;
09723 }
09724 tpeer->trunkact = ast_tvnow();
09725 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09726 tpeer->rxtrunktime = tpeer->trunkact;
09727 rxtrunktime = tpeer->rxtrunktime;
09728 ast_mutex_unlock(&tpeer->lock);
09729 while (packet_len >= sizeof(*mte)) {
09730
09731 unsigned short callno, trunked_ts, len;
09732
09733 if (metatype == IAX_META_TRUNK_MINI) {
09734 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09735 ptr += sizeof(*mtm);
09736 packet_len -= sizeof(*mtm);
09737 len = ntohs(mtm->len);
09738 callno = ntohs(mtm->mini.callno);
09739 trunked_ts = ntohs(mtm->mini.ts);
09740 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09741 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09742 ptr += sizeof(*mte);
09743 packet_len -= sizeof(*mte);
09744 len = ntohs(mte->len);
09745 callno = ntohs(mte->callno);
09746 trunked_ts = 0;
09747 } else {
09748 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09749 break;
09750 }
09751
09752 if (len > packet_len)
09753 break;
09754 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09755 if (!fr->callno)
09756 continue;
09757
09758
09759
09760
09761 memset(&f, 0, sizeof(f));
09762 f.frametype = AST_FRAME_VOICE;
09763 if (!iaxs[fr->callno]) {
09764
09765 } else if (iaxs[fr->callno]->voiceformat == 0) {
09766 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09767 iax2_vnak(fr->callno);
09768 } else {
09769 f.subclass.codec = iaxs[fr->callno]->voiceformat;
09770 f.datalen = len;
09771 if (f.datalen >= 0) {
09772 if (f.datalen)
09773 f.data.ptr = ptr;
09774 else
09775 f.data.ptr = NULL;
09776 if (trunked_ts)
09777 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09778 else
09779 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09780
09781 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09782 struct iax_frame *duped_fr;
09783
09784
09785 f.src = "IAX2";
09786 f.mallocd = 0;
09787 f.offset = 0;
09788 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09789 f.samples = ast_codec_get_samples(&f);
09790 else
09791 f.samples = 0;
09792 fr->outoforder = 0;
09793 iax_frame_wrap(fr, &f);
09794 duped_fr = iaxfrdup2(fr);
09795 if (duped_fr)
09796 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09797 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09798 iaxs[fr->callno]->last = fr->ts;
09799 }
09800 } else {
09801 ast_log(LOG_WARNING, "Datalen < 0?\n");
09802 }
09803 }
09804 ast_mutex_unlock(&iaxsl[fr->callno]);
09805 ptr += len;
09806 packet_len -= len;
09807 }
09808
09809 return 1;
09810 }
09811
09812 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09813 {
09814 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09815 AST_LIST_HEAD(, ast_var_t) *varlist;
09816 struct ast_var_t *var;
09817
09818 if (!variablestore) {
09819 *buf = '\0';
09820 return 0;
09821 }
09822 varlist = variablestore->data;
09823
09824 AST_LIST_LOCK(varlist);
09825 AST_LIST_TRAVERSE(varlist, var, entries) {
09826 if (strcmp(var->name, data) == 0) {
09827 ast_copy_string(buf, var->value, len);
09828 break;
09829 }
09830 }
09831 AST_LIST_UNLOCK(varlist);
09832 return 0;
09833 }
09834
09835 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09836 {
09837 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09838 AST_LIST_HEAD(, ast_var_t) *varlist;
09839 struct ast_var_t *var;
09840
09841 if (!variablestore) {
09842 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09843 if (!variablestore) {
09844 ast_log(LOG_ERROR, "Memory allocation error\n");
09845 return -1;
09846 }
09847 varlist = ast_calloc(1, sizeof(*varlist));
09848 if (!varlist) {
09849 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09850 return -1;
09851 }
09852
09853 AST_LIST_HEAD_INIT(varlist);
09854 variablestore->data = varlist;
09855 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09856 ast_channel_datastore_add(chan, variablestore);
09857 } else
09858 varlist = variablestore->data;
09859
09860 AST_LIST_LOCK(varlist);
09861 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09862 if (strcmp(var->name, data) == 0) {
09863 AST_LIST_REMOVE_CURRENT(entries);
09864 ast_var_delete(var);
09865 break;
09866 }
09867 }
09868 AST_LIST_TRAVERSE_SAFE_END;
09869 var = ast_var_assign(data, value);
09870 if (var)
09871 AST_LIST_INSERT_TAIL(varlist, var, entries);
09872 else
09873 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09874 AST_LIST_UNLOCK(varlist);
09875 return 0;
09876 }
09877
09878 static struct ast_custom_function iaxvar_function = {
09879 .name = "IAXVAR",
09880 .read = acf_iaxvar_read,
09881 .write = acf_iaxvar_write,
09882 };
09883
09884 static void set_hangup_source_and_cause(int callno, unsigned char causecode)
09885 {
09886 iax2_lock_owner(callno);
09887 if (iaxs[callno] && iaxs[callno]->owner) {
09888 if (causecode) {
09889 iaxs[callno]->owner->hangupcause = causecode;
09890 }
09891 ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
09892 ast_channel_unlock(iaxs[callno]->owner);
09893 }
09894 }
09895
09896 static int socket_process(struct iax2_thread *thread)
09897 {
09898 struct sockaddr_in sin;
09899 int res;
09900 int updatehistory=1;
09901 int new = NEW_PREVENT;
09902 int dcallno = 0;
09903 char decrypted = 0;
09904 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09905 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09906 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09907 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09908 struct iax_frame *fr;
09909 struct iax_frame *cur;
09910 struct ast_frame f = { 0, };
09911 struct ast_channel *c = NULL;
09912 struct iax2_dpcache *dp;
09913 struct iax2_peer *peer;
09914 struct iax_ies ies;
09915 struct iax_ie_data ied0, ied1;
09916 format_t format;
09917 int fd;
09918 int exists;
09919 int minivid = 0;
09920 char empty[32]="";
09921 struct iax_frame *duped_fr;
09922 char host_pref_buf[128];
09923 char caller_pref_buf[128];
09924 struct ast_codec_pref pref;
09925 char *using_prefs = "mine";
09926
09927
09928 fr = alloca(sizeof(*fr) + 4096);
09929 memset(fr, 0, sizeof(*fr));
09930 fr->afdatalen = 4096;
09931
09932
09933 res = thread->buf_len;
09934 fd = thread->iofd;
09935 memcpy(&sin, &thread->iosin, sizeof(sin));
09936
09937 if (res < sizeof(*mh)) {
09938 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09939 return 1;
09940 }
09941 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09942 if (res < sizeof(*vh)) {
09943 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));
09944 return 1;
09945 }
09946
09947
09948 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09949 minivid = 1;
09950 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09951 return socket_process_meta(res, meta, &sin, fd, fr);
09952
09953 #ifdef DEBUG_SUPPORT
09954 if (res >= sizeof(*fh))
09955 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09956 #endif
09957 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09958 if (res < sizeof(*fh)) {
09959 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));
09960 return 1;
09961 }
09962
09963
09964 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09965
09966
09967
09968
09969
09970
09971 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09972 ast_mutex_lock(&iaxsl[fr->callno]);
09973 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
09974 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09975 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09976 ast_mutex_unlock(&iaxsl[fr->callno]);
09977 return 1;
09978 }
09979 decrypted = 1;
09980 }
09981 ast_mutex_unlock(&iaxsl[fr->callno]);
09982 }
09983
09984
09985 f.frametype = fh->type;
09986 if (f.frametype == AST_FRAME_VIDEO) {
09987 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09988 } else if (f.frametype == AST_FRAME_VOICE) {
09989 f.subclass.codec = uncompress_subclass(fh->csub);
09990 } else {
09991 f.subclass.integer = uncompress_subclass(fh->csub);
09992 }
09993
09994
09995 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
09996
09997 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09998 return 1;
09999 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10000
10001 return 1;
10002 }
10003
10004 f.datalen = res - sizeof(*fh);
10005 if (f.datalen) {
10006 if (f.frametype == AST_FRAME_IAX) {
10007 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10008 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
10009 ast_variables_destroy(ies.vars);
10010 return 1;
10011 }
10012 f.data.ptr = NULL;
10013 f.datalen = 0;
10014 } else {
10015 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10016 memset(&ies, 0, sizeof(ies));
10017 }
10018 } else {
10019 if (f.frametype == AST_FRAME_IAX)
10020 f.data.ptr = NULL;
10021 else
10022 f.data.ptr = empty;
10023 memset(&ies, 0, sizeof(ies));
10024 }
10025
10026 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10027
10028 if (handle_call_token(fh, &ies, &sin, fd)) {
10029 ast_variables_destroy(ies.vars);
10030 return 1;
10031 }
10032
10033 if (ies.calltoken && ies.calltokendata) {
10034
10035
10036
10037
10038 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10039 } else {
10040 new = NEW_ALLOW;
10041 }
10042 }
10043 } else {
10044
10045 f.frametype = AST_FRAME_NULL;
10046 f.subclass.integer = 0;
10047 memset(&ies, 0, sizeof(ies));
10048 }
10049
10050 if (!fr->callno) {
10051 int check_dcallno = 0;
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10062 check_dcallno = 1;
10063 }
10064
10065 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10066 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10067 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10068 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10069 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10070 }
10071 ast_variables_destroy(ies.vars);
10072 return 1;
10073 }
10074 }
10075
10076 if (fr->callno > 0)
10077 ast_mutex_lock(&iaxsl[fr->callno]);
10078
10079 if (!fr->callno || !iaxs[fr->callno]) {
10080
10081
10082 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10083
10084 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10085 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10086 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10087 (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10088 (f.frametype != AST_FRAME_IAX))
10089 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10090 fd);
10091 }
10092 if (fr->callno > 0)
10093 ast_mutex_unlock(&iaxsl[fr->callno]);
10094 ast_variables_destroy(ies.vars);
10095 return 1;
10096 }
10097 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10098 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10099 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10100 ast_variables_destroy(ies.vars);
10101 ast_mutex_unlock(&iaxsl[fr->callno]);
10102 return 1;
10103 }
10104 decrypted = 1;
10105 }
10106
10107 #ifdef DEBUG_SUPPORT
10108 if (decrypted) {
10109 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10110 }
10111 #endif
10112
10113
10114
10115 iaxs[fr->callno]->frames_received++;
10116
10117 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10118 f.subclass.integer != IAX_COMMAND_TXCNT &&
10119 f.subclass.integer != IAX_COMMAND_TXACC) {
10120 unsigned short new_peercallno;
10121
10122 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10123 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10124 if (iaxs[fr->callno]->peercallno) {
10125 remove_by_peercallno(iaxs[fr->callno]);
10126 }
10127 iaxs[fr->callno]->peercallno = new_peercallno;
10128 store_by_peercallno(iaxs[fr->callno]);
10129 }
10130 }
10131 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10132 if (iaxdebug)
10133 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10134
10135 fr->oseqno = fh->oseqno;
10136 fr->iseqno = fh->iseqno;
10137 fr->ts = ntohl(fh->ts);
10138 #ifdef IAXTESTS
10139 if (test_resync) {
10140 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10141 fr->ts += test_resync;
10142 }
10143 #endif
10144 #if 0
10145 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10146 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10147 (f.subclass == IAX_COMMAND_NEW ||
10148 f.subclass == IAX_COMMAND_AUTHREQ ||
10149 f.subclass == IAX_COMMAND_ACCEPT ||
10150 f.subclass == IAX_COMMAND_REJECT)) ) )
10151 #endif
10152 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10153 updatehistory = 0;
10154 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10155 (iaxs[fr->callno]->iseqno ||
10156 ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10157 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10158 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10159 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10160 (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10161 (f.frametype != AST_FRAME_IAX))) {
10162 if (
10163 ((f.subclass.integer != IAX_COMMAND_ACK) &&
10164 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10165 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10166 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10167 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10168 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10169 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10170 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10171 (f.frametype != AST_FRAME_IAX)) {
10172
10173 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
10174 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10175
10176
10177 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10178
10179 if ((f.frametype != AST_FRAME_IAX) ||
10180 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10181 ast_debug(1, "Acking anyway\n");
10182
10183
10184 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10185 }
10186 } else {
10187
10188 iax2_vnak(fr->callno);
10189 }
10190 ast_variables_destroy(ies.vars);
10191 ast_mutex_unlock(&iaxsl[fr->callno]);
10192 return 1;
10193 }
10194 } else {
10195
10196 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10197 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10198 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10199 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10200 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10201 (f.frametype != AST_FRAME_IAX))
10202 iaxs[fr->callno]->iseqno++;
10203 }
10204
10205 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10206 if (res < thread->buf_size)
10207 thread->buf[res++] = '\0';
10208 else
10209 thread->buf[res - 1] = '\0';
10210 }
10211
10212
10213
10214 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10215 ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10216 (f.frametype != AST_FRAME_IAX))) {
10217 unsigned char x;
10218 int call_to_destroy;
10219
10220 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10221 x = fr->iseqno;
10222 else
10223 x = iaxs[fr->callno]->oseqno;
10224 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10225
10226
10227 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10228
10229 if (iaxdebug)
10230 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10231 call_to_destroy = 0;
10232 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10233
10234 if (x == cur->oseqno) {
10235 cur->retries = -1;
10236
10237 if (cur->final)
10238 call_to_destroy = fr->callno;
10239 }
10240 }
10241 if (call_to_destroy) {
10242 if (iaxdebug)
10243 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10244 ast_mutex_lock(&iaxsl[call_to_destroy]);
10245 iax2_destroy(call_to_destroy);
10246 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10247 }
10248 }
10249
10250 if (iaxs[fr->callno])
10251 iaxs[fr->callno]->rseqno = fr->iseqno;
10252 else {
10253
10254 ast_variables_destroy(ies.vars);
10255 ast_mutex_unlock(&iaxsl[fr->callno]);
10256 return 1;
10257 }
10258 } else {
10259 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10260 }
10261 }
10262 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10263 ((f.frametype != AST_FRAME_IAX) ||
10264 ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10265 (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10266
10267 ast_variables_destroy(ies.vars);
10268 ast_mutex_unlock(&iaxsl[fr->callno]);
10269 return 1;
10270 }
10271
10272
10273
10274
10275 if ((f.frametype == AST_FRAME_VOICE) ||
10276 (f.frametype == AST_FRAME_VIDEO) ||
10277 (f.frametype == AST_FRAME_IAX)) {
10278 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10279 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10280 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
10281 ast_variables_destroy(ies.vars);
10282 ast_mutex_unlock(&iaxsl[fr->callno]);
10283 return 1;
10284 }
10285 }
10286
10287 if (ies.vars) {
10288 struct ast_datastore *variablestore = NULL;
10289 struct ast_variable *var, *prev = NULL;
10290 AST_LIST_HEAD(, ast_var_t) *varlist;
10291
10292 iax2_lock_owner(fr->callno);
10293 if (!iaxs[fr->callno]) {
10294 ast_variables_destroy(ies.vars);
10295 ast_mutex_unlock(&iaxsl[fr->callno]);
10296 return 1;
10297 }
10298 if ((c = iaxs[fr->callno]->owner)) {
10299 varlist = ast_calloc(1, sizeof(*varlist));
10300 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10301
10302 if (variablestore && varlist) {
10303 variablestore->data = varlist;
10304 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10305 AST_LIST_HEAD_INIT(varlist);
10306 ast_debug(1, "I can haz IAX vars?\n");
10307 for (var = ies.vars; var; var = var->next) {
10308 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10309 if (prev) {
10310 ast_free(prev);
10311 }
10312 prev = var;
10313 if (!newvar) {
10314
10315 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10316 } else {
10317 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10318 }
10319 }
10320 if (prev) {
10321 ast_free(prev);
10322 }
10323 ies.vars = NULL;
10324 ast_channel_datastore_add(c, variablestore);
10325 } else {
10326 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10327 if (variablestore) {
10328 ast_datastore_free(variablestore);
10329 }
10330 if (varlist) {
10331 ast_free(varlist);
10332 }
10333 }
10334 ast_channel_unlock(c);
10335 } else {
10336
10337
10338 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10339 for (var = ies.vars; var && var->next; var = var->next);
10340 if (var) {
10341 var->next = iaxs[fr->callno]->iaxvars;
10342 iaxs[fr->callno]->iaxvars = ies.vars;
10343 ies.vars = NULL;
10344 }
10345 }
10346 }
10347
10348 if (ies.vars) {
10349 ast_debug(1, "I have IAX variables, but they were not processed\n");
10350 }
10351 }
10352
10353
10354
10355 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10356 send_signaling(iaxs[fr->callno]);
10357 }
10358
10359 if (f.frametype == AST_FRAME_VOICE) {
10360 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10361 iaxs[fr->callno]->voiceformat = f.subclass.codec;
10362 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10363 if (iaxs[fr->callno]->owner) {
10364 iax2_lock_owner(fr->callno);
10365 if (iaxs[fr->callno]) {
10366 if (iaxs[fr->callno]->owner) {
10367 format_t orignative;
10368
10369 orignative = iaxs[fr->callno]->owner->nativeformats;
10370 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10371 if (iaxs[fr->callno]->owner->readformat)
10372 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10373 iaxs[fr->callno]->owner->nativeformats = orignative;
10374 ast_channel_unlock(iaxs[fr->callno]->owner);
10375 }
10376 } else {
10377 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10378
10379 if (ies.vars) {
10380 ast_variables_destroy(ies.vars);
10381 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10382 ies.vars = NULL;
10383 }
10384 ast_mutex_unlock(&iaxsl[fr->callno]);
10385 return 1;
10386 }
10387 }
10388 }
10389 }
10390 if (f.frametype == AST_FRAME_VIDEO) {
10391 if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10392 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10393 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10394 }
10395 }
10396 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10397 if (f.subclass.integer == AST_CONTROL_BUSY) {
10398 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10399 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10400 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10401 }
10402 }
10403 if (f.frametype == AST_FRAME_IAX) {
10404 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10405
10406 if (iaxdebug)
10407 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10408
10409
10410 if (iaxs[fr->callno]->last < fr->ts &&
10411 f.subclass.integer != IAX_COMMAND_ACK &&
10412 f.subclass.integer != IAX_COMMAND_PONG &&
10413 f.subclass.integer != IAX_COMMAND_LAGRP) {
10414 iaxs[fr->callno]->last = fr->ts;
10415 if (iaxdebug)
10416 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10417 }
10418 iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10419 if (!iaxs[fr->callno]->first_iax_message) {
10420 iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10421 }
10422 switch(f.subclass.integer) {
10423 case IAX_COMMAND_ACK:
10424
10425 break;
10426 case IAX_COMMAND_QUELCH:
10427 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10428
10429 if (iaxs[fr->callno]->owner) {
10430 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10431 "Status: On\r\n"
10432 "Channel: %s\r\n"
10433 "Uniqueid: %s\r\n",
10434 iaxs[fr->callno]->owner->name,
10435 iaxs[fr->callno]->owner->uniqueid);
10436 }
10437
10438 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10439 if (ies.musiconhold) {
10440 iax2_lock_owner(fr->callno);
10441 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10442 break;
10443 }
10444 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10445 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10446
10447
10448
10449
10450
10451 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10452 S_OR(moh_suggest, NULL),
10453 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10454 }
10455 ast_channel_unlock(iaxs[fr->callno]->owner);
10456 }
10457 }
10458 break;
10459 case IAX_COMMAND_UNQUELCH:
10460 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10461 iax2_lock_owner(fr->callno);
10462 if (!iaxs[fr->callno]) {
10463 break;
10464 }
10465
10466 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10467 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10468 "Status: Off\r\n"
10469 "Channel: %s\r\n"
10470 "Uniqueid: %s\r\n",
10471 iaxs[fr->callno]->owner->name,
10472 iaxs[fr->callno]->owner->uniqueid);
10473 }
10474
10475 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10476 if (!iaxs[fr->callno]->owner) {
10477 break;
10478 }
10479 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10480
10481
10482
10483
10484 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10485 }
10486 ast_channel_unlock(iaxs[fr->callno]->owner);
10487 }
10488 break;
10489 case IAX_COMMAND_TXACC:
10490 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10491
10492 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10493
10494 if (cur->transfer) {
10495 cur->retries = -1;
10496 }
10497 }
10498 memset(&ied1, 0, sizeof(ied1));
10499 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10500 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10501 iaxs[fr->callno]->transferring = TRANSFER_READY;
10502 }
10503 break;
10504 case IAX_COMMAND_NEW:
10505
10506 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10507 break;
10508 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10509 ast_mutex_unlock(&iaxsl[fr->callno]);
10510 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10511 ast_mutex_lock(&iaxsl[fr->callno]);
10512 if (!iaxs[fr->callno]) {
10513 break;
10514 }
10515 }
10516
10517 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10518 int new_callno;
10519 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10520 fr->callno = new_callno;
10521 }
10522
10523 if (delayreject)
10524 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10525 if (check_access(fr->callno, &sin, &ies)) {
10526
10527 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10528 if (authdebug)
10529 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);
10530 break;
10531 }
10532 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10533 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10534 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10535 break;
10536 }
10537 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10538 const char *context, *exten, *cid_num;
10539
10540 context = ast_strdupa(iaxs[fr->callno]->context);
10541 exten = ast_strdupa(iaxs[fr->callno]->exten);
10542 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10543
10544
10545 ast_mutex_unlock(&iaxsl[fr->callno]);
10546 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10547 ast_mutex_lock(&iaxsl[fr->callno]);
10548
10549 if (!iaxs[fr->callno]) {
10550 break;
10551 }
10552 } else
10553 exists = 0;
10554
10555 save_osptoken(fr, &ies);
10556 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10557 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10558 memset(&ied0, 0, sizeof(ied0));
10559 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10560 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10561 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10562 if (!iaxs[fr->callno]) {
10563 break;
10564 }
10565 if (authdebug)
10566 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);
10567 } else {
10568
10569
10570 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10571 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10572 using_prefs = "reqonly";
10573 } else {
10574 using_prefs = "disabled";
10575 }
10576 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10577 memset(&pref, 0, sizeof(pref));
10578 strcpy(caller_pref_buf, "disabled");
10579 strcpy(host_pref_buf, "disabled");
10580 } else {
10581 using_prefs = "mine";
10582
10583 if (ies.codec_prefs)
10584 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10585 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10586
10587 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10588 pref = iaxs[fr->callno]->rprefs;
10589 using_prefs = "caller";
10590 } else {
10591 pref = iaxs[fr->callno]->prefs;
10592 }
10593 } else
10594 pref = iaxs[fr->callno]->prefs;
10595
10596 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10597 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10598 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10599 }
10600 if (!format) {
10601 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10602 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10603 if (!format) {
10604 memset(&ied0, 0, sizeof(ied0));
10605 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10606 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10607 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10608 if (!iaxs[fr->callno]) {
10609 break;
10610 }
10611 if (authdebug) {
10612 char tmp[256], tmp2[256], tmp3[256];
10613 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10614 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10615 ast_inet_ntoa(sin.sin_addr),
10616 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10617 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10618 } else {
10619 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10620 ast_inet_ntoa(sin.sin_addr),
10621 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10622 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10623 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10624 }
10625 }
10626 } else {
10627
10628 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10629 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10630 format = 0;
10631 } else {
10632 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10633 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10634 memset(&pref, 0, sizeof(pref));
10635 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10636 strcpy(caller_pref_buf,"disabled");
10637 strcpy(host_pref_buf,"disabled");
10638 } else {
10639 using_prefs = "mine";
10640 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10641
10642 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10643 pref = iaxs[fr->callno]->prefs;
10644 } else {
10645 pref = iaxs[fr->callno]->rprefs;
10646 using_prefs = "caller";
10647 }
10648 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10649 } else
10650 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10651 }
10652 }
10653
10654 if (!format) {
10655 char tmp[256], tmp2[256], tmp3[256];
10656 memset(&ied0, 0, sizeof(ied0));
10657 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10658 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10659 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10660 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10661 if (!iaxs[fr->callno]) {
10662 break;
10663 }
10664 if (authdebug) {
10665 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10666 ast_inet_ntoa(sin.sin_addr),
10667 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10668 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10669 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10670 }
10671 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10672 break;
10673 }
10674 }
10675 }
10676 if (format) {
10677
10678 memset(&ied1, 0, sizeof(ied1));
10679 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10680 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10681 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10682 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10683 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10684 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10685 "%srequested format = %s,\n"
10686 "%srequested prefs = %s,\n"
10687 "%sactual format = %s,\n"
10688 "%shost prefs = %s,\n"
10689 "%spriority = %s\n",
10690 ast_inet_ntoa(sin.sin_addr),
10691 VERBOSE_PREFIX_4,
10692 ast_getformatname(iaxs[fr->callno]->peerformat),
10693 VERBOSE_PREFIX_4,
10694 caller_pref_buf,
10695 VERBOSE_PREFIX_4,
10696 ast_getformatname(format),
10697 VERBOSE_PREFIX_4,
10698 host_pref_buf,
10699 VERBOSE_PREFIX_4,
10700 using_prefs);
10701
10702 iaxs[fr->callno]->chosenformat = format;
10703 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10704 } else {
10705 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10706
10707 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10708 }
10709 }
10710 }
10711 break;
10712 }
10713 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10714 merge_encryption(iaxs[fr->callno],ies.encmethods);
10715 else
10716 iaxs[fr->callno]->encmethods = 0;
10717 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10718 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10719 break;
10720 case IAX_COMMAND_DPREQ:
10721
10722 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10723 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10724 if (iaxcompat) {
10725
10726 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10727 } else {
10728
10729 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10730 }
10731 }
10732 break;
10733 case IAX_COMMAND_HANGUP:
10734 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10735 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10736
10737 if (iaxs[fr->callno]->owner) {
10738 set_hangup_source_and_cause(fr->callno, ies.causecode);
10739 if (!iaxs[fr->callno]) {
10740 break;
10741 }
10742 }
10743
10744
10745 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10746 iax2_destroy(fr->callno);
10747 break;
10748 case IAX_COMMAND_REJECT:
10749
10750 if (iaxs[fr->callno]->owner) {
10751 set_hangup_source_and_cause(fr->callno, ies.causecode);
10752 if (!iaxs[fr->callno]) {
10753 break;
10754 }
10755 }
10756
10757 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10758 if (iaxs[fr->callno]->owner && authdebug)
10759 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10760 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10761 ies.cause ? ies.cause : "<Unknown>");
10762 ast_debug(1, "Immediately destroying %d, having received reject\n",
10763 fr->callno);
10764 }
10765
10766 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10767 fr->ts, NULL, 0, fr->iseqno);
10768 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10769 iaxs[fr->callno]->error = EPERM;
10770 iax2_destroy(fr->callno);
10771 break;
10772 case IAX_COMMAND_TRANSFER:
10773 {
10774 struct ast_channel *bridged_chan;
10775 struct ast_channel *owner;
10776
10777 iax2_lock_owner(fr->callno);
10778 if (!iaxs[fr->callno]) {
10779
10780 break;
10781 }
10782 owner = iaxs[fr->callno]->owner;
10783 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10784 if (bridged_chan && ies.called_number) {
10785 const char *context;
10786
10787 context = ast_strdupa(iaxs[fr->callno]->context);
10788
10789 ast_channel_ref(owner);
10790 ast_channel_ref(bridged_chan);
10791 ast_channel_unlock(owner);
10792 ast_mutex_unlock(&iaxsl[fr->callno]);
10793
10794
10795 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10796 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10797
10798
10799 if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10800 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10801 if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10802 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10803 bridged_chan->name);
10804 }
10805 } else {
10806 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10807 ast_log(LOG_WARNING,
10808 "Async goto of '%s' to '%s@%s' failed\n",
10809 bridged_chan->name, ies.called_number, context);
10810 } else {
10811 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10812 bridged_chan->name, ies.called_number, context);
10813 }
10814 }
10815 ast_channel_unref(owner);
10816 ast_channel_unref(bridged_chan);
10817
10818 ast_mutex_lock(&iaxsl[fr->callno]);
10819 } else {
10820 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10821 if (owner) {
10822 ast_channel_unlock(owner);
10823 }
10824 }
10825
10826 break;
10827 }
10828 case IAX_COMMAND_ACCEPT:
10829
10830 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10831 break;
10832 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10833
10834 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10835 iax2_destroy(fr->callno);
10836 break;
10837 }
10838 if (ies.format) {
10839 iaxs[fr->callno]->peerformat = ies.format;
10840 } else {
10841 if (iaxs[fr->callno]->owner)
10842 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10843 else
10844 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10845 }
10846 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));
10847 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10848 memset(&ied0, 0, sizeof(ied0));
10849 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10850 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10851 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10852 if (!iaxs[fr->callno]) {
10853 break;
10854 }
10855 if (authdebug) {
10856 char tmp1[256], tmp2[256];
10857 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10858 ast_inet_ntoa(sin.sin_addr),
10859 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10860 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10861 }
10862 } else {
10863 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10864 iax2_lock_owner(fr->callno);
10865 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10866
10867 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10868 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10869
10870
10871 if (iaxs[fr->callno]->owner->writeformat)
10872 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10873 if (iaxs[fr->callno]->owner->readformat)
10874 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10875 ast_channel_unlock(iaxs[fr->callno]->owner);
10876 }
10877 }
10878 if (iaxs[fr->callno]) {
10879 AST_LIST_LOCK(&dpcache);
10880 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10881 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10882 iax2_dprequest(dp, fr->callno);
10883 AST_LIST_UNLOCK(&dpcache);
10884 }
10885 break;
10886 case IAX_COMMAND_POKE:
10887
10888 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10889 break;
10890 case IAX_COMMAND_PING:
10891 {
10892 struct iax_ie_data pingied;
10893 construct_rr(iaxs[fr->callno], &pingied);
10894
10895 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10896 }
10897 break;
10898 case IAX_COMMAND_PONG:
10899
10900 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10901
10902 save_rr(fr, &ies);
10903
10904
10905 log_jitterstats(fr->callno);
10906
10907 if (iaxs[fr->callno]->peerpoke) {
10908 peer = iaxs[fr->callno]->peerpoke;
10909 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10910 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10911 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10912 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);
10913 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10914 }
10915 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10916 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10917 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10918 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);
10919 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10920 }
10921 }
10922 peer->lastms = iaxs[fr->callno]->pingtime;
10923 if (peer->smoothing && (peer->lastms > -1))
10924 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10925 else if (peer->smoothing && peer->lastms < 0)
10926 peer->historicms = (0 + peer->historicms) / 2;
10927 else
10928 peer->historicms = iaxs[fr->callno]->pingtime;
10929
10930
10931 if (peer->pokeexpire > -1) {
10932 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10933 peer_unref(peer);
10934 peer->pokeexpire = -1;
10935 }
10936 }
10937
10938 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10939 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10940 else
10941 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10942 if (peer->pokeexpire == -1)
10943 peer_unref(peer);
10944
10945 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10946
10947 iax2_destroy(fr->callno);
10948 peer->callno = 0;
10949 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10950 }
10951 break;
10952 case IAX_COMMAND_LAGRQ:
10953 case IAX_COMMAND_LAGRP:
10954 f.src = "LAGRQ";
10955 f.mallocd = 0;
10956 f.offset = 0;
10957 f.samples = 0;
10958 iax_frame_wrap(fr, &f);
10959 if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
10960
10961 fr->af.subclass.integer = IAX_COMMAND_LAGRP;
10962 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10963 } else {
10964
10965 unsigned int ts;
10966
10967 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10968 iaxs[fr->callno]->lag = ts - fr->ts;
10969 if (iaxdebug)
10970 ast_debug(1, "Peer %s lag measured as %dms\n",
10971 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10972 }
10973 break;
10974 case IAX_COMMAND_AUTHREQ:
10975 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10976 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>");
10977 break;
10978 }
10979 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10980 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10981 .subclass.integer = AST_CONTROL_HANGUP,
10982 };
10983 ast_log(LOG_WARNING,
10984 "I don't know how to authenticate %s to %s\n",
10985 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10986 iax2_queue_frame(fr->callno, &hangup_fr);
10987 }
10988 break;
10989 case IAX_COMMAND_AUTHREP:
10990
10991 if (delayreject)
10992 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10993
10994 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10995 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>");
10996 break;
10997 }
10998 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10999 if (authdebug)
11000 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);
11001 memset(&ied0, 0, sizeof(ied0));
11002 auth_fail(fr->callno, IAX_COMMAND_REJECT);
11003 break;
11004 }
11005 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11006
11007 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
11008 } else
11009 exists = 0;
11010 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11011 if (authdebug)
11012 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);
11013 memset(&ied0, 0, sizeof(ied0));
11014 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11015 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11016 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11017 if (!iaxs[fr->callno]) {
11018 break;
11019 }
11020 } else {
11021
11022 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11023 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11024 using_prefs = "reqonly";
11025 } else {
11026 using_prefs = "disabled";
11027 }
11028 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11029 memset(&pref, 0, sizeof(pref));
11030 strcpy(caller_pref_buf, "disabled");
11031 strcpy(host_pref_buf, "disabled");
11032 } else {
11033 using_prefs = "mine";
11034 if (ies.codec_prefs)
11035 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11036 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11037 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11038 pref = iaxs[fr->callno]->rprefs;
11039 using_prefs = "caller";
11040 } else {
11041 pref = iaxs[fr->callno]->prefs;
11042 }
11043 } else
11044 pref = iaxs[fr->callno]->prefs;
11045 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11046 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11047 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11048 }
11049 if (!format) {
11050 char tmp1[256], tmp2[256], tmp3[256];
11051 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11052 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11053 ast_getformatname(iaxs[fr->callno]->peerformat),
11054 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11055 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11056 }
11057 if (!format) {
11058 if (authdebug) {
11059 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11060 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11061 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11062 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11063 } else {
11064 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11065 ast_inet_ntoa(sin.sin_addr),
11066 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11067 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11068 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11069 }
11070 }
11071 memset(&ied0, 0, sizeof(ied0));
11072 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11073 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11074 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11075 if (!iaxs[fr->callno]) {
11076 break;
11077 }
11078 } else {
11079
11080 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11081 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11082 format = 0;
11083 } else {
11084 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11085 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11086 memset(&pref, 0, sizeof(pref));
11087 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11088 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11089 strcpy(caller_pref_buf,"disabled");
11090 strcpy(host_pref_buf,"disabled");
11091 } else {
11092 using_prefs = "mine";
11093 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11094
11095 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11096 pref = iaxs[fr->callno]->prefs;
11097 } else {
11098 pref = iaxs[fr->callno]->rprefs;
11099 using_prefs = "caller";
11100 }
11101 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11102 } else
11103 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11104 }
11105 }
11106 if (!format) {
11107 char tmp1[256], tmp2[256], tmp3[256];
11108 ast_log(LOG_ERROR, "No best format in %s???\n",
11109 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11110 if (authdebug) {
11111 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11112 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11113 ast_inet_ntoa(sin.sin_addr),
11114 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11115 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11116 } else {
11117 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11118 ast_inet_ntoa(sin.sin_addr),
11119 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11120 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11121 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11122 }
11123 }
11124 memset(&ied0, 0, sizeof(ied0));
11125 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11126 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11127 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11128 if (!iaxs[fr->callno]) {
11129 break;
11130 }
11131 }
11132 }
11133 }
11134 if (format) {
11135
11136 memset(&ied1, 0, sizeof(ied1));
11137 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11138 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11139 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11140 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11141 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11142 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11143 "%srequested format = %s,\n"
11144 "%srequested prefs = %s,\n"
11145 "%sactual format = %s,\n"
11146 "%shost prefs = %s,\n"
11147 "%spriority = %s\n",
11148 ast_inet_ntoa(sin.sin_addr),
11149 VERBOSE_PREFIX_4,
11150 ast_getformatname(iaxs[fr->callno]->peerformat),
11151 VERBOSE_PREFIX_4,
11152 caller_pref_buf,
11153 VERBOSE_PREFIX_4,
11154 ast_getformatname(format),
11155 VERBOSE_PREFIX_4,
11156 host_pref_buf,
11157 VERBOSE_PREFIX_4,
11158 using_prefs);
11159
11160 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11161 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
11162 iax2_destroy(fr->callno);
11163 else if (ies.vars) {
11164 struct ast_datastore *variablestore;
11165 struct ast_variable *var, *prev = NULL;
11166 AST_LIST_HEAD(, ast_var_t) *varlist;
11167 varlist = ast_calloc(1, sizeof(*varlist));
11168 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11169 if (variablestore && varlist) {
11170 variablestore->data = varlist;
11171 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11172 AST_LIST_HEAD_INIT(varlist);
11173 ast_debug(1, "I can haz IAX vars? w00t\n");
11174 for (var = ies.vars; var; var = var->next) {
11175 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11176 if (prev)
11177 ast_free(prev);
11178 prev = var;
11179 if (!newvar) {
11180
11181 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11182 } else {
11183 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11184 }
11185 }
11186 if (prev)
11187 ast_free(prev);
11188 ies.vars = NULL;
11189 ast_channel_datastore_add(c, variablestore);
11190 } else {
11191 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11192 if (variablestore)
11193 ast_datastore_free(variablestore);
11194 if (varlist)
11195 ast_free(varlist);
11196 }
11197 }
11198 } else {
11199 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11200
11201 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11202 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11203 goto immediatedial;
11204 }
11205 }
11206 }
11207 }
11208 break;
11209 case IAX_COMMAND_DIAL:
11210 immediatedial:
11211 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11212 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11213 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11214 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11215 if (authdebug)
11216 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);
11217 memset(&ied0, 0, sizeof(ied0));
11218 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11219 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11220 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11221 if (!iaxs[fr->callno]) {
11222 break;
11223 }
11224 } else {
11225 char tmp[256];
11226 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11227 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11228 ast_inet_ntoa(sin.sin_addr),
11229 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11230 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11231 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11232 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
11233 iax2_destroy(fr->callno);
11234 else if (ies.vars) {
11235 struct ast_datastore *variablestore;
11236 struct ast_variable *var, *prev = NULL;
11237 AST_LIST_HEAD(, ast_var_t) *varlist;
11238 varlist = ast_calloc(1, sizeof(*varlist));
11239 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11240 ast_debug(1, "I can haz IAX vars? w00t\n");
11241 if (variablestore && varlist) {
11242 variablestore->data = varlist;
11243 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11244 AST_LIST_HEAD_INIT(varlist);
11245 for (var = ies.vars; var; var = var->next) {
11246 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11247 if (prev)
11248 ast_free(prev);
11249 prev = var;
11250 if (!newvar) {
11251
11252 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11253 } else {
11254 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11255 }
11256 }
11257 if (prev)
11258 ast_free(prev);
11259 ies.vars = NULL;
11260 ast_channel_datastore_add(c, variablestore);
11261 } else {
11262 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11263 if (variablestore)
11264 ast_datastore_free(variablestore);
11265 if (varlist)
11266 ast_free(varlist);
11267 }
11268 }
11269 }
11270 }
11271 break;
11272 case IAX_COMMAND_INVAL:
11273 iaxs[fr->callno]->error = ENOTCONN;
11274 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11275 iax2_destroy(fr->callno);
11276 ast_debug(1, "Destroying call %d\n", fr->callno);
11277 break;
11278 case IAX_COMMAND_VNAK:
11279 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11280
11281 vnak_retransmit(fr->callno, fr->iseqno);
11282 break;
11283 case IAX_COMMAND_REGREQ:
11284 case IAX_COMMAND_REGREL:
11285
11286 if (delayreject)
11287 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11288 if (register_verify(fr->callno, &sin, &ies)) {
11289 if (!iaxs[fr->callno]) {
11290 break;
11291 }
11292
11293 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11294 break;
11295 }
11296 if (!iaxs[fr->callno]) {
11297 break;
11298 }
11299 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11300 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11301
11302 if (f.subclass.integer == IAX_COMMAND_REGREL) {
11303 memset(&sin, 0, sizeof(sin));
11304 sin.sin_family = AF_INET;
11305 }
11306 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11307 ast_log(LOG_WARNING, "Registry error\n");
11308 }
11309 if (!iaxs[fr->callno]) {
11310 break;
11311 }
11312 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11313 ast_mutex_unlock(&iaxsl[fr->callno]);
11314 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11315 ast_mutex_lock(&iaxsl[fr->callno]);
11316 }
11317 break;
11318 }
11319 registry_authrequest(fr->callno);
11320 break;
11321 case IAX_COMMAND_REGACK:
11322 if (iax2_ack_registry(&ies, &sin, fr->callno))
11323 ast_log(LOG_WARNING, "Registration failure\n");
11324
11325 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11326 iax2_destroy(fr->callno);
11327 break;
11328 case IAX_COMMAND_REGREJ:
11329 if (iaxs[fr->callno]->reg) {
11330 if (authdebug) {
11331 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));
11332 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>");
11333 }
11334 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11335 }
11336
11337 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11338 iax2_destroy(fr->callno);
11339 break;
11340 case IAX_COMMAND_REGAUTH:
11341
11342 if (registry_rerequest(&ies, fr->callno, &sin)) {
11343 memset(&ied0, 0, sizeof(ied0));
11344 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11345 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11346 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11347 }
11348 break;
11349 case IAX_COMMAND_TXREJ:
11350 iaxs[fr->callno]->transferring = 0;
11351 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11352 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11353 if (iaxs[fr->callno]->bridgecallno) {
11354 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11355 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11356 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11357 }
11358 }
11359 break;
11360 case IAX_COMMAND_TXREADY:
11361 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11362 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11363 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11364 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11365 else
11366 iaxs[fr->callno]->transferring = TRANSFER_READY;
11367 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11368 if (iaxs[fr->callno]->bridgecallno) {
11369 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11370 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11371
11372 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11373 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11374 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11375
11376 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11377 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11378
11379 memset(&ied0, 0, sizeof(ied0));
11380 memset(&ied1, 0, sizeof(ied1));
11381 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11382 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11383 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11384 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11385 } else {
11386 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11387 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11388
11389 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11390 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11391 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11392 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11393
11394
11395 stop_stuff(fr->callno);
11396 stop_stuff(iaxs[fr->callno]->bridgecallno);
11397
11398 memset(&ied0, 0, sizeof(ied0));
11399 memset(&ied1, 0, sizeof(ied1));
11400 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11401 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11402 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11403 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11404 }
11405
11406 }
11407 }
11408 }
11409 break;
11410 case IAX_COMMAND_TXREQ:
11411 try_transfer(iaxs[fr->callno], &ies);
11412 break;
11413 case IAX_COMMAND_TXCNT:
11414 if (iaxs[fr->callno]->transferring)
11415 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11416 break;
11417 case IAX_COMMAND_TXREL:
11418
11419 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11420 complete_transfer(fr->callno, &ies);
11421 stop_stuff(fr->callno);
11422 break;
11423 case IAX_COMMAND_TXMEDIA:
11424 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11425 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11426
11427 if (cur->transfer) {
11428 cur->retries = -1;
11429 }
11430 }
11431
11432 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11433 }
11434 break;
11435 case IAX_COMMAND_RTKEY:
11436 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11437 ast_log(LOG_WARNING,
11438 "we've been told to rotate our encryption key, "
11439 "but this isn't an encrypted call. bad things will happen.\n"
11440 );
11441 break;
11442 }
11443
11444 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11445
11446 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11447 break;
11448 case IAX_COMMAND_DPREP:
11449 complete_dpreply(iaxs[fr->callno], &ies);
11450 break;
11451 case IAX_COMMAND_UNSUPPORT:
11452 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11453 break;
11454 case IAX_COMMAND_FWDOWNL:
11455
11456 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11457 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11458 break;
11459 }
11460 memset(&ied0, 0, sizeof(ied0));
11461 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11462 if (res < 0)
11463 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11464 else if (res > 0)
11465 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11466 else
11467 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11468 break;
11469 case IAX_COMMAND_CALLTOKEN:
11470 {
11471 struct iax_frame *cur;
11472
11473 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11474 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11475 }
11476 break;
11477 }
11478 default:
11479 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11480 memset(&ied0, 0, sizeof(ied0));
11481 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11482 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11483 }
11484
11485 if (ies.vars) {
11486 ast_variables_destroy(ies.vars);
11487 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11488 ies.vars = NULL;
11489 }
11490
11491
11492 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11493 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11494 (f.subclass.integer != IAX_COMMAND_TXACC) &&
11495 (f.subclass.integer != IAX_COMMAND_INVAL) &&
11496 (f.subclass.integer != IAX_COMMAND_VNAK)) {
11497 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11498 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11499 }
11500 ast_mutex_unlock(&iaxsl[fr->callno]);
11501 return 1;
11502 }
11503
11504 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11505 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11506 } else if (minivid) {
11507 f.frametype = AST_FRAME_VIDEO;
11508 if (iaxs[fr->callno]->videoformat > 0)
11509 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11510 else {
11511 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11512 iax2_vnak(fr->callno);
11513 ast_variables_destroy(ies.vars);
11514 ast_mutex_unlock(&iaxsl[fr->callno]);
11515 return 1;
11516 }
11517 f.datalen = res - sizeof(*vh);
11518 if (f.datalen)
11519 f.data.ptr = thread->buf + sizeof(*vh);
11520 else
11521 f.data.ptr = NULL;
11522 #ifdef IAXTESTS
11523 if (test_resync) {
11524 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11525 } else
11526 #endif
11527 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11528 } else {
11529
11530 f.frametype = AST_FRAME_VOICE;
11531 if (iaxs[fr->callno]->voiceformat > 0)
11532 f.subclass.codec = iaxs[fr->callno]->voiceformat;
11533 else {
11534 ast_debug(1, "Received mini frame before first full voice frame\n");
11535 iax2_vnak(fr->callno);
11536 ast_variables_destroy(ies.vars);
11537 ast_mutex_unlock(&iaxsl[fr->callno]);
11538 return 1;
11539 }
11540 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11541 if (f.datalen < 0) {
11542 ast_log(LOG_WARNING, "Datalen < 0?\n");
11543 ast_variables_destroy(ies.vars);
11544 ast_mutex_unlock(&iaxsl[fr->callno]);
11545 return 1;
11546 }
11547 if (f.datalen)
11548 f.data.ptr = thread->buf + sizeof(*mh);
11549 else
11550 f.data.ptr = NULL;
11551 #ifdef IAXTESTS
11552 if (test_resync) {
11553 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11554 } else
11555 #endif
11556 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11557
11558 }
11559
11560 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11561 ast_variables_destroy(ies.vars);
11562 ast_mutex_unlock(&iaxsl[fr->callno]);
11563 return 1;
11564 }
11565
11566 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11567 struct ast_party_connected_line connected;
11568
11569 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11570 ast_variables_destroy(ies.vars);
11571 ast_mutex_unlock(&iaxsl[fr->callno]);
11572 return 1;
11573 }
11574
11575
11576 ast_party_connected_line_init(&connected);
11577 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11578 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11579
11580 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11581 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11582 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11583 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11584
11585 if (iaxs[fr->callno]->owner) {
11586 ast_set_callerid(iaxs[fr->callno]->owner,
11587 S_COR(connected.id.number.valid, connected.id.number.str, ""),
11588 S_COR(connected.id.name.valid, connected.id.name.str, ""),
11589 NULL);
11590 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11591 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11592 }
11593 }
11594 ast_party_connected_line_free(&connected);
11595 }
11596
11597 f.src = "IAX2";
11598 f.mallocd = 0;
11599 f.offset = 0;
11600 f.len = 0;
11601 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11602 f.samples = ast_codec_get_samples(&f);
11603
11604 if (f.subclass.codec == AST_FORMAT_SLINEAR)
11605 ast_frame_byteswap_be(&f);
11606 } else
11607 f.samples = 0;
11608 iax_frame_wrap(fr, &f);
11609
11610
11611 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11612
11613 fr->outoforder = 0;
11614 } else {
11615 if (iaxdebug && iaxs[fr->callno])
11616 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);
11617 fr->outoforder = -1;
11618 }
11619 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11620 duped_fr = iaxfrdup2(fr);
11621 if (duped_fr) {
11622 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11623 }
11624 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11625 iaxs[fr->callno]->last = fr->ts;
11626 #if 1
11627 if (iaxdebug)
11628 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11629 #endif
11630 }
11631
11632
11633 ast_variables_destroy(ies.vars);
11634 ast_mutex_unlock(&iaxsl[fr->callno]);
11635 return 1;
11636 }
11637
11638
11639 static void iax2_process_thread_cleanup(void *data)
11640 {
11641 struct iax2_thread *thread = data;
11642 ast_mutex_destroy(&thread->lock);
11643 ast_cond_destroy(&thread->cond);
11644 ast_mutex_destroy(&thread->init_lock);
11645 ast_cond_destroy(&thread->init_cond);
11646 ast_free(thread);
11647 ast_atomic_dec_and_test(&iaxactivethreadcount);
11648 }
11649
11650 static void *iax2_process_thread(void *data)
11651 {
11652 struct iax2_thread *thread = data;
11653 struct timeval wait;
11654 struct timespec ts;
11655 int put_into_idle = 0;
11656 int first_time = 1;
11657 int old_state;
11658
11659 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11660
11661 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11662 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11663
11664 for (;;) {
11665
11666 ast_mutex_lock(&thread->lock);
11667
11668 if (thread->stop) {
11669 ast_mutex_unlock(&thread->lock);
11670 break;
11671 }
11672
11673
11674 if (first_time) {
11675 signal_condition(&thread->init_lock, &thread->init_cond);
11676 first_time = 0;
11677 }
11678
11679
11680 if (put_into_idle) {
11681 insert_idle_thread(thread);
11682 }
11683
11684 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11685 struct iax2_thread *t = NULL;
11686
11687 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11688 ts.tv_sec = wait.tv_sec;
11689 ts.tv_nsec = wait.tv_usec * 1000;
11690 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11691
11692
11693 if (!put_into_idle || thread->stop) {
11694 ast_mutex_unlock(&thread->lock);
11695 break;
11696 }
11697 AST_LIST_LOCK(&dynamic_list);
11698
11699 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11700 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11701 AST_LIST_UNLOCK(&dynamic_list);
11702 if (t) {
11703
11704
11705
11706 ast_mutex_unlock(&thread->lock);
11707 break;
11708 }
11709
11710
11711
11712 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11713 ts.tv_sec = wait.tv_sec;
11714 ts.tv_nsec = wait.tv_usec * 1000;
11715 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11716 ast_mutex_unlock(&thread->lock);
11717 break;
11718 }
11719 }
11720 } else {
11721 ast_cond_wait(&thread->cond, &thread->lock);
11722 }
11723
11724
11725 put_into_idle = 1;
11726
11727 ast_mutex_unlock(&thread->lock);
11728
11729 if (thread->stop) {
11730 break;
11731 }
11732
11733 if (thread->iostate == IAX_IOSTATE_IDLE)
11734 continue;
11735
11736
11737 switch (thread->iostate) {
11738 case IAX_IOSTATE_READY:
11739 thread->actions++;
11740 thread->iostate = IAX_IOSTATE_PROCESSING;
11741 socket_process(thread);
11742 handle_deferred_full_frames(thread);
11743 break;
11744 case IAX_IOSTATE_SCHEDREADY:
11745 thread->actions++;
11746 thread->iostate = IAX_IOSTATE_PROCESSING;
11747 #ifdef SCHED_MULTITHREADED
11748 thread->schedfunc(thread->scheddata);
11749 #endif
11750 default:
11751 break;
11752 }
11753 time(&thread->checktime);
11754 thread->iostate = IAX_IOSTATE_IDLE;
11755 #ifdef DEBUG_SCHED_MULTITHREAD
11756 thread->curfunc[0]='\0';
11757 #endif
11758
11759
11760
11761
11762 AST_LIST_LOCK(&active_list);
11763 AST_LIST_REMOVE(&active_list, thread, list);
11764 AST_LIST_UNLOCK(&active_list);
11765
11766
11767 handle_deferred_full_frames(thread);
11768 }
11769
11770
11771
11772
11773
11774
11775 AST_LIST_LOCK(&idle_list);
11776 AST_LIST_REMOVE(&idle_list, thread, list);
11777 AST_LIST_UNLOCK(&idle_list);
11778
11779 AST_LIST_LOCK(&dynamic_list);
11780 AST_LIST_REMOVE(&dynamic_list, thread, list);
11781 AST_LIST_UNLOCK(&dynamic_list);
11782
11783 if (!thread->stop) {
11784
11785 pthread_detach(pthread_self());
11786 }
11787
11788
11789
11790
11791 pthread_cleanup_pop(1);
11792 return NULL;
11793 }
11794
11795 static int iax2_do_register(struct iax2_registry *reg)
11796 {
11797 struct iax_ie_data ied;
11798 if (iaxdebug)
11799 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11800
11801 if (reg->dnsmgr &&
11802 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) {
11803
11804 ast_dnsmgr_refresh(reg->dnsmgr);
11805 }
11806
11807
11808
11809
11810
11811 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11812 int callno = reg->callno;
11813 ast_mutex_lock(&iaxsl[callno]);
11814 iax2_destroy(callno);
11815 ast_mutex_unlock(&iaxsl[callno]);
11816 reg->callno = 0;
11817 }
11818 if (!ast_sockaddr_ipv4(®->addr)) {
11819 if (iaxdebug)
11820 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11821
11822 reg->expire = iax2_sched_replace(reg->expire, sched,
11823 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11824 return -1;
11825 }
11826
11827 if (!reg->callno) {
11828 struct sockaddr_in reg_addr;
11829
11830 ast_debug(3, "Allocate call number\n");
11831
11832 ast_sockaddr_to_sin(®->addr, ®_addr);
11833
11834 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0);
11835 if (reg->callno < 1) {
11836 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11837 return -1;
11838 } else
11839 ast_debug(3, "Registration created on call %d\n", reg->callno);
11840 iaxs[reg->callno]->reg = reg;
11841 ast_mutex_unlock(&iaxsl[reg->callno]);
11842 }
11843
11844 reg->expire = iax2_sched_replace(reg->expire, sched,
11845 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11846
11847 memset(&ied, 0, sizeof(ied));
11848 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11849 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11850 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11851 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11852 reg->regstate = REG_STATE_REGSENT;
11853 return 0;
11854 }
11855
11856 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
11857 {
11858
11859
11860 struct iax_ie_data provdata;
11861 struct iax_ie_data ied;
11862 unsigned int sig;
11863 struct sockaddr_in sin;
11864 int callno;
11865 struct create_addr_info cai;
11866
11867 memset(&cai, 0, sizeof(cai));
11868
11869 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11870
11871 if (iax_provision_build(&provdata, &sig, template, force)) {
11872 ast_debug(1, "No provisioning found for template '%s'\n", template);
11873 return 0;
11874 }
11875
11876 if (end) {
11877 memcpy(&sin, end, sizeof(sin));
11878 cai.sockfd = sockfd;
11879 } else if (create_addr(dest, NULL, &sin, &cai))
11880 return -1;
11881
11882
11883 memset(&ied, 0, sizeof(ied));
11884 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11885
11886 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11887 if (!callno)
11888 return -1;
11889
11890 if (iaxs[callno]) {
11891
11892 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11893 sched, 15000, auto_hangup, (void *)(long)callno);
11894 ast_set_flag64(iaxs[callno], IAX_PROVISION);
11895
11896 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11897 }
11898 ast_mutex_unlock(&iaxsl[callno]);
11899
11900 return 1;
11901 }
11902
11903 static char *papp = "IAX2Provision";
11904
11905
11906
11907
11908 static int iax2_prov_app(struct ast_channel *chan, const char *data)
11909 {
11910 int res;
11911 char *sdata;
11912 char *opts;
11913 int force =0;
11914 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11915 if (ast_strlen_zero(data))
11916 data = "default";
11917 sdata = ast_strdupa(data);
11918 opts = strchr(sdata, '|');
11919 if (opts)
11920 *opts='\0';
11921
11922 if (chan->tech != &iax2_tech) {
11923 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11924 return -1;
11925 }
11926 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11927 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11928 return -1;
11929 }
11930 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11931 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11932 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11933 sdata, res);
11934 return res;
11935 }
11936
11937 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11938 {
11939 int force = 0;
11940 int res;
11941
11942 switch (cmd) {
11943 case CLI_INIT:
11944 e->command = "iax2 provision";
11945 e->usage =
11946 "Usage: iax2 provision <host> <template> [forced]\n"
11947 " Provisions the given peer or IP address using a template\n"
11948 " matching either 'template' or '*' if the template is not\n"
11949 " found. If 'forced' is specified, even empty provisioning\n"
11950 " fields will be provisioned as empty fields.\n";
11951 return NULL;
11952 case CLI_GENERATE:
11953 if (a->pos == 3)
11954 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11955 return NULL;
11956 }
11957
11958 if (a->argc < 4)
11959 return CLI_SHOWUSAGE;
11960 if (a->argc > 4) {
11961 if (!strcasecmp(a->argv[4], "forced"))
11962 force = 1;
11963 else
11964 return CLI_SHOWUSAGE;
11965 }
11966 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11967 if (res < 0)
11968 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11969 else if (res < 1)
11970 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11971 else
11972 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11973 return CLI_SUCCESS;
11974 }
11975
11976 static void __iax2_poke_noanswer(const void *data)
11977 {
11978 struct iax2_peer *peer = (struct iax2_peer *)data;
11979 int callno;
11980
11981 if (peer->lastms > -1) {
11982 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11983 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11984 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11985 }
11986 if ((callno = peer->callno) > 0) {
11987 ast_mutex_lock(&iaxsl[callno]);
11988 iax2_destroy(callno);
11989 ast_mutex_unlock(&iaxsl[callno]);
11990 }
11991 peer->callno = 0;
11992 peer->lastms = -1;
11993
11994 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11995 if (peer->pokeexpire == -1)
11996 peer_unref(peer);
11997 }
11998
11999 static int iax2_poke_noanswer(const void *data)
12000 {
12001 struct iax2_peer *peer = (struct iax2_peer *)data;
12002 peer->pokeexpire = -1;
12003 #ifdef SCHED_MULTITHREADED
12004 if (schedule_action(__iax2_poke_noanswer, data))
12005 #endif
12006 __iax2_poke_noanswer(data);
12007 peer_unref(peer);
12008 return 0;
12009 }
12010
12011 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
12012 {
12013 struct iax2_peer *peer = obj;
12014
12015 iax2_poke_peer(peer, 0);
12016
12017 return 0;
12018 }
12019
12020 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
12021 {
12022 int callno;
12023 struct sockaddr_in peer_addr;
12024
12025 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
12026
12027
12028 peer->lastms = 0;
12029 peer->historicms = 0;
12030 peer->pokeexpire = -1;
12031 peer->callno = 0;
12032 return 0;
12033 }
12034
12035 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
12036
12037
12038 if ((callno = peer->callno) > 0) {
12039 ast_log(LOG_NOTICE, "Still have a callno...\n");
12040 ast_mutex_lock(&iaxsl[callno]);
12041 iax2_destroy(callno);
12042 ast_mutex_unlock(&iaxsl[callno]);
12043 }
12044 if (heldcall)
12045 ast_mutex_unlock(&iaxsl[heldcall]);
12046 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12047 if (heldcall)
12048 ast_mutex_lock(&iaxsl[heldcall]);
12049 if (peer->callno < 1) {
12050 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12051 return -1;
12052 }
12053
12054
12055 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12056 iaxs[peer->callno]->peerpoke = peer;
12057
12058 if (peer->pokeexpire > -1) {
12059 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
12060 peer->pokeexpire = -1;
12061 peer_unref(peer);
12062 }
12063 }
12064
12065
12066
12067 if (peer->lastms < 0)
12068 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12069 else
12070 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12071
12072 if (peer->pokeexpire == -1)
12073 peer_unref(peer);
12074
12075
12076 ast_mutex_lock(&iaxsl[callno]);
12077 if (iaxs[callno]) {
12078 struct iax_ie_data ied = {
12079 .buf = { 0 },
12080 .pos = 0,
12081 };
12082 add_empty_calltoken_ie(iaxs[callno], &ied);
12083 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12084 }
12085 ast_mutex_unlock(&iaxsl[callno]);
12086
12087 return 0;
12088 }
12089
12090 static void free_context(struct iax2_context *con)
12091 {
12092 struct iax2_context *conl;
12093 while(con) {
12094 conl = con;
12095 con = con->next;
12096 ast_free(conl);
12097 }
12098 }
12099
12100 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
12101 {
12102 int callno;
12103 int res;
12104 format_t fmt, native;
12105 struct sockaddr_in sin;
12106 struct ast_channel *c;
12107 struct parsed_dial_string pds;
12108 struct create_addr_info cai;
12109 char *tmpstr;
12110
12111 memset(&pds, 0, sizeof(pds));
12112 tmpstr = ast_strdupa(data);
12113 parse_dial_string(tmpstr, &pds);
12114
12115 if (ast_strlen_zero(pds.peer)) {
12116 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12117 return NULL;
12118 }
12119
12120 memset(&cai, 0, sizeof(cai));
12121 cai.capability = iax2_capability;
12122
12123 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12124
12125
12126 if (create_addr(pds.peer, NULL, &sin, &cai)) {
12127 *cause = AST_CAUSE_UNREGISTERED;
12128 return NULL;
12129 }
12130
12131 if (pds.port)
12132 sin.sin_port = htons(atoi(pds.port));
12133
12134 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12135 if (callno < 1) {
12136 ast_log(LOG_WARNING, "Unable to create call\n");
12137 *cause = AST_CAUSE_CONGESTION;
12138 return NULL;
12139 }
12140
12141
12142 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12143 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12144 int new_callno;
12145 if ((new_callno = make_trunk(callno, 1)) != -1)
12146 callno = new_callno;
12147 }
12148 iaxs[callno]->maxtime = cai.maxtime;
12149 if (cai.found)
12150 ast_string_field_set(iaxs[callno], host, pds.peer);
12151
12152 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
12153
12154 ast_mutex_unlock(&iaxsl[callno]);
12155
12156 if (c) {
12157
12158 if (c->nativeformats & format)
12159 c->nativeformats &= format;
12160 else {
12161 native = c->nativeformats;
12162 fmt = format;
12163 res = ast_translator_best_choice(&fmt, &native);
12164 if (res < 0) {
12165 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12166 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12167 ast_hangup(c);
12168 return NULL;
12169 }
12170 c->nativeformats = native;
12171 }
12172 c->readformat = ast_best_codec(c->nativeformats);
12173 c->writeformat = c->readformat;
12174 }
12175
12176 return c;
12177 }
12178
12179 static void *network_thread(void *ignore)
12180 {
12181 if (timer) {
12182 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12183 }
12184
12185 for (;;) {
12186 pthread_testcancel();
12187
12188
12189
12190 ast_io_wait(io, 1000);
12191 }
12192
12193 return NULL;
12194 }
12195
12196 static int start_network_thread(void)
12197 {
12198 struct iax2_thread *thread;
12199 int threadcount = 0;
12200 int x;
12201 for (x = 0; x < iaxthreadcount; x++) {
12202 thread = ast_calloc(1, sizeof(*thread));
12203 if (thread) {
12204 thread->type = IAX_THREAD_TYPE_POOL;
12205 thread->threadnum = ++threadcount;
12206 ast_mutex_init(&thread->lock);
12207 ast_cond_init(&thread->cond, NULL);
12208 ast_mutex_init(&thread->init_lock);
12209 ast_cond_init(&thread->init_cond, NULL);
12210 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12211 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12212 ast_mutex_destroy(&thread->lock);
12213 ast_cond_destroy(&thread->cond);
12214 ast_mutex_destroy(&thread->init_lock);
12215 ast_cond_destroy(&thread->init_cond);
12216 ast_free(thread);
12217 thread = NULL;
12218 continue;
12219 }
12220 AST_LIST_LOCK(&idle_list);
12221 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12222 AST_LIST_UNLOCK(&idle_list);
12223 }
12224 }
12225 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12226 ast_verb(2, "%d helper threads started\n", threadcount);
12227 return 0;
12228 }
12229
12230 static struct iax2_context *build_context(const char *context)
12231 {
12232 struct iax2_context *con;
12233
12234 if ((con = ast_calloc(1, sizeof(*con))))
12235 ast_copy_string(con->context, context, sizeof(con->context));
12236
12237 return con;
12238 }
12239
12240 static int get_auth_methods(const char *value)
12241 {
12242 int methods = 0;
12243 if (strstr(value, "rsa"))
12244 methods |= IAX_AUTH_RSA;
12245 if (strstr(value, "md5"))
12246 methods |= IAX_AUTH_MD5;
12247 if (strstr(value, "plaintext"))
12248 methods |= IAX_AUTH_PLAINTEXT;
12249 return methods;
12250 }
12251
12252
12253
12254
12255
12256 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
12257 {
12258 int sd;
12259 int res;
12260
12261 sd = socket(AF_INET, SOCK_DGRAM, 0);
12262 if (sd < 0) {
12263 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12264 return -1;
12265 }
12266
12267 res = bind(sd, sa, salen);
12268 if (res < 0) {
12269 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12270 close(sd);
12271 return 1;
12272 }
12273
12274 close(sd);
12275 return 0;
12276 }
12277
12278
12279
12280
12281 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12282 {
12283 struct sockaddr_in sin;
12284 struct ast_sockaddr sin_tmp;
12285 int nonlocal = 1;
12286 int port = IAX_DEFAULT_PORTNO;
12287 int sockfd = defaultsockfd;
12288 char *tmp;
12289 char *addr;
12290 char *portstr;
12291
12292 if (!(tmp = ast_strdupa(srcaddr)))
12293 return -1;
12294
12295 addr = strsep(&tmp, ":");
12296 portstr = tmp;
12297
12298 if (portstr) {
12299 port = atoi(portstr);
12300 if (port < 1)
12301 port = IAX_DEFAULT_PORTNO;
12302 }
12303
12304 sin_tmp.ss.ss_family = AF_INET;
12305 if (!ast_get_ip(&sin_tmp, addr)) {
12306 struct ast_netsock *sock;
12307 int res;
12308
12309 ast_sockaddr_to_sin(&sin_tmp, &sin);
12310 sin.sin_port = 0;
12311 sin.sin_family = AF_INET;
12312 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12313 if (res == 0) {
12314
12315 sin.sin_port = htons(port);
12316 if (!(sock = ast_netsock_find(netsock, &sin)))
12317 sock = ast_netsock_find(outsock, &sin);
12318 if (sock) {
12319 sockfd = ast_netsock_sockfd(sock);
12320 nonlocal = 0;
12321 } else {
12322 unsigned int orig_saddr = sin.sin_addr.s_addr;
12323
12324 sin.sin_addr.s_addr = INADDR_ANY;
12325 if (ast_netsock_find(netsock, &sin)) {
12326 sin.sin_addr.s_addr = orig_saddr;
12327 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12328 if (sock) {
12329 sockfd = ast_netsock_sockfd(sock);
12330 ast_netsock_unref(sock);
12331 nonlocal = 0;
12332 } else {
12333 nonlocal = 2;
12334 }
12335 }
12336 }
12337 }
12338 }
12339
12340 peer->sockfd = sockfd;
12341
12342 if (nonlocal == 1) {
12343 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12344 srcaddr, peer->name);
12345 return -1;
12346 } else if (nonlocal == 2) {
12347 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12348 srcaddr, peer->name);
12349 return -1;
12350 } else {
12351 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12352 return 0;
12353 }
12354 }
12355
12356 static void peer_destructor(void *obj)
12357 {
12358 struct iax2_peer *peer = obj;
12359 int callno = peer->callno;
12360
12361 ast_free_ha(peer->ha);
12362
12363 if (callno > 0) {
12364 ast_mutex_lock(&iaxsl[callno]);
12365 iax2_destroy(callno);
12366 ast_mutex_unlock(&iaxsl[callno]);
12367 }
12368
12369 register_peer_exten(peer, 0);
12370
12371 if (peer->dnsmgr)
12372 ast_dnsmgr_release(peer->dnsmgr);
12373
12374 if (peer->mwi_event_sub)
12375 ast_event_unsubscribe(peer->mwi_event_sub);
12376
12377 ast_string_field_free_memory(peer);
12378 }
12379
12380
12381 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12382 {
12383 struct iax2_peer *peer = NULL;
12384 struct ast_ha *oldha = NULL;
12385 int maskfound = 0;
12386 int found = 0;
12387 int firstpass = 1;
12388 struct iax2_peer tmp_peer = {
12389 .name = name,
12390 };
12391
12392 if (!temponly) {
12393 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12394 if (peer && !ast_test_flag64(peer, IAX_DELME))
12395 firstpass = 0;
12396 }
12397
12398 if (peer) {
12399 found++;
12400 if (firstpass) {
12401 oldha = peer->ha;
12402 peer->ha = NULL;
12403 }
12404 unlink_peer(peer);
12405 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12406 peer->expire = -1;
12407 peer->pokeexpire = -1;
12408 peer->sockfd = defaultsockfd;
12409 peer->addr.ss.ss_family = AF_INET;
12410 peer->addr.len = sizeof(struct sockaddr_in);
12411 if (ast_string_field_init(peer, 32))
12412 peer = peer_unref(peer);
12413 }
12414
12415 if (peer) {
12416 if (firstpass) {
12417 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12418 peer->encmethods = iax2_encryption;
12419 peer->adsi = adsi;
12420 ast_string_field_set(peer,secret,"");
12421 if (!found) {
12422 ast_string_field_set(peer, name, name);
12423 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12424 peer->expiry = min_reg_expire;
12425 }
12426 peer->prefs = prefs;
12427 peer->capability = iax2_capability;
12428 peer->smoothing = 0;
12429 peer->pokefreqok = DEFAULT_FREQ_OK;
12430 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12431 peer->maxcallno = 0;
12432 peercnt_modify(0, 0, &peer->addr);
12433 peer->calltoken_required = CALLTOKEN_DEFAULT;
12434 ast_string_field_set(peer,context,"");
12435 ast_string_field_set(peer,peercontext,"");
12436 ast_clear_flag64(peer, IAX_HASCALLERID);
12437 ast_string_field_set(peer, cid_name, "");
12438 ast_string_field_set(peer, cid_num, "");
12439 ast_string_field_set(peer, mohinterpret, mohinterpret);
12440 ast_string_field_set(peer, mohsuggest, mohsuggest);
12441 }
12442
12443 if (!v) {
12444 v = alt;
12445 alt = NULL;
12446 }
12447 while(v) {
12448 if (!strcasecmp(v->name, "secret")) {
12449 ast_string_field_set(peer, secret, v->value);
12450 } else if (!strcasecmp(v->name, "mailbox")) {
12451 ast_string_field_set(peer, mailbox, v->value);
12452 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12453 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12454 ast_string_field_set(peer, mailbox, name);
12455 }
12456 } else if (!strcasecmp(v->name, "mohinterpret")) {
12457 ast_string_field_set(peer, mohinterpret, v->value);
12458 } else if (!strcasecmp(v->name, "mohsuggest")) {
12459 ast_string_field_set(peer, mohsuggest, v->value);
12460 } else if (!strcasecmp(v->name, "dbsecret")) {
12461 ast_string_field_set(peer, dbsecret, v->value);
12462 } else if (!strcasecmp(v->name, "trunk")) {
12463 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12464 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12465 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12466 ast_clear_flag64(peer, IAX_TRUNK);
12467 }
12468 } else if (!strcasecmp(v->name, "auth")) {
12469 peer->authmethods = get_auth_methods(v->value);
12470 } else if (!strcasecmp(v->name, "encryption")) {
12471 peer->encmethods |= get_encrypt_methods(v->value);
12472 if (!peer->encmethods) {
12473 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12474 }
12475 } else if (!strcasecmp(v->name, "forceencryption")) {
12476 if (ast_false(v->value)) {
12477 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12478 } else {
12479 peer->encmethods |= get_encrypt_methods(v->value);
12480 if (peer->encmethods) {
12481 ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12482 }
12483 }
12484 } else if (!strcasecmp(v->name, "transfer")) {
12485 if (!strcasecmp(v->value, "mediaonly")) {
12486 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12487 } else if (ast_true(v->value)) {
12488 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12489 } else
12490 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12491 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12492 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12493 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12494 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12495 } else if (!strcasecmp(v->name, "host")) {
12496 if (!strcasecmp(v->value, "dynamic")) {
12497
12498 ast_set_flag64(peer, IAX_DYNAMIC);
12499 if (!found) {
12500
12501
12502 if (ast_sockaddr_port(&peer->addr)) {
12503 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12504 }
12505 ast_sockaddr_setnull(&peer->addr);
12506 }
12507 } else {
12508
12509 ast_sched_thread_del(sched, peer->expire);
12510 ast_clear_flag64(peer, IAX_DYNAMIC);
12511 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12512 return peer_unref(peer);
12513 if (!ast_sockaddr_port(&peer->addr)) {
12514 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12515 }
12516 }
12517 if (!maskfound)
12518 inet_aton("255.255.255.255", &peer->mask);
12519 } else if (!strcasecmp(v->name, "defaultip")) {
12520 struct ast_sockaddr peer_defaddr_tmp;
12521
12522 peer_defaddr_tmp.ss.ss_family = AF_INET;
12523 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12524 return peer_unref(peer);
12525 }
12526 ast_sockaddr_to_sin(&peer_defaddr_tmp,
12527 &peer->defaddr);
12528 } else if (!strcasecmp(v->name, "sourceaddress")) {
12529 peer_set_srcaddr(peer, v->value);
12530 } else if (!strcasecmp(v->name, "permit") ||
12531 !strcasecmp(v->name, "deny")) {
12532 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12533 } else if (!strcasecmp(v->name, "mask")) {
12534 maskfound++;
12535 inet_aton(v->value, &peer->mask);
12536 } else if (!strcasecmp(v->name, "context")) {
12537 ast_string_field_set(peer, context, v->value);
12538 } else if (!strcasecmp(v->name, "regexten")) {
12539 ast_string_field_set(peer, regexten, v->value);
12540 } else if (!strcasecmp(v->name, "peercontext")) {
12541 ast_string_field_set(peer, peercontext, v->value);
12542 } else if (!strcasecmp(v->name, "port")) {
12543 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12544 peer->defaddr.sin_port = htons(atoi(v->value));
12545 } else {
12546 ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12547 }
12548 } else if (!strcasecmp(v->name, "username")) {
12549 ast_string_field_set(peer, username, v->value);
12550 } else if (!strcasecmp(v->name, "allow")) {
12551 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12552 } else if (!strcasecmp(v->name, "disallow")) {
12553 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12554 } else if (!strcasecmp(v->name, "callerid")) {
12555 if (!ast_strlen_zero(v->value)) {
12556 char name2[80];
12557 char num2[80];
12558 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12559 ast_string_field_set(peer, cid_name, name2);
12560 ast_string_field_set(peer, cid_num, num2);
12561 } else {
12562 ast_string_field_set(peer, cid_name, "");
12563 ast_string_field_set(peer, cid_num, "");
12564 }
12565 ast_set_flag64(peer, IAX_HASCALLERID);
12566 } else if (!strcasecmp(v->name, "fullname")) {
12567 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12568 ast_set_flag64(peer, IAX_HASCALLERID);
12569 } else if (!strcasecmp(v->name, "cid_number")) {
12570 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12571 ast_set_flag64(peer, IAX_HASCALLERID);
12572 } else if (!strcasecmp(v->name, "sendani")) {
12573 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12574 } else if (!strcasecmp(v->name, "inkeys")) {
12575 ast_string_field_set(peer, inkeys, v->value);
12576 } else if (!strcasecmp(v->name, "outkey")) {
12577 ast_string_field_set(peer, outkey, v->value);
12578 } else if (!strcasecmp(v->name, "qualify")) {
12579 if (!strcasecmp(v->value, "no")) {
12580 peer->maxms = 0;
12581 } else if (!strcasecmp(v->value, "yes")) {
12582 peer->maxms = DEFAULT_MAXMS;
12583 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12584 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);
12585 peer->maxms = 0;
12586 }
12587 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12588 peer->smoothing = ast_true(v->value);
12589 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12590 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12591 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);
12592 }
12593 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12594 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12595 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);
12596 }
12597 } else if (!strcasecmp(v->name, "timezone")) {
12598 ast_string_field_set(peer, zonetag, v->value);
12599 } else if (!strcasecmp(v->name, "adsi")) {
12600 peer->adsi = ast_true(v->value);
12601 } else if (!strcasecmp(v->name, "connectedline")) {
12602 if (ast_true(v->value)) {
12603 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12604 } else if (!strcasecmp(v->value, "send")) {
12605 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12606 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12607 } else if (!strcasecmp(v->value, "receive")) {
12608 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12609 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12610 } else {
12611 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12612 }
12613 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12614 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12615 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12616 } else {
12617 peercnt_modify(1, peer->maxcallno, &peer->addr);
12618 }
12619 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12620
12621 if (ast_false(v->value)) {
12622 peer->calltoken_required = CALLTOKEN_NO;
12623 } else if (!strcasecmp(v->value, "auto")) {
12624 peer->calltoken_required = CALLTOKEN_AUTO;
12625 } else if (ast_true(v->value)) {
12626 peer->calltoken_required = CALLTOKEN_YES;
12627 } else {
12628 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12629 }
12630 }
12631
12632 v = v->next;
12633 if (!v) {
12634 v = alt;
12635 alt = NULL;
12636 }
12637 }
12638 if (!peer->authmethods)
12639 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12640 ast_clear_flag64(peer, IAX_DELME);
12641 }
12642
12643 if (oldha)
12644 ast_free_ha(oldha);
12645
12646 if (!ast_strlen_zero(peer->mailbox)) {
12647 char *mailbox, *context;
12648 context = mailbox = ast_strdupa(peer->mailbox);
12649 strsep(&context, "@");
12650 if (ast_strlen_zero(context))
12651 context = "default";
12652 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12653 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12654 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12655 AST_EVENT_IE_END);
12656 }
12657
12658 return peer;
12659 }
12660
12661 static void user_destructor(void *obj)
12662 {
12663 struct iax2_user *user = obj;
12664
12665 ast_free_ha(user->ha);
12666 free_context(user->contexts);
12667 if(user->vars) {
12668 ast_variables_destroy(user->vars);
12669 user->vars = NULL;
12670 }
12671 ast_string_field_free_memory(user);
12672 }
12673
12674
12675 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12676 {
12677 struct iax2_user *user = NULL;
12678 struct iax2_context *con, *conl = NULL;
12679 struct ast_ha *oldha = NULL;
12680 struct iax2_context *oldcon = NULL;
12681 int format;
12682 int firstpass=1;
12683 int oldcurauthreq = 0;
12684 char *varname = NULL, *varval = NULL;
12685 struct ast_variable *tmpvar = NULL;
12686 struct iax2_user tmp_user = {
12687 .name = name,
12688 };
12689
12690 if (!temponly) {
12691 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12692 if (user && !ast_test_flag64(user, IAX_DELME))
12693 firstpass = 0;
12694 }
12695
12696 if (user) {
12697 if (firstpass) {
12698 oldcurauthreq = user->curauthreq;
12699 oldha = user->ha;
12700 oldcon = user->contexts;
12701 user->ha = NULL;
12702 user->contexts = NULL;
12703 }
12704
12705 ao2_unlink(users, user);
12706 } else {
12707 user = ao2_alloc(sizeof(*user), user_destructor);
12708 }
12709
12710 if (user) {
12711 if (firstpass) {
12712 ast_string_field_free_memory(user);
12713 memset(user, 0, sizeof(struct iax2_user));
12714 if (ast_string_field_init(user, 32)) {
12715 user = user_unref(user);
12716 goto cleanup;
12717 }
12718 user->maxauthreq = maxauthreq;
12719 user->curauthreq = oldcurauthreq;
12720 user->prefs = prefs;
12721 user->capability = iax2_capability;
12722 user->encmethods = iax2_encryption;
12723 user->adsi = adsi;
12724 user->calltoken_required = CALLTOKEN_DEFAULT;
12725 ast_string_field_set(user, name, name);
12726 ast_string_field_set(user, language, language);
12727 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);
12728 ast_clear_flag64(user, IAX_HASCALLERID);
12729 ast_string_field_set(user, cid_name, "");
12730 ast_string_field_set(user, cid_num, "");
12731 ast_string_field_set(user, accountcode, accountcode);
12732 ast_string_field_set(user, mohinterpret, mohinterpret);
12733 ast_string_field_set(user, mohsuggest, mohsuggest);
12734 }
12735 if (!v) {
12736 v = alt;
12737 alt = NULL;
12738 }
12739 while(v) {
12740 if (!strcasecmp(v->name, "context")) {
12741 con = build_context(v->value);
12742 if (con) {
12743 if (conl)
12744 conl->next = con;
12745 else
12746 user->contexts = con;
12747 conl = con;
12748 }
12749 } else if (!strcasecmp(v->name, "permit") ||
12750 !strcasecmp(v->name, "deny")) {
12751 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12752 } else if (!strcasecmp(v->name, "setvar")) {
12753 varname = ast_strdupa(v->value);
12754 if (varname && (varval = strchr(varname,'='))) {
12755 *varval = '\0';
12756 varval++;
12757 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12758 tmpvar->next = user->vars;
12759 user->vars = tmpvar;
12760 }
12761 }
12762 } else if (!strcasecmp(v->name, "allow")) {
12763 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12764 } else if (!strcasecmp(v->name, "disallow")) {
12765 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12766 } else if (!strcasecmp(v->name, "trunk")) {
12767 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
12768 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12769 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12770 ast_clear_flag64(user, IAX_TRUNK);
12771 }
12772 } else if (!strcasecmp(v->name, "auth")) {
12773 user->authmethods = get_auth_methods(v->value);
12774 } else if (!strcasecmp(v->name, "encryption")) {
12775 user->encmethods |= get_encrypt_methods(v->value);
12776 if (!user->encmethods) {
12777 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12778 }
12779 } else if (!strcasecmp(v->name, "forceencryption")) {
12780 if (ast_false(v->value)) {
12781 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12782 } else {
12783 user->encmethods |= get_encrypt_methods(v->value);
12784 if (user->encmethods) {
12785 ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12786 }
12787 }
12788 } else if (!strcasecmp(v->name, "transfer")) {
12789 if (!strcasecmp(v->value, "mediaonly")) {
12790 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12791 } else if (ast_true(v->value)) {
12792 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12793 } else
12794 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12795 } else if (!strcasecmp(v->name, "codecpriority")) {
12796 if(!strcasecmp(v->value, "caller"))
12797 ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12798 else if(!strcasecmp(v->value, "disabled"))
12799 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12800 else if(!strcasecmp(v->value, "reqonly")) {
12801 ast_set_flag64(user, IAX_CODEC_NOCAP);
12802 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12803 }
12804 } else if (!strcasecmp(v->name, "immediate")) {
12805 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12806 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12807 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12808 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12809 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12810 } else if (!strcasecmp(v->name, "dbsecret")) {
12811 ast_string_field_set(user, dbsecret, v->value);
12812 } else if (!strcasecmp(v->name, "secret")) {
12813 if (!ast_strlen_zero(user->secret)) {
12814 char *old = ast_strdupa(user->secret);
12815
12816 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12817 } else
12818 ast_string_field_set(user, secret, v->value);
12819 } else if (!strcasecmp(v->name, "callerid")) {
12820 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12821 char name2[80];
12822 char num2[80];
12823 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12824 ast_string_field_set(user, cid_name, name2);
12825 ast_string_field_set(user, cid_num, num2);
12826 ast_set_flag64(user, IAX_HASCALLERID);
12827 } else {
12828 ast_clear_flag64(user, IAX_HASCALLERID);
12829 ast_string_field_set(user, cid_name, "");
12830 ast_string_field_set(user, cid_num, "");
12831 }
12832 } else if (!strcasecmp(v->name, "fullname")) {
12833 if (!ast_strlen_zero(v->value)) {
12834 ast_string_field_set(user, cid_name, v->value);
12835 ast_set_flag64(user, IAX_HASCALLERID);
12836 } else {
12837 ast_string_field_set(user, cid_name, "");
12838 if (ast_strlen_zero(user->cid_num))
12839 ast_clear_flag64(user, IAX_HASCALLERID);
12840 }
12841 } else if (!strcasecmp(v->name, "cid_number")) {
12842 if (!ast_strlen_zero(v->value)) {
12843 ast_string_field_set(user, cid_num, v->value);
12844 ast_set_flag64(user, IAX_HASCALLERID);
12845 } else {
12846 ast_string_field_set(user, cid_num, "");
12847 if (ast_strlen_zero(user->cid_name))
12848 ast_clear_flag64(user, IAX_HASCALLERID);
12849 }
12850 } else if (!strcasecmp(v->name, "accountcode")) {
12851 ast_string_field_set(user, accountcode, v->value);
12852 } else if (!strcasecmp(v->name, "mohinterpret")) {
12853 ast_string_field_set(user, mohinterpret, v->value);
12854 } else if (!strcasecmp(v->name, "mohsuggest")) {
12855 ast_string_field_set(user, mohsuggest, v->value);
12856 } else if (!strcasecmp(v->name, "parkinglot")) {
12857 ast_string_field_set(user, parkinglot, v->value);
12858 } else if (!strcasecmp(v->name, "language")) {
12859 ast_string_field_set(user, language, v->value);
12860 } else if (!strcasecmp(v->name, "amaflags")) {
12861 format = ast_cdr_amaflags2int(v->value);
12862 if (format < 0) {
12863 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12864 } else {
12865 user->amaflags = format;
12866 }
12867 } else if (!strcasecmp(v->name, "inkeys")) {
12868 ast_string_field_set(user, inkeys, v->value);
12869 } else if (!strcasecmp(v->name, "maxauthreq")) {
12870 user->maxauthreq = atoi(v->value);
12871 if (user->maxauthreq < 0)
12872 user->maxauthreq = 0;
12873 } else if (!strcasecmp(v->name, "adsi")) {
12874 user->adsi = ast_true(v->value);
12875 } else if (!strcasecmp(v->name, "connectedline")) {
12876 if (ast_true(v->value)) {
12877 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12878 } else if (!strcasecmp(v->value, "send")) {
12879 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12880 ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12881 } else if (!strcasecmp(v->value, "receive")) {
12882 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12883 ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12884 } else {
12885 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12886 }
12887 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12888
12889 if (ast_false(v->value)) {
12890 user->calltoken_required = CALLTOKEN_NO;
12891 } else if (!strcasecmp(v->value, "auto")) {
12892 user->calltoken_required = CALLTOKEN_AUTO;
12893 } else if (ast_true(v->value)) {
12894 user->calltoken_required = CALLTOKEN_YES;
12895 } else {
12896 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12897 }
12898 }
12899
12900 v = v->next;
12901 if (!v) {
12902 v = alt;
12903 alt = NULL;
12904 }
12905 }
12906 if (!user->authmethods) {
12907 if (!ast_strlen_zero(user->secret)) {
12908 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12909 if (!ast_strlen_zero(user->inkeys))
12910 user->authmethods |= IAX_AUTH_RSA;
12911 } else if (!ast_strlen_zero(user->inkeys)) {
12912 user->authmethods = IAX_AUTH_RSA;
12913 } else {
12914 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12915 }
12916 }
12917 ast_clear_flag64(user, IAX_DELME);
12918 }
12919 cleanup:
12920 if (oldha)
12921 ast_free_ha(oldha);
12922 if (oldcon)
12923 free_context(oldcon);
12924 return user;
12925 }
12926
12927 static int peer_delme_cb(void *obj, void *arg, int flags)
12928 {
12929 struct iax2_peer *peer = obj;
12930
12931 ast_set_flag64(peer, IAX_DELME);
12932
12933 return 0;
12934 }
12935
12936 static int user_delme_cb(void *obj, void *arg, int flags)
12937 {
12938 struct iax2_user *user = obj;
12939
12940 ast_set_flag64(user, IAX_DELME);
12941
12942 return 0;
12943 }
12944
12945 static void delete_users(void)
12946 {
12947 struct iax2_registry *reg;
12948
12949 ao2_callback(users, 0, user_delme_cb, NULL);
12950
12951 AST_LIST_LOCK(®istrations);
12952 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12953 if (sched) {
12954 ast_sched_thread_del(sched, reg->expire);
12955 }
12956 if (reg->callno) {
12957 int callno = reg->callno;
12958 ast_mutex_lock(&iaxsl[callno]);
12959 if (iaxs[callno]) {
12960 iaxs[callno]->reg = NULL;
12961 iax2_destroy(callno);
12962 }
12963 ast_mutex_unlock(&iaxsl[callno]);
12964 }
12965 if (reg->dnsmgr)
12966 ast_dnsmgr_release(reg->dnsmgr);
12967 ast_free(reg);
12968 }
12969 AST_LIST_UNLOCK(®istrations);
12970
12971 ao2_callback(peers, 0, peer_delme_cb, NULL);
12972 }
12973
12974 static void prune_users(void)
12975 {
12976 struct iax2_user *user;
12977 struct ao2_iterator i;
12978
12979 i = ao2_iterator_init(users, 0);
12980 while ((user = ao2_iterator_next(&i))) {
12981 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
12982 ao2_unlink(users, user);
12983 }
12984 user_unref(user);
12985 }
12986 ao2_iterator_destroy(&i);
12987 }
12988
12989
12990 static void prune_peers(void)
12991 {
12992 struct iax2_peer *peer;
12993 struct ao2_iterator i;
12994
12995 i = ao2_iterator_init(peers, 0);
12996 while ((peer = ao2_iterator_next(&i))) {
12997 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
12998 unlink_peer(peer);
12999 }
13000 peer_unref(peer);
13001 }
13002 ao2_iterator_destroy(&i);
13003 }
13004
13005 static void set_config_destroy(void)
13006 {
13007 strcpy(accountcode, "");
13008 strcpy(language, "");
13009 strcpy(mohinterpret, "");
13010 strcpy(mohsuggest, "");
13011 trunkmaxsize = MAX_TRUNKDATA;
13012 amaflags = 0;
13013 delayreject = 0;
13014 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF |
13015 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13016 delete_users();
13017 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
13018 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
13019 }
13020
13021
13022 static int set_config(const char *config_file, int reload)
13023 {
13024 struct ast_config *cfg, *ucfg;
13025 format_t capability = iax2_capability;
13026 struct ast_variable *v;
13027 char *cat;
13028 const char *utype;
13029 const char *tosval;
13030 int format;
13031 int portno = IAX_DEFAULT_PORTNO;
13032 int x;
13033 int mtuv;
13034 int subscribe_network_change = 1;
13035 struct iax2_user *user;
13036 struct iax2_peer *peer;
13037 struct ast_netsock *ns;
13038 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13039 #if 0
13040 static unsigned short int last_port=0;
13041 #endif
13042
13043 cfg = ast_config_load(config_file, config_flags);
13044
13045 if (!cfg) {
13046 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13047 return -1;
13048 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13049 ucfg = ast_config_load("users.conf", config_flags);
13050 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13051 return 0;
13052
13053 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13054 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13055 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13056 ast_config_destroy(ucfg);
13057 return 0;
13058 }
13059 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13060 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13061 return 0;
13062 } else {
13063 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13064 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13065 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
13066 ast_config_destroy(cfg);
13067 return 0;
13068 }
13069 }
13070
13071 if (reload) {
13072 set_config_destroy();
13073 }
13074
13075
13076 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13077
13078
13079 memset(&globalflags, 0, sizeof(globalflags));
13080 ast_set_flag64(&globalflags, IAX_RTUPDATE);
13081 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13082
13083 #ifdef SO_NO_CHECK
13084 nochecksums = 0;
13085 #endif
13086
13087 default_parkinglot[0] = '\0';
13088
13089 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13090 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13091 global_max_trunk_mtu = MAX_TRUNK_MTU;
13092 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13093 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13094
13095 maxauthreq = 3;
13096
13097 srvlookup = 0;
13098
13099 v = ast_variable_browse(cfg, "general");
13100
13101
13102 tosval = ast_variable_retrieve(cfg, "general", "tos");
13103 if (tosval) {
13104 if (ast_str2tos(tosval, &qos.tos))
13105 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13106 }
13107
13108 tosval = ast_variable_retrieve(cfg, "general", "cos");
13109 if (tosval) {
13110 if (ast_str2cos(tosval, &qos.cos))
13111 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13112 }
13113 while(v) {
13114 if (!strcasecmp(v->name, "bindport")){
13115 if (reload)
13116 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13117 else
13118 portno = atoi(v->value);
13119 } else if (!strcasecmp(v->name, "pingtime"))
13120 ping_time = atoi(v->value);
13121 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13122 if (reload) {
13123 if (atoi(v->value) != iaxthreadcount)
13124 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13125 } else {
13126 iaxthreadcount = atoi(v->value);
13127 if (iaxthreadcount < 1) {
13128 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13129 iaxthreadcount = 1;
13130 } else if (iaxthreadcount > 256) {
13131 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13132 iaxthreadcount = 256;
13133 }
13134 }
13135 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13136 if (reload) {
13137 AST_LIST_LOCK(&dynamic_list);
13138 iaxmaxthreadcount = atoi(v->value);
13139 AST_LIST_UNLOCK(&dynamic_list);
13140 } else {
13141 iaxmaxthreadcount = atoi(v->value);
13142 if (iaxmaxthreadcount < 0) {
13143 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13144 iaxmaxthreadcount = 0;
13145 } else if (iaxmaxthreadcount > 256) {
13146 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13147 iaxmaxthreadcount = 256;
13148 }
13149 }
13150 } else if (!strcasecmp(v->name, "nochecksums")) {
13151 #ifdef SO_NO_CHECK
13152 if (ast_true(v->value))
13153 nochecksums = 1;
13154 else
13155 nochecksums = 0;
13156 #else
13157 if (ast_true(v->value))
13158 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13159 #endif
13160 }
13161 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13162 maxjitterbuffer = atoi(v->value);
13163 else if (!strcasecmp(v->name, "resyncthreshold"))
13164 resyncthreshold = atoi(v->value);
13165 else if (!strcasecmp(v->name, "maxjitterinterps"))
13166 maxjitterinterps = atoi(v->value);
13167 else if (!strcasecmp(v->name, "jittertargetextra"))
13168 jittertargetextra = atoi(v->value);
13169 else if (!strcasecmp(v->name, "lagrqtime"))
13170 lagrq_time = atoi(v->value);
13171 else if (!strcasecmp(v->name, "maxregexpire"))
13172 max_reg_expire = atoi(v->value);
13173 else if (!strcasecmp(v->name, "minregexpire"))
13174 min_reg_expire = atoi(v->value);
13175 else if (!strcasecmp(v->name, "bindaddr")) {
13176 if (reload) {
13177 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13178 } else {
13179 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13180 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13181 } else {
13182 if (strchr(v->value, ':'))
13183 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13184 else
13185 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13186 if (defaultsockfd < 0)
13187 defaultsockfd = ast_netsock_sockfd(ns);
13188 ast_netsock_unref(ns);
13189 }
13190 }
13191 } else if (!strcasecmp(v->name, "authdebug")) {
13192 authdebug = ast_true(v->value);
13193 } else if (!strcasecmp(v->name, "encryption")) {
13194 iax2_encryption |= get_encrypt_methods(v->value);
13195 if (!iax2_encryption) {
13196 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13197 }
13198 } else if (!strcasecmp(v->name, "forceencryption")) {
13199 if (ast_false(v->value)) {
13200 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13201 } else {
13202 iax2_encryption |= get_encrypt_methods(v->value);
13203 if (iax2_encryption) {
13204 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13205 }
13206 }
13207 } else if (!strcasecmp(v->name, "transfer")) {
13208 if (!strcasecmp(v->value, "mediaonly")) {
13209 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13210 } else if (ast_true(v->value)) {
13211 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13212 } else
13213 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13214 } else if (!strcasecmp(v->name, "codecpriority")) {
13215 if(!strcasecmp(v->value, "caller"))
13216 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13217 else if(!strcasecmp(v->value, "disabled"))
13218 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13219 else if(!strcasecmp(v->value, "reqonly")) {
13220 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13221 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13222 }
13223 } else if (!strcasecmp(v->name, "jitterbuffer"))
13224 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13225 else if (!strcasecmp(v->name, "forcejitterbuffer"))
13226 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13227 else if (!strcasecmp(v->name, "delayreject"))
13228 delayreject = ast_true(v->value);
13229 else if (!strcasecmp(v->name, "allowfwdownload"))
13230 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13231 else if (!strcasecmp(v->name, "rtcachefriends"))
13232 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13233 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13234 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13235 else if (!strcasecmp(v->name, "rtupdate"))
13236 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13237 else if (!strcasecmp(v->name, "rtsavesysname"))
13238 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13239 else if (!strcasecmp(v->name, "trunktimestamps"))
13240 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13241 else if (!strcasecmp(v->name, "rtautoclear")) {
13242 int i = atoi(v->value);
13243 if(i > 0)
13244 global_rtautoclear = i;
13245 else
13246 i = 0;
13247 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13248 } else if (!strcasecmp(v->name, "trunkfreq")) {
13249 trunkfreq = atoi(v->value);
13250 if (trunkfreq < 10) {
13251 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13252 trunkfreq = 10;
13253 } else if (trunkfreq > 1000) {
13254 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13255 trunkfreq = 1000;
13256 }
13257 } else if (!strcasecmp(v->name, "trunkmtu")) {
13258 mtuv = atoi(v->value);
13259 if (mtuv == 0 )
13260 global_max_trunk_mtu = 0;
13261 else if (mtuv >= 172 && mtuv < 4000)
13262 global_max_trunk_mtu = mtuv;
13263 else
13264 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13265 mtuv, v->lineno);
13266 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13267 trunkmaxsize = atoi(v->value);
13268 if (trunkmaxsize == 0)
13269 trunkmaxsize = MAX_TRUNKDATA;
13270 } else if (!strcasecmp(v->name, "autokill")) {
13271 if (sscanf(v->value, "%30d", &x) == 1) {
13272 if (x >= 0)
13273 autokill = x;
13274 else
13275 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13276 } else if (ast_true(v->value)) {
13277 autokill = DEFAULT_MAXMS;
13278 } else {
13279 autokill = 0;
13280 }
13281 } else if (!strcasecmp(v->name, "bandwidth")) {
13282 if (!strcasecmp(v->value, "low")) {
13283 capability = IAX_CAPABILITY_LOWBANDWIDTH;
13284 } else if (!strcasecmp(v->value, "medium")) {
13285 capability = IAX_CAPABILITY_MEDBANDWIDTH;
13286 } else if (!strcasecmp(v->value, "high")) {
13287 capability = IAX_CAPABILITY_FULLBANDWIDTH;
13288 } else
13289 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13290 } else if (!strcasecmp(v->name, "allow")) {
13291 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13292 } else if (!strcasecmp(v->name, "disallow")) {
13293 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13294 } else if (!strcasecmp(v->name, "register")) {
13295 iax2_register(v->value, v->lineno);
13296 } else if (!strcasecmp(v->name, "iaxcompat")) {
13297 iaxcompat = ast_true(v->value);
13298 } else if (!strcasecmp(v->name, "regcontext")) {
13299 ast_copy_string(regcontext, v->value, sizeof(regcontext));
13300
13301 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13302 } else if (!strcasecmp(v->name, "tos")) {
13303 if (ast_str2tos(v->value, &qos.tos))
13304 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13305 } else if (!strcasecmp(v->name, "cos")) {
13306 if (ast_str2cos(v->value, &qos.cos))
13307 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13308 } else if (!strcasecmp(v->name, "parkinglot")) {
13309 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13310 } else if (!strcasecmp(v->name, "accountcode")) {
13311 ast_copy_string(accountcode, v->value, sizeof(accountcode));
13312 } else if (!strcasecmp(v->name, "mohinterpret")) {
13313 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13314 } else if (!strcasecmp(v->name, "mohsuggest")) {
13315 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13316 } else if (!strcasecmp(v->name, "amaflags")) {
13317 format = ast_cdr_amaflags2int(v->value);
13318 if (format < 0) {
13319 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13320 } else {
13321 amaflags = format;
13322 }
13323 } else if (!strcasecmp(v->name, "language")) {
13324 ast_copy_string(language, v->value, sizeof(language));
13325 } else if (!strcasecmp(v->name, "maxauthreq")) {
13326 maxauthreq = atoi(v->value);
13327 if (maxauthreq < 0)
13328 maxauthreq = 0;
13329 } else if (!strcasecmp(v->name, "adsi")) {
13330 adsi = ast_true(v->value);
13331 } else if (!strcasecmp(v->name, "srvlookup")) {
13332 srvlookup = ast_true(v->value);
13333 } else if (!strcasecmp(v->name, "connectedline")) {
13334 if (ast_true(v->value)) {
13335 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13336 } else if (!strcasecmp(v->value, "send")) {
13337 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13338 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13339 } else if (!strcasecmp(v->value, "receive")) {
13340 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13341 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13342 } else {
13343 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13344 }
13345 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13346 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13347 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
13348 }
13349 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13350 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13351 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);
13352 }
13353 } else if (!strcasecmp(v->name, "calltokenoptional")) {
13354 if (add_calltoken_ignore(v->value)) {
13355 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13356 }
13357 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13358 if (ast_true(v->value)) {
13359 subscribe_network_change = 1;
13360 } else if (ast_false(v->value)) {
13361 subscribe_network_change = 0;
13362 } else {
13363 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13364 }
13365 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13366 if (ast_true(v->value)) {
13367 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13368 } else if (ast_false(v->value)) {
13369 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13370 } else {
13371 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13372 }
13373 }
13374
13375 v = v->next;
13376 }
13377
13378 if (subscribe_network_change) {
13379 network_change_event_subscribe();
13380 } else {
13381 network_change_event_unsubscribe();
13382 }
13383
13384 if (defaultsockfd < 0) {
13385 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13386 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13387 } else {
13388 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13389 defaultsockfd = ast_netsock_sockfd(ns);
13390 ast_netsock_unref(ns);
13391 }
13392 }
13393 if (reload) {
13394 ast_netsock_release(outsock);
13395 outsock = ast_netsock_list_alloc();
13396 if (!outsock) {
13397 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13398 return -1;
13399 }
13400 ast_netsock_init(outsock);
13401 }
13402
13403 if (min_reg_expire > max_reg_expire) {
13404 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13405 min_reg_expire, max_reg_expire, max_reg_expire);
13406 min_reg_expire = max_reg_expire;
13407 }
13408 iax2_capability = capability;
13409
13410 if (ucfg) {
13411 struct ast_variable *gen;
13412 int genhasiax;
13413 int genregisteriax;
13414 const char *hasiax, *registeriax;
13415
13416 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13417 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13418 gen = ast_variable_browse(ucfg, "general");
13419 cat = ast_category_browse(ucfg, NULL);
13420 while (cat) {
13421 if (strcasecmp(cat, "general")) {
13422 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13423 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13424 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13425
13426 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13427 if (user) {
13428 ao2_link(users, user);
13429 user = user_unref(user);
13430 }
13431 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13432 if (peer) {
13433 if (ast_test_flag64(peer, IAX_DYNAMIC))
13434 reg_source_db(peer);
13435 ao2_link(peers, peer);
13436 peer = peer_unref(peer);
13437 }
13438 }
13439 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13440 char tmp[256];
13441 const char *host = ast_variable_retrieve(ucfg, cat, "host");
13442 const char *username = ast_variable_retrieve(ucfg, cat, "username");
13443 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13444 if (!host)
13445 host = ast_variable_retrieve(ucfg, "general", "host");
13446 if (!username)
13447 username = ast_variable_retrieve(ucfg, "general", "username");
13448 if (!secret)
13449 secret = ast_variable_retrieve(ucfg, "general", "secret");
13450 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13451 if (!ast_strlen_zero(secret))
13452 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13453 else
13454 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13455 iax2_register(tmp, 0);
13456 }
13457 }
13458 }
13459 cat = ast_category_browse(ucfg, cat);
13460 }
13461 ast_config_destroy(ucfg);
13462 }
13463
13464 cat = ast_category_browse(cfg, NULL);
13465 while(cat) {
13466 if (strcasecmp(cat, "general")) {
13467 utype = ast_variable_retrieve(cfg, cat, "type");
13468 if (!strcasecmp(cat, "callnumberlimits")) {
13469 build_callno_limits(ast_variable_browse(cfg, cat));
13470 } else if (utype) {
13471 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13472 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13473 if (user) {
13474 ao2_link(users, user);
13475 user = user_unref(user);
13476 }
13477 }
13478 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13479 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13480 if (peer) {
13481 if (ast_test_flag64(peer, IAX_DYNAMIC))
13482 reg_source_db(peer);
13483 ao2_link(peers, peer);
13484 peer = peer_unref(peer);
13485 }
13486 } else if (strcasecmp(utype, "user")) {
13487 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13488 }
13489 } else
13490 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13491 }
13492 cat = ast_category_browse(cfg, cat);
13493 }
13494 ast_config_destroy(cfg);
13495 return 1;
13496 }
13497
13498 static void poke_all_peers(void)
13499 {
13500 struct ao2_iterator i;
13501 struct iax2_peer *peer;
13502
13503 i = ao2_iterator_init(peers, 0);
13504 while ((peer = ao2_iterator_next(&i))) {
13505 iax2_poke_peer(peer, 0);
13506 peer_unref(peer);
13507 }
13508 ao2_iterator_destroy(&i);
13509 }
13510 static int reload_config(void)
13511 {
13512 static const char config[] = "iax.conf";
13513 struct iax2_registry *reg;
13514
13515 if (set_config(config, 1) > 0) {
13516 prune_peers();
13517 prune_users();
13518 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13519 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13520 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13521 trunk_timed = trunk_untimed = 0;
13522 trunk_nmaxmtu = trunk_maxmtu = 0;
13523 memset(&debugaddr, '\0', sizeof(debugaddr));
13524
13525 AST_LIST_LOCK(®istrations);
13526 AST_LIST_TRAVERSE(®istrations, reg, entry)
13527 iax2_do_register(reg);
13528 AST_LIST_UNLOCK(®istrations);
13529
13530
13531 poke_all_peers();
13532 }
13533
13534 reload_firmware(0);
13535 iax_provision_reload(1);
13536 ast_unload_realtime("iaxpeers");
13537
13538 return 0;
13539 }
13540
13541 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13542 {
13543 switch (cmd) {
13544 case CLI_INIT:
13545 e->command = "iax2 reload";
13546 e->usage =
13547 "Usage: iax2 reload\n"
13548 " Reloads IAX configuration from iax.conf\n";
13549 return NULL;
13550 case CLI_GENERATE:
13551 return NULL;
13552 }
13553
13554 reload_config();
13555
13556 return CLI_SUCCESS;
13557 }
13558
13559 static int reload(void)
13560 {
13561 return reload_config();
13562 }
13563
13564 static int cache_get_callno_locked(const char *data)
13565 {
13566 struct sockaddr_in sin;
13567 int x;
13568 int callno;
13569 struct iax_ie_data ied;
13570 struct create_addr_info cai;
13571 struct parsed_dial_string pds;
13572 char *tmpstr;
13573
13574 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13575
13576
13577 if (!ast_mutex_trylock(&iaxsl[x])) {
13578 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13579 return x;
13580 ast_mutex_unlock(&iaxsl[x]);
13581 }
13582 }
13583
13584
13585
13586 memset(&cai, 0, sizeof(cai));
13587 memset(&ied, 0, sizeof(ied));
13588 memset(&pds, 0, sizeof(pds));
13589
13590 tmpstr = ast_strdupa(data);
13591 parse_dial_string(tmpstr, &pds);
13592
13593 if (ast_strlen_zero(pds.peer)) {
13594 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13595 return -1;
13596 }
13597
13598
13599 if (create_addr(pds.peer, NULL, &sin, &cai))
13600 return -1;
13601
13602 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13603 pds.peer, pds.username, pds.password, pds.context);
13604
13605 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13606 if (callno < 1) {
13607 ast_log(LOG_WARNING, "Unable to create call\n");
13608 return -1;
13609 }
13610
13611 ast_string_field_set(iaxs[callno], dproot, data);
13612 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13613
13614 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13615 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13616
13617
13618
13619 if (pds.exten)
13620 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13621 if (pds.username)
13622 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13623 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13624 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13625
13626 if (pds.password)
13627 ast_string_field_set(iaxs[callno], secret, pds.password);
13628 if (pds.key)
13629 ast_string_field_set(iaxs[callno], outkey, pds.key);
13630
13631 add_empty_calltoken_ie(iaxs[callno], &ied);
13632 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13633
13634 return callno;
13635 }
13636
13637 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13638 {
13639 struct iax2_dpcache *dp = NULL;
13640 struct timeval now = ast_tvnow();
13641 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13642 struct ast_channel *c = NULL;
13643 struct ast_frame *f = NULL;
13644
13645 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13646 if (ast_tvcmp(now, dp->expiry) > 0) {
13647 AST_LIST_REMOVE_CURRENT(cache_list);
13648 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13649 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13650 else
13651 ast_free(dp);
13652 continue;
13653 }
13654 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13655 break;
13656 }
13657 AST_LIST_TRAVERSE_SAFE_END;
13658
13659 if (!dp) {
13660
13661
13662 if ((callno = cache_get_callno_locked(data)) < 0) {
13663 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13664 return NULL;
13665 }
13666 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13667 ast_mutex_unlock(&iaxsl[callno]);
13668 return NULL;
13669 }
13670 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13671 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13672 dp->expiry = ast_tvnow();
13673 dp->orig = dp->expiry;
13674
13675 dp->expiry.tv_sec += iaxdefaultdpcache;
13676 dp->flags = CACHE_FLAG_PENDING;
13677 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13678 dp->waiters[x] = -1;
13679
13680 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13681 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13682
13683 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13684 iax2_dprequest(dp, callno);
13685 ast_mutex_unlock(&iaxsl[callno]);
13686 }
13687
13688
13689 if (dp->flags & CACHE_FLAG_PENDING) {
13690
13691
13692 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13693
13694 if (dp->waiters[x] < 0)
13695 break;
13696 }
13697 if (x >= ARRAY_LEN(dp->waiters)) {
13698 ast_log(LOG_WARNING, "No more waiter positions available\n");
13699 return NULL;
13700 }
13701 if (pipe(com)) {
13702 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13703 return NULL;
13704 }
13705 dp->waiters[x] = com[1];
13706
13707 timeout = iaxdefaulttimeout * 1000;
13708
13709 AST_LIST_UNLOCK(&dpcache);
13710
13711 if (chan)
13712 old = ast_channel_defer_dtmf(chan);
13713 doabort = 0;
13714 while(timeout) {
13715 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13716 if (outfd > -1)
13717 break;
13718 if (!c)
13719 continue;
13720 if (!(f = ast_read(c))) {
13721 doabort = 1;
13722 break;
13723 }
13724 ast_frfree(f);
13725 }
13726 if (!timeout) {
13727 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13728 }
13729 AST_LIST_LOCK(&dpcache);
13730 dp->waiters[x] = -1;
13731 close(com[1]);
13732 close(com[0]);
13733 if (doabort) {
13734
13735
13736 if (!old && chan)
13737 ast_channel_undefer_dtmf(chan);
13738 return NULL;
13739 }
13740 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13741
13742 if (dp->flags & CACHE_FLAG_PENDING) {
13743
13744
13745 dp->flags &= ~CACHE_FLAG_PENDING;
13746 dp->flags |= CACHE_FLAG_TIMEOUT;
13747
13748
13749 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13750 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13751 if (dp->waiters[x] > -1) {
13752 if (write(dp->waiters[x], "asdf", 4) < 0) {
13753 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13754 }
13755 }
13756 }
13757 }
13758 }
13759
13760 if (!old && chan)
13761 ast_channel_undefer_dtmf(chan);
13762 }
13763 return dp;
13764 }
13765
13766
13767 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13768 {
13769 int res = 0;
13770 struct iax2_dpcache *dp = NULL;
13771 #if 0
13772 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13773 #endif
13774 if ((priority != 1) && (priority != 2))
13775 return 0;
13776
13777 AST_LIST_LOCK(&dpcache);
13778 if ((dp = find_cache(chan, data, context, exten, priority))) {
13779 if (dp->flags & CACHE_FLAG_EXISTS)
13780 res = 1;
13781 } else {
13782 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13783 }
13784 AST_LIST_UNLOCK(&dpcache);
13785
13786 return res;
13787 }
13788
13789
13790 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13791 {
13792 int res = 0;
13793 struct iax2_dpcache *dp = NULL;
13794 #if 0
13795 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13796 #endif
13797 if ((priority != 1) && (priority != 2))
13798 return 0;
13799
13800 AST_LIST_LOCK(&dpcache);
13801 if ((dp = find_cache(chan, data, context, exten, priority))) {
13802 if (dp->flags & CACHE_FLAG_CANEXIST)
13803 res = 1;
13804 } else {
13805 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13806 }
13807 AST_LIST_UNLOCK(&dpcache);
13808
13809 return res;
13810 }
13811
13812
13813 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13814 {
13815 int res = 0;
13816 struct iax2_dpcache *dp = NULL;
13817 #if 0
13818 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13819 #endif
13820 if ((priority != 1) && (priority != 2))
13821 return 0;
13822
13823 AST_LIST_LOCK(&dpcache);
13824 if ((dp = find_cache(chan, data, context, exten, priority))) {
13825 if (dp->flags & CACHE_FLAG_MATCHMORE)
13826 res = 1;
13827 } else {
13828 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13829 }
13830 AST_LIST_UNLOCK(&dpcache);
13831
13832 return res;
13833 }
13834
13835
13836 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13837 {
13838 char odata[256];
13839 char req[256];
13840 char *ncontext;
13841 struct iax2_dpcache *dp = NULL;
13842 struct ast_app *dial = NULL;
13843 #if 0
13844 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);
13845 #endif
13846 if (priority == 2) {
13847
13848 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13849 if (dialstatus) {
13850 dial = pbx_findapp(dialstatus);
13851 if (dial)
13852 pbx_exec(chan, dial, "");
13853 }
13854 return -1;
13855 } else if (priority != 1)
13856 return -1;
13857
13858 AST_LIST_LOCK(&dpcache);
13859 if ((dp = find_cache(chan, data, context, exten, priority))) {
13860 if (dp->flags & CACHE_FLAG_EXISTS) {
13861 ast_copy_string(odata, data, sizeof(odata));
13862 ncontext = strchr(odata, '/');
13863 if (ncontext) {
13864 *ncontext = '\0';
13865 ncontext++;
13866 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13867 } else {
13868 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13869 }
13870 ast_verb(3, "Executing Dial('%s')\n", req);
13871 } else {
13872 AST_LIST_UNLOCK(&dpcache);
13873 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13874 return -1;
13875 }
13876 }
13877 AST_LIST_UNLOCK(&dpcache);
13878
13879 if ((dial = pbx_findapp("Dial")))
13880 return pbx_exec(chan, dial, req);
13881 else
13882 ast_log(LOG_WARNING, "No dial application registered\n");
13883
13884 return -1;
13885 }
13886
13887 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13888 {
13889 struct iax2_peer *peer;
13890 char *peername, *colname;
13891
13892 peername = ast_strdupa(data);
13893
13894
13895 if (!strcmp(peername,"CURRENTCHANNEL")) {
13896 unsigned short callno;
13897 if (chan->tech != &iax2_tech)
13898 return -1;
13899 callno = PTR_TO_CALLNO(chan->tech_pvt);
13900 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13901 return 0;
13902 }
13903
13904 if ((colname = strchr(peername, ',')))
13905 *colname++ = '\0';
13906 else
13907 colname = "ip";
13908
13909 if (!(peer = find_peer(peername, 1)))
13910 return -1;
13911
13912 if (!strcasecmp(colname, "ip")) {
13913 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13914 } else if (!strcasecmp(colname, "status")) {
13915 peer_status(peer, buf, len);
13916 } else if (!strcasecmp(colname, "mailbox")) {
13917 ast_copy_string(buf, peer->mailbox, len);
13918 } else if (!strcasecmp(colname, "context")) {
13919 ast_copy_string(buf, peer->context, len);
13920 } else if (!strcasecmp(colname, "expire")) {
13921 snprintf(buf, len, "%d", peer->expire);
13922 } else if (!strcasecmp(colname, "dynamic")) {
13923 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13924 } else if (!strcasecmp(colname, "callerid_name")) {
13925 ast_copy_string(buf, peer->cid_name, len);
13926 } else if (!strcasecmp(colname, "callerid_num")) {
13927 ast_copy_string(buf, peer->cid_num, len);
13928 } else if (!strcasecmp(colname, "codecs")) {
13929 ast_getformatname_multiple(buf, len -1, peer->capability);
13930 } else if (!strncasecmp(colname, "codec[", 6)) {
13931 char *codecnum, *ptr;
13932 int codec = 0;
13933
13934 codecnum = strchr(colname, '[');
13935 *codecnum = '\0';
13936 codecnum++;
13937 if ((ptr = strchr(codecnum, ']'))) {
13938 *ptr = '\0';
13939 }
13940 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13941 ast_copy_string(buf, ast_getformatname(codec), len);
13942 } else {
13943 buf[0] = '\0';
13944 }
13945 } else {
13946 buf[0] = '\0';
13947 }
13948
13949 peer_unref(peer);
13950
13951 return 0;
13952 }
13953
13954 static struct ast_custom_function iaxpeer_function = {
13955 .name = "IAXPEER",
13956 .read = function_iaxpeer,
13957 };
13958
13959 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13960 {
13961 struct chan_iax2_pvt *pvt;
13962 unsigned int callno;
13963 int res = 0;
13964
13965 if (!chan || chan->tech != &iax2_tech) {
13966 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13967 return -1;
13968 }
13969
13970 callno = PTR_TO_CALLNO(chan->tech_pvt);
13971 ast_mutex_lock(&iaxsl[callno]);
13972 if (!(pvt = iaxs[callno])) {
13973 ast_mutex_unlock(&iaxsl[callno]);
13974 return -1;
13975 }
13976
13977 if (!strcasecmp(args, "osptoken")) {
13978 ast_copy_string(buf, pvt->osptoken, buflen);
13979 } else if (!strcasecmp(args, "peerip")) {
13980 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13981 } else if (!strcasecmp(args, "peername")) {
13982 ast_copy_string(buf, pvt->username, buflen);
13983 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
13984 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
13985 } else {
13986 res = -1;
13987 }
13988
13989 ast_mutex_unlock(&iaxsl[callno]);
13990
13991 return res;
13992 }
13993
13994
13995 static int iax2_devicestate(void *data)
13996 {
13997 struct parsed_dial_string pds;
13998 char *tmp = ast_strdupa(data);
13999 struct iax2_peer *p;
14000 int res = AST_DEVICE_INVALID;
14001
14002 memset(&pds, 0, sizeof(pds));
14003 parse_dial_string(tmp, &pds);
14004
14005 if (ast_strlen_zero(pds.peer)) {
14006 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
14007 return res;
14008 }
14009
14010 ast_debug(3, "Checking device state for device %s\n", pds.peer);
14011
14012
14013 if (!(p = find_peer(pds.peer, 1)))
14014 return res;
14015
14016 res = AST_DEVICE_UNAVAILABLE;
14017 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
14018 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
14019
14020 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
14021 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14022
14023
14024 if (p->historicms == 0 || p->historicms <= p->maxms)
14025
14026 res = AST_DEVICE_UNKNOWN;
14027 }
14028
14029 peer_unref(p);
14030
14031 return res;
14032 }
14033
14034 static struct ast_switch iax2_switch =
14035 {
14036 .name = "IAX2",
14037 .description = "IAX Remote Dialplan Switch",
14038 .exists = iax2_exists,
14039 .canmatch = iax2_canmatch,
14040 .exec = iax2_exec,
14041 .matchmore = iax2_matchmore,
14042 };
14043
14044
14045
14046
14047
14048
14049
14050
14051
14052
14053
14054
14055
14056
14057
14058
14059
14060
14061
14062
14063
14064
14065
14066
14067
14068
14069
14070
14071
14072
14073
14074
14075
14076
14077
14078
14079
14080
14081
14082
14083
14084
14085
14086
14087
14088
14089
14090
14091
14092
14093
14094
14095
14096
14097
14098
14099
14100
14101
14102
14103
14104
14105
14106
14107
14108
14109
14110
14111
14112
14113
14114
14115
14116
14117
14118
14119
14120
14121
14122
14123
14124
14125
14126
14127
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137
14138
14139
14140
14141
14142
14143
14144
14145
14146
14147
14148 static struct ast_cli_entry cli_iax2[] = {
14149 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14150 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14151 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14152 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14153 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14154 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14155 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14156 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14157 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14158 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14159 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14160 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14161 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14162 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14163 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14164 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14165 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14166 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14167 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14168 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14169 #ifdef IAXTESTS
14170 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14171 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14172 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14173 #endif
14174 };
14175
14176 #ifdef TEST_FRAMEWORK
14177 AST_TEST_DEFINE(test_iax2_peers_get)
14178 {
14179 struct ast_data_query query = {
14180 .path = "/asterisk/channel/iax2/peers",
14181 .search = "peers/peer/name=test_peer_data_provider"
14182 };
14183 struct ast_data *node;
14184 struct iax2_peer *peer;
14185
14186 switch (cmd) {
14187 case TEST_INIT:
14188 info->name = "iax2_peers_get_data_test";
14189 info->category = "/main/data/iax2/peers/";
14190 info->summary = "IAX2 peers data providers unit test";
14191 info->description =
14192 "Tests whether the IAX2 peers data provider implementation works as expected.";
14193 return AST_TEST_NOT_RUN;
14194 case TEST_EXECUTE:
14195 break;
14196 }
14197
14198
14199 peer = build_peer("test_peer_data_provider", NULL, NULL, 0);
14200 if (!peer) {
14201 return AST_TEST_FAIL;
14202 }
14203 peer->expiry= 1010;
14204 ao2_link(peers, peer);
14205
14206 node = ast_data_get(&query);
14207 if (!node) {
14208 ao2_unlink(peers, peer);
14209 peer_unref(peer);
14210 return AST_TEST_FAIL;
14211 }
14212
14213
14214 if (strcmp(ast_data_retrieve_string(node, "peer/name"), "test_peer_data_provider")) {
14215 ao2_unlink(peers, peer);
14216 peer_unref(peer);
14217 ast_data_free(node);
14218 return AST_TEST_FAIL;
14219 }
14220
14221 if (ast_data_retrieve_int(node, "peer/expiry") != 1010) {
14222 ao2_unlink(peers, peer);
14223 peer_unref(peer);
14224 ast_data_free(node);
14225 return AST_TEST_FAIL;
14226 }
14227
14228
14229 ast_data_free(node);
14230
14231 ao2_unlink(peers, peer);
14232 peer_unref(peer);
14233
14234 return AST_TEST_PASS;
14235 }
14236
14237 AST_TEST_DEFINE(test_iax2_users_get)
14238 {
14239 struct ast_data_query query = {
14240 .path = "/asterisk/channel/iax2/users",
14241 .search = "users/user/name=test_user_data_provider"
14242 };
14243 struct ast_data *node;
14244 struct iax2_user *user;
14245
14246 switch (cmd) {
14247 case TEST_INIT:
14248 info->name = "iax2_users_get_data_test";
14249 info->category = "/main/data/iax2/users/";
14250 info->summary = "IAX2 users data providers unit test";
14251 info->description =
14252 "Tests whether the IAX2 users data provider implementation works as expected.";
14253 return AST_TEST_NOT_RUN;
14254 case TEST_EXECUTE:
14255 break;
14256 }
14257
14258 user = build_user("test_user_data_provider", NULL, NULL, 0);
14259 if (!user) {
14260 ast_test_status_update(test, "Failed to build a test user\n");
14261 return AST_TEST_FAIL;
14262 }
14263 user->amaflags = 1010;
14264 ao2_link(users, user);
14265
14266 node = ast_data_get(&query);
14267 if (!node) {
14268 ast_test_status_update(test, "The data query to find our test user failed\n");
14269 ao2_unlink(users, user);
14270 user_unref(user);
14271 return AST_TEST_FAIL;
14272 }
14273
14274 if (strcmp(ast_data_retrieve_string(node, "user/name"), "test_user_data_provider")) {
14275 ast_test_status_update(test, "Our data results did not return the test user created in the previous step.\n");
14276 ao2_unlink(users, user);
14277 user_unref(user);
14278 ast_data_free(node);
14279 return AST_TEST_FAIL;
14280 }
14281
14282 if (ast_data_retrieve_int(node, "user/amaflags/value") != 1010) {
14283 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"));
14284 ao2_unlink(users, user);
14285 user_unref(user);
14286 ast_data_free(node);
14287 return AST_TEST_FAIL;
14288 }
14289
14290 ast_data_free(node);
14291
14292 ao2_unlink(users, user);
14293 user_unref(user);
14294
14295 return AST_TEST_PASS;
14296 }
14297 #endif
14298
14299 static void cleanup_thread_list(void *head)
14300 {
14301 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14302 struct iax2_thread_list *list_head = head;
14303 struct iax2_thread *thread;
14304
14305 AST_LIST_LOCK(list_head);
14306 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14307 pthread_t thread_id = thread->threadid;
14308
14309 thread->stop = 1;
14310 signal_condition(&thread->lock, &thread->cond);
14311
14312 AST_LIST_UNLOCK(list_head);
14313 pthread_join(thread_id, NULL);
14314 AST_LIST_LOCK(list_head);
14315 }
14316 AST_LIST_UNLOCK(list_head);
14317 }
14318
14319 static int __unload_module(void)
14320 {
14321 struct ast_context *con;
14322 int x;
14323
14324 network_change_event_unsubscribe();
14325
14326 ast_manager_unregister("IAXpeers");
14327 ast_manager_unregister("IAXpeerlist");
14328 ast_manager_unregister("IAXnetstats");
14329 ast_manager_unregister("IAXregistry");
14330 ast_unregister_application(papp);
14331 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14332 ast_unregister_switch(&iax2_switch);
14333 ast_channel_unregister(&iax2_tech);
14334
14335 if (netthreadid != AST_PTHREADT_NULL) {
14336 pthread_cancel(netthreadid);
14337 pthread_kill(netthreadid, SIGURG);
14338 pthread_join(netthreadid, NULL);
14339 }
14340
14341 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14342 if (iaxs[x]) {
14343 iax2_destroy(x);
14344 }
14345 }
14346
14347
14348 cleanup_thread_list(&idle_list);
14349 cleanup_thread_list(&active_list);
14350 cleanup_thread_list(&dynamic_list);
14351
14352 ast_netsock_release(netsock);
14353 ast_netsock_release(outsock);
14354 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14355 if (iaxs[x]) {
14356 iax2_destroy(x);
14357 }
14358 }
14359 ast_manager_unregister( "IAXpeers" );
14360 ast_manager_unregister( "IAXpeerlist" );
14361 ast_manager_unregister( "IAXnetstats" );
14362 ast_manager_unregister( "IAXregistry" );
14363 ast_unregister_application(papp);
14364 #ifdef TEST_FRAMEWORK
14365 AST_TEST_UNREGISTER(test_iax2_peers_get);
14366 AST_TEST_UNREGISTER(test_iax2_users_get);
14367 #endif
14368 ast_data_unregister(NULL);
14369 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14370 ast_unregister_switch(&iax2_switch);
14371 ast_channel_unregister(&iax2_tech);
14372 delete_users();
14373 iax_provision_unload();
14374 reload_firmware(1);
14375
14376 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14377 ast_mutex_destroy(&iaxsl[x]);
14378 }
14379
14380 ao2_ref(peers, -1);
14381 ao2_ref(users, -1);
14382 ao2_ref(iax_peercallno_pvts, -1);
14383 ao2_ref(iax_transfercallno_pvts, -1);
14384 ao2_ref(peercnts, -1);
14385 ao2_ref(callno_limits, -1);
14386 ao2_ref(calltoken_ignores, -1);
14387 ao2_ref(callno_pool, -1);
14388 ao2_ref(callno_pool_trunk, -1);
14389 if (timer) {
14390 ast_timer_close(timer);
14391 }
14392 transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14393 sched = ast_sched_thread_destroy(sched);
14394
14395 con = ast_context_find(regcontext);
14396 if (con)
14397 ast_context_destroy(con, "IAX2");
14398 ast_unload_realtime("iaxpeers");
14399 return 0;
14400 }
14401
14402 static int unload_module(void)
14403 {
14404 ast_custom_function_unregister(&iaxpeer_function);
14405 ast_custom_function_unregister(&iaxvar_function);
14406 return __unload_module();
14407 }
14408
14409 static int peer_set_sock_cb(void *obj, void *arg, int flags)
14410 {
14411 struct iax2_peer *peer = obj;
14412
14413 if (peer->sockfd < 0)
14414 peer->sockfd = defaultsockfd;
14415
14416 return 0;
14417 }
14418
14419 static int pvt_hash_cb(const void *obj, const int flags)
14420 {
14421 const struct chan_iax2_pvt *pvt = obj;
14422
14423 return pvt->peercallno;
14424 }
14425
14426 static int pvt_cmp_cb(void *obj, void *arg, int flags)
14427 {
14428 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14429
14430
14431
14432
14433 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14434 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14435 }
14436
14437 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14438 {
14439 const struct chan_iax2_pvt *pvt = obj;
14440
14441 return pvt->transfercallno;
14442 }
14443
14444 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14445 {
14446 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14447
14448
14449
14450
14451 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14452 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14453 }
14454
14455 static int load_objects(void)
14456 {
14457 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14458 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14459
14460 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14461 goto container_fail;
14462 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14463 goto container_fail;
14464 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14465 goto container_fail;
14466 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14467 goto container_fail;
14468 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14469 goto container_fail;
14470 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14471 goto container_fail;
14472 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14473 goto container_fail;
14474 } else if (create_callno_pools()) {
14475 goto container_fail;
14476 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14477 goto container_fail;
14478 }
14479
14480 return 0;
14481
14482 container_fail:
14483 if (peers) {
14484 ao2_ref(peers, -1);
14485 }
14486 if (users) {
14487 ao2_ref(users, -1);
14488 }
14489 if (iax_peercallno_pvts) {
14490 ao2_ref(iax_peercallno_pvts, -1);
14491 }
14492 if (iax_transfercallno_pvts) {
14493 ao2_ref(iax_transfercallno_pvts, -1);
14494 }
14495 if (peercnts) {
14496 ao2_ref(peercnts, -1);
14497 }
14498 if (callno_limits) {
14499 ao2_ref(callno_limits, -1);
14500 }
14501 if (calltoken_ignores) {
14502 ao2_ref(calltoken_ignores, -1);
14503 }
14504 if (callno_pool) {
14505 ao2_ref(callno_pool, -1);
14506 }
14507 if (callno_pool_trunk) {
14508 ao2_ref(callno_pool_trunk, -1);
14509 }
14510 return AST_MODULE_LOAD_FAILURE;
14511 }
14512
14513
14514 #define DATA_EXPORT_IAX2_PEER(MEMBER) \
14515 MEMBER(iax2_peer, name, AST_DATA_STRING) \
14516 MEMBER(iax2_peer, username, AST_DATA_STRING) \
14517 MEMBER(iax2_peer, secret, AST_DATA_PASSWORD) \
14518 MEMBER(iax2_peer, dbsecret, AST_DATA_PASSWORD) \
14519 MEMBER(iax2_peer, outkey, AST_DATA_STRING) \
14520 MEMBER(iax2_peer, regexten, AST_DATA_STRING) \
14521 MEMBER(iax2_peer, context, AST_DATA_STRING) \
14522 MEMBER(iax2_peer, peercontext, AST_DATA_STRING) \
14523 MEMBER(iax2_peer, mailbox, AST_DATA_STRING) \
14524 MEMBER(iax2_peer, mohinterpret, AST_DATA_STRING) \
14525 MEMBER(iax2_peer, mohsuggest, AST_DATA_STRING) \
14526 MEMBER(iax2_peer, inkeys, AST_DATA_STRING) \
14527 MEMBER(iax2_peer, cid_num, AST_DATA_STRING) \
14528 MEMBER(iax2_peer, cid_name, AST_DATA_STRING) \
14529 MEMBER(iax2_peer, zonetag, AST_DATA_STRING) \
14530 MEMBER(iax2_peer, parkinglot, AST_DATA_STRING) \
14531 MEMBER(iax2_peer, expiry, AST_DATA_SECONDS) \
14532 MEMBER(iax2_peer, callno, AST_DATA_INTEGER) \
14533 MEMBER(iax2_peer, lastms, AST_DATA_MILLISECONDS) \
14534 MEMBER(iax2_peer, maxms, AST_DATA_MILLISECONDS) \
14535 MEMBER(iax2_peer, pokefreqok, AST_DATA_MILLISECONDS) \
14536 MEMBER(iax2_peer, pokefreqnotok, AST_DATA_MILLISECONDS) \
14537 MEMBER(iax2_peer, historicms, AST_DATA_INTEGER) \
14538 MEMBER(iax2_peer, smoothing, AST_DATA_BOOLEAN) \
14539 MEMBER(iax2_peer, maxcallno, AST_DATA_INTEGER)
14540
14541 AST_DATA_STRUCTURE(iax2_peer, DATA_EXPORT_IAX2_PEER);
14542
14543 static int peers_data_provider_get(const struct ast_data_search *search,
14544 struct ast_data *data_root)
14545 {
14546 struct ast_data *data_peer;
14547 struct iax2_peer *peer;
14548 struct ao2_iterator i;
14549 char status[20];
14550 struct ast_str *encmethods = ast_str_alloca(256);
14551
14552 i = ao2_iterator_init(peers, 0);
14553 while ((peer = ao2_iterator_next(&i))) {
14554 data_peer = ast_data_add_node(data_root, "peer");
14555 if (!data_peer) {
14556 peer_unref(peer);
14557 continue;
14558 }
14559
14560 ast_data_add_structure(iax2_peer, data_peer, peer);
14561
14562 ast_data_add_codecs(data_peer, "codecs", peer->capability);
14563
14564 peer_status(peer, status, sizeof(status));
14565 ast_data_add_str(data_peer, "status", status);
14566
14567 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14568
14569 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14570
14571 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14572
14573 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14574
14575 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14576
14577 encmethods_to_str(peer->encmethods, encmethods);
14578 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14579
14580 peer_unref(peer);
14581
14582 if (!ast_data_search_match(search, data_peer)) {
14583 ast_data_remove_node(data_root, data_peer);
14584 }
14585 }
14586 ao2_iterator_destroy(&i);
14587
14588 return 0;
14589 }
14590
14591 #define DATA_EXPORT_IAX2_USER(MEMBER) \
14592 MEMBER(iax2_user, name, AST_DATA_STRING) \
14593 MEMBER(iax2_user, dbsecret, AST_DATA_PASSWORD) \
14594 MEMBER(iax2_user, accountcode, AST_DATA_STRING) \
14595 MEMBER(iax2_user, mohinterpret, AST_DATA_STRING) \
14596 MEMBER(iax2_user, mohsuggest, AST_DATA_STRING) \
14597 MEMBER(iax2_user, inkeys, AST_DATA_STRING) \
14598 MEMBER(iax2_user, language, AST_DATA_STRING) \
14599 MEMBER(iax2_user, cid_num, AST_DATA_STRING) \
14600 MEMBER(iax2_user, cid_name, AST_DATA_STRING) \
14601 MEMBER(iax2_user, parkinglot, AST_DATA_STRING) \
14602 MEMBER(iax2_user, maxauthreq, AST_DATA_INTEGER) \
14603 MEMBER(iax2_user, curauthreq, AST_DATA_INTEGER)
14604
14605 AST_DATA_STRUCTURE(iax2_user, DATA_EXPORT_IAX2_USER);
14606
14607 static int users_data_provider_get(const struct ast_data_search *search,
14608 struct ast_data *data_root)
14609 {
14610 struct ast_data *data_user, *data_authmethods, *data_enum_node;
14611 struct iax2_user *user;
14612 struct ao2_iterator i;
14613 char auth[90];
14614 char *pstr = "";
14615
14616 i = ao2_iterator_init(users, 0);
14617 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14618 data_user = ast_data_add_node(data_root, "user");
14619 if (!data_user) {
14620 continue;
14621 }
14622
14623 ast_data_add_structure(iax2_user, data_user, user);
14624
14625 ast_data_add_codecs(data_user, "codecs", user->capability);
14626
14627 if (!ast_strlen_zero(user->secret)) {
14628 ast_copy_string(auth, user->secret, sizeof(auth));
14629 } else if (!ast_strlen_zero(user->inkeys)) {
14630 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14631 } else {
14632 ast_copy_string(auth, "no secret", sizeof(auth));
14633 }
14634 ast_data_add_password(data_user, "secret", auth);
14635
14636 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14637
14638
14639 data_authmethods = ast_data_add_node(data_user, "authmethods");
14640 if (!data_authmethods) {
14641 ast_data_remove_node(data_root, data_user);
14642 continue;
14643 }
14644 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14645 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14646 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14647
14648
14649 data_enum_node = ast_data_add_node(data_user, "amaflags");
14650 if (!data_enum_node) {
14651 ast_data_remove_node(data_root, data_user);
14652 continue;
14653 }
14654 ast_data_add_int(data_enum_node, "value", user->amaflags);
14655 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14656
14657 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14658
14659 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14660 pstr = "REQ only";
14661 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14662 pstr = "disabled";
14663 } else {
14664 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14665 }
14666 ast_data_add_str(data_user, "codec-preferences", pstr);
14667
14668 if (!ast_data_search_match(search, data_user)) {
14669 ast_data_remove_node(data_root, data_user);
14670 }
14671 }
14672 ao2_iterator_destroy(&i);
14673
14674 return 0;
14675 }
14676
14677 static const struct ast_data_handler peers_data_provider = {
14678 .version = AST_DATA_HANDLER_VERSION,
14679 .get = peers_data_provider_get
14680 };
14681
14682 static const struct ast_data_handler users_data_provider = {
14683 .version = AST_DATA_HANDLER_VERSION,
14684 .get = users_data_provider_get
14685 };
14686
14687 static const struct ast_data_entry iax2_data_providers[] = {
14688 AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
14689 AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
14690 };
14691
14692
14693 static int load_module(void)
14694 {
14695 static const char config[] = "iax.conf";
14696 int x = 0;
14697 struct iax2_registry *reg = NULL;
14698
14699 if (load_objects()) {
14700 return AST_MODULE_LOAD_FAILURE;
14701 }
14702
14703 memset(iaxs, 0, sizeof(iaxs));
14704
14705 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14706 ast_mutex_init(&iaxsl[x]);
14707 }
14708
14709 if (!(sched = ast_sched_thread_create())) {
14710 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14711 return AST_MODULE_LOAD_FAILURE;
14712 }
14713
14714 if (!(io = io_context_create())) {
14715 ast_log(LOG_ERROR, "Failed to create I/O context\n");
14716 sched = ast_sched_thread_destroy(sched);
14717 return AST_MODULE_LOAD_FAILURE;
14718 }
14719
14720 if (!(netsock = ast_netsock_list_alloc())) {
14721 ast_log(LOG_ERROR, "Failed to create netsock list\n");
14722 io_context_destroy(io);
14723 sched = ast_sched_thread_destroy(sched);
14724 return AST_MODULE_LOAD_FAILURE;
14725 }
14726 ast_netsock_init(netsock);
14727
14728 outsock = ast_netsock_list_alloc();
14729 if (!outsock) {
14730 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14731 io_context_destroy(io);
14732 sched = ast_sched_thread_destroy(sched);
14733 return AST_MODULE_LOAD_FAILURE;
14734 }
14735 ast_netsock_init(outsock);
14736
14737 randomcalltokendata = ast_random();
14738
14739 iax_set_output(iax_debug_output);
14740 iax_set_error(iax_error_output);
14741 jb_setoutput(jb_error_output, jb_warning_output, NULL);
14742
14743 if ((timer = ast_timer_open())) {
14744 ast_timer_set_rate(timer, 1000 / trunkfreq);
14745 }
14746
14747 if (set_config(config, 0) == -1) {
14748 if (timer) {
14749 ast_timer_close(timer);
14750 }
14751 return AST_MODULE_LOAD_DECLINE;
14752 }
14753
14754 #ifdef TEST_FRAMEWORK
14755 AST_TEST_REGISTER(test_iax2_peers_get);
14756 AST_TEST_REGISTER(test_iax2_users_get);
14757 #endif
14758
14759
14760 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14761 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14762
14763 ast_register_application_xml(papp, iax2_prov_app);
14764
14765 ast_custom_function_register(&iaxpeer_function);
14766 ast_custom_function_register(&iaxvar_function);
14767
14768 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14769 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14770 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14771 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14772
14773 if (ast_channel_register(&iax2_tech)) {
14774 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14775 __unload_module();
14776 return AST_MODULE_LOAD_FAILURE;
14777 }
14778
14779 if (ast_register_switch(&iax2_switch)) {
14780 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14781 }
14782
14783 if (start_network_thread()) {
14784 ast_log(LOG_ERROR, "Unable to start network thread\n");
14785 __unload_module();
14786 return AST_MODULE_LOAD_FAILURE;
14787 } else {
14788 ast_verb(2, "IAX Ready and Listening\n");
14789 }
14790
14791 AST_LIST_LOCK(®istrations);
14792 AST_LIST_TRAVERSE(®istrations, reg, entry)
14793 iax2_do_register(reg);
14794 AST_LIST_UNLOCK(®istrations);
14795
14796 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14797 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14798
14799
14800 reload_firmware(0);
14801 iax_provision_reload(0);
14802
14803 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14804
14805 network_change_event_subscribe();
14806
14807 return AST_MODULE_LOAD_SUCCESS;
14808 }
14809
14810 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
14811 .load = load_module,
14812 .unload = unload_module,
14813 .reload = reload,
14814 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
14815 .nonoptreq = "res_crypto",
14816 );